diff options
-rw-r--r-- | bootstraptest/test_yjit.rb | 23 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 2 |
2 files changed, 24 insertions, 1 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index c5bb681e84..175f5bd86c 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -45,6 +45,29 @@ assert_normal_exit %q{ Object.send(:remove_const, :Foo) } +assert_normal_exit %q{ + # Test to ensure send on overriden c functions + # doesn't corrupt the stack + class Bar + def bar(x) + x + end + end + + class Foo + def bar + Bar.new + end + end + + foo = Foo.new + # before this change, this line would error + # because "s" would still be on the stack + # String.to_s is the overridden method here + p foo.bar.bar("s".__send__(:to_s)) +} + + assert_equal '[nil, nil, nil, nil, nil, nil]', %q{ [NilClass, TrueClass, FalseClass, Integer, Float, Symbol].each do |klass| klass.class_eval("def foo = @foo") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 0c51f589db..be4fc423b6 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -4179,7 +4179,7 @@ fn gen_send_cfunc( } // Delegate to codegen for C methods if we have it. - if kw_arg.is_null() { + if kw_arg.is_null() && flags & VM_CALL_OPT_SEND == 0 { let codegen_p = lookup_cfunc_codegen(unsafe { (*cme).def }); if let Some(known_cfunc_codegen) = codegen_p { if known_cfunc_codegen(jit, ctx, asm, ocb, ci, cme, block, argc, recv_known_klass) { |