def build(cache, gateway): "NOT_RPYTHON" space = cache.space defs = gateway._getdefaults(space) # needs to be implemented by subclass code = gateway._code fn = Function(space, code, None, defs, forcename = gateway.name) if not space.config.translating: # for tests and py.py fn._freeze_() if gateway.as_classmethod: fn = ClassMethod(space.wrap(fn)) return fn
def build(cache, gateway): "NOT_RPYTHON" space = cache.space defs = gateway._getdefaults( space) # needs to be implemented by subclass code = gateway._code fn = Function(space, code, None, defs, forcename=gateway.name) if not space.config.translating: # for tests and py.py fn._freeze_() if gateway.as_classmethod: fn = ClassMethod(space.wrap(fn)) return fn
def test_fastcall_method(self): space = self.space def f(self, a): return a code = PyCode._from_code(self.space, f.func_code) fn = Function(self.space, code, self.space.newdict()) assert fn.code.fast_natural_arity == 2 called = [] fastcall_2 = fn.code.fastcall_2 def witness_fastcall_2(space, w_func, w_arg1, w_arg2): called.append(w_func) return fastcall_2(space, w_func, w_arg1, w_arg2) fn.code.fastcall_2 = witness_fastcall_2 w_3 = space.newint(3) w_res = space.appexec([fn, w_3], """(f, x): class A(object): m = f y = A().m(x) b = A().m z = b(x) return y is x and z is x """) assert space.is_true(w_res) assert called == [fn, fn]
def test_flatcall(self): space = self.space def f(a): return a code = PyCode._from_code(self.space, f.func_code) fn = Function(self.space, code, self.space.newdict()) assert fn.code.fast_natural_arity == 1 | PyCode.FLATPYCALL def bomb(*args): assert False, "shortcutting should have avoided this" code.funcrun = bomb code.funcrun_obj = bomb w_3 = space.newint(3) w_res = space.call_function(fn, w_3) assert w_res is w_3 w_res = space.appexec([fn, w_3], """(f, x): return f(x) """) assert w_res is w_3
def test_flatcall_method(self): space = self.space def f(self, a): return a code = PyCode._from_code(self.space, f.func_code) fn = Function(self.space, code, self.space.newdict()) assert fn.code.fast_natural_arity == 2 | PyCode.FLATPYCALL def bomb(*args): assert False, "shortcutting should have avoided this" code.funcrun = bomb code.funcrun_obj = bomb w_3 = space.newint(3) w_res = space.appexec([fn, w_3], """(f, x): class A(object): m = f y = A().m(x) b = A().m z = b(x) return y is x and z is x """) assert space.is_true(w_res)
def test_flatcall_default_arg(self): space = self.space def f(a, b): return a + b code = PyCode._from_code(self.space, f.func_code) fn = Function(self.space, code, self.space.newdict(), defs_w=[space.newint(1)]) assert fn.code.fast_natural_arity == 2 | eval.Code.FLATPYCALL def bomb(*args): assert False, "shortcutting should have avoided this" code.funcrun = bomb code.funcrun_obj = bomb w_3 = space.newint(3) w_4 = space.newint(4) # ignore this for now #w_res = space.call_function(fn, w_3) # assert space.eq_w(w_res, w_4) w_res = space.appexec([fn, w_3], """(f, x): return f(x) """) assert space.eq_w(w_res, w_4)
def test_method_get(self): space = self.space # Create some function for this test only def m(self): return self func = Function(space, PyCode._from_code(self.space, m.func_code), space.newdict()) # Some shorthands obj1 = space.wrap(23) obj2 = space.wrap(42) args = Arguments(space, []) # Check method returned from func.__get__() w_meth1 = descr_function_get(space, func, obj1, space.type(obj1)) meth1 = space.unwrap(w_meth1) assert isinstance(meth1, Method) assert meth1.call_args(args) == obj1 # Check method returned from method.__get__() # --- meth1 is already bound so meth1.__get__(*) is meth1. w_meth2 = meth1.descr_method_get(obj2, space.type(obj2)) meth2 = space.unwrap(w_meth2) assert isinstance(meth2, Method) assert meth2.call_args(args) == obj1 # Check method returned from unbound_method.__get__() w_meth3 = descr_function_get(space, func, None, space.type(obj2)) meth3 = space.unwrap(w_meth3) w_meth4 = meth3.descr_method_get(obj2, space.w_None) meth4 = space.unwrap(w_meth4) assert isinstance(meth4, Method) assert meth4.call_args(args) == obj2 # Check method returned from unbound_method.__get__() # --- with an incompatible class w_meth5 = meth3.descr_method_get(space.wrap('hello'), space.w_str) assert space.is_w(w_meth5, w_meth3)
def test_flatcall_default_arg_method(self): space = self.space def f(self, a, b): return a + b code = PyCode._from_code(self.space, f.func_code) fn = Function(self.space, code, self.space.newdict(), defs_w=[space.newint(1)]) assert fn.code.fast_natural_arity == 3 | eval.Code.FLATPYCALL def bomb(*args): assert False, "shortcutting should have avoided this" code.funcrun = bomb code.funcrun_obj = bomb w_3 = space.newint(3) w_res = space.appexec([fn, w_3], """(f, x): class A(object): m = f y = A().m(x) b = A().m z = b(x) return y+10*z """) assert space.eq_w(w_res, space.wrap(44))
def test_call_function(self): space = self.space d = {} for i in range(10): args = "(" + ''.join(["a%d," % a for a in range(i)]) + ")" exec """ def f%s: return %s """ % (args, args) in d f = d['f'] res = f(*range(i)) code = PyCode._from_code(self.space, f.func_code) fn = Function(self.space, code, self.space.newdict()) assert fn.code.fast_natural_arity == i | PyCode.FLATPYCALL if i < 5: def bomb(*args): assert False, "shortcutting should have avoided this" code.funcrun = bomb code.funcrun_obj = bomb args_w = map(space.wrap, range(i)) w_res = space.call_function(fn, *args_w) check = space.is_true(space.eq(w_res, space.wrap(res))) assert check
def test_fastcall(self): space = self.space def f(a): return a code = PyCode._from_code(self.space, f.func_code) fn = Function(self.space, code, self.space.newdict()) assert fn.code.fast_natural_arity == 1 called = [] fastcall_1 = fn.code.fastcall_1 def witness_fastcall_1(space, w_func, w_arg): called.append(w_func) return fastcall_1(space, w_func, w_arg) fn.code.fastcall_1 = witness_fastcall_1 w_3 = space.newint(3) w_res = space.call_function(fn, w_3) assert w_res is w_3 assert called == [fn] called = [] w_res = space.appexec([fn, w_3], """(f, x): return f(x) """) assert w_res is w_3 assert called == [fn]
def build(cache, gateway): "NOT_RPYTHON" space = cache.space defs = gateway._getdefaults(space) # needs to be implemented by subclass code = gateway._code fn = Function(space, code, None, defs, forcename = gateway.name) if gateway.as_classmethod: fn = ClassMethod(space.wrap(fn)) return fn
def test_method_get(self): space = self.space # Create some function for this test only def m(self): return self func = Function(space, PyCode._from_code(self.space, m.func_code), space.newdict()) # Some shorthands obj1 = space.wrap(23) obj2 = space.wrap(42) args = Arguments(space, []) # Check method returned from func.__get__() w_meth1 = descr_function_get(space, func, obj1, space.type(obj1)) meth1 = space.unwrap(w_meth1) assert isinstance(meth1, Method) assert meth1.call_args(args) == obj1 # Check method returned from method.__get__() # --- meth1 is already bound so meth1.__get__(*) is meth1. w_meth2 = meth1.descr_method_get(obj2, space.type(obj2)) meth2 = space.unwrap(w_meth2) assert isinstance(meth2, Method) assert meth2.call_args(args) == obj1 # Check method returned from unbound_method.__get__() w_meth3 = descr_function_get(space, func, space.w_None, space.type(obj2)) meth3 = space.unwrap(w_meth3) w_meth4 = meth3.descr_method_get(obj2, space.w_None) meth4 = space.unwrap(w_meth4) assert isinstance(meth4, Method) assert meth4.call_args(args) == obj2 # Check method returned from unbound_method.__get__() # --- with an incompatible class w_meth5 = meth3.descr_method_get(space.wrap('hello'), space.w_text) assert space.is_w(w_meth5, w_meth3) # Same thing, with an old-style class w_oldclass = space.call_function(space.builtin.get('__metaclass__'), space.wrap('OldClass'), space.newtuple([]), space.newdict()) w_meth6 = meth3.descr_method_get(space.wrap('hello'), w_oldclass) assert space.is_w(w_meth6, w_meth3) # Reverse order of old/new styles w_meth7 = descr_function_get(space, func, space.w_None, w_oldclass) meth7 = space.unwrap(w_meth7) w_meth8 = meth7.descr_method_get(space.wrap('hello'), space.w_text) assert space.is_w(w_meth8, w_meth7)
def find(space, identifier): from pypy.interpreter.function import Function return Function.find(space, identifier).code
def descr__setstate__(self, space, w_args): from pypy.module._pickle_support import maker # helper fns from pypy.interpreter.pycode import PyCode from pypy.interpreter.module import Module args_w = space.unpackiterable(w_args) w_f_back, w_builtin, w_pycode, w_valuestack, w_blockstack, w_exc_value, w_tb,\ w_globals, w_last_instr, w_finished, w_f_lineno, w_fastlocals, w_f_locals, \ w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev_plus_one, w_cells = args_w new_frame = self pycode = space.interp_w(PyCode, w_pycode) if space.is_w(w_cells, space.w_None): closure = None cellvars = [] else: from pypy.interpreter.nestedscope import Cell cells_w = space.unpackiterable(w_cells) cells = [space.interp_w(Cell, w_cell) for w_cell in cells_w] ncellvars = len(pycode.co_cellvars) cellvars = cells[:ncellvars] closure = cells[ncellvars:] # do not use the instance's __init__ but the base's, because we set # everything like cells from here # XXX hack from pypy.interpreter.function import Function outer_func = Function(space, None, closure=closure, forcename="fake") PyFrame.__init__(self, space, pycode, w_globals, outer_func) f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True) new_frame.f_backref = jit.non_virtual_ref(f_back) new_frame.builtin = space.interp_w(Module, w_builtin) new_frame.set_blocklist([ unpickle_block(space, w_blk) for w_blk in space.unpackiterable(w_blockstack) ]) values_w = maker.slp_from_tuple_with_nulls(space, w_valuestack) for w_value in values_w: new_frame.pushvalue(w_value) if space.is_w(w_exc_value, space.w_None): new_frame.last_exception = None else: from pypy.interpreter.pytraceback import PyTraceback tb = space.interp_w(PyTraceback, w_tb) new_frame.last_exception = OperationError(space.type(w_exc_value), w_exc_value, tb) new_frame.last_instr = space.int_w(w_last_instr) new_frame.frame_finished_execution = space.is_true(w_finished) new_frame.f_lineno = space.int_w(w_f_lineno) fastlocals_w = maker.slp_from_tuple_with_nulls(space, w_fastlocals) new_frame.locals_stack_w[:len(fastlocals_w)] = fastlocals_w if space.is_w(w_f_trace, space.w_None): new_frame.w_f_trace = None else: new_frame.w_f_trace = w_f_trace new_frame.instr_lb = space.int_w(w_instr_lb) #the three for tracing new_frame.instr_ub = space.int_w(w_instr_ub) new_frame.instr_prev_plus_one = space.int_w(w_instr_prev_plus_one) self._setcellvars(cellvars) # XXX what if the frame is in another thread?? space.frame_trace_action.fire()
def descr__setstate__(self, space, w_args): from pypy.module._pickle_support import maker # helper fns from pypy.interpreter.pycode import PyCode from pypy.interpreter.module import Module args_w = space.unpackiterable(w_args, 17) w_f_back, w_builtin, w_pycode, w_locals_cells_stack, w_blockstack, w_exc_value, w_tb,\ w_globals, w_last_instr, w_finished, w_f_lineno, w_f_locals, \ w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev_plus_one, w_stackdepth = args_w new_frame = self pycode = space.interp_w(PyCode, w_pycode) values_w = maker.slp_from_tuple_with_nulls(space, w_locals_cells_stack) nfreevars = len(pycode.co_freevars) closure = None if nfreevars: base = pycode.co_nlocals + len(pycode.co_cellvars) closure = values_w[base:base + nfreevars] # do not use the instance's __init__ but the base's, because we set # everything like cells from here # XXX hack from pypy.interpreter.function import Function outer_func = Function(space, None, closure=closure, forcename="fake") PyFrame.__init__(self, space, pycode, w_globals, outer_func) f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True) new_frame.f_backref = jit.non_virtual_ref(f_back) if space.config.objspace.honor__builtins__: new_frame.builtin = space.interp_w(Module, w_builtin) else: assert space.interp_w(Module, w_builtin) is space.builtin new_frame.set_blocklist([ unpickle_block(space, w_blk) for w_blk in space.unpackiterable(w_blockstack) ]) self.locals_cells_stack_w = values_w[:] valuestackdepth = space.int_w(w_stackdepth) if not self._check_stack_index(valuestackdepth): raise oefmt(space.w_ValueError, "invalid stackdepth") assert valuestackdepth >= 0 self.valuestackdepth = valuestackdepth if space.is_w(w_exc_value, space.w_None): new_frame.last_exception = None else: from pypy.interpreter.pytraceback import PyTraceback tb = space.interp_w(PyTraceback, w_tb) new_frame.last_exception = OperationError(space.type(w_exc_value), w_exc_value, tb) new_frame.last_instr = space.int_w(w_last_instr) new_frame.frame_finished_execution = space.is_true(w_finished) d = new_frame.getorcreatedebug() d.f_lineno = space.int_w(w_f_lineno) if space.is_w(w_f_trace, space.w_None): d.w_f_trace = None else: d.w_f_trace = w_f_trace d.instr_lb = space.int_w(w_instr_lb) #the three for tracing d.instr_ub = space.int_w(w_instr_ub) d.instr_prev_plus_one = space.int_w(w_instr_prev_plus_one)
def fake_builtin_callable(space, val): return Function(space, CPythonFakeCode(val))
def make_callable_wrapper(cls, func): def f(space, w_x): return space.wrap(func(space.unwrap(w_x))) return Function(cls.space, BuiltinCode(f))
def compile(cls, src): assert src.strip().startswith("def ") compiler = cls.space.createcompiler() code = compiler.compile(src, '<hello>', 'exec', 0).co_consts_w[0] return Function(cls.space, code, cls.space.newdict())
def setup_method(self, method): def c(self, bar): return bar code = PyCode._from_code(self.space, c.func_code) self.fn = Function(self.space, code, self.space.newdict())