mini_racer 0.21.3 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +11 -0
- data/README.md +34 -0
- data/ext/mini_racer_extension/mini_racer_extension.c +232 -59
- data/ext/mini_racer_extension/mini_racer_v8.cc +188 -17
- data/ext/mini_racer_extension/mini_racer_v8.h +6 -1
- data/lib/mini_racer/shared.rb +151 -111
- data/lib/mini_racer/truffleruby.rb +89 -66
- data/lib/mini_racer/version.rb +1 -1
- data/lib/mini_racer.rb +17 -9
- metadata +33 -5
|
@@ -1,42 +1,43 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "shared"
|
|
4
4
|
|
|
5
5
|
module MiniRacer
|
|
6
|
-
|
|
7
6
|
class Context
|
|
8
|
-
|
|
9
7
|
class ExternalFunction
|
|
10
8
|
private
|
|
11
9
|
|
|
12
10
|
def notify_v8
|
|
13
11
|
name = @name.encode(::Encoding::UTF_8)
|
|
14
|
-
wrapped =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
wrapped =
|
|
13
|
+
lambda do |*args|
|
|
14
|
+
converted = @parent.send(:convert_js_to_ruby, args)
|
|
15
|
+
begin
|
|
16
|
+
result = @callback.call(*converted)
|
|
17
|
+
rescue Polyglot::ForeignException => e
|
|
18
|
+
e = RuntimeError.new(e.message)
|
|
19
|
+
e.set_backtrace(e.backtrace)
|
|
20
|
+
@parent.instance_variable_set(:@current_exception, e)
|
|
21
|
+
raise e
|
|
22
|
+
rescue => e
|
|
23
|
+
@parent.instance_variable_set(:@current_exception, e)
|
|
24
|
+
raise e
|
|
25
|
+
end
|
|
26
|
+
@parent.send(:convert_ruby_to_js, result)
|
|
26
27
|
end
|
|
27
|
-
@parent.send(:convert_ruby_to_js, result)
|
|
28
|
-
end
|
|
29
28
|
|
|
30
29
|
if @parent_object.nil?
|
|
31
30
|
# set global name to proc
|
|
32
|
-
result = @parent.eval_in_context(
|
|
31
|
+
result = @parent.eval_in_context("this")
|
|
33
32
|
result[name] = wrapped
|
|
34
33
|
else
|
|
35
34
|
parent_object_eval = @parent_object_eval.encode(::Encoding::UTF_8)
|
|
36
35
|
begin
|
|
37
36
|
result = @parent.eval_in_context(parent_object_eval)
|
|
38
37
|
rescue Polyglot::ForeignException, StandardError => e
|
|
39
|
-
raise ParseError,
|
|
38
|
+
raise ParseError,
|
|
39
|
+
"Was expecting #{@parent_object} to be an object",
|
|
40
|
+
e.backtrace
|
|
40
41
|
end
|
|
41
42
|
result[name] = wrapped
|
|
42
43
|
# set evaluated object results name to proc
|
|
@@ -51,7 +52,7 @@ module MiniRacer
|
|
|
51
52
|
total_heap_size_executable: 0,
|
|
52
53
|
total_heap_size: 0,
|
|
53
54
|
used_heap_size: 0,
|
|
54
|
-
heap_size_limit: 0
|
|
55
|
+
heap_size_limit: 0
|
|
55
56
|
}
|
|
56
57
|
end
|
|
57
58
|
|
|
@@ -77,7 +78,6 @@ module MiniRacer
|
|
|
77
78
|
raise "TruffleRuby #{RUBY_ENGINE_VERSION} does not have support for inner contexts, use a more recent version"
|
|
78
79
|
end
|
|
79
80
|
|
|
80
|
-
|
|
81
81
|
if TruffleRuby.native?
|
|
82
82
|
raise "You need the TruffleRuby JVM Standalone for mini_racer because it is not possible to install the js component in the the Native standalone"
|
|
83
83
|
end
|
|
@@ -86,19 +86,21 @@ module MiniRacer
|
|
|
86
86
|
raise "The language 'js' is not available, you need to install the 'js' component.\nSee https://github.com/oracle/truffleruby/blob/master/doc/user/polyglot.md#installing-other-languages"
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
@context =
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
@context =
|
|
90
|
+
Polyglot::InnerContext.new(
|
|
91
|
+
on_cancelled: -> do
|
|
92
|
+
raise ScriptTerminatedError,
|
|
93
|
+
"JavaScript was terminated (either by timeout or explicitly)"
|
|
94
|
+
end
|
|
95
|
+
)
|
|
92
96
|
Context.instance_variable_set(:@context_initialized, true)
|
|
93
|
-
@js_object = @context.eval(
|
|
97
|
+
@js_object = @context.eval("js", "Object")
|
|
94
98
|
@isolate_mutex = Mutex.new
|
|
95
99
|
@stopped = false
|
|
96
100
|
@entered = false
|
|
97
101
|
@has_entered = false
|
|
98
102
|
@current_exception = nil
|
|
99
|
-
if isolate && snapshot
|
|
100
|
-
isolate.instance_variable_set(:@snapshot, snapshot)
|
|
101
|
-
end
|
|
103
|
+
isolate.instance_variable_set(:@snapshot, snapshot) if isolate && snapshot
|
|
102
104
|
if snapshot
|
|
103
105
|
@snapshot = snapshot
|
|
104
106
|
elsif isolate
|
|
@@ -107,15 +109,20 @@ module MiniRacer
|
|
|
107
109
|
@snapshot = nil
|
|
108
110
|
end
|
|
109
111
|
|
|
110
|
-
@is_object_or_array_func =
|
|
112
|
+
@is_object_or_array_func =
|
|
113
|
+
eval_in_context "(x) => { return (x instanceof Object || x instanceof Array) && !(x instanceof Date) && !(x instanceof Function) }"
|
|
111
114
|
@is_map_func = eval_in_context "(x) => { return x instanceof Map }"
|
|
112
|
-
@is_map_iterator_func =
|
|
115
|
+
@is_map_iterator_func =
|
|
116
|
+
eval_in_context "(x) => { return x[Symbol.toStringTag] === 'Map Iterator' }"
|
|
113
117
|
@is_time_func = eval_in_context "(x) => { return x instanceof Date }"
|
|
114
|
-
@is_symbol_func =
|
|
115
|
-
|
|
118
|
+
@is_symbol_func =
|
|
119
|
+
eval_in_context "(x) => { return typeof x === 'symbol' }"
|
|
120
|
+
@is_uint8_array_func =
|
|
121
|
+
eval_in_context "(x) => { return x instanceof Uint8Array }"
|
|
116
122
|
|
|
117
123
|
@js_date_to_time_func = eval_in_context "(x) => { return x.getTime(x) }"
|
|
118
|
-
@js_symbol_to_symbol_func =
|
|
124
|
+
@js_symbol_to_symbol_func =
|
|
125
|
+
eval_in_context "(x) => { var r = x.description; return r === undefined ? 'undefined' : r }"
|
|
119
126
|
@js_new_date_func = eval_in_context "(x) => { return new Date(x) }"
|
|
120
127
|
@js_new_array_func = eval_in_context "(x) => { return new Array(x) }"
|
|
121
128
|
# looks up a (dotted) function name as properties from globalThis,
|
|
@@ -136,7 +143,8 @@ module MiniRacer
|
|
|
136
143
|
return target;
|
|
137
144
|
}
|
|
138
145
|
JS
|
|
139
|
-
@js_new_uint8array_func =
|
|
146
|
+
@js_new_uint8array_func =
|
|
147
|
+
eval_in_context "(x) => { return new Uint8Array(x) }"
|
|
140
148
|
end
|
|
141
149
|
|
|
142
150
|
def dispose_unsafe
|
|
@@ -154,15 +162,20 @@ module MiniRacer
|
|
|
154
162
|
end
|
|
155
163
|
end
|
|
156
164
|
@has_entered = true
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
165
|
+
if @stopped
|
|
166
|
+
raise RuntimeError, "TruffleRuby does not support eval after stop"
|
|
167
|
+
end
|
|
168
|
+
unless str.is_a?(String)
|
|
169
|
+
raise TypeError, "wrong type argument #{str.class} (should be a string)"
|
|
170
|
+
end
|
|
171
|
+
unless filename.nil? || filename.is_a?(String)
|
|
172
|
+
raise TypeError,
|
|
173
|
+
"wrong type argument #{filename.class} (should be a string)"
|
|
174
|
+
end
|
|
160
175
|
|
|
161
176
|
str = encode(str)
|
|
162
177
|
begin
|
|
163
|
-
translate
|
|
164
|
-
eval_in_context(str, filename)
|
|
165
|
-
end
|
|
178
|
+
translate { eval_in_context(str, filename) }
|
|
166
179
|
rescue Polyglot::ForeignException => e
|
|
167
180
|
raise RuntimeError, e.message, e.backtrace
|
|
168
181
|
rescue ::RuntimeError => e
|
|
@@ -189,10 +202,15 @@ module MiniRacer
|
|
|
189
202
|
end
|
|
190
203
|
end
|
|
191
204
|
@has_entered = true
|
|
192
|
-
|
|
205
|
+
if @stopped
|
|
206
|
+
raise RuntimeError, "TruffleRuby does not support call after stop"
|
|
207
|
+
end
|
|
193
208
|
begin
|
|
194
209
|
translate do
|
|
195
|
-
function =
|
|
210
|
+
function =
|
|
211
|
+
@js_lookup_call_target_func.call(
|
|
212
|
+
convert_ruby_to_js(encode(function_name))
|
|
213
|
+
)
|
|
196
214
|
function.call(*convert_ruby_to_js(arguments))
|
|
197
215
|
end
|
|
198
216
|
rescue Polyglot::ForeignException => e
|
|
@@ -218,7 +236,7 @@ module MiniRacer
|
|
|
218
236
|
message = e.message
|
|
219
237
|
if @current_exception
|
|
220
238
|
raise @current_exception
|
|
221
|
-
elsif e.message && e.message.start_with?(
|
|
239
|
+
elsif e.message && e.message.start_with?("SyntaxError:")
|
|
222
240
|
error_class = MiniRacer::ParseError
|
|
223
241
|
elsif e.is_a?(MiniRacer::ScriptTerminatedError)
|
|
224
242
|
error_class = MiniRacer::ScriptTerminatedError
|
|
@@ -227,10 +245,14 @@ module MiniRacer
|
|
|
227
245
|
end
|
|
228
246
|
|
|
229
247
|
if error_class == MiniRacer::RuntimeError
|
|
230
|
-
bls =
|
|
248
|
+
bls =
|
|
249
|
+
e.backtrace_locations&.select do |bl|
|
|
250
|
+
bl&.source_location&.language == "js"
|
|
251
|
+
end
|
|
231
252
|
if bls && !bls.empty?
|
|
232
|
-
if
|
|
233
|
-
message =
|
|
253
|
+
if "(eval)" != bls[0].path
|
|
254
|
+
message =
|
|
255
|
+
"#{e.message}\n at #{bls[0]}\n" + bls[1..].map(&:to_s).join("\n")
|
|
234
256
|
else
|
|
235
257
|
message = "#{e.message}\n" + bls.map(&:to_s).join("\n")
|
|
236
258
|
end
|
|
@@ -256,16 +278,10 @@ module MiniRacer
|
|
|
256
278
|
elsif value.respond_to?(:to_str)
|
|
257
279
|
value.to_str.dup
|
|
258
280
|
elsif value.respond_to?(:to_ary)
|
|
259
|
-
if uint8_array?(value)
|
|
260
|
-
return value.to_a.pack('C*')
|
|
261
|
-
end
|
|
281
|
+
return value.to_a.pack("C*") if uint8_array?(value)
|
|
262
282
|
|
|
263
283
|
value.to_ary.map do |e|
|
|
264
|
-
|
|
265
|
-
nil
|
|
266
|
-
else
|
|
267
|
-
convert_js_to_ruby(e)
|
|
268
|
-
end
|
|
284
|
+
e.respond_to?(:call) ? nil : convert_js_to_ruby(e)
|
|
269
285
|
end
|
|
270
286
|
elsif time?(value)
|
|
271
287
|
js_date_to_time(value)
|
|
@@ -284,9 +300,7 @@ module MiniRacer
|
|
|
284
300
|
h = {}
|
|
285
301
|
object.instance_variables.each do |member|
|
|
286
302
|
v = object[member]
|
|
287
|
-
unless v.respond_to?(:call)
|
|
288
|
-
h[member.to_s] = convert_js_to_ruby(v)
|
|
289
|
-
end
|
|
303
|
+
h[member.to_s] = convert_js_to_ruby(v) unless v.respond_to?(:call)
|
|
290
304
|
end
|
|
291
305
|
h
|
|
292
306
|
end
|
|
@@ -346,9 +360,7 @@ module MiniRacer
|
|
|
346
360
|
value
|
|
347
361
|
when Array
|
|
348
362
|
ary = js_new_array(value.size)
|
|
349
|
-
value.each_with_index
|
|
350
|
-
ary[i] = convert_ruby_to_js(v)
|
|
351
|
-
end
|
|
363
|
+
value.each_with_index { |v, i| ary[i] = convert_ruby_to_js(v) }
|
|
352
364
|
ary
|
|
353
365
|
when Hash
|
|
354
366
|
h = @js_object.new
|
|
@@ -377,7 +389,6 @@ module MiniRacer
|
|
|
377
389
|
class_eval <<-'RUBY', "(mini_racer)", 1
|
|
378
390
|
def eval_in_context(code, file = nil); code = ('"use strict";' + code) if Context.instance_variable_get(:@use_strict); @context.eval('js', code, file || '(mini_racer)'); end
|
|
379
391
|
RUBY
|
|
380
|
-
|
|
381
392
|
end
|
|
382
393
|
|
|
383
394
|
class Isolate
|
|
@@ -390,24 +401,36 @@ module MiniRacer
|
|
|
390
401
|
|
|
391
402
|
class Platform
|
|
392
403
|
def self.set_flag_as_str!(flag)
|
|
393
|
-
|
|
404
|
+
unless flag.is_a?(String)
|
|
405
|
+
raise TypeError,
|
|
406
|
+
"wrong type argument #{flag.class} (should be a string)"
|
|
407
|
+
end
|
|
394
408
|
raise ArgumentError, "flag contains NUL byte" if flag.include?("\0")
|
|
395
409
|
# the C extension normalizes flags into a 256 byte "--flag" buffer
|
|
396
410
|
normalized = flag.start_with?("--") ? flag : "--#{flag}"
|
|
397
411
|
raise ArgumentError, "flag too long" if normalized.bytesize >= 256
|
|
398
|
-
|
|
399
|
-
|
|
412
|
+
if Context.instance_variable_get(:@context_initialized)
|
|
413
|
+
raise MiniRacer::PlatformAlreadyInitialized,
|
|
414
|
+
"The platform is already initialized."
|
|
415
|
+
end
|
|
416
|
+
if "--use_strict" == flag
|
|
417
|
+
Context.instance_variable_set(:@use_strict, true)
|
|
418
|
+
end
|
|
400
419
|
end
|
|
401
420
|
end
|
|
402
421
|
|
|
403
422
|
class Snapshot
|
|
404
423
|
def load(str)
|
|
405
|
-
|
|
424
|
+
unless str.is_a?(String)
|
|
425
|
+
raise TypeError, "wrong type argument #{str.class} (should be a string)"
|
|
426
|
+
end
|
|
406
427
|
# Intentionally noop since TruffleRuby mocks the snapshot API
|
|
407
428
|
end
|
|
408
429
|
|
|
409
430
|
def warmup_unsafe!(src)
|
|
410
|
-
|
|
431
|
+
unless src.is_a?(String)
|
|
432
|
+
raise TypeError, "wrong type argument #{src.class} (should be a string)"
|
|
433
|
+
end
|
|
411
434
|
# Intentionally noop since TruffleRuby mocks the snapshot API
|
|
412
435
|
# by replaying snapshot source before the first eval/call
|
|
413
436
|
self
|
data/lib/mini_racer/version.rb
CHANGED
data/lib/mini_racer.rb
CHANGED
|
@@ -6,7 +6,9 @@ module MiniRacer
|
|
|
6
6
|
attr_reader :data
|
|
7
7
|
|
|
8
8
|
def initialize(data)
|
|
9
|
-
|
|
9
|
+
unless data.is_a?(String)
|
|
10
|
+
raise TypeError, "wrong argument type #{data.class} (expected String)"
|
|
11
|
+
end
|
|
10
12
|
@data = data
|
|
11
13
|
end
|
|
12
14
|
end
|
|
@@ -34,20 +36,26 @@ else
|
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
require "thread"
|
|
38
39
|
require "json"
|
|
39
40
|
require "io/wait"
|
|
40
41
|
|
|
41
42
|
module MiniRacer
|
|
42
|
-
class Error < ::StandardError
|
|
43
|
+
class Error < ::StandardError
|
|
44
|
+
end
|
|
43
45
|
|
|
44
|
-
class ContextDisposedError < Error
|
|
45
|
-
|
|
46
|
+
class ContextDisposedError < Error
|
|
47
|
+
end
|
|
48
|
+
class PlatformAlreadyInitialized < Error
|
|
49
|
+
end
|
|
46
50
|
|
|
47
|
-
class EvalError < Error
|
|
48
|
-
|
|
49
|
-
class
|
|
50
|
-
|
|
51
|
+
class EvalError < Error
|
|
52
|
+
end
|
|
53
|
+
class ParseError < EvalError
|
|
54
|
+
end
|
|
55
|
+
class ScriptTerminatedError < EvalError
|
|
56
|
+
end
|
|
57
|
+
class V8OutOfMemoryError < EvalError
|
|
58
|
+
end
|
|
51
59
|
|
|
52
60
|
class RuntimeError < EvalError
|
|
53
61
|
def initialize(message)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mini_racer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.22.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Saffron
|
|
@@ -93,6 +93,34 @@ dependencies:
|
|
|
93
93
|
- - ">="
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
95
|
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rubocop
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: syntax_tree
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
96
124
|
- !ruby/object:Gem::Dependency
|
|
97
125
|
name: libv8-node
|
|
98
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -136,9 +164,9 @@ licenses:
|
|
|
136
164
|
- MIT
|
|
137
165
|
metadata:
|
|
138
166
|
bug_tracker_uri: https://github.com/discourse/mini_racer/issues
|
|
139
|
-
changelog_uri: https://github.com/discourse/mini_racer/blob/v0.
|
|
140
|
-
documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.
|
|
141
|
-
source_code_uri: https://github.com/discourse/mini_racer/tree/v0.
|
|
167
|
+
changelog_uri: https://github.com/discourse/mini_racer/blob/v0.22.0/CHANGELOG
|
|
168
|
+
documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.22.0
|
|
169
|
+
source_code_uri: https://github.com/discourse/mini_racer/tree/v0.22.0
|
|
142
170
|
rdoc_options: []
|
|
143
171
|
require_paths:
|
|
144
172
|
- lib
|
|
@@ -154,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
154
182
|
- !ruby/object:Gem::Version
|
|
155
183
|
version: '0'
|
|
156
184
|
requirements: []
|
|
157
|
-
rubygems_version:
|
|
185
|
+
rubygems_version: 3.6.9
|
|
158
186
|
specification_version: 4
|
|
159
187
|
summary: Minimal embedded v8 for Ruby
|
|
160
188
|
test_files: []
|