mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	Track the block stack more reasonably in order to handle continue in
try/except or try/finally. Previous versions had only track SETUP_LOOP blocks and ignored the exception part. This meant that it allowed continue inside a try/except but generated buggy code. Now it does the right thing.
This commit is contained in:
		
							parent
							
								
									9263848fa1
								
							
						
					
					
						commit
						e4685ec57e
					
				
					 2 changed files with 90 additions and 26 deletions
				
			
		| 
						 | 
					@ -28,6 +28,11 @@
 | 
				
			||||||
    (1,1) : "CALL_FUNCTION_VAR_KW",
 | 
					    (1,1) : "CALL_FUNCTION_VAR_KW",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOOP = 1
 | 
				
			||||||
 | 
					EXCEPT = 2
 | 
				
			||||||
 | 
					TRY_FINALLY = 3
 | 
				
			||||||
 | 
					END_FINALLY = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def compile(filename, display=0):
 | 
					def compile(filename, display=0):
 | 
				
			||||||
    f = open(filename)
 | 
					    f = open(filename)
 | 
				
			||||||
    buf = f.read()
 | 
					    buf = f.read()
 | 
				
			||||||
| 
						 | 
					@ -142,7 +147,7 @@ def __init__(self, filename):
 | 
				
			||||||
        self.checkClass()
 | 
					        self.checkClass()
 | 
				
			||||||
        self.filename = filename
 | 
					        self.filename = filename
 | 
				
			||||||
        self.locals = misc.Stack()
 | 
					        self.locals = misc.Stack()
 | 
				
			||||||
        self.loops = misc.Stack()
 | 
					        self.setups = misc.Stack()
 | 
				
			||||||
        self.curStack = 0
 | 
					        self.curStack = 0
 | 
				
			||||||
        self.maxStack = 0
 | 
					        self.maxStack = 0
 | 
				
			||||||
        self.last_lineno = None
 | 
					        self.last_lineno = None
 | 
				
			||||||
| 
						 | 
					@ -327,7 +332,7 @@ def visitWhile(self, node):
 | 
				
			||||||
        self.emit('SETUP_LOOP', after)
 | 
					        self.emit('SETUP_LOOP', after)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.nextBlock(loop)
 | 
					        self.nextBlock(loop)
 | 
				
			||||||
        self.loops.push(loop)
 | 
					        self.setups.push((LOOP, loop))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.set_lineno(node, force=1)
 | 
					        self.set_lineno(node, force=1)
 | 
				
			||||||
        self.visit(node.test)
 | 
					        self.visit(node.test)
 | 
				
			||||||
| 
						 | 
					@ -341,7 +346,7 @@ def visitWhile(self, node):
 | 
				
			||||||
        self.startBlock(else_) # or just the POPs if not else clause
 | 
					        self.startBlock(else_) # or just the POPs if not else clause
 | 
				
			||||||
        self.emit('POP_TOP')
 | 
					        self.emit('POP_TOP')
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
        self.loops.pop()
 | 
					        self.setups.pop()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
            self.visit(node.else_)
 | 
					            self.visit(node.else_)
 | 
				
			||||||
        self.nextBlock(after)
 | 
					        self.nextBlock(after)
 | 
				
			||||||
| 
						 | 
					@ -350,7 +355,7 @@ def visitFor(self, node):
 | 
				
			||||||
        start = self.newBlock()
 | 
					        start = self.newBlock()
 | 
				
			||||||
        anchor = self.newBlock()
 | 
					        anchor = self.newBlock()
 | 
				
			||||||
        after = self.newBlock()
 | 
					        after = self.newBlock()
 | 
				
			||||||
        self.loops.push(start)
 | 
					        self.setups.push((LOOP, start))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('SETUP_LOOP', after)
 | 
					        self.emit('SETUP_LOOP', after)
 | 
				
			||||||
