ruby--ruby/bootstraptest/test_yjit_rust_port.rb

423 lines
5.4 KiB
Ruby

# 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()
}