diff options
Diffstat (limited to 'bootstraptest/test_yjit_rust_port.rb')
-rw-r--r-- | bootstraptest/test_yjit_rust_port.rb | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/bootstraptest/test_yjit_rust_port.rb b/bootstraptest/test_yjit_rust_port.rb new file mode 100644 index 0000000000..e399e0e49e --- /dev/null +++ b/bootstraptest/test_yjit_rust_port.rb @@ -0,0 +1,422 @@ +# Simple tests that we know we can pass +# To keep track of what we got working during the Rust port +# And avoid breaking/losing functionality +# +# Say "Thread" here to dodge WASM CI check. We use ractors here +# which WASM doesn't support and it only greps for "Thread". + +# Test for opt_mod +assert_equal '2', %q{ + def mod(a, b) + a % b + end + + mod(7, 5) + mod(7, 5) +} + +# Test for opt_mult +assert_equal '12', %q{ + def mult(a, b) + a * b + end + + mult(6, 2) + mult(6, 2) +} + +# Test for opt_div +assert_equal '3', %q{ + def div(a, b) + a / b + end + + div(6, 2) + div(6, 2) +} + +assert_equal '5', %q{ + def plus(a, b) + a + b + end + + plus(3, 2) +} + +assert_equal '1', %q{ + def foo(a, b) + a - b + end + + foo(3, 2) +} + +assert_equal 'true', %q{ + def foo(a, b) + a < b + end + + foo(2, 3) +} + +# Bitwise left shift +assert_equal '4', %q{ + def foo(a, b) + 1 << 2 + end + + foo(1, 2) +} + +assert_equal '-7', %q{ + def foo(a, b) + -7 + end + + foo(1, 2) +} + +# Putstring +assert_equal 'foo', %q{ + def foo(a, b) + "foo" + end + + foo(1, 2) +} + +assert_equal '-6', %q{ + def foo(a, b) + a + -7 + end + + foo(1, 2) +} + +assert_equal 'true', %q{ + def foo(a, b) + a == b + end + + foo(3, 3) +} + +assert_equal 'true', %q{ + def foo(a, b) + a < b + end + + foo(3, 5) +} + +assert_equal '777', %q{ + def foo(a) + if a + 777 + else + 333 + end + end + + foo(true) +} + +assert_equal '5', %q{ + def foo(a, b) + while a < b + a += 1 + end + a + end + + foo(1, 5) +} + +# opt_aref +assert_equal '2', %q{ + def foo(a, b) + a[b] + end + + foo([0, 1, 2], 2) +} + +# Simple function calls with 0, 1, 2 arguments +assert_equal '-2', %q{ + def bar() + -2 + end + + def foo(a, b) + bar() + end + + foo(3, 2) +} +assert_equal '2', %q{ + def bar(a) + a + end + + def foo(a, b) + bar(b) + end + + foo(3, 2) +} +assert_equal '1', %q{ + def bar(a, b) + a - b + end + + def foo(a, b) + bar(a, b) + end + + foo(3, 2) +} + +# Regression test for assembler bug +assert_equal '1', %q{ + def check_index(index) + if 0x40000000 < index + return -1 + end + 1 + end + + check_index 2 +} + +# Setivar test +assert_equal '2', %q{ + class Klass + attr_accessor :a + + def set() + @a = 2 + end + + def get() + @a + end + end + + o = Klass.new + o.set() + o.a +} + +# Regression for putobject bug +assert_equal '1.5', %q{ + def foo(x) + x + end + + def bar + foo(1.5) + end + + bar() +} + +# Getivar with an extended ivar table +assert_equal '3', %q{ + class Foo + def initialize + @x1 = 1 + @x2 = 1 + @x3 = 1 + @x4 = 3 + end + + def bar + @x4 + end + end + + f = Foo.new + f.bar +} + +assert_equal 'true', %q{ + x = [[false, true]] + for i, j in x + ; + end + j +} + +# Regression for getivar +assert_equal '[nil]', %q{ + [TrueClass].each do |klass| + klass.class_eval("def foo = @foo") + end + + [true].map do |instance| + instance.foo + end +} + +# Regression for send +assert_equal 'ok', %q{ + def bar(baz: 2) + baz + end + + def foo + bar(1, baz: 123) + end + + begin + foo + foo + rescue ArgumentError => e + print "ok" + end +} + +# Array access regression test +assert_equal '[0, 1, 2, 3, 4, 5]', %q{ + def expandarray_useless_splat + arr = [0, 1, 2, 3, 4, 5] + a, * = arr + end + + expandarray_useless_splat +} + +# Make sure we're correctly reading RStruct's as.ary union for embedded RStructs +assert_equal '3,12', %q{ + pt_struct = Struct.new(:x, :y) + p = pt_struct.new(3, 12) + def pt_inspect(pt) + "#{pt.x},#{pt.y}" + end + + # Make sure pt_inspect is JITted + 10.times { pt_inspect(p) } + + # Make sure it's returning '3,12' instead of e.g. '3,false' + pt_inspect(p) +} + +assert_equal '2', %q{ + def foo(s) + s.foo + end + + S = Struct.new(:foo) + foo(S.new(1)) + foo(S.new(2)) +} + +# Try to compile new method while OOM +assert_equal 'ok', %q{ + def foo + :ok + end + + RubyVM::YJIT.simulate_oom! if defined?(RubyVM::YJIT) + + foo +} + +# test hitting a branch stub when out of memory +assert_equal 'ok', %q{ + def nimai(jita) + if jita + :ng + else + :ok + end + end + + nimai(true) + nimai(true) + + RubyVM::YJIT.simulate_oom! if defined?(RubyVM::YJIT) + + nimai(false) +} + +# Ractor.current returns a current ractor +assert_equal 'Ractor', %q{ + Ractor.current.class +} + +# Ractor.new returns new Ractor +assert_equal 'Ractor', %q{ + Ractor.new{}.class +} + +# Ractor.allocate is not supported +assert_equal "[:ok, :ok]", %q{ + rs = [] + begin + Ractor.allocate + rescue => e + rs << :ok if e.message == 'allocator undefined for Ractor' + end + + begin + Ractor.new{}.dup + rescue + rs << :ok if e.message == 'allocator undefined for Ractor' + end + + rs +} + +# A return value of a Ractor block will be a message from the Ractor. +assert_equal 'ok', %q{ + # join + r = Ractor.new do + 'ok' + end + r.take +} + +# Passed arguments to Ractor.new will be a block parameter +# The values are passed with Ractor-communication pass. +assert_equal 'ok', %q{ + # ping-pong with arg + r = Ractor.new 'ok' do |msg| + msg + end + r.take +} + +# Pass multiple arguments to Ractor.new +assert_equal 'ok', %q{ + # ping-pong with two args + r = Ractor.new 'ping', 'pong' do |msg, msg2| + [msg, msg2] + end + 'ok' if r.take == ['ping', 'pong'] +} + +# Ractor#send passes an object with copy to a Ractor +# and Ractor.receive in the Ractor block can receive the passed value. +assert_equal 'ok', %q{ + r = Ractor.new do + msg = Ractor.receive + end + r.send 'ok' + r.take +} + +assert_equal '[1, 2, 3]', %q{ + def foo(arr) + arr << 1 + arr << 2 + arr << 3 + arr + end + + def bar() + foo([]) + end + + bar() +} |