| 
						 | 
					@ -365,26 +370,44 @@ def visitFor(self, node):
 | 
				
			||||||
        self.emit('JUMP_ABSOLUTE', start)
 | 
					        self.emit('JUMP_ABSOLUTE', start)
 | 
				
			||||||
        self.nextBlock(anchor)
 | 
					        self.nextBlock(anchor)
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
        self.loops.pop()
 | 
					        self.setups.pop()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
            self.visit(node.else_)
 | 
					            self.visit(node.else_)
 | 
				
			||||||
        self.nextBlock(after)
 | 
					        self.nextBlock(after)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitBreak(self, node):
 | 
					    def visitBreak(self, node):
 | 
				
			||||||
        if not self.loops:
 | 
					        if not self.setups:
 | 
				
			||||||
            raise SyntaxError, "'break' outside loop (%s, %d)" % \
 | 
					            raise SyntaxError, "'break' outside loop (%s, %d)" % \
 | 
				
			||||||
                  (self.filename, node.lineno)
 | 
					                  (self.filename, node.lineno)
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('BREAK_LOOP')
 | 
					        self.emit('BREAK_LOOP')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitContinue(self, node):
 | 
					    def visitContinue(self, node):
 | 
				
			||||||
        if not self.loops:
 | 
					        if not self.setups:
 | 
				
			||||||
            raise SyntaxError, "'continue' outside loop (%s, %d)" % \
 | 
					            raise SyntaxError, "'continue' outside loop (%s, %d)" % \
 | 
				
			||||||
                  (self.filename, node.lineno)
 | 
					                  (self.filename, node.lineno)
 | 
				
			||||||
        l = self.loops.top()
 | 
					        kind, block = self.setups.top()
 | 
				
			||||||
 | 
					        if kind == LOOP:
 | 
				
			||||||
            self.set_lineno(node)
 | 
					            self.set_lineno(node)
 | 
				
			||||||
        self.emit('JUMP_ABSOLUTE', l)
 | 
					            self.emit('JUMP_ABSOLUTE', block)
 | 
				
			||||||
            self.nextBlock()
 | 
					            self.nextBlock()
 | 
				
			||||||
 | 
					        elif kind == EXCEPT or kind == TRY_FINALLY:
 | 
				
			||||||
 | 
					            self.set_lineno(node)
 | 
				
			||||||
 | 
					            # find the block that starts the loop
 | 
				
			||||||
 | 
					            top = len(self.setups)
 | 
				
			||||||
 | 
					            while top > 0:
 | 
				
			||||||
 | 
					                top = top - 1
 | 
				
			||||||
 | 
					                kind, loop_block = self.setups[top]
 | 
				
			||||||
 | 
					                if kind == LOOP:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					            if kind != LOOP:
 | 
				
			||||||
 | 
					                raise SyntaxError, "'continue' outside loop (%s, %d)" % \
 | 
				
			||||||
 | 
					                      (self.filename, node.lineno)
 | 
				
			||||||
 | 
					            self.emit('CONTINUE_LOOP', loop_block)
 | 
				
			||||||
 | 
					            self.nextBlock()
 | 
				
			||||||
 | 
					        elif kind == END_FINALLY:
 | 
				
			||||||
 | 
					            msg = "'continue' not allowed inside 'finally' clause (%s, %d)"  
 | 
				
			||||||
 | 
					            raise SyntaxError, msg % (self.filename, node.lineno)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitTest(self, node, jump):
 | 
					    def visitTest(self, node, jump):
 | 
				
			||||||
        end = self.newBlock()
 | 
					        end = self.newBlock()
 | 
				
			||||||
| 
						 | 
					@ -529,6 +552,7 @@ def visitRaise(self, node):
 | 
				
			||||||
        self.emit('RAISE_VARARGS', n)
 | 
					        self.emit('RAISE_VARARGS', n)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitTryExcept(self, node):
 | 
					    def visitTryExcept(self, node):
 | 
				
			||||||
 | 
					        body = self.newBlock()
 | 
				
			||||||
        handlers = self.newBlock()
 | 
					        handlers = self.newBlock()
 | 
				
			||||||
        end = self.newBlock()
 | 
					        end = self.newBlock()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
