@@ -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 ) ]
16681678pub enum ParseError {
16691679 StackUnderflow ( FrameState ) ,
16701680 UnknownOpcode ( String ) ,
16711681 UnknownNewArraySend ( String ) ,
16721682 UnhandledCallType ( CallType ) ,
1683+ UnhandledArgType ( ArgType ) ,
16731684}
16741685
16751686fn 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
17031725pub 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