Commit c1486ff9 authored by Guido van Rossum's avatar Guido van Rossum

Properly pop the engine's scope stack when an error is handled.

Properly pop the interpreter level even when an exception happens.

Add a few asserts to ensure that the scope level and the interpreter
level are correctly maintained.
parent d26a3d9f
...@@ -165,22 +165,33 @@ class TALInterpreter: ...@@ -165,22 +165,33 @@ class TALInterpreter:
self.position = None, None # (lineno, offset) self.position = None, None # (lineno, offset)
self.col = 0 self.col = 0
self.level = 0 self.level = 0
self.scopeLevel = 0
def saveState(self): def saveState(self):
return (self.position, self.col, self.stream) return (self.position, self.col, self.stream,
self.scopeLevel, self.level)
def restoreState(self, state): def restoreState(self, state):
(self.position, self.col, self.stream) = state (self.position, self.col, self.stream, scopeLevel, level) = state
assert self.level == level
while self.scopeLevel > scopeLevel:
self.do_endScope()
def restoreOutputState(self, state): def restoreOutputState(self, state):
(dummy, self.col, self.stream) = state (dummy, self.col, self.stream, scopeLevel, level) = state
assert self.level == level
assert self.scopeLevel == scopeLevel
def __call__(self): def __call__(self):
assert self.level == 0
assert self.scopeLevel == 0
if self.html: if self.html:
self.endsep = " />" self.endsep = " />"
else: else:
self.endsep = "/>" self.endsep = "/>"
self.interpret(self.program) self.interpret(self.program)
assert self.level == 0
assert self.scopeLevel == 0
if self.col > 0: if self.col > 0:
self.stream_write("\n") self.stream_write("\n")
...@@ -194,16 +205,19 @@ class TALInterpreter: ...@@ -194,16 +205,19 @@ class TALInterpreter:
def interpret(self, program): def interpret(self, program):
self.level = self.level + 1 self.level = self.level + 1
try:
for item in program: for item in program:
methodName = "do_" + item[0] methodName = "do_" + item[0]
args = item[1:] args = item[1:]
if self.debug: if self.debug:
s = "%s%s%s\n" % (" "*self.level, methodName, repr(args)) s = "%s%s%s\n" % (" "*self.level, methodName,
repr(args))
if len(s) > 80: if len(s) > 80:
s = s[:76] + "...\n" s = s[:76] + "...\n"
sys.stderr.write(s) sys.stderr.write(s)
method = getattr(self, methodName) method = getattr(self, methodName)
apply(method, args) apply(method, args)
finally:
self.level = self.level - 1 self.level = self.level - 1
def do_version(self, version): def do_version(self, version):
...@@ -262,9 +276,11 @@ class TALInterpreter: ...@@ -262,9 +276,11 @@ class TALInterpreter:
def do_beginScope(self): def do_beginScope(self):
self.engine.beginScope() self.engine.beginScope()
self.scopeLevel = self.scopeLevel + 1
def do_endScope(self): def do_endScope(self):
self.engine.endScope() self.engine.endScope()
self.scopeLevel = self.scopeLevel - 1
def do_setLocal(self, name, expr): def do_setLocal(self, name, expr):
if not self.tal: if not self.tal:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment