mini_racer 0.2.4 → 0.2.5
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 +4 -4
- data/CHANGELOG +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +4 -0
- data/ext/mini_racer_extension/mini_racer_extension.cc +367 -276
- data/lib/mini_racer/version.rb +1 -1
- data/mini_racer.gemspec +2 -2
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33363eb77714da62e0920f19b096785488a5f425866918e1942a8062cb5fe233
|
4
|
+
data.tar.gz: 1aba90413863460047822b072d92c261f6bc5927918409cf19f8f36ecf97d5e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d9acc921de43092d13c1edfc37a2fd753b0d572b2979d38185b0ea76b4527092d9569329479df8a21561589fe57acbcc6db8087948914bed2dde7178c9cfa2a
|
7
|
+
data.tar.gz: 537161ead4afdb14675b4593eea7f0e714d424c8a31bb2fc32960d3c8500a495b3d98f76280018df7a2d6072cdc8d038d791908b63ccd571e0c5757bb3ebc698
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
- 25-04-2019
|
2
|
+
|
3
|
+
- 0.2.5
|
4
|
+
|
5
|
+
- FIX: Compatiblity fixes for V8 7 and above @ignisf
|
6
|
+
- FIX: Memory leak in gc_callback @messense
|
7
|
+
- IMPROVEMENT: Added example of sourcemap support @ianks
|
8
|
+
- URGENT: you will need this release for latest version of libv8 to work
|
9
|
+
|
1
10
|
- 02-11-2018
|
2
11
|
|
3
12
|
- 0.2.4
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2016
|
3
|
+
Copyright (c) 2016-2019, the mini_racer project authors.
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -346,6 +346,10 @@ Note how the global interpreter lock release leads to 2 threads doing the same w
|
|
346
346
|
|
347
347
|
As a rule MiniRacer strives to always support and depend on the latest stable version of libv8.
|
348
348
|
|
349
|
+
## Source Maps
|
350
|
+
|
351
|
+
MiniRacer can fully support source maps but must be configured correctly to do so. [Check out this example](./examples/source-map-support/) for a working implementation.
|
352
|
+
|
349
353
|
## Installation
|
350
354
|
|
351
355
|
Add this line to your application's Gemfile:
|
@@ -71,7 +71,7 @@ public:
|
|
71
71
|
}
|
72
72
|
|
73
73
|
int refs() {
|
74
|
-
|
74
|
+
return refs_count;
|
75
75
|
}
|
76
76
|
|
77
77
|
static void* operator new(size_t size) {
|
@@ -200,9 +200,9 @@ static void gc_callback(Isolate *isolate, GCType type, GCCallbackFlags flags) {
|
|
200
200
|
|
201
201
|
size_t softlimit = *(size_t*) isolate->GetData(MEM_SOFTLIMIT_VALUE);
|
202
202
|
|
203
|
-
HeapStatistics
|
204
|
-
isolate->GetHeapStatistics(stats);
|
205
|
-
size_t used = stats
|
203
|
+
HeapStatistics stats;
|
204
|
+
isolate->GetHeapStatistics(&stats);
|
205
|
+
size_t used = stats.used_heap_size();
|
206
206
|
|
207
207
|
if(used > softlimit) {
|
208
208
|
isolate->SetData(MEM_SOFTLIMIT_REACHED, (void*)true);
|
@@ -230,13 +230,13 @@ static void prepare_result(MaybeLocal<Value> v8res,
|
|
230
230
|
Local<Value> local_value = v8res.ToLocalChecked();
|
231
231
|
if ((local_value->IsObject() || local_value->IsArray()) &&
|
232
232
|
!local_value->IsDate() && !local_value->IsFunction()) {
|
233
|
-
Local<Object> JSON = context->Global()->Get(
|
234
|
-
|
233
|
+
Local<Object> JSON = context->Global()->Get(String::NewFromUtf8(isolate, "JSON"))
|
234
|
+
->ToObject(context).ToLocalChecked();
|
235
235
|
|
236
236
|
Local<Function> stringify = JSON->Get(v8::String::NewFromUtf8(isolate, "stringify"))
|
237
237
|
.As<Function>();
|
238
238
|
|
239
|
-
Local<Object> object = local_value->ToObject();
|
239
|
+
Local<Object> object = local_value->ToObject(context).ToLocalChecked();
|
240
240
|
const unsigned argc = 1;
|
241
241
|
Local<Value> argv[argc] = { object };
|
242
242
|
MaybeLocal<Value> json = stringify->Call(JSON, argc, argv);
|
@@ -263,11 +263,21 @@ static void prepare_result(MaybeLocal<Value> v8res,
|
|
263
263
|
evalRes.message = new Persistent<Value>();
|
264
264
|
Local<Message> message = trycatch.Message();
|
265
265
|
char buf[1000];
|
266
|
-
int len;
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
266
|
+
int len, line, column;
|
267
|
+
|
268
|
+
if (!message->GetLineNumber(context).To(&line)) {
|
269
|
+
line = 0;
|
270
|
+
}
|
271
|
+
|
272
|
+
if (!message->GetStartColumn(context).To(&column)) {
|
273
|
+
column = 0;
|
274
|
+
}
|
275
|
+
|
276
|
+
len = snprintf(buf, sizeof(buf), "%s at %s:%i:%i", *String::Utf8Value(isolate, message->Get()),
|
277
|
+
*String::Utf8Value(isolate, message->GetScriptResourceName()->ToString(context).ToLocalChecked()),
|
278
|
+
line,
|
279
|
+
column);
|
280
|
+
|
271
281
|
if ((size_t) len >= sizeof(buf)) {
|
272
282
|
len = sizeof(buf) - 1;
|
273
283
|
buf[len] = '\0';
|
@@ -281,9 +291,10 @@ static void prepare_result(MaybeLocal<Value> v8res,
|
|
281
291
|
Local<String> tmp = String::NewFromUtf8(isolate, "JavaScript was terminated (either by timeout or explicitly)");
|
282
292
|
evalRes.message->Reset(isolate, tmp);
|
283
293
|
}
|
284
|
-
if (!trycatch.StackTrace().IsEmpty()) {
|
294
|
+
if (!trycatch.StackTrace(context).IsEmpty()) {
|
285
295
|
evalRes.backtrace = new Persistent<Value>();
|
286
|
-
evalRes.backtrace->Reset(isolate,
|
296
|
+
evalRes.backtrace->Reset(isolate,
|
297
|
+
trycatch.StackTrace(context).ToLocalChecked()->ToString(context).ToLocalChecked());
|
287
298
|
}
|
288
299
|
}
|
289
300
|
}
|
@@ -315,13 +326,13 @@ nogvl_context_eval(void* arg) {
|
|
315
326
|
MaybeLocal<Script> parsed_script;
|
316
327
|
|
317
328
|
if (eval_params->filename) {
|
318
|
-
|
329
|
+
origin = new v8::ScriptOrigin(*eval_params->filename);
|
319
330
|
}
|
320
331
|
|
321
332
|
parsed_script = Script::Compile(context, *eval_params->eval, origin);
|
322
333
|
|
323
334
|
if (origin) {
|
324
|
-
|
335
|
+
delete origin;
|
325
336
|
}
|
326
337
|
|
327
338
|
result->parsed = !parsed_script.IsEmpty();
|
@@ -332,8 +343,8 @@ nogvl_context_eval(void* arg) {
|
|
332
343
|
|
333
344
|
MaybeLocal<Value> maybe_value;
|
334
345
|
if (!result->parsed) {
|
335
|
-
|
336
|
-
|
346
|
+
result->message = new Persistent<Value>();
|
347
|
+
result->message->Reset(isolate, trycatch.Exception());
|
337
348
|
} else {
|
338
349
|
// parsing successful
|
339
350
|
if (eval_params->max_memory > 0) {
|
@@ -359,41 +370,41 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
|
|
359
370
|
HandleScope scope(isolate);
|
360
371
|
|
361
372
|
if (value->IsNull() || value->IsUndefined()){
|
362
|
-
|
373
|
+
return Qnil;
|
363
374
|
}
|
364
375
|
|
365
376
|
if (value->IsInt32()) {
|
366
|
-
|
377
|
+
return INT2FIX(value->Int32Value(context).ToChecked());
|
367
378
|
}
|
368
379
|
|
369
380
|
if (value->IsNumber()) {
|
370
|
-
|
381
|
+
return rb_float_new(value->NumberValue(context).ToChecked());
|
371
382
|
}
|
372
383
|
|
373
384
|
if (value->IsTrue()) {
|
374
|
-
|
385
|
+
return Qtrue;
|
375
386
|
}
|
376
387
|
|
377
388
|
if (value->IsFalse()) {
|
378
|
-
|
389
|
+
return Qfalse;
|
379
390
|
}
|
380
391
|
|
381
392
|
if (value->IsArray()) {
|
382
393
|
VALUE rb_array = rb_ary_new();
|
383
394
|
Local<Array> arr = Local<Array>::Cast(value);
|
384
395
|
for(uint32_t i=0; i < arr->Length(); i++) {
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
396
|
+
Local<Value> element = arr->Get(i);
|
397
|
+
VALUE rb_elem = convert_v8_to_ruby(isolate, context, element);
|
398
|
+
if (rb_funcall(rb_elem, rb_intern("class"), 0) == rb_cFailedV8Conversion) {
|
399
|
+
return rb_elem;
|
400
|
+
}
|
390
401
|
rb_ary_push(rb_array, rb_elem);
|
391
402
|
}
|
392
403
|
return rb_array;
|
393
404
|
}
|
394
405
|
|
395
406
|
if (value->IsFunction()){
|
396
|
-
|
407
|
+
return rb_funcall(rb_cJavaScriptFunction, rb_intern("new"), 0);
|
397
408
|
}
|
398
409
|
|
399
410
|
if (value->IsDate()){
|
@@ -405,34 +416,34 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
|
|
405
416
|
}
|
406
417
|
|
407
418
|
if (value->IsObject()) {
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
419
|
+
VALUE rb_hash = rb_hash_new();
|
420
|
+
TryCatch trycatch(isolate);
|
421
|
+
|
422
|
+
Local<Object> object = value->ToObject(context).ToLocalChecked();
|
423
|
+
auto maybe_props = object->GetOwnPropertyNames(context);
|
424
|
+
if (!maybe_props.IsEmpty()) {
|
425
|
+
Local<Array> props = maybe_props.ToLocalChecked();
|
426
|
+
for(uint32_t i=0; i < props->Length(); i++) {
|
427
|
+
Local<Value> key = props->Get(i);
|
428
|
+
VALUE rb_key = convert_v8_to_ruby(isolate, context, key);
|
429
|
+
Local<Value> prop_value = object->Get(key);
|
430
|
+
// this may have failed due to Get raising
|
431
|
+
|
432
|
+
if (trycatch.HasCaught()) {
|
433
|
+
// TODO isolate code that translates execption to ruby
|
434
|
+
// exception so we can properly return it
|
435
|
+
return rb_funcall(rb_cFailedV8Conversion, rb_intern("new"), 1, rb_str_new2(""));
|
436
|
+
}
|
437
|
+
|
438
|
+
VALUE rb_value = convert_v8_to_ruby(isolate, context, prop_value);
|
439
|
+
rb_hash_aset(rb_hash, rb_key, rb_value);
|
440
|
+
}
|
441
|
+
}
|
442
|
+
return rb_hash;
|
432
443
|
}
|
433
444
|
|
434
|
-
Local<String> rstr = value->ToString();
|
435
|
-
return rb_enc_str_new(*String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
445
|
+
Local<String> rstr = value->ToString(context).ToLocalChecked();
|
446
|
+
return rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(isolate), rb_enc_find("utf-8"));
|
436
447
|
}
|
437
448
|
|
438
449
|
static VALUE convert_v8_to_ruby(Isolate* isolate,
|
@@ -453,7 +464,7 @@ static VALUE convert_v8_to_ruby(Isolate* isolate,
|
|
453
464
|
Local<Value>::New(isolate, value));
|
454
465
|
}
|
455
466
|
|
456
|
-
static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
467
|
+
static Local<Value> convert_ruby_to_v8(Isolate* isolate, Local<Context> context, VALUE value) {
|
457
468
|
EscapableHandleScope scope(isolate);
|
458
469
|
|
459
470
|
Local<Array> array;
|
@@ -487,7 +498,7 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|
487
498
|
length = RARRAY_LEN(value);
|
488
499
|
array = Array::New(isolate, (int)length);
|
489
500
|
for(i=0; i<length; i++) {
|
490
|
-
|
501
|
+
array->Set(i, convert_ruby_to_v8(isolate, context, rb_ary_entry(value, i)));
|
491
502
|
}
|
492
503
|
return scope.Escape(array);
|
493
504
|
case T_HASH:
|
@@ -496,8 +507,8 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|
496
507
|
length = RARRAY_LEN(hash_as_array);
|
497
508
|
for(i=0; i<length; i++) {
|
498
509
|
pair = rb_ary_entry(hash_as_array, i);
|
499
|
-
object->Set(convert_ruby_to_v8(isolate, rb_ary_entry(pair, 0)),
|
500
|
-
|
510
|
+
object->Set(convert_ruby_to_v8(isolate, context, rb_ary_entry(pair, 0)),
|
511
|
+
convert_ruby_to_v8(isolate, context, rb_ary_entry(pair, 1)));
|
501
512
|
}
|
502
513
|
return scope.Escape(object);
|
503
514
|
case T_SYMBOL:
|
@@ -512,7 +523,7 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|
512
523
|
value = rb_funcall(value, rb_intern("to_time"), 0);
|
513
524
|
}
|
514
525
|
value = rb_funcall(value, rb_intern("to_f"), 0);
|
515
|
-
return scope.Escape(Date::New(
|
526
|
+
return scope.Escape(Date::New(context, NUM2DBL(value) * 1000).ToLocalChecked());
|
516
527
|
}
|
517
528
|
case T_OBJECT:
|
518
529
|
case T_CLASS:
|
@@ -528,7 +539,6 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|
528
539
|
default:
|
529
540
|
return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
|
530
541
|
}
|
531
|
-
|
532
542
|
}
|
533
543
|
|
534
544
|
static void unblock_eval(void *ptr) {
|
@@ -536,6 +546,91 @@ static void unblock_eval(void *ptr) {
|
|
536
546
|
eval->context_info->isolate_info->interrupted = true;
|
537
547
|
}
|
538
548
|
|
549
|
+
/*
|
550
|
+
* The implementations of the run_extra_code(), create_snapshot_data_blob() and
|
551
|
+
* warm_up_snapshot_data_blob() functions have been derived from V8's test suite.
|
552
|
+
*/
|
553
|
+
bool run_extra_code(Isolate *isolate, Local<v8::Context> context,
|
554
|
+
const char *utf8_source, const char *name) {
|
555
|
+
Context::Scope context_scope(context);
|
556
|
+
TryCatch try_catch(isolate);
|
557
|
+
Local<String> source_string;
|
558
|
+
if (!String::NewFromUtf8(isolate, utf8_source,
|
559
|
+
NewStringType::kNormal)
|
560
|
+
.ToLocal(&source_string)) {
|
561
|
+
return false;
|
562
|
+
}
|
563
|
+
Local<v8::String> resource_name =
|
564
|
+
String::NewFromUtf8(isolate, name, NewStringType::kNormal)
|
565
|
+
.ToLocalChecked();
|
566
|
+
ScriptOrigin origin(resource_name);
|
567
|
+
ScriptCompiler::Source source(source_string, origin);
|
568
|
+
Local<Script> script;
|
569
|
+
if (!ScriptCompiler::Compile(context, &source).ToLocal(&script))
|
570
|
+
return false;
|
571
|
+
if (script->Run(context).IsEmpty())
|
572
|
+
return false;
|
573
|
+
// CHECK(!try_catch.HasCaught());
|
574
|
+
return true;
|
575
|
+
}
|
576
|
+
|
577
|
+
StartupData
|
578
|
+
create_snapshot_data_blob(const char *embedded_source = nullptr) {
|
579
|
+
// Create a new isolate and a new context from scratch, optionally run
|
580
|
+
// a script to embed, and serialize to create a snapshot blob.
|
581
|
+
StartupData result = {nullptr, 0};
|
582
|
+
{
|
583
|
+
SnapshotCreator snapshot_creator;
|
584
|
+
Isolate *isolate = snapshot_creator.GetIsolate();
|
585
|
+
{
|
586
|
+
HandleScope scope(isolate);
|
587
|
+
Local<Context> context = Context::New(isolate);
|
588
|
+
if (embedded_source != nullptr &&
|
589
|
+
!run_extra_code(isolate, context, embedded_source,
|
590
|
+
"<embedded>")) {
|
591
|
+
return result;
|
592
|
+
}
|
593
|
+
snapshot_creator.SetDefaultContext(context);
|
594
|
+
}
|
595
|
+
result = snapshot_creator.CreateBlob(
|
596
|
+
SnapshotCreator::FunctionCodeHandling::kClear);
|
597
|
+
}
|
598
|
+
return result;
|
599
|
+
}
|
600
|
+
|
601
|
+
StartupData warm_up_snapshot_data_blob(StartupData cold_snapshot_blob,
|
602
|
+
const char *warmup_source) {
|
603
|
+
// Use following steps to create a warmed up snapshot blob from a cold one:
|
604
|
+
// - Create a new isolate from the cold snapshot.
|
605
|
+
// - Create a new context to run the warmup script. This will trigger
|
606
|
+
// compilation of executed functions.
|
607
|
+
// - Create a new context. This context will be unpolluted.
|
608
|
+
// - Serialize the isolate and the second context into a new snapshot blob.
|
609
|
+
StartupData result = {nullptr, 0};
|
610
|
+
|
611
|
+
if (cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != nullptr &&
|
612
|
+
warmup_source != NULL) {
|
613
|
+
SnapshotCreator snapshot_creator(nullptr, &cold_snapshot_blob);
|
614
|
+
Isolate *isolate = snapshot_creator.GetIsolate();
|
615
|
+
{
|
616
|
+
HandleScope scope(isolate);
|
617
|
+
Local<Context> context = Context::New(isolate);
|
618
|
+
if (!run_extra_code(isolate, context, warmup_source, "<warm-up>")) {
|
619
|
+
return result;
|
620
|
+
}
|
621
|
+
}
|
622
|
+
{
|
623
|
+
HandleScope handle_scope(isolate);
|
624
|
+
isolate->ContextDisposedNotification(false);
|
625
|
+
Local<Context> context = Context::New(isolate);
|
626
|
+
snapshot_creator.SetDefaultContext(context);
|
627
|
+
}
|
628
|
+
result = snapshot_creator.CreateBlob(
|
629
|
+
SnapshotCreator::FunctionCodeHandling::kKeep);
|
630
|
+
}
|
631
|
+
return result;
|
632
|
+
}
|
633
|
+
|
539
634
|
static VALUE rb_snapshot_size(VALUE self, VALUE str) {
|
540
635
|
SnapshotInfo* snapshot_info;
|
541
636
|
Data_Get_Struct(self, SnapshotInfo, snapshot_info);
|
@@ -554,7 +649,7 @@ static VALUE rb_snapshot_load(VALUE self, VALUE str) {
|
|
554
649
|
|
555
650
|
init_v8();
|
556
651
|
|
557
|
-
StartupData startup_data =
|
652
|
+
StartupData startup_data = create_snapshot_data_blob(RSTRING_PTR(str));
|
558
653
|
|
559
654
|
if (startup_data.data == NULL && startup_data.raw_size == 0) {
|
560
655
|
rb_raise(rb_eSnapshotError, "Could not create snapshot, most likely the source is incorrect");
|
@@ -585,7 +680,7 @@ static VALUE rb_snapshot_warmup_unsafe(VALUE self, VALUE str) {
|
|
585
680
|
init_v8();
|
586
681
|
|
587
682
|
StartupData cold_startup_data = {snapshot_info->data, snapshot_info->raw_size};
|
588
|
-
StartupData warm_startup_data =
|
683
|
+
StartupData warm_startup_data = warm_up_snapshot_data_blob(cold_startup_data, RSTRING_PTR(str));
|
589
684
|
|
590
685
|
if (warm_startup_data.data == NULL && warm_startup_data.raw_size == 0) {
|
591
686
|
rb_raise(rb_eSnapshotError, "Could not warm up snapshot, most likely the source is incorrect");
|
@@ -675,13 +770,13 @@ static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
|
|
675
770
|
// the ruby lock is needed if this isn't a new isolate
|
676
771
|
IsolateInfo::Lock ruby_lock(isolate_info->mutex);
|
677
772
|
Locker lock(isolate_info->isolate);
|
678
|
-
|
679
|
-
|
773
|
+
Isolate::Scope isolate_scope(isolate_info->isolate);
|
774
|
+
HandleScope handle_scope(isolate_info->isolate);
|
680
775
|
|
681
|
-
|
776
|
+
Local<Context> context = Context::New(isolate_info->isolate);
|
682
777
|
|
683
|
-
|
684
|
-
|
778
|
+
context_info->context = new Persistent<Context>();
|
779
|
+
context_info->context->Reset(isolate_info->isolate, context);
|
685
780
|
}
|
686
781
|
|
687
782
|
if (Qnil == rb_cDateTime && rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, rb_str_new2("DateTime")) == Qtrue)
|
@@ -764,8 +859,8 @@ static VALUE convert_result_to_ruby(VALUE self /* context */,
|
|
764
859
|
Local<Value> tmp = Local<Value>::New(isolate, *result.value);
|
765
860
|
|
766
861
|
if (result.json) {
|
767
|
-
Local<String> rstr = tmp->ToString();
|
768
|
-
VALUE json_string = rb_enc_str_new(*String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
862
|
+
Local<String> rstr = tmp->ToString(p_ctx->Get(isolate)).ToLocalChecked();
|
863
|
+
VALUE json_string = rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(isolate), rb_enc_find("utf-8"));
|
769
864
|
ret = rb_funcall(rb_mJSON, rb_intern("parse"), 1, json_string);
|
770
865
|
} else {
|
771
866
|
ret = convert_v8_to_ruby(isolate, *p_ctx, tmp);
|
@@ -803,42 +898,42 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str, VALUE filename) {
|
|
803
898
|
}
|
804
899
|
|
805
900
|
{
|
806
|
-
|
807
|
-
|
808
|
-
|
901
|
+
Locker lock(isolate);
|
902
|
+
Isolate::Scope isolate_scope(isolate);
|
903
|
+
HandleScope handle_scope(isolate);
|
809
904
|
|
810
|
-
|
811
|
-
|
905
|
+
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(str),
|
906
|
+
NewStringType::kNormal, (int)RSTRING_LEN(str)).ToLocalChecked();
|
812
907
|
|
813
|
-
|
908
|
+
Local<String> local_filename;
|
814
909
|
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
910
|
+
if (filename != Qnil) {
|
911
|
+
local_filename = String::NewFromUtf8(isolate, RSTRING_PTR(filename),
|
912
|
+
NewStringType::kNormal, (int)RSTRING_LEN(filename)).ToLocalChecked();
|
913
|
+
eval_params.filename = &local_filename;
|
914
|
+
} else {
|
915
|
+
eval_params.filename = NULL;
|
916
|
+
}
|
822
917
|
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
918
|
+
eval_params.context_info = context_info;
|
919
|
+
eval_params.eval = &eval;
|
920
|
+
eval_params.result = &eval_result;
|
921
|
+
eval_params.timeout = 0;
|
922
|
+
eval_params.max_memory = 0;
|
923
|
+
VALUE timeout = rb_iv_get(self, "@timeout");
|
924
|
+
if (timeout != Qnil) {
|
925
|
+
eval_params.timeout = (useconds_t)NUM2LONG(timeout);
|
926
|
+
}
|
832
927
|
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
928
|
+
VALUE mem_softlimit = rb_iv_get(self, "@max_memory");
|
929
|
+
if (mem_softlimit != Qnil) {
|
930
|
+
eval_params.max_memory = (size_t)NUM2ULONG(mem_softlimit);
|
931
|
+
}
|
837
932
|
|
838
|
-
|
839
|
-
|
933
|
+
eval_result.message = NULL;
|
934
|
+
eval_result.backtrace = NULL;
|
840
935
|
|
841
|
-
|
936
|
+
rb_thread_call_without_gvl(nogvl_context_eval, &eval_params, unblock_eval, &eval_params);
|
842
937
|
}
|
843
938
|
|
844
939
|
return convert_result_to_ruby(self, eval_result);
|
@@ -851,17 +946,16 @@ typedef struct {
|
|
851
946
|
bool failed;
|
852
947
|
} protected_callback_data;
|
853
948
|
|
854
|
-
static
|
855
|
-
VALUE protected_callback(VALUE rdata) {
|
949
|
+
static VALUE protected_callback(VALUE rdata) {
|
856
950
|
protected_callback_data* data = (protected_callback_data*)rdata;
|
857
951
|
VALUE result;
|
858
952
|
|
859
953
|
if (data->length > 0) {
|
860
|
-
|
861
|
-
|
862
|
-
|
954
|
+
result = rb_funcall2(data->callback, rb_intern("call"), data->length,
|
955
|
+
RARRAY_PTR(data->ruby_args));
|
956
|
+
RB_GC_GUARD(data->ruby_args);
|
863
957
|
} else {
|
864
|
-
|
958
|
+
result = rb_funcall(data->callback, rb_intern("call"), 0);
|
865
959
|
}
|
866
960
|
return result;
|
867
961
|
}
|
@@ -883,6 +977,8 @@ gvl_ruby_callback(void* data) {
|
|
883
977
|
VALUE result;
|
884
978
|
VALUE self;
|
885
979
|
VALUE parent;
|
980
|
+
ContextInfo* context_info;
|
981
|
+
|
886
982
|
{
|
887
983
|
HandleScope scope(args->GetIsolate());
|
888
984
|
Local<External> external = Local<External>::Cast(args->Data());
|
@@ -895,19 +991,18 @@ gvl_ruby_callback(void* data) {
|
|
895
991
|
return NULL;
|
896
992
|
}
|
897
993
|
|
898
|
-
ContextInfo* context_info;
|
899
994
|
Data_Get_Struct(parent, ContextInfo, context_info);
|
900
995
|
|
901
|
-
|
902
|
-
|
903
|
-
|
996
|
+
if (length > 0) {
|
997
|
+
ruby_args = rb_ary_tmp_new(length);
|
998
|
+
}
|
904
999
|
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
1000
|
+
for (int i = 0; i < length; i++) {
|
1001
|
+
Local<Value> value = ((*args)[i]).As<Value>();
|
1002
|
+
VALUE tmp = convert_v8_to_ruby(args->GetIsolate(),
|
1003
|
+
*context_info->context, value);
|
1004
|
+
rb_ary_push(ruby_args, tmp);
|
1005
|
+
}
|
911
1006
|
}
|
912
1007
|
|
913
1008
|
// may raise exception stay clear of handle scope
|
@@ -918,31 +1013,31 @@ gvl_ruby_callback(void* data) {
|
|
918
1013
|
callback_data.failed = false;
|
919
1014
|
|
920
1015
|
if ((bool)args->GetIsolate()->GetData(DO_TERMINATE) == true) {
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
1016
|
+
args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Terminated execution during transition from Ruby to JS"));
|
1017
|
+
args->GetIsolate()->TerminateExecution();
|
1018
|
+
if (length > 0) {
|
1019
|
+
rb_ary_clear(ruby_args);
|
1020
|
+
rb_gc_force_recycle(ruby_args);
|
1021
|
+
}
|
1022
|
+
return NULL;
|
928
1023
|
}
|
929
1024
|
|
930
1025
|
result = rb_rescue2((VALUE(*)(...))&protected_callback, (VALUE)(&callback_data),
|
931
|
-
|
1026
|
+
(VALUE(*)(...))&rescue_callback, (VALUE)(&callback_data), rb_eException, (VALUE)0);
|
932
1027
|
|
933
1028
|
if(callback_data.failed) {
|
934
|
-
|
935
|
-
|
1029
|
+
rb_iv_set(parent, "@current_exception", result);
|
1030
|
+
args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Ruby exception"));
|
936
1031
|
}
|
937
1032
|
else {
|
938
|
-
|
939
|
-
|
940
|
-
|
1033
|
+
HandleScope scope(args->GetIsolate());
|
1034
|
+
Handle<Value> v8_result = convert_ruby_to_v8(args->GetIsolate(), context_info->context->Get(args->GetIsolate()), result);
|
1035
|
+
args->GetReturnValue().Set(v8_result);
|
941
1036
|
}
|
942
1037
|
|
943
1038
|
if (length > 0) {
|
944
|
-
|
945
|
-
|
1039
|
+
rb_ary_clear(ruby_args);
|
1040
|
+
rb_gc_force_recycle(ruby_args);
|
946
1041
|
}
|
947
1042
|
|
948
1043
|
if ((bool)args->GetIsolate()->GetData(DO_TERMINATE) == true) {
|
@@ -957,11 +1052,11 @@ static void ruby_callback(const FunctionCallbackInfo<Value>& args) {
|
|
957
1052
|
bool has_gvl = (bool)args.GetIsolate()->GetData(IN_GVL);
|
958
1053
|
|
959
1054
|
if(has_gvl) {
|
960
|
-
|
1055
|
+
gvl_ruby_callback((void*)&args);
|
961
1056
|
} else {
|
962
|
-
|
963
|
-
|
964
|
-
|
1057
|
+
args.GetIsolate()->SetData(IN_GVL, (void*)true);
|
1058
|
+
rb_thread_call_with_gvl(gvl_ruby_callback, (void*)(&args));
|
1059
|
+
args.GetIsolate()->SetData(IN_GVL, (void*)false);
|
965
1060
|
}
|
966
1061
|
}
|
967
1062
|
|
@@ -982,55 +1077,55 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
982
1077
|
Isolate* isolate = context_info->isolate_info->isolate;
|
983
1078
|
|
984
1079
|
{
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1080
|
+
Locker lock(isolate);
|
1081
|
+
Isolate::Scope isolate_scope(isolate);
|
1082
|
+
HandleScope handle_scope(isolate);
|
1083
|
+
|
1084
|
+
Local<Context> context = context_info->context->Get(isolate);
|
1085
|
+
Context::Scope context_scope(context);
|
1086
|
+
|
1087
|
+
Local<String> v8_str = String::NewFromUtf8(isolate, RSTRING_PTR(name),
|
1088
|
+
NewStringType::kNormal, (int)RSTRING_LEN(name)).ToLocalChecked();
|
1089
|
+
|
1090
|
+
// copy self so we can access from v8 external
|
1091
|
+
VALUE* self_copy;
|
1092
|
+
Data_Get_Struct(self, VALUE, self_copy);
|
1093
|
+
*self_copy = self;
|
1094
|
+
|
1095
|
+
Local<Value> external = External::New(isolate, self_copy);
|
1096
|
+
|
1097
|
+
if (parent_object == Qnil) {
|
1098
|
+
context->Global()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1099
|
+
} else {
|
1100
|
+
|
1101
|
+
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(parent_object_eval),
|
1102
|
+
NewStringType::kNormal, (int)RSTRING_LEN(parent_object_eval)).ToLocalChecked();
|
1103
|
+
|
1104
|
+
MaybeLocal<Script> parsed_script = Script::Compile(context, eval);
|
1105
|
+
if (parsed_script.IsEmpty()) {
|
1106
|
+
parse_error = true;
|
1107
|
+
} else {
|
1108
|
+
MaybeLocal<Value> maybe_value = parsed_script.ToLocalChecked()->Run(context);
|
1109
|
+
attach_error = true;
|
1110
|
+
|
1111
|
+
if (!maybe_value.IsEmpty()) {
|
1112
|
+
Local<Value> value = maybe_value.ToLocalChecked();
|
1113
|
+
if (value->IsObject()){
|
1114
|
+
value.As<Object>()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1115
|
+
attach_error = false;
|
1116
|
+
}
|
1117
|
+
}
|
1118
|
+
}
|
1119
|
+
}
|
1025
1120
|
}
|
1026
1121
|
|
1027
1122
|
// always raise out of V8 context
|
1028
1123
|
if (parse_error) {
|
1029
|
-
|
1124
|
+
rb_raise(rb_eParseError, "Invalid object %" PRIsVALUE, parent_object);
|
1030
1125
|
}
|
1031
1126
|
|
1032
1127
|
if (attach_error) {
|
1033
|
-
|
1128
|
+
rb_raise(rb_eParseError, "Was expecting %" PRIsVALUE" to be an object", parent_object);
|
1034
1129
|
}
|
1035
1130
|
|
1036
1131
|
return Qnil;
|
@@ -1050,19 +1145,19 @@ static VALUE rb_context_isolate_mutex(VALUE self) {
|
|
1050
1145
|
void free_isolate(IsolateInfo* isolate_info) {
|
1051
1146
|
|
1052
1147
|
if (isolate_info->isolate) {
|
1053
|
-
|
1148
|
+
Locker lock(isolate_info->isolate);
|
1054
1149
|
}
|
1055
1150
|
|
1056
1151
|
if (isolate_info->isolate) {
|
1057
1152
|
if (isolate_info->interrupted) {
|
1058
1153
|
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");
|
1059
1154
|
} else {
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1155
|
+
|
1156
|
+
if (isolate_info->pid != getpid()) {
|
1157
|
+
fprintf(stderr, "WARNING: V8 isolate was forked, it can not be disposed and memory will not be reclaimed till the Ruby process exits.\n");
|
1158
|
+
} else {
|
1159
|
+
isolate_info->isolate->Dispose();
|
1160
|
+
}
|
1066
1161
|
}
|
1067
1162
|
isolate_info->isolate = NULL;
|
1068
1163
|
}
|
@@ -1105,17 +1200,17 @@ static void free_context(ContextInfo* context_info) {
|
|
1105
1200
|
context_info_copy->context = context_info->context;
|
1106
1201
|
|
1107
1202
|
if (isolate_info && isolate_info->refs() > 1) {
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1203
|
+
pthread_t free_context_thread;
|
1204
|
+
if (pthread_create(&free_context_thread, NULL, free_context_raw, (void*)context_info_copy)) {
|
1205
|
+
fprintf(stderr, "WARNING failed to release memory in MiniRacer, thread to release could not be created, process will leak memory\n");
|
1206
|
+
}
|
1112
1207
|
|
1113
1208
|
} else {
|
1114
|
-
|
1209
|
+
free_context_raw(context_info_copy);
|
1115
1210
|
}
|
1116
1211
|
|
1117
1212
|
if (context_info->context && isolate_info && isolate_info->isolate) {
|
1118
|
-
|
1213
|
+
context_info->context = NULL;
|
1119
1214
|
}
|
1120
1215
|
|
1121
1216
|
if (isolate_info) {
|
@@ -1201,20 +1296,20 @@ rb_heap_stats(VALUE self) {
|
|
1201
1296
|
|
1202
1297
|
if (!isolate) {
|
1203
1298
|
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1299
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(0));
|
1300
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(0));
|
1301
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(0));
|
1302
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(0));
|
1303
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(0));
|
1209
1304
|
|
1210
1305
|
} else {
|
1211
|
-
|
1306
|
+
isolate->GetHeapStatistics(&stats);
|
1212
1307
|
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1308
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(stats.total_physical_size()));
|
1309
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(stats.total_heap_size_executable()));
|
1310
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(stats.total_heap_size()));
|
1311
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(stats.used_heap_size()));
|
1312
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(stats.heap_size_limit()));
|
1218
1313
|
}
|
1219
1314
|
|
1220
1315
|
return rval;
|
@@ -1287,8 +1382,7 @@ static void unblock_function(void *args) {
|
|
1287
1382
|
call->context_info->isolate_info->interrupted = true;
|
1288
1383
|
}
|
1289
1384
|
|
1290
|
-
static VALUE
|
1291
|
-
rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
1385
|
+
static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
1292
1386
|
ContextInfo* context_info;
|
1293
1387
|
FunctionCall call;
|
1294
1388
|
VALUE *call_argv = NULL;
|
@@ -1321,7 +1415,6 @@ rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1321
1415
|
}
|
1322
1416
|
|
1323
1417
|
bool missingFunction = false;
|
1324
|
-
|
1325
1418
|
{
|
1326
1419
|
Locker lock(isolate);
|
1327
1420
|
Isolate::Scope isolate_scope(isolate);
|
@@ -1332,35 +1425,34 @@ rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1332
1425
|
|
1333
1426
|
// examples of such usage can be found in
|
1334
1427
|
// https://github.com/v8/v8/blob/36b32aa28db5e993312f4588d60aad5c8330c8a5/test/cctest/test-api.cc#L15711
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
if (val.IsEmpty() || !val.ToLocalChecked()->IsFunction()) {
|
1339
|
-
missingFunction = true;
|
1340
|
-
} else {
|
1341
|
-
|
1342
|
-
Local<v8::Function> fun = Local<v8::Function>::Cast(val.ToLocalChecked());
|
1343
|
-
call.fun = fun;
|
1344
|
-
int fun_argc = call.argc;
|
1345
|
-
|
1346
|
-
if (fun_argc > 0) {
|
1347
|
-
call.argv = (v8::Local<Value> *) malloc(sizeof(void *) * fun_argc);
|
1348
|
-
if (!call.argv) {
|
1349
|
-
return Qnil;
|
1350
|
-
}
|
1351
|
-
for(int i=0; i < fun_argc; i++) {
|
1352
|
-
call.argv[i] = convert_ruby_to_v8(isolate, call_argv[i]);
|
1353
|
-
}
|
1354
|
-
}
|
1355
|
-
|
1356
|
-
rb_thread_call_without_gvl(nogvl_context_call, &call, unblock_function, &call);
|
1357
|
-
free(call.argv);
|
1428
|
+
Local<String> fname = String::NewFromUtf8(isolate, call.function_name);
|
1429
|
+
MaybeLocal<v8::Value> val = context->Global()->Get(fname);
|
1358
1430
|
|
1359
|
-
|
1431
|
+
if (val.IsEmpty() || !val.ToLocalChecked()->IsFunction()) {
|
1432
|
+
missingFunction = true;
|
1433
|
+
} else {
|
1434
|
+
|
1435
|
+
Local<v8::Function> fun = Local<v8::Function>::Cast(val.ToLocalChecked());
|
1436
|
+
call.fun = fun;
|
1437
|
+
int fun_argc = call.argc;
|
1438
|
+
|
1439
|
+
if (fun_argc > 0) {
|
1440
|
+
call.argv = (v8::Local<Value> *) malloc(sizeof(void *) * fun_argc);
|
1441
|
+
if (!call.argv) {
|
1442
|
+
return Qnil;
|
1443
|
+
}
|
1444
|
+
for(int i=0; i < fun_argc; i++) {
|
1445
|
+
call.argv[i] = convert_ruby_to_v8(isolate, context, call_argv[i]);
|
1446
|
+
}
|
1447
|
+
}
|
1448
|
+
rb_thread_call_without_gvl(nogvl_context_call, &call, unblock_function, &call);
|
1449
|
+
free(call.argv);
|
1450
|
+
|
1451
|
+
}
|
1360
1452
|
}
|
1361
1453
|
|
1362
1454
|
if (missingFunction) {
|
1363
|
-
|
1455
|
+
rb_raise(rb_eScriptRuntimeError, "Unknown JavaScript method invoked");
|
1364
1456
|
}
|
1365
1457
|
|
1366
1458
|
return convert_result_to_ruby(self, call.result);
|
@@ -1383,53 +1475,52 @@ extern "C" {
|
|
1383
1475
|
|
1384
1476
|
void Init_mini_racer_extension ( void )
|
1385
1477
|
{
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1478
|
+
VALUE rb_mMiniRacer = rb_define_module("MiniRacer");
|
1479
|
+
rb_cContext = rb_define_class_under(rb_mMiniRacer, "Context", rb_cObject);
|
1480
|
+
rb_cSnapshot = rb_define_class_under(rb_mMiniRacer, "Snapshot", rb_cObject);
|
1481
|
+
rb_cIsolate = rb_define_class_under(rb_mMiniRacer, "Isolate", rb_cObject);
|
1482
|
+
VALUE rb_cPlatform = rb_define_class_under(rb_mMiniRacer, "Platform", rb_cObject);
|
1483
|
+
|
1484
|
+
VALUE rb_eError = rb_define_class_under(rb_mMiniRacer, "Error", rb_eStandardError);
|
1485
|
+
|
1486
|
+
VALUE rb_eEvalError = rb_define_class_under(rb_mMiniRacer, "EvalError", rb_eError);
|
1487
|
+
rb_eScriptTerminatedError = rb_define_class_under(rb_mMiniRacer, "ScriptTerminatedError", rb_eEvalError);
|
1488
|
+
rb_eV8OutOfMemoryError = rb_define_class_under(rb_mMiniRacer, "V8OutOfMemoryError", rb_eEvalError);
|
1489
|
+
rb_eParseError = rb_define_class_under(rb_mMiniRacer, "ParseError", rb_eEvalError);
|
1490
|
+
rb_eScriptRuntimeError = rb_define_class_under(rb_mMiniRacer, "RuntimeError", rb_eEvalError);
|
1491
|
+
|
1492
|
+
rb_cJavaScriptFunction = rb_define_class_under(rb_mMiniRacer, "JavaScriptFunction", rb_cObject);
|
1493
|
+
rb_eSnapshotError = rb_define_class_under(rb_mMiniRacer, "SnapshotError", rb_eError);
|
1494
|
+
rb_ePlatformAlreadyInitializedError = rb_define_class_under(rb_mMiniRacer, "PlatformAlreadyInitialized", rb_eError);
|
1495
|
+
rb_cFailedV8Conversion = rb_define_class_under(rb_mMiniRacer, "FailedV8Conversion", rb_cObject);
|
1496
|
+
rb_mJSON = rb_define_module("JSON");
|
1497
|
+
|
1498
|
+
VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
|
1499
|
+
|
1500
|
+
rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
|
1501
|
+
rb_define_method(rb_cContext, "dispose_unsafe", (VALUE(*)(...))&rb_context_dispose, 0);
|
1502
|
+
rb_define_method(rb_cContext, "heap_stats", (VALUE(*)(...))&rb_heap_stats, 0);
|
1503
|
+
rb_define_private_method(rb_cContext, "create_isolate_value",(VALUE(*)(...))&rb_context_create_isolate_value, 0);
|
1504
|
+
rb_define_private_method(rb_cContext, "eval_unsafe",(VALUE(*)(...))&rb_context_eval_unsafe, 2);
|
1505
|
+
rb_define_private_method(rb_cContext, "call_unsafe", (VALUE(*)(...))&rb_context_call_unsafe, -1);
|
1506
|
+
rb_define_private_method(rb_cContext, "isolate_mutex", (VALUE(*)(...))&rb_context_isolate_mutex, 0);
|
1507
|
+
rb_define_private_method(rb_cContext, "init_unsafe",(VALUE(*)(...))&rb_context_init_unsafe, 2);
|
1508
|
+
|
1509
|
+
rb_define_alloc_func(rb_cContext, allocate);
|
1510
|
+
rb_define_alloc_func(rb_cSnapshot, allocate_snapshot);
|
1511
|
+
rb_define_alloc_func(rb_cIsolate, allocate_isolate);
|
1512
|
+
|
1513
|
+
rb_define_private_method(rb_cExternalFunction, "notify_v8", (VALUE(*)(...))&rb_external_function_notify_v8, 0);
|
1514
|
+
rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
|
1515
|
+
|
1516
|
+
rb_define_method(rb_cSnapshot, "size", (VALUE(*)(...))&rb_snapshot_size, 0);
|
1517
|
+
rb_define_method(rb_cSnapshot, "dump", (VALUE(*)(...))&rb_snapshot_dump, 0);
|
1518
|
+
rb_define_method(rb_cSnapshot, "warmup_unsafe!", (VALUE(*)(...))&rb_snapshot_warmup_unsafe, 1);
|
1519
|
+
rb_define_private_method(rb_cSnapshot, "load", (VALUE(*)(...))&rb_snapshot_load, 1);
|
1520
|
+
|
1521
|
+
rb_define_method(rb_cIsolate, "idle_notification", (VALUE(*)(...))&rb_isolate_idle_notification, 1);
|
1522
|
+
rb_define_private_method(rb_cIsolate, "init_with_snapshot",(VALUE(*)(...))&rb_isolate_init_with_snapshot, 1);
|
1523
|
+
|
1524
|
+
rb_define_singleton_method(rb_cPlatform, "set_flag_as_str!", (VALUE(*)(...))&rb_platform_set_flag_as_str, 1);
|
1433
1525
|
}
|
1434
|
-
|
1435
1526
|
}
|
data/lib/mini_racer/version.rb
CHANGED
data/mini_racer.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
17
|
|
18
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(benchmark|test|spec|features)/}) }
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(benchmark|test|spec|features|examples)/}) }
|
19
19
|
spec.bindir = "exe"
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "minitest", "~> 5.0"
|
26
26
|
spec.add_development_dependency "rake-compiler"
|
27
27
|
|
28
|
-
spec.add_dependency 'libv8', '>= 6.
|
28
|
+
spec.add_dependency 'libv8', '>= 6.9.411'
|
29
29
|
spec.require_paths = ["lib", "ext"]
|
30
30
|
|
31
31
|
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.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 6.9.411
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 6.9.411
|
83
83
|
description: Minimal embedded v8 engine for Ruby
|
84
84
|
email:
|
85
85
|
- sam.saffron@gmail.com
|
@@ -123,8 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
requirements: []
|
126
|
-
|
127
|
-
rubygems_version: 2.7.6
|
126
|
+
rubygems_version: 3.0.3
|
128
127
|
signing_key:
|
129
128
|
specification_version: 4
|
130
129
|
summary: Minimal embedded v8 for Ruby
|