@@ -104,6 +104,16 @@ func (vm *Vm) SetException(exception py.Object) {
104
104
vm .exit = exitException
105
105
}
106
106
107
+ // Clears the current exception
108
+ //
109
+ // Doesn't adjust the exit code
110
+ func (vm * Vm ) ClearException () {
111
+ // Clear the exception
112
+ vm .exc .Type = nil
113
+ vm .exc .Value = nil
114
+ vm .exc .Traceback = nil
115
+ }
116
+
107
117
// Check for an exception (panic)
108
118
//
109
119
// Should be called with the result of recover
@@ -629,16 +639,15 @@ func do_POP_EXCEPT(vm *Vm, arg int32) {
629
639
func do_END_FINALLY (vm * Vm , arg int32 ) {
630
640
defer vm .CheckException ()
631
641
v := vm .POP ()
642
+ fmt .Printf ("END_FINALLY v=%v\n " , v )
632
643
if vInt , ok := v .(py.Int ); ok {
633
644
vm .exit = vmExit (vInt )
634
- if vm .exit == exitYield {
645
+ switch vm .exit {
646
+ case exitYield :
635
647
panic ("Unexpected exitYield in END_FINALLY" )
636
- }
637
- if vm .exit == exitReturn || vm .exit == exitContinue {
638
- // Leave return value on the stack
639
- // retval = vm.POP()
640
- }
641
- if vm .exit == exitSilenced {
648
+ case exitReturn , exitContinue :
649
+ vm .result = vm .POP ()
650
+ case exitSilenced :
642
651
// An exception was silenced by 'with', we must
643
652
// manually unwind the EXCEPT_HANDLER block which was
644
653
// created when the exception was caught, otherwise
@@ -662,7 +671,10 @@ func do_END_FINALLY(vm *Vm, arg int32) {
662
671
vm .exit = exitReraise
663
672
} else if v != py .None {
664
673
vm .SetException (py .ExceptionNewf (py .SystemError , "'finally' pops bad exception %#v" , v ))
674
+ } else {
675
+ vm .ClearException ()
665
676
}
677
+
666
678
}
667
679
668
680
// Loads the __build_class__ helper function to the stack which
@@ -1367,9 +1379,19 @@ func (vm *Vm) UnwindExceptHandler(frame *py.Frame, block *py.TryBlock) {
1367
1379
} else {
1368
1380
frame .Stack = frame .Stack [:block .Level + 3 ]
1369
1381
}
1370
- vm .exc .Type = vm .POP ().(* py.Type )
1371
- vm .exc .Value = vm .POP ()
1372
- vm .exc .Traceback = vm .POP ().(* py.Traceback )
1382
+ // If have just raised an exception, don't overwrite it
1383
+ //
1384
+ // FIXME if have two exceptions python shows both tracebacks
1385
+ //
1386
+ // FIXME this is a departure from python's way not sure it is
1387
+ // correct
1388
+ if vm .exc .Value != nil {
1389
+ vm .DROPN (3 )
1390
+ } else {
1391
+ vm .exc .Type = vm .POP ().(* py.Type )
1392
+ vm .exc .Value = vm .POP ()
1393
+ vm .exc .Traceback = vm .POP ().(* py.Traceback )
1394
+ }
1373
1395
}
1374
1396
1375
1397
// Run the virtual machine on a Frame object
0 commit comments