gnue / NEWT0

NewtonScript
http://gnue.github.io/NEWT0
34 stars 13 forks source link

Exception handler stack is not popped when handler returns a value #7

Open pablomarx opened 5 years ago

pablomarx commented 5 years ago

It appears that the exception handler stack is not popped when a handler is invoked that returns a value. This would seem to be because the kNBCPopHandlers is generated after the branch to the handler, and thus is not invoked due to the return statement.

This causes subsequent exceptions to not be handled properly.

The following NewtonScript code demonstrates the problem:

func x() begin
    try
        Throw('|evt.ex|, "");
    onexception |evt.ex| do
        return "caught";
    return "not caught";
end;

print("Attempt 1: " & x() & "\n");
print("Attempt 2: " & x() & "\n");

When ran under NEWT/0, the output is:

Attempt 1: caught

(Note: Attempt 2 is never logged)

Under WallyScript/NewtonScript 1.x:

Welcome to WallyScript!

      0 > func x() begin try Throw('|evt.ex|, ""); onexception |evt.ex| do return "caught"; return "not caught"; end;
#2AE5F9   x
      0 > print("Attempt 1: " & x() & "\n");
"Attempt 1: caught
"
#2        NIL
      0 > print("Attempt 2: " & x() & "\n");
"Attempt 2: caught
"
#2        NIL
      0 > 
pablomarx commented 5 years ago

I've been able to resolve this by removing the call to pop handlers from NBCGenTry():

https://github.com/gnue/NEWT0/blob/9c9c5d1e5b2b34b271ea614134ed7ed8201c0698/src/newt_core/NewtBC.c#L1259

And adding it above this line in NBCGenTryPost():

https://github.com/gnue/NEWT0/blob/9c9c5d1e5b2b34b271ea614134ed7ed8201c0698/src/newt_core/NewtBC.c#L1207

I'm not sure if this a proper fix and would appreciate guidance.

pguyot commented 4 years ago

Wrote new tests to compare NEWT/0 generated bytecode with NewtonOS built-in compiler. There are differences that may account for what you observed, fixing them one by one. However, the proposed change doesn't fix it.

pguyot commented 4 years ago

The issue is here: https://github.com/gnue/NEWT0/blob/6234fed3cf9e17f87dbf2acf6fc54ea77334658e/src/newt_core/NewtBC.c#L2281

Try blocks should be passed ret to handle the pop at the appropriate place. Will submit a pull-request as soon as tests pass, including with a fix for #8.