2021-02-10 19:57:06 -05:00
|
|
|
# Putobject, less-than operator, fixnums
|
|
|
|
assert_equal '2', %q{
|
|
|
|
def check_index(index)
|
|
|
|
if 0x40000000 < index
|
|
|
|
raise "wat? #{index}"
|
|
|
|
end
|
|
|
|
index
|
|
|
|
end
|
|
|
|
check_index 2
|
|
|
|
check_index 2
|
|
|
|
}
|
|
|
|
|
2021-02-12 14:35:57 -05:00
|
|
|
# foo leaves a temp on the stack before the call
|
|
|
|
assert_equal '6', %q{
|
|
|
|
def bar
|
|
|
|
return 5
|
2021-02-03 17:39:38 -05:00
|
|
|
end
|
|
|
|
|
2021-02-12 14:35:57 -05:00
|
|
|
def foo
|
|
|
|
return 1 + bar
|
2021-02-03 17:39:38 -05:00
|
|
|
end
|
|
|
|
|
2021-02-12 14:35:57 -05:00
|
|
|
foo()
|
|
|
|
retval = foo()
|
2021-02-05 12:18:55 -05:00
|
|
|
}
|
|
|
|
|
2021-02-12 14:35:57 -05:00
|
|
|
# Method with one arguments
|
2021-02-05 12:18:55 -05:00
|
|
|
# foo leaves a temp on the stack before the call
|
2021-02-12 14:35:57 -05:00
|
|
|
assert_equal '7', %q{
|
|
|
|
def bar(a)
|
|
|
|
return a + 1
|
2021-02-05 12:18:55 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def foo
|
2021-02-12 14:35:57 -05:00
|
|
|
return 1 + bar(5)
|
2021-02-05 12:18:55 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
foo()
|
|
|
|
retval = foo()
|
|
|
|
}
|
|
|
|
|
2021-02-12 14:35:57 -05:00
|
|
|
# Method with two arguments
|
2021-02-09 17:34:02 -05:00
|
|
|
# foo leaves a temp on the stack before the call
|
|
|
|
assert_equal '0', %q{
|
|
|
|
def bar(a, b)
|
|
|
|
return a - b
|
|
|
|
end
|
|
|
|
|
|
|
|
def foo
|
|
|
|
return 1 + bar(1, 2)
|
|
|
|
end
|
|
|
|
|
|
|
|
foo()
|
|
|
|
retval = foo()
|
|
|
|
}
|
|
|
|
|
|
|
|
# Recursive Ruby-to-Ruby calls
|
|
|
|
assert_equal '21', %q{
|
|
|
|
def fib(n)
|
|
|
|
if n < 2
|
|
|
|
return n
|
|
|
|
end
|
|
|
|
|
|
|
|
return fib(n-1) + fib(n-2)
|
|
|
|
end
|
|
|
|
|
|
|
|
r = fib(8)
|
|
|
|
}
|
|
|
|
|
2021-02-05 12:18:55 -05:00
|
|
|
# Ruby-to-Ruby call and C call
|
|
|
|
assert_normal_exit %q{
|
|
|
|
def bar
|
|
|
|
puts('hi!')
|
|
|
|
end
|
|
|
|
|
|
|
|
def foo
|
|
|
|
bar
|
|
|
|
end
|
|
|
|
|
|
|
|
foo()
|
|
|
|
foo()
|
|
|
|
}
|
|
|
|
|
2021-02-12 14:35:57 -05:00
|
|
|
# Method redefinition (code invalidation) test
|
|
|
|
assert_equal '1', %q{
|
|
|
|
def ret1
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
|
|
|
klass = Class.new do
|
|
|
|
def alias_then_hash(klass, method_to_redefine)
|
|
|
|
# Redefine the method to be ret1
|
|
|
|
klass.alias_method(method_to_redefine, :ret1)
|
|
|
|
hash
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
instance = klass.new
|
|
|
|
|
|
|
|
i = 0
|
|
|
|
while i < 12
|
|
|
|
if i < 11
|
|
|
|
# Redefine the bar method
|
|
|
|
instance.alias_then_hash(klass, :bar)
|
|
|
|
else
|
|
|
|
# Redefine the hash method to be ret1
|
|
|
|
retval = instance.alias_then_hash(klass, :hash)
|
|
|
|
end
|
|
|
|
i += 1
|
|
|
|
end
|
|
|
|
|
|
|
|
retval
|
|
|
|
}
|
|
|
|
|
|
|
|
# Method redefinition (code invalidation) and GC
|
|
|
|
assert_equal '7', %q{
|
|
|
|
def bar()
|
|
|
|
return 5
|
|
|
|
end
|
|
|
|
|
|
|
|
def foo()
|
|
|
|
bar()
|
|
|
|
end
|
|
|
|
|
|
|
|
foo()
|
|
|
|
foo()
|
|
|
|
|
|
|
|
def bar()
|
|
|
|
return 7
|
|
|
|
end
|
|
|
|
|
|
|
|
4.times { GC.start }
|
|
|
|
|
|
|
|
foo()
|
|
|
|
foo()
|
|
|
|
}
|
|
|
|
|
|
|
|
# Method redefinition with two block versions
|
|
|
|
assert_equal '7', %q{
|
|
|
|
def bar()
|
|
|
|
return 5
|
|
|
|
end
|
|
|
|
|
|
|
|
def foo(n)
|
|
|
|
return ((n < 5)? 5:false), bar()
|
|
|
|
end
|
|
|
|
|
|
|
|
foo(4)
|
|
|
|
foo(4)
|
|
|
|
foo(10)
|
|
|
|
foo(10)
|
|
|
|
|
|
|
|
def bar()
|
|
|
|
return 7
|
|
|
|
end
|
|
|
|
|
|
|
|
4.times { GC.start }
|
|
|
|
|
|
|
|
foo(4)
|
|
|
|
foo(4)[1]
|
|
|
|
}
|
|
|
|
|
2021-02-05 12:18:55 -05:00
|
|
|
# Test for GC safety. Don't invalidate dead iseqs.
|
|
|
|
assert_normal_exit %q{
|
|
|
|
Class.new do
|
|
|
|
def foo
|
|
|
|
itself
|
|
|
|
end
|
|
|
|
|
|
|
|
new.foo
|
|
|
|
UJIT.install_entry(RubyVM::InstructionSequence.of(instance_method(:foo)))
|
|
|
|
new.foo
|
|
|
|
end
|
|
|
|
|
|
|
|
4.times { GC.start }
|
|
|
|
def itself
|
|
|
|
self
|
|
|
|
end
|
|
|
|
}
|