mini_racer 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +9 -0
- data/README.md +51 -5
- data/ext/mini_racer_extension/extconf.rb +1 -1
- data/ext/mini_racer_extension/mini_racer_extension.cc +154 -34
- data/lib/mini_racer/version.rb +1 -1
- data/lib/mini_racer.rb +23 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0af151705087d66782e15f8a45952d95e3a7ff80
|
4
|
+
data.tar.gz: 13c8ac7228b49b3c4be26a521ffd01b9cf2b77ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c0359323d659fe170453a0b0304bc512c0d3d66edc07d991eb4383f354f788b9a54bc7abeec4f7280ae9e1c85bf9652fa2682d0c54ed5e41a3677009fdbb5d7
|
7
|
+
data.tar.gz: 3da5843bd59f285d3fcc3e9eaf92ee6cc823974016f669d01eeeb36a886055c3b9e6038b6f5e6e9ccc9a74eab4a7729ac2da9ed75df9ab388a5e0e34b4d22542
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
13-07-2017
|
2
|
+
|
3
|
+
- 0.1.10
|
4
|
+
|
5
|
+
- Fix leak: memory leak when disposing a context (20 bytes per context)
|
6
|
+
- Feature: added #heap_stats so you can get visibility from context to actual memory usage of isolate
|
7
|
+
- Feature: added #dispose so you reclaim all v8 memory right away as opposed to waiting for GC
|
8
|
+
- Feature: you can now specify filename in an eval eg: eval('a = 1', filename: 'my_awesome.js')
|
9
|
+
|
1
10
|
09-03-2017
|
2
11
|
|
3
12
|
- 0.1.9
|
data/README.md
CHANGED
@@ -68,6 +68,19 @@ context.eval 'while(true){}'
|
|
68
68
|
# => exception is raised
|
69
69
|
```
|
70
70
|
|
71
|
+
### Rich debugging with "filename" support
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
|
75
|
+
context = MiniRacer::Context.new
|
76
|
+
context.eval('var foo = function() {bar();}', filename: 'a/foo.js')
|
77
|
+
context.eval('bar()', filename: 'a/bar.js')
|
78
|
+
|
79
|
+
# MiniRacer::RuntimeError is raised containing the filenames you specified for evals in backtrace
|
80
|
+
|
81
|
+
```
|
82
|
+
|
83
|
+
|
71
84
|
### Threadsafe
|
72
85
|
|
73
86
|
Context usage is threadsafe
|
@@ -226,6 +239,39 @@ A list of all V8 runtime flags can be found using `node --v8-options`, or else b
|
|
226
239
|
|
227
240
|
Note that runtime flags must be set before any other operation (e.g. creating a context, a snapshot or an isolate), otherwise an exception will be thrown.
|
228
241
|
|
242
|
+
Flags:
|
243
|
+
|
244
|
+
- :expose_gc : Will expose `gc()` which you can run in JavaScript to issue a gc
|
245
|
+
- :max_old_space_size : defaults to 1400 (megs) on 64 bit, you can restric memory usage by limiting this.
|
246
|
+
- **NOTE TO READER** our documentation could be awesome we could be properly documenting all the flags, they are hugely useful, if you feel like documenting a few more, PLEASE DO, PRs are welcome.
|
247
|
+
|
248
|
+
## Controlling memory
|
249
|
+
|
250
|
+
When hosting v8 you may want to keep track of memory usage, use #heap_stats to get memory usage:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
context = MiniRacer::Context.new(timeout: 5)
|
254
|
+
context.eval("let a='testing';")
|
255
|
+
p context.heap_stats
|
256
|
+
# {:total_physical_size=>1280640,
|
257
|
+
# :total_heap_size_executable=>4194304,
|
258
|
+
# :total_heap_size=>3100672,
|
259
|
+
# :used_heap_size=>1205376,
|
260
|
+
# :heap_size_limit=>1501560832}
|
261
|
+
```
|
262
|
+
|
263
|
+
If you wish to dispose of a context before waiting on the GC use
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
context = MiniRacer::Context.new(timeout: 5)
|
267
|
+
context.eval("let a='testing';")
|
268
|
+
context.dispose
|
269
|
+
context.eval("a = 2")
|
270
|
+
# MiniRacer::ContextDisposedError
|
271
|
+
|
272
|
+
# nothing works on the context from now on, its a shell waiting to be disposed
|
273
|
+
```
|
274
|
+
|
229
275
|
## Performance
|
230
276
|
|
231
277
|
The `bench` folder contains benchmark.
|
@@ -302,14 +348,14 @@ Add this to your .travis.yml file:
|
|
302
348
|
|
303
349
|
## Similar Projects
|
304
350
|
|
305
|
-
###therubyracer
|
351
|
+
### therubyracer
|
306
352
|
|
307
353
|
- https://github.com/cowboyd/therubyracer
|
308
354
|
- Most comprehensive bridge available
|
309
355
|
- Provides the ability to "eval" JavaScript
|
310
356
|
- Provides the ability to invoke Ruby code from JavaScript
|
311
|
-
- Hold
|
312
|
-
- Hold
|
357
|
+
- Hold references to JavaScript objects and methods in your Ruby code
|
358
|
+
- Hold references to Ruby objects and methods in JavaScript code
|
313
359
|
- Uses libv8, so installation is fast
|
314
360
|
- Supports timeouts for JavaScript execution
|
315
361
|
- Does not release global interpreter lock, so performance is constrained to a single thread
|
@@ -317,7 +363,7 @@ Add this to your .travis.yml file:
|
|
317
363
|
- Supports execjs
|
318
364
|
|
319
365
|
|
320
|
-
###v8eval
|
366
|
+
### v8eval
|
321
367
|
|
322
368
|
- https://github.com/sony/v8eval
|
323
369
|
- Provides the ability to "eval" JavaScript using the latest V8 engine
|
@@ -330,7 +376,7 @@ Add this to your .travis.yml file:
|
|
330
376
|
- No support for execjs (can not be used with Rails uglifier and coffeescript gems)
|
331
377
|
|
332
378
|
|
333
|
-
###therubyrhino
|
379
|
+
### therubyrhino
|
334
380
|
|
335
381
|
- https://github.com/cowboyd/therubyrhino
|
336
382
|
- API compatible with therubyracer
|
@@ -32,7 +32,7 @@ WARNING: C++11 support is required for compiling mini_racer. Please make sure
|
|
32
32
|
you are using a compiler that supports at least C++11. Examples of such
|
33
33
|
compilers are GCC 4.7+ and Clang 3.2+.
|
34
34
|
|
35
|
-
If you are using Travis, consider either migrating your
|
35
|
+
If you are using Travis, consider either migrating your build to Ubuntu Trusty or
|
36
36
|
installing GCC 4.8. See mini_racer's README.md for more information.
|
37
37
|
|
38
38
|
|
@@ -17,8 +17,12 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
|
17
17
|
void* data = AllocateUninitialized(length);
|
18
18
|
return data == NULL ? data : memset(data, 0, length);
|
19
19
|
}
|
20
|
-
virtual void* AllocateUninitialized(size_t length) {
|
21
|
-
|
20
|
+
virtual void* AllocateUninitialized(size_t length) {
|
21
|
+
return malloc(length);
|
22
|
+
}
|
23
|
+
virtual void Free(void* data, size_t) {
|
24
|
+
free(data);
|
25
|
+
}
|
22
26
|
};
|
23
27
|
|
24
28
|
typedef struct {
|
@@ -31,6 +35,7 @@ typedef struct {
|
|
31
35
|
ArrayBufferAllocator* allocator;
|
32
36
|
StartupData* startup_data;
|
33
37
|
bool interrupted;
|
38
|
+
bool disposed;
|
34
39
|
pid_t pid;
|
35
40
|
|
36
41
|
// how many references to this isolate exist
|
@@ -38,7 +43,7 @@ typedef struct {
|
|
38
43
|
// objects, Ruby will destroy ruby objects first, then call the
|
39
44
|
// extenstion's deallocators. In this case, that means it would
|
40
45
|
// call `deallocate_isolate` _before_ `deallocate`, causing a segfault
|
41
|
-
int refs_count;
|
46
|
+
volatile int refs_count;
|
42
47
|
} IsolateInfo;
|
43
48
|
|
44
49
|
typedef struct {
|
@@ -59,6 +64,7 @@ typedef struct {
|
|
59
64
|
typedef struct {
|
60
65
|
ContextInfo* context_info;
|
61
66
|
Local<String>* eval;
|
67
|
+
Local<String>* filename;
|
62
68
|
useconds_t timeout;
|
63
69
|
EvalResult* result;
|
64
70
|
} EvalParams;
|
@@ -126,13 +132,25 @@ nogvl_context_eval(void* arg) {
|
|
126
132
|
TryCatch trycatch(isolate);
|
127
133
|
Local<Context> context = eval_params->context_info->context->Get(isolate);
|
128
134
|
Context::Scope context_scope(context);
|
135
|
+
v8::ScriptOrigin *origin = NULL;
|
129
136
|
|
130
137
|
// in gvl flag
|
131
138
|
isolate->SetData(0, (void*)false);
|
132
139
|
// terminate ASAP
|
133
140
|
isolate->SetData(1, (void*)false);
|
134
141
|
|
135
|
-
MaybeLocal<Script> parsed_script
|
142
|
+
MaybeLocal<Script> parsed_script;
|
143
|
+
|
144
|
+
if (eval_params->filename) {
|
145
|
+
origin = new v8::ScriptOrigin(*eval_params->filename);
|
146
|
+
}
|
147
|
+
|
148
|
+
parsed_script = Script::Compile(context, *eval_params->eval, origin);
|
149
|
+
|
150
|
+
if (origin) {
|
151
|
+
delete origin;
|
152
|
+
}
|
153
|
+
|
136
154
|
result->parsed = !parsed_script.IsEmpty();
|
137
155
|
result->executed = false;
|
138
156
|
result->terminated = false;
|
@@ -484,14 +502,14 @@ static VALUE rb_context_init_with_isolate(VALUE self, VALUE isolate) {
|
|
484
502
|
isolate_info->refs_count++;
|
485
503
|
|
486
504
|
{
|
487
|
-
|
488
|
-
|
489
|
-
|
505
|
+
Locker lock(isolate_info->isolate);
|
506
|
+
Isolate::Scope isolate_scope(isolate_info->isolate);
|
507
|
+
HandleScope handle_scope(isolate_info->isolate);
|
490
508
|
|
491
|
-
|
509
|
+
Local<Context> context = Context::New(isolate_info->isolate);
|
492
510
|
|
493
|
-
|
494
|
-
|
511
|
+
context_info->context = new Persistent<Context>();
|
512
|
+
context_info->context->Reset(isolate_info->isolate, context);
|
495
513
|
}
|
496
514
|
|
497
515
|
if (Qnil == rb_cDateTime && rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, rb_str_new2("DateTime")) == Qtrue)
|
@@ -502,7 +520,7 @@ static VALUE rb_context_init_with_isolate(VALUE self, VALUE isolate) {
|
|
502
520
|
return Qnil;
|
503
521
|
}
|
504
522
|
|
505
|
-
static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
|
523
|
+
static VALUE rb_context_eval_unsafe(VALUE self, VALUE str, VALUE filename) {
|
506
524
|
|
507
525
|
EvalParams eval_params;
|
508
526
|
EvalResult eval_result;
|
@@ -521,7 +539,17 @@ static VALUE rb_context_eval_unsafe(VALUE self, VALUE str) {
|
|
521
539
|
HandleScope handle_scope(isolate);
|
522
540
|
|
523
541
|
Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(str),
|
524
|
-
|
542
|
+
NewStringType::kNormal, (int)RSTRING_LEN(str)).ToLocalChecked();
|
543
|
+
|
544
|
+
Local<String> local_filename;
|
545
|
+
|
546
|
+
if (filename != Qnil) {
|
547
|
+
local_filename = String::NewFromUtf8(isolate, RSTRING_PTR(filename),
|
548
|
+
NewStringType::kNormal, (int)RSTRING_LEN(filename)).ToLocalChecked();
|
549
|
+
eval_params.filename = &local_filename;
|
550
|
+
} else {
|
551
|
+
eval_params.filename = NULL;
|
552
|
+
}
|
525
553
|
|
526
554
|
eval_params.context_info = context_info;
|
527
555
|
eval_params.eval = &eval;
|
@@ -786,15 +814,10 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
|
|
786
814
|
return Qnil;
|
787
815
|
}
|
788
816
|
|
789
|
-
void
|
790
|
-
// an isolate can only be freed if no Isolate or Context (ruby) object
|
791
|
-
// still need it
|
792
|
-
if (isolate_info == NULL || isolate_info->refs_count > 0) {
|
793
|
-
return;
|
794
|
-
}
|
817
|
+
void free_isolate(IsolateInfo* isolate_info) {
|
795
818
|
|
796
819
|
if (isolate_info->isolate) {
|
797
|
-
|
820
|
+
Locker lock(isolate_info->isolate);
|
798
821
|
}
|
799
822
|
|
800
823
|
if (isolate_info->isolate) {
|
@@ -817,18 +840,25 @@ void maybe_free_isolate_info(IsolateInfo* isolate_info) {
|
|
817
840
|
}
|
818
841
|
|
819
842
|
delete isolate_info->allocator;
|
820
|
-
|
843
|
+
isolate_info->disposed = true;
|
821
844
|
}
|
822
845
|
|
823
|
-
void
|
824
|
-
|
825
|
-
|
826
|
-
|
846
|
+
void maybe_free_isolate(IsolateInfo* isolate_info) {
|
847
|
+
// an isolate can only be freed if no Isolate or Context (ruby) object
|
848
|
+
// still need it
|
849
|
+
//
|
850
|
+
// there is a sequence issue here where Ruby may call the deallocator on the
|
851
|
+
// context object after it calles the dallocator on the isolate
|
852
|
+
if (isolate_info->refs_count != 0 || isolate_info->disposed) {
|
853
|
+
return;
|
854
|
+
}
|
827
855
|
|
828
|
-
|
856
|
+
free_isolate(isolate_info);
|
829
857
|
}
|
830
858
|
|
831
|
-
|
859
|
+
|
860
|
+
void free_context(void* data) {
|
861
|
+
|
832
862
|
ContextInfo* context_info = (ContextInfo*)data;
|
833
863
|
IsolateInfo* isolate_info = context_info->isolate_info;
|
834
864
|
|
@@ -837,23 +867,56 @@ void deallocate(void* data) {
|
|
837
867
|
v8::Isolate::Scope isolate_scope(isolate_info->isolate);
|
838
868
|
context_info->context->Reset();
|
839
869
|
delete context_info->context;
|
870
|
+
context_info->context = NULL;
|
840
871
|
}
|
872
|
+
}
|
873
|
+
|
874
|
+
void deallocate_context(void* data) {
|
875
|
+
|
876
|
+
ContextInfo* context_info = (ContextInfo*)data;
|
877
|
+
IsolateInfo* isolate_info = context_info->isolate_info;
|
878
|
+
|
879
|
+
free_context(data);
|
841
880
|
|
842
881
|
if (isolate_info) {
|
843
|
-
|
844
|
-
|
882
|
+
isolate_info->refs_count--;
|
883
|
+
maybe_free_isolate(isolate_info);
|
845
884
|
}
|
846
885
|
}
|
847
886
|
|
887
|
+
void deallocate_isolate(void* data) {
|
888
|
+
|
889
|
+
IsolateInfo* isolate_info = (IsolateInfo*) data;
|
890
|
+
|
891
|
+
isolate_info->refs_count--;
|
892
|
+
maybe_free_isolate(isolate_info);
|
893
|
+
|
894
|
+
if (isolate_info->refs_count == 0) {
|
895
|
+
xfree(isolate_info);
|
896
|
+
}
|
897
|
+
}
|
898
|
+
|
899
|
+
void deallocate(void* data) {
|
900
|
+
ContextInfo* context_info = (ContextInfo*)data;
|
901
|
+
IsolateInfo* isolate_info = context_info->isolate_info;
|
902
|
+
|
903
|
+
deallocate_context(data);
|
904
|
+
|
905
|
+
if (isolate_info && isolate_info->refs_count == 0) {
|
906
|
+
xfree(isolate_info);
|
907
|
+
}
|
908
|
+
|
909
|
+
xfree(data);
|
910
|
+
}
|
911
|
+
|
912
|
+
|
848
913
|
void deallocate_external_function(void * data) {
|
849
914
|
xfree(data);
|
850
915
|
}
|
851
916
|
|
852
917
|
void deallocate_snapshot(void * data) {
|
853
918
|
SnapshotInfo* snapshot_info = (SnapshotInfo*)data;
|
854
|
-
|
855
919
|
delete[] snapshot_info->data;
|
856
|
-
|
857
920
|
xfree(snapshot_info);
|
858
921
|
}
|
859
922
|
|
@@ -887,10 +950,44 @@ VALUE allocate_isolate(VALUE klass) {
|
|
887
950
|
isolate_info->interrupted = false;
|
888
951
|
isolate_info->refs_count = 0;
|
889
952
|
isolate_info->pid = getpid();
|
953
|
+
isolate_info->disposed = false;
|
890
954
|
|
891
955
|
return Data_Wrap_Struct(klass, NULL, deallocate_isolate, (void*)isolate_info);
|
892
956
|
}
|
893
957
|
|
958
|
+
static VALUE
|
959
|
+
rb_heap_stats(VALUE self) {
|
960
|
+
|
961
|
+
ContextInfo* context_info;
|
962
|
+
Data_Get_Struct(self, ContextInfo, context_info);
|
963
|
+
Isolate* isolate;
|
964
|
+
v8::HeapStatistics stats;
|
965
|
+
|
966
|
+
isolate = context_info->isolate_info ? context_info->isolate_info->isolate : NULL;
|
967
|
+
|
968
|
+
VALUE rval = rb_hash_new();
|
969
|
+
|
970
|
+
if (!isolate) {
|
971
|
+
|
972
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(0));
|
973
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(0));
|
974
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(0));
|
975
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(0));
|
976
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(0));
|
977
|
+
|
978
|
+
} else {
|
979
|
+
isolate->GetHeapStatistics(&stats);
|
980
|
+
|
981
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_physical_size")), ULONG2NUM(stats.total_physical_size()));
|
982
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size_executable")), ULONG2NUM(stats.total_heap_size_executable()));
|
983
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("total_heap_size")), ULONG2NUM(stats.total_heap_size()));
|
984
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("used_heap_size")), ULONG2NUM(stats.used_heap_size()));
|
985
|
+
rb_hash_aset(rval, ID2SYM(rb_intern("heap_size_limit")), ULONG2NUM(stats.heap_size_limit()));
|
986
|
+
}
|
987
|
+
|
988
|
+
return rval;
|
989
|
+
}
|
990
|
+
|
894
991
|
static VALUE
|
895
992
|
rb_context_stop(VALUE self) {
|
896
993
|
|
@@ -908,6 +1005,22 @@ rb_context_stop(VALUE self) {
|
|
908
1005
|
return Qnil;
|
909
1006
|
}
|
910
1007
|
|
1008
|
+
static VALUE
|
1009
|
+
rb_context_dispose(VALUE self) {
|
1010
|
+
|
1011
|
+
ContextInfo* context_info;
|
1012
|
+
Data_Get_Struct(self, ContextInfo, context_info);
|
1013
|
+
|
1014
|
+
free_context(context_info);
|
1015
|
+
|
1016
|
+
if (context_info->isolate_info && context_info->isolate_info->refs_count == 2) {
|
1017
|
+
// special case, we only have isolate + context so we can burn the
|
1018
|
+
// isolate as well
|
1019
|
+
free_isolate(context_info->isolate_info);
|
1020
|
+
}
|
1021
|
+
return Qnil;
|
1022
|
+
}
|
1023
|
+
|
911
1024
|
extern "C" {
|
912
1025
|
|
913
1026
|
void Init_mini_racer_extension ( void )
|
@@ -918,23 +1031,30 @@ extern "C" {
|
|
918
1031
|
VALUE rb_cIsolate = rb_define_class_under(rb_mMiniRacer, "Isolate", rb_cObject);
|
919
1032
|
VALUE rb_cPlatform = rb_define_class_under(rb_mMiniRacer, "Platform", rb_cObject);
|
920
1033
|
|
921
|
-
VALUE
|
1034
|
+
VALUE rb_eError = rb_define_class_under(rb_mMiniRacer, "Error", rb_eStandardError);
|
1035
|
+
|
1036
|
+
VALUE rb_eEvalError = rb_define_class_under(rb_mMiniRacer, "EvalError", rb_eError);
|
922
1037
|
rb_eScriptTerminatedError = rb_define_class_under(rb_mMiniRacer, "ScriptTerminatedError", rb_eEvalError);
|
923
1038
|
rb_eParseError = rb_define_class_under(rb_mMiniRacer, "ParseError", rb_eEvalError);
|
924
1039
|
rb_eScriptRuntimeError = rb_define_class_under(rb_mMiniRacer, "RuntimeError", rb_eEvalError);
|
1040
|
+
|
925
1041
|
rb_cJavaScriptFunction = rb_define_class_under(rb_mMiniRacer, "JavaScriptFunction", rb_cObject);
|
926
|
-
rb_eSnapshotError = rb_define_class_under(rb_mMiniRacer, "SnapshotError",
|
927
|
-
rb_ePlatformAlreadyInitializedError = rb_define_class_under(rb_mMiniRacer, "PlatformAlreadyInitialized",
|
1042
|
+
rb_eSnapshotError = rb_define_class_under(rb_mMiniRacer, "SnapshotError", rb_eError);
|
1043
|
+
rb_ePlatformAlreadyInitializedError = rb_define_class_under(rb_mMiniRacer, "PlatformAlreadyInitialized", rb_eError);
|
928
1044
|
rb_cFailedV8Conversion = rb_define_class_under(rb_mMiniRacer, "FailedV8Conversion", rb_cObject);
|
929
1045
|
rb_mJSON = rb_define_module("JSON");
|
930
1046
|
|
931
1047
|
VALUE rb_cExternalFunction = rb_define_class_under(rb_cContext, "ExternalFunction", rb_cObject);
|
1048
|
+
|
932
1049
|
rb_define_method(rb_cContext, "stop", (VALUE(*)(...))&rb_context_stop, 0);
|
1050
|
+
rb_define_method(rb_cContext, "dispose_unsafe", (VALUE(*)(...))&rb_context_dispose, 0);
|
1051
|
+
rb_define_method(rb_cContext, "heap_stats", (VALUE(*)(...))&rb_heap_stats, 0);
|
1052
|
+
|
933
1053
|
rb_define_alloc_func(rb_cContext, allocate);
|
934
1054
|
rb_define_alloc_func(rb_cSnapshot, allocate_snapshot);
|
935
1055
|
rb_define_alloc_func(rb_cIsolate, allocate_isolate);
|
936
1056
|
|
937
|
-
rb_define_private_method(rb_cContext, "eval_unsafe",(VALUE(*)(...))&rb_context_eval_unsafe,
|
1057
|
+
rb_define_private_method(rb_cContext, "eval_unsafe",(VALUE(*)(...))&rb_context_eval_unsafe, 2);
|
938
1058
|
rb_define_private_method(rb_cContext, "init_with_isolate",(VALUE(*)(...))&rb_context_init_with_isolate, 1);
|
939
1059
|
rb_define_private_method(rb_cExternalFunction, "notify_v8", (VALUE(*)(...))&rb_external_function_notify_v8, 0);
|
940
1060
|
rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
|
data/lib/mini_racer/version.rb
CHANGED
data/lib/mini_racer.rb
CHANGED
@@ -5,11 +5,15 @@ require "json"
|
|
5
5
|
|
6
6
|
module MiniRacer
|
7
7
|
|
8
|
-
class
|
9
|
-
|
8
|
+
class Error < ::StandardError; end
|
9
|
+
|
10
|
+
class ContextDisposedError < Error; end
|
11
|
+
class SnapshotError < Error; end
|
12
|
+
class PlatformAlreadyInitialized < Error; end
|
13
|
+
|
14
|
+
class EvalError < Error; end
|
10
15
|
class ParseError < EvalError; end
|
11
|
-
class
|
12
|
-
class PlatformAlreadyInitialized < StandardError; end
|
16
|
+
class ScriptTerminatedError < EvalError; end
|
13
17
|
|
14
18
|
class FailedV8Conversion
|
15
19
|
attr_reader :info
|
@@ -160,18 +164,31 @@ module MiniRacer
|
|
160
164
|
eval(File.read(filename))
|
161
165
|
end
|
162
166
|
|
163
|
-
def eval(str)
|
167
|
+
def eval(str, options=nil)
|
168
|
+
raise(ContextDisposedError, 'attempted to call eval on a disposed context!') if @disposed
|
169
|
+
|
170
|
+
filename = options && options[:filename].to_s
|
171
|
+
|
164
172
|
@eval_thread = Thread.current
|
165
173
|
isolate.with_lock do
|
166
174
|
@current_exception = nil
|
167
175
|
timeout do
|
168
|
-
eval_unsafe(str)
|
176
|
+
eval_unsafe(str, filename)
|
169
177
|
end
|
170
178
|
end
|
171
179
|
ensure
|
172
180
|
@eval_thread = nil
|
173
181
|
end
|
174
182
|
|
183
|
+
def dispose
|
184
|
+
if !@disposed
|
185
|
+
isolate.with_lock do
|
186
|
+
dispose_unsafe
|
187
|
+
end
|
188
|
+
@disposed = true
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
175
192
|
|
176
193
|
def attach(name, callback)
|
177
194
|
|
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.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|