| 
						 | 
					@ -537,9 +561,11 @@ def visitTryExcept(self, node):
 | 
				
			||||||
            lElse = end
 | 
					            lElse = end
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('SETUP_EXCEPT', handlers)
 | 
					        self.emit('SETUP_EXCEPT', handlers)
 | 
				
			||||||
        self.nextBlock()
 | 
					        self.nextBlock(body)
 | 
				
			||||||
 | 
					        self.setups.push((EXCEPT, body))
 | 
				
			||||||
        self.visit(node.body)
 | 
					        self.visit(node.body)
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
        self.emit('JUMP_FORWARD', lElse)
 | 
					        self.emit('JUMP_FORWARD', lElse)
 | 
				
			||||||
        self.startBlock(handlers)
 | 
					        self.startBlock(handlers)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -570,22 +596,28 @@ def visitTryExcept(self, node):
 | 
				
			||||||
            if expr: # XXX
 | 
					            if expr: # XXX
 | 
				
			||||||
                self.emit('POP_TOP')
 | 
					                self.emit('POP_TOP')
 | 
				
			||||||
        self.emit('END_FINALLY')
 | 
					        self.emit('END_FINALLY')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
            self.nextBlock(lElse)
 | 
					            self.nextBlock(lElse)
 | 
				
			||||||
            self.visit(node.else_)
 | 
					            self.visit(node.else_)
 | 
				
			||||||
        self.nextBlock(end)
 | 
					        self.nextBlock(end)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def visitTryFinally(self, node):
 | 
					    def visitTryFinally(self, node):
 | 
				
			||||||
 | 
					        body = self.newBlock()
 | 
				
			||||||
        final = self.newBlock()
 | 
					        final = self.newBlock()
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('SETUP_FINALLY', final)
 | 
					        self.emit('SETUP_FINALLY', final)
 | 
				
			||||||
        self.nextBlock()
 | 
					        self.nextBlock(body)
 | 
				
			||||||
 | 
					        self.setups.push((TRY_FINALLY, body))
 | 
				
			||||||
        self.visit(node.body)
 | 
					        self.visit(node.body)
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
        self.emit('LOAD_CONST', None)
 | 
					        self.emit('LOAD_CONST', None)
 | 
				
			||||||
        self.nextBlock(final)
 | 
					        self.nextBlock(final)
 | 
				
			||||||
 | 
					        self.setups.push((END_FINALLY, final))
 | 
				
			||||||
        self.visit(node.final)
 | 
					        self.visit(node.final)
 | 
				
			||||||
        self.emit('END_FINALLY')
 | 
					        self.emit('END_FINALLY')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # misc
 | 
					    # misc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,11 @@
 | 
				
			||||||
    (1,1) : "CALL_FUNCTION_VAR_KW",
 | 
					    (1,1) : "CALL_FUNCTION_VAR_KW",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOOP = 1
 | 
				
			||||||
 | 
					EXCEPT = 2
 | 
				
			||||||
 | 
					TRY_FINALLY = 3
 | 
				
			||||||
 | 
					END_FINALLY = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def compile(filename, display=0):
 | 
					def compile(filename, display=0):
 | 
				
			||||||
    f = open(filename)
 | 
					    f = open(filename)
 | 
				
			||||||
    buf = f.read()
 | 
					    buf = f.read()
 | 
				
			||||||
| 
						 | 
					@ -142,7 +147,7 @@ def __init__(self, filename):
 | 
				
			||||||
        self.checkClass()
 | 
					        self.checkClass()
 | 
				
			||||||
        self.filename = filename
 | 
					        self.filename = filename
 | 
				
			||||||
        self.locals = misc.Stack()
 | 
					        self.locals = misc.Stack()
 | 
				
			||||||
        self.loops = misc.Stack()
 | 
					        self.setups = misc.Stack()
 | 
				
			||||||
        self.curStack = 0
 | 
					        self.curStack = 0
 | 
				
			||||||
        self.maxStack = 0
 | 
					        self.maxStack = 0
 | 
				
			||||||
        self.last_lineno = None
 | 
					        self.last_lineno = None
 | 
				
			||||||
| 
						 | 
					@ -327,7 +332,7 @@ def visitWhile(self, node):
 | 
				
			||||||
        self.emit('SETUP_LOOP', after)
 | 
					        self.emit('SETUP_LOOP', after)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.nextBlock(loop)
 | 
					        self.nextBlock(loop)
 | 
				
			||||||
        self.loops.push(loop)
 | 
					        self.setups.push((LOOP, loop))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.set_lineno(node, force=1)
 | 
					        self.set_lineno(node, force=1)
 | 
				
			||||||
        self.visit(node.test)
 | 
					        self.visit(node.test)
 | 
				
			||||||
