@@ -439,7 +439,7 @@ impl PtrPrintMap {
439439#[ derive( Debug , Clone , Copy ) ]
440440pub enum SideExitReason {
441441 UnknownNewarraySend ( vm_opt_newarray_send_type ) ,
442- UnknownCallType ,
442+ UnhandledCallType ( CallType ) ,
443443 UnknownSpecialVariable ( u64 ) ,
444444 UnhandledHIRInsn ( InsnId ) ,
445445 UnhandledYARVInsn ( u32 ) ,
@@ -2808,7 +2808,7 @@ fn compute_bytecode_info(iseq: *const rb_iseq_t) -> BytecodeInfo {
28082808 BytecodeInfo { jump_targets : result, has_send }
28092809}
28102810
2811- #[ derive( Debug , PartialEq ) ]
2811+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
28122812pub enum CallType {
28132813 Splat ,
28142814 BlockArg ,
@@ -2846,19 +2846,19 @@ fn num_locals(iseq: *const rb_iseq_t) -> usize {
28462846}
28472847
28482848/// If we can't handle the type of send (yet), bail out.
2849- fn unknown_call_type ( flag : u32 ) -> bool {
2850- if ( flag & VM_CALL_KW_SPLAT_MUT ) != 0 { return true ; }
2851- if ( flag & VM_CALL_ARGS_SPLAT_MUT ) != 0 { return true ; }
2852- if ( flag & VM_CALL_ARGS_SPLAT ) != 0 { return true ; }
2853- if ( flag & VM_CALL_KW_SPLAT ) != 0 { return true ; }
2854- if ( flag & VM_CALL_ARGS_BLOCKARG ) != 0 { return true ; }
2855- if ( flag & VM_CALL_KWARG ) != 0 { return true ; }
2856- if ( flag & VM_CALL_TAILCALL ) != 0 { return true ; }
2857- if ( flag & VM_CALL_SUPER ) != 0 { return true ; }
2858- if ( flag & VM_CALL_ZSUPER ) != 0 { return true ; }
2859- if ( flag & VM_CALL_OPT_SEND ) != 0 { return true ; }
2860- if ( flag & VM_CALL_FORWARDING ) != 0 { return true ; }
2861- false
2849+ fn unknown_call_type ( flag : u32 ) -> Result < ( ) , CallType > {
2850+ if ( flag & VM_CALL_KW_SPLAT_MUT ) != 0 { return Err ( CallType :: KwSplatMut ) ; }
2851+ if ( flag & VM_CALL_ARGS_SPLAT_MUT ) != 0 { return Err ( CallType :: SplatMut ) ; }
2852+ if ( flag & VM_CALL_ARGS_SPLAT ) != 0 { return Err ( CallType :: Splat ) ; }
2853+ if ( flag & VM_CALL_KW_SPLAT ) != 0 { return Err ( CallType :: KwSplat ) ; }
2854+ if ( flag & VM_CALL_ARGS_BLOCKARG ) != 0 { return Err ( CallType :: BlockArg ) ; }
2855+ if ( flag & VM_CALL_KWARG ) != 0 { return Err ( CallType :: Kwarg ) ; }
2856+ if ( flag & VM_CALL_TAILCALL ) != 0 { return Err ( CallType :: Tailcall ) ; }
2857+ if ( flag & VM_CALL_SUPER ) != 0 { return Err ( CallType :: Super ) ; }
2858+ if ( flag & VM_CALL_ZSUPER ) != 0 { return Err ( CallType :: Zsuper ) ; }
2859+ if ( flag & VM_CALL_OPT_SEND ) != 0 { return Err ( CallType :: OptSend ) ; }
2860+ if ( flag & VM_CALL_FORWARDING ) != 0 { return Err ( CallType :: Forwarding ) ; }
2861+ Ok ( ( ) )
28622862}
28632863
28642864/// We have IseqPayload, which keeps track of HIR Types in the interpreter, but this is not useful
@@ -3324,10 +3324,10 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
33243324 // NB: opt_neq has two cd; get_arg(0) is for eq and get_arg(1) is for neq
33253325 let cd: * const rb_call_data = get_arg ( pc, 1 ) . as_ptr ( ) ;
33263326 let call_info = unsafe { rb_get_call_data_ci ( cd) } ;
3327- if unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
3327+ if let Err ( call_type ) = unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
33283328 // Unknown call type; side-exit into the interpreter
33293329 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
3330- fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnknownCallType } ) ;
3330+ fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnhandledCallType ( call_type ) } ) ;
33313331 break ; // End the block
33323332 }
33333333 let argc = unsafe { vm_ci_argc ( ( * cd) . ci ) } ;
@@ -3345,10 +3345,10 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
33453345 // NB: these instructions have the recv for the call at get_arg(0)
33463346 let cd: * const rb_call_data = get_arg ( pc, 1 ) . as_ptr ( ) ;
33473347 let call_info = unsafe { rb_get_call_data_ci ( cd) } ;
3348- if unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
3348+ if let Err ( call_type ) = unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
33493349 // Unknown call type; side-exit into the interpreter
33503350 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
3351- fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnknownCallType } ) ;
3351+ fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnhandledCallType ( call_type ) } ) ;
33523352 break ; // End the block
33533353 }
33543354 let argc = unsafe { vm_ci_argc ( ( * cd) . ci ) } ;
@@ -3403,10 +3403,10 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
34033403 YARVINSN_opt_send_without_block => {
34043404 let cd: * const rb_call_data = get_arg ( pc, 0 ) . as_ptr ( ) ;
34053405 let call_info = unsafe { rb_get_call_data_ci ( cd) } ;
3406- if unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
3406+ if let Err ( call_type ) = unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
34073407 // Unknown call type; side-exit into the interpreter
34083408 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
3409- fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnknownCallType } ) ;
3409+ fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnhandledCallType ( call_type ) } ) ;
34103410 break ; // End the block
34113411 }
34123412 let argc = unsafe { vm_ci_argc ( ( * cd) . ci ) } ;
@@ -3421,10 +3421,10 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
34213421 let cd: * const rb_call_data = get_arg ( pc, 0 ) . as_ptr ( ) ;
34223422 let blockiseq: IseqPtr = get_arg ( pc, 1 ) . as_iseq ( ) ;
34233423 let call_info = unsafe { rb_get_call_data_ci ( cd) } ;
3424- if unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
3424+ if let Err ( call_type ) = unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
34253425 // Unknown call type; side-exit into the interpreter
34263426 let exit_id = fun. push_insn ( block, Insn :: Snapshot { state : exit_state } ) ;
3427- fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnknownCallType } ) ;
3427+ fun. push_insn ( block, Insn :: SideExit { state : exit_id, reason : SideExitReason :: UnhandledCallType ( call_type ) } ) ;
34283428 break ; // End the block
34293429 }
34303430 let argc = unsafe { vm_ci_argc ( ( * cd) . ci ) } ;
@@ -3549,8 +3549,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
35493549 let cd: * const rb_call_data = get_arg ( pc, 0 ) . as_ptr ( ) ;
35503550 let call_info = unsafe { rb_get_call_data_ci ( cd) } ;
35513551
3552- if unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
3553- assert ! ( false , "objtostring should not have unknown call type" ) ;
3552+ if let Err ( call_type ) = unknown_call_type ( unsafe { rb_vm_ci_flag ( call_info) } ) {
3553+ assert ! ( false , "objtostring should not have unknown call type {call_type:?} " ) ;
35543554 }
35553555 let argc = unsafe { vm_ci_argc ( ( * cd) . ci ) } ;
35563556 assert_eq ! ( 0 , argc, "objtostring should not have args" ) ;
@@ -4872,12 +4872,12 @@ mod tests {
48724872 eval ( "
48734873 def test(a) = foo(*a)
48744874 " ) ;
4875- assert_snapshot ! ( hir_string( "test" ) , @r# "
4876- fn test@<compiled>:2:
4877- bb0(v0:BasicObject, v1:BasicObject):
4878- v4:ArrayExact = ToArray v1
4879- SideExit UnknownCallType
4880- "# ) ;
4875+ assert_snapshot ! ( hir_string( "test" ) , @r"
4876+ fn test@<compiled>:2:
4877+ bb0(v0:BasicObject, v1:BasicObject):
4878+ v4:ArrayExact = ToArray v1
4879+ SideExit UnhandledCallType(Splat)
4880+ " ) ;
48814881 }
48824882
48834883 #[ test]
@@ -4889,7 +4889,7 @@ mod tests {
48894889 fn test@<compiled>:2:
48904890 bb0(v0:BasicObject, v1:BasicObject):
48914891 v3:BasicObject = GetLocal l0, EP@3
4892- SideExit UnknownCallType
4892+ SideExit UnhandledCallType(BlockArg)
48934893 " ) ;
48944894 }
48954895
@@ -4898,24 +4898,24 @@ mod tests {
48984898 eval ( "
48994899 def test(a) = foo(a: 1)
49004900 " ) ;
4901- assert_snapshot ! ( hir_string( "test" ) , @r# "
4902- fn test@<compiled>:2:
4903- bb0(v0:BasicObject, v1:BasicObject):
4904- v3:Fixnum[1] = Const Value(1)
4905- SideExit UnknownCallType
4906- "# ) ;
4901+ assert_snapshot ! ( hir_string( "test" ) , @r"
4902+ fn test@<compiled>:2:
4903+ bb0(v0:BasicObject, v1:BasicObject):
4904+ v3:Fixnum[1] = Const Value(1)
4905+ SideExit UnhandledCallType(Kwarg)
4906+ " ) ;
49074907 }
49084908
49094909 #[ test]
49104910 fn test_cant_compile_kw_splat ( ) {
49114911 eval ( "
49124912 def test(a) = foo(**a)
49134913 " ) ;
4914- assert_snapshot ! ( hir_string( "test" ) , @r# "
4915- fn test@<compiled>:2:
4916- bb0(v0:BasicObject, v1:BasicObject):
4917- SideExit UnknownCallType
4918- "# ) ;
4914+ assert_snapshot ! ( hir_string( "test" ) , @r"
4915+ fn test@<compiled>:2:
4916+ bb0(v0:BasicObject, v1:BasicObject):
4917+ SideExit UnhandledCallType(KwSplat)
4918+ " ) ;
49194919 }
49204920
49214921 // TODO(max): Figure out how to generate a call with TAILCALL flag
@@ -4965,33 +4965,33 @@ mod tests {
49654965 eval ( "
49664966 def test(a) = foo **a, b: 1
49674967 " ) ;
4968- assert_snapshot ! ( hir_string( "test" ) , @r# "
4969- fn test@<compiled>:2:
4970- bb0(v0:BasicObject, v1:BasicObject):
4971- v3:Class[VMFrozenCore] = Const Value(VALUE(0x1000))
4972- v5:HashExact = NewHash
4973- v7:BasicObject = SendWithoutBlock v3, :core#hash_merge_kwd, v5, v1
4974- v8:Class[VMFrozenCore] = Const Value(VALUE(0x1000))
4975- v9:StaticSymbol[:b] = Const Value(VALUE(0x1008))
4976- v10:Fixnum[1] = Const Value(1)
4977- v12:BasicObject = SendWithoutBlock v8, :core#hash_merge_ptr, v7, v9, v10
4978- SideExit UnknownCallType
4979- "# ) ;
4968+ assert_snapshot ! ( hir_string( "test" ) , @r"
4969+ fn test@<compiled>:2:
4970+ bb0(v0:BasicObject, v1:BasicObject):
4971+ v3:Class[VMFrozenCore] = Const Value(VALUE(0x1000))
4972+ v5:HashExact = NewHash
4973+ v7:BasicObject = SendWithoutBlock v3, :core#hash_merge_kwd, v5, v1
4974+ v8:Class[VMFrozenCore] = Const Value(VALUE(0x1000))
4975+ v9:StaticSymbol[:b] = Const Value(VALUE(0x1008))
4976+ v10:Fixnum[1] = Const Value(1)
4977+ v12:BasicObject = SendWithoutBlock v8, :core#hash_merge_ptr, v7, v9, v10
4978+ SideExit UnhandledCallType(KwSplatMut)
4979+ " ) ;
49804980 }
49814981
49824982 #[ test]
49834983 fn test_cant_compile_splat_mut ( ) {
49844984 eval ( "
49854985 def test(*) = foo *, 1
49864986 " ) ;
4987- assert_snapshot ! ( hir_string( "test" ) , @r# "
4988- fn test@<compiled>:2:
4989- bb0(v0:BasicObject, v1:ArrayExact):
4990- v4:ArrayExact = ToNewArray v1
4991- v5:Fixnum[1] = Const Value(1)
4992- ArrayPush v4, v5
4993- SideExit UnknownCallType
4994- "# ) ;
4987+ assert_snapshot ! ( hir_string( "test" ) , @r"
4988+ fn test@<compiled>:2:
4989+ bb0(v0:BasicObject, v1:ArrayExact):
4990+ v4:ArrayExact = ToNewArray v1
4991+ v5:Fixnum[1] = Const Value(1)
4992+ ArrayPush v4, v5
4993+ SideExit UnhandledCallType(SplatMut)
4994+ " ) ;
49954995 }
49964996
49974997 #[ test]
@@ -7398,12 +7398,12 @@ mod opt_tests {
73987398 test
73997399 test
74007400 " ) ;
7401- assert_snapshot ! ( hir_string( "test" ) , @r# "
7402- fn test@<compiled>:3:
7403- bb0(v0:BasicObject):
7404- v2:Fixnum[1] = Const Value(1)
7405- SideExit UnknownCallType
7406- "# ) ;
7401+ assert_snapshot ! ( hir_string( "test" ) , @r"
7402+ fn test@<compiled>:3:
7403+ bb0(v0:BasicObject):
7404+ v2:Fixnum[1] = Const Value(1)
7405+ SideExit UnhandledCallType(Kwarg)
7406+ " ) ;
74077407 }
74087408
74097409 #[ test]
@@ -7414,12 +7414,12 @@ mod opt_tests {
74147414 test
74157415 test
74167416 " ) ;
7417- assert_snapshot ! ( hir_string( "test" ) , @r# "
7418- fn test@<compiled>:3:
7419- bb0(v0:BasicObject):
7420- v2:Fixnum[1] = Const Value(1)
7421- SideExit UnknownCallType
7422- "# ) ;
7417+ assert_snapshot ! ( hir_string( "test" ) , @r"
7418+ fn test@<compiled>:3:
7419+ bb0(v0:BasicObject):
7420+ v2:Fixnum[1] = Const Value(1)
7421+ SideExit UnhandledCallType(Kwarg)
7422+ " ) ;
74237423 }
74247424
74257425 #[ test]
0 commit comments