@@ -1209,8 +1209,8 @@ impl ExecutingFrame<'_> {
12091209 }
12101210 Instruction :: CompareOp { op } => self . execute_compare ( vm, op. get ( arg) ) ,
12111211 Instruction :: ContainsOp ( invert) => {
1212- let b = self . pop_stackref ( ) ;
1213- let a = self . pop_stackref ( ) ;
1212+ let b = self . pop_value ( ) ;
1213+ let a = self . pop_value ( ) ;
12141214
12151215 let value = match invert. get ( arg) {
12161216 bytecode:: Invert :: No => self . _in ( vm, & a, & b) ?,
@@ -1228,12 +1228,7 @@ impl ExecutingFrame<'_> {
12281228 // This is 1-indexed to match CPython
12291229 let idx = index. get ( arg) as usize ;
12301230 let stack_len = self . state . stack . len ( ) ;
1231- if stack_len < idx {
1232- eprintln ! ( "CopyItem ERROR: stack_len={}, idx={}" , stack_len, idx) ;
1233- eprintln ! ( " code: {}" , self . code. obj_name) ;
1234- eprintln ! ( " lasti: {}" , self . lasti( ) ) ;
1235- panic ! ( "CopyItem: stack underflow" ) ;
1236- }
1231+ debug_assert ! ( stack_len >= idx, "CopyItem: stack underflow" ) ;
12371232 let value = self . state . stack [ stack_len - idx] . clone ( ) ;
12381233 self . push_stackref_opt ( value) ;
12391234 Ok ( None )
@@ -1816,9 +1811,10 @@ impl ExecutingFrame<'_> {
18161811 Ok ( None )
18171812 }
18181813 Instruction :: LoadFastBorrow ( idx) => {
1814+ // TODO: re-enable true borrowed ref optimization after fixing
1815+ // stack corruption issue
18191816 let idx = idx. get ( arg) as usize ;
1820- let fastlocals = self . fastlocals . lock ( ) ;
1821- let obj = fastlocals[ idx] . as_deref ( ) . ok_or_else ( || {
1817+ let x = self . fastlocals . lock ( ) [ idx] . clone ( ) . ok_or_else ( || {
18221818 vm. new_exception_msg (
18231819 vm. ctx . exceptions . unbound_local_error . to_owned ( ) ,
18241820 format ! (
@@ -1828,19 +1824,15 @@ impl ExecutingFrame<'_> {
18281824 . into ( ) ,
18291825 )
18301826 } ) ?;
1831- // SAFETY: the compiler guarantees this value is consumed within
1832- // the same basic block, before any STORE_FAST/DELETE_FAST could
1833- // overwrite the source fastlocal slot.
1834- unsafe { self . push_borrowed ( obj) } ;
1835- drop ( fastlocals) ;
1827+ self . push_value ( x) ;
18361828 Ok ( None )
18371829 }
18381830 Instruction :: LoadFastBorrowLoadFastBorrow { arg : packed } => {
18391831 let oparg = packed. get ( arg) ;
18401832 let idx1 = ( oparg >> 4 ) as usize ;
18411833 let idx2 = ( oparg & 15 ) as usize ;
18421834 let fastlocals = self . fastlocals . lock ( ) ;
1843- let obj1 = fastlocals[ idx1] . as_deref ( ) . ok_or_else ( || {
1835+ let x1 = fastlocals[ idx1] . clone ( ) . ok_or_else ( || {
18441836 vm. new_exception_msg (
18451837 vm. ctx . exceptions . unbound_local_error . to_owned ( ) ,
18461838 format ! (
@@ -1850,7 +1842,7 @@ impl ExecutingFrame<'_> {
18501842 . into ( ) ,
18511843 )
18521844 } ) ?;
1853- let obj2 = fastlocals[ idx2] . as_deref ( ) . ok_or_else ( || {
1845+ let x2 = fastlocals[ idx2] . clone ( ) . ok_or_else ( || {
18541846 vm. new_exception_msg (
18551847 vm. ctx . exceptions . unbound_local_error . to_owned ( ) ,
18561848 format ! (
@@ -1860,12 +1852,9 @@ impl ExecutingFrame<'_> {
18601852 . into ( ) ,
18611853 )
18621854 } ) ?;
1863- // SAFETY: see LoadFastBorrow above.
1864- unsafe {
1865- self . push_borrowed ( obj1) ;
1866- self . push_borrowed ( obj2) ;
1867- }
18681855 drop ( fastlocals) ;
1856+ self . push_value ( x1) ;
1857+ self . push_value ( x2) ;
18691858 Ok ( None )
18701859 }
18711860 Instruction :: LoadGlobal ( idx) => {
@@ -2460,7 +2449,11 @@ impl ExecutingFrame<'_> {
24602449 }
24612450 Instruction :: YieldValue { arg : oparg } => {
24622451 debug_assert ! (
2463- self . state. stack. iter( ) . flatten( ) . all( |sr| !sr. is_borrowed( ) ) ,
2452+ self . state
2453+ . stack
2454+ . iter( )
2455+ . flatten( )
2456+ . all( |sr| !sr. is_borrowed( ) ) ,
24642457 "borrowed refs on stack at yield point"
24652458 ) ;
24662459 let value = self . pop_value ( ) ;
@@ -3740,37 +3733,37 @@ impl ExecutingFrame<'_> {
37403733
37413734 #[ cfg_attr( feature = "flame-it" , flame( "Frame" ) ) ]
37423735 fn execute_bin_op ( & mut self , vm : & VirtualMachine , op : bytecode:: BinaryOperator ) -> FrameResult {
3743- let b_ref = self . pop_stackref ( ) ;
3744- let a_ref = self . pop_stackref ( ) ;
3736+ let b_ref = & self . pop_value ( ) ;
3737+ let a_ref = & self . pop_value ( ) ;
37453738 let value = match op {
3746- bytecode:: BinaryOperator :: Subtract => vm. _sub ( & a_ref, & b_ref) ,
3747- bytecode:: BinaryOperator :: Add => vm. _add ( & a_ref, & b_ref) ,
3748- bytecode:: BinaryOperator :: Multiply => vm. _mul ( & a_ref, & b_ref) ,
3749- bytecode:: BinaryOperator :: MatrixMultiply => vm. _matmul ( & a_ref, & b_ref) ,
3750- bytecode:: BinaryOperator :: Power => vm. _pow ( & a_ref, & b_ref, vm. ctx . none . as_object ( ) ) ,
3751- bytecode:: BinaryOperator :: TrueDivide => vm. _truediv ( & a_ref, & b_ref) ,
3752- bytecode:: BinaryOperator :: FloorDivide => vm. _floordiv ( & a_ref, & b_ref) ,
3753- bytecode:: BinaryOperator :: Remainder => vm. _mod ( & a_ref, & b_ref) ,
3754- bytecode:: BinaryOperator :: Lshift => vm. _lshift ( & a_ref, & b_ref) ,
3755- bytecode:: BinaryOperator :: Rshift => vm. _rshift ( & a_ref, & b_ref) ,
3756- bytecode:: BinaryOperator :: Xor => vm. _xor ( & a_ref, & b_ref) ,
3757- bytecode:: BinaryOperator :: Or => vm. _or ( & a_ref, & b_ref) ,
3758- bytecode:: BinaryOperator :: And => vm. _and ( & a_ref, & b_ref) ,
3759- bytecode:: BinaryOperator :: InplaceSubtract => vm. _isub ( & a_ref, & b_ref) ,
3760- bytecode:: BinaryOperator :: InplaceAdd => vm. _iadd ( & a_ref, & b_ref) ,
3761- bytecode:: BinaryOperator :: InplaceMultiply => vm. _imul ( & a_ref, & b_ref) ,
3762- bytecode:: BinaryOperator :: InplaceMatrixMultiply => vm. _imatmul ( & a_ref, & b_ref) ,
3739+ bytecode:: BinaryOperator :: Subtract => vm. _sub ( a_ref, b_ref) ,
3740+ bytecode:: BinaryOperator :: Add => vm. _add ( a_ref, b_ref) ,
3741+ bytecode:: BinaryOperator :: Multiply => vm. _mul ( a_ref, b_ref) ,
3742+ bytecode:: BinaryOperator :: MatrixMultiply => vm. _matmul ( a_ref, b_ref) ,
3743+ bytecode:: BinaryOperator :: Power => vm. _pow ( a_ref, b_ref, vm. ctx . none . as_object ( ) ) ,
3744+ bytecode:: BinaryOperator :: TrueDivide => vm. _truediv ( a_ref, b_ref) ,
3745+ bytecode:: BinaryOperator :: FloorDivide => vm. _floordiv ( a_ref, b_ref) ,
3746+ bytecode:: BinaryOperator :: Remainder => vm. _mod ( a_ref, b_ref) ,
3747+ bytecode:: BinaryOperator :: Lshift => vm. _lshift ( a_ref, b_ref) ,
3748+ bytecode:: BinaryOperator :: Rshift => vm. _rshift ( a_ref, b_ref) ,
3749+ bytecode:: BinaryOperator :: Xor => vm. _xor ( a_ref, b_ref) ,
3750+ bytecode:: BinaryOperator :: Or => vm. _or ( a_ref, b_ref) ,
3751+ bytecode:: BinaryOperator :: And => vm. _and ( a_ref, b_ref) ,
3752+ bytecode:: BinaryOperator :: InplaceSubtract => vm. _isub ( a_ref, b_ref) ,
3753+ bytecode:: BinaryOperator :: InplaceAdd => vm. _iadd ( a_ref, b_ref) ,
3754+ bytecode:: BinaryOperator :: InplaceMultiply => vm. _imul ( a_ref, b_ref) ,
3755+ bytecode:: BinaryOperator :: InplaceMatrixMultiply => vm. _imatmul ( a_ref, b_ref) ,
37633756 bytecode:: BinaryOperator :: InplacePower => {
3764- vm. _ipow ( & a_ref, & b_ref, vm. ctx . none . as_object ( ) )
3765- }
3766- bytecode:: BinaryOperator :: InplaceTrueDivide => vm. _itruediv ( & a_ref, & b_ref) ,
3767- bytecode:: BinaryOperator :: InplaceFloorDivide => vm. _ifloordiv ( & a_ref, & b_ref) ,
3768- bytecode:: BinaryOperator :: InplaceRemainder => vm. _imod ( & a_ref, & b_ref) ,
3769- bytecode:: BinaryOperator :: InplaceLshift => vm. _ilshift ( & a_ref, & b_ref) ,
3770- bytecode:: BinaryOperator :: InplaceRshift => vm. _irshift ( & a_ref, & b_ref) ,
3771- bytecode:: BinaryOperator :: InplaceXor => vm. _ixor ( & a_ref, & b_ref) ,
3772- bytecode:: BinaryOperator :: InplaceOr => vm. _ior ( & a_ref, & b_ref) ,
3773- bytecode:: BinaryOperator :: InplaceAnd => vm. _iand ( & a_ref, & b_ref) ,
3757+ vm. _ipow ( a_ref, b_ref, vm. ctx . none . as_object ( ) )
3758+ }
3759+ bytecode:: BinaryOperator :: InplaceTrueDivide => vm. _itruediv ( a_ref, b_ref) ,
3760+ bytecode:: BinaryOperator :: InplaceFloorDivide => vm. _ifloordiv ( a_ref, b_ref) ,
3761+ bytecode:: BinaryOperator :: InplaceRemainder => vm. _imod ( a_ref, b_ref) ,
3762+ bytecode:: BinaryOperator :: InplaceLshift => vm. _ilshift ( a_ref, b_ref) ,
3763+ bytecode:: BinaryOperator :: InplaceRshift => vm. _irshift ( a_ref, b_ref) ,
3764+ bytecode:: BinaryOperator :: InplaceXor => vm. _ixor ( a_ref, b_ref) ,
3765+ bytecode:: BinaryOperator :: InplaceOr => vm. _ior ( a_ref, b_ref) ,
3766+ bytecode:: BinaryOperator :: InplaceAnd => vm. _iand ( a_ref, b_ref) ,
37743767 bytecode:: BinaryOperator :: Subscr => a_ref. get_item ( b_ref. as_object ( ) , vm) ,
37753768 } ?;
37763769
@@ -4063,6 +4056,7 @@ impl ExecutingFrame<'_> {
40634056 /// The compiler guarantees consumption within the same basic block.
40644057 #[ inline]
40654058 #[ track_caller]
4059+ #[ allow( dead_code) ]
40664060 unsafe fn push_borrowed ( & mut self , obj : & PyObject ) {
40674061 self . push_stackref_opt ( Some ( unsafe { PyStackRef :: new_borrowed ( obj) } ) ) ;
40684062 }
@@ -4272,8 +4266,7 @@ impl ExecutingFrame<'_> {
42724266 ) ;
42734267 }
42744268 self . state . stack . drain ( stack_len - count..) . map ( |obj| {
4275- expect_unchecked ( obj, "pop_multiple but null found. This is a compiler bug." )
4276- . to_pyobj ( )
4269+ expect_unchecked ( obj, "pop_multiple but null found. This is a compiler bug." ) . to_pyobj ( )
42774270 } )
42784271 }
42794272
0 commit comments