mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 20:44:20 +00:00
ZJIT: Load return value before frame teardown
Or else the following returns garbage since it loads after
moving SP. Prior bad disassembly:
def a(n1,n2,n3,n4,n5,n6,n7,n8) = n8
a(1,1,1,1,1,1,1,0)
# Block: bb0(v0, v1, v2, v3, v4, v5, v6, v7, v8)
stp x29, x30, [sp, #-0x10]!
mov x29, sp
# bump C stack pointer
sub sp, sp, #0x10
# Insn: v10 Return v8
# pop stack frame
adds x19, x19, #0x38
stur x19, [x20, #0x10]
# restore C stack pointer
add sp, sp, #0x10
mov sp, x29
ldp x29, x30, [sp], #0x10
ldur x0, [sp]
ret
This commit is contained in:
parent
9f961a4b30
commit
e77eee96a3
@ -806,6 +806,11 @@ class TestZJIT < Test::Unit::TestCase
|
||||
def a(n1,n2,n3,n4,n5,n6,n7,n8,n9) = n1+n9
|
||||
a(2,0,0,0,0,0,0,0,-1)
|
||||
}
|
||||
|
||||
assert_compiles '0', %q{
|
||||
def a(n1,n2,n3,n4,n5,n6,n7,n8) = n8
|
||||
a(1,1,1,1,1,1,1,0)
|
||||
}
|
||||
end
|
||||
|
||||
def test_opt_aref_with
|
||||
|
||||
@ -898,6 +898,10 @@ fn gen_return(jit: &JITState, asm: &mut Assembler, val: lir::Opnd) -> Option<()>
|
||||
asm.mov(CFP, incr_cfp);
|
||||
asm.mov(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP);
|
||||
|
||||
// Order here is important. Because we're about to tear down the frame,
|
||||
// we need to load the return value, which might be part of the frame.
|
||||
asm.load_into(C_RET_OPND, val);
|
||||
|
||||
// Restore the C stack pointer bumped for basic block arguments
|
||||
if jit.c_stack_bytes > 0 {
|
||||
asm_comment!(asm, "restore C stack pointer");
|
||||
@ -908,7 +912,7 @@ fn gen_return(jit: &JITState, asm: &mut Assembler, val: lir::Opnd) -> Option<()>
|
||||
asm.frame_teardown();
|
||||
|
||||
// Return from the function
|
||||
asm.cret(val);
|
||||
asm.cret(C_RET_OPND);
|
||||
Some(())
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user