@@ -182,10 +182,31 @@ pop_value(int64_t stack)
182
182
return Py_ARITHMETIC_RIGHT_SHIFT (int64_t , stack , BITS_PER_BLOCK );
183
183
}
184
184
185
+ #define MASK ((1<<BITS_PER_BLOCK)-1)
186
+
185
187
static inline Kind
186
188
top_of_stack (int64_t stack )
187
189
{
188
- return stack & ((1 <<BITS_PER_BLOCK )- 1 );
190
+ return stack & MASK ;
191
+ }
192
+
193
+ static inline Kind
194
+ peek (int64_t stack , int n )
195
+ {
196
+ assert (n >= 1 );
197
+ return (stack >>(BITS_PER_BLOCK * (n - 1 ))) & MASK ;
198
+ }
199
+
200
+ static Kind
201
+ stack_swap (int64_t stack , int n )
202
+ {
203
+ assert (n >= 1 );
204
+ Kind to_swap = peek (stack , n );
205
+ Kind top = top_of_stack (stack );
206
+ int shift = BITS_PER_BLOCK * (n - 1 );
207
+ int64_t replaced_low = (stack & ~(MASK << shift )) | (top << shift );
208
+ int64_t replaced_top = (replaced_low & ~MASK ) | to_swap ;
209
+ return replaced_top ;
189
210
}
190
211
191
212
static int64_t
@@ -218,6 +239,7 @@ tos_char(int64_t stack) {
218
239
case Null :
219
240
return 'N' ;
220
241
}
242
+ return '?' ;
221
243
}
222
244
223
245
static void
@@ -371,6 +393,7 @@ mark_stacks(PyCodeObject *code_obj, int len)
371
393
stacks [i + 1 ] = next_stack ;
372
394
break ;
373
395
case POP_EXCEPT :
396
+ assert (top_of_stack (next_stack ) == Except );
374
397
next_stack = pop_value (next_stack );
375
398
stacks [i + 1 ] = next_stack ;
376
399
break ;
@@ -409,6 +432,20 @@ mark_stacks(PyCodeObject *code_obj, int len)
409
432
stacks [i + 1 ] = next_stack ;
410
433
break ;
411
434
}
435
+ case SWAP :
436
+ {
437
+ int n = get_arg (code , i );
438
+ next_stack = stack_swap (next_stack , n );
439
+ stacks [i + 1 ] = next_stack ;
440
+ break ;
441
+ }
442
+ case COPY :
443
+ {
444
+ int n = get_arg (code , i );
445
+ next_stack = push_value (next_stack , peek (next_stack , n ));
446
+ stacks [i + 1 ] = next_stack ;
447
+ break ;
448
+ }
412
449
default :
413
450
{
414
451
int delta = PyCompile_OpcodeStackEffect (opcode , _Py_OPARG (code [i ]));
@@ -545,13 +582,6 @@ first_line_not_before(int *lines, int len, int line)
545
582
return result ;
546
583
}
547
584
548
- static void
549
- frame_stack_pop (PyFrameObject * f )
550
- {
551
- PyObject * v = _PyFrame_StackPop (f -> f_frame );
552
- Py_XDECREF (v );
553
- }
554
-
555
585
static PyFrameState
556
586
_PyFrame_GetState (PyFrameObject * frame )
557
587
{
@@ -739,7 +769,20 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
739
769
start_stack = pop_value (start_stack );
740
770
}
741
771
while (start_stack > best_stack ) {
742
- frame_stack_pop (f );
772
+ if (top_of_stack (start_stack ) == Except ) {
773
+ /* Pop exception stack as well as the evaluation stack */
774
+ PyThreadState * tstate = _PyThreadState_GET ();
775
+ _PyErr_StackItem * exc_info = tstate -> exc_info ;
776
+ PyObject * value = exc_info -> exc_value ;
777
+ PyObject * exc = _PyFrame_StackPop (f -> f_frame );
778
+ assert (PyExceptionInstance_Check (exc ) || exc == Py_None );
779
+ exc_info -> exc_value = exc ;
780
+ Py_XDECREF (value );
781
+ }
782
+ else {
783
+ PyObject * v = _PyFrame_StackPop (f -> f_frame );
784
+ Py_XDECREF (v );
785
+ }
743
786
start_stack = pop_value (start_stack );
744
787
}
745
788
/* Finally set the new lasti and return OK. */
0 commit comments