mini_racer 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f868c575c8ed41f4080580b2d09d0d42522d337390f425b3110e38298952a6f4
4
- data.tar.gz: 9c2df1f0171dd3ed4bba7a59faa3ea7d87a1976087395da3ec56966aeedd23d8
3
+ metadata.gz: 179c0a63082cf1ec6bc7f8ead94fbcba3c41255ee91b1639482570d1ec3f7646
4
+ data.tar.gz: cdef6f06a6ab72060aa43b21518c6f0103bf80c034bee09b7cf1d6f215620c31
5
5
  SHA512:
6
- metadata.gz: 7c51ea3a8f4abc4ae458090ce2f37760110ac240f7600e3fd249f07df97725e0b7903884fb90063b3d3140c0337eeae132a6e395b1f74777c85dfddc03b6ad96
7
- data.tar.gz: '0948c498cdb9a0767dbe0de9d4b233d2561eb6b72f6603170c3f4d9304083487a03fc395f8803f1d1690ef6f9d06e0faddc86ef694b950c0e95ea4047943c96e'
6
+ metadata.gz: 0efd1873f139141ac489ed24ebcad3e289092ea67ea7823d0b94fe07a3acfcd602ed64c287b39b556d370db5c17b094d38a9c5ff06f31f546dddda7694d01c81
7
+ data.tar.gz: 1ccc24b53320211be2b3cd887ac1193ee0654e0b54c0d2b3da636a382ce00c95d4af3ba5acd23a931436d08e0707dc0b4d348b6bbd0863cb56df9fb2fbd2678e
data/CHANGELOG CHANGED
@@ -1,5 +1,21 @@
1
+ - 31-12-2021
2
+
3
+ - 0.6.0
4
+
5
+ - Ruby 3.1 support
6
+ - Fixes memory leak in heap snapshotting
7
+ - Improved compilation ergonomics in clang
8
+ - Migrated internal storage in c extension to TypedData
9
+
1
10
  - 11-04-2021
2
11
 
