Skip to content

Commit a045094

Browse files
committed
Bail out of HIR translation if we can't handle a param flag
1 parent 3e94b5f commit a045094

1 file changed

Lines changed: 84 additions & 11 deletions

File tree

zjit/src/hir.rs

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,12 +1664,23 @@ pub enum CallType {
16641664
Forwarding,
16651665
}
16661666

1667+
#[derive(Debug, PartialEq)]
1668+
pub enum ArgType {
1669+
Opt,
1670+
Rest,
1671+
Post,
1672+
Kw,
1673+
KwRest,
1674+
Block,
1675+
}
1676+
16671677
#[derive(Debug, PartialEq)]
16681678
pub enum ParseError {
16691679
StackUnderflow(FrameState),
16701680
UnknownOpcode(String),
16711681
UnknownNewArraySend(String),
16721682
UnhandledCallType(CallType),
1683+
UnhandledArgType(ArgType),
16731684
}
16741685

16751686
fn num_lead_params(iseq: *const rb_iseq_t) -> usize {
@@ -1699,8 +1710,20 @@ fn filter_translatable_calls(flag: u32) -> Result<(), ParseError> {
16991710
Ok(())
17001711
}
17011712

1713+
/// If we can't handle the type of params (yet), bail out.
1714+
fn filter_translatable_params(iseq: IseqPtr) -> Result<(), ParseError> {
1715+
if unsafe { rb_get_iseq_flags_has_opt(iseq) } { return Err(ParseError::UnhandledArgType(ArgType::Opt)); }
1716+
if unsafe { rb_get_iseq_flags_has_rest(iseq) } { return Err(ParseError::UnhandledArgType(ArgType::Rest)); }
1717+
if unsafe { rb_get_iseq_flags_has_post(iseq) } { return Err(ParseError::UnhandledArgType(ArgType::Post)); }
1718+
if unsafe { rb_get_iseq_flags_has_kw(iseq) } { return Err(ParseError::UnhandledArgType(ArgType::Kw)); }
1719+
if unsafe { rb_get_iseq_flags_has_kwrest(iseq) } { return Err(ParseError::UnhandledArgType(ArgType::KwRest)); }
1720+
if unsafe { rb_get_iseq_flags_has_block(iseq) } { return Err(ParseError::UnhandledArgType(ArgType::Block)); }
1721+
Ok(())
1722+
}
1723+
17021724
/// Compile ISEQ into High-level IR
17031725
pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
1726+
filter_translatable_params(iseq)?;
17041727
let mut fun = Function::new(iseq);
17051728
// Compute a map of PC->Block by finding jump targets
17061729
let jump_targets = compute_jump_targets(iseq);
@@ -2789,31 +2812,80 @@ mod tests {
27892812
}
27902813

27912814
#[test]
2792-
fn test_cant_compile_splat() {
2815+
fn test_cant_compile_opt_arg() {
2816+
eval("
2817+
def test(a=1) = 1
2818+
");
2819+
assert_compile_fails("test", ParseError::UnhandledArgType(ArgType::Opt))
2820+
}
2821+
2822+
#[test]
2823+
fn test_cant_compile_rest_arg() {
2824+
eval("
2825+
def test(*a) = 1
2826+
");
2827+
assert_compile_fails("test", ParseError::UnhandledArgType(ArgType::Rest))
2828+
}
2829+
2830+
#[test]
2831+
fn test_cant_compile_post_arg() {
2832+
eval("
2833+
def test(*a, b) = 1
2834+
");
2835+
// TODO(max): Change to Post when we support Rest
2836+
assert_compile_fails("test", ParseError::UnhandledArgType(ArgType::Rest))
2837+
}
2838+
2839+
#[test]
2840+
fn test_cant_compile_kw_arg() {
2841+
eval("
2842+
def test(a:) = 1
2843+
");
2844+
assert_compile_fails("test", ParseError::UnhandledArgType(ArgType::Kw))
2845+
}
2846+
2847+
#[test]
2848+
fn test_cant_compile_kwrest_arg() {
2849+
eval("
2850+
def test(**a) = 1
2851+
");
2852+
assert_compile_fails("test", ParseError::UnhandledArgType(ArgType::KwRest))
2853+
}
2854+
2855+
#[test]
2856+
fn test_cant_compile_block_arg() {
2857+
eval("
2858+
def test(&a) = 1
2859+
");
2860+
assert_compile_fails("test", ParseError::UnhandledArgType(ArgType::Block))
2861+
}
2862+
2863+
#[test]
2864+
fn test_cant_compile_send_splat() {
27932865
eval("
27942866
def test(a) = foo(*a)
27952867
");
27962868
assert_compile_fails("test", ParseError::UnknownOpcode("splatarray".into()))
27972869
}
27982870

27992871
#[test]
2800-
fn test_cant_compile_block_arg() {
2872+
fn test_cant_compile_send_block_arg() {
28012873
eval("
28022874
def test(a) = foo(&a)
28032875
");
28042876
assert_compile_fails("test", ParseError::UnhandledCallType(CallType::BlockArg))
28052877
}
28062878

28072879
#[test]
2808-
fn test_cant_compile_kwarg() {
2880+
fn test_cant_compile_send_kwarg() {
28092881
eval("
28102882
def test(a) = foo(a: 1)
28112883
");
28122884
assert_compile_fails("test", ParseError::UnhandledCallType(CallType::Kwarg))
28132885
}
28142886

28152887
#[test]
2816-
fn test_cant_compile_kw_splat() {
2888+
fn test_cant_compile_send_kw_splat() {
28172889
eval("
28182890
def test(a) = foo(**a)
28192891
");
@@ -2823,23 +2895,23 @@ mod tests {
28232895
// TODO(max): Figure out how to generate a call with TAILCALL flag
28242896

28252897
#[test]
2826-
fn test_cant_compile_super() {
2898+
fn test_cant_compile_send_super() {
28272899
eval("
28282900
def test = super()
28292901
");
28302902
assert_compile_fails("test", ParseError::UnknownOpcode("invokesuper".into()))
28312903
}
28322904

28332905
#[test]
2834-
fn test_cant_compile_zsuper() {
2906+
fn test_cant_compile_send_zsuper() {
28352907
eval("
28362908
def test = super
28372909
");
28382910
assert_compile_fails("test", ParseError::UnknownOpcode("invokesuper".into()))
28392911
}
28402912

28412913
#[test]
2842-
fn test_cant_compile_super_forward() {
2914+
fn test_cant_compile_send_super_forward() {
28432915
eval("
28442916
def test(...) = super(...)
28452917
");
@@ -2849,23 +2921,24 @@ mod tests {
28492921
// TODO(max): Figure out how to generate a call with OPT_SEND flag
28502922

28512923
#[test]
2852-
fn test_cant_compile_kw_splat_mut() {
2924+
fn test_cant_compile_send_kw_splat_mut() {
28532925
eval("
28542926
def test(a) = foo **a, b: 1
28552927
");
28562928
assert_compile_fails("test", ParseError::UnknownOpcode("putspecialobject".into()))
28572929
}
28582930

28592931
#[test]
2860-
fn test_cant_compile_splat_mut() {
2932+
fn test_cant_compile_send_splat_mut() {
28612933
eval("
28622934
def test(*) = foo *, 1
28632935
");
2864-
assert_compile_fails("test", ParseError::UnknownOpcode("splatarray".into()))
2936+
// TODO(max): Change to unhandled splat mut call type when we support rest params
2937+
assert_compile_fails("test", ParseError::UnhandledArgType(ArgType::Rest))
28652938
}
28662939

28672940
#[test]
2868-
fn test_cant_compile_forwarding() {
2941+
fn test_cant_compile_send_forwarding() {
28692942
eval("
28702943
def test(...) = foo(...)
28712944
");

0 commit comments

Comments
 (0)