summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_yjit.rb23
-rw-r--r--yjit/src/codegen.rs2
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) {