@@ -1131,7 +1131,21 @@ impl ExecutingFrame<'_> {
11311131 // TODO: In CPython, this does in-place unicode concatenation when
11321132 // refcount is 1. Falls back to regular iadd for now.
11331133 Instruction :: BinaryOpInplaceAddUnicode => {
1134- self . execute_bin_op ( vm, bytecode:: BinaryOperator :: InplaceAdd )
1134+ let b = self . top_value ( ) ;
1135+ let a = self . nth_value ( 1 ) ;
1136+ if let ( Some ( a_str) , Some ( b_str) ) = (
1137+ a. downcast_ref_if_exact :: < PyStr > ( vm) ,
1138+ b. downcast_ref_if_exact :: < PyStr > ( vm) ,
1139+ ) {
1140+ let result = a_str. as_wtf8 ( ) . py_add ( b_str. as_wtf8 ( ) ) ;
1141+ self . pop_value ( ) ;
1142+ self . pop_value ( ) ;
1143+ self . push_value ( result. to_pyobject ( vm) ) ;
1144+ Ok ( None )
1145+ } else {
1146+ self . deoptimize_binary_op ( bytecode:: BinaryOperator :: InplaceAdd ) ;
1147+ self . execute_bin_op ( vm, bytecode:: BinaryOperator :: InplaceAdd )
1148+ }
11351149 }
11361150 Instruction :: BinarySlice => {
11371151 // Stack: [container, start, stop] -> [result]
@@ -3139,15 +3153,11 @@ impl ExecutingFrame<'_> {
31393153 Ok ( ch) => {
31403154 self . pop_value ( ) ;
31413155 self . pop_value ( ) ;
3142- self . push_value (
3143- PyStr :: from ( ch) . into_pyobject ( vm) ,
3144- ) ;
3156+ self . push_value ( PyStr :: from ( ch) . into_pyobject ( vm) ) ;
31453157 return Ok ( None ) ;
31463158 }
31473159 Err ( e) => {
3148- self . deoptimize_binary_op (
3149- bytecode:: BinaryOperator :: Subscr ,
3150- ) ;
3160+ self . deoptimize_binary_op ( bytecode:: BinaryOperator :: Subscr ) ;
31513161 return Err ( e) ;
31523162 }
31533163 }
@@ -3339,8 +3349,7 @@ impl ExecutingFrame<'_> {
33393349 let callable = self . pop_value ( ) ;
33403350 let callable_tag = & * callable as * const PyObject as u32 ;
33413351 if cached_tag == callable_tag {
3342- let elements: Vec < PyObjectRef > =
3343- vm. extract_elements_with ( & obj, Ok ) ?;
3352+ let elements: Vec < PyObjectRef > = vm. extract_elements_with ( & obj, Ok ) ?;
33443353 self . push_value ( vm. ctx . new_tuple ( elements) . into ( ) ) ;
33453354 return Ok ( None ) ;
33463355 }
@@ -3590,7 +3599,9 @@ impl ExecutingFrame<'_> {
35903599 if elements. len ( ) == size {
35913600 let elems: Vec < _ > = elements. to_vec ( ) ;
35923601 self . pop_value ( ) ;
3593- self . state . stack . extend ( elems. into_iter ( ) . rev ( ) . map ( Some ) ) ;
3602+ for elem in elems. into_iter ( ) . rev ( ) {
3603+ self . push_value ( elem) ;
3604+ }
35943605 return Ok ( None ) ;
35953606 }
35963607 }
@@ -3606,7 +3617,9 @@ impl ExecutingFrame<'_> {
36063617 let elems: Vec < _ > = vec. to_vec ( ) ;
36073618 drop ( vec) ;
36083619 self . pop_value ( ) ;
3609- self . state . stack . extend ( elems. into_iter ( ) . rev ( ) . map ( Some ) ) ;
3620+ for elem in elems. into_iter ( ) . rev ( ) {
3621+ self . push_value ( elem) ;
3622+ }
36103623 return Ok ( None ) ;
36113624 }
36123625 }
@@ -5334,6 +5347,15 @@ impl ExecutingFrame<'_> {
53345347 None
53355348 }
53365349 }
5350+ bytecode:: BinaryOperator :: InplaceAdd => {
5351+ if a. downcast_ref_if_exact :: < PyStr > ( vm) . is_some ( )
5352+ && b. downcast_ref_if_exact :: < PyStr > ( vm) . is_some ( )
5353+ {
5354+ Some ( Instruction :: BinaryOpInplaceAddUnicode )
5355+ } else {
5356+ None
5357+ }
5358+ }
53375359 _ => None ,
53385360 } ;
53395361
0 commit comments