@@ -326,7 +326,7 @@ pub enum Insn {
326326
327327 // Call a C function
328328 // `name` is for printing purposes only
329- CCall { cfun : * const u8 , args : Vec < InsnId > , name : ID } ,
329+ CCall { cfun : * const u8 , args : Vec < InsnId > , name : ID , return_type : Type } ,
330330
331331 // Send without block with dynamic dispatch
332332 // Ignoring keyword arguments etc for now
@@ -475,11 +475,11 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
475475 Insn :: FixnumLe { left, right, .. } => { write ! ( f, "FixnumLe {left}, {right}" ) } ,
476476 Insn :: FixnumGt { left, right, .. } => { write ! ( f, "FixnumGt {left}, {right}" ) } ,
477477 Insn :: FixnumGe { left, right, .. } => { write ! ( f, "FixnumGe {left}, {right}" ) } ,
478- Insn :: GuardType { val, guard_type, .. } => { write ! ( f, "GuardType {val}, {guard_type}" ) } ,
478+ Insn :: GuardType { val, guard_type, .. } => { write ! ( f, "GuardType {val}, {}" , guard_type . print ( self . ptr_map ) ) } ,
479479 Insn :: GuardBitEquals { val, expected, .. } => { write ! ( f, "GuardBitEquals {val}, {}" , expected. print( self . ptr_map) ) } ,
480480 Insn :: PatchPoint ( invariant) => { write ! ( f, "PatchPoint {}" , invariant. print( self . ptr_map) ) } ,
481481 Insn :: GetConstantPath { ic } => { write ! ( f, "GetConstantPath {:p}" , self . ptr_map. map_ptr( ic) ) } ,
482- Insn :: CCall { cfun, args, name } => {
482+ Insn :: CCall { cfun, args, name, return_type : _ } => {
483483 write ! ( f, "CCall {}@{:p}" , name. contents_lossy( ) , self . ptr_map. map_ptr( cfun) ) ?;
484484 for arg in args {
485485 write ! ( f, ", {arg}" ) ?;
@@ -790,7 +790,7 @@ impl Function {
790790 } ,
791791 ArraySet { array, idx, val } => ArraySet { array : find ! ( * array) , idx : * idx, val : find ! ( * val) } ,
792792 ArrayDup { val } => ArrayDup { val : find ! ( * val) } ,
793- CCall { cfun, args, name } => CCall { cfun : * cfun, args : args. iter ( ) . map ( |arg| find ! ( * arg) ) . collect ( ) , name : * name } ,
793+ CCall { cfun, args, name, return_type } => CCall { cfun : * cfun, args : args. iter ( ) . map ( |arg| find ! ( * arg) ) . collect ( ) , name : * name, return_type : * return_type } ,
794794 Defined { .. } => todo ! ( "find(Defined)" ) ,
795795 }
796796 }
@@ -838,7 +838,7 @@ impl Function {
838838 Insn :: StringIntern { .. } => types:: StringExact ,
839839 Insn :: NewArray { .. } => types:: ArrayExact ,
840840 Insn :: ArrayDup { .. } => types:: ArrayExact ,
841- Insn :: CCall { .. } => types :: Any ,
841+ Insn :: CCall { return_type , .. } => * return_type ,
842842 Insn :: GuardType { val, guard_type, .. } => self . type_of ( * val) . intersection ( * guard_type) ,
843843 Insn :: GuardBitEquals { val, expected, .. } => self . type_of ( * val) . intersection ( Type :: from_value ( * expected) ) ,
844844 Insn :: FixnumAdd { .. } => types:: Fixnum ,
@@ -1024,7 +1024,7 @@ impl Function {
10241024
10251025 // Filter for a leaf and GC free function
10261026 use crate :: cruby_methods:: FnProperties ;
1027- let Some ( FnProperties { leaf : true , no_gc : true } ) =
1027+ let Some ( FnProperties { leaf : true , no_gc : true , return_type } ) =
10281028 ZJITState :: get_method_annotations ( ) . get_cfunc_properties ( method)
10291029 else {
10301030 return Err ( ( ) ) ;
@@ -1040,7 +1040,7 @@ impl Function {
10401040 let cfun = unsafe { get_mct_func ( cfunc) } . cast ( ) ;
10411041 let mut cfunc_args = vec ! [ self_val] ;
10421042 cfunc_args. append ( & mut args) ;
1043- let ccall = fun. push_insn ( block, Insn :: CCall { cfun, args : cfunc_args, name : method_id } ) ;
1043+ let ccall = fun. push_insn ( block, Insn :: CCall { cfun, args : cfunc_args, name : method_id, return_type } ) ;
10441044 fun. make_equal_to ( send_insn_id, ccall) ;
10451045 return Ok ( ( ) ) ;
10461046 }
@@ -3306,7 +3306,7 @@ mod opt_tests {
33063306 bb0():
33073307 v1:Fixnum[1] = Const Value(1)
33083308 PatchPoint MethodRedefined(Integer@0x1000, itself@0x1008)
3309- v8:Any = CCall itself@0x1010, v1
3309+ v8:BasicObject = CCall itself@0x1010, v1
33103310 PatchPoint CalleeModifiedLocals(v8)
33113311 Return v8
33123312 "# ] ] ) ;
@@ -3330,4 +3330,24 @@ mod opt_tests {
33303330 Return v4
33313331 "# ] ] ) ;
33323332 }
3333+
3334+ #[ test]
3335+ fn string_bytesize_simple ( ) {
3336+ eval ( "
3337+ def test = 'abc'.bytesize
3338+ test
3339+ test
3340+ " ) ;
3341+ assert_optimized_method_hir ( "test" , expect ! [ [ r#"
3342+ fn test:
3343+ bb0():
3344+ v1:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
3345+ v2:StringExact = StringCopy v1
3346+ PatchPoint MethodRedefined(String@0x1008, bytesize@0x1010)
3347+ v8:StringExact[VALUE(0x1018)] = GuardType v2, StringExact[VALUE(0x1018)]
3348+ v9:Fixnum = CCall bytesize@0x1020, v2
3349+ PatchPoint CalleeModifiedLocals(v9)
3350+ Return v9
3351+ "# ] ] ) ;
3352+ }
33333353}
0 commit comments