12
+ - 0.5.0
13
+ - Fixes issues on aarch (Apple M1)
14
+ - Update to use libv8-node 16.x (#210) [Loic Nageleisen]
15
+ - FEATURE: Configurable max marshal stack depth (#202) [seanmakesgames]
16
+ - FEATURE: Configurable max marshal stack depth (#202) [seanmakesgames]
17
+ - Ruby 2.3 and 2.4 are EOL, we no longer support them
18
+
3
19
  - 0.4.0
4
20
 
5
21
  - FEATURE: upgrade to libv8 node 15.14.0 (v8 8.6.395.17)
data/Rakefile CHANGED
@@ -92,5 +92,5 @@ task :lint do
92
92
  portability-*
93
93
  readability-*).join(',')
94
94
 
95
- sh RbConfig::expand("clang-tidy -checks='#{checks}' ext/mini_racer_extension/mini_racer_extension.cc -- #$INCFLAGS #$CPPFLAGS", conf)
95
+ sh RbConfig::expand("clang-tidy -checks='#{checks}' ext/mini_racer_extension/mini_racer_extension.cc -- #$INCFLAGS #$CXXFLAGS", conf)
96
96
  end
@@ -7,18 +7,25 @@ IS_DARWIN = RUBY_PLATFORM =~ /darwin/
7
7
 
8
8
  have_library('pthread')
9
9
  have_library('objc') if IS_DARWIN
10
- $CPPFLAGS += " -Wall" unless $CPPFLAGS.split.include? "-Wall"
11
- $CPPFLAGS += " -g" unless $CPPFLAGS.split.include? "-g"
12
- $CPPFLAGS += " -rdynamic" unless $CPPFLAGS.split.include? "-rdynamic"
13
- $CPPFLAGS += " -fPIC" unless $CPPFLAGS.split.include? "-rdynamic" or IS_DARWIN
14
- $CPPFLAGS += " -std=c++14"
15
- $CPPFLAGS += " -fpermissive"
16
- #$CPPFLAGS += " -DV8_COMPRESS_POINTERS"
17
- $CPPFLAGS += " -fvisibility=hidden "
18
-
19
- $CPPFLAGS += " -Wno-reserved-user-defined-literal" if IS_DARWIN
20
-
21
- $LDFLAGS.insert(0, " -stdlib=libc++ ") if IS_DARWIN
10
+ $CXXFLAGS += " -Wall" unless $CXXFLAGS.split.include? "-Wall"
11
+ $CXXFLAGS += " -g" unless $CXXFLAGS.split.include? "-g"
12
+ $CXXFLAGS += " -rdynamic" unless $CXXFLAGS.split.include? "-rdynamic"
13
+ $CXXFLAGS += " -fPIC" unless $CXXFLAGS.split.include? "-rdynamic" or IS_DARWIN
14
+ $CXXFLAGS += " -std=c++14"
15
+ $CXXFLAGS += " -fpermissive"
16
+ #$CXXFLAGS += " -DV8_COMPRESS_POINTERS"
17
+ $CXXFLAGS += " -fvisibility=hidden "
18
+
19
+ # __declspec gets used by clang via ruby 3.x headers...
20
+ $CXXFLAGS += " -fms-extensions"
21
+
22
+ $CXXFLAGS += " -Wno-reserved-user-defined-literal" if IS_DARWIN
23
+
24
+ if IS_DARWIN
25
+ $LDFLAGS.insert(0, " -stdlib=libc++ ")
26
+ else
27
+ $LDFLAGS.insert(0, " -lstdc++ ")
28
+ end
22
29
 
23
30
  # check for missing symbols at link time
24
31
  # $LDFLAGS += " -Wl,--no-undefined " unless IS_DARWIN
@@ -64,7 +71,7 @@ end
64
71
  Libv8::Node.configure_makefile
65
72
 
66
73
  if enable_config('asan')
67
- $CPPFLAGS.insert(0, " -fsanitize=address ")
74
+ $CXXFLAGS.insert(0, " -fsanitize=address ")
68
75
  $LDFLAGS.insert(0, " -fsanitize=address ")
69
76
  end
70
77
 
@@ -11,6 +11,7 @@
11
11
  #include <mutex>
12
12
  #include <atomic>
13
13
  #include <math.h>
14
+ #include <errno.h>
14
15
 
15
16
  using namespace v8;
16
17
 
@@ -299,6 +300,29 @@ static pthread_rwlock_t exit_lock = PTHREAD_RWLOCK_INITIALIZER;
299
300
  static bool ruby_exiting = false; // guarded by exit_lock
300
301
  static bool single_threaded = false;
301
302
 
303
+ static void mark_context(void *);
304
+ static void deallocate(void *);
305
+ static size_t context_memsize(const void *);
306
+ static const rb_data_type_t context_type = {
307
+ "mini_racer/context_info",
308
+ { mark_context, deallocate, context_memsize }
309
+ };
310
+
311
+ static void deallocate_snapshot(void *);
312
+ static size_t snapshot_memsize(const void *);
313
+ static const rb_data_type_t snapshot_type = {
314
+ "mini_racer/snapshot_info",
315
+ { NULL, deallocate_snapshot, snapshot_memsize }
316
+ };
317
+
318
+ static void mark_isolate(void *);
319
+ static void deallocate_isolate(void *);
320
+ static size_t isolate_memsize(const void *);
321
+ static const rb_data_type_t isolate_type = {
322
+ "mini_racer/isolate_info",
323
+ { mark_isolate, deallocate_isolate, isolate_memsize }
324
+ };
325
+
302
326
  static VALUE rb_platform_set_flag_as_str(VALUE _klass, VALUE flag_as_str) {
303
327
  bool platform_already_initialized = false;
304
328
 
@@ -453,7 +477,7 @@ static void prepare_result(MaybeLocal<Value> v8res,
453
477
  }
454
478
  }
455
479
 
456
- void*
480
+ static void*
457
481
  nogvl_context_eval(void* arg) {
458
482
 
459
483
  EvalParams* eval_params = (EvalParams*)arg;
@@ -786,6 +810,7 @@ create_snapshot_data_blob(const char *embedded_source = nullptr) {
786
810
  SnapshotCreator::FunctionCodeHandling::kClear);
787
811
  }
788
812
 
813
+ static
789
814
  StartupData warm_up_snapshot_data_blob(StartupData cold_snapshot_blob,
790
815
  const char *warmup_source) {
791
816
  // Use following steps to create a warmed up snapshot blob from a cold one:
@@ -821,14 +846,14 @@ StartupData warm_up_snapshot_data_blob(StartupData cold_snapshot_blob,
821
846
 
822
847
  static VALUE rb_snapshot_size(VALUE self, VALUE str) {
823
848
  SnapshotInfo* snapshot_info;
824
- Data_Get_Struct(self, SnapshotInfo, snapshot_info);
849
+ TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
825
850
 
826
851
  return INT2NUM(snapshot_info->raw_size);
827
852
  }
828
853
 
829
854
  static VALUE rb_snapshot_load(VALUE self, VALUE str) {
830
855
  SnapshotInfo* snapshot_info;
831
- Data_Get_Struct(self, SnapshotInfo, snapshot_info);
856
+ TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
832
857
 
833
858
  if(TYPE(str) != T_STRING) {
834
859
  rb_raise(rb_eArgError, "wrong type argument %" PRIsVALUE " (should be a string)",
@@ -851,14 +876,14 @@ static VALUE rb_snapshot_load(VALUE self, VALUE str) {
851
876
 
852
877
  static VALUE rb_snapshot_dump(VALUE self, VALUE str) {
853
878
  SnapshotInfo* snapshot_info;
854
- Data_Get_Struct(self, SnapshotInfo, snapshot_info);
879
+ TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
855
880
 
856
881
  return rb_str_new(snapshot_info->data, snapshot_info->raw_size);
857
882
  }
858
883
 
859
884
  static VALUE rb_snapshot_warmup_unsafe(VALUE self, VALUE str) {
860
885
  SnapshotInfo* snapshot_info;
861
- Data_Get_Struct(self, SnapshotInfo, snapshot_info);
886
+ TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
862
887
 
863
888
  if(TYPE(str) != T_STRING) {
864
889
  rb_raise(rb_eArgError, "wrong type argument %" PRIsVALUE " (should be a string)",
@@ -905,13 +930,13 @@ void IsolateInfo::init(SnapshotInfo* snapshot_info) {
905
930
 
906
931
  static VALUE rb_isolate_init_with_snapshot(VALUE self, VALUE snapshot) {
907
932
  IsolateInfo* isolate_info;
908
- Data_Get_Struct(self, IsolateInfo, isolate_info);
933
+ TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
909
934
 
910
935
  init_v8();
911
936
 
912
937
  SnapshotInfo* snapshot_info = nullptr;
913
938
  if (!NIL_P(snapshot)) {
914
- Data_Get_Struct(snapshot, SnapshotInfo, snapshot_info);
939
+ TypedData_Get_Struct(snapshot, SnapshotInfo, &snapshot_type, snapshot_info);
915
940
  }
916
941
 
917
942
  isolate_info->init(snapshot_info);
@@ -922,7 +947,7 @@ static VALUE rb_isolate_init_with_snapshot(VALUE self, VALUE snapshot) {
922
947
 
923
948
  static VALUE rb_isolate_idle_notification(VALUE self, VALUE idle_time_in_ms) {
924
949
  IsolateInfo* isolate_info;
925
- Data_Get_Struct(self, IsolateInfo, isolate_info);
950
+ TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
926
951
 
927
952
  if (current_platform == NULL) return Qfalse;
928
953
 
@@ -933,7 +958,7 @@ static VALUE rb_isolate_idle_notification(VALUE self, VALUE idle_time_in_ms) {
933
958
 
934
959
  static VALUE rb_isolate_low_memory_notification(VALUE self) {
935
960
  IsolateInfo* isolate_info;
936
- Data_Get_Struct(self, IsolateInfo, isolate_info);
961
+ TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
937
962
 
938
963
  if (current_platform == NULL) return Qfalse;
939
964
 
@@ -943,7 +968,7 @@ static VALUE rb_isolate_low_memory_notification(VALUE self) {
943
968
 
944
969
  static VALUE rb_isolate_pump_message_loop(VALUE self) {
945
970
  IsolateInfo* isolate_info;
946
- Data_Get_Struct(self, IsolateInfo, isolate_info);
971
+ TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
947
972
 
948
973
  if (current_platform == NULL) return Qfalse;
949
974
 
@@ -956,7 +981,7 @@ static VALUE rb_isolate_pump_message_loop(VALUE self) {
956
981
 
957
982
  static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
958
983
  ContextInfo* context_info;
959
- Data_Get_Struct(self, ContextInfo, context_info);
984
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
960
985
 
961
986
  init_v8();
962
987
 
@@ -967,11 +992,11 @@ static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
967
992
 
968
993
  SnapshotInfo *snapshot_info = nullptr;
969
994
  if (!NIL_P(snap) && rb_obj_is_kind_of(snap, rb_cSnapshot)) {
970
- Data_Get_Struct(snap, SnapshotInfo, snapshot_info);
995
+ TypedData_Get_Struct(snap, SnapshotInfo, &snapshot_type, snapshot_info);
971
996
  }
972
997
  isolate_info->init(snapshot_info);
973
998
  } else { // given isolate or snapshot
974
- Data_Get_Struct(isolate, IsolateInfo, isolate_info);
999
+ TypedData_Get_Struct(isolate, IsolateInfo, &isolate_type, isolate_info);
975
1000
  }
976
1001
 
977
1002
  context_info->isolate_info = isolate_info;
@@ -1001,7 +1026,7 @@ static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
1001
1026
  static VALUE convert_result_to_ruby(VALUE self /* context */,
1002
1027
  EvalResult& result) {
1003
1028
  ContextInfo *context_info;
1004
- Data_Get_Struct(self, ContextInfo, context_info);
1029
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1005
1030
 
1006
1031
  Isolate *isolate = context_info->isolate_info->isolate;
1007
1032
  Persistent<Context> *p_ctx = context_info->context;
@@ -1102,7 +1127,7 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str, VALUE filename) {
1102
1127
  EvalResult eval_result;
1103
1128
  ContextInfo* context_info;
1104
1129
 
1105
- Data_Get_Struct(self, ContextInfo, context_info);
1130
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1106
1131
  Isolate* isolate = context_info->isolate_info->isolate;
1107
1132
 
1108
1133
  if(TYPE(str) != T_STRING) {
@@ -1190,7 +1215,7 @@ VALUE rescue_callback(VALUE rdata, VALUE exception) {
1190
1215
  return exception;
1191
1216
  }
1192
1217
 
1193
- void*
1218
+ static void*
1194
1219
  gvl_ruby_callback(void* data) {
1195
1220
 
1196
1221
  FunctionCallbackInfo<Value>* args = (FunctionCallbackInfo<Value>*)data;
@@ -1206,7 +1231,7 @@ gvl_ruby_callback(void* data) {
1206
1231
  HandleScope scope(args->GetIsolate());
1207
1232
  Local<External> external = Local<External>::Cast(args->Data());
1208
1233
 
1209
- self = *(VALUE*)(external->Value());
1234
+ self = (VALUE)(external->Value());
1210
1235
  callback = rb_iv_get(self, "@callback");
1211
1236
 
1212
1237
  parent = rb_iv_get(self, "@parent");
@@ -1214,7 +1239,7 @@ gvl_ruby_callback(void* data) {
1214
1239
  return NULL;
1215
1240
  }
1216
1241
 
1217
- Data_Get_Struct(parent, ContextInfo, context_info);
1242
+ TypedData_Get_Struct(parent, ContextInfo, &context_type, context_info);
1218
1243
 
1219
1244
  if (length > 0) {
1220
1245
  ruby_args = rb_ary_tmp_new(length);
@@ -1243,7 +1268,6 @@ gvl_ruby_callback(void* data) {
1243
1268
  args->GetIsolate()->TerminateExecution();
1244
1269
  if (length > 0) {
1245
1270
  rb_ary_clear(ruby_args);
1246
- rb_gc_force_recycle(ruby_args);
1247
1271
  }
1248
1272
  return NULL;
1249
1273
  }
@@ -1251,8 +1275,8 @@ gvl_ruby_callback(void* data) {
1251
1275
  VALUE callback_data_value = (VALUE)&callback_data;
1252
1276
 
1253
1277
  // TODO: use rb_vrescue2 in Ruby 2.7 and above
1254
- result = rb_rescue2(RUBY_METHOD_FUNC(protected_callback), callback_data_value,
1255
- RUBY_METHOD_FUNC(rescue_callback), callback_data_value, rb_eException, (VALUE)0);
1278
+ result = rb_rescue2(protected_callback, callback_data_value,
1279
+ rescue_callback, callback_data_value, rb_eException, (VALUE)0);
1256
1280
 
1257
1281
  if(callback_data.failed) {
1258
1282
  rb_iv_set(parent, "@current_exception", result);
@@ -1266,7 +1290,6 @@ gvl_ruby_callback(void* data) {
1266
1290
 
1267
1291
  if (length > 0) {
1268
1292
  rb_ary_clear(ruby_args);
1269
- rb_gc_force_recycle(ruby_args);
1270
1293
  }
1271
1294
 
1272
1295
  if (IsolateData::Get(args->GetIsolate(), IsolateData::DO_TERMINATE)) {
@@ -1301,7 +1324,7 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1301
1324
  bool parse_error = false;
1302
1325
  bool attach_error = false;
1303
1326
 
1304
- Data_Get_Struct(parent, ContextInfo, context_info);
1327
+ TypedData_Get_Struct(parent, ContextInfo, &context_type, context_info);
1305
1328
  Isolate* isolate = context_info->isolate_info->isolate;
1306
1329
 
1307
1330
  {
@@ -1317,12 +1340,9 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1317
1340
  NewStringType::kNormal, (int)RSTRING_LEN(name))
1318
1341
  .ToLocalChecked();
1319
1342
 
1320
- // copy self so we can access from v8 external
1321
- VALUE* self_copy;
1322
- Data_Get_Struct(self, VALUE, self_copy);
1323
- *self_copy = self;
1324
-
1325
- Local<Value> external = External::New(isolate, self_copy);
1343
+ // Note that self (rb_cExternalFunction) is a pure Ruby T_OBJECT,
1344
+ // not a T_DATA type like most other classes in this file
1345
+ Local<Value> external = External::New(isolate, (void *)self);
1326
1346
 
1327
1347
  if (parent_object == Qnil) {
1328
1348
  Maybe<bool> success = context->Global()->Set(
@@ -1379,7 +1399,7 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1379
1399
 
1380
1400
  static VALUE rb_context_isolate_mutex(VALUE self) {
1381
1401
  ContextInfo* context_info;
1382
- Data_Get_Struct(self, ContextInfo, context_info);
1402
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1383
1403
 
1384
1404
  if (!context_info->isolate_info) {
1385
1405
  rb_raise(rb_eScriptRuntimeError, "Context has no Isolate available anymore");
@@ -1489,6 +1509,11 @@ static void mark_isolate(void* data) {
1489
1509
  isolate_info->mark();
1490
1510
  }
1491
1511
 
1512
+ static size_t isolate_memsize(const void *ptr) {
1513
+ const IsolateInfo *isolate_info = (const IsolateInfo *)ptr;
1514
+ return sizeof(*isolate_info);
1515
+ }
1516
+
1492
1517
  static void deallocate(void* data) {
1493
1518
  ContextInfo* context_info = (ContextInfo*)data;
1494
1519
 
@@ -1497,6 +1522,11 @@ static void deallocate(void* data) {
1497
1522
  xfree(data);
1498
1523
  }
1499
1524
 
1525
+ static size_t context_memsize(const void *ptr)
1526
+ {
1527
+ return sizeof(ContextInfo);
1528
+ }
1529
+
1500
1530
  static void mark_context(void* data) {
1501
1531
  ContextInfo* context_info = (ContextInfo*)data;
1502
1532
  if (context_info->isolate_info) {
@@ -1504,48 +1534,39 @@ static void mark_context(void* data) {
1504
1534
  }
1505
1535
  }
1506
1536
 
1507
- static void deallocate_external_function(void * data) {
1508
- xfree(data);
1509
- }
1510
-
1511
1537
  static void deallocate_snapshot(void * data) {
1512
1538
  SnapshotInfo* snapshot_info = (SnapshotInfo*)data;
1513
1539
  delete[] snapshot_info->data;
1514
1540
  xfree(snapshot_info);
1515
1541
  }
1516
1542
 
1517
- static VALUE allocate_external_function(VALUE klass) {
1518
- VALUE* self = ALLOC(VALUE);
1519
- return Data_Wrap_Struct(klass, NULL, deallocate_external_function, (void*)self);
1543
+ static size_t snapshot_memsize(const void *data) {
1544
+ SnapshotInfo* snapshot_info = (SnapshotInfo*)data;
1545
+ return sizeof(*snapshot_info) + snapshot_info->raw_size;
1520
1546
  }
1521
1547
 
1522
1548
  static VALUE allocate(VALUE klass) {
1523
- ContextInfo* context_info = ALLOC(ContextInfo);
1524
- context_info->isolate_info = NULL;
1525
- context_info->context = NULL;
1526
-
1527
- return Data_Wrap_Struct(klass, mark_context, deallocate, (void*)context_info);
1549
+ ContextInfo* context_info;
1550
+ return TypedData_Make_Struct(klass, ContextInfo, &context_type, context_info);
1528
1551
  }
1529
1552
 
1530
1553
  static VALUE allocate_snapshot(VALUE klass) {
1531
- SnapshotInfo* snapshot_info = ALLOC(SnapshotInfo);
1532
- snapshot_info->data = NULL;
1533
- snapshot_info->raw_size = 0;
1554
+ SnapshotInfo* snapshot_info;
1534
1555
 
1535
- return Data_Wrap_Struct(klass, NULL, deallocate_snapshot, (void*)snapshot_info);
1556
+ return TypedData_Make_Struct(klass, SnapshotInfo, &snapshot_type, snapshot_info);
1536
1557
  }
1537
1558
 
1538
1559
  static VALUE allocate_isolate(VALUE klass) {
1539
1560
  IsolateInfo* isolate_info = new IsolateInfo();
1540
1561
 
1541
- return Data_Wrap_Struct(klass, mark_isolate, deallocate_isolate, (void*)isolate_info);
1562
+ return TypedData_Wrap_Struct(klass, &isolate_type, isolate_info);
1542
1563
  }
1543
1564
 
1544
1565
  static VALUE
1545
1566
  rb_heap_stats(VALUE self) {
1546
1567
 
1547
1568
  ContextInfo* context_info;
1548
- Data_Get_Struct(self, ContextInfo, context_info);
1569
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1549
1570
  Isolate* isolate;
1550
1571
  v8::HeapStatistics stats;
1551
1572
 
@@ -1577,7 +1598,9 @@ rb_heap_stats(VALUE self) {
1577
1598
  // https://github.com/bnoordhuis/node-heapdump/blob/master/src/heapdump.cc
1578
1599
  class FileOutputStream : public OutputStream {
1579
1600
  public:
1580
- FileOutputStream(FILE* stream) : stream_(stream) {}
1601
+ int err;
1602
+
1603
+ FileOutputStream(int fd) : fd(fd) { err = 0; }
1581
1604
 
1582
1605
  virtual int GetChunkSize() {
1583
1606
  return 65536;
@@ -1586,17 +1609,27 @@ class FileOutputStream : public OutputStream {
1586
1609
  virtual void EndOfStream() {}
1587
1610
 
1588
1611
  virtual WriteResult WriteAsciiChunk(char* data, int size) {
1589
- const size_t len = static_cast<size_t>(size);
1590
- size_t off = 0;
1591
-
1592
- while (off < len && !feof(stream_) && !ferror(stream_))
1593
- off += fwrite(data + off, 1, len - off, stream_);
1594
-
1595
- return off == len ? kContinue : kAbort;
1612
+ size_t len = static_cast<size_t>(size);
1613
+
1614
+ while (len) {
1615
+ ssize_t w = write(fd, data, len);
1616
+
1617
+ if (w > 0) {
1618
+ data += w;
1619
+ len -= w;
1620
+ } else if (w < 0) {
1621
+ err = errno;
1622
+ return kAbort;
1623
+ } else { /* w == 0, could be out-of-space */
1624
+ err = -1;
1625
+ return kAbort;
1626
+ }
1627
+ }
1628
+ return kContinue;
1596
1629
  }
1597
1630
 
1598
1631
  private:
1599
- FILE* stream_;
1632
+ int fd;
1600
1633
  };
1601
1634
 
1602
1635
 
@@ -1609,13 +1642,11 @@ rb_heap_snapshot(VALUE self, VALUE file) {
1609
1642
 
1610
1643
  if (!fptr) return Qfalse;
1611
1644
 
1612
- FILE* fp;
1613
- fp = fdopen(fptr->fd, "w");
1614
- if (fp == NULL) return Qfalse;
1615
-
1645
+ // prepare for unbuffered write(2) below:
1646
+ rb_funcall(file, rb_intern("flush"), 0);
1616
1647
 
1617
1648
  ContextInfo* context_info;
1618
- Data_Get_Struct(self, ContextInfo, context_info);
1649
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1619
1650
  Isolate* isolate;
1620
1651
  isolate = context_info->isolate_info ? context_info->isolate_info->isolate : NULL;
1621
1652
 
@@ -1629,13 +1660,14 @@ rb_heap_snapshot(VALUE self, VALUE file) {
1629
1660
 
1630
1661
  const HeapSnapshot* const snap = heap_profiler->TakeHeapSnapshot();
1631
1662
 
1632
- FileOutputStream stream(fp);
1663
+ FileOutputStream stream(fptr->fd);
1633
1664
  snap->Serialize(&stream, HeapSnapshot::kJSON);
1634
1665
 
1635
- fflush(fp);
1636
-
1637
1666
  const_cast<HeapSnapshot*>(snap)->Delete();
1638
1667
 
1668
+ /* TODO: perhaps rb_sys_fail here */
1669
+ if (stream.err) return Qfalse;
1670
+
1639
1671
  return Qtrue;
1640
1672
  }
1641
1673
 
@@ -1643,7 +1675,7 @@ static VALUE
1643
1675
  rb_context_stop(VALUE self) {
1644
1676
 
1645
1677
  ContextInfo* context_info;
1646
- Data_Get_Struct(self, ContextInfo, context_info);
1678
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1647
1679
 
1648
1680
  Isolate* isolate = context_info->isolate_info->isolate;
1649
1681
 
@@ -1660,7 +1692,7 @@ static VALUE
1660
1692
  rb_context_dispose(VALUE self) {
1661
1693
 
1662
1694
  ContextInfo* context_info;
1663
- Data_Get_Struct(self, ContextInfo, context_info);
1695
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1664
1696
 
1665
1697
  free_context(context_info);
1666
1698
 
@@ -1723,7 +1755,7 @@ static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
1723
1755
  FunctionCall call;
1724
1756
  VALUE *call_argv = NULL;
1725
1757
 
1726
- Data_Get_Struct(self, ContextInfo, context_info);
1758
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1727
1759
  Isolate* isolate = context_info->isolate_info->isolate;
1728
1760
 
1729
1761
  if (argc < 1) {
@@ -1813,7 +1845,7 @@ static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
1813
1845
 
1814
1846
  static VALUE rb_context_create_isolate_value(VALUE self) {
1815
1847
  ContextInfo* context_info;
1816
- Data_Get_Struct(self, ContextInfo, context_info);
1848
+ TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
1817
1849
  IsolateInfo *isolate_info = context_info->isolate_info;
1818
1850
 
1819
1851
  if (!isolate_info) {
@@ -1821,7 +1853,7 @@ static VALUE rb_context_create_isolate_value(VALUE self) {
1821
1853
  }
1822
1854
 
1823
1855
  isolate_info->hold();
1824
- return Data_Wrap_Struct(rb_cIsolate, NULL, &deallocate_isolate, isolate_info);
1856
+ return TypedData_Wrap_Struct(rb_cIsolate, &isolate_type, isolate_info);
1825
1857
  }
1826
1858
 
1827
1859
  static void set_ruby_exiting(VALUE value) {
@@ -1877,7 +1909,6 @@ extern "C" {
1877
1909
  rb_define_alloc_func(rb_cIsolate, allocate_isolate);
1878
1910
 
1879
1911
  rb_define_private_method(rb_cExternalFunction, "notify_v8", (VALUE(*)(...))&rb_external_function_notify_v8, 0);
1880
- rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
1881
1912
 
1882
1913
  rb_define_method(rb_cSnapshot, "size", (VALUE(*)(...))&rb_snapshot_size, 0);
1883
1914
  rb_define_method(rb_cSnapshot, "dump", (VALUE(*)(...))&rb_snapshot_dump, 0);
@@ -3,6 +3,6 @@ require 'mkmf'
3
3
  extension_name = 'mini_racer_loader'
4
4
  dir_config extension_name
5
5
 
6
- $CPPFLAGS += " -fvisibility=hidden "
6
+ $CXXFLAGS += " -fvisibility=hidden "
7
7
 
8
8
  create_makefile extension_name
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniRacer
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  LIBV8_NODE_VERSION = "~> 16.10.0.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_racer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-11 00:00:00.000000000 Z
11
+ date: 2021-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -128,10 +128,10 @@ licenses:
128
128
  - MIT
129
129
  metadata:
130
130
  bug_tracker_uri: https://github.com/discourse/mini_racer/issues
131
- changelog_uri: https://github.com/discourse/mini_racer/blob/v0.5.0/CHANGELOG
132
- documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.5.0
133
- source_code_uri: https://github.com/discourse/mini_racer/tree/v0.5.0
134
- post_install_message:
131
+ changelog_uri: https://github.com/discourse/mini_racer/blob/v0.6.0/CHANGELOG
132
+ documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.6.0
133
+ source_code_uri: https://github.com/discourse/mini_racer/tree/v0.6.0
134
+ post_install_message:
135
135
  rdoc_options: []
136
136
  require_paths:
137
137
  - lib
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  version: '0'
149
149
  requirements: []
150
150
  rubygems_version: 3.1.6
151
- signing_key:
151
+ signing_key:
152
152
  specification_version: 4
153
153
  summary: Minimal embedded v8 for Ruby
154
154
  test_files: []