Skip to content

Commit 4fd4229

Browse files
committed
Correct truffle implementation
1 parent a69e832 commit 4fd4229

1 file changed

Lines changed: 27 additions & 2 deletions

File tree

lib/mini_racer/truffleruby.rb

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,24 @@ def init_unsafe(isolate, snapshot)
118118
@js_symbol_to_symbol_func = eval_in_context "(x) => { var r = x.description; return r === undefined ? 'undefined' : r }"
119119
@js_new_date_func = eval_in_context "(x) => { return new Date(x) }"
120120
@js_new_array_func = eval_in_context "(x) => { return new Array(x) }"
121+
# looks up a (dotted) function name as properties from globalThis,
122+
# instead of evaluating the name as source code, so that names with
123+
# embedded NUL bytes or other invalid syntax resolve correctly
124+
@js_lookup_call_target_func = eval_in_context <<~JS
125+
(name) => {
126+
let target = globalThis;
127+
for (const key of name.split(".")) {
128+
if (target == null) {
129+
throw new ReferenceError(name + " is not defined");
130+
}
131+
target = target[key];
132+
}
133+
if (target === undefined) {
134+
throw new ReferenceError(name + " is not defined");
135+
}
136+
return target;
137+
}
138+
JS
121139
@js_new_uint8array_func = eval_in_context "(x) => { return new Uint8Array(x) }"
122140
end
123141

@@ -174,7 +192,7 @@ def call_unsafe(function_name, *arguments)
174192
raise RuntimeError, "TruffleRuby does not support call after stop" if @stopped
175193
begin
176194
translate do
177-
function = eval_in_context(function_name)
195+
function = @js_lookup_call_target_func.call(convert_ruby_to_js(encode(function_name)))
178196
function.call(*convert_ruby_to_js(arguments))
179197
end
180198
rescue Polyglot::ForeignException => e
@@ -225,8 +243,11 @@ def translate
225243

226244
def convert_js_to_ruby(value)
227245
case value
228-
when true, false, Integer, Float
246+
when true, false, Integer
229247
value
248+
when Float
249+
# match the C extension: integral doubles convert to Ruby Integers
250+
value.finite? && value == value.truncate ? value.to_i : value
230251
else
231252
if value.nil?
232253
nil
@@ -370,6 +391,10 @@ def init_with_snapshot(snapshot)
370391
class Platform
371392
def self.set_flag_as_str!(flag)
372393
raise TypeError, "wrong type argument #{flag.class} (should be a string)" unless flag.is_a?(String)
394+
raise ArgumentError, "flag contains NUL byte" if flag.include?("\0")
395+
# the C extension normalizes flags into a 256 byte "--flag" buffer
396+
normalized = flag.start_with?("--") ? flag : "--#{flag}"
397+
raise ArgumentError, "flag too long" if normalized.bytesize >= 256
373398
raise MiniRacer::PlatformAlreadyInitialized, "The platform is already initialized." if Context.instance_variable_get(:@context_initialized)
374399
Context.instance_variable_set(:@use_strict, true) if "--use_strict" == flag
375400
end

0 commit comments

Comments
 (0)