mini_racer 0.2.14 → 0.3.1

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: d31e1517a2d52257af3ecd56079e6fcaed4a569ff2256fba4db7c92f922b6cbd
4
- data.tar.gz: 777208a006502e94f375e54f43541273b49ecdc7657ac004bec88515b1e620b7
3
+ metadata.gz: e370d4752aeb013f408e1df0b94521d25b81ea3fc576a53e28ecbe857bec7336
4
+ data.tar.gz: 5f8eae12d493d3c70ce07f32d41da6d847de31762d6d546e42d5148843112808
5
5
  SHA512:
6
- metadata.gz: c08eecc3edcc923625a8cd6cd87b4c88a4c4f80d64c9c4edee1f68897b595f5cf02927d1d3268f8bdb1d9e81b170c75dfe3875cc1c436fdeed11ebc40759b64c
7
- data.tar.gz: 3d82acdd3ec745bc2467e5429c849f1719bf3c711a454b588db9871b36770df64aa37947103eedc553846a04e0e754752d214c208f9f65a6eae1e35686f3068e
6
+ metadata.gz: 9a7f5d67e29902e7fec4f516ff1037bb8c62da2dbda8cfa8604c0d0c59f3a222e37776c7d42f7cfb17bead48dc201c95209c4bcdd7f5202b0ba6d98e5678a5a2
7
+ data.tar.gz: 77cef34527ace5fa77c4c4ef138809cddf1238c3388db845e595f614653feac7e8c77a378162f73bac35d9d84899a1f52c2265e27264a8368771e797e6d86189
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.4
4
3
  - 2.5
5
4
  - 2.6
6
5
  - 2.7
@@ -10,12 +9,6 @@ matrix:
10
9
  - rvm: 2.5.1
11
10
  os: osx
12
11
  osx_image: xcode9.4
13
- - rvm: 2.4.0
14
- os: osx
15
- osx_image: xcode8.3
16
- - rvm: 2.4.0
17
- os: osx
18
- osx_image: xcode7.3
19
12
  dist: trusty
20
13
  sudo: true
21
14
  before_install:
data/CHANGELOG CHANGED
@@ -1,3 +1,21 @@
1
+ - 23-07-202
2
+
3
+ - 0.3.1
4
+
5
+ - FIX: specify that libv8 must be larger than 8.4.255 but smaller than 8.5, this avoids issues going forward
6
+
7
+ - 22-07-2020
8
+
9
+ - 0.3.0
10
+
11
+ - FEATURE: upgraded to libv8 version 8.4.255.0
12
+
13
+ - 29-06-2020
14
+
15
+ - 0.2.15
16
+
17
+ - FEATURE: basic wasm support via pump_message_loop
18
+
1
19
  - 15-05-2020
2
20
 
3
21
  - 0.2.14
data/README.md CHANGED
@@ -315,6 +315,16 @@ context.eval("a = 2")
315
315
  # nothing works on the context from now on, its a shell waiting to be disposed
316
316
  ```
317
317
 
318
+ A MiniRacer context can also be dumped in a heapsnapshot file using `#write_heap_snapshot(file_or_io)`
319
+
320
+ ```ruby
321
+ context = MiniRacer::Context.new(timeout: 5)
322
+ context.eval("let a='testing';")
323
+ context.write_heap_snapshot("test.heapsnapshot")
324
+ ```
325
+
326
+ This file can then be loaded in the memory tab of the chrome dev console.
327
+
318
328
  ### Function call
319
329
 
320
330
  This calls the function passed as first argument:
@@ -11,6 +11,7 @@ $CPPFLAGS += " -rdynamic" unless $CPPFLAGS.split.include? "-rdynamic"
11
11
  $CPPFLAGS += " -fPIC" unless $CPPFLAGS.split.include? "-rdynamic" or IS_DARWIN
12
12
  $CPPFLAGS += " -std=c++0x"
13
13
  $CPPFLAGS += " -fpermissive"
14
+ $CPPFLAGS += " -DV8_COMPRESS_POINTERS"
14
15
 
15
16
  $CPPFLAGS += " -Wno-reserved-user-defined-literal" if IS_DARWIN
16
17
 
@@ -25,6 +25,7 @@ public:
25
25
  ArrayBuffer::Allocator* allocator;
26
26
  StartupData* startup_data;
27
27
  bool interrupted;
