FEATURE: Implement MiniRacer for TruffleRuby (#253)
This commit is contained in:
parent
7419fd154e
commit
e0f5a7ac66
|
@ -3,6 +3,26 @@ on:
|
|||
- push
|
||||
|
||||
jobs:
|
||||
test-truffleruby:
|
||||
name: Test TruffleRuby
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
TRUFFLERUBYOPT: "--jvm --polyglot"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: truffleruby+graalvm-head
|
||||
- name: Install GraalVM js component
|
||||
run: if ! gu list | grep '^js '; then gu install js; fi
|
||||
- name: Bundle
|
||||
run: bundle install
|
||||
- name: Compile
|
||||
run: bundle exec rake compile
|
||||
- name: Test
|
||||
run: bundle exec rake test
|
||||
test-darwin:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
18
Rakefile
18
Rakefile
|
@ -1,6 +1,5 @@
|
|||
require "bundler/gem_tasks"
|
||||
require "rake/testtask"
|
||||
require "rake/extensiontask"
|
||||
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << "test"
|
||||
|
@ -11,8 +10,21 @@ end
|
|||
task :default => [:compile, :test]
|
||||
|
||||
gem = Gem::Specification.load( File.dirname(__FILE__) + '/mini_racer.gemspec' )
|
||||
Rake::ExtensionTask.new( 'mini_racer_loader', gem )
|
||||
Rake::ExtensionTask.new( 'mini_racer_extension', gem )
|
||||
|
||||
if RUBY_ENGINE == "truffleruby"
|
||||
task :compile do
|
||||
# noop
|
||||
end
|
||||
|
||||
task :clean do
|
||||
# noop
|
||||
end
|
||||
else
|
||||
require 'rake/extensiontask'
|
||||
Rake::ExtensionTask.new( 'mini_racer_loader', gem )
|
||||
Rake::ExtensionTask.new( 'mini_racer_extension', gem )
|
||||
end
|
||||
|
||||
|
||||
|
||||
# via http://blog.flavorjon.es/2009/06/easily-valgrind-gdb-your-ruby-c.html
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
require 'mkmf'
|
||||
|
||||
if RUBY_ENGINE == "truffleruby"
|
||||
File.write("Makefile", dummy_makefile($srcdir).join(""))
|
||||
return
|
||||
end
|
||||
|
||||
require_relative '../../lib/mini_racer/version'
|
||||
gem 'libv8-node', MiniRacer::LIBV8_NODE_VERSION
|
||||
require 'libv8-node'
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
require 'mkmf'
|
||||
|
||||
if RUBY_ENGINE == "truffleruby"
|
||||
File.write("Makefile", dummy_makefile($srcdir).join(""))
|
||||
return
|
||||
end
|
||||
|
||||
extension_name = 'mini_racer_loader'
|
||||
dir_config extension_name
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
require "mini_racer/version"
|
||||
require "mini_racer_loader"
|
||||
require "pathname"
|
||||
|
||||
ext_filename = "mini_racer_extension.#{RbConfig::CONFIG['DLEXT']}"
|
||||
ext_path = Gem.loaded_specs['mini_racer'].require_paths
|
||||
.map { |p| (p = Pathname.new(p)).absolute? ? p : Pathname.new(__dir__).parent + p }
|
||||
ext_found = ext_path.map { |p| p + ext_filename }.find { |p| p.file? }
|
||||
if RUBY_ENGINE == "truffleruby"
|
||||
require "mini_racer/truffleruby"
|
||||
else
|
||||
require "mini_racer_loader"
|
||||
ext_filename = "mini_racer_extension.#{RbConfig::CONFIG['DLEXT']}"
|
||||
ext_path = Gem.loaded_specs['mini_racer'].require_paths
|
||||
.map { |p| (p = Pathname.new(p)).absolute? ? p : Pathname.new(__dir__).parent + p }
|
||||
ext_found = ext_path.map { |p| p + ext_filename }.find { |p| p.file? }
|
||||
|
||||
raise LoadError, "Could not find #{ext_filename} in #{ext_path.map(&:to_s)}" unless ext_found
|
||||
MiniRacer::Loader.load(ext_found.to_s)
|
||||
raise LoadError, "Could not find #{ext_filename} in #{ext_path.map(&:to_s)}" unless ext_found
|
||||
MiniRacer::Loader.load(ext_found.to_s)
|
||||
end
|
||||
|
||||
require "thread"
|
||||
require "json"
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MiniRacer
|
||||
|
||||
class Context
|
||||
|
||||
class ExternalFunction
|
||||
private
|
||||
|
||||
def notify_v8
|
||||
name = @name.encode(::Encoding::UTF_8)
|
||||
wrapped = lambda do |*args|
|
||||
converted = @parent.send(:convert_js_to_ruby, args)
|
||||
begin
|
||||
result = @callback.call(*converted)
|
||||
rescue Polyglot::ForeignException => e
|
||||
e = RuntimeError.new(e.message)
|
||||
e.set_backtrace(e.backtrace)
|
||||
@parent.instance_variable_set(:@current_exception, e)
|
||||
raise e
|
||||
rescue => e
|
||||
@parent.instance_variable_set(:@current_exception, e)
|
||||
raise e
|
||||
end
|
||||
@parent.send(:convert_ruby_to_js, result)
|
||||
end
|
||||
|
||||
if @parent_object.nil?
|
||||
# set global name to proc
|
||||
result = @parent.eval_in_context('this')
|
||||
result[name] = wrapped
|
||||
else
|
||||
parent_object_eval = @parent_object_eval.encode(::Encoding::UTF_8)
|
||||
begin
|
||||
result = @parent.eval_in_context(parent_object_eval)
|
||||
rescue Polyglot::ForeignException, StandardError => e
|
||||
raise ParseError, "Was expecting #{@parent_object} to be an object", e.backtrace
|
||||
end
|
||||
result[name] = wrapped
|
||||
# set evaluated object results name to proc
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def heap_stats
|
||||
{
|
||||
total_physical_size: 0,
|
||||
total_heap_size_executable: 0,
|
||||
total_heap_size: 0,
|
||||
used_heap_size: 0,
|
||||
heap_size_limit: 0,
|
||||
}
|
||||
end
|
||||
|
||||
def stop
|
||||
if @entered
|
||||
@context.stop
|
||||
@stopped = true
|
||||
stop_attached
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@context_initialized = false
|
||||
@use_strict = false
|
||||
|
||||
def init_unsafe(isolate, snapshot)
|
||||
unless defined?(Polyglot::InnerContext)
|
||||
raise "TruffleRuby #{RUBY_ENGINE_VERSION} does not have support for inner contexts, use a more recent version"
|
||||
end
|
||||
|
||||
unless Polyglot.languages.include? "js"
|
||||
warn "You also need to install the 'js' component with 'gu install js' on GraalVM 22.2+", uplevel: 0 if $VERBOSE
|
||||
end
|
||||
|
||||
@context = Polyglot::InnerContext.new(on_cancelled: -> {
|
||||
raise ScriptTerminatedError, 'JavaScript was terminated (either by timeout or explicitly)'
|
||||
})
|
||||
Context.instance_variable_set(:@context_initialized, true)
|
||||
@js_object = @context.eval('js', 'Object')
|
||||
@isolate_mutex = Mutex.new
|
||||
@stopped = false
|
||||
@entered = false
|
||||
@has_entered = false
|
||||
@current_exception = nil
|
||||
if isolate && snapshot
|
||||
isolate.instance_variable_set(:@snapshot, snapshot)
|
||||
end
|
||||
if snapshot
|
||||
@snapshot = snapshot
|
||||
elsif isolate
|
||||
@snapshot = isolate.instance_variable_get(:@snapshot)
|
||||
else
|
||||
@snapshot = nil
|
||||
end
|
||||
@is_object_or_array_func, @is_time_func, @js_date_to_time_func, @is_symbol_func, @js_symbol_to_symbol_func, @js_new_date_func, @js_new_array_func = eval_in_context <<-CODE
|
||||
[
|
||||
(x) => { return (x instanceof Object || x instanceof Array) && !(x instanceof Date) && !(x instanceof Function) },
|
||||
(x) => { return x instanceof Date },
|
||||
(x) => { return x.getTime(x) },
|
||||
(x) => { return typeof x === 'symbol' },
|
||||
(x) => { var r = x.description; return r === undefined ? 'undefined' : r },
|
||||
(x) => { return new Date(x) },
|
||||
(x) => { return new Array(x) },
|
||||
]
|
||||
CODE
|
||||
end
|
||||
|
||||
def dispose_unsafe
|
||||
@context.close
|
||||
end
|
||||
|
||||
def eval_unsafe(str, filename)
|
||||
@entered = true
|
||||
if !@has_entered && @snapshot
|
||||
snapshot_src = encode(@snapshot.instance_variable_get(:@source))
|
||||
begin
|
||||
eval_in_context(snapshot_src, filename)
|
||||
rescue Polyglot::ForeignException => e
|
||||
raise RuntimeError, e.message, e.backtrace
|
||||
end
|
||||
end
|
||||
@has_entered = true
|
||||
raise RuntimeError, "TruffleRuby does not support eval after stop" if @stopped
|
||||
raise TypeError, "wrong type argument #{str.class} (should be a string)" unless str.is_a?(String)
|
||||
raise TypeError, "wrong type argument #{filename.class} (should be a string)" unless filename.nil? || filename.is_a?(String)
|
||||
|
||||
str = encode(str)
|
||||
begin
|
||||
translate do
|
||||
eval_in_context(str, filename)
|
||||
end
|
||||
rescue Polyglot::ForeignException => e
|
||||
raise RuntimeError, e.message, e.backtrace
|
||||
rescue ::RuntimeError => e
|
||||
if @current_exception
|
||||
e = @current_exception
|
||||
@current_exception = nil
|
||||
raise e
|
||||
else
|
||||
raise e, e.message
|
||||
end
|
||||
end
|
||||
ensure
|
||||
@entered = false
|
||||
end
|
||||
|
||||
def call_unsafe(function_name, *arguments)
|
||||
@entered = true
|
||||
if !@has_entered && @snapshot
|
||||
src = encode(@snapshot.instance_variable_get(:source))
|
||||
begin
|
||||
eval_in_context(src)
|
||||
rescue Polyglot::ForeignException => e
|
||||
raise RuntimeError, e.message, e.backtrace
|
||||
end
|
||||
end
|
||||
@has_entered = true
|
||||
raise RuntimeError, "TruffleRuby does not support call after stop" if @stopped
|
||||
begin
|
||||
translate do
|
||||
function = eval_in_context(function_name)
|
||||
function.call(*convert_ruby_to_js(arguments))
|
||||
end
|
||||
rescue Polyglot::ForeignException => e
|
||||
raise RuntimeError, e.message, e.backtrace
|
||||
end
|
||||
ensure
|
||||
@entered = false
|
||||
end
|
||||
|
||||
def create_isolate_value
|
||||
# Returning a dummy object since TruffleRuby does not have a 1-1 concept with isolate.
|
||||
# However, code and ASTs are shared between contexts.
|
||||
Isolate.new
|
||||
end
|
||||
|
||||
def isolate_mutex
|
||||
@isolate_mutex
|
||||
end
|
||||
|
||||
def translate
|
||||
convert_js_to_ruby yield
|
||||
rescue Object => e
|
||||
message = e.message
|
||||
if @current_exception
|
||||
raise @current_exception
|
||||
elsif e.message && e.message.start_with?('SyntaxError:')
|
||||
error_class = MiniRacer::ParseError
|
||||
elsif e.is_a?(MiniRacer::ScriptTerminatedError)
|
||||
error_class = MiniRacer::ScriptTerminatedError
|
||||
else
|
||||
error_class = MiniRacer::RuntimeError
|
||||
end
|
||||
|
||||
if error_class == MiniRacer::RuntimeError
|
||||
bls = e.backtrace_locations&.select { |bl| bl&.source_location&.language == 'js' }
|
||||
if bls && !bls.empty?
|
||||
if '(eval)' != bls[0].path
|
||||
message = "#{e.message}\n at #{bls[0]}\n" + bls[1..].map(&:to_s).join("\n")
|
||||
else
|
||||
message = "#{e.message}\n" + bls.map(&:to_s).join("\n")
|
||||
end
|
||||
end
|
||||
raise error_class, message
|
||||
else
|
||||
raise error_class, message, e.backtrace
|
||||
end
|
||||
end
|
||||
|
||||
def convert_js_to_ruby(value)
|
||||
case value
|
||||
when true, false, Integer, Float
|
||||
value
|
||||
else
|
||||
if value.nil?
|
||||
nil
|
||||
elsif value.respond_to?(:call)
|
||||
MiniRacer::JavaScriptFunction.new
|
||||
elsif value.respond_to?(:to_str)
|
||||
value.to_str.dup
|
||||
elsif value.respond_to?(:to_ary)
|
||||
value.to_ary.map do |e|
|
||||
if e.respond_to?(:call)
|
||||
nil
|
||||
else
|
||||
convert_js_to_ruby(e)
|
||||
end
|
||||
end
|
||||
elsif time?(value)
|
||||
js_date_to_time(value)
|
||||
elsif symbol?(value)
|
||||
js_symbol_to_symbol(value)
|
||||
else
|
||||
object = value
|
||||
h = {}
|
||||
object.instance_variables.each do |member|
|
||||
v = object[member]
|
||||
unless v.respond_to?(:call)
|
||||
h[member.to_s] = convert_js_to_ruby(v)
|
||||
end
|
||||
end
|
||||
h
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def object_or_array?(val)
|
||||
@is_object_or_array_func.call(val)
|
||||
end
|
||||
|
||||
def time?(value)
|
||||
@is_time_func.call(value)
|
||||
end
|
||||
|
||||
def js_date_to_time(value)
|
||||
millis = @js_date_to_time_func.call(value)
|
||||
Time.at(Rational(millis, 1000))
|
||||
end
|
||||
|
||||
def symbol?(value)
|
||||
@is_symbol_func.call(value)
|
||||
end
|
||||
|
||||
def js_symbol_to_symbol(value)
|
||||
@js_symbol_to_symbol_func.call(value).to_s.to_sym
|
||||
end
|
||||
|
||||
def js_new_date(value)
|
||||
@js_new_date_func.call(value)
|
||||
end
|
||||
|
||||
def js_new_array(size)
|
||||
@js_new_array_func.call(size)
|
||||
end
|
||||
|
||||
def convert_ruby_to_js(value)
|
||||
case value
|
||||
when nil, true, false, Integer, Float
|
||||
value
|
||||
when Array
|
||||
ary = js_new_array(value.size)
|
||||
value.each_with_index do |v, i|
|
||||
ary[i] = convert_ruby_to_js(v)
|
||||
end
|
||||
ary
|
||||
when Hash
|
||||
h = @js_object.new
|
||||
value.each_pair do |k, v|
|
||||
h[convert_ruby_to_js(k.to_s)] = convert_ruby_to_js(v)
|
||||
end
|
||||
h
|
||||
when String, Symbol
|
||||
Truffle::Interop.as_truffle_string value
|
||||
when Time
|
||||
js_new_date(value.to_f * 1000)
|
||||
when DateTime
|
||||
js_new_date(value.to_time.to_f * 1000)
|
||||
else
|
||||
"Undefined Conversion"
|
||||
end
|
||||
end
|
||||
|
||||
def encode(string)
|
||||
raise ArgumentError unless string
|
||||
string.encode(::Encoding::UTF_8)
|
||||
end
|
||||
|
||||
class_eval <<-'RUBY', "(mini_racer)", 1
|
||||
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
|
||||
RUBY
|
||||
|
||||
end
|
||||
|
||||
class Isolate
|
||||
def init_with_snapshot(snapshot)
|
||||
# TruffleRuby does not have a 1-1 concept with isolate.
|
||||
# However, isolate can hold a snapshot, and code and ASTs are shared between contexts.
|
||||
@snapshot = snapshot
|
||||
end
|
||||
|
||||
def low_memory_notification
|
||||
GC.start
|
||||
end
|
||||
|
||||
def idle_notification(idle_time)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class Platform
|
||||
def self.set_flag_as_str!(flag)
|
||||
raise TypeError, "wrong type argument #{flag.class} (should be a string)" unless flag.is_a?(String)
|
||||
raise MiniRacer::PlatformAlreadyInitialized, "The platform is already initialized." if Context.instance_variable_get(:@context_initialized)
|
||||
Context.instance_variable_set(:@use_strict, true) if "--use_strict" == flag
|
||||
end
|
||||
end
|
||||
|
||||
class Snapshot
|
||||
def load(str)
|
||||
raise TypeError, "wrong type argument #{str.class} (should be a string)" unless str.is_a?(String)
|
||||
# Intentionally noop since TruffleRuby mocks the snapshot API
|
||||
end
|
||||
|
||||
def warmup_unsafe!(src)
|
||||
raise TypeError, "wrong type argument #{src.class} (should be a string)" unless src.is_a?(String)
|
||||
# Intentionally noop since TruffleRuby mocks the snapshot API
|
||||
# by replaying snapshot source before the first eval/call
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -35,7 +35,8 @@ class MiniRacerFunctionTest < Minitest::Test
|
|||
context.call('f', 1)
|
||||
end
|
||||
assert_equal err.message, 'Error: foo bar'
|
||||
assert_match(/1:23/, err.backtrace[0])
|
||||
assert_match(/1:23/, err.backtrace[0]) unless RUBY_ENGINE == "truffleruby"
|
||||
assert_match(/1:/, err.backtrace[0]) if RUBY_ENGINE == "truffleruby"
|
||||
end
|
||||
|
||||
def test_args_types
|
||||
|
|
|
@ -10,6 +10,7 @@ class MiniRacerTest < Minitest::Test
|
|||
|
||||
|
||||
def test_locale
|
||||
skip "TruffleRuby does not have all js timezone by default" if RUBY_ENGINE == "truffleruby"
|
||||
val = MiniRacer::Context.new.eval("new Date('April 28 2021').toLocaleDateString('es-MX');")
|
||||
assert_equal '28/4/2021', val
|
||||
|
||||
|
@ -88,7 +89,7 @@ class MiniRacerTest < Minitest::Test
|
|||
|
||||
begin
|
||||
Thread.new do
|
||||
sleep 0.001
|
||||
sleep 0.01
|
||||
context.stop
|
||||
end
|
||||
context.eval('while(true){}')
|
||||
|
@ -102,6 +103,7 @@ class MiniRacerTest < Minitest::Test
|
|||
end
|
||||
|
||||
def test_it_can_timeout_during_serialization
|
||||
skip "TruffleRuby needs a fix for timing out during translation" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(timeout: 500)
|
||||
|
||||
assert_raises(MiniRacer::ScriptTerminatedError) do
|
||||
|
@ -302,12 +304,14 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_max_memory
|
||||
skip "TruffleRuby does not yet implement max_memory" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(max_memory: 200_000_000)
|
||||
|
||||
assert_raises(MiniRacer::V8OutOfMemoryError) { context.eval('let s = 1000; var a = new Array(s); a.fill(0); while(true) {s *= 1.1; let n = new Array(Math.floor(s)); n.fill(0); a = a.concat(n); };') }
|
||||
end
|
||||
|
||||
def test_max_memory_for_call
|
||||
skip "TruffleRuby does not yet implement max_memory" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(max_memory: 100_000_000)
|
||||
context.eval(<<~JS)
|
||||
let s;
|
||||
|
@ -399,6 +403,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_snapshot_size
|
||||
skip "TruffleRuby does not yet implement snapshots" if RUBY_ENGINE == "truffleruby"
|
||||
snapshot = MiniRacer::Snapshot.new('var foo = "bar";')
|
||||
|
||||
# for some reason sizes seem to change across runs, so we just
|
||||
|
@ -407,6 +412,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_snapshot_dump
|
||||
skip "TruffleRuby does not yet implement snapshots" if RUBY_ENGINE == "truffleruby"
|
||||
snapshot = MiniRacer::Snapshot.new('var foo = "bar";')
|
||||
dump = snapshot.dump
|
||||
|
||||
|
@ -581,13 +587,11 @@ raise FooError, "I like foos"
|
|||
def test_concurrent_access_over_the_same_isolate_2
|
||||
isolate = MiniRacer::Isolate.new
|
||||
|
||||
equals_after_sleep = {}
|
||||
|
||||
# workaround Rubies prior to commit 475c8701d74ebebe
|
||||
# (Make SecureRandom support Ractor, 2020-09-04)
|
||||
SecureRandom.hex
|
||||
|
||||
(1..10).map do |i|
|
||||
equals_after_sleep = (1..10).map do |i|
|
||||
Thread.new {
|
||||
random = SecureRandom.hex
|
||||
context = MiniRacer::Context.new(isolate: isolate)
|
||||
|
@ -598,12 +602,12 @@ raise FooError, "I like foos"
|
|||
|
||||
# cruby hashes are thread safe as long as you don't mess with the
|
||||
# same key in different threads
|
||||
equals_after_sleep[i] = context.eval('a') == random
|
||||
context.eval('a') == random
|
||||
}
|
||||
end.each(&:join)
|
||||
end.map(&:value)
|
||||
|
||||
assert_equal 10, equals_after_sleep.size
|
||||
assert equals_after_sleep.values.all?
|
||||
assert equals_after_sleep.all?
|
||||
end
|
||||
|
||||
def test_platform_set_flags_raises_an_exception_if_already_initialized
|
||||
|
@ -711,6 +715,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_estimated_size
|
||||
skip "TruffleRuby does not yet implement heap_stats" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(timeout: 5)
|
||||
context.eval("let a='testing';")
|
||||
|
||||
|
@ -780,7 +785,7 @@ raise FooError, "I like foos"
|
|||
|
||||
def test_estimated_size_when_disposed
|
||||
|
||||
context = MiniRacer::Context.new(timeout: 5)
|
||||
context = MiniRacer::Context.new(timeout: 50)
|
||||
context.eval("let a='testing';")
|
||||
context.dispose
|
||||
|
||||
|
@ -805,7 +810,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_attached_recursion
|
||||
context = MiniRacer::Context.new(timeout: 20)
|
||||
context = MiniRacer::Context.new(timeout: 200)
|
||||
context.attach("a", proc{|a| a})
|
||||
context.attach("b", proc{|a| a})
|
||||
|
||||
|
@ -842,6 +847,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_heap_dump
|
||||
skip "TruffleRuby does not yet implement heap_dump" if RUBY_ENGINE == "truffleruby"
|
||||
f = Tempfile.new("heap")
|
||||
path = f.path
|
||||
f.unlink
|
||||
|
@ -873,6 +879,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_cyclical_object_js
|
||||
skip "TruffleRuby does not yet implement marshal_stack_depth" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(marshal_stack_depth: 5)
|
||||
context.attach("a", proc{|a| a})
|
||||
|
||||
|
@ -880,6 +887,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_cyclical_array_js
|
||||
skip "TruffleRuby does not yet implement marshal_stack_depth" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(marshal_stack_depth: 5)
|
||||
context.attach("a", proc{|a| a})
|
||||
|
||||
|
@ -887,6 +895,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_cyclical_elem_in_array_js
|
||||
skip "TruffleRuby does not yet implement marshal_stack_depth" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(marshal_stack_depth: 5)
|
||||
context.attach("a", proc{|a| a})
|
||||
|
||||
|
@ -894,6 +903,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_infinite_object_js
|
||||
skip "TruffleRuby does not yet implement marshal_stack_depth" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(marshal_stack_depth: 5)
|
||||
context.attach("a", proc{|a| a})
|
||||
|
||||
|
@ -911,6 +921,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_deep_object_js
|
||||
skip "TruffleRuby does not yet implement marshal_stack_depth" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new(marshal_stack_depth: 5)
|
||||
context.attach("a", proc{|a| a})
|
||||
|
||||
|
@ -966,6 +977,7 @@ raise FooError, "I like foos"
|
|||
end
|
||||
|
||||
def test_webassembly
|
||||
skip "TruffleRuby does not enable WebAssembly by default" if RUBY_ENGINE == "truffleruby"
|
||||
context = MiniRacer::Context.new()
|
||||
context.eval("let instance = null;")
|
||||
filename = File.expand_path("../support/add.wasm", __FILE__)
|
||||
|
|
|
@ -23,6 +23,6 @@ trigger_gc
|
|||
|
||||
MiniRacer::Context.new.dispose
|
||||
|
||||
Process.wait fork { puts @ctx.eval("a"); @ctx.dispose; puts Process.pid; trigger_gc; puts "done #{Process.pid}" }
|
||||
|
||||
|
||||
if Process.respond_to?(:fork)
|
||||
Process.wait fork { puts @ctx.eval("a"); @ctx.dispose; puts Process.pid; trigger_gc; puts "done #{Process.pid}" }
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue