skulpt / skulpt

Skulpt is a Javascript implementation of the Python programming language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

try finally with a return and an exception

s-cork opened this issue · comments

commented
def foo():
  try:
    return
  finally:
    print("finally")
    1/0

foo()

In the above example I'd expect finally to get printed only once.
But in skulpt finally is printed twice.

A similar thing happens in a context manager's __exit__ method.
(if there is a return in the with statement and the __exit__ block raises, it will get called again).

The bug is caused in compile code in the Return case.
We jump to the finally block before we've cleaned up the exception blocks.
Which means we don't pop the $exc object correctly.
So when the finally block raises, we still have an exception block in the $exc array.
And the final handler says oh wait, we still have an exception block to visit, let's go visit it.

It's worse if we have Exception handlers

def foo():
  try:
    return
  except:
    print("except")
    return
  finally:
    print("finally")
    1/0

foo()
# finally, except, finally, finally