ZJIT: Side-exit into the interpreter on unknown opt_newarray_send
This commit is contained in:
parent
0c29ff8e8f
commit
a0df4cf6f1
Notes:
git
2025-05-23 20:33:04 +00:00
@ -1797,7 +1797,6 @@ pub enum CallType {
|
|||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
StackUnderflow(FrameState),
|
StackUnderflow(FrameState),
|
||||||
UnknownNewArraySend(String),
|
|
||||||
UnhandledCallType(CallType),
|
UnhandledCallType(CallType),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1976,11 +1975,11 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
|||||||
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
|
||||||
let (bop, insn) = match method {
|
let (bop, insn) = match method {
|
||||||
VM_OPT_NEWARRAY_SEND_MAX => (BOP_MAX, Insn::ArrayMax { elements, state: exit_id }),
|
VM_OPT_NEWARRAY_SEND_MAX => (BOP_MAX, Insn::ArrayMax { elements, state: exit_id }),
|
||||||
VM_OPT_NEWARRAY_SEND_MIN => return Err(ParseError::UnknownNewArraySend("min".into())),
|
_ => {
|
||||||
VM_OPT_NEWARRAY_SEND_HASH => return Err(ParseError::UnknownNewArraySend("hash".into())),
|
// Unknown opcode; side-exit into the interpreter
|
||||||
VM_OPT_NEWARRAY_SEND_PACK => return Err(ParseError::UnknownNewArraySend("pack".into())),
|
fun.push_insn(block, Insn::SideExit { state: exit_id });
|
||||||
VM_OPT_NEWARRAY_SEND_PACK_BUFFER => return Err(ParseError::UnknownNewArraySend("pack_buffer".into())),
|
break; // End the block
|
||||||
_ => return Err(ParseError::UnknownNewArraySend(format!("{method}"))),
|
},
|
||||||
};
|
};
|
||||||
fun.push_insn(block, Insn::PatchPoint(Invariant::BOPRedefined { klass: ARRAY_REDEFINED_OP_FLAG, bop }));
|
fun.push_insn(block, Insn::PatchPoint(Invariant::BOPRedefined { klass: ARRAY_REDEFINED_OP_FLAG, bop }));
|
||||||
state.stack_push(fun.push_insn(block, insn));
|
state.stack_push(fun.push_insn(block, insn));
|
||||||
@ -3231,6 +3230,90 @@ mod tests {
|
|||||||
"#]]);
|
"#]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_opt_newarray_send_min() {
|
||||||
|
eval("
|
||||||
|
def test(a,b)
|
||||||
|
sum = a+b
|
||||||
|
result = [a,b].min
|
||||||
|
puts [1,2,3]
|
||||||
|
result
|
||||||
|
end
|
||||||
|
");
|
||||||
|
assert_method_hir("test", expect![[r#"
|
||||||
|
fn test:
|
||||||
|
bb0(v0:BasicObject, v1:BasicObject):
|
||||||
|
v2:NilClassExact = Const Value(nil)
|
||||||
|
v3:NilClassExact = Const Value(nil)
|
||||||
|
v6:BasicObject = SendWithoutBlock v0, :+, v1
|
||||||
|
SideExit
|
||||||
|
"#]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_opt_newarray_send_hash() {
|
||||||
|
eval("
|
||||||
|
def test(a,b)
|
||||||
|
sum = a+b
|
||||||
|
result = [a,b].hash
|
||||||
|
puts [1,2,3]
|
||||||
|
result
|
||||||
|
end
|
||||||
|
");
|
||||||
|
assert_method_hir("test", expect![[r#"
|
||||||
|
fn test:
|
||||||
|
bb0(v0:BasicObject, v1:BasicObject):
|
||||||
|
v2:NilClassExact = Const Value(nil)
|
||||||
|
v3:NilClassExact = Const Value(nil)
|
||||||
|
v6:BasicObject = SendWithoutBlock v0, :+, v1
|
||||||
|
SideExit
|
||||||
|
"#]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_opt_newarray_send_pack() {
|
||||||
|
eval("
|
||||||
|
def test(a,b)
|
||||||
|
sum = a+b
|
||||||
|
result = [a,b].pack 'C'
|
||||||
|
puts [1,2,3]
|
||||||
|
result
|
||||||
|
end
|
||||||
|
");
|
||||||
|
assert_method_hir("test", expect![[r#"
|
||||||
|
fn test:
|
||||||
|
bb0(v0:BasicObject, v1:BasicObject):
|
||||||
|
v2:NilClassExact = Const Value(nil)
|
||||||
|
v3:NilClassExact = Const Value(nil)
|
||||||
|
v6:BasicObject = SendWithoutBlock v0, :+, v1
|
||||||
|
v7:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
|
||||||
|
v8:StringExact = StringCopy v7
|
||||||
|
SideExit
|
||||||
|
"#]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(max): Add a test for VM_OPT_NEWARRAY_SEND_PACK_BUFFER
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_opt_newarray_send_include_p() {
|
||||||
|
eval("
|
||||||
|
def test(a,b)
|
||||||
|
sum = a+b
|
||||||
|
result = [a,b].include? b
|
||||||
|
puts [1,2,3]
|
||||||
|
result
|
||||||
|
end
|
||||||
|
");
|
||||||
|
assert_method_hir("test", expect![[r#"
|
||||||
|
fn test:
|
||||||
|
bb0(v0:BasicObject, v1:BasicObject):
|
||||||
|
v2:NilClassExact = Const Value(nil)
|
||||||
|
v3:NilClassExact = Const Value(nil)
|
||||||
|
v6:BasicObject = SendWithoutBlock v0, :+, v1
|
||||||
|
SideExit
|
||||||
|
"#]]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_opt_length() {
|
fn test_opt_length() {
|
||||||
eval("
|
eval("
|
||||||
|
Loading…
x
Reference in New Issue
Block a user