| 
						 | 
					@ -341,7 +346,7 @@ def visitWhile(self, node):
 | 
				
			||||||
        self.startBlock(else_) # or just the POPs if not else clause
 | 
					        self.startBlock(else_) # or just the POPs if not else clause
 | 
				
			||||||
        self.emit('POP_TOP')
 | 
					        self.emit('POP_TOP')
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
        self.loops.pop()
 | 
					        self.setups.pop()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
            self.visit(node.else_)
 | 
					            self.visit(node.else_)
 | 
				
			||||||
        self.nextBlock(after)
 | 
					        self.nextBlock(after)
 | 
				
			||||||
| 
						 | 
					@ -350,7 +355,7 @@ def visitFor(self, node):
 | 
				
			||||||
        start = self.newBlock()
 | 
					        start = self.newBlock()
 | 
				
			||||||
        anchor = self.newBlock()
 | 
					        anchor = self.newBlock()
 | 
				
			||||||
        after = self.newBlock()
 | 
					        after = self.newBlock()
 | 
				
			||||||
        self.loops.push(start)
 | 
					        self.setups.push((LOOP, start))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('SETUP_LOOP', after)
 | 
					        self.emit('SETUP_LOOP', after)
 | 
				
			||||||
| 
						 | 
					@ -365,26 +370,44 @@ def visitFor(self, node):
 | 
				
			||||||
        self.emit('JUMP_ABSOLUTE', start)
 | 
					        self.emit('JUMP_ABSOLUTE', start)
 | 
				
			||||||
        self.nextBlock(anchor)
 | 
					        self.nextBlock(anchor)
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
        self.loops.pop()
 | 
					        self.setups.pop()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
            self.visit(node.else_)
 | 
					            self.visit(node.else_)
 | 
				
			||||||
        self.nextBlock(after)
 | 
					        self.nextBlock(after)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitBreak(self, node):
 | 
					    def visitBreak(self, node):
 | 
				
			||||||
        if not self.loops:
 | 
					        if not self.setups:
 | 
				
			||||||
            raise SyntaxError, "'break' outside loop (%s, %d)" % \
 | 
					            raise SyntaxError, "'break' outside loop (%s, %d)" % \
 | 
				
			||||||
                  (self.filename, node.lineno)
 | 
					                  (self.filename, node.lineno)
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('BREAK_LOOP')
 | 
					        self.emit('BREAK_LOOP')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitContinue(self, node):
 | 
					    def visitContinue(self, node):
 | 
				
			||||||
        if not self.loops:
 | 
					        if not self.setups:
 | 
				
			||||||
            raise SyntaxError, "'continue' outside loop (%s, %d)" % \
 | 
					            raise SyntaxError, "'continue' outside loop (%s, %d)" % \
 | 
				
			||||||
                  (self.filename, node.lineno)
 | 
					                  (self.filename, node.lineno)
 | 
				
			||||||
        l = self.loops.top()
 | 
					        kind, block = self.setups.top()
 | 
				
			||||||
 | 
					        if kind == LOOP:
 | 
				
			||||||
            self.set_lineno(node)
 | 
					            self.set_lineno(node)
 | 
				
			||||||
        self.emit('JUMP_ABSOLUTE', l)
 | 
					            self.emit('JUMP_ABSOLUTE', block)
 | 
				
			||||||
            self.nextBlock()
 | 
					            self.nextBlock()
 | 
				
			||||||
 | 
					        elif kind == EXCEPT or kind == TRY_FINALLY:
 | 
				
			||||||
 | 
					            self.set_lineno(node)
 | 
				
			||||||
 | 
					            # find the block that starts the loop
 | 
				
			||||||
 | 
					            top = len(self.setups)
 | 
				
			||||||
 | 
					            while top > 0:
 | 
				
			||||||
 | 
					                top = top - 1
 | 
				
			||||||
 | 
					                kind, loop_block = self.setups[top]
 | 
				
			||||||
 | 
					                if kind == LOOP:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					            if kind != LOOP:
 | 
				
			||||||
 | 
					                raise SyntaxError, "'continue' outside loop (%s, %d)" % \
 | 
				
			||||||
 | 
					                      (self.filename, node.lineno)
 | 
				
			||||||
 | 
					            self.emit('CONTINUE_LOOP', loop_block)
 | 
				
			||||||
 | 
					            self.nextBlock()
 | 
				
			||||||
 | 
					        elif kind == END_FINALLY:
 | 
				
			||||||
 | 
					            msg = "'continue' not allowed inside 'finally' clause (%s, %d)"  
 | 
				
			||||||
 | 
					            raise SyntaxError, msg % (self.filename, node.lineno)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitTest(self, node, jump):
 | 
					    def visitTest(self, node, jump):
 | 
				
			||||||
        end = self.newBlock()
 | 
					        end = self.newBlock()
 | 
				
			||||||
