diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2025-09-10 08:54:10 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-10 08:54:10 -0700 |
| commit | c0e01a271475ae765fc92e31245e42ea2b2d43f6 (patch) | |
| tree | 0318198fa11b106a97daba1995879b8b8acdba1d | |
| parent | 928fea3bfa86053c0bc6f7a5bf7559b115a676b5 (diff) | |
ZJIT: Compile ISEQs with forwardable parameters (#14491)
| -rw-r--r-- | test/ruby/test_zjit.rb | 15 | ||||
| -rw-r--r-- | zjit/src/hir.rs | 36 | ||||
| -rw-r--r-- | zjit/src/stats.rs | 5 |
3 files changed, 33 insertions, 23 deletions
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index 5f59f9fc02..f010995e58 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -439,6 +439,21 @@ class TestZJIT < Test::Unit::TestCase }, call_threshold: 2 end + def test_forwardable_iseq + assert_compiles '1', %q{ + def test(...) = 1 + test + } + end + + def test_sendforward + assert_runs '[1, 2]', %q{ + def callee(a, b) = [a, b] + def test(...) = callee(...) + test(1, 2) + }, insns: [:sendforward] + end + def test_iseq_with_optional_arguments assert_compiles '[[1, 2], [3, 4]]', %q{ def test(a, b = 2) = [a, b] diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index b7674b6a8c..aa05882a60 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -2966,16 +2966,8 @@ pub enum CallType { } #[derive(Clone, Debug, PartialEq)] -pub enum ParameterType { - /// For example, `foo(...)`. Interaction of JIT - /// calling convention and side exits currently unsolved. - Forwardable, -} - -#[derive(Clone, Debug, PartialEq)] pub enum ParseError { StackUnderflow(FrameState), - UnknownParameterType(ParameterType), MalformedIseq(u32), // insn_idx into iseq_encoded Validation(ValidationError), NotAllowed, @@ -3049,17 +3041,11 @@ impl ProfileOracle { /// The index of the self parameter in the HIR function pub const SELF_PARAM_IDX: usize = 0; -fn filter_unknown_parameter_type(iseq: *const rb_iseq_t) -> Result<(), ParseError> { - if unsafe { rb_get_iseq_flags_forwardable(iseq) } { return Err(ParseError::UnknownParameterType(ParameterType::Forwardable)); } - Ok(()) -} - /// Compile ISEQ into High-level IR pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> { if !ZJITState::can_compile_iseq(iseq) { return Err(ParseError::NotAllowed); } - filter_unknown_parameter_type(iseq)?; let payload = get_or_create_iseq_payload(iseq); let mut profiles = ProfileOracle::new(payload); let mut fun = Function::new(iseq); @@ -5198,13 +5184,23 @@ mod tests { eval(" def test(...) = super(...) "); - assert_compile_fails("test", ParseError::UnknownParameterType(ParameterType::Forwardable)); + assert_snapshot!(hir_string("test"), @r" + fn test@<compiled>:2: + bb0(v0:BasicObject, v1:BasicObject): + SideExit UnhandledYARVInsn(invokesuperforward) + "); } #[test] - fn test_cant_compile_forwardable() { + fn test_compile_forwardable() { eval("def forwardable(...) = nil"); - assert_compile_fails("forwardable", ParseError::UnknownParameterType(ParameterType::Forwardable)); + assert_snapshot!(hir_string("forwardable"), @r" + fn forwardable@<compiled>:1: + bb0(v0:BasicObject, v1:BasicObject): + v5:NilClass = Const Value(nil) + CheckInterrupts + Return v5 + "); } // TODO(max): Figure out how to generate a call with OPT_SEND flag @@ -5249,7 +5245,11 @@ mod tests { eval(" def test(...) = foo(...) "); - assert_compile_fails("test", ParseError::UnknownParameterType(ParameterType::Forwardable)); + assert_snapshot!(hir_string("test"), @r" + fn test@<compiled>:2: + bb0(v0:BasicObject, v1:BasicObject): + SideExit UnhandledYARVInsn(sendforward) + "); } #[test] diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs index 67edfe3d2d..471704bc06 100644 --- a/zjit/src/stats.rs +++ b/zjit/src/stats.rs @@ -130,7 +130,6 @@ make_counters! { compile_error_parse_malformed_iseq, compile_error_parse_validation, compile_error_parse_not_allowed, - compile_error_parse_parameter_type_forwardable, // The number of times YARV instructions are executed on JIT code zjit_insn_count, @@ -196,7 +195,6 @@ pub enum CompileError { /// Return a raw pointer to the exit counter for a given CompileError pub fn exit_counter_for_compile_error(compile_error: &CompileError) -> Counter { use crate::hir::ParseError::*; - use crate::hir::ParameterType::*; use crate::stats::CompileError::*; use crate::stats::Counter::*; match compile_error { @@ -210,9 +208,6 @@ pub fn exit_counter_for_compile_error(compile_error: &CompileError) -> Counter { MalformedIseq(_) => compile_error_parse_malformed_iseq, Validation(_) => compile_error_parse_validation, NotAllowed => compile_error_parse_not_allowed, - UnknownParameterType(parameter_type) => match parameter_type { - Forwardable => compile_error_parse_parameter_type_forwardable, - } } } } |
