mini_racer 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []