sq_mini_racer 0.2.4.sqreen1 → 0.2.4.sqreen2
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/LICENSE.txt +8 -1
- data/ext/mini_racer_extension/extconf.rb +5 -0
- data/ext/mini_racer_extension/mini_racer_extension.cc +401 -307
- data/ext/mini_racer_extension/simdutf8check.h +463 -0
- data/lib/sqreen/mini_racer/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e20539790e64f4295e6e1e09a4e1acf6b4220b7c706886fb8411f4aa27318ba
|
4
|
+
data.tar.gz: d8e1504d61888f9fbc486362b497540b4f8d2ecb97e568039dd2ad221d5ff44a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80df85cc03fd5ce85da08699bdc9e7d384b0be879c5cce96044a35db5e63e11483b8e60808d3433e6734573458477ac432a7abe347d816ef38049f36818adc25
|
7
|
+
data.tar.gz: cd5d54e082237ee0b06b6d98bff69a9f671a94d8ab827550b691d0edf5c4e4a932a173b1b7b5f4dde9f4cc6b89aafeda8f36f8b70a28bb0ebaac1390f101da40
|
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 contributors
|
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
|
@@ -19,3 +19,10 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
The file ext/mini_racer_extension/simdutf8check.h is a slighly modified file
|
25
|
+
from https://github.com/lemire/fastvalidate-utf-8, which is licensed under the
|
26
|
+
Apache 2.0 license. For more details, see:
|
27
|
+
|
28
|
+
https://github.com/lemire/fastvalidate-utf-8/blob/0f04b4068288711b72f1c3c730a8fb2d1b4cdd00/LICENSE
|
@@ -14,6 +14,11 @@ $CPPFLAGS += " -fPIC" unless $CPPFLAGS.split.include? "-rdynamic" or IS_DARWIN
|
|
14
14
|
$CPPFLAGS += " -std=c++0x"
|
15
15
|
$CPPFLAGS += " -fpermissive"
|
16
16
|
$CPPFLAGS += " -fno-omit-frame-pointer"
|
17
|
+
if enable_config('avx2')
|
18
|
+
$CPPFLAGS += " -mavx2"
|
19
|
+
else
|
20
|
+
$CPPFLAGS += " -mssse3"
|
21
|
+
end
|
17
22
|
|
18
23
|
$CPPFLAGS += " -Wno-reserved-user-defined-literal" if IS_DARWIN
|
19
24
|
|
@@ -1,4 +1,6 @@
|
|
1
1
|
#include <stdio.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include <assert.h>
|
2
4
|
|
3
5
|
// workaround for Ruby 2.3.0 and perhaps certain 2.2 versions
|
4
6
|
// see https://bugs.ruby-lang.org/issues/11962
|
@@ -20,6 +22,7 @@
|
|
20
22
|
#include <atomic>
|
21
23
|
#include <math.h>
|
22
24
|
#include "compat.hpp"
|
25
|
+
#include "simdutf8check.h"
|
23
26
|
|
24
27
|
using namespace v8;
|
25
28
|
|
@@ -82,7 +85,7 @@ public:
|
|
82
85
|
}
|
83
86
|
|
84
87
|
int refs() {
|
85
|
-
|
88
|
+
return refs_count;
|
86
89
|
}
|
87
90
|
|
88
91
|
static void* operator new(size_t size) {
|
@@ -330,13 +333,13 @@ nogvl_context_eval(void* arg) {
|
|
330
333
|
MaybeLocal<Script> parsed_script;
|
331
334
|
|
332
335
|
if (eval_params->filename) {
|
333
|
-
|
336
|
+
origin = new v8::ScriptOrigin(*eval_params->filename);
|
334
337
|
}
|
335
338
|
|
336
339
|
parsed_script = Script::Compile(context, *eval_params->eval, origin);
|
337
340
|
|
338
341
|
if (origin) {
|
339
|
-
|
342
|
+
delete origin;
|
340
343
|
}
|
341
344
|
|
342
345
|
result->parsed = !parsed_script.IsEmpty();
|
@@ -347,8 +350,8 @@ nogvl_context_eval(void* arg) {
|
|
347
350
|
|
348
351
|
MaybeLocal<Value> maybe_value;
|
349
352
|
if (!result->parsed) {
|
350
|
-
|
351
|
-
|
353
|
+
result->message = new Persistent<Value>();
|
354
|
+
result->message->Reset(isolate, trycatch.Exception());
|
352
355
|
} else {
|
353
356
|
// parsing successful
|
354
357
|
if (eval_params->max_memory > 0) {
|
@@ -374,41 +377,41 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
|
|
374
377
|
HandleScope scope(isolate);
|
375
378
|
|
376
379
|
if (value->IsNull() || value->IsUndefined()){
|
377
|
-
|
380
|
+
return Qnil;
|
378
381
|
}
|
379
382
|
|
380
383
|
if (value->IsInt32()) {
|
381
|
-
|
384
|
+
return INT2FIX(value->Int32Value());
|
382
385
|
}
|
383
386
|
|
384
387
|
if (value->IsNumber()) {
|
385
|
-
|
388
|
+
return rb_float_new(value->NumberValue());
|
386
389
|
}
|
387
390
|
|
388
391
|
if (value->IsTrue()) {
|
389
|
-
|
392
|
+
return Qtrue;
|
390
393
|
}
|
391
394
|
|
392
395
|
if (value->IsFalse()) {
|
393
|
-
|
396
|
+
return Qfalse;
|
394
397
|
}
|
395
398
|
|
396
399
|
if (value->IsArray()) {
|
397
400
|
VALUE rb_array = rb_ary_new();
|
398
401
|
Local<Array> arr = Local<Array>::Cast(value);
|
399
402
|
for(uint32_t i=0; i < arr->Length(); i++) {
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
403
|
+
Local<Value> element = arr->Get(i);
|
404
|
+
VALUE rb_elem = convert_v8_to_ruby(isolate, context, element);
|
405
|
+
if (rb_funcall(rb_elem, rb_intern("class"), 0) == rb_cFailedV8Conversion) {
|
406
|
+
return rb_elem;
|
407
|
+
}
|
405
408
|
rb_ary_push(rb_array, rb_elem);
|
406
409
|
}
|
407
410
|
return rb_array;
|
408
411
|
}
|
409
412
|
|
410
413
|
if (value->IsFunction()){
|
411
|
-
|
414
|
+
return rb_funcall(rb_cJavaScriptFunction, rb_intern("new"), 0);
|
412
415
|
}
|
413
416
|
|
414
417
|
if (value->IsDate()){
|
@@ -420,30 +423,30 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
|
|
420
423
|
}
|
421
424
|
|
422
425
|
if (value->IsObject()) {
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
426
|
+
VALUE rb_hash = rb_hash_new();
|
427
|
+
TryCatch trycatch(isolate);
|
428
|
+
|
429
|
+
Local<Object> object = value->ToObject();
|
430
|
+
auto maybe_props = object->GetOwnPropertyNames(context);
|
431
|
+
if (!maybe_props.IsEmpty()) {
|
432
|
+
Local<Array> props = maybe_props.ToLocalChecked();
|
433
|
+
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
|
438
|
+
|
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(""));
|
443
|
+
}
|
444
|
+
|
445
|
+
VALUE rb_value = convert_v8_to_ruby(isolate, context, prop_value);
|
446
|
+
rb_hash_aset(rb_hash, rb_key, rb_value);
|
447
|
+
}
|
448
|
+
}
|
449
|
+
return rb_hash;
|
447
450
|
}
|
448
451
|
|
449
452
|
Local<String> rstr = value->ToString();
|
@@ -468,7 +471,84 @@ static VALUE convert_v8_to_ruby(Isolate* isolate,
|
|
468
471
|
Local<Value>::New(isolate, value));
|
469
472
|
}
|
470
473
|
|
471
|
-
static
|
474
|
+
static VALUE encode_as_utf8(VALUE string)
|
475
|
+
{
|
476
|
+
return rb_funcall(string, rb_intern("encode"), 1, rb_str_new2("UTF-8"));
|
477
|
+
}
|
478
|
+
|
479
|
+
#ifdef __AVX2__
|
480
|
+
static bool (*best_utf8_validate_func(void))(const char *, size_t)
|
481
|
+
{
|
482
|
+
__builtin_cpu_init();
|
483
|
+
if (__builtin_cpu_supports("avx2")) {
|
484
|
+
return validate_utf8_fast_avx;
|
485
|
+
} else {
|
486
|
+
return validate_utf8_fast;
|
487
|
+
}
|
488
|
+
}
|
489
|
+
#endif
|
490
|
+
|
491
|
+
static inline Local<Value> convert_ruby_str_to_v8(
|
492
|
+
HandleScope& scope, Isolate *isolate, VALUE value)
|
493
|
+
{
|
494
|
+
static const rb_encoding *utf8_enc = rb_utf8_encoding();
|
495
|
+
static const rb_encoding *ascii8bit_enc = rb_ascii8bit_encoding();
|
496
|
+
static const rb_encoding *usascii_enc = rb_usascii_encoding();
|
497
|
+
static const rb_encoding *latin1_enc = rb_enc_find("ISO-8859-1");
|
498
|
+
assert(latin1_enc != nullptr);
|
499
|
+
#ifndef __AVX2__
|
500
|
+
# define validate_utf8 validate_utf8_fast
|
501
|
+
#else
|
502
|
+
static const (*validate_utf8)(const char *, size_t) =
|
503
|
+
best_utf8_validate_func();
|
504
|
+
#endif
|
505
|
+
|
506
|
+
rb_encoding *enc = rb_enc_get(value);
|
507
|
+
char *str = RSTRING_PTR(value);
|
508
|
+
long len = RSTRING_LEN(value);
|
509
|
+
if (len < 0 || len > INT_MAX) {
|
510
|
+
return Null(isolate);
|
511
|
+
}
|
512
|
+
bool is_valid_utf8 = enc == utf8_enc &&
|
513
|
+
validate_utf8(str, static_cast<size_t>(len));
|
514
|
+
|
515
|
+
MaybeLocal<String> v8str;
|
516
|
+
int int_len = static_cast<int>(len);
|
517
|
+
if (is_valid_utf8) {
|
518
|
+
convert_from_utf8:
|
519
|
+
v8str = String::NewFromUtf8(
|
520
|
+
isolate, str, NewStringType::kNormal, int_len);
|
521
|
+
} else if (enc == utf8_enc || enc == ascii8bit_enc ||
|
522
|
+
enc == usascii_enc || enc == latin1_enc ||
|
523
|
+
rb_funcall(value, rb_intern("valid_encoding?"), 0) == Qfalse) {
|
524
|
+
treat_as_latin1:
|
525
|
+
// if ASCII, it could be that the string is invalid
|
526
|
+
// ignore that possibility (effectively treat it as latin1)
|
527
|
+
v8str = String::NewFromOneByte(
|
528
|
+
isolate, reinterpret_cast<uint8_t *>(str),
|
529
|
+
NewStringType::kNormal, int_len);
|
530
|
+
} else {
|
531
|
+
int state;
|
532
|
+
VALUE result = rb_protect(encode_as_utf8, value, &state);
|
533
|
+
|
534
|
+
//Ran into an exception!
|
535
|
+
if (state) {
|
536
|
+
rb_set_errinfo(Qnil);
|
537
|
+
goto treat_as_latin1;
|
538
|
+
} else if (rb_enc_get(result) != utf8_enc) {
|
539
|
+
// conversion did not result in UTF-8. Odd!
|
540
|
+
goto treat_as_latin1;
|
541
|
+
} else {
|
542
|
+
str = RSTRING_PTR(result);
|
543
|
+
int_len = RSTRING_LEN(result);
|
544
|
+
goto convert_from_utf8;
|
545
|
+
}
|
546
|
+
}
|
547
|
+
return v8str.ToLocalChecked();
|
548
|
+
}
|
549
|
+
|
550
|
+
static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value)
|
551
|
+
{
|
472
552
|
EscapableHandleScope scope(isolate);
|
473
553
|
|
474
554
|
Local<Array> array;
|
@@ -481,67 +561,85 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|
481
561
|
VALUE klass;
|
482
562
|
|
483
563
|
switch (TYPE(value)) {
|
484
|
-
|
485
|
-
|
486
|
-
|
564
|
+
case T_FIXNUM:
|
565
|
+
{
|
566
|
+
fixnum = NUM2LONG(value);
|
567
|
+
if (fixnum > INT_MAX)
|
568
|
+
{
|
569
|
+
return scope.Escape(Number::New(isolate, (double)fixnum));
|
570
|
+
}
|
571
|
+
return scope.Escape(Integer::New(isolate, (int)fixnum));
|
572
|
+
}
|
573
|
+
case T_FLOAT:
|
574
|
+
return scope.Escape(Number::New(isolate, NUM2DBL(value)));
|
575
|
+
case T_STRING:
|
576
|
+
return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
|
577
|
+
case T_NIL:
|
578
|
+
return scope.Escape(Null(isolate));
|
579
|
+
case T_TRUE:
|
580
|
+
return scope.Escape(True(isolate));
|
581
|
+
case T_FALSE:
|
582
|
+
return scope.Escape(False(isolate));
|
583
|
+
case T_ARRAY:
|
487
584
|
{
|
488
|
-
|
585
|
+
length = RARRAY_LEN(value);
|
586
|
+
array = Array::New(isolate, (int)length);
|
587
|
+
for(i=0; i<length; i++) {
|
588
|
+
array->Set(i, convert_ruby_to_v8(isolate, rb_ary_entry(value, i)));
|
589
|
+
}
|
590
|
+
return scope.Escape(array);
|
591
|
+
}
|
592
|
+
case T_HASH:
|
593
|
+
{
|
594
|
+
object = Object::New(isolate);
|
595
|
+
hash_as_array = rb_funcall(value, rb_intern("to_a"), 0);
|
596
|
+
length = RARRAY_LEN(hash_as_array);
|
597
|
+
for(i=0; i<length; i++) {
|
598
|
+
pair = rb_ary_entry(hash_as_array, i);
|
599
|
+
object->Set(convert_ruby_to_v8(isolate, rb_ary_entry(pair, 0)),
|
600
|
+
convert_ruby_to_v8(isolate, rb_ary_entry(pair, 1)));
|
601
|
+
}
|
602
|
+
return scope.Escape(object);
|
603
|
+
}
|
604
|
+
case T_SYMBOL:
|
605
|
+
{
|
606
|
+
value = rb_funcall(value, rb_intern("to_s"), 0);
|
607
|
+
return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
|
489
608
|
}
|
490
|
-
|
491
|
-
case T_FLOAT:
|
492
|
-
return scope.Escape(Number::New(isolate, NUM2DBL(value)));
|
493
|
-
case T_STRING:
|
494
|
-
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (int)RSTRING_LEN(value)).ToLocalChecked());
|
495
|
-
case T_NIL:
|
496
|
-
return scope.Escape(Null(isolate));
|
497
|
-
case T_TRUE:
|
498
|
-
return scope.Escape(True(isolate));
|
499
|
-
case T_FALSE:
|
500
|
-
return scope.Escape(False(isolate));
|
501
|
-
case T_ARRAY:
|
502
|
-
length = RARRAY_LEN(value);
|
503
|
-
array = Array::New(isolate, (int)length);
|
504
|
-
for(i=0; i<length; i++) {
|
505
|
-
array->Set(i, convert_ruby_to_v8(isolate, rb_ary_entry(value, i)));
|
506
|
-
}
|
507
|
-
return scope.Escape(array);
|
508
|
-
case T_HASH:
|
509
|
-
object = Object::New(isolate);
|
510
|
-
hash_as_array = rb_funcall(value, rb_intern("to_a"), 0);
|
511
|
-
length = RARRAY_LEN(hash_as_array);
|
512
|
-
for(i=0; i<length; i++) {
|
513
|
-
pair = rb_ary_entry(hash_as_array, i);
|
514
|
-
object->Set(convert_ruby_to_v8(isolate, rb_ary_entry(pair, 0)),
|
515
|
-
convert_ruby_to_v8(isolate, rb_ary_entry(pair, 1)));
|
516
|
-
}
|
517
|
-
return scope.Escape(object);
|
518
|
-
case T_SYMBOL:
|
519
|
-
value = rb_funcall(value, rb_intern("to_s"), 0);
|
520
|
-
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (int)RSTRING_LEN(value)).ToLocalChecked());
|
521
|
-
case T_DATA:
|
522
|
-
klass = rb_funcall(value, rb_intern("class"), 0);
|
523
|
-
if (klass == rb_cTime || klass == rb_cDateTime)
|
609
|
+
case T_DATA:
|
524
610
|
{
|
525
|
-
|
611
|
+
klass = rb_funcall(value, rb_intern("class"), 0);
|
612
|
+
if (klass == rb_cTime || klass == rb_cDateTime)
|
526
613
|
{
|
527
|
-
|
614
|
+
if (klass == rb_cDateTime)
|
615
|
+
{
|
616
|
+
value = rb_funcall(value, rb_intern("to_time"), 0);
|
617
|
+
}
|
618
|
+
value = rb_funcall(value, rb_intern("to_f"), 0);
|
619
|
+
return scope.Escape(Date::New(isolate, NUM2DBL(value) * 1000));
|
620
|
+
}
|
621
|
+
// break intentionally missing
|
622
|
+
}
|
623
|
+
case T_OBJECT:
|
624
|
+
case T_CLASS:
|
625
|
+
case T_ICLASS:
|
626
|
+
case T_MODULE:
|
627
|
+
case T_REGEXP:
|
628
|
+
case T_MATCH:
|
629
|
+
case T_STRUCT:
|
630
|
+
case T_BIGNUM:
|
631
|
+
case T_FILE:
|
632
|
+
case T_UNDEF:
|
633
|
+
case T_NODE:
|
634
|
+
default:
|
635
|
+
{
|
636
|
+
if (rb_respond_to(value, rb_intern("to_s"))) {
|
637
|
+
// TODO: if this throws we're screwed
|
638
|
+
value = rb_funcall(value, rb_intern("to_s"), 0);
|
639
|
+
return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
|
528
640
|
}
|
529
|
-
|
530
|
-
return scope.Escape(Date::New(isolate, NUM2DBL(value) * 1000));
|
641
|
+
return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
|
531
642
|
}
|
532
|
-
case T_OBJECT:
|
533
|
-
case T_CLASS:
|
534
|
-
case T_ICLASS:
|
535
|
-
case T_MODULE:
|
536
|
-
case T_REGEXP:
|
537
|
-
case T_MATCH:
|
538
|
-
case T_STRUCT:
|
539
|
-
case T_BIGNUM:
|
540
|
-
case T_FILE:
|
541
|
-
case T_UNDEF:
|
542
|
-
case T_NODE:
|
543
|
-
default:
|
544
|
-
return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
|
545
643
|
}
|
546
644
|
|
547
645
|
}
|
@@ -690,13 +788,13 @@ static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
|
|
690
788
|
// the ruby lock is needed if this isn't a new isolate
|
691
789
|
IsolateInfo::Lock ruby_lock(isolate_info->mutex);
|
692
790
|
Locker lock(isolate_info->isolate);
|
693
|
-
|
694
|
-
|
791
|
+
Isolate::Scope isolate_scope(isolate_info->isolate);
|
792
|
+
HandleScope handle_scope(isolate_info->isolate);
|
695
793
|
|
696
|
-
|
794
|
+
Local<Context> context = Context::New(isolate_info->isolate);
|
697
795
|
|
698
|
-
|
699
|
-
|
796
|
+
context_info->context = new Persistent<Context>();
|
797
|
+
context_info->context->Reset(isolate_info->isolate, context);
|
700
798
|
}
|
701
799
|
|
702
800
|
if (Qnil == rb_cDateTime && rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, rb_str_new2("DateTime")) == Qtrue)
|
@@ -818,45 +916,45 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str, VALUE filename) {
|
|
818
916
|
}
|
819
917
|
|
820
918
|
{
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
919
|
+
Locker lock(isolate);
|
920
|
+
Isolate::Scope isolate_scope(isolate);
|
921
|
+
HandleScope handle_scope(isolate);
|
922
|
+
|
923
|
+
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(str),
|
924
|
+
NewStringType::kNormal, (int)RSTRING_LEN(str)).ToLocalChecked();
|
925
|
+
|
926
|
+
Local<String> local_filename;
|
927
|
+
|
928
|
+
if (filename != Qnil) {
|
929
|
+
local_filename = String::NewFromUtf8(isolate, RSTRING_PTR(filename),
|
930
|
+
NewStringType::kNormal, (int)RSTRING_LEN(filename)).ToLocalChecked();
|
931
|
+
eval_params.filename = &local_filename;
|
932
|
+
} else {
|
933
|
+
eval_params.filename = NULL;
|
934
|
+
}
|
935
|
+
|
936
|
+
eval_params.context_info = context_info;
|
937
|
+
eval_params.eval = &eval;
|
938
|
+
eval_params.result = &eval_result;
|
939
|
+
eval_params.timeout = 0;
|
940
|
+
eval_params.max_memory = 0;
|
941
|
+
VALUE timeout = rb_iv_get(self, "@timeout");
|
942
|
+
if (timeout != Qnil) {
|
943
|
+
eval_params.timeout = (useconds_t)NUM2LONG(timeout);
|
944
|
+
}
|
945
|
+
|
946
|
+
VALUE mem_softlimit = rb_iv_get(self, "@max_memory");
|
947
|
+
if (mem_softlimit != Qnil) {
|
948
|
+
eval_params.max_memory = (size_t)NUM2ULONG(mem_softlimit);
|
949
|
+
}
|
950
|
+
|
951
|
+
eval_result.message = NULL;
|
952
|
+
eval_result.backtrace = NULL;
|
855
953
|
|
856
954
|
#if RUBY_API_VERSION_MAJOR > 1
|
857
|
-
|
955
|
+
rb_thread_call_without_gvl(nogvl_context_eval, &eval_params, unblock_eval, &eval_params);
|
858
956
|
#else
|
859
|
-
|
957
|
+
rb_thread_blocking_region(nogvl_context_eval, &eval_params, unblock_eval, &eval_params);
|
860
958
|
#endif
|
861
959
|
}
|
862
960
|
|
@@ -870,17 +968,16 @@ typedef struct {
|
|
870
968
|
bool failed;
|
871
969
|
} protected_callback_data;
|
872
970
|
|
873
|
-
static
|
874
|
-
VALUE protected_callback(VALUE rdata) {
|
971
|
+
static VALUE protected_callback(VALUE rdata) {
|
875
972
|
protected_callback_data* data = (protected_callback_data*)rdata;
|
876
973
|
VALUE result;
|
877
974
|
|
878
975
|
if (data->length > 0) {
|
879
|
-
|
880
|
-
|
881
|
-
|
976
|
+
result = rb_funcall2(data->callback, rb_intern("call"), data->length,
|
977
|
+
RARRAY_PTR(data->ruby_args));
|
978
|
+
RB_GC_GUARD(data->ruby_args);
|
882
979
|
} else {
|
883
|
-
|
980
|
+
result = rb_funcall(data->callback, rb_intern("call"), 0);
|
884
981
|
}
|
885
982
|
return result;
|
886
983
|
}
|
@@ -917,16 +1014,16 @@ gvl_ruby_callback(void* data) {
|
|
917
1014
|
ContextInfo* context_info;
|
918
1015
|
Data_Get_Struct(parent, ContextInfo, context_info);
|
919
1016
|
|
920
|
-
|
921
|
-
|
922
|
-
|
1017
|
+
if (length > 0) {
|
1018
|
+
ruby_args = rb_ary_tmp_new(length);
|
1019
|
+
}
|
923
1020
|
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
1021
|
+
for (int i = 0; i < length; i++) {
|
1022
|
+
Local<Value> value = ((*args)[i]).As<Value>();
|
1023
|
+
VALUE tmp = convert_v8_to_ruby(args->GetIsolate(),
|
1024
|
+
*context_info->context, value);
|
1025
|
+
rb_ary_push(ruby_args, tmp);
|
1026
|
+
}
|
930
1027
|
}
|
931
1028
|
|
932
1029
|
// may raise exception stay clear of handle scope
|
@@ -937,31 +1034,31 @@ gvl_ruby_callback(void* data) {
|
|
937
1034
|
callback_data.failed = false;
|
938
1035
|
|
939
1036
|
if ((bool)args->GetIsolate()->GetData(DO_TERMINATE) == true) {
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
1037
|
+
args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Terminated execution during transition from Ruby to JS"));
|
1038
|
+
args->GetIsolate()->TerminateExecution();
|
1039
|
+
if (length > 0) {
|
1040
|
+
rb_ary_clear(ruby_args);
|
1041
|
+
rb_gc_force_recycle(ruby_args);
|
1042
|
+
}
|
1043
|
+
return NULL;
|
947
1044
|
}
|
948
1045
|
|
949
1046
|
result = rb_rescue2((VALUE(*)(...))&protected_callback, (VALUE)(&callback_data),
|
950
|
-
|
1047
|
+
(VALUE(*)(...))&rescue_callback, (VALUE)(&callback_data), rb_eException, (VALUE)0);
|
951
1048
|
|
952
1049
|
if(callback_data.failed) {
|
953
|
-
|
954
|
-
|
1050
|
+
rb_iv_set(parent, "@current_exception", result);
|
1051
|
+
args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Ruby exception"));
|
955
1052
|
}
|
956
1053
|
else {
|
957
|
-
|
958
|
-
|
959
|
-
|
1054
|
+
HandleScope scope(args->GetIsolate());
|
1055
|
+
Handle<Value> v8_result = convert_ruby_to_v8(args->GetIsolate(), result);
|
1056
|
+
args->GetReturnValue().Set(v8_result);
|
960
1057
|
}
|
961
1058
|
|
962
1059
|
if (length > 0) {
|
963
|
-
|
964
|
-
|
1060
|
+
rb_ary_clear(ruby_args);
|
1061
|
+
rb_gc_force_recycle(ruby_args);
|
965
1062
|
}
|
966
1063
|
|
967
1064
|
if ((bool)args->GetIsolate()->GetData(DO_TERMINATE) == true) {
|
@@ -980,11 +1077,11 @@ static void ruby_callback(const FunctionCallbackInfo<Value>& args) {
|
|
980
1077
|
bool has_gvl = (bool)args.GetIsolate()->GetData(IN_GVL);
|
981
1078
|
|
982
1079
|
if(has_gvl) {
|
983
|
-
|
1080
|
+
gvl_ruby_callback((void*)&args);
|
984
1081
|
} else {
|
985
|
-
|
986
|
-
|
987
|
-
|
1082
|
+
args.GetIsolate()->SetData(IN_GVL, (void*)true);
|
1083
|
+
rb_thread_call_with_gvl(gvl_ruby_callback, (void*)(&args));
|
1084
|
+
args.GetIsolate()->SetData(IN_GVL, (void*)false);
|
988
1085
|
}
|
989
1086
|
}
|
990
1087
|
|
@@ -1005,46 +1102,46 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
1005
1102
|
Isolate* isolate = context_info->isolate_info->isolate;
|
1006
1103
|
|
1007
1104
|
{
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
Local<Context> context = context_info->context->Get(isolate);
|
1013
|
-
Context::Scope context_scope(context);
|
1105
|
+
Locker lock(isolate);
|
1106
|
+
Isolate::Scope isolate_scope(isolate);
|
1107
|
+
HandleScope handle_scope(isolate);
|
1014
1108
|
|
1015
|
-
|
1016
|
-
|
1109
|
+
Local<Context> context = context_info->context->Get(isolate);
|
1110
|
+
Context::Scope context_scope(context);
|
1017
1111
|
|
1018
|
-
|
1019
|
-
|
1020
|
-
Data_Get_Struct(self, VALUE, self_copy);
|
1021
|
-
*self_copy = self;
|
1112
|
+
Local<String> v8_str = String::NewFromUtf8(isolate, RSTRING_PTR(name),
|
1113
|
+
NewStringType::kNormal, (int)RSTRING_LEN(name)).ToLocalChecked();
|
1022
1114
|
|
1023
|
-
|
1115
|
+
// copy self so we can access from v8 external
|
1116
|
+
VALUE* self_copy;
|
1117
|
+
Data_Get_Struct(self, VALUE, self_copy);
|
1118
|
+
*self_copy = self;
|
1024
1119
|
|
1025
|
-
|
1026
|
-
context->Global()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1027
|
-
} else {
|
1120
|
+
Local<Value> external = External::New(isolate, self_copy);
|
1028
1121
|
|
1029
|
-
|
1030
|
-
|
1122
|
+
if (parent_object == Qnil) {
|
1123
|
+
context->Global()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1124
|
+
} else {
|
1031
1125
|
|
1032
|
-
|
1033
|
-
|
1034
|
-
parse_error = true;
|
1035
|
-
} else {
|
1036
|
-
MaybeLocal<Value> maybe_value = parsed_script.ToLocalChecked()->Run(context);
|
1037
|
-
attach_error = true;
|
1126
|
+
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(parent_object_eval),
|
1127
|
+
NewStringType::kNormal, (int)RSTRING_LEN(parent_object_eval)).ToLocalChecked();
|
1038
1128
|
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1129
|
+
MaybeLocal<Script> parsed_script = Script::Compile(context, eval);
|
1130
|
+
if (parsed_script.IsEmpty()) {
|
1131
|
+
parse_error = true;
|
1132
|
+
} else {
|
1133
|
+
MaybeLocal<Value> maybe_value = parsed_script.ToLocalChecked()->Run(context);
|
1134
|
+
attach_error = true;
|
1135
|
+
|
1136
|
+
if (!maybe_value.IsEmpty()) {
|
1137
|
+
Local<Value> value = maybe_value.ToLocalChecked();
|
1138
|
+
if (value->IsObject()){
|
1139
|
+
value.As<Object>()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1140
|
+
attach_error = false;
|
1141
|
+
}
|
1142
|
+
}
|
1143
|
+
}
|
1144
|
+
}
|
1048
1145
|
}
|
1049
1146
|
|
1050
1147
|
// always raise out of V8 context
|
@@ -1073,19 +1170,19 @@ static VALUE rb_context_isolate_mutex(VALUE self) {
|
|
1073
1170
|
void free_isolate(IsolateInfo* isolate_info) {
|
1074
1171
|
|
1075
1172
|
if (isolate_info->isolate) {
|
1076
|
-
|
1173
|
+
Locker lock(isolate_info->isolate);
|
1077
1174
|
}
|
1078
1175
|
|
1079
1176
|
if (isolate_info->isolate) {
|
1080
1177
|
if (isolate_info->interrupted) {
|
1081
1178
|
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");
|
1082
1179
|
} else {
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1180
|
+
|
1181
|
+
if (isolate_info->pid != getpid()) {
|
1182
|
+
fprintf(stderr, "WARNING: V8 isolate was forked, it can not be disposed and memory will not be reclaimed till the Ruby process exits.\n");
|
1183
|
+
} else {
|
1184
|
+
isolate_info->isolate->Dispose();
|
1185
|
+
}
|
1089
1186
|
}
|
1090
1187
|
isolate_info->isolate = NULL;
|
1091
1188
|
}
|
@@ -1128,17 +1225,17 @@ static void free_context(ContextInfo* context_info) {
|
|
1128
1225
|
context_info_copy->context = context_info->context;
|
1129
1226
|
|
1130
1227
|
if (isolate_info && isolate_info->refs() > 1) {
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1228
|
+
pthread_t free_context_thread;
|
1229
|
+
if (pthread_create(&free_context_thread, NULL, free_context_raw, (void*)context_info_copy)) {
|
1230
|
+
fprintf(stderr, "WARNING failed to release memory in MiniRacer, thread to release could not be created, process will leak memory\n");
|
1231
|
+
}
|
1135
1232
|
|
1136
1233
|
} else {
|
1137
|
-
|
1234
|
+
free_context_raw(context_info_copy);
|
1138
1235
|
}
|
1139
1236
|
|
1140
1237
|
if (context_info->context && isolate_info && isolate_info->isolate) {
|
1141
|
-
|
1238
|
+
context_info->context = NULL;
|
1142
1239
|
}
|
1143
1240
|
|
1144
1241
|
if (isolate_info) {
|
@@ -1224,20 +1321,20 @@ rb_heap_stats(VALUE self) {
|
|
1224
1321
|
|
1225
1322
|
if (!isolate) {
|
1226
1323
|
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1324
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(0));
|
1325
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(0));
|
1326
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(0));
|
1327
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(0));
|
1328
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(0));
|
1232
1329
|
|
1233
1330
|
} else {
|
1234
|
-
|
1331
|
+
isolate->GetHeapStatistics(&stats);
|
1235
1332
|
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1333
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(stats.total_physical_size()));
|
1334
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(stats.total_heap_size_executable()));
|
1335
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(stats.total_heap_size()));
|
1336
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(stats.used_heap_size()));
|
1337
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(stats.heap_size_limit()));
|
1241
1338
|
}
|
1242
1339
|
|
1243
1340
|
return rval;
|
@@ -1327,8 +1424,7 @@ static void unblock_function(void *args) {
|
|
1327
1424
|
call->context_info->isolate_info->interrupted = true;
|
1328
1425
|
}
|
1329
1426
|
|
1330
|
-
static VALUE
|
1331
|
-
rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
1427
|
+
static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
1332
1428
|
ContextInfo* context_info;
|
1333
1429
|
FunctionCall call;
|
1334
1430
|
VALUE *call_argv = NULL;
|
@@ -1361,7 +1457,6 @@ rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1361
1457
|
}
|
1362
1458
|
|
1363
1459
|
bool missingFunction = false;
|
1364
|
-
|
1365
1460
|
{
|
1366
1461
|
Locker lock(isolate);
|
1367
1462
|
Isolate::Scope isolate_scope(isolate);
|
@@ -1372,38 +1467,38 @@ rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1372
1467
|
|
1373
1468
|
// examples of such usage can be found in
|
1374
1469
|
// https://github.com/v8/v8/blob/36b32aa28db5e993312f4588d60aad5c8330c8a5/test/cctest/test-api.cc#L15711
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
if (fun_argc > 0) {
|
1387
|
-
call.argv = (v8::Local<Value> *) malloc(sizeof(void *) * fun_argc);
|
1388
|
-
if (!call.argv) {
|
1389
|
-
return Qnil;
|
1390
|
-
}
|
1391
|
-
for(int i=0; i < fun_argc; i++) {
|
1392
|
-
call.argv[i] = convert_ruby_to_v8(isolate, call_argv[i]);
|
1393
|
-
}
|
1394
|
-
}
|
1395
|
-
#if RUBY_API_VERSION_MAJOR > 1
|
1396
|
-
rb_thread_call_without_gvl(nogvl_context_call, &call, unblock_function, &call);
|
1397
|
-
#else
|
1398
|
-
rb_thread_blocking_region(nogvl_context_call, &call, unblock_function, &call);
|
1399
|
-
#endif
|
1400
|
-
free(call.argv);
|
1470
|
+
Local<String> fname = String::NewFromUtf8(isolate, call.function_name);
|
1471
|
+
MaybeLocal<v8::Value> val = context->Global()->Get(fname);
|
1472
|
+
|
1473
|
+
if (val.IsEmpty() || !val.ToLocalChecked()->IsFunction()) {
|
1474
|
+
missingFunction = true;
|
1475
|
+
} else {
|
1476
|
+
|
1477
|
+
Local<v8::Function> fun = Local<v8::Function>::Cast(val.ToLocalChecked());
|
1478
|
+
call.fun = fun;
|
1479
|
+
int fun_argc = call.argc;
|
1401
1480
|
|
1402
|
-
|
1481
|
+
if (fun_argc > 0) {
|
1482
|
+
call.argv = (v8::Local<Value> *) malloc(sizeof(void *) * fun_argc);
|
1483
|
+
if (!call.argv) {
|
1484
|
+
return Qnil;
|
1485
|
+
}
|
1486
|
+
for(int i=0; i < fun_argc; i++) {
|
1487
|
+
call.argv[i] = convert_ruby_to_v8(isolate, call_argv[i]);
|
1488
|
+
}
|
1489
|
+
}
|
1490
|
+
#if RUBY_API_VERSION_MAJOR > 1
|
1491
|
+
rb_thread_call_without_gvl(nogvl_context_call, &call, unblock_function, &call);
|
1492
|
+
#else
|
1493
|
+
rb_thread_blocking_region(nogvl_context_call, &call, unblock_function, &call);
|
1494
|
+
#endif
|
1495
|
+
free(call.argv);
|
1496
|
+
|
1497
|
+
}
|
1403
1498
|
}
|
1404
1499
|
|
1405
1500
|
if (missingFunction) {
|
1406
|
-
|
1501
|
+
rb_raise(rb_eScriptRuntimeError, "Unknown JavaScript method invoked");
|
1407
1502
|
}
|
1408
1503
|
|
1409
1504
|
return convert_result_to_ruby(self, call.result);
|
@@ -1428,53 +1523,52 @@ extern "C" {
|
|
1428
1523
|
{
|
1429
1524
|
VALUE rb_mSqreen = rb_define_module("Sqreen");
|
1430
1525
|
VALUE rb_mMiniRacer = rb_define_module_under(rb_mSqreen, "MiniRacer");
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1526
|
+
rb_cContext = rb_define_class_under(rb_mMiniRacer, "Context", rb_cObject);
|
1527
|
+
rb_cSnapshot = rb_define_class_under(rb_mMiniRacer, "Snapshot", rb_cObject);
|
1528
|
+
rb_cIsolate = rb_define_class_under(rb_mMiniRacer, "Isolate", rb_cObject);
|
1529
|
+
VALUE rb_cPlatform = rb_define_class_under(rb_mMiniRacer, "Platform", rb_cObject);
|
1530
|
+
|
1531
|
+
VALUE rb_eError = rb_define_class_under(rb_mMiniRacer, "Error", rb_eStandardError);
|
1532
|
+
|
1533
|
+
VALUE rb_eEvalError = rb_define_class_under(rb_mMiniRacer, "EvalError", rb_eError);
|
1534
|
+
rb_eScriptTerminatedError = rb_define_class_under(rb_mMiniRacer, "ScriptTerminatedError", rb_eEvalError);
|
1535
|
+
rb_eV8OutOfMemoryError = rb_define_class_under(rb_mMiniRacer, "V8OutOfMemoryError", rb_eEvalError);
|
1536
|
+
rb_eParseError = rb_define_class_under(rb_mMiniRacer, "ParseError", rb_eEvalError);
|
1537
|
+
rb_eScriptRuntimeError = rb_define_class_under(rb_mMiniRacer, "RuntimeError", rb_eEvalError);
|
1538
|
+
|
1539
|
+
rb_cJavaScriptFunction = rb_define_class_under(rb_mMiniRacer, "JavaScriptFunction", rb_cObject);
|
1540
|
+
rb_eSnapshotError = rb_define_class_under(rb_mMiniRacer, "SnapshotError", rb_eError);
|
1541
|
+
rb_ePlatformAlreadyInitializedError = rb_define_class_under(rb_mMiniRacer, "PlatformAlreadyInitialized", rb_eError);
|
1542
|
+
rb_cFailedV8Conversion = rb_define_class_under(rb_mMiniRacer, "FailedV8Conversion", rb_cObject);
|
1543
|
+
rb_mJSON = rb_define_module("JSON");
|
1544
|
+
|
1545
|
+
VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
|
1546
|
+
|
1547
|
+
rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
|
1548
|
+
rb_define_method(rb_cContext, "dispose_unsafe", (VALUE(*)(...))&rb_context_dispose, 0);
|
1549
|
+
rb_define_method(rb_cContext, "low_memory_notification", (VALUE(*)(...))&rb_context_low_memory_notification, 0);
|
1550
|
+
rb_define_method(rb_cContext, "heap_stats", (VALUE(*)(...))&rb_heap_stats, 0);
|
1551
|
+
rb_define_private_method(rb_cContext, "create_isolate_value",(VALUE(*)(...))&rb_context_create_isolate_value, 0);
|
1552
|
+
rb_define_private_method(rb_cContext, "eval_unsafe",(VALUE(*)(...))&rb_context_eval_unsafe, 2);
|
1553
|
+
rb_define_private_method(rb_cContext, "call_unsafe", (VALUE(*)(...))&rb_context_call_unsafe, -1);
|
1554
|
+
rb_define_private_method(rb_cContext, "isolate_mutex", (VALUE(*)(...))&rb_context_isolate_mutex, 0);
|
1555
|
+
rb_define_private_method(rb_cContext, "init_unsafe",(VALUE(*)(...))&rb_context_init_unsafe, 2);
|
1556
|
+
|
1557
|
+
rb_define_alloc_func(rb_cContext, allocate);
|
1558
|
+
rb_define_alloc_func(rb_cSnapshot, allocate_snapshot);
|
1559
|
+
rb_define_alloc_func(rb_cIsolate, allocate_isolate);
|
1560
|
+
|
1561
|
+
rb_define_private_method(rb_cExternalFunction, "notify_v8", (VALUE(*)(...))&rb_external_function_notify_v8, 0);
|
1562
|
+
rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
|
1563
|
+
|
1564
|
+
rb_define_method(rb_cSnapshot, "size", (VALUE(*)(...))&rb_snapshot_size, 0);
|
1565
|
+
rb_define_method(rb_cSnapshot, "dump", (VALUE(*)(...))&rb_snapshot_dump, 0);
|
1566
|
+
rb_define_method(rb_cSnapshot, "warmup_unsafe!", (VALUE(*)(...))&rb_snapshot_warmup_unsafe, 1);
|
1567
|
+
rb_define_private_method(rb_cSnapshot, "load", (VALUE(*)(...))&rb_snapshot_load, 1);
|
1568
|
+
|
1569
|
+
rb_define_method(rb_cIsolate, "idle_notification", (VALUE(*)(...))&rb_isolate_idle_notification, 1);
|
1570
|
+
rb_define_private_method(rb_cIsolate, "init_with_snapshot",(VALUE(*)(...))&rb_isolate_init_with_snapshot, 1);
|
1571
|
+
|
1572
|
+
rb_define_singleton_method(rb_cPlatform, "set_flag_as_str!", (VALUE(*)(...))&rb_platform_set_flag_as_str, 1);
|
1478
1573
|
}
|
1479
|
-
|
1480
1574
|
}
|