def __init__(self, space, code, globals, constargs={}, closure=None, name=None): ExecutionContext.__init__(self, space) self.code = code self.w_globals = w_globals = space.wrap(globals) self.crnt_offset = -1 self.crnt_frame = None if closure is None: self.closure = None else: from pypy.interpreter.nestedscope import Cell self.closure = [Cell(Constant(value)) for value in closure] frame = self.create_frame() formalargcount = code.getformalargcount() arg_list = [Variable() for i in range(formalargcount)] for position, value in constargs.items(): arg_list[position] = Constant(value) frame.setfastscope(arg_list) self.joinpoints = {} #for joinpoint in code.getjoinpoints(): # self.joinpoints[joinpoint] = [] # list of blocks initialblock = SpamBlock(FrameState(frame).copy()) self.pendingblocks = collections.deque([initialblock]) self.graph = FunctionGraph(name or code.co_name, initialblock)
def descr_clear(self, space): """F.clear(): clear most references held by the frame""" # Clears a random subset of the attributes: the local variables # and the w_locals. Note that CPython doesn't clear f_locals # (which can create leaks) but it's hard to notice because # the next Python-level read of 'frame.f_locals' will clear it. if not self.frame_finished_execution: if not self._is_generator_or_coroutine(): raise oefmt(space.w_RuntimeError, "cannot clear an executing frame") gen = self.get_generator() if gen is not None: if gen.running: raise oefmt(space.w_RuntimeError, "cannot clear an executing frame") # xxx CPython raises the RuntimeWarning "coroutine was never # awaited" in this case too. Does it make any sense? gen.descr_close() debug = self.getdebug() if debug is not None: debug.w_f_trace = None if debug.w_locals is not None: debug.w_locals = space.newdict() # clear the locals, including the cell/free vars, and the stack for i in range(len(self.locals_cells_stack_w)): w_oldvalue = self.locals_cells_stack_w[i] if isinstance(w_oldvalue, Cell): w_newvalue = Cell(None, w_oldvalue.family) else: w_newvalue = None self.locals_cells_stack_w[i] = w_newvalue self.valuestackdepth = 0 self.lastblock = None # the FrameBlock chained list
def initialize_frame_scopes(self, outer_func, code): # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS. # class bodies only have CO_NEWLOCALS. # CO_NEWLOCALS: make a locals dict unless optimized is also set # CO_OPTIMIZED: no locals dict needed at all flags = code.co_flags if not (flags & pycode.CO_OPTIMIZED): if flags & pycode.CO_NEWLOCALS: self.getorcreatedebug().w_locals = self.space.newdict( module=True) else: w_globals = self.get_w_globals() assert w_globals is not None self.getorcreatedebug().w_locals = w_globals ncellvars = len(code.co_cellvars) nfreevars = len(code.co_freevars) if not nfreevars: if not ncellvars: return # no cells needed - fast path elif outer_func is None: space = self.space raise oefmt( space.w_TypeError, "directly executed code object may not contain free " "variables") if outer_func and outer_func.closure: closure_size = len(outer_func.closure) else: closure_size = 0 if closure_size != nfreevars: raise ValueError("code object received a closure with " "an unexpected number of free variables") index = code.co_nlocals for i in range(ncellvars): self.locals_cells_stack_w[index] = Cell( None, self.pycode.cell_families[i]) index += 1 for i in range(nfreevars): self.locals_cells_stack_w[index] = outer_func.closure[i] index += 1
def initialize_frame_scopes(self, outer_func, code): # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS. # class bodies only have CO_NEWLOCALS. # CO_NEWLOCALS: make a locals dict unless optimized is also set # CO_OPTIMIZED: no locals dict needed at all flags = code.co_flags if not (flags & pycode.CO_OPTIMIZED): if flags & pycode.CO_NEWLOCALS: self.getorcreatedebug().w_locals = self.space.newdict( module=True) else: assert self.w_globals is not None self.getorcreatedebug().w_locals = self.w_globals ncellvars = len(code.co_cellvars) nfreevars = len(code.co_freevars) if not nfreevars: if not ncellvars: self.cells = self._NO_CELLS return # no self.cells needed - fast path elif outer_func is None: space = self.space raise OperationError( space.w_TypeError, space.wrap("directly executed code object " "may not contain free variables")) if outer_func and outer_func.closure: closure_size = len(outer_func.closure) else: closure_size = 0 if closure_size != nfreevars: raise ValueError("code object received a closure with " "an unexpected number of free variables") self.cells = [None] * (ncellvars + nfreevars) for i in range(ncellvars): self.cells[i] = Cell() for i in range(nfreevars): self.cells[i + ncellvars] = outer_func.closure[i]