| 
						 | 
					@ -529,6 +552,7 @@ def visitRaise(self, node):
 | 
				
			||||||
        self.emit('RAISE_VARARGS', n)
 | 
					        self.emit('RAISE_VARARGS', n)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitTryExcept(self, node):
 | 
					    def visitTryExcept(self, node):
 | 
				
			||||||
 | 
					        body = self.newBlock()
 | 
				
			||||||
        handlers = self.newBlock()
 | 
					        handlers = self.newBlock()
 | 
				
			||||||
        end = self.newBlock()
 | 
					        end = self.newBlock()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
| 
						 | 
					@ -537,9 +561,11 @@ def visitTryExcept(self, node):
 | 
				
			||||||
            lElse = end
 | 
					            lElse = end
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('SETUP_EXCEPT', handlers)
 | 
					        self.emit('SETUP_EXCEPT', handlers)
 | 
				
			||||||
        self.nextBlock()
 | 
					        self.nextBlock(body)
 | 
				
			||||||
 | 
					        self.setups.push((EXCEPT, body))
 | 
				
			||||||
        self.visit(node.body)
 | 
					        self.visit(node.body)
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
        self.emit('JUMP_FORWARD', lElse)
 | 
					        self.emit('JUMP_FORWARD', lElse)
 | 
				
			||||||
        self.startBlock(handlers)
 | 
					        self.startBlock(handlers)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -570,22 +596,28 @@ def visitTryExcept(self, node):
 | 
				
			||||||
            if expr: # XXX
 | 
					            if expr: # XXX
 | 
				
			||||||
                self.emit('POP_TOP')
 | 
					                self.emit('POP_TOP')
 | 
				
			||||||
        self.emit('END_FINALLY')
 | 
					        self.emit('END_FINALLY')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
        if node.else_:
 | 
					        if node.else_:
 | 
				
			||||||
            self.nextBlock(lElse)
 | 
					            self.nextBlock(lElse)
 | 
				
			||||||
            self.visit(node.else_)
 | 
					            self.visit(node.else_)
 | 
				
			||||||
        self.nextBlock(end)
 | 
					        self.nextBlock(end)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def visitTryFinally(self, node):
 | 
					    def visitTryFinally(self, node):
 | 
				
			||||||
 | 
					        body = self.newBlock()
 | 
				
			||||||
        final = self.newBlock()
 | 
					        final = self.newBlock()
 | 
				
			||||||
        self.set_lineno(node)
 | 
					        self.set_lineno(node)
 | 
				
			||||||
        self.emit('SETUP_FINALLY', final)
 | 
					        self.emit('SETUP_FINALLY', final)
 | 
				
			||||||
        self.nextBlock()
 | 
					        self.nextBlock(body)
 | 
				
			||||||
 | 
					        self.setups.push((TRY_FINALLY, body))
 | 
				
			||||||
        self.visit(node.body)
 | 
					        self.visit(node.body)
 | 
				
			||||||
        self.emit('POP_BLOCK')
 | 
					        self.emit('POP_BLOCK')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
        self.emit('LOAD_CONST', None)
 | 
					        self.emit('LOAD_CONST', None)
 | 
				
			||||||
        self.nextBlock(final)
 | 
					        self.nextBlock(final)
 | 
				
			||||||
 | 
					        self.setups.push((END_FINALLY, final))
 | 
				
			||||||
        self.visit(node.final)
 | 
					        self.visit(node.final)
 | 
				
			||||||
        self.emit('END_FINALLY')
 | 
					        self.emit('END_FINALLY')
 | 
				
			||||||
 | 
					        self.setups.pop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # misc
 | 
					    # misc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue