def execute_frame(self): """Execute this frame. Main entry point to the interpreter.""" from pypy.rlib import rstack # the following 'assert' is an annotation hint: it hides from # the annotator all methods that are defined in PyFrame but # overridden in the FrameClass subclass of PyFrame. assert isinstance(self, self.space.FrameClass) executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. next_instr = self.last_instr + 1 w_exitvalue = self.dispatch(self.pycode, next_instr, executioncontext) rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) executioncontext.return_trace(self, w_exitvalue) # on exit, we try to release self.last_exception -- breaks an # obvious reference cycle, so it helps refcounting implementations self.last_exception = None finally: executioncontext.leave(self) return w_exitvalue
def execute_frame(self): """Execute this frame. Main entry point to the interpreter.""" from pypy.rlib import rstack # the following 'assert' is an annotation hint: it hides from # the annotator all methods that are defined in PyFrame but # overridden in the FrameClass subclass of PyFrame. assert isinstance(self, self.space.FrameClass) executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: if not we_are_jitted(): executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. next_instr = self.last_instr + 1 try: w_exitvalue = self.dispatch(self.pycode, next_instr, executioncontext) rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) except Exception: if not we_are_jitted(): executioncontext.return_trace(self, self.space.w_None) raise if not we_are_jitted(): executioncontext.return_trace(self, w_exitvalue) # on exit, we try to release self.last_exception -- breaks an # obvious reference cycle, so it helps refcounting implementations self.last_exception = None finally: executioncontext.leave(self) return w_exitvalue
def execute_frame(self): """Execute this frame. Main entry point to the interpreter.""" from pypy.rlib import rstack # the following 'assert' is an annotation hint: it hides from # the annotator all methods that are defined in PyFrame but # overridden in the FrameClass subclass of PyFrame. assert isinstance(self, self.space.FrameClass) executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. next_instr = self.last_instr + 1 try: w_exitvalue = self.dispatch(self.pycode, next_instr, executioncontext) rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) except Exception: executioncontext.return_trace(self, self.space.w_None) raise executioncontext.return_trace(self, w_exitvalue) # clean up the exception, might be useful for not # allocating exception objects in some cases self.last_exception = None finally: executioncontext.leave(self) return w_exitvalue
def _execute(self, incoming_frame): state = self.costate try: try: try: exc = None thunk = self.thunk self.thunk = None syncstate.switched(incoming_frame) thunk.call() resume_point("coroutine__bind", state) except Exception, e: exc = e raise finally: # warning! we must reload the 'self' from the costate, # because after a clone() the 'self' of both copies # point to the original! self = state.current self.finish(exc) except CoroutineExit: # ignore a shutdown exception pass except Exception, e: # redirect all unhandled exceptions to the parent syncstate.push_exception(e)
def handle_bytecode(self, co_code, next_instr, ec): try: next_instr = self.dispatch_bytecode(co_code, next_instr, ec) rstack.resume_point("handle_bytecode", self, co_code, ec, returns=next_instr) except OperationError, operr: next_instr = self.handle_operation_error(ec, operr)
def f(x): x = x - 1 try: r = g(x) rstack.resume_point("rp1", returns=r) except KeyError: r = 42 return r - 1
def f(coro, n, x): if n == 0: coro.switch() rstack.resume_point("f_0") return f(coro, n-1, 2*x) rstack.resume_point("f_1", coro, n, x) output.append(x)
def g(x): r = y = 0 r += f(x) try: y = f(x) rstack.resume_point("rp0", x, r, returns=y) finally: r += in_finally(x) return r + y
def switch(self): if self.frame is None: # considered a programming error. # greenlets and tasklets have different ideas about this. raise CoroutineDamage state = self.costate incoming_frame = state.update(self).switch() resume_point("coroutine_switch", state, returns=incoming_frame) syncstate.switched(incoming_frame)
def h(out): try: # g is always raising, good enough to put the resume point # before, instead of after! rstack.resume_point('h', out) g(out) except KeyError: return 0 return -1
def f(coro, n, x): if n == 0: coro.switch() rstack.resume_point("f_0") assert rstack.stack_frames_depth() == 9 return f(coro, n-1, 2*x) rstack.resume_point("f_1", coro, n, x) output.append(x)
def f(coro, n, x): if n == 0: coro.switch() rstack.resume_point("f_0") assert rstack.stack_frames_depth() == 9 return f(coro, n - 1, 2 * x) rstack.resume_point("f_1", coro, n, x) output.append(x)
def g(x): r = y = 0 r += f(x) try: y = f(x) rstack.resume_point("rp0", x, r, y, returns=y) except ZeroDivisionError: r += f(x) return r + y
def switch(self): if self.frame is None: raise RuntimeError state = self.costate incoming_frame = state.update(self).switch() rstack.resume_point("coroutine_switch", self, state, returns=incoming_frame) left = state.last left.frame = incoming_frame left.goodbye() self.hello()
def w_switch(self): space = self.space if self.frame is None: raise OperationError(space.w_ValueError, space.wrap( "cannot switch to an unbound Coroutine")) state = self.costate self.switch() rstack.resume_point("w_switch", state, space) w_ret, state.w_tempval = state.w_tempval, space.w_None return w_ret
def w_switch(self): space = self.space if self.frame is None: raise OperationError( space.w_ValueError, space.wrap("cannot switch to an unbound Coroutine")) state = self.costate self.switch() rstack.resume_point("w_switch", state, space) w_ret, state.w_tempval = state.w_tempval, space.w_None return w_ret
def CALL_METHOD(f, nargs, *ignored): # 'nargs' is the argument count excluding the implicit 'self' w_self = f.peekvalue(nargs) w_callable = f.peekvalue(nargs + 1) n = nargs + (w_self is not None) try: w_result = f.space.call_valuestack(w_callable, n, f) rstack.resume_point("CALL_METHOD", f, nargs, returns=w_result) finally: f.dropvalues(nargs + 2) f.pushvalue(w_result)
def call_function(f, oparg, w_star=None, w_starstar=None): n_arguments = oparg & 0xff n_keywords = (oparg>>8) & 0xff keywords = None if n_keywords: keywords = f.popstrdictvalues(n_keywords) arguments = f.popvalues(n_arguments) args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.popvalue() w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.pushvalue(w_result)
def call_function(f, oparg, w_star=None, w_starstar=None): n_arguments = oparg & 0xff n_keywords = (oparg >> 8) & 0xff keywords = None if n_keywords: keywords = f.popstrdictvalues(n_keywords) arguments = f.popvalues(n_arguments) args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.popvalue() w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.pushvalue(w_result)
def dispatch(self, pycode, next_instr, ec): # For the sequel, force 'next_instr' to be unsigned for performance next_instr = r_uint(next_instr) co_code = pycode.co_code try: while True: next_instr = self.handle_bytecode(co_code, next_instr, ec) rstack.resume_point("dispatch", self, co_code, ec, returns=next_instr) except ExitFrame: return self.popvalue()
def CALL_FUNCTION(f, oparg, *ignored): # XXX start of hack for performance if (oparg >> 8) & 0xff == 0: # Only positional arguments nargs = oparg & 0xff w_function = f.peekvalue(nargs) try: w_result = f.space.call_valuestack(w_function, nargs, f) rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) finally: f.dropvalues(nargs + 1) f.pushvalue(w_result) # XXX end of hack for performance else: # general case f.call_function(oparg)
def call_function(f, oparg, w_star=None, w_starstar=None): from pypy.rlib import rstack # for resume points from pypy.interpreter.function import is_builtin_code n_arguments = oparg & 0xff n_keywords = (oparg>>8) & 0xff keywords = None if n_keywords: keywords = f.popstrdictvalues(n_keywords) arguments = f.popvalues(n_arguments) args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.popvalue() if f.is_being_profiled and is_builtin_code(w_function): w_result = f.space.call_args_and_c_profile(f, w_function, args) else: w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.pushvalue(w_result)
def call_function(f, oparg, w_star=None, w_starstar=None): n_arguments = oparg & 0xff n_keywords = (oparg >> 8) & 0xff keywords = None if n_keywords: keywords = {} for i in range(n_keywords): w_value = f.valuestack.pop() w_key = f.valuestack.pop() key = f.space.str_w(w_key) keywords[key] = w_value arguments = [None] * n_arguments for i in range(n_arguments - 1, -1, -1): arguments[i] = f.valuestack.pop() args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.valuestack.pop() w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.valuestack.push(w_result)
def call_function(f, oparg, w_star=None, w_starstar=None): n_arguments = oparg & 0xff n_keywords = (oparg>>8) & 0xff keywords = None if n_keywords: keywords = {} for i in range(n_keywords): w_value = f.valuestack.pop() w_key = f.valuestack.pop() key = f.space.str_w(w_key) keywords[key] = w_value arguments = [None] * n_arguments for i in range(n_arguments - 1, -1, -1): arguments[i] = f.valuestack.pop() args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.valuestack.pop() w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.valuestack.push(w_result)
def execute_frame(self): """Execute this frame. Main entry point to the interpreter.""" executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. next_instr = self.last_instr + 1 w_exitvalue = self.dispatch(self.pycode, next_instr, executioncontext) rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) executioncontext.return_trace(self, w_exitvalue) # on exit, we try to release self.last_exception -- breaks an # obvious reference cycle, so it helps refcounting implementations self.last_exception = None finally: executioncontext.leave(self) return w_exitvalue
def f(x, y): z = g(x,y) rstack.resume_point("rp1", y, returns=z) return z+y+x
def fn(x): rstack.resume_point('hello world', x) return x
def dispatch_bytecode(self, co_code, next_instr, ec): space = self.space while True: self.last_instr = intmask(next_instr) if not we_are_jitted(): ec.bytecode_trace(self) next_instr = r_uint(self.last_instr) opcode = ord(co_code[next_instr]) next_instr += 1 if space.config.objspace.logbytecodes: space.bytecodecounts[opcode] = space.bytecodecounts.get(opcode, 0) + 1 if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr+1]) next_instr += 2 oparg = (hi << 8) | lo else: oparg = 0 hint(opcode, concrete=True) hint(oparg, concrete=True) while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr+1]) hi = ord(co_code[next_instr+2]) next_instr += 3 oparg = (oparg << 16) | (hi << 8) | lo hint(opcode, concrete=True) hint(oparg, concrete=True) if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: self.pushvalue(w_returnvalue) # XXX ping pong raise Return else: unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block if opcode == opcodedesc.YIELD_VALUE.index: #self.last_instr = intmask(next_instr - 1) XXX clean up! raise Yield if opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack block = self.unrollstack(unroller.kind) if block is None: w_result = unroller.nomoreblocks() self.pushvalue(w_result) raise Return else: next_instr = block.handle(self, unroller) return next_instr if we_are_translated(): for opdesc in unrolling_opcode_descs: # static checks to skip this whole case if necessary if not opdesc.is_enabled(space): continue if not hasattr(pyframe.PyFrame, opdesc.methodname): continue # e.g. for JUMP_FORWARD, implemented above if opcode == opdesc.index: # dispatch to the opcode method meth = getattr(self, opdesc.methodname) res = meth(oparg, next_instr) if opdesc.index == opcodedesc.CALL_FUNCTION.index: rstack.resume_point("dispatch_call", self, co_code, next_instr, ec) # !! warning, for the annotator the next line is not # comparing an int and None - you can't do that. # Instead, it's constant-folded to either True or False if res is not None: next_instr = res break else: self.MISSING_OPCODE(oparg, next_instr) else: # when we are not translated, a list lookup is much faster methodname = opcode_method_names[opcode] res = getattr(self, methodname)(oparg, next_instr) if res is not None: next_instr = res if we_are_jitted(): return next_instr
def f(x, y): x = x-1 rstack.resume_point("rp0", x, y) r = x+y rstack.stack_unwind() return r
def f(x, y): r = g(x) rstack.resume_point("rp1", y, returns=r) return r.x + y
def f(x, y): x = x - 1 rstack.resume_point("rp0", x, y) r = x + y rstack.stack_unwind() return r
def g(x): rstack.resume_point("rp0", x) return x + 1
def dispatch_bytecode(self, co_code, next_instr, ec): space = self.space while True: self.last_instr = intmask(next_instr) if not we_are_jitted(): ec.bytecode_trace(self) next_instr = r_uint(self.last_instr) opcode = ord(co_code[next_instr]) next_instr += 1 if space.config.objspace.logbytecodes: space.bytecodecounts[opcode] = space.bytecodecounts.get( opcode, 0) + 1 if opcode >= HAVE_ARGUMENT: lo = ord(co_code[next_instr]) hi = ord(co_code[next_instr + 1]) next_instr += 2 oparg = (hi << 8) | lo else: oparg = 0 hint(opcode, concrete=True) hint(oparg, concrete=True) while opcode == opcodedesc.EXTENDED_ARG.index: opcode = ord(co_code[next_instr]) if opcode < HAVE_ARGUMENT: raise BytecodeCorruption lo = ord(co_code[next_instr + 1]) hi = ord(co_code[next_instr + 2]) next_instr += 3 oparg = (oparg << 16) | (hi << 8) | lo hint(opcode, concrete=True) hint(oparg, concrete=True) if opcode == opcodedesc.RETURN_VALUE.index: w_returnvalue = self.popvalue() block = self.unrollstack(SReturnValue.kind) if block is None: self.pushvalue(w_returnvalue) # XXX ping pong raise Return else: unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) return next_instr # now inside a 'finally' block if opcode == opcodedesc.YIELD_VALUE.index: #self.last_instr = intmask(next_instr - 1) XXX clean up! raise Yield if opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() if isinstance(unroller, SuspendedUnroller): # go on unrolling the stack block = self.unrollstack(unroller.kind) if block is None: w_result = unroller.nomoreblocks() self.pushvalue(w_result) raise Return else: next_instr = block.handle(self, unroller) return next_instr if we_are_translated(): for opdesc in unrolling_opcode_descs: # static checks to skip this whole case if necessary if not opdesc.is_enabled(space): continue if not hasattr(pyframe.PyFrame, opdesc.methodname): continue # e.g. for JUMP_FORWARD, implemented above if opcode == opdesc.index: # dispatch to the opcode method meth = getattr(self, opdesc.methodname) res = meth(oparg, next_instr) if opdesc.index == opcodedesc.CALL_FUNCTION.index: rstack.resume_point("dispatch_call", self, co_code, next_instr, ec) # !! warning, for the annotator the next line is not # comparing an int and None - you can't do that. # Instead, it's constant-folded to either True or False if res is not None: next_instr = res break else: self.MISSING_OPCODE(oparg, next_instr) else: # when we are not translated, a list lookup is much faster methodname = opcode_method_names[opcode] res = getattr(self, methodname)(oparg, next_instr) if res is not None: next_instr = res if we_are_jitted(): return next_instr
def f(x, y): x = x-1 rstack.resume_point("rp0", x, y) return x+y
def f(x, y): z = g(x, y) rstack.resume_point("rp1", y, returns=z) return z + y
def call(self): costate = self.costate w_result = self.space.call_args(self.w_func, self.args) rstack.resume_point("appthunk", costate, returns=w_result) costate.w_tempval = w_result
def in_finally(x): rstack.resume_point("rp1.5", x) return 2/x
def in_finally(x): rstack.resume_point("rp1.5", x) return 2 / x
def g(out): out.append(3) rstack.resume_point('g') raise KeyError
def f(x): rstack.resume_point("rp1", x) return 1 / x
def f(x, y): x = x - 1 rstack.resume_point("rp0", x, y) return x + y
def g(x): rstack.resume_point("rp0", x) if x == 0: raise KeyError return x + 1
def f(x): rstack.resume_point("rp1", x) return 1/x