@@ -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 ;
@@ -420,6 +443,20 @@ mark_stacks(PyCodeObject *code_obj, int len)
420
443
stacks [i + 1 ] = next_stack ;
421
444
break ;
422
445
}
446
+ case SWAP :
447
+ {
448
+ int n = get_arg (code , i );
449
+ next_stack = stack_swap (next_stack , n );
450
+ stacks [i + 1 ] = next_stack ;
451
+ break ;
452
+ }
453
+ case COPY :
454
+ {
455
+ int n = get_arg (code , i );
456
+ next_stack = push_value (next_stack , peek (next_stack , n ));
457
+ stacks [i + 1 ] = next_stack ;
458
+ break ;
459
+ }
423
460
default :
424
461
{
425
462
int delta = PyCompile_OpcodeStackEffect (opcode , _Py_OPARG (code [i ]));
@@ -556,13 +593,6 @@ first_line_not_before(int *lines, int len, int line)
556
593
return result ;
557
594
}
558
595
559
- static void
560
- frame_stack_pop (PyFrameObject * f )
561
- {
562
- PyObject * v = _PyFrame_StackPop (f -> f_frame );
563
- Py_XDECREF (v );
564
- }
565
-
566
596
static PyFrameState
567
597
_PyFrame_GetState (PyFrameObject * frame )
568
598
{
@@ -782,7 +812,20 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
782
812
start_stack = pop_value (start_stack );
783
813
}
784
814
while (start_stack > best_stack ) {
785
- frame_stack_pop (f );
815
+ if (top_of_stack (start_stack ) == Except ) {
816
+ /* Pop exception stack as well as the evaluation stack */
817
+ PyThreadState * tstate = _PyThreadState_GET ();
818
+ _PyErr_StackItem * exc_info = tstate -> exc_info ;
819
+ PyObject * value = exc_info -> exc_value ;
820
+ PyObject * exc = _PyFrame_StackPop (f -> f_frame );
821
+ assert (PyExceptionInstance_Check (exc ) || exc == Py_None );
822
+ exc_info -> exc_value = exc ;
823
+ Py_XDECREF (value );
824
+ }
825
+ else {
826
+ PyObject * v = _PyFrame_StackPop (f -> f_frame );
827
+ Py_XDECREF (v );
828
+ }
786
829
start_stack = pop_value (start_stack );
787
830
}
788
831
/* Finally set the new lasti and return OK. */
0 commit comments