sq_mini_racer 0.2.3.sqreen4 → 0.2.4.0.2
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/.dockerignore +12 -0
- data/CHANGELOG +7 -0
- data/Dockerfile +22 -0
- data/LICENSE.txt +8 -1
- data/azure-pipelines.yml +69 -0
- data/azure-template.yml +92 -0
- data/ext/mini_racer_extension/extconf.rb +205 -87
- data/ext/mini_racer_extension/mini_racer_extension.cc +466 -315
- data/ext/mini_racer_extension/simdutf8check.h +463 -0
- data/lib/sqreen/mini_racer.rb +2 -2
- data/lib/sqreen/mini_racer/version.rb +1 -1
- data/mini_racer.gemspec +0 -1
- metadata +13 -23
@@ -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
|
@@ -6,8 +8,18 @@
|
|
6
8
|
# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
|
7
9
|
# undef HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P
|
8
10
|
|
9
|
-
#include <ruby.h>
|
10
11
|
#include <ruby/version.h>
|
12
|
+
|
13
|
+
// workaround for Ruby 2.3.0 on macOS
|
14
|
+
#if RUBY_API_VERSION_CODE == 20300
|
15
|
+
#ifdef _DARWIN_C_SOURCE
|
16
|
+
#ifndef __STDC_LIB_EXT1__
|
17
|
+
#undef HAVE_MEMSET_S
|
18
|
+
#endif
|
19
|
+
#endif
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#include <ruby.h>
|
11
23
|
#if RUBY_API_VERSION_MAJOR > 1
|
12
24
|
#include <ruby/thread.h>
|
13
25
|
#endif
|
@@ -20,6 +32,7 @@
|
|
20
32
|
#include <atomic>
|
21
33
|
#include <math.h>
|
22
34
|
#include "compat.hpp"
|
35
|
+
#include "simdutf8check.h"
|
23
36
|
|
24
37
|
using namespace v8;
|
25
38
|
|
@@ -81,6 +94,10 @@ public:
|
|
81
94
|
}
|
82
95
|
}
|
83
96
|
|
97
|
+
int refs() {
|
98
|
+
return refs_count;
|
99
|
+
}
|
100
|
+
|
84
101
|
static void* operator new(size_t size) {
|
85
102
|
return ruby_xmalloc(size);
|
86
103
|
}
|
@@ -207,9 +224,9 @@ static void gc_callback(Isolate *isolate, GCType type, GCCallbackFlags flags) {
|
|
207
224
|
|
208
225
|
size_t softlimit = *(size_t*) isolate->GetData(MEM_SOFTLIMIT_VALUE);
|
209
226
|
|
210
|
-
HeapStatistics
|
211
|
-
isolate->GetHeapStatistics(stats);
|
212
|
-
size_t used = stats
|
227
|
+
HeapStatistics stats;
|
228
|
+
isolate->GetHeapStatistics(&stats);
|
229
|
+
size_t used = stats.used_heap_size();
|
213
230
|
|
214
231
|
if(used > softlimit) {
|
215
232
|
isolate->SetData(MEM_SOFTLIMIT_REACHED, (void*)true);
|
@@ -271,8 +288,8 @@ static void prepare_result(MaybeLocal<Value> v8res,
|
|
271
288
|
Local<Message> message = trycatch.Message();
|
272
289
|
char buf[1000];
|
273
290
|
int len;
|
274
|
-
len = snprintf(buf, sizeof(buf), "%s at %s:%i:%i", *String::Utf8Value(message->Get()),
|
275
|
-
*String::Utf8Value(message->GetScriptResourceName()->ToString()),
|
291
|
+
len = snprintf(buf, sizeof(buf), "%s at %s:%i:%i", *String::Utf8Value(isolate, message->Get()),
|
292
|
+
*String::Utf8Value(isolate, message->GetScriptResourceName()->ToString()),
|
276
293
|
message->GetLineNumber(),
|
277
294
|
message->GetStartColumn());
|
278
295
|
if ((size_t) len >= sizeof(buf)) {
|
@@ -288,9 +305,9 @@ static void prepare_result(MaybeLocal<Value> v8res,
|
|
288
305
|
Local<String> tmp = String::NewFromUtf8(isolate, "JavaScript was terminated (either by timeout or explicitly)");
|
289
306
|
evalRes.message->Reset(isolate, tmp);
|
290
307
|
}
|
291
|
-
if (!trycatch.StackTrace().IsEmpty()) {
|
308
|
+
if (!trycatch.StackTrace(context).IsEmpty()) {
|
292
309
|
evalRes.backtrace = new Persistent<Value>();
|
293
|
-
evalRes.backtrace->Reset(isolate, trycatch.StackTrace()->ToString());
|
310
|
+
evalRes.backtrace->Reset(isolate, trycatch.StackTrace(context).ToLocalChecked()->ToString());
|
294
311
|
}
|
295
312
|
}
|
296
313
|
}
|
@@ -326,13 +343,13 @@ nogvl_context_eval(void* arg) {
|
|
326
343
|
MaybeLocal<Script> parsed_script;
|
327
344
|
|
328
345
|
if (eval_params->filename) {
|
329
|
-
|
346
|
+
origin = new v8::ScriptOrigin(*eval_params->filename);
|
330
347
|
}
|
331
348
|
|
332
349
|
parsed_script = Script::Compile(context, *eval_params->eval, origin);
|
333
350
|
|
334
351
|
if (origin) {
|
335
|
-
|
352
|
+
delete origin;
|
336
353
|
}
|
337
354
|
|
338
355
|
result->parsed = !parsed_script.IsEmpty();
|
@@ -343,8 +360,8 @@ nogvl_context_eval(void* arg) {
|
|
343
360
|
|
344
361
|
MaybeLocal<Value> maybe_value;
|
345
362
|
if (!result->parsed) {
|
346
|
-
|
347
|
-
|
363
|
+
result->message = new Persistent<Value>();
|
364
|
+
result->message->Reset(isolate, trycatch.Exception());
|
348
365
|
} else {
|
349
366
|
// parsing successful
|
350
367
|
if (eval_params->max_memory > 0) {
|
@@ -370,41 +387,41 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
|
|
370
387
|
HandleScope scope(isolate);
|
371
388
|
|
372
389
|
if (value->IsNull() || value->IsUndefined()){
|
373
|
-
|
390
|
+
return Qnil;
|
374
391
|
}
|
375
392
|
|
376
393
|
if (value->IsInt32()) {
|
377
|
-
|
394
|
+
return INT2FIX(value->Int32Value());
|
378
395
|
}
|
379
396
|
|
380
397
|
if (value->IsNumber()) {
|
381
|
-
|
398
|
+
return rb_float_new(value->NumberValue());
|
382
399
|
}
|
383
400
|
|
384
401
|
if (value->IsTrue()) {
|
385
|
-
|
402
|
+
return Qtrue;
|
386
403
|
}
|
387
404
|
|
388
405
|
if (value->IsFalse()) {
|
389
|
-
|
406
|
+
return Qfalse;
|
390
407
|
}
|
391
408
|
|
392
409
|
if (value->IsArray()) {
|
393
410
|
VALUE rb_array = rb_ary_new();
|
394
411
|
Local<Array> arr = Local<Array>::Cast(value);
|
395
412
|
for(uint32_t i=0; i < arr->Length(); i++) {
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
413
|
+
Local<Value> element = arr->Get(i);
|
414
|
+
VALUE rb_elem = convert_v8_to_ruby(isolate, context, element);
|
415
|
+
if (rb_funcall(rb_elem, rb_intern("class"), 0) == rb_cFailedV8Conversion) {
|
416
|
+
return rb_elem;
|
417
|
+
}
|
401
418
|
rb_ary_push(rb_array, rb_elem);
|
402
419
|
}
|
403
420
|
return rb_array;
|
404
421
|
}
|
405
422
|
|
406
423
|
if (value->IsFunction()){
|
407
|
-
|
424
|
+
return rb_funcall(rb_cJavaScriptFunction, rb_intern("new"), 0);
|
408
425
|
}
|
409
426
|
|
410
427
|
if (value->IsDate()){
|
@@ -416,34 +433,34 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
|
|
416
433
|
}
|
417
434
|
|
418
435
|
if (value->IsObject()) {
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
436
|
+
VALUE rb_hash = rb_hash_new();
|
437
|
+
TryCatch trycatch(isolate);
|
438
|
+
|
439
|
+
Local<Object> object = value->ToObject();
|
440
|
+
auto maybe_props = object->GetOwnPropertyNames(context);
|
441
|
+
if (!maybe_props.IsEmpty()) {
|
442
|
+
Local<Array> props = maybe_props.ToLocalChecked();
|
443
|
+
for(uint32_t i=0; i < props->Length(); i++) {
|
444
|
+
Local<Value> key = props->Get(i);
|
445
|
+
VALUE rb_key = convert_v8_to_ruby(isolate, context, key);
|
446
|
+
Local<Value> prop_value = object->Get(key);
|
447
|
+
// this may have failed due to Get raising
|
448
|
+
|
449
|
+
if (trycatch.HasCaught()) {
|
450
|
+
// TODO isolate code that translates execption to ruby
|
451
|
+
// exception so we can properly return it
|
452
|
+
return rb_funcall(rb_cFailedV8Conversion, rb_intern("new"), 1, rb_str_new2(""));
|
453
|
+
}
|
454
|
+
|
455
|
+
VALUE rb_value = convert_v8_to_ruby(isolate, context, prop_value);
|
456
|
+
rb_hash_aset(rb_hash, rb_key, rb_value);
|
457
|
+
}
|
458
|
+
}
|
459
|
+
return rb_hash;
|
443
460
|
}
|
444
461
|
|
445
462
|
Local<String> rstr = value->ToString();
|
446
|
-
return rb_enc_str_new(*String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
463
|
+
return rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
447
464
|
}
|
448
465
|
|
449
466
|
static VALUE convert_v8_to_ruby(Isolate* isolate,
|
@@ -464,7 +481,84 @@ static VALUE convert_v8_to_ruby(Isolate* isolate,
|
|
464
481
|
Local<Value>::New(isolate, value));
|
465
482
|
}
|
466
483
|
|
467
|
-
static
|
484
|
+
static VALUE encode_as_utf8(VALUE string)
|
485
|
+
{
|
486
|
+
return rb_funcall(string, rb_intern("encode"), 1, rb_str_new2("UTF-8"));
|
487
|
+
}
|
488
|
+
|
489
|
+
#ifdef __AVX2__
|
490
|
+
static bool (*best_utf8_validate_func(void))(const char *, size_t)
|
491
|
+
{
|
492
|
+
__builtin_cpu_init();
|
493
|
+
if (__builtin_cpu_supports("avx2")) {
|
494
|
+
return validate_utf8_fast_avx;
|
495
|
+
} else {
|
496
|
+
return validate_utf8_fast;
|
497
|
+
}
|
498
|
+
}
|
499
|
+
#endif
|
500
|
+
|
501
|
+
static inline Local<Value> convert_ruby_str_to_v8(
|
502
|
+
HandleScope& scope, Isolate *isolate, VALUE value)
|
503
|
+
{
|
504
|
+
static const rb_encoding *utf8_enc = rb_utf8_encoding();
|
505
|
+
static const rb_encoding *ascii8bit_enc = rb_ascii8bit_encoding();
|
506
|
+
static const rb_encoding *usascii_enc = rb_usascii_encoding();
|
507
|
+
static const rb_encoding *latin1_enc = rb_enc_find("ISO-8859-1");
|
508
|
+
assert(latin1_enc != nullptr);
|
509
|
+
#ifndef __AVX2__
|
510
|
+
# define validate_utf8 validate_utf8_fast
|
511
|
+
#else
|
512
|
+
static const (*validate_utf8)(const char *, size_t) =
|
513
|
+
best_utf8_validate_func();
|
514
|
+
#endif
|
515
|
+
|
516
|
+
rb_encoding *enc = rb_enc_get(value);
|
517
|
+
char *str = RSTRING_PTR(value);
|
518
|
+
long len = RSTRING_LEN(value);
|
519
|
+
if (len < 0 || len > INT_MAX) {
|
520
|
+
return Null(isolate);
|
521
|
+
}
|
522
|
+
bool is_valid_utf8 = enc == utf8_enc &&
|
523
|
+
validate_utf8(str, static_cast<size_t>(len));
|
524
|
+
|
525
|
+
MaybeLocal<String> v8str;
|
526
|
+
int int_len = static_cast<int>(len);
|
527
|
+
if (is_valid_utf8) {
|
528
|
+
convert_from_utf8:
|
529
|
+
v8str = String::NewFromUtf8(
|
530
|
+
isolate, str, NewStringType::kNormal, int_len);
|
531
|
+
} else if (enc == utf8_enc || enc == ascii8bit_enc ||
|
532
|
+
enc == usascii_enc || enc == latin1_enc ||
|
533
|
+
rb_funcall(value, rb_intern("valid_encoding?"), 0) == Qfalse) {
|
534
|
+
treat_as_latin1:
|
535
|
+
// if ASCII, it could be that the string is invalid
|
536
|
+
// ignore that possibility (effectively treat it as latin1)
|
537
|
+
v8str = String::NewFromOneByte(
|
538
|
+
isolate, reinterpret_cast<uint8_t *>(str),
|
539
|
+
NewStringType::kNormal, int_len);
|
540
|
+
} else {
|
541
|
+
int state;
|
542
|
+
VALUE result = rb_protect(encode_as_utf8, value, &state);
|
543
|
+
|
544
|
+
//Ran into an exception!
|
545
|
+
if (state) {
|
546
|
+
rb_set_errinfo(Qnil);
|
547
|
+
goto treat_as_latin1;
|
548
|
+
} else if (rb_enc_get(result) != utf8_enc) {
|
549
|
+
// conversion did not result in UTF-8. Odd!
|
550
|
+
goto treat_as_latin1;
|
551
|
+
} else {
|
552
|
+
str = RSTRING_PTR(result);
|
553
|
+
int_len = RSTRING_LEN(result);
|
554
|
+
goto convert_from_utf8;
|
555
|
+
}
|
556
|
+
}
|
557
|
+
return v8str.ToLocalChecked();
|
558
|
+
}
|
559
|
+
|
560
|
+
static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value)
|
561
|
+
{
|
468
562
|
EscapableHandleScope scope(isolate);
|
469
563
|
|
470
564
|
Local<Array> array;
|
@@ -477,67 +571,85 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value) {
|
|
477
571
|
VALUE klass;
|
478
572
|
|
479
573
|
switch (TYPE(value)) {
|
480
|
-
|
481
|
-
|
482
|
-
|
574
|
+
case T_FIXNUM:
|
575
|
+
{
|
576
|
+
fixnum = NUM2LONG(value);
|
577
|
+
if (fixnum > INT_MAX)
|
578
|
+
{
|
579
|
+
return scope.Escape(Number::New(isolate, (double)fixnum));
|
580
|
+
}
|
581
|
+
return scope.Escape(Integer::New(isolate, (int)fixnum));
|
582
|
+
}
|
583
|
+
case T_FLOAT:
|
584
|
+
return scope.Escape(Number::New(isolate, NUM2DBL(value)));
|
585
|
+
case T_STRING:
|
586
|
+
return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
|
587
|
+
case T_NIL:
|
588
|
+
return scope.Escape(Null(isolate));
|
589
|
+
case T_TRUE:
|
590
|
+
return scope.Escape(True(isolate));
|
591
|
+
case T_FALSE:
|
592
|
+
return scope.Escape(False(isolate));
|
593
|
+
case T_ARRAY:
|
594
|
+
{
|
595
|
+
length = RARRAY_LEN(value);
|
596
|
+
array = Array::New(isolate, (int)length);
|
597
|
+
for(i=0; i<length; i++) {
|
598
|
+
array->Set(i, convert_ruby_to_v8(isolate, rb_ary_entry(value, i)));
|
599
|
+
}
|
600
|
+
return scope.Escape(array);
|
601
|
+
}
|
602
|
+
case T_HASH:
|
603
|
+
{
|
604
|
+
object = Object::New(isolate);
|
605
|
+
hash_as_array = rb_funcall(value, rb_intern("to_a"), 0);
|
606
|
+
length = RARRAY_LEN(hash_as_array);
|
607
|
+
for(i=0; i<length; i++) {
|
608
|
+
pair = rb_ary_entry(hash_as_array, i);
|
609
|
+
object->Set(convert_ruby_to_v8(isolate, rb_ary_entry(pair, 0)),
|
610
|
+
convert_ruby_to_v8(isolate, rb_ary_entry(pair, 1)));
|
611
|
+
}
|
612
|
+
return scope.Escape(object);
|
613
|
+
}
|
614
|
+
case T_SYMBOL:
|
483
615
|
{
|
484
|
-
|
616
|
+
value = rb_funcall(value, rb_intern("to_s"), 0);
|
617
|
+
return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
|
485
618
|
}
|
486
|
-
|
487
|
-
case T_FLOAT:
|
488
|
-
return scope.Escape(Number::New(isolate, NUM2DBL(value)));
|
489
|
-
case T_STRING:
|
490
|
-
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (int)RSTRING_LEN(value)).ToLocalChecked());
|
491
|
-
case T_NIL:
|
492
|
-
return scope.Escape(Null(isolate));
|
493
|
-
case T_TRUE:
|
494
|
-
return scope.Escape(True(isolate));
|
495
|
-
case T_FALSE:
|
496
|
-
return scope.Escape(False(isolate));
|
497
|
-
case T_ARRAY:
|
498
|
-
length = RARRAY_LEN(value);
|
499
|
-
array = Array::New(isolate, (int)length);
|
500
|
-
for(i=0; i<length; i++) {
|
501
|
-
array->Set(i, convert_ruby_to_v8(isolate, rb_ary_entry(value, i)));
|
502
|
-
}
|
503
|
-
return scope.Escape(array);
|
504
|
-
case T_HASH:
|
505
|
-
object = Object::New(isolate);
|
506
|
-
hash_as_array = rb_funcall(value, rb_intern("to_a"), 0);
|
507
|
-
length = RARRAY_LEN(hash_as_array);
|
508
|
-
for(i=0; i<length; i++) {
|
509
|
-
pair = rb_ary_entry(hash_as_array, i);
|
510
|
-
object->Set(convert_ruby_to_v8(isolate, rb_ary_entry(pair, 0)),
|
511
|
-
convert_ruby_to_v8(isolate, rb_ary_entry(pair, 1)));
|
512
|
-
}
|
513
|
-
return scope.Escape(object);
|
514
|
-
case T_SYMBOL:
|
515
|
-
value = rb_funcall(value, rb_intern("to_s"), 0);
|
516
|
-
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (int)RSTRING_LEN(value)).ToLocalChecked());
|
517
|
-
case T_DATA:
|
518
|
-
klass = rb_funcall(value, rb_intern("class"), 0);
|
519
|
-
if (klass == rb_cTime || klass == rb_cDateTime)
|
619
|
+
case T_DATA:
|
520
620
|
{
|
521
|
-
|
621
|
+
klass = rb_funcall(value, rb_intern("class"), 0);
|
622
|
+
if (klass == rb_cTime || klass == rb_cDateTime)
|
522
623
|
{
|
523
|
-
|
624
|
+
if (klass == rb_cDateTime)
|
625
|
+
{
|
626
|
+
value = rb_funcall(value, rb_intern("to_time"), 0);
|
627
|
+
}
|
628
|
+
value = rb_funcall(value, rb_intern("to_f"), 0);
|
629
|
+
return scope.Escape(Date::New(isolate, NUM2DBL(value) * 1000));
|
630
|
+
}
|
631
|
+
// break intentionally missing
|
632
|
+
}
|
633
|
+
case T_OBJECT:
|
634
|
+
case T_CLASS:
|
635
|
+
case T_ICLASS:
|
636
|
+
case T_MODULE:
|
637
|
+
case T_REGEXP:
|
638
|
+
case T_MATCH:
|
639
|
+
case T_STRUCT:
|
640
|
+
case T_BIGNUM:
|
641
|
+
case T_FILE:
|
642
|
+
case T_UNDEF:
|
643
|
+
case T_NODE:
|
644
|
+
default:
|
645
|
+
{
|
646
|
+
if (rb_respond_to(value, rb_intern("to_s"))) {
|
647
|
+
// TODO: if this throws we're screwed
|
648
|
+
value = rb_funcall(value, rb_intern("to_s"), 0);
|
649
|
+
return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
|
524
650
|
}
|
525
|
-
|
526
|
-
return scope.Escape(Date::New(isolate, NUM2DBL(value) * 1000));
|
651
|
+
return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
|
527
652
|
}
|
528
|
-
case T_OBJECT:
|
529
|
-
case T_CLASS:
|
530
|
-
case T_ICLASS:
|
531
|
-
case T_MODULE:
|
532
|
-
case T_REGEXP:
|
533
|
-
case T_MATCH:
|
534
|
-
case T_STRUCT:
|
535
|
-
case T_BIGNUM:
|
536
|
-
case T_FILE:
|
537
|
-
case T_UNDEF:
|
538
|
-
case T_NODE:
|
539
|
-
default:
|
540
|
-
return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
|
541
653
|
}
|
542
654
|
|
543
655
|
}
|
@@ -686,13 +798,13 @@ static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
|
|
686
798
|
// the ruby lock is needed if this isn't a new isolate
|
687
799
|
IsolateInfo::Lock ruby_lock(isolate_info->mutex);
|
688
800
|
Locker lock(isolate_info->isolate);
|
689
|
-
|
690
|
-
|
801
|
+
Isolate::Scope isolate_scope(isolate_info->isolate);
|
802
|
+
HandleScope handle_scope(isolate_info->isolate);
|
691
803
|
|
692
|
-
|
804
|
+
Local<Context> context = Context::New(isolate_info->isolate);
|
693
805
|
|
694
|
-
|
695
|
-
|
806
|
+
context_info->context = new Persistent<Context>();
|
807
|
+
context_info->context->Reset(isolate_info->isolate, context);
|
696
808
|
}
|
697
809
|
|
698
810
|
if (Qnil == rb_cDateTime && rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, rb_str_new2("DateTime")) == Qtrue)
|
@@ -776,7 +888,7 @@ static VALUE convert_result_to_ruby(VALUE self /* context */,
|
|
776
888
|
|
777
889
|
if (result.json) {
|
778
890
|
Local<String> rstr = tmp->ToString();
|
779
|
-
VALUE json_string = rb_enc_str_new(*String::Utf8Value(rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
891
|
+
VALUE json_string = rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
|
780
892
|
ret = rb_funcall(rb_mJSON, rb_intern("parse"), 1, json_string);
|
781
893
|
} else {
|
782
894
|
ret = convert_v8_to_ruby(isolate, *p_ctx, tmp);
|
@@ -814,45 +926,45 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str, VALUE filename) {
|
|
814
926
|
}
|
815
927
|
|
816
928
|
{
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
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
|
-
|
929
|
+
Locker lock(isolate);
|
930
|
+
Isolate::Scope isolate_scope(isolate);
|
931
|
+
HandleScope handle_scope(isolate);
|
932
|
+
|
933
|
+
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(str),
|
934
|
+
NewStringType::kNormal, (int)RSTRING_LEN(str)).ToLocalChecked();
|
935
|
+
|
936
|
+
Local<String> local_filename;
|
937
|
+
|
938
|
+
if (filename != Qnil) {
|
939
|
+
local_filename = String::NewFromUtf8(isolate, RSTRING_PTR(filename),
|
940
|
+
NewStringType::kNormal, (int)RSTRING_LEN(filename)).ToLocalChecked();
|
941
|
+
eval_params.filename = &local_filename;
|
942
|
+
} else {
|
943
|
+
eval_params.filename = NULL;
|
944
|
+
}
|
945
|
+
|
946
|
+
eval_params.context_info = context_info;
|
947
|
+
eval_params.eval = &eval;
|
948
|
+
eval_params.result = &eval_result;
|
949
|
+
eval_params.timeout = 0;
|
950
|
+
eval_params.max_memory = 0;
|
951
|
+
VALUE timeout = rb_iv_get(self, "@timeout");
|
952
|
+
if (timeout != Qnil) {
|
953
|
+
eval_params.timeout = (useconds_t)NUM2LONG(timeout);
|
954
|
+
}
|
955
|
+
|
956
|
+
VALUE mem_softlimit = rb_iv_get(self, "@max_memory");
|
957
|
+
if (mem_softlimit != Qnil) {
|
958
|
+
eval_params.max_memory = (size_t)NUM2ULONG(mem_softlimit);
|
959
|
+
}
|
960
|
+
|
961
|
+
eval_result.message = NULL;
|
962
|
+
eval_result.backtrace = NULL;
|
851
963
|
|
852
964
|
#if RUBY_API_VERSION_MAJOR > 1
|
853
|
-
|
965
|
+
rb_thread_call_without_gvl(nogvl_context_eval, &eval_params, unblock_eval, &eval_params);
|
854
966
|
#else
|
855
|
-
|
967
|
+
rb_thread_blocking_region(nogvl_context_eval, &eval_params, unblock_eval, &eval_params);
|
856
968
|
#endif
|
857
969
|
}
|
858
970
|
|
@@ -866,17 +978,16 @@ typedef struct {
|
|
866
978
|
bool failed;
|
867
979
|
} protected_callback_data;
|
868
980
|
|
869
|
-
static
|
870
|
-
VALUE protected_callback(VALUE rdata) {
|
981
|
+
static VALUE protected_callback(VALUE rdata) {
|
871
982
|
protected_callback_data* data = (protected_callback_data*)rdata;
|
872
983
|
VALUE result;
|
873
984
|
|
874
985
|
if (data->length > 0) {
|
875
|
-
|
876
|
-
|
877
|
-
|
986
|
+
result = rb_funcall2(data->callback, rb_intern("call"), data->length,
|
987
|
+
RARRAY_PTR(data->ruby_args));
|
988
|
+
RB_GC_GUARD(data->ruby_args);
|
878
989
|
} else {
|
879
|
-
|
990
|
+
result = rb_funcall(data->callback, rb_intern("call"), 0);
|
880
991
|
}
|
881
992
|
return result;
|
882
993
|
}
|
@@ -913,16 +1024,16 @@ gvl_ruby_callback(void* data) {
|
|
913
1024
|
ContextInfo* context_info;
|
914
1025
|
Data_Get_Struct(parent, ContextInfo, context_info);
|
915
1026
|
|
916
|
-
|
917
|
-
|
918
|
-
|
1027
|
+
if (length > 0) {
|
1028
|
+
ruby_args = rb_ary_tmp_new(length);
|
1029
|
+
}
|
919
1030
|
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
1031
|
+
for (int i = 0; i < length; i++) {
|
1032
|
+
Local<Value> value = ((*args)[i]).As<Value>();
|
1033
|
+
VALUE tmp = convert_v8_to_ruby(args->GetIsolate(),
|
1034
|
+
*context_info->context, value);
|
1035
|
+
rb_ary_push(ruby_args, tmp);
|
1036
|
+
}
|
926
1037
|
}
|
927
1038
|
|
928
1039
|
// may raise exception stay clear of handle scope
|
@@ -933,31 +1044,31 @@ gvl_ruby_callback(void* data) {
|
|
933
1044
|
callback_data.failed = false;
|
934
1045
|
|
935
1046
|
if ((bool)args->GetIsolate()->GetData(DO_TERMINATE) == true) {
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
1047
|
+
args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Terminated execution during transition from Ruby to JS"));
|
1048
|
+
args->GetIsolate()->TerminateExecution();
|
1049
|
+
if (length > 0) {
|
1050
|
+
rb_ary_clear(ruby_args);
|
1051
|
+
rb_gc_force_recycle(ruby_args);
|
1052
|
+
}
|
1053
|
+
return NULL;
|
943
1054
|
}
|
944
1055
|
|
945
1056
|
result = rb_rescue2((VALUE(*)(...))&protected_callback, (VALUE)(&callback_data),
|
946
|
-
|
1057
|
+
(VALUE(*)(...))&rescue_callback, (VALUE)(&callback_data), rb_eException, (VALUE)0);
|
947
1058
|
|
948
1059
|
if(callback_data.failed) {
|
949
|
-
|
950
|
-
|
1060
|
+
rb_iv_set(parent, "@current_exception", result);
|
1061
|
+
args->GetIsolate()->ThrowException(String::NewFromUtf8(args->GetIsolate(), "Ruby exception"));
|
951
1062
|
}
|
952
1063
|
else {
|
953
|
-
|
954
|
-
|
955
|
-
|
1064
|
+
HandleScope scope(args->GetIsolate());
|
1065
|
+
Handle<Value> v8_result = convert_ruby_to_v8(args->GetIsolate(), result);
|
1066
|
+
args->GetReturnValue().Set(v8_result);
|
956
1067
|
}
|
957
1068
|
|
958
1069
|
if (length > 0) {
|
959
|
-
|
960
|
-
|
1070
|
+
rb_ary_clear(ruby_args);
|
1071
|
+
rb_gc_force_recycle(ruby_args);
|
961
1072
|
}
|
962
1073
|
|
963
1074
|
if ((bool)args->GetIsolate()->GetData(DO_TERMINATE) == true) {
|
@@ -976,11 +1087,11 @@ static void ruby_callback(const FunctionCallbackInfo<Value>& args) {
|
|
976
1087
|
bool has_gvl = (bool)args.GetIsolate()->GetData(IN_GVL);
|
977
1088
|
|
978
1089
|
if(has_gvl) {
|
979
|
-
|
1090
|
+
gvl_ruby_callback((void*)&args);
|
980
1091
|
} else {
|
981
|
-
|
982
|
-
|
983
|
-
|
1092
|
+
args.GetIsolate()->SetData(IN_GVL, (void*)true);
|
1093
|
+
rb_thread_call_with_gvl(gvl_ruby_callback, (void*)(&args));
|
1094
|
+
args.GetIsolate()->SetData(IN_GVL, (void*)false);
|
984
1095
|
}
|
985
1096
|
}
|
986
1097
|
|
@@ -1001,46 +1112,46 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
1001
1112
|
Isolate* isolate = context_info->isolate_info->isolate;
|
1002
1113
|
|
1003
1114
|
{
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
Local<Context> context = context_info->context->Get(isolate);
|
1009
|
-
Context::Scope context_scope(context);
|
1115
|
+
Locker lock(isolate);
|
1116
|
+
Isolate::Scope isolate_scope(isolate);
|
1117
|
+
HandleScope handle_scope(isolate);
|
1010
1118
|
|
1011
|
-
|
1012
|
-
|
1119
|
+
Local<Context> context = context_info->context->Get(isolate);
|
1120
|
+
Context::Scope context_scope(context);
|
1013
1121
|
|
1014
|
-
|
1015
|
-
|
1016
|
-
Data_Get_Struct(self, VALUE, self_copy);
|
1017
|
-
*self_copy = self;
|
1122
|
+
Local<String> v8_str = String::NewFromUtf8(isolate, RSTRING_PTR(name),
|
1123
|
+
NewStringType::kNormal, (int)RSTRING_LEN(name)).ToLocalChecked();
|
1018
1124
|
|
1019
|
-
|
1125
|
+
// copy self so we can access from v8 external
|
1126
|
+
VALUE* self_copy;
|
1127
|
+
Data_Get_Struct(self, VALUE, self_copy);
|
1128
|
+
*self_copy = self;
|
1020
1129
|
|
1021
|
-
|
1022
|
-
context->Global()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1023
|
-
} else {
|
1130
|
+
Local<Value> external = External::New(isolate, self_copy);
|
1024
1131
|
|
1025
|
-
|
1026
|
-
|
1132
|
+
if (parent_object == Qnil) {
|
1133
|
+
context->Global()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1134
|
+
} else {
|
1027
1135
|
|
1028
|
-
|
1029
|
-
|
1030
|
-
parse_error = true;
|
1031
|
-
} else {
|
1032
|
-
MaybeLocal<Value> maybe_value = parsed_script.ToLocalChecked()->Run(context);
|
1033
|
-
attach_error = true;
|
1136
|
+
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(parent_object_eval),
|
1137
|
+
NewStringType::kNormal, (int)RSTRING_LEN(parent_object_eval)).ToLocalChecked();
|
1034
1138
|
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1139
|
+
MaybeLocal<Script> parsed_script = Script::Compile(context, eval);
|
1140
|
+
if (parsed_script.IsEmpty()) {
|
1141
|
+
parse_error = true;
|
1142
|
+
} else {
|
1143
|
+
MaybeLocal<Value> maybe_value = parsed_script.ToLocalChecked()->Run(context);
|
1144
|
+
attach_error = true;
|
1145
|
+
|
1146
|
+
if (!maybe_value.IsEmpty()) {
|
1147
|
+
Local<Value> value = maybe_value.ToLocalChecked();
|
1148
|
+
if (value->IsObject()){
|
1149
|
+
value.As<Object>()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
|
1150
|
+
attach_error = false;
|
1151
|
+
}
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
}
|
1044
1155
|
}
|
1045
1156
|
|
1046
1157
|
// always raise out of V8 context
|
@@ -1069,19 +1180,19 @@ static VALUE rb_context_isolate_mutex(VALUE self) {
|
|
1069
1180
|
void free_isolate(IsolateInfo* isolate_info) {
|
1070
1181
|
|
1071
1182
|
if (isolate_info->isolate) {
|
1072
|
-
|
1183
|
+
Locker lock(isolate_info->isolate);
|
1073
1184
|
}
|
1074
1185
|
|
1075
1186
|
if (isolate_info->isolate) {
|
1076
1187
|
if (isolate_info->interrupted) {
|
1077
1188
|
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");
|
1078
1189
|
} else {
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1190
|
+
|
1191
|
+
if (isolate_info->pid != getpid()) {
|
1192
|
+
fprintf(stderr, "WARNING: V8 isolate was forked, it can not be disposed and memory will not be reclaimed till the Ruby process exits.\n");
|
1193
|
+
} else {
|
1194
|
+
isolate_info->isolate->Dispose();
|
1195
|
+
}
|
1085
1196
|
}
|
1086
1197
|
isolate_info->isolate = NULL;
|
1087
1198
|
}
|
@@ -1094,21 +1205,50 @@ void free_isolate(IsolateInfo* isolate_info) {
|
|
1094
1205
|
delete isolate_info->allocator;
|
1095
1206
|
}
|
1096
1207
|
|
1208
|
+
static void *free_context_raw(void* arg) {
|
1209
|
+
ContextInfo* context_info = (ContextInfo*)arg;
|
1210
|
+
IsolateInfo* isolate_info = context_info->isolate_info;
|
1211
|
+
Persistent<Context>* context = context_info->context;
|
1212
|
+
|
1213
|
+
if (context && isolate_info && isolate_info->isolate) {
|
1214
|
+
Locker lock(isolate_info->isolate);
|
1215
|
+
v8::Isolate::Scope isolate_scope(isolate_info->isolate);
|
1216
|
+
context->Reset();
|
1217
|
+
delete context;
|
1218
|
+
}
|
1219
|
+
|
1220
|
+
if (isolate_info) {
|
1221
|
+
isolate_info->release();
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
xfree(context_info);
|
1225
|
+
return NULL;
|
1226
|
+
}
|
1227
|
+
|
1097
1228
|
// destroys everything except freeing the ContextInfo struct (see deallocate())
|
1098
1229
|
static void free_context(ContextInfo* context_info) {
|
1099
1230
|
|
1100
1231
|
IsolateInfo* isolate_info = context_info->isolate_info;
|
1101
1232
|
|
1233
|
+
ContextInfo* context_info_copy = ALLOC(ContextInfo);
|
1234
|
+
context_info_copy->isolate_info = context_info->isolate_info;
|
1235
|
+
context_info_copy->context = context_info->context;
|
1236
|
+
|
1237
|
+
if (isolate_info && isolate_info->refs() > 1) {
|
1238
|
+
pthread_t free_context_thread;
|
1239
|
+
if (pthread_create(&free_context_thread, NULL, free_context_raw, (void*)context_info_copy)) {
|
1240
|
+
fprintf(stderr, "WARNING failed to release memory in MiniRacer, thread to release could not be created, process will leak memory\n");
|
1241
|
+
}
|
1242
|
+
|
1243
|
+
} else {
|
1244
|
+
free_context_raw(context_info_copy);
|
1245
|
+
}
|
1246
|
+
|
1102
1247
|
if (context_info->context && isolate_info && isolate_info->isolate) {
|
1103
|
-
|
1104
|
-
v8::Isolate::Scope isolate_scope(isolate_info->isolate);
|
1105
|
-
context_info->context->Reset();
|
1106
|
-
delete context_info->context;
|
1107
|
-
context_info->context = NULL;
|
1248
|
+
context_info->context = NULL;
|
1108
1249
|
}
|
1109
1250
|
|
1110
1251
|
if (isolate_info) {
|
1111
|
-
isolate_info->release();
|
1112
1252
|
context_info->isolate_info = NULL;
|
1113
1253
|
}
|
1114
1254
|
}
|
@@ -1191,20 +1331,20 @@ rb_heap_stats(VALUE self) {
|
|
1191
1331
|
|
1192
1332
|
if (!isolate) {
|
1193
1333
|
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1334
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(0));
|
1335
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(0));
|
1336
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(0));
|
1337
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(0));
|
1338
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(0));
|
1199
1339
|
|
1200
1340
|
} else {
|
1201
|
-
|
1341
|
+
isolate->GetHeapStatistics(&stats);
|
1202
1342
|
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1343
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(stats.total_physical_size()));
|
1344
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(stats.total_heap_size_executable()));
|
1345
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(stats.total_heap_size()));
|
1346
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(stats.used_heap_size()));
|
1347
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(stats.heap_size_limit()));
|
1208
1348
|
}
|
1209
1349
|
|
1210
1350
|
return rval;
|
@@ -1238,6 +1378,19 @@ rb_context_dispose(VALUE self) {
|
|
1238
1378
|
return Qnil;
|
1239
1379
|
}
|
1240
1380
|
|
1381
|
+
static VALUE
|
1382
|
+
rb_context_low_memory_notification(VALUE self) {
|
1383
|
+
|
1384
|
+
ContextInfo* context_info;
|
1385
|
+
Data_Get_Struct(self, ContextInfo, context_info);
|
1386
|
+
|
1387
|
+
if (context_info->isolate_info && context_info->isolate_info->isolate) {
|
1388
|
+
context_info->isolate_info->isolate->LowMemoryNotification();
|
1389
|
+
}
|
1390
|
+
|
1391
|
+
return Qnil;
|
1392
|
+
}
|
1393
|
+
|
1241
1394
|
#if RUBY_API_VERSION_MAJOR > 1
|
1242
1395
|
static void*
|
1243
1396
|
#else
|
@@ -1281,8 +1434,7 @@ static void unblock_function(void *args) {
|
|
1281
1434
|
call->context_info->isolate_info->interrupted = true;
|
1282
1435
|
}
|
1283
1436
|
|
1284
|
-
static VALUE
|
1285
|
-
rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
1437
|
+
static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
1286
1438
|
ContextInfo* context_info;
|
1287
1439
|
FunctionCall call;
|
1288
1440
|
VALUE *call_argv = NULL;
|
@@ -1315,7 +1467,6 @@ rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1315
1467
|
}
|
1316
1468
|
|
1317
1469
|
bool missingFunction = false;
|
1318
|
-
|
1319
1470
|
{
|
1320
1471
|
Locker lock(isolate);
|
1321
1472
|
Isolate::Scope isolate_scope(isolate);
|
@@ -1326,38 +1477,38 @@ rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1326
1477
|
|
1327
1478
|
// examples of such usage can be found in
|
1328
1479
|
// https://github.com/v8/v8/blob/36b32aa28db5e993312f4588d60aad5c8330c8a5/test/cctest/test-api.cc#L15711
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
if (fun_argc > 0) {
|
1341
|
-
call.argv = (v8::Local<Value> *) malloc(sizeof(void *) * fun_argc);
|
1342
|
-
if (!call.argv) {
|
1343
|
-
return Qnil;
|
1344
|
-
}
|
1345
|
-
for(int i=0; i < fun_argc; i++) {
|
1346
|
-
call.argv[i] = convert_ruby_to_v8(isolate, call_argv[i]);
|
1347
|
-
}
|
1348
|
-
}
|
1349
|
-
#if RUBY_API_VERSION_MAJOR > 1
|
1350
|
-
rb_thread_call_without_gvl(nogvl_context_call, &call, unblock_function, &call);
|
1351
|
-
#else
|
1352
|
-
rb_thread_blocking_region(nogvl_context_call, &call, unblock_function, &call);
|
1353
|
-
#endif
|
1354
|
-
free(call.argv);
|
1480
|
+
Local<String> fname = String::NewFromUtf8(isolate, call.function_name);
|
1481
|
+
MaybeLocal<v8::Value> val = context->Global()->Get(fname);
|
1482
|
+
|
1483
|
+
if (val.IsEmpty() || !val.ToLocalChecked()->IsFunction()) {
|
1484
|
+
missingFunction = true;
|
1485
|
+
} else {
|
1486
|
+
|
1487
|
+
Local<v8::Function> fun = Local<v8::Function>::Cast(val.ToLocalChecked());
|
1488
|
+
call.fun = fun;
|
1489
|
+
int fun_argc = call.argc;
|
1355
1490
|
|
1356
|
-
|
1491
|
+
if (fun_argc > 0) {
|
1492
|
+
call.argv = (v8::Local<Value> *) malloc(sizeof(void *) * fun_argc);
|
1493
|
+
if (!call.argv) {
|
1494
|
+
return Qnil;
|
1495
|
+
}
|
1496
|
+
for(int i=0; i < fun_argc; i++) {
|
1497
|
+
call.argv[i] = convert_ruby_to_v8(isolate, call_argv[i]);
|
1498
|
+
}
|
1499
|
+
}
|
1500
|
+
#if RUBY_API_VERSION_MAJOR > 1
|
1501
|
+
rb_thread_call_without_gvl(nogvl_context_call, &call, unblock_function, &call);
|
1502
|
+
#else
|
1503
|
+
rb_thread_blocking_region(nogvl_context_call, &call, unblock_function, &call);
|
1504
|
+
#endif
|
1505
|
+
free(call.argv);
|
1506
|
+
|
1507
|
+
}
|
1357
1508
|
}
|
1358
1509
|
|
1359
1510
|
if (missingFunction) {
|
1360
|
-
|
1511
|
+
rb_raise(rb_eScriptRuntimeError, "Unknown JavaScript method invoked");
|
1361
1512
|
}
|
1362
1513
|
|
1363
1514
|
return convert_result_to_ruby(self, call.result);
|
@@ -1382,52 +1533,52 @@ extern "C" {
|
|
1382
1533
|
{
|
1383
1534
|
VALUE rb_mSqreen = rb_define_module("Sqreen");
|
1384
1535
|
VALUE rb_mMiniRacer = rb_define_module_under(rb_mSqreen, "MiniRacer");
|
1385
|
-
|
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
|
-
|
1536
|
+
rb_cContext = rb_define_class_under(rb_mMiniRacer, "Context", rb_cObject);
|
1537
|
+
rb_cSnapshot = rb_define_class_under(rb_mMiniRacer, "Snapshot", rb_cObject);
|
1538
|
+
rb_cIsolate = rb_define_class_under(rb_mMiniRacer, "Isolate", rb_cObject);
|
1539
|
+
VALUE rb_cPlatform = rb_define_class_under(rb_mMiniRacer, "Platform", rb_cObject);
|
1540
|
+
|
1541
|
+
VALUE rb_eError = rb_define_class_under(rb_mMiniRacer, "Error", rb_eStandardError);
|
1542
|
+
|
1543
|
+
VALUE rb_eEvalError = rb_define_class_under(rb_mMiniRacer, "EvalError", rb_eError);
|
1544
|
+
rb_eScriptTerminatedError = rb_define_class_under(rb_mMiniRacer, "ScriptTerminatedError", rb_eEvalError);
|
1545
|
+
rb_eV8OutOfMemoryError = rb_define_class_under(rb_mMiniRacer, "V8OutOfMemoryError", rb_eEvalError);
|
1546
|
+
rb_eParseError = rb_define_class_under(rb_mMiniRacer, "ParseError", rb_eEvalError);
|
1547
|
+
rb_eScriptRuntimeError = rb_define_class_under(rb_mMiniRacer, "RuntimeError", rb_eEvalError);
|
1548
|
+
|
1549
|
+
rb_cJavaScriptFunction = rb_define_class_under(rb_mMiniRacer, "JavaScriptFunction", rb_cObject);
|
1550
|
+
rb_eSnapshotError = rb_define_class_under(rb_mMiniRacer, "SnapshotError", rb_eError);
|
1551
|
+
rb_ePlatformAlreadyInitializedError = rb_define_class_under(rb_mMiniRacer, "PlatformAlreadyInitialized", rb_eError);
|
1552
|
+
rb_cFailedV8Conversion = rb_define_class_under(rb_mMiniRacer, "FailedV8Conversion", rb_cObject);
|
1553
|
+
rb_mJSON = rb_define_module("JSON");
|
1554
|
+
|
1555
|
+
VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
|
1556
|
+
|
1557
|
+
rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
|
1558
|
+
rb_define_method(rb_cContext, "dispose_unsafe", (VALUE(*)(...))&rb_context_dispose, 0);
|
1559
|
+
rb_define_method(rb_cContext, "low_memory_notification", (VALUE(*)(...))&rb_context_low_memory_notification, 0);
|
1560
|
+
rb_define_method(rb_cContext, "heap_stats", (VALUE(*)(...))&rb_heap_stats, 0);
|
1561
|
+
rb_define_private_method(rb_cContext, "create_isolate_value",(VALUE(*)(...))&rb_context_create_isolate_value, 0);
|
1562
|
+
rb_define_private_method(rb_cContext, "eval_unsafe",(VALUE(*)(...))&rb_context_eval_unsafe, 2);
|
1563
|
+
rb_define_private_method(rb_cContext, "call_unsafe", (VALUE(*)(...))&rb_context_call_unsafe, -1);
|
1564
|
+
rb_define_private_method(rb_cContext, "isolate_mutex", (VALUE(*)(...))&rb_context_isolate_mutex, 0);
|
1565
|
+
rb_define_private_method(rb_cContext, "init_unsafe",(VALUE(*)(...))&rb_context_init_unsafe, 2);
|
1566
|
+
|
1567
|
+
rb_define_alloc_func(rb_cContext, allocate);
|
1568
|
+
rb_define_alloc_func(rb_cSnapshot, allocate_snapshot);
|
1569
|
+
rb_define_alloc_func(rb_cIsolate, allocate_isolate);
|
1570
|
+
|
1571
|
+
rb_define_private_method(rb_cExternalFunction, "notify_v8", (VALUE(*)(...))&rb_external_function_notify_v8, 0);
|
1572
|
+
rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
|
1573
|
+
|
1574
|
+
rb_define_method(rb_cSnapshot, "size", (VALUE(*)(...))&rb_snapshot_size, 0);
|
1575
|
+
rb_define_method(rb_cSnapshot, "dump", (VALUE(*)(...))&rb_snapshot_dump, 0);
|
1576
|
+
rb_define_method(rb_cSnapshot, "warmup_unsafe!", (VALUE(*)(...))&rb_snapshot_warmup_unsafe, 1);
|
1577
|
+
rb_define_private_method(rb_cSnapshot, "load", (VALUE(*)(...))&rb_snapshot_load, 1);
|
1578
|
+
|
1579
|
+
rb_define_method(rb_cIsolate, "idle_notification", (VALUE(*)(...))&rb_isolate_idle_notification, 1);
|
1580
|
+
rb_define_private_method(rb_cIsolate, "init_with_snapshot",(VALUE(*)(...))&rb_isolate_init_with_snapshot, 1);
|
1581
|
+
|
1582
|
+
rb_define_singleton_method(rb_cPlatform, "set_flag_as_str!", (VALUE(*)(...))&rb_platform_set_flag_as_str, 1);
|
1431
1583
|
}
|
1432
|
-
|
1433
1584
|
}
|