@@ -71,6 +71,16 @@ func (vm *Vm) PUSH(obj py.Object) {
7171 vm .frame .Stack = append (vm .frame .Stack , obj )
7272}
7373
74+ // Adds a traceback to the exc passed in for the current vm state
75+ func (vm * Vm ) AddTraceback (exc * py.ExceptionInfo ) {
76+ exc .Traceback = & py.Traceback {
77+ Next : exc .Traceback ,
78+ Frame : vm .frame ,
79+ Lasti : vm .frame .Lasti ,
80+ Lineno : vm .frame .Code .Addr2Line (vm .frame .Lasti ),
81+ }
82+ }
83+
7484// Set an exception in the VM
7585//
7686// The exception must be a valid exception instance (eg as returned by
@@ -81,7 +91,8 @@ func (vm *Vm) SetException(exception py.Object) {
8191 vm .old_exc = vm .exc
8292 vm .exc .Value = exception
8393 vm .exc .Type = exception .Type ()
84- vm .exc .Traceback = py .None // FIXME start the traceback
94+ vm .exc .Traceback = nil
95+ vm .AddTraceback (& vm .exc )
8596 vm .exit = exitException
8697}
8798
@@ -93,6 +104,7 @@ func (vm *Vm) CheckExceptionRecover(r interface{}) {
93104 if exc , ok := r .(py.ExceptionInfo ); ok {
94105 vm .old_exc = vm .exc
95106 vm .exc = exc
107+ vm .AddTraceback (& vm .exc )
96108 vm .exit = exitException
97109 fmt .Printf ("*** Propagating exception: %s\n " , exc .Error ())
98110 } else {
@@ -636,9 +648,9 @@ func do_END_FINALLY(vm *Vm, arg int32) {
636648 w := vm .POP ()
637649 u := vm .POP ()
638650 // FIXME PyErr_Restore(v, w, u)
639- vm .exc .Type = v
651+ vm .exc .Type = v .( * py. Type )
640652 vm .exc .Value = w
641- vm .exc .Traceback = u
653+ vm .exc .Traceback = u .( * py. Traceback )
642654 vm .exit = exitReraise
643655 } else if v != py .None {
644656 vm .SetException (py .ExceptionNewf (py .SystemError , "'finally' pops bad exception %#v" , v ))
@@ -1315,9 +1327,9 @@ func (vm *Vm) UnwindExceptHandler(frame *py.Frame, block *py.TryBlock) {
13151327 } else {
13161328 frame .Stack = frame .Stack [:block .Level + 3 ]
13171329 }
1318- vm .exc .Type = vm .POP ()
1330+ vm .exc .Type = vm .POP ().( * py. Type )
13191331 vm .exc .Value = vm .POP ()
1320- vm .exc .Traceback = vm .POP ()
1332+ vm .exc .Traceback = vm .POP ().( * py. Traceback )
13211333}
13221334
13231335// Run the virtual machine on a Frame object
@@ -1405,21 +1417,16 @@ func RunFrame(frame *py.Frame) (res py.Object, err error) {
14051417 }
14061418 if vm .exit & (exitException | exitReraise ) != 0 && (b .Type == SETUP_EXCEPT || b .Type == SETUP_FINALLY ) {
14071419 fmt .Printf ("*** Exception\n " )
1408- var exc , val , tb py.Object
14091420 handler := b .Handler
14101421 // This invalidates b
14111422 frame .PushBlock (EXCEPT_HANDLER , - 1 , vm .STACK_LEVEL ())
14121423 vm .PUSH (vm .old_exc .Traceback )
14131424 vm .PUSH (vm .old_exc .Value )
1414- if vm .old_exc .Type != nil {
1415- vm .PUSH (vm .exc .Type )
1416- } else {
1417- vm .PUSH (py .None )
1418- }
1425+ vm .PUSH (vm .exc .Type ) // can be nil
14191426 // FIXME PyErr_Fetch(&exc, &val, &tb)
1420- exc = vm .exc .Type
1421- val = vm .exc .Value
1422- tb = vm .exc .Traceback
1427+ exc : = vm .exc .Type
1428+ val : = vm .exc .Value
1429+ tb : = vm .exc .Traceback
14231430 // Make the raw exception data
14241431 // available to the handler,
14251432 // so a program can emulate the
@@ -1429,9 +1436,6 @@ func RunFrame(frame *py.Frame) (res py.Object, err error) {
14291436 vm .exc .Type = exc
14301437 vm .exc .Value = val
14311438 vm .exc .Traceback = tb
1432- if tb == nil {
1433- tb = py .None
1434- }
14351439 vm .PUSH (tb )
14361440 vm .PUSH (val )
14371441 vm .PUSH (exc )
0 commit comments