mini_racer 0.5.0.pre → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +30 -0
- data/Rakefile +1 -1
- data/ext/mini_racer_extension/extconf.rb +25 -13
- data/ext/mini_racer_extension/mini_racer_extension.cc +156 -114
- data/ext/mini_racer_loader/extconf.rb +1 -1
- data/lib/mini_racer/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e832863760637f983976194ebef263d8815c149d48ff26c7200367ab33640dda
|
4
|
+
data.tar.gz: 7c1c393ae6403a75d2a413395d56e7d5f3affe706b81c121273b4c6b5d471bf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4504cb3a564e5b311b65de74bac321b058995af17df47f9f3dc01fcb589a87eebfda55497e0ddb135a2ab15ef1818760652561d434d3f497c0dbd036451934c6
|
7
|
+
data.tar.gz: b83df123a61092ab4041212bb6e4f15b276d5e32e8be8d2b5cbc014988b8cf20ed0e0b3b30595de53ca4c0d599a86112d695009cda13891fe177742aff7d911e
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,35 @@
|
|
1
|
+
- 17-01-2021
|
2
|
+
|
3
|
+
- 0.6.2
|
4
|
+
|
5
|
+
- Fix support for compilation on 2.6, llvm compiles
|
6
|
+
- Stability patches to handle rare memory leaks
|
7
|
+
- Corrected re-raising of exceptions to support strings
|
8
|
+
- During early termination of context under certain conditions MiniRacer could crash
|
9
|
+
|
10
|
+
|
11
|
+
- 31-12-2021
|
12
|
+
|
13
|
+
- 0.6.1
|
14
|
+
|
15
|
+
- Added support for single threaded platform: `MiniRacer::Platform.set_flags! :single_threaded`
|
16
|
+
must be called prior to booting ANY MiniRacer::Context
|
17
|
+
|
18
|
+
- 0.6.0
|
19
|
+
|
20
|
+
- Ruby 3.1 support
|
21
|
+
- Fixes memory leak in heap snapshotting
|
22
|
+
- Improved compilation ergonomics in clang
|
23
|
+
- Migrated internal storage in c extension to TypedData
|
24
|
+
|
1
25
|
- 11-04-2021
|
2
26
|
|
27
|
+
- 0.5.0
|
28
|
+
- Fixes issues on aarch (Apple M1)
|
29
|
+
- Update to use libv8-node 16.x (#210) [Loic Nageleisen]
|
30
|
+
- FEATURE: Configurable max marshal stack depth (#202) [seanmakesgames]
|
31
|
+
- Ruby 2.3 and 2.4 are EOL, we no longer support them
|
32
|
+
|
3
33
|
- 0.4.0
|
4
34
|
|
5
35
|
- FEATURE: upgrade to libv8 node 15.14.0 (v8 8.6.395.17)
|
data/Rakefile
CHANGED
@@ -92,5 +92,5 @@ task :lint do
|
|
92
92
|
portability-*
|
93
93
|
readability-*).join(',')
|
94
94
|
|
95
|
-
sh RbConfig::expand("clang-tidy -checks='#{checks}' ext/mini_racer_extension/mini_racer_extension.cc -- #$INCFLAGS #$
|
95
|
+
sh RbConfig::expand("clang-tidy -checks='#{checks}' ext/mini_racer_extension/mini_racer_extension.cc -- #$INCFLAGS #$CXXFLAGS", conf)
|
96
96
|
end
|
@@ -7,18 +7,25 @@ IS_DARWIN = RUBY_PLATFORM =~ /darwin/
|
|
7
7
|
|
8
8
|
have_library('pthread')
|
9
9
|
have_library('objc') if IS_DARWIN
|
10
|
-
$
|
11
|
-
$
|
12
|
-
$
|
13
|
-
$
|
14
|
-
$
|
15
|
-
$
|
16
|
-
#$
|
17
|
-
$
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
$CXXFLAGS += " -Wall" unless $CXXFLAGS.split.include? "-Wall"
|
11
|
+
$CXXFLAGS += " -g" unless $CXXFLAGS.split.include? "-g"
|
12
|
+
$CXXFLAGS += " -rdynamic" unless $CXXFLAGS.split.include? "-rdynamic"
|
13
|
+
$CXXFLAGS += " -fPIC" unless $CXXFLAGS.split.include? "-rdynamic" or IS_DARWIN
|
14
|
+
$CXXFLAGS += " -std=c++14"
|
15
|
+
$CXXFLAGS += " -fpermissive"
|
16
|
+
#$CXXFLAGS += " -DV8_COMPRESS_POINTERS"
|
17
|
+
$CXXFLAGS += " -fvisibility=hidden "
|
18
|
+
|
19
|
+
# __declspec gets used by clang via ruby 3.x headers...
|
20
|
+
$CXXFLAGS += " -fms-extensions"
|
21
|
+
|
22
|
+
$CXXFLAGS += " -Wno-reserved-user-defined-literal" if IS_DARWIN
|
23
|
+
|
24
|
+
if IS_DARWIN
|
25
|
+
$LDFLAGS.insert(0, " -stdlib=libc++ ")
|
26
|
+
else
|
27
|
+
$LDFLAGS.insert(0, " -lstdc++ ")
|
28
|
+
end
|
22
29
|
|
23
30
|
# check for missing symbols at link time
|
24
31
|
# $LDFLAGS += " -Wl,--no-undefined " unless IS_DARWIN
|
@@ -64,8 +71,13 @@ end
|
|
64
71
|
Libv8::Node.configure_makefile
|
65
72
|
|
66
73
|
if enable_config('asan')
|
67
|
-
$
|
74
|
+
$CXXFLAGS.insert(0, " -fsanitize=address ")
|
68
75
|
$LDFLAGS.insert(0, " -fsanitize=address ")
|
69
76
|
end
|
70
77
|
|
78
|
+
# there doesn't seem to be a CPP macro for this in Ruby 2.6:
|
79
|
+
if RUBY_ENGINE == 'ruby'
|
80
|
+
$CPPFLAGS += ' -DENGINE_IS_CRUBY '
|
81
|
+
end
|
82
|
+
|
71
83
|
create_makefile 'mini_racer_extension'
|
@@ -2,6 +2,7 @@
|
|
2
2
|
#include <ruby.h>
|
3
3
|
#include <ruby/thread.h>
|
4
4
|
#include <ruby/io.h>
|
5
|
+
#include <ruby/version.h>
|
5
6
|
#include <v8.h>
|
6
7
|
#include <v8-profiler.h>
|
7
8
|
#include <libplatform/libplatform.h>
|
@@ -11,6 +12,15 @@
|
|
11
12
|
#include <mutex>
|
12
13
|
#include <atomic>
|
13
14
|
#include <math.h>
|
15
|
+
#include <errno.h>
|
16
|
+
|
17
|
+
/* workaround C Ruby <= 2.x problems w/ clang in C++ mode */
|
18
|
+
#if defined(ENGINE_IS_CRUBY) && \
|
19
|
+
RUBY_API_VERSION_MAJOR == 2 && RUBY_API_VERSION_MINOR <= 6
|
20
|
+
# define MR_METHOD_FUNC(fn) RUBY_METHOD_FUNC(fn)
|
21
|
+
#else
|
22
|
+
# define MR_METHOD_FUNC(fn) fn
|
23
|
+
#endif
|
14
24
|
|
15
25
|
using namespace v8;
|
16
26
|
|
@@ -299,6 +309,29 @@ static pthread_rwlock_t exit_lock = PTHREAD_RWLOCK_INITIALIZER;
|
|
299
309
|
static bool ruby_exiting = false; // guarded by exit_lock
|
300
310
|
static bool single_threaded = false;
|
301
311
|
|
312
|
+
static void mark_context(void *);
|
313
|
+
static void deallocate(void *);
|
314
|
+
static size_t context_memsize(const void *);
|
315
|
+
static const rb_data_type_t context_type = {
|
316
|
+
"mini_racer/context_info",
|
317
|
+
{ mark_context, deallocate, context_memsize }
|
318
|
+
};
|
319
|
+
|
320
|
+
static void deallocate_snapshot(void *);
|
321
|
+
static size_t snapshot_memsize(const void *);
|
322
|
+
static const rb_data_type_t snapshot_type = {
|
323
|
+
"mini_racer/snapshot_info",
|
324
|
+
{ NULL, deallocate_snapshot, snapshot_memsize }
|
325
|
+
};
|
326
|
+
|
327
|
+
static void mark_isolate(void *);
|
328
|
+
static void deallocate_isolate(void *);
|
329
|
+
static size_t isolate_memsize(const void *);
|
330
|
+
static const rb_data_type_t isolate_type = {
|
331
|
+
"mini_racer/isolate_info",
|
332
|
+
{ mark_isolate, deallocate_isolate, isolate_memsize }
|
333
|
+
};
|
334
|
+
|
302
335
|
static VALUE rb_platform_set_flag_as_str(VALUE _klass, VALUE flag_as_str) {
|
303
336
|
bool platform_already_initialized = false;
|
304
337
|
|
@@ -313,7 +346,7 @@ static VALUE rb_platform_set_flag_as_str(VALUE _klass, VALUE flag_as_str) {
|
|
313
346
|
if (!strcmp(RSTRING_PTR(flag_as_str), "--single_threaded")) {
|
314
347
|
single_threaded = true;
|
315
348
|
}
|
316
|
-
V8::SetFlagsFromString(RSTRING_PTR(flag_as_str), (
|
349
|
+
V8::SetFlagsFromString(RSTRING_PTR(flag_as_str), RSTRING_LENINT(flag_as_str));
|
317
350
|
} else {
|
318
351
|
platform_already_initialized = true;
|
319
352
|
}
|
@@ -336,7 +369,11 @@ static void init_v8() {
|
|
336
369
|
|
337
370
|
if (current_platform == NULL) {
|
338
371
|
V8::InitializeICU();
|
339
|
-
|
372
|
+
if (single_threaded) {
|
373
|
+
current_platform = platform::NewSingleThreadedDefaultPlatform();
|
374
|
+
} else {
|
375
|
+
current_platform = platform::NewDefaultPlatform();
|
376
|
+
}
|
340
377
|
V8::InitializePlatform(current_platform.get());
|
341
378
|
V8::Initialize();
|
342
379
|
}
|
@@ -381,28 +418,32 @@ static void prepare_result(MaybeLocal<Value> v8res,
|
|
381
418
|
Local<Value> local_value = v8res.ToLocalChecked();
|
382
419
|
if ((local_value->IsObject() || local_value->IsArray()) &&
|
383
420
|
!local_value->IsDate() && !local_value->IsFunction()) {
|
384
|
-
|
385
|
-
context, String::NewFromUtf8Literal(isolate, "JSON"))
|
386
|
-
.ToLocalChecked().As<Object>();
|
387
|
-
|
388
|
-
Local<Function> stringify = JSON->Get(
|
389
|
-
context, v8::String::NewFromUtf8Literal(isolate, "stringify"))
|
390
|
-
.ToLocalChecked().As<Function>();
|
421
|
+
MaybeLocal<v8::Value> ml = context->Global()->Get(
|
422
|
+
context, String::NewFromUtf8Literal(isolate, "JSON"));
|
391
423
|
|
392
|
-
|
393
|
-
const unsigned argc = 1;
|
394
|
-
Local<Value> argv[argc] = { object };
|
395
|
-
MaybeLocal<Value> json = stringify->Call(context, JSON, argc, argv);
|
396
|
-
|
397
|
-
if (json.IsEmpty()) {
|
424
|
+
if (ml.IsEmpty()) { // exception
|
398
425
|
evalRes.executed = false;
|
399
426
|
} else {
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
427
|
+
Local<Object> JSON = ml.ToLocalChecked().As<Object>();
|
428
|
+
|
429
|
+
Local<Function> stringify = JSON->Get(
|
430
|
+
context, v8::String::NewFromUtf8Literal(isolate, "stringify"))
|
431
|
+
.ToLocalChecked().As<Function>();
|
432
|
+
|
433
|
+
Local<Object> object = local_value->ToObject(context).ToLocalChecked();
|
434
|
+
const unsigned argc = 1;
|
435
|
+
Local<Value> argv[argc] = { object };
|
436
|
+
MaybeLocal<Value> json = stringify->Call(context, JSON, argc, argv);
|
437
|
+
|
438
|
+
if (json.IsEmpty()) {
|
439
|
+
evalRes.executed = false;
|
440
|
+
} else {
|
441
|
+
evalRes.json = true;
|
442
|
+
Persistent<Value>* persistent = new Persistent<Value>();
|
443
|
+
persistent->Reset(isolate, json.ToLocalChecked());
|
444
|
+
evalRes.value = persistent;
|
445
|
+
}
|
404
446
|
}
|
405
|
-
|
406
447
|
} else {
|
407
448
|
Persistent<Value>* persistent = new Persistent<Value>();
|
408
449
|
persistent->Reset(isolate, local_value);
|
@@ -453,7 +494,7 @@ static void prepare_result(MaybeLocal<Value> v8res,
|
|
453
494
|
}
|
454
495
|
}
|
455
496
|
|
456
|
-
void*
|
497
|
+
static void*
|
457
498
|
nogvl_context_eval(void* arg) {
|
458
499
|
|
459
500
|
EvalParams* eval_params = (EvalParams*)arg;
|
@@ -683,7 +724,7 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, Local<Context> context,
|
|
683
724
|
case T_FLOAT:
|
684
725
|
return scope.Escape(Number::New(isolate, NUM2DBL(value)));
|
685
726
|
case T_STRING:
|
686
|
-
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (
|
727
|
+
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, RSTRING_LENINT(value)).ToLocalChecked());
|
687
728
|
case T_NIL:
|
688
729
|
return scope.Escape(Null(isolate));
|
689
730
|
case T_TRUE:
|
@@ -711,7 +752,7 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, Local<Context> context,
|
|
711
752
|
return scope.Escape(object);
|
712
753
|
case T_SYMBOL:
|
713
754
|
value = rb_funcall(value, rb_intern("to_s"), 0);
|
714
|
-
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, (
|
755
|
+
return scope.Escape(String::NewFromUtf8(isolate, RSTRING_PTR(value), NewStringType::kNormal, RSTRING_LENINT(value)).ToLocalChecked());
|
715
756
|
case T_DATA:
|
716
757
|
klass = rb_funcall(value, rb_intern("class"), 0);
|
717
758
|
if (klass == rb_cTime || klass == rb_cDateTime)
|
@@ -786,6 +827,7 @@ create_snapshot_data_blob(const char *embedded_source = nullptr) {
|
|
786
827
|
SnapshotCreator::FunctionCodeHandling::kClear);
|
787
828
|
}
|
788
829
|
|
830
|
+
static
|
789
831
|
StartupData warm_up_snapshot_data_blob(StartupData cold_snapshot_blob,
|
790
832
|
const char *warmup_source) {
|
791
833
|
// Use following steps to create a warmed up snapshot blob from a cold one:
|
@@ -821,14 +863,14 @@ StartupData warm_up_snapshot_data_blob(StartupData cold_snapshot_blob,
|
|
821
863
|
|
822
864
|
static VALUE rb_snapshot_size(VALUE self, VALUE str) {
|
823
865
|
SnapshotInfo* snapshot_info;
|
824
|
-
|
866
|
+
TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
|
825
867
|
|
826
868
|
return INT2NUM(snapshot_info->raw_size);
|
827
869
|
}
|
828
870
|
|
829
871
|
static VALUE rb_snapshot_load(VALUE self, VALUE str) {
|
830
872
|
SnapshotInfo* snapshot_info;
|
831
|
-
|
873
|
+
TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
|
832
874
|
|
833
875
|
if(TYPE(str) != T_STRING) {
|
834
876
|
rb_raise(rb_eArgError, "wrong type argument %" PRIsVALUE " (should be a string)",
|
@@ -851,14 +893,14 @@ static VALUE rb_snapshot_load(VALUE self, VALUE str) {
|
|
851
893
|
|
852
894
|
static VALUE rb_snapshot_dump(VALUE self, VALUE str) {
|
853
895
|
SnapshotInfo* snapshot_info;
|
854
|
-
|
896
|
+
TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
|
855
897
|
|
856
898
|
return rb_str_new(snapshot_info->data, snapshot_info->raw_size);
|
857
899
|
}
|
858
900
|
|
859
901
|
static VALUE rb_snapshot_warmup_unsafe(VALUE self, VALUE str) {
|
860
902
|
SnapshotInfo* snapshot_info;
|
861
|
-
|
903
|
+
TypedData_Get_Struct(self, SnapshotInfo, &snapshot_type, snapshot_info);
|
862
904
|
|
863
905
|
if(TYPE(str) != T_STRING) {
|
864
906
|
rb_raise(rb_eArgError, "wrong type argument %" PRIsVALUE " (should be a string)",
|
@@ -905,13 +947,13 @@ void IsolateInfo::init(SnapshotInfo* snapshot_info) {
|
|
905
947
|
|
906
948
|
static VALUE rb_isolate_init_with_snapshot(VALUE self, VALUE snapshot) {
|
907
949
|
IsolateInfo* isolate_info;
|
908
|
-
|
950
|
+
TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
|
909
951
|
|
910
952
|
init_v8();
|
911
953
|
|
912
954
|
SnapshotInfo* snapshot_info = nullptr;
|
913
955
|
if (!NIL_P(snapshot)) {
|
914
|
-
|
956
|
+
TypedData_Get_Struct(snapshot, SnapshotInfo, &snapshot_type, snapshot_info);
|
915
957
|
}
|
916
958
|
|
917
959
|
isolate_info->init(snapshot_info);
|
@@ -922,7 +964,7 @@ static VALUE rb_isolate_init_with_snapshot(VALUE self, VALUE snapshot) {
|
|
922
964
|
|
923
965
|
static VALUE rb_isolate_idle_notification(VALUE self, VALUE idle_time_in_ms) {
|
924
966
|
IsolateInfo* isolate_info;
|
925
|
-
|
967
|
+
TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
|
926
968
|
|
927
969
|
if (current_platform == NULL) return Qfalse;
|
928
970
|
|
@@ -933,7 +975,7 @@ static VALUE rb_isolate_idle_notification(VALUE self, VALUE idle_time_in_ms) {
|
|
933
975
|
|
934
976
|
static VALUE rb_isolate_low_memory_notification(VALUE self) {
|
935
977
|
IsolateInfo* isolate_info;
|
936
|
-
|
978
|
+
TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
|
937
979
|
|
938
980
|
if (current_platform == NULL) return Qfalse;
|
939
981
|
|
@@ -943,7 +985,7 @@ static VALUE rb_isolate_low_memory_notification(VALUE self) {
|
|
943
985
|
|
944
986
|
static VALUE rb_isolate_pump_message_loop(VALUE self) {
|
945
987
|
IsolateInfo* isolate_info;
|
946
|
-
|
988
|
+
TypedData_Get_Struct(self, IsolateInfo, &isolate_type, isolate_info);
|
947
989
|
|
948
990
|
if (current_platform == NULL) return Qfalse;
|
949
991
|
|
@@ -956,7 +998,7 @@ static VALUE rb_isolate_pump_message_loop(VALUE self) {
|
|
956
998
|
|
957
999
|
static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
|
958
1000
|
ContextInfo* context_info;
|
959
|
-
|
1001
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
960
1002
|
|
961
1003
|
init_v8();
|
962
1004
|
|
@@ -967,11 +1009,11 @@ static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
|
|
967
1009
|
|
968
1010
|
SnapshotInfo *snapshot_info = nullptr;
|
969
1011
|
if (!NIL_P(snap) && rb_obj_is_kind_of(snap, rb_cSnapshot)) {
|
970
|
-
|
1012
|
+
TypedData_Get_Struct(snap, SnapshotInfo, &snapshot_type, snapshot_info);
|
971
1013
|
}
|
972
1014
|
isolate_info->init(snapshot_info);
|
973
1015
|
} else { // given isolate or snapshot
|
974
|
-
|
1016
|
+
TypedData_Get_Struct(isolate, IsolateInfo, &isolate_type, isolate_info);
|
975
1017
|
}
|
976
1018
|
|
977
1019
|
context_info->isolate_info = isolate_info;
|
@@ -1001,7 +1043,7 @@ static VALUE rb_context_init_unsafe(VALUE self, VALUE isolate, VALUE snap) {
|
|
1001
1043
|
static VALUE convert_result_to_ruby(VALUE self /* context */,
|
1002
1044
|
EvalResult& result) {
|
1003
1045
|
ContextInfo *context_info;
|
1004
|
-
|
1046
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1005
1047
|
|
1006
1048
|
Isolate *isolate = context_info->isolate_info->isolate;
|
1007
1049
|
Persistent<Context> *p_ctx = context_info->context;
|
@@ -1028,7 +1070,7 @@ static VALUE convert_result_to_ruby(VALUE self /* context */,
|
|
1028
1070
|
// a v8 scope, if we do the scope is never cleaned up properly and we leak
|
1029
1071
|
if (!result.parsed) {
|
1030
1072
|
if(TYPE(message) == T_STRING) {
|
1031
|
-
rb_raise(rb_eParseError, "%
|
1073
|
+
rb_raise(rb_eParseError, "%" PRIsVALUE, message);
|
1032
1074
|
} else {
|
1033
1075
|
rb_raise(rb_eParseError, "Unknown JavaScript Error during parse");
|
1034
1076
|
}
|
@@ -1052,15 +1094,17 @@ static VALUE convert_result_to_ruby(VALUE self /* context */,
|
|
1052
1094
|
|
1053
1095
|
// exception report about what happened
|
1054
1096
|
if (TYPE(backtrace) == T_STRING) {
|
1055
|
-
rb_raise(ruby_exception, "%
|
1097
|
+
rb_raise(ruby_exception, "%" PRIsVALUE, backtrace);
|
1056
1098
|
} else if(TYPE(message) == T_STRING) {
|
1057
|
-
rb_raise(ruby_exception, "%
|
1099
|
+
rb_raise(ruby_exception, "%" PRIsVALUE, message);
|
1058
1100
|
} else {
|
1059
1101
|
rb_raise(ruby_exception, "Unknown JavaScript Error during execution");
|
1060
1102
|
}
|
1103
|
+
} else if (rb_obj_is_kind_of(ruby_exception, rb_eException)) {
|
1104
|
+
rb_exc_raise(ruby_exception);
|
1061
1105
|
} else {
|
1062
1106
|
VALUE rb_str = rb_funcall(ruby_exception, rb_intern("to_s"), 0);
|
1063
|
-
rb_raise(CLASS_OF(ruby_exception), "%
|
1107
|
+
rb_raise(CLASS_OF(ruby_exception), "%" PRIsVALUE, rb_str);
|
1064
1108
|
}
|
1065
1109
|
}
|
1066
1110
|
|
@@ -1102,7 +1146,7 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str, VALUE filename) {
|
|
1102
1146
|
EvalResult eval_result;
|
1103
1147
|
ContextInfo* context_info;
|
1104
1148
|
|
1105
|
-
|
1149
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1106
1150
|
Isolate* isolate = context_info->isolate_info->isolate;
|
1107
1151
|
|
1108
1152
|
if(TYPE(str) != T_STRING) {
|
@@ -1120,13 +1164,13 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str, VALUE filename) {
|
|
1120
1164
|
HandleScope handle_scope(isolate);
|
1121
1165
|
|
1122
1166
|
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(str),
|
1123
|
-
NewStringType::kNormal, (
|
1167
|
+
NewStringType::kNormal, RSTRING_LENINT(str)).ToLocalChecked();
|
1124
1168
|
|
1125
1169
|
Local<String> local_filename;
|
1126
1170
|
|
1127
1171
|
if (filename != Qnil) {
|
1128
1172
|
local_filename = String::NewFromUtf8(isolate, RSTRING_PTR(filename),
|
1129
|
-
NewStringType::kNormal, (
|
1173
|
+
NewStringType::kNormal, RSTRING_LENINT(filename)).ToLocalChecked();
|
1130
1174
|
eval_params.filename = &local_filename;
|
1131
1175
|
} else {
|
1132
1176
|
eval_params.filename = NULL;
|
@@ -1190,7 +1234,7 @@ VALUE rescue_callback(VALUE rdata, VALUE exception) {
|
|
1190
1234
|
return exception;
|
1191
1235
|
}
|
1192
1236
|
|
1193
|
-
void*
|
1237
|
+
static void*
|
1194
1238
|
gvl_ruby_callback(void* data) {
|
1195
1239
|
|
1196
1240
|
FunctionCallbackInfo<Value>* args = (FunctionCallbackInfo<Value>*)data;
|
@@ -1206,7 +1250,7 @@ gvl_ruby_callback(void* data) {
|
|
1206
1250
|
HandleScope scope(args->GetIsolate());
|
1207
1251
|
Local<External> external = Local<External>::Cast(args->Data());
|
1208
1252
|
|
1209
|
-
self =
|
1253
|
+
self = (VALUE)(external->Value());
|
1210
1254
|
callback = rb_iv_get(self, "@callback");
|
1211
1255
|
|
1212
1256
|
parent = rb_iv_get(self, "@parent");
|
@@ -1214,7 +1258,7 @@ gvl_ruby_callback(void* data) {
|
|
1214
1258
|
return NULL;
|
1215
1259
|
}
|
1216
1260
|
|
1217
|
-
|
1261
|
+
TypedData_Get_Struct(parent, ContextInfo, &context_type, context_info);
|
1218
1262
|
|
1219
1263
|
if (length > 0) {
|
1220
1264
|
ruby_args = rb_ary_tmp_new(length);
|
@@ -1243,7 +1287,6 @@ gvl_ruby_callback(void* data) {
|
|
1243
1287
|
args->GetIsolate()->TerminateExecution();
|
1244
1288
|
if (length > 0) {
|
1245
1289
|
rb_ary_clear(ruby_args);
|
1246
|
-
rb_gc_force_recycle(ruby_args);
|
1247
1290
|
}
|
1248
1291
|
return NULL;
|
1249
1292
|
}
|
@@ -1251,8 +1294,8 @@ gvl_ruby_callback(void* data) {
|
|
1251
1294
|
VALUE callback_data_value = (VALUE)&callback_data;
|
1252
1295
|
|
1253
1296
|
// TODO: use rb_vrescue2 in Ruby 2.7 and above
|
1254
|
-
result = rb_rescue2(
|
1255
|
-
|
1297
|
+
result = rb_rescue2(MR_METHOD_FUNC(protected_callback), callback_data_value,
|
1298
|
+
MR_METHOD_FUNC(rescue_callback), callback_data_value, rb_eException, (VALUE)0);
|
1256
1299
|
|
1257
1300
|
if(callback_data.failed) {
|
1258
1301
|
rb_iv_set(parent, "@current_exception", result);
|
@@ -1266,7 +1309,6 @@ gvl_ruby_callback(void* data) {
|
|
1266
1309
|
|
1267
1310
|
if (length > 0) {
|
1268
1311
|
rb_ary_clear(ruby_args);
|
1269
|
-
rb_gc_force_recycle(ruby_args);
|
1270
1312
|
}
|
1271
1313
|
|
1272
1314
|
if (IsolateData::Get(args->GetIsolate(), IsolateData::DO_TERMINATE)) {
|
@@ -1301,7 +1343,7 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
1301
1343
|
bool parse_error = false;
|
1302
1344
|
bool attach_error = false;
|
1303
1345
|
|
1304
|
-
|
1346
|
+
TypedData_Get_Struct(parent, ContextInfo, &context_type, context_info);
|
1305
1347
|
Isolate* isolate = context_info->isolate_info->isolate;
|
1306
1348
|
|
1307
1349
|
{
|
@@ -1314,15 +1356,12 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
1314
1356
|
|
1315
1357
|
Local<String> v8_str =
|
1316
1358
|
String::NewFromUtf8(isolate, RSTRING_PTR(name),
|
1317
|
-
NewStringType::kNormal, (
|
1359
|
+
NewStringType::kNormal, RSTRING_LENINT(name))
|
1318
1360
|
.ToLocalChecked();
|
1319
1361
|
|
1320
|
-
//
|
1321
|
-
|
1322
|
-
|
1323
|
-
*self_copy = self;
|
1324
|
-
|
1325
|
-
Local<Value> external = External::New(isolate, self_copy);
|
1362
|
+
// Note that self (rb_cExternalFunction) is a pure Ruby T_OBJECT,
|
1363
|
+
// not a T_DATA type like most other classes in this file
|
1364
|
+
Local<Value> external = External::New(isolate, (void *)self);
|
1326
1365
|
|
1327
1366
|
if (parent_object == Qnil) {
|
1328
1367
|
Maybe<bool> success = context->Global()->Set(
|
@@ -1337,7 +1376,7 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
1337
1376
|
Local<String> eval =
|
1338
1377
|
String::NewFromUtf8(isolate, RSTRING_PTR(parent_object_eval),
|
1339
1378
|
NewStringType::kNormal,
|
1340
|
-
(
|
1379
|
+
RSTRING_LENINT(parent_object_eval))
|
1341
1380
|
.ToLocalChecked();
|
1342
1381
|
|
1343
1382
|
MaybeLocal<Script> parsed_script = Script::Compile(context, eval);
|
@@ -1379,7 +1418,7 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
1379
1418
|
|
1380
1419
|
static VALUE rb_context_isolate_mutex(VALUE self) {
|
1381
1420
|
ContextInfo* context_info;
|
1382
|
-
|
1421
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1383
1422
|
|
1384
1423
|
if (!context_info->isolate_info) {
|
1385
1424
|
rb_raise(rb_eScriptRuntimeError, "Context has no Isolate available anymore");
|
@@ -1489,6 +1528,11 @@ static void mark_isolate(void* data) {
|
|
1489
1528
|
isolate_info->mark();
|
1490
1529
|
}
|
1491
1530
|
|
1531
|
+
static size_t isolate_memsize(const void *ptr) {
|
1532
|
+
const IsolateInfo *isolate_info = (const IsolateInfo *)ptr;
|
1533
|
+
return sizeof(*isolate_info);
|
1534
|
+
}
|
1535
|
+
|
1492
1536
|
static void deallocate(void* data) {
|
1493
1537
|
ContextInfo* context_info = (ContextInfo*)data;
|
1494
1538
|
|
@@ -1497,6 +1541,11 @@ static void deallocate(void* data) {
|
|
1497
1541
|
xfree(data);
|
1498
1542
|
}
|
1499
1543
|
|
1544
|
+
static size_t context_memsize(const void *ptr)
|
1545
|
+
{
|
1546
|
+
return sizeof(ContextInfo);
|
1547
|
+
}
|
1548
|
+
|
1500
1549
|
static void mark_context(void* data) {
|
1501
1550
|
ContextInfo* context_info = (ContextInfo*)data;
|
1502
1551
|
if (context_info->isolate_info) {
|
@@ -1504,48 +1553,39 @@ static void mark_context(void* data) {
|
|
1504
1553
|
}
|
1505
1554
|
}
|
1506
1555
|
|
1507
|
-
static void deallocate_external_function(void * data) {
|
1508
|
-
xfree(data);
|
1509
|
-
}
|
1510
|
-
|
1511
1556
|
static void deallocate_snapshot(void * data) {
|
1512
1557
|
SnapshotInfo* snapshot_info = (SnapshotInfo*)data;
|
1513
1558
|
delete[] snapshot_info->data;
|
1514
1559
|
xfree(snapshot_info);
|
1515
1560
|
}
|
1516
1561
|
|
1517
|
-
static
|
1518
|
-
|
1519
|
-
return
|
1562
|
+
static size_t snapshot_memsize(const void *data) {
|
1563
|
+
SnapshotInfo* snapshot_info = (SnapshotInfo*)data;
|
1564
|
+
return sizeof(*snapshot_info) + snapshot_info->raw_size;
|
1520
1565
|
}
|
1521
1566
|
|
1522
1567
|
static VALUE allocate(VALUE klass) {
|
1523
|
-
ContextInfo* context_info
|
1524
|
-
|
1525
|
-
context_info->context = NULL;
|
1526
|
-
|
1527
|
-
return Data_Wrap_Struct(klass, mark_context, deallocate, (void*)context_info);
|
1568
|
+
ContextInfo* context_info;
|
1569
|
+
return TypedData_Make_Struct(klass, ContextInfo, &context_type, context_info);
|
1528
1570
|
}
|
1529
1571
|
|
1530
1572
|
static VALUE allocate_snapshot(VALUE klass) {
|
1531
|
-
SnapshotInfo* snapshot_info
|
1532
|
-
snapshot_info->data = NULL;
|
1533
|
-
snapshot_info->raw_size = 0;
|
1573
|
+
SnapshotInfo* snapshot_info;
|
1534
1574
|
|
1535
|
-
return
|
1575
|
+
return TypedData_Make_Struct(klass, SnapshotInfo, &snapshot_type, snapshot_info);
|
1536
1576
|
}
|
1537
1577
|
|
1538
1578
|
static VALUE allocate_isolate(VALUE klass) {
|
1539
1579
|
IsolateInfo* isolate_info = new IsolateInfo();
|
1540
1580
|
|
1541
|
-
return
|
1581
|
+
return TypedData_Wrap_Struct(klass, &isolate_type, isolate_info);
|
1542
1582
|
}
|
1543
1583
|
|
1544
1584
|
static VALUE
|
1545
1585
|
rb_heap_stats(VALUE self) {
|
1546
1586
|
|
1547
1587
|
ContextInfo* context_info;
|
1548
|
-
|
1588
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1549
1589
|
Isolate* isolate;
|
1550
1590
|
v8::HeapStatistics stats;
|
1551
1591
|
|
@@ -1577,7 +1617,9 @@ rb_heap_stats(VALUE self) {
|
|
1577
1617
|
// https://github.com/bnoordhuis/node-heapdump/blob/master/src/heapdump.cc
|
1578
1618
|
class FileOutputStream : public OutputStream {
|
1579
1619
|
public:
|
1580
|
-
|
1620
|
+
int err;
|
1621
|
+
|
1622
|
+
FileOutputStream(int fd) : fd(fd) { err = 0; }
|
1581
1623
|
|
1582
1624
|
virtual int GetChunkSize() {
|
1583
1625
|
return 65536;
|
@@ -1586,17 +1628,27 @@ class FileOutputStream : public OutputStream {
|
|
1586
1628
|
virtual void EndOfStream() {}
|
1587
1629
|
|
1588
1630
|
virtual WriteResult WriteAsciiChunk(char* data, int size) {
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1631
|
+
size_t len = static_cast<size_t>(size);
|
1632
|
+
|
1633
|
+
while (len) {
|
1634
|
+
ssize_t w = write(fd, data, len);
|
1635
|
+
|
1636
|
+
if (w > 0) {
|
1637
|
+
data += w;
|
1638
|
+
len -= w;
|
1639
|
+
} else if (w < 0) {
|
1640
|
+
err = errno;
|
1641
|
+
return kAbort;
|
1642
|
+
} else { /* w == 0, could be out-of-space */
|
1643
|
+
err = -1;
|
1644
|
+
return kAbort;
|
1645
|
+
}
|
1646
|
+
}
|
1647
|
+
return kContinue;
|
1596
1648
|
}
|
1597
1649
|
|
1598
1650
|
private:
|
1599
|
-
|
1651
|
+
int fd;
|
1600
1652
|
};
|
1601
1653
|
|
1602
1654
|
|
@@ -1609,13 +1661,11 @@ rb_heap_snapshot(VALUE self, VALUE file) {
|
|
1609
1661
|
|
1610
1662
|
if (!fptr) return Qfalse;
|
1611
1663
|
|
1612
|
-
|
1613
|
-
|
1614
|
-
if (fp == NULL) return Qfalse;
|
1615
|
-
|
1664
|
+
// prepare for unbuffered write(2) below:
|
1665
|
+
rb_funcall(file, rb_intern("flush"), 0);
|
1616
1666
|
|
1617
1667
|
ContextInfo* context_info;
|
1618
|
-
|
1668
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1619
1669
|
Isolate* isolate;
|
1620
1670
|
isolate = context_info->isolate_info ? context_info->isolate_info->isolate : NULL;
|
1621
1671
|
|
@@ -1629,13 +1679,14 @@ rb_heap_snapshot(VALUE self, VALUE file) {
|
|
1629
1679
|
|
1630
1680
|
const HeapSnapshot* const snap = heap_profiler->TakeHeapSnapshot();
|
1631
1681
|
|
1632
|
-
FileOutputStream stream(
|
1682
|
+
FileOutputStream stream(fptr->fd);
|
1633
1683
|
snap->Serialize(&stream, HeapSnapshot::kJSON);
|
1634
1684
|
|
1635
|
-
fflush(fp);
|
1636
|
-
|
1637
1685
|
const_cast<HeapSnapshot*>(snap)->Delete();
|
1638
1686
|
|
1687
|
+
/* TODO: perhaps rb_sys_fail here */
|
1688
|
+
if (stream.err) return Qfalse;
|
1689
|
+
|
1639
1690
|
return Qtrue;
|
1640
1691
|
}
|
1641
1692
|
|
@@ -1643,7 +1694,7 @@ static VALUE
|
|
1643
1694
|
rb_context_stop(VALUE self) {
|
1644
1695
|
|
1645
1696
|
ContextInfo* context_info;
|
1646
|
-
|
1697
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1647
1698
|
|
1648
1699
|
Isolate* isolate = context_info->isolate_info->isolate;
|
1649
1700
|
|
@@ -1660,7 +1711,7 @@ static VALUE
|
|
1660
1711
|
rb_context_dispose(VALUE self) {
|
1661
1712
|
|
1662
1713
|
ContextInfo* context_info;
|
1663
|
-
|
1714
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1664
1715
|
|
1665
1716
|
free_context(context_info);
|
1666
1717
|
|
@@ -1723,7 +1774,7 @@ static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1723
1774
|
FunctionCall call;
|
1724
1775
|
VALUE *call_argv = NULL;
|
1725
1776
|
|
1726
|
-
|
1777
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1727
1778
|
Isolate* isolate = context_info->isolate_info->isolate;
|
1728
1779
|
|
1729
1780
|
if (argc < 1) {
|
@@ -1784,23 +1835,15 @@ static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1784
1835
|
if (val.IsEmpty() || !val.ToLocalChecked()->IsFunction()) {
|
1785
1836
|
missingFunction = true;
|
1786
1837
|
} else {
|
1787
|
-
|
1788
1838
|
Local<v8::Function> fun = Local<v8::Function>::Cast(val.ToLocalChecked());
|
1839
|
+
VALUE tmp;
|
1789
1840
|
call.fun = fun;
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
call.argv = (v8::Local<Value> *) malloc(sizeof(void *) * fun_argc);
|
1794
|
-
if (!call.argv) {
|
1795
|
-
return Qnil;
|
1796
|
-
}
|
1797
|
-
for(int i=0; i < fun_argc; i++) {
|
1798
|
-
call.argv[i] = convert_ruby_to_v8(isolate, context, call_argv[i]);
|
1799
|
-
}
|
1841
|
+
call.argv = (v8::Local<Value> *)RB_ALLOCV_N(void *, tmp, call.argc);
|
1842
|
+
for(int i=0; i < call.argc; i++) {
|
1843
|
+
call.argv[i] = convert_ruby_to_v8(isolate, context, call_argv[i]);
|
1800
1844
|
}
|
1801
1845
|
rb_thread_call_without_gvl(nogvl_context_call, &call, unblock_function, &call);
|
1802
|
-
|
1803
|
-
|
1846
|
+
RB_ALLOCV_END(tmp);
|
1804
1847
|
}
|
1805
1848
|
}
|
1806
1849
|
|
@@ -1813,7 +1856,7 @@ static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
|
|
1813
1856
|
|
1814
1857
|
static VALUE rb_context_create_isolate_value(VALUE self) {
|
1815
1858
|
ContextInfo* context_info;
|
1816
|
-
|
1859
|
+
TypedData_Get_Struct(self, ContextInfo, &context_type, context_info);
|
1817
1860
|
IsolateInfo *isolate_info = context_info->isolate_info;
|
1818
1861
|
|
1819
1862
|
if (!isolate_info) {
|
@@ -1821,7 +1864,7 @@ static VALUE rb_context_create_isolate_value(VALUE self) {
|
|
1821
1864
|
}
|
1822
1865
|
|
1823
1866
|
isolate_info->hold();
|
1824
|
-
return
|
1867
|
+
return TypedData_Wrap_Struct(rb_cIsolate, &isolate_type, isolate_info);
|
1825
1868
|
}
|
1826
1869
|
|
1827
1870
|
static void set_ruby_exiting(VALUE value) {
|
@@ -1877,7 +1920,6 @@ extern "C" {
|
|
1877
1920
|
rb_define_alloc_func(rb_cIsolate, allocate_isolate);
|
1878
1921
|
|
1879
1922
|
rb_define_private_method(rb_cExternalFunction, "notify_v8", (VALUE(*)(...))&rb_external_function_notify_v8, 0);
|
1880
|
-
rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
|
1881
1923
|
|
1882
1924
|
rb_define_method(rb_cSnapshot, "size", (VALUE(*)(...))&rb_snapshot_size, 0);
|
1883
1925
|
rb_define_method(rb_cSnapshot, "dump", (VALUE(*)(...))&rb_snapshot_dump, 0);
|
data/lib/mini_racer/version.rb
CHANGED
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.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -128,10 +128,10 @@ licenses:
|
|
128
128
|
- MIT
|
129
129
|
metadata:
|
130
130
|
bug_tracker_uri: https://github.com/discourse/mini_racer/issues
|
131
|
-
changelog_uri: https://github.com/discourse/mini_racer/blob/v0.
|
132
|
-
documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.
|
133
|
-
source_code_uri: https://github.com/discourse/mini_racer/tree/v0.
|
134
|
-
post_install_message:
|
131
|
+
changelog_uri: https://github.com/discourse/mini_racer/blob/v0.6.2/CHANGELOG
|
132
|
+
documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.6.2
|
133
|
+
source_code_uri: https://github.com/discourse/mini_racer/tree/v0.6.2
|
134
|
+
post_install_message:
|
135
135
|
rdoc_options: []
|
136
136
|
require_paths:
|
137
137
|
- lib
|
@@ -143,12 +143,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
143
|
version: '2.6'
|
144
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
145
|
requirements:
|
146
|
-
- - "
|
146
|
+
- - ">="
|
147
147
|
- !ruby/object:Gem::Version
|
148
|
-
version:
|
148
|
+
version: '0'
|
149
149
|
requirements: []
|
150
150
|
rubygems_version: 3.1.6
|
151
|
-
signing_key:
|
151
|
+
signing_key:
|
152
152
|
specification_version: 4
|
153
153
|
summary: Minimal embedded v8 for Ruby
|
154
154
|
test_files: []
|