28
+ bool added_gc_cb;
28
29
  pid_t pid;
29
30
  VALUE mutex;
30
31
 
@@ -42,15 +43,12 @@ public:
42
43
 
43
44
 
44
45
  IsolateInfo() : isolate(nullptr), allocator(nullptr), startup_data(nullptr),
45
- interrupted(false), pid(getpid()), refs_count(0) {
46
+ interrupted(false), added_gc_cb(false), pid(getpid()), refs_count(0) {
46
47
  VALUE cMutex = rb_const_get(rb_cThread, rb_intern("Mutex"));
47
48
  mutex = rb_class_new_instance(0, nullptr, cMutex);
48
49
  }
49
50
 
50
- ~IsolateInfo() {
51
- void free_isolate(IsolateInfo*);
52
- free_isolate(this);
53
- }
51
+ ~IsolateInfo();
54
52
 
55
53
  void init(SnapshotInfo* snapshot_info = nullptr);
56
54
 
@@ -237,11 +235,13 @@ static void prepare_result(MaybeLocal v8res,
237
235
  Local<Value> local_value = v8res.ToLocalChecked();
238
236
  if ((local_value->IsObject() || local_value->IsArray()) &&
239
237
  !local_value->IsDate() && !local_value->IsFunction()) {
240
- Local<Object> JSON = context->Global()->Get(String::NewFromUtf8(isolate, "JSON"))
241
- ->ToObject(context).ToLocalChecked();
238
+ Local<Object> JSON = context->Global()->Get(
239
+ context, String::NewFromUtf8Literal(isolate, "JSON"))
240
+ .ToLocalChecked().As<Object>();
242
241
 
243
- Local<Function> stringify = JSON->Get(v8::String::NewFromUtf8(isolate, "stringify"))
244
- .As<Function>();
242
+ Local<Function> stringify = JSON->Get(
243
+ context, v8::String::NewFromUtf8Literal(isolate, "stringify"))
244
+ .ToLocalChecked().As<Function>();
245
245
 
246
246
  Local<Object> object = local_value->ToObject(context).ToLocalChecked();
247
247
  const unsigned argc = 1;
@@ -295,7 +295,7 @@ static void prepare_result(MaybeLocal v8res,
295
295
  } else if(trycatch.HasTerminated()) {
296
296
  evalRes.terminated = true;
297
297
  evalRes.message = new Persistent<Value>();
298
- Local<String> tmp = String::NewFromUtf8(isolate, "JavaScript was terminated (either by timeout or explicitly)");
298
+ Local<String> tmp = String::NewFromUtf8Literal(isolate, "JavaScript was terminated (either by timeout or explicitly)");
299
299
  evalRes.message->Reset(isolate, tmp);
300
300
  }
301
301
  if (!trycatch.StackTrace(context).IsEmpty()) {
@@ -312,7 +312,8 @@ nogvl_context_eval(void* arg) {
312
312
 
313
313
  EvalParams* eval_params = (EvalParams*)arg;
314
314
  EvalResult* result = eval_params->result;
315
- Isolate* isolate = eval_params->context_info->isolate_info->isolate;
315
+ IsolateInfo* isolate_info = eval_params->context_info->isolate_info;
316
+ Isolate* isolate = isolate_info->isolate;
316
317
 
317
318
  Isolate::Scope isolate_scope(isolate);
318
319
  HandleScope handle_scope(isolate);
@@ -356,7 +357,10 @@ nogvl_context_eval(void* arg) {
356
357
  // parsing successful
357
358
  if (eval_params->max_memory > 0) {
358
359
  isolate->SetData(MEM_SOFTLIMIT_VALUE, &eval_params->max_memory);
360
+ if (!isolate_info->added_gc_cb) {
359
361
  isolate->AddGCEpilogueCallback(gc_callback);
362
+ isolate_info->added_gc_cb = true;
363
+ }
360
364
  }
361
365
 
362
366
  maybe_value = parsed_script.ToLocalChecked()->Run(context);
@@ -369,6 +373,12 @@ nogvl_context_eval(void* arg) {
369
373
  return NULL;
370
374
  }
371
375
 
376
+ static VALUE new_empty_failed_conv_obj() {
377
+ // TODO isolate code that translates execption to ruby
378
+ // exception so we can properly return it
379
+ return rb_funcall(rb_cFailedV8Conversion, rb_intern("new"), 1, rb_str_new2(""));
380
+ }
381
+
372
382
  // assumes isolate locking is in place
373
383
  static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
374
384
  Local<Value> value) {
@@ -400,8 +410,11 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local context,
400
410
  VALUE rb_array = rb_ary_new();
401
411
  Local<Array> arr = Local<Array>::Cast(value);
402
412
  for(uint32_t i=0; i < arr->Length(); i++) {
403
- Local<Value> element = arr->Get(i);
404
- VALUE rb_elem = convert_v8_to_ruby(isolate, context, element);
413
+ MaybeLocal<Value> element = arr->Get(context, i);
414
+ if (element.IsEmpty()) {
415
+ continue;
416
+ }
417
+ VALUE rb_elem = convert_v8_to_ruby(isolate, context, element.ToLocalChecked());
405
418
  if (rb_funcall(rb_elem, rb_intern("class"), 0) == rb_cFailedV8Conversion) {
406
419
  return rb_elem;
407
420
  }
@@ -431,18 +444,20 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local context,
431
444
  if (!maybe_props.IsEmpty()) {
432
445
  Local<Array> props = maybe_props.ToLocalChecked();
433
446
  for(uint32_t i=0; i < props->Length(); i++) {
434
- Local<Value> key = props->Get(i);
435
- VALUE rb_key = convert_v8_to_ruby(isolate, context, key);
436
- Local<Value> prop_value = object->Get(key);
437
- // this may have failed due to Get raising
447
+ MaybeLocal<Value> key = props->Get(context, i);
448
+ if (key.IsEmpty()) {
449
+ return rb_funcall(rb_cFailedV8Conversion, rb_intern("new"), 1, rb_str_new2(""));
450
+ }
451
+ VALUE rb_key = convert_v8_to_ruby(isolate, context, key.ToLocalChecked());
438
452
 
439
- if (trycatch.HasCaught()) {
440
- // TODO isolate code that translates execption to ruby
441
- // exception so we can properly return it
442
- return rb_funcall(rb_cFailedV8Conversion, rb_intern("new"), 1, rb_str_new2(""));
453
+ MaybeLocal<Value> prop_value = object->Get(context, key.ToLocalChecked());
454
+ // this may have failed due to Get raising
455
+ if (prop_value.IsEmpty() || trycatch.HasCaught()) {
456
+ return new_empty_failed_conv_obj();
443
457
  }
444
458
 
445
- VALUE rb_value = convert_v8_to_ruby(isolate, context, prop_value);
459
+ VALUE rb_value = convert_v8_to_ruby(
460
+ isolate, context, prop_value.ToLocalChecked());
446
461
  rb_hash_aset(rb_hash, rb_key, rb_value);
447
462
  }
448
463
  }
@@ -524,7 +539,7 @@ static Local convert_ruby_to_v8(Isolate* isolate, Local context,
524
539
  length = RARRAY_LEN(value);
525
540
  array = Array::New(isolate, (int)length);
526
541
  for(i=0; i<length; i++) {
527
- array->Set(i, convert_ruby_to_v8(isolate, context, rb_ary_entry(value, i)));
542
+ array->Set(context, i, convert_ruby_to_v8(isolate, context, rb_ary_entry(value, i)));
528
543
  }
529
544
  return scope.Escape(array);
530
545
  case T_HASH:
@@ -533,7 +548,7 @@ static Local convert_ruby_to_v8(Isolate* isolate, Local context,
533
548
  length = RARRAY_LEN(hash_as_array);
534
549
  for(i=0; i<length; i++) {
535
550
  pair = rb_ary_entry(hash_as_array, i);
536
- object->Set(convert_ruby_to_v8(isolate, context, rb_ary_entry(pair, 0)),
551
+ object->Set(context, convert_ruby_to_v8(isolate, context, rb_ary_entry(pair, 0)),
537
552
  convert_ruby_to_v8(isolate, context, rb_ary_entry(pair, 1)));
538
553
  }
539
554
  return scope.Escape(object);
@@ -563,9 +578,9 @@ static Local convert_ruby_to_v8(Isolate* isolate, Local context,
563
578
  case T_UNDEF:
564
579
  case T_NODE:
565
580
  default:
566
- return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
581
+ return scope.Escape(String::NewFromUtf8Literal(isolate, "Undefined Conversion"));
582
+ }
567
583
  }
568
- }
569
584
 
570
585
  static void unblock_eval(void *ptr) {
571
586
  EvalParams* eval = (EvalParams*)ptr;
@@ -576,53 +591,43 @@ static void unblock_eval(void *ptr) {
576
591
  * The implementations of the run_extra_code(), create_snapshot_data_blob() and
577
592
  * warm_up_snapshot_data_blob() functions have been derived from V8's test suite.
578
593
  */
579
- bool run_extra_code(Isolate *isolate, Local<v8::Context> context,
594
+ static bool run_extra_code(Isolate *isolate, Local<v8::Context> context,
580
595
  const char *utf8_source, const char *name) {
581
596
  Context::Scope context_scope(context);
582
597
  TryCatch try_catch(isolate);
583
598
  Local<String> source_string;
584
- if (!String::NewFromUtf8(isolate, utf8_source,
585
- NewStringType::kNormal)
586
- .ToLocal(&source_string)) {
599
+ if (!String::NewFromUtf8(isolate, utf8_source).ToLocal(&source_string)) {
587
600
  return false;
588
601
  }
589
- Local<v8::String> resource_name =
590
- String::NewFromUtf8(isolate, name, NewStringType::kNormal)
591
- .ToLocalChecked();
602
+ Local<String> resource_name =
603
+ String::NewFromUtf8(isolate, name).ToLocalChecked();
592
604
  ScriptOrigin origin(resource_name);
593
605
  ScriptCompiler::Source source(source_string, origin);
594
606
  Local<Script> script;
595
607
  if (!ScriptCompiler::Compile(context, &source).ToLocal(&script))
596
608
  return false;
597
- if (script->Run(context).IsEmpty())
598
- return false;
599
- // CHECK(!try_catch.HasCaught());
609
+ if (script->Run(context).IsEmpty()) return false;
600
610
  return true;
601
611
  }
602
612
 
603
- StartupData
613
+ static StartupData
604
614
  create_snapshot_data_blob(const char *embedded_source = nullptr) {
605
- // Create a new isolate and a new context from scratch, optionally run
606
- // a script to embed, and serialize to create a snapshot blob.
607
- StartupData result = {nullptr, 0};
608
- {
609
- SnapshotCreator snapshot_creator;
610
- Isolate *isolate = snapshot_creator.GetIsolate();
615
+ Isolate *isolate = Isolate::Allocate();
616
+
617
+ // Optionally run a script to embed, and serialize to create a snapshot blob.
618
+ SnapshotCreator snapshot_creator(isolate);
611
619
  {
612
620
  HandleScope scope(isolate);
613
- Local<Context> context = Context::New(isolate);
621
+ Local<v8::Context> context = v8::Context::New(isolate);
614
622
  if (embedded_source != nullptr &&
615
- !run_extra_code(isolate, context, embedded_source,
616
- "<embedded>")) {
617
- return result;
623
+ !run_extra_code(isolate, context, embedded_source, "<embedded>")) {
624
+ return {};
618
625
  }
619
626
  snapshot_creator.SetDefaultContext(context);
620
627
  }
621
- result = snapshot_creator.CreateBlob(
628
+ return snapshot_creator.CreateBlob(
622
629
  SnapshotCreator::FunctionCodeHandling::kClear);
623
630
  }
624
- return result;
625
- }
626
631
 
627
632
  StartupData warm_up_snapshot_data_blob(StartupData cold_snapshot_blob,
628
633
  const char *warmup_source) {
@@ -779,6 +784,19 @@ static VALUE rb_isolate_low_memory_notification(VALUE self) {
779
784
  return Qnil;
780
785
  }
781
786
 
787
+ static VALUE rb_isolate_pump_message_loop(VALUE self) {
788
+ IsolateInfo* isolate_info;
789
+ Data_Get_Struct(self, IsolateInfo, isolate_info);
790
+
791
+ if (current_platform == NULL) return Qfalse;
792
+
793
+ if (platform::PumpMessageLoop(current_platform.get(), isolate_info->isolate)){
794
+ return Qtrue;
795
+ } else {
796
+ return Qfalse;
797
+ }
798
+ }
799
+
782
800
  static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
783
801
  ContextInfo* context_info;
784
802
  Data_Get_Struct(self, ContextInfo, context_info);
@@ -1049,7 +1067,9 @@ gvl_ruby_callback(void* data) {
1049
1067
  callback_data.failed = false;
1050
1068
 
1051
1069
  if ((bool)args->GetIsolate()->GetData(DO_TERMINATE) == true) {
1052
- args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Terminated execution during transition from Ruby to JS"));
1070
+ args->GetIsolate()->ThrowException(
1071
+ String::NewFromUtf8Literal(args->GetIsolate(),
1072
+ "Terminated execution during transition from Ruby to JS"));
1053
1073
  args->GetIsolate()->TerminateExecution();
1054
1074
  if (length > 0) {
1055
1075
  rb_ary_clear(ruby_args);
@@ -1063,7 +1083,7 @@ gvl_ruby_callback(void* data) {
1063
1083
 
1064
1084
  if(callback_data.failed) {
1065
1085
  rb_iv_set(parent, "@current_exception", result);
1066
- args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Ruby exception"));
1086
+ args->GetIsolate()->ThrowException(String::NewFromUtf8Literal(args->GetIsolate(), "Ruby exception"));
1067
1087
  }
1068
1088
  else {
1069
1089
  HandleScope scope(args->GetIsolate());
@@ -1134,7 +1154,9 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1134
1154
 
1135
1155
  if (parent_object == Qnil) {
1136
1156
  context->Global()->Set(
1137
- v8_str, FunctionTemplate::New(isolate, ruby_callback, external)
1157
+ context,
1158
+ v8_str,
1159
+ FunctionTemplate::New(isolate, ruby_callback, external)
1138
1160
  ->GetFunction(context)
1139
1161
  .ToLocalChecked());
1140
1162
 
@@ -1147,7 +1169,7 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1147
1169
 
1148
1170
  MaybeLocal<Script> parsed_script = Script::Compile(context, eval);
1149
1171
  if (parsed_script.IsEmpty()) {
1150
- parse_error = true;
1172
+ parse_error = true;
1151
1173
  } else {
1152
1174
  MaybeLocal<Value> maybe_value =
1153
1175
  parsed_script.ToLocalChecked()->Run(context);
@@ -1157,11 +1179,12 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1157
1179
  Local<Value> value = maybe_value.ToLocalChecked();
1158
1180
  if (value->IsObject()) {
1159
1181
  value.As<Object>()->Set(
1160
- v8_str, FunctionTemplate::New(
1161
- isolate, ruby_callback, external)
1182
+ context,
1183
+ v8_str,
1184
+ FunctionTemplate::New(isolate, ruby_callback, external)
1162
1185
  ->GetFunction(context)
1163
1186
  .ToLocalChecked());
1164
- attach_error = false;
1187
+ attach_error = false;
1165
1188
  }
1166
1189
  }
1167
1190
  }
@@ -1191,32 +1214,31 @@ static VALUE rb_context_isolate_mutex(VALUE self) {
1191
1214
  return context_info->isolate_info->mutex;
1192
1215
  }
1193
1216
 
1194
- void free_isolate(IsolateInfo* isolate_info) {
1195
-
1196
- if (isolate_info->isolate) {
1197
- Locker lock(isolate_info->isolate);
1198
- }
1199
-
1200
- if (isolate_info->isolate) {
1201
- if (isolate_info->interrupted) {
1202
- fprintf(stderr, "WARNING: V8 isolate was interrupted by Ruby, it can not be disposed and memory will not be reclaimed till the Ruby process exits.\n");
1217
+ IsolateInfo::~IsolateInfo() {
1218
+ if (isolate) {
1219
+ if (this->interrupted) {
1220
+ fprintf(stderr, "WARNING: V8 isolate was interrupted by Ruby, "
1221
+ "it can not be disposed and memory will not be "
1222
+ "reclaimed till the Ruby process exits.\n");
1203
1223
  } else {
1204
-
1205
- if (isolate_info->pid != getpid()) {
1206
- fprintf(stderr, "WARNING: V8 isolate was forked, it can not be disposed and memory will not be reclaimed till the Ruby process exits.\n");
1224
+ if (this->pid != getpid()) {
1225
+ fprintf(stderr, "WARNING: V8 isolate was forked, "
1226
+ "it can not be disposed and "
1227
+ "memory will not be reclaimed "
1228
+ "till the Ruby process exits.\n");
1207
1229
  } else {
1208
- isolate_info->isolate->Dispose();
1230
+ isolate->Dispose();
1209
1231
  }
1210
1232
  }
1211
- isolate_info->isolate = NULL;
1233
+ isolate = nullptr;
1212
1234
  }
1213
1235
 
1214
- if (isolate_info->startup_data) {
1215
- delete[] isolate_info->startup_data->data;
1216
- delete isolate_info->startup_data;
1236
+ if (startup_data) {
1237
+ delete[] startup_data->data;
1238
+ delete startup_data;
1217
1239
  }
1218
1240
 
1219
- delete isolate_info->allocator;
1241
+ delete allocator;
1220
1242
  }
1221
1243
 
1222
1244
  static void free_context_raw(void *arg) {
@@ -1288,7 +1310,7 @@ static void mark_isolate(void* data) {
1288
1310
  isolate_info->mark();
1289
1311
  }
1290
1312
 
1291
- void deallocate(void* data) {
1313
+ static void deallocate(void* data) {
1292
1314
  ContextInfo* context_info = (ContextInfo*)data;
1293
1315
 
1294
1316
  free_context(context_info);
@@ -1303,22 +1325,22 @@ static void mark_context(void* data) {
1303
1325
  }
1304
1326
  }
1305
1327
 
1306
- void deallocate_external_function(void * data) {
1328
+ static void deallocate_external_function(void * data) {
1307
1329
  xfree(data);
1308
1330
  }
1309
1331
 
1310
- void deallocate_snapshot(void * data) {
1332
+ static void deallocate_snapshot(void * data) {
1311
1333
  SnapshotInfo* snapshot_info = (SnapshotInfo*)data;
1312
1334
  delete[] snapshot_info->data;
1313
1335
  xfree(snapshot_info);
1314
1336
  }
1315
1337
 
1316
- VALUE allocate_external_function(VALUE klass) {
1338
+ static VALUE allocate_external_function(VALUE klass) {
1317
1339
  VALUE* self = ALLOC(VALUE);
1318
1340
  return Data_Wrap_Struct(klass, NULL, deallocate_external_function, (void*)self);
1319
1341
  }
1320
1342
 
1321
- VALUE allocate(VALUE klass) {
1343
+ static VALUE allocate(VALUE klass) {
1322
1344
  ContextInfo* context_info = ALLOC(ContextInfo);
1323
1345
  context_info->isolate_info = NULL;
1324
1346
  context_info->context = NULL;
@@ -1326,7 +1348,7 @@ VALUE allocate(VALUE klass) {
1326
1348
  return Data_Wrap_Struct(klass, mark_context, deallocate, (void*)context_info);
1327
1349
  }
1328
1350
 
1329
- VALUE allocate_snapshot(VALUE klass) {
1351
+ static VALUE allocate_snapshot(VALUE klass) {
1330
1352
  SnapshotInfo* snapshot_info = ALLOC(SnapshotInfo);
1331
1353
  snapshot_info->data = NULL;
1332
1354
  snapshot_info->raw_size = 0;
@@ -1334,7 +1356,7 @@ VALUE allocate_snapshot(VALUE klass) {
1334
1356
  return Data_Wrap_Struct(klass, NULL, deallocate_snapshot, (void*)snapshot_info);
1335
1357
  }
1336
1358
 
1337
- VALUE allocate_isolate(VALUE klass) {
1359
+ static VALUE allocate_isolate(VALUE klass) {
1338
1360
  IsolateInfo* isolate_info = new IsolateInfo();
1339
1361
 
1340
1362
  return Data_Wrap_Struct(klass, mark_isolate, deallocate_isolate, (void*)isolate_info);
@@ -1473,7 +1495,8 @@ nogvl_context_call(void *args) {
1473
1495
  if (!call) {
1474
1496
  return NULL;
1475
1497
  }
1476
- Isolate* isolate = call->context_info->isolate_info->isolate;
1498
+ IsolateInfo *isolate_info = call->context_info->isolate_info;
1499
+ Isolate* isolate = isolate_info->isolate;
1477
1500
 
1478
1501
  // in gvl flag
1479
1502
  isolate->SetData(IN_GVL, (void*)false);
@@ -1483,7 +1506,10 @@ nogvl_context_call(void *args) {
1483
1506
  if (call->max_memory > 0) {
1484
1507
  isolate->SetData(MEM_SOFTLIMIT_VALUE, &call->max_memory);
1485
1508
  isolate->SetData(MEM_SOFTLIMIT_REACHED, (void*)false);
1509
+ if (!isolate_info->added_gc_cb) {
1486
1510
  isolate->AddGCEpilogueCallback(gc_callback);
1511
+ isolate_info->added_gc_cb = true;
1512
+ }
1487
1513
  }
1488
1514
 
1489
1515
  Isolate::Scope isolate_scope(isolate);
@@ -1561,8 +1587,11 @@ static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
1561
1587
 
1562
1588
  // examples of such usage can be found in
1563
1589
  // https://github.com/v8/v8/blob/36b32aa28db5e993312f4588d60aad5c8330c8a5/test/cctest/test-api.cc#L15711
1564
- Local<String> fname = String::NewFromUtf8(isolate, call.function_name);
1565
- MaybeLocal<v8::Value> val = context->Global()->Get(fname);
1590
+ MaybeLocal<String> fname = String::NewFromUtf8(isolate, call.function_name);
1591
+ MaybeLocal<v8::Value> val;
1592
+ if (!fname.IsEmpty()) {
1593
+ val = context->Global()->Get(context, fname.ToLocalChecked());
1594
+ }
1566
1595
 
1567
1596
  if (val.IsEmpty() || !val.ToLocalChecked()->IsFunction()) {
1568
1597
  missingFunction = true;
@@ -1668,7 +1697,7 @@ extern "C" {
1668
1697
 
1669
1698
  rb_define_method(rb_cIsolate, "idle_notification", (VALUE(*)(...))&rb_isolate_idle_notification, 1);
1670
1699
  rb_define_method(rb_cIsolate, "low_memory_notification", (VALUE(*)(...))&rb_isolate_low_memory_notification, 0);
1671
-
1700
+ rb_define_method(rb_cIsolate, "pump_message_loop", (VALUE(*)(...))&rb_isolate_pump_message_loop, 0);
1672
1701
  rb_define_private_method(rb_cIsolate, "init_with_snapshot",(VALUE(*)(...))&rb_isolate_init_with_snapshot, 1);
1673
1702
 
1674
1703
  rb_define_singleton_method(rb_cPlatform, "set_flag_as_str!", (VALUE(*)(...))&rb_platform_set_flag_as_str, 1);
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniRacer
4
- VERSION = "0.2.14"
4
+ VERSION = "0.3.1"
5
5
  end
@@ -30,8 +30,9 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "rake", ">= 12.3.3"
31
31
  spec.add_development_dependency "minitest", "~> 5.0"
32
32
  spec.add_development_dependency "rake-compiler"
33
+ spec.add_development_dependency "m"
33
34
 
34
- spec.add_dependency 'libv8', '> 7.3'
35
+ spec.add_dependency 'libv8', '~> 8.4.255'
35
36
  spec.require_paths = ["lib", "ext"]
36
37
 
37
38
  spec.extensions = ["ext/mini_racer_extension/extconf.rb"]
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.2.14
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-15 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,20 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: m
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: libv8
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">"
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '7.3'
89
+ version: 8.4.255
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">"
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '7.3'
96
+ version: 8.4.255
83
97
  description: Minimal embedded v8 engine for Ruby
84
98
  email:
85
99
  - sam.saffron@gmail.com
@@ -108,10 +122,10 @@ licenses:
108
122
  - MIT
109
123
  metadata:
110
124
  bug_tracker_uri: https://github.com/discourse/mini_racer/issues
111
- changelog_uri: https://github.com/discourse/mini_racer/blob/v0.2.14/CHANGELOG
112
- documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.2.14
113
- source_code_uri: https://github.com/discourse/mini_racer/tree/v0.2.14
114
- post_install_message:
125
+ changelog_uri: https://github.com/discourse/mini_racer/blob/v0.3.1/CHANGELOG
126
+ documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.3.1
127
+ source_code_uri: https://github.com/discourse/mini_racer/tree/v0.3.1
128
+ post_install_message:
115
129
  rdoc_options: []
116
130
  require_paths:
117
131
  - lib
@@ -128,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
142
  version: '0'
129
143
  requirements: []
130
144
  rubygems_version: 3.0.3
131
- signing_key:
145
+ signing_key:
132
146
  specification_version: 4
133
147
  summary: Minimal embedded v8 for Ruby
134
148
  test_files: []