summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_zjit.rb9
-rw-r--r--zjit/src/hir.rs30
2 files changed, 22 insertions, 17 deletions
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb
index e040463bbf..c86ac62a9f 100644
--- a/test/ruby/test_zjit.rb
+++ b/test/ruby/test_zjit.rb
@@ -70,6 +70,15 @@ class TestZJIT < Test::Unit::TestCase
}
end
+ def test_call_a_forwardable_method
+ assert_runs '[]', %q{
+ def test_root = forwardable
+ def forwardable(...) = Array.[](...)
+ test_root
+ test_root
+ }, call_threshold: 2
+ end
+
def test_setlocal_on_eval_with_spill
assert_compiles '1', %q{
@b = binding
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs
index f2f990afde..87d2a613d0 100644
--- a/zjit/src/hir.rs
+++ b/zjit/src/hir.rs
@@ -969,6 +969,7 @@ fn can_direct_send(iseq: *const rb_iseq_t) -> bool {
else if unsafe { rb_get_iseq_flags_has_kw(iseq) } { false }
else if unsafe { rb_get_iseq_flags_has_kwrest(iseq) } { false }
else if unsafe { rb_get_iseq_flags_has_block(iseq) } { false }
+ else if unsafe { rb_get_iseq_flags_forwardable(iseq) } { false }
else { true }
}
@@ -2581,6 +2582,9 @@ pub enum CallType {
#[derive(Debug, PartialEq)]
pub enum ParameterType {
Optional,
+ /// For example, `foo(...)`. Interaction of JIT
+ /// calling convention and side exits currently unsolved.
+ Forwardable,
}
#[derive(Debug, PartialEq)]
@@ -2650,6 +2654,7 @@ pub const SELF_PARAM_IDX: usize = 0;
fn filter_unknown_parameter_type(iseq: *const rb_iseq_t) -> Result<(), ParseError> {
if unsafe { rb_get_iseq_body_param_opt_num(iseq) } != 0 { return Err(ParseError::UnknownParameterType(ParameterType::Optional)); }
+ if unsafe { rb_get_iseq_flags_forwardable(iseq) } { return Err(ParseError::UnknownParameterType(ParameterType::Forwardable)); }
Ok(())
}
@@ -4583,11 +4588,13 @@ mod tests {
eval("
def test(...) = super(...)
");
- assert_method_hir("test", expect![[r#"
- fn test@<compiled>:2:
- bb0(v0:BasicObject, v1:BasicObject):
- SideExit UnknownOpcode(invokesuperforward)
- "#]]);
+ assert_compile_fails("test", ParseError::UnknownParameterType(ParameterType::Forwardable));
+ }
+
+ #[test]
+ fn test_cant_compile_forwardable() {
+ eval("def forwardable(...) = nil");
+ assert_compile_fails("forwardable", ParseError::UnknownParameterType(ParameterType::Forwardable));
}
// TODO(max): Figure out how to generate a call with OPT_SEND flag
@@ -4631,11 +4638,7 @@ mod tests {
eval("
def test(...) = foo(...)
");
- assert_method_hir("test", expect![[r#"
- fn test@<compiled>:2:
- bb0(v0:BasicObject, v1:BasicObject):
- SideExit UnknownOpcode(sendforward)
- "#]]);
+ assert_compile_fails("test", ParseError::UnknownParameterType(ParameterType::Forwardable));
}
#[test]
@@ -5691,7 +5694,6 @@ mod opt_tests {
def kw_rest(**k) = k
def post(*rest, post) = post
def block(&b) = nil
- def forwardable(...) = nil
");
assert_optimized_method_hir("rest", expect![[r#"
@@ -5721,12 +5723,6 @@ mod opt_tests {
bb0(v0:BasicObject, v1:ArrayExact, v2:BasicObject):
Return v2
"#]]);
- assert_optimized_method_hir("forwardable", expect![[r#"
- fn forwardable@<compiled>:7:
- bb0(v0:BasicObject, v1:BasicObject):
- v3:NilClass = Const Value(nil)
- Return v3
- "#]]);
}
#[test]