summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_zjit.rb75
-rw-r--r--zjit/src/hir/opt_tests.rs64
2 files changed, 138 insertions, 1 deletions
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb
index ff9d45a083..18e10f5206 100644
--- a/test/ruby/test_zjit.rb
+++ b/test/ruby/test_zjit.rb
@@ -555,7 +555,8 @@ class TestZJIT < Test::Unit::TestCase
def test(a:, b:) = [a, b]
def entry = test(b: 2, a: 1) # change order
entry
- }
+ entry
+ }, call_threshold: 2
end
def test_send_kwarg_optional
@@ -567,6 +568,15 @@ class TestZJIT < Test::Unit::TestCase
}, call_threshold: 2
end
+ def test_send_kwarg_optional_too_many
+ assert_compiles '[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]', %q{
+ def test(a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10) = [a, b, c, d, e, f, g, h, i, j]
+ def entry = test
+ entry
+ entry
+ }, call_threshold: 2
+ end
+
def test_send_kwarg_required_and_optional
assert_compiles '[3, 2]', %q{
def test(a:, b: 2) = [a, b]
@@ -585,6 +595,28 @@ class TestZJIT < Test::Unit::TestCase
}, call_threshold: 2
end
+ def test_send_kwarg_to_ccall
+ assert_compiles '["a", "b", "c"]', %q{
+ def test(s) = s.each_line(chomp: true).to_a
+ def entry = test(%(a\nb\nc))
+ entry
+ entry
+ }, call_threshold: 2
+ end
+
+ def test_send_kwarg_and_block_to_ccall
+ assert_compiles '["a", "b", "c"]', %q{
+ def test(s)
+ a = []
+ s.each_line(chomp: true) { |l| a << l }
+ a
+ end
+ def entry = test(%(a\nb\nc))
+ entry
+ entry
+ }, call_threshold: 2
+ end
+
def test_send_kwrest
assert_compiles '{a: 3}', %q{
def test(**kwargs) = kwargs
@@ -594,6 +626,47 @@ class TestZJIT < Test::Unit::TestCase
}, call_threshold: 2
end
+ def test_send_req_kwreq
+ assert_compiles '[1, 3]', %q{
+ def test(a, c:) = [a, c]
+ def entry = test(1, c: 3)
+ entry
+ entry
+ }, call_threshold: 2
+ end
+
+ def test_send_req_opt_kwreq_kwopt
+ assert_compiles '[[1, 2, 3, 4], [-1, -2, -3, -4]]', %q{
+ def test(a, b = 2, c:, d: 4) = [a, b, c, d]
+ def entry = [test(1, c: 3), test(-1, -2, d: -4, c: -3)] # specify all, change kw order
+ entry
+ entry
+ }, call_threshold: 2
+ end
+
+ def test_send_unexpected_keyword
+ assert_compiles ':error', %q{
+ def test(a: 1) = a*2
+ def entry
+ test(z: 2)
+ rescue ArgumentError
+ :error
+ end
+
+ entry
+ entry
+ }, call_threshold: 2
+ end
+
+ def test_send_all_arg_types
+ assert_compiles '[:req, :opt, :post, :kwr, :kwo, true]', %q{
+ def test(a, b = :opt, c, d:, e: :kwo) = [a, b, c, d, e, block_given?]
+ def entry = test(:req, :post, d: :kwr) {}
+ entry
+ entry
+ }, call_threshold: 2
+ end
+
def test_send_ccall_variadic_with_different_receiver_classes
assert_compiles '[true, true]', %q{
def test(obj) = obj.start_with?("a")
diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs
index 5646af804a..81a2cea806 100644
--- a/zjit/src/hir/opt_tests.rs
+++ b/zjit/src/hir/opt_tests.rs
@@ -2863,6 +2863,70 @@ mod hir_opt_tests {
}
#[test]
+ fn dont_optimize_ccall_with_kwarg() {
+ eval("
+ def test = sprintf('%s', a: 1)
+ test
+ test
+ ");
+ assert_snapshot!(hir_string("test"), @r"
+ fn test@<compiled>:2:
+ bb0():
+ EntryPoint interpreter
+ v1:BasicObject = LoadSelf
+ Jump bb2(v1)
+ bb1(v4:BasicObject):
+ EntryPoint JIT(0)
+ Jump bb2(v4)
+ bb2(v6:BasicObject):
+ v11:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
+ v12:StringExact = StringCopy v11
+ v14:Fixnum[1] = Const Value(1)
+ IncrCounter complex_arg_pass_caller_kwarg
+ v16:BasicObject = SendWithoutBlock v6, :sprintf, v12, v14
+ CheckInterrupts
+ Return v16
+ ");
+ }
+
+ #[test]
+ fn dont_optimize_ccall_with_block_and_kwarg() {
+ eval("
+ def test(s)
+ a = []
+ s.each_line(chomp: true) { |l| a << l }
+ a
+ end
+ test %(a\nb\nc)
+ test %()
+ ");
+ assert_snapshot!(hir_string("test"), @r"
+ fn test@<compiled>:3:
+ bb0():
+ EntryPoint interpreter
+ v1:BasicObject = LoadSelf
+ v2:BasicObject = GetLocal :s, l0, SP@5
+ v3:NilClass = Const Value(nil)
+ Jump bb2(v1, v2, v3)
+ bb1(v6:BasicObject, v7:BasicObject):
+ EntryPoint JIT(0)
+ v8:NilClass = Const Value(nil)
+ Jump bb2(v6, v7, v8)
+ bb2(v10:BasicObject, v11:BasicObject, v12:NilClass):
+ v16:ArrayExact = NewArray
+ SetLocal :a, l0, EP@3, v16
+ v22:TrueClass = Const Value(true)
+ IncrCounter complex_arg_pass_caller_kwarg
+ v24:BasicObject = Send v11, 0x1000, :each_line, v22
+ v25:BasicObject = GetLocal :s, l0, EP@4
+ v26:BasicObject = GetLocal :a, l0, EP@3
+ v30:BasicObject = GetLocal :a, l0, EP@3
+ CheckInterrupts
+ Return v30
+ ");
+ }
+
+ #[test]
fn dont_replace_get_constant_path_with_empty_ic() {
eval("
def test = Kernel