def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) activation_factory_cls, run_args = cache[key] assert run_args == self.run_args, ( "unexpected: same spec, different run_args") return activation_factory_cls except KeyError: parts = [] for el in unwrap_spec: if isinstance(el, tuple): parts.append(''.join([getattr(subel, '__name__', subel) for subel in el])) elif isinstance(el, WrappedDefault): parts.append('W_Root') else: parts.append(getattr(el, '__name__', el)) label = '_'.join(parts) #print label d = {} source = """if 1: def _run(self, space, scope_w): return self.behavior(%s) \n""" % (', '.join(self.run_args),) exec compile2(source) in self.miniglobals, d activation_cls = type("BuiltinActivation_UwS_%s" % label, (BuiltinActivation,), d) activation_cls._immutable_ = True cache[key] = activation_cls, self.run_args return activation_cls
def setup(space): for name in ObjSpace.ConstantTable + ObjSpace.ExceptionTable + BUILTIN_TYPES: setattr(space, "w_" + name, w_some_obj()) space.w_type = w_some_type() # for (name, _, arity, _) in ObjSpace.MethodTable: if name == "type": continue args = ["w_%d" % i for i in range(arity)] params = args[:] d = {"is_root": is_root, "w_some_obj": w_some_obj} if name in ("get",): params[-1] += "=None" exec compile2( """\ def meth(%s): %s return w_some_obj() """ % (", ".join(params), "; ".join(["is_root(%s)" % arg for arg in args])) ) in d meth = func_with_new_name(d["meth"], name) setattr(space, name, meth) # for name in ObjSpace.IrregularOpTable: assert hasattr(space, name) # missing?
def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() unwrap_info.apply_over(unwrap_spec) narg = unwrap_info.n args = ['space'] + unwrap_info.args if args == unwrap_info.unwrap: fastfunc = func else: # try to avoid excessive bloat mod = func.__module__ if mod is None: mod = "" if mod == 'pypy.interpreter.astcompiler.ast': raise FastFuncNotSupported #if (not mod.startswith('pypy.module.__builtin__') and # not mod.startswith('pypy.module.sys') and # not mod.startswith('pypy.module.math')): # if not func.__name__.startswith('descr'): # raise FastFuncNotSupported d = {} unwrap_info.miniglobals['func'] = func source = """if 1: def fastfunc_%s_%d(%s): return func(%s) \n""" % (func.__name__.replace('-', '_'), narg, ', '.join(args), ', '.join(unwrap_info.unwrap)) exec compile2(source) in unwrap_info.miniglobals, d fastfunc = d['fastfunc_%s_%d' % (func.__name__.replace('-', '_'), narg)] return narg, fastfunc
def setup(space): for name in (ObjSpace.ConstantTable + ObjSpace.ExceptionTable + ['int', 'str', 'float', 'long', 'tuple', 'list', 'dict', 'unicode', 'complex', 'slice', 'bool', 'basestring', 'object', 'bytearray', 'buffer']): setattr(space, 'w_' + name, w_some_obj()) space.w_type = w_some_type() # for (name, _, arity, _) in ObjSpace.MethodTable: if name == 'type': continue args = ['w_%d' % i for i in range(arity)] params = args[:] d = {'is_root': is_root, 'w_some_obj': w_some_obj} if name in ('get',): params[-1] += '=None' exec compile2("""\ def meth(%s): %s return w_some_obj() """ % (', '.join(params), '; '.join(['is_root(%s)' % arg for arg in args]))) in d meth = func_with_new_name(d['meth'], name) setattr(space, name, meth) # for name in ObjSpace.IrregularOpTable: assert hasattr(space, name) # missing?
def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) activation_factory_cls, run_args = cache[key] assert run_args == self.run_args, ( "unexpected: same spec, different run_args") return activation_factory_cls except KeyError: parts = [] for el in unwrap_spec: if isinstance(el, tuple): parts.append(''.join( [getattr(subel, '__name__', subel) for subel in el])) elif isinstance(el, WrappedDefault): parts.append('W_Root') else: parts.append(getattr(el, '__name__', el)) label = '_'.join(parts) #print label d = {} source = """if 1: def _run(self, space, scope_w): return self.behavior(%s) \n""" % (', '.join(self.run_args), ) exec compile2(source) in self.miniglobals, d activation_cls = type("BuiltinActivation_UwS_%s" % label, (BuiltinActivation, ), d) activation_cls._immutable_ = True cache[key] = activation_cls, self.run_args return activation_cls
def _make_descroperation_shortcut(self, name, rpy_cls, checkerfunc): if self._shortcut: return self._shortcut emit = UnwrapSpec_EmitShortcut(rpy_cls) emit.apply_over(self._code._unwrap_spec) assert emit.rpy_cls is rpy_cls d = {} f = self._code.activation.behavior d['func'] = f d['checkerfunc'] = checkerfunc d['we_are_translated'] = we_are_translated source = """def shortcut_%s(self, space, %s): # for %s w_res = func(%s) if not we_are_translated(): assert not self.user_overridden_class if checkerfunc: assert checkerfunc(space, w_res) if w_res is None: return space.w_None return w_res """ % (name, ", ".join(emit.extraargs), rpy_cls, ', '.join( emit.run_args)) exec compile2(source) in d shortcut = d['shortcut_%s' % name] self._shortcut = shortcut return shortcut
def setup(space): for name in (ObjSpace.ConstantTable + ObjSpace.ExceptionTable + BUILTIN_TYPES): setattr(space, 'w_' + name, w_some_obj()) space.w_type = w_some_type() # for (name, _, arity, _) in ObjSpace.MethodTable: if name == 'type': continue args = ['w_%d' % i for i in range(arity)] params = args[:] d = {'is_root': is_root, 'w_some_obj': w_some_obj} if name in ('get',): params[-1] += '=None' exec compile2("""\ def meth(%s): %s return w_some_obj() """ % (', '.join(params), '; '.join(['is_root(%s)' % arg for arg in args]))) in d meth = func_with_new_name(d['meth'], name) setattr(space, name, meth) # for name in ObjSpace.IrregularOpTable: assert hasattr(space, name) # missing?
def setup(space): for name in (ObjSpace.ConstantTable + ObjSpace.ExceptionTable + BUILTIN_TYPES): if name != "str": setattr(space, 'w_' + name, w_some_obj()) space.w_bytes = w_some_obj() space.w_text = w_some_obj() space.w_type = w_some_type() # for (name, _, arity, _) in ObjSpace.MethodTable: if name == 'type': continue args = ['w_%d' % i for i in range(arity)] params = args[:] d = {'is_root': is_root, 'w_some_obj': w_some_obj} if name in ('get',): params[-1] += '=None' exec compile2("""\ def meth(%s): %s return w_some_obj() """ % (', '.join(params), '; '.join(['is_root(%s)' % arg for arg in args]))) in d meth = func_with_new_name(d['meth'], name) setattr(space, name, meth) # for name in ObjSpace.IrregularOpTable: assert hasattr(space, name) # missing?
def make_func(name, desc): sig = [] fieldvalues = [] for field in desc.fields: if field in desc.specializations: fieldvalues.append((field, desc.specializations[field])) else: sig.append(field.name) fieldvalues.append((field, field.name)) if isinstance(desc, IDupDesc): for destfield, srcfield in desc.dupfields.iteritems(): fieldvalues.append((destfield, srcfield.name)) body = ['v = r_uint(0)'] assert 'v' not in sig # that wouldn't be funny #body.append('print %r'%name + ', ' + ', '.join(["'%s:', %s"%(s, s) for s in sig])) for field, value in fieldvalues: if field.name == 'spr': body.append('spr1 = (%s&31) << 5 | (%s >> 5 & 31)' % (value, value)) value = 'spr1' elif field.name == 'mbe': body.append('mbe1 = (%s & 31) << 1 | (%s & 32) >> 5' % (value, value)) value = 'mbe1' elif field.name == 'sh': body.append('sh1 = (%s & 31) << 10 | (%s & 32) >> 5' % (value, value)) value = 'sh1' elif field.name == 'fvrT': body.append('vrT1 = (%s & 31) << 21 | (%s & 32) >> 5' % (value, value)) value = 'vrT1' elif field.name == 'fvrA': body.append('fvrA1 = (%s & 31) << 14 | (%s & 32) >> 5' % (value, value)) value = 'fvrA1' elif field.name == 'fvrB': body.append('fvrB1 = (%s & 31) << 10 | (%s & 32) >> 5' % (value, value)) value = 'fvrB1' if isinstance(field, IField): body.append('v |= ((%3s >> 2) & r_uint(%#05x)) << 2' % (value, field.mask)) else: body.append('v |= (%3s & r_uint(%#05x)) << %d' % (value, field.mask, (32 - field.right - 1))) #body.append('self.check(desc, v, %s)' % ', '.join(sig)) body.append('self.emit(v)') src = 'def %s(self, %s):\n %s' % (name, ', '.join(sig), '\n '.join(body)) d = {'r_uint': r_uint, 'desc': desc} #print src exec compile2(src) in d return d[name]
def make_function(self, fnargs, nbargs_before, mrdtable): if self._function is not None: return self._function name = self.get_function_name() self.compress_typechecks(mrdtable) checklines = self.generate_typechecks(mrdtable, fnargs[nbargs_before:]) if not checklines: body = self.body else: checklines.append(self.body) body = '\n '.join(checklines) source = 'def %s(%s):\n %s\n' % (name, ', '.join(fnargs), body) self.debug_dump(source) exec compile2(source) in self.miniglobals self._function = self.miniglobals[name] return self._function
def setup(space): for name in ( ObjSpace.ConstantTable + ObjSpace.ExceptionTable + [ "int", "str", "float", "long", "tuple", "list", "dict", "unicode", "complex", "slice", "bool", "basestring", "object", "bytearray", "buffer", ] ): setattr(space, "w_" + name, w_some_obj()) space.w_type = w_some_type() # for (name, _, arity, _) in ObjSpace.MethodTable: if name == "type": continue args = ["w_%d" % i for i in range(arity)] params = args[:] d = {"is_root": is_root, "w_some_obj": w_some_obj} if name in ("get",): params[-1] += "=None" exec compile2( """\ def meth(%s): %s return w_some_obj() """ % (", ".join(params), "; ".join(["is_root(%s)" % arg for arg in args])) ) in d meth = func_with_new_name(d["meth"], name) setattr(space, name, meth) # for name in ObjSpace.IrregularOpTable: assert hasattr(space, name) # missing?
def make_func(name, desc): sig = [] fieldvalues = [] for field in desc.fields: if field in desc.specializations: fieldvalues.append((field, desc.specializations[field])) else: sig.append(field.name) fieldvalues.append((field, field.name)) if isinstance(desc, IDupDesc): for destfield, srcfield in desc.dupfields.iteritems(): fieldvalues.append((destfield, srcfield.name)) body = ["v = r_uint(0)"] assert "v" not in sig # that wouldn't be funny # body.append('print %r'%name + ', ' + ', '.join(["'%s:', %s"%(s, s) for s in sig])) for field, value in fieldvalues: if field.name == "spr": body.append("spr1 = (%s&31) << 5 | (%s >> 5 & 31)" % (value, value)) value = "spr1" elif field.name == "mbe": body.append("mbe1 = (%s & 31) << 1 | (%s & 32) >> 5" % (value, value)) value = "mbe1" elif field.name == "sh": body.append("sh1 = (%s & 31) << 10 | (%s & 32) >> 5" % (value, value)) value = "sh1" elif field.name == "fvrT": body.append("vrT1 = (%s & 31) << 21 | (%s & 32) >> 5" % (value, value)) value = "vrT1" elif field.name == "fvrA": body.append("fvrA1 = (%s & 31) << 14 | (%s & 32) >> 5" % (value, value)) value = "fvrA1" elif field.name == "fvrB": body.append("fvrB1 = (%s & 31) << 10 | (%s & 32) >> 5" % (value, value)) value = "fvrB1" if isinstance(field, IField): body.append("v |= ((%3s >> 2) & r_uint(%#05x)) << 2" % (value, field.mask)) else: body.append("v |= (%3s & r_uint(%#05x)) << %d" % (value, field.mask, (32 - field.right - 1))) # body.append('self.check(desc, v, %s)' % ', '.join(sig)) body.append("self.emit(v)") src = "def %s(self, %s):\n %s" % (name, ", ".join(sig), "\n ".join(body)) d = {"r_uint": r_uint, "desc": desc} # print src exec compile2(src) in d return d[name]
def decorate(func): from rpython.tool.sourcetools import compile2 # def get_printable_location(): return name jitdriver = JitDriver(get_printable_location=get_printable_location, greens=[], reds='auto', name=name) # args = ','.join(['a%d' % i for i in range(func.func_code.co_argcount)]) source = """def callback_with_jitdriver(%(args)s): jitdriver.jit_merge_point() return real_callback(%(args)s)""" % locals() miniglobals = { 'jitdriver': jitdriver, 'real_callback': func, } exec compile2(source) in miniglobals return miniglobals['callback_with_jitdriver']
def _make_objclass_getter(cls): if not cls: return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: miniglobals['cls'] = cls typeexpr = "space.gettypeobject(cls.typedef)" source = """if 1: def objclass_getter(space): return %s \n""" % (typeexpr, ) exec compile2(source) in miniglobals res = miniglobals['objclass_getter'], cls return res
def _make_objclass_getter(cls): if not cls: return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: miniglobals['cls'] = cls typeexpr = "space.gettypeobject(cls.typedef)" source = """if 1: def objclass_getter(space): return %s \n""" % (typeexpr,) exec compile2(source) in miniglobals res = miniglobals['objclass_getter'], cls return res
def make_func(name, desc): sig = [] fieldvalues = [] for field in desc.fields: if field in desc.specializations: fieldvalues.append((field, desc.specializations[field])) else: sig.append(field.name) fieldvalues.append((field, field.name)) if isinstance(desc, IDupDesc): for destfield, srcfield in desc.dupfields.iteritems(): fieldvalues.append((destfield, srcfield.name)) body = ['v = r_uint(0)'] assert 'v' not in sig # that wouldn't be funny #body.append('print %r'%name + ', ' + ', '.join(["'%s:', %s"%(s, s) for s in sig])) for field, value in fieldvalues: if field.name == 'spr': body.append('spr1 = (%s&31) << 5 | (%s >> 5 & 31)'%(value, value)) value = 'spr1' elif field.name == 'mbe': body.append('mbe1 = (%s & 31) << 1 | (%s & 32) >> 5' % (value, value)) value = 'mbe1' elif field.name == 'sh': body.append('sh1 = (%s & 31) << 10 | (%s & 32) >> 5' % (value, value)) value = 'sh1' if isinstance(field, IField): body.append('v |= ((%3s >> 2) & r_uint(%#05x)) << 2' % (value, field.mask)) else: body.append('v |= (%3s & r_uint(%#05x)) << %d'%(value, field.mask, (32 - field.right - 1))) #body.append('self.check(desc, v, %s)' % ', '.join(sig)) body.append('self.emit(v)') src = 'def %s(self, %s):\n %s'%(name, ', '.join(sig), '\n '.join(body)) d = {'r_uint':r_uint, 'desc': desc} #print src exec compile2(src) in d return d[name]
def make_perform_trampoline(prefix, exprargs, expr, miniglobals, multimethod, selfindex=0, allow_NotImplemented_results=False): """NOT_RPYTHON""" # mess to figure out how to put a gateway around executing expr argnames = ['_%d' % (i + 1) for i in range(multimethod.arity)] explicit_argnames = multimethod.extras.get('argnames', []) argnames[len(argnames) - len(explicit_argnames):] = explicit_argnames solid_arglist = ['w_' + name for name in argnames] wrapper_arglist = solid_arglist[:] if multimethod.extras.get('varargs_w', False): wrapper_arglist.append('args_w') if multimethod.extras.get('keywords', False): raise Exception, "no longer supported, use __args__" if multimethod.extras.get('general__args__', False): wrapper_arglist.append('__args__') wrapper_arglist += multimethod.extras.get('extra_args', ()) miniglobals.update({ 'OperationError': OperationError, 'gettypeerror': gettypeerror }) app_defaults = multimethod.extras.get('defaults', ()) i = len(argnames) - len(app_defaults) wrapper_signature = wrapper_arglist[:] unwrap_spec_kwds = {} for app_default in app_defaults: name = wrapper_signature[i] unwrap_spec_kwds[name] = gateway.WrappedDefault(app_default) i += 1 wrapper_signature.insert(0, wrapper_signature.pop(selfindex)) wrapper_sig = ', '.join(wrapper_signature) src = [] dest = [] for wrapper_arg, expr_arg in zip(['space'] + wrapper_arglist, exprargs): if wrapper_arg != expr_arg: src.append(wrapper_arg) dest.append(expr_arg) renaming = ', '.join(dest) + " = " + ', '.join(src) if allow_NotImplemented_results and ( len(multimethod.specialnames) > 1 or multimethod.name.startswith('inplace_')): # turn FailedToImplement into NotImplemented code = """def %s_perform_call(space, %s): %s try: return %s except FailedToImplement, e: if e.get_w_type(space) is not None: raise OperationError(e.w_type, e.get_w_value(space)) else: return space.w_NotImplemented """ % (prefix, wrapper_sig, renaming, expr) else: # turn FailedToImplement into nice TypeErrors code = """def %s_perform_call(space, %s): %s try: w_res = %s except FailedToImplement, e: if e.get_w_type(space) is not None: raise OperationError(e.w_type, e.get_w_value(space)) else: raise gettypeerror(space, %r, %s) if w_res is None: w_res = space.w_None return w_res """ % (prefix, wrapper_sig, renaming, expr, multimethod.operatorsymbol, ', '.join(solid_arglist)) exec compile2(code, '', 'exec') in miniglobals func = miniglobals["%s_perform_call" % prefix] if unwrap_spec_kwds: func = gateway.unwrap_spec(**unwrap_spec_kwds)(func) return func
if w_impl is None: raise oefmt(space.w_TypeError, %(msg)r, w_obj) w_result = space.get_and_call_function(w_impl, w_obj) if %(checker)s: return w_result raise oefmt(space.w_TypeError, "%(specialname)s returned non-%(targetname)s (type " "'%%T')", w_result) assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s \n""" % locals() exec compile2(source) for targetname, specialname in [('str', '__str__'), ('repr', '__repr__')]: source = """if 1: def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: raise oefmt(space.w_TypeError, "unsupported operand type for %(targetname)s(): " "'%%T'", w_obj) w_result = space.get_and_call_function(w_impl, w_obj) if space.isinstance_w(w_result, space.w_unicode): return w_result raise oefmt(space.w_TypeError,
def __init__(self, func, unwrap_spec=None, self_type=None, descrmismatch=None, doc=None): # 'implfunc' is the interpreter-level function. # Note that this uses a lot of (construction-time) introspection. Code.__init__(self, func.__name__) self.docstring = doc or func.__doc__ self.identifier = "%s-%s-%s" % (func.__module__, func.__name__, getattr(self_type, '__name__', '*')) # unwrap_spec can be passed to interp2app or # attached as an attribute to the function. # It is a list of types or singleton objects: # baseobjspace.ObjSpace is used to specify the space argument # baseobjspace.W_Root is for wrapped arguments to keep wrapped # argument.Arguments is for a final rest arguments Arguments object # 'args_w' for fixedview applied to rest arguments # 'w_args' for rest arguments passed as wrapped tuple # str,int,float: unwrap argument as such type # (function, cls) use function to check/unwrap argument of type cls # First extract the signature from the (CPython-level) code object from pypy.interpreter import pycode sig = pycode.cpython_code_signature(func.func_code) argnames = sig.argnames varargname = sig.varargname kwargname = sig.kwargname self._argnames = argnames if unwrap_spec is None: unwrap_spec = build_unwrap_spec(func, argnames, self_type) if self_type: assert unwrap_spec[ 0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: assert issubclass(self_type, W_Root) unwrap_spec[0] = ('INTERNAL:self', self_type) self.descrmismatch_op = descrmismatch self.descr_reqcls = self_type else: unwrap_spec[0] = self_type else: assert descrmismatch is None, ( "descrmismatch without a self-type specified") orig_sig = SignatureBuilder(func, argnames, varargname, kwargname) app_sig = SignatureBuilder(func) UnwrapSpec_Check(orig_sig).apply_over(unwrap_spec, app_sig) self.sig = app_sig.signature() argnames = self.sig.argnames varargname = self.sig.varargname self.minargs = len(argnames) if varargname: self.maxargs = sys.maxint else: self.maxargs = self.minargs self.activation = UnwrapSpec_EmitRun.make_activation(unwrap_spec, func) self._bltin = func self._unwrap_spec = unwrap_spec # speed hack if 0 <= len(unwrap_spec) <= 5: try: arity, fastfunc = UnwrapSpec_FastFunc_Unwrap.make_fastfunc( unwrap_spec, func) except FastFuncNotSupported: if unwrap_spec == [ObjSpace, Arguments]: self.__class__ = BuiltinCodePassThroughArguments0 self.func__args__ = func elif unwrap_spec == [ObjSpace, W_Root, Arguments]: self.__class__ = BuiltinCodePassThroughArguments1 self.func__args__ = func elif unwrap_spec == [self_type, ObjSpace, Arguments]: self.__class__ = BuiltinCodePassThroughArguments1 miniglobals = {'func': func, 'self_type': self_type} d = {} source = """if 1: def _call(space, w_obj, args): self = space.descr_self_interp_w(self_type, w_obj) return func(self, space, args) \n""" exec compile2(source) in miniglobals, d self.func__args__ = d['_call'] else: self.__class__ = globals()['BuiltinCode%d' % arity] setattr(self, 'fastfunc_%d' % arity, fastfunc)
def make_perform_trampoline(prefix, exprargs, expr, miniglobals, multimethod, selfindex=0, allow_NotImplemented_results=False): """NOT_RPYTHON""" # mess to figure out how to put a gateway around executing expr argnames = ['_%d'%(i+1) for i in range(multimethod.arity)] explicit_argnames = multimethod.extras.get('argnames', []) argnames[len(argnames)-len(explicit_argnames):] = explicit_argnames solid_arglist = ['w_'+name for name in argnames] wrapper_arglist = solid_arglist[:] if multimethod.extras.get('varargs_w', False): wrapper_arglist.append('args_w') if multimethod.extras.get('keywords', False): raise Exception, "no longer supported, use __args__" if multimethod.extras.get('general__args__', False): wrapper_arglist.append('__args__') wrapper_arglist += multimethod.extras.get('extra_args', ()) miniglobals.update({ 'OperationError': OperationError, 'gettypeerror': gettypeerror}) app_defaults = multimethod.extras.get('defaults', ()) i = len(argnames) - len(app_defaults) wrapper_signature = wrapper_arglist[:] unwrap_spec_kwds = {} for app_default in app_defaults: name = wrapper_signature[i] unwrap_spec_kwds[name] = gateway.WrappedDefault(app_default) i += 1 wrapper_signature.insert(0, wrapper_signature.pop(selfindex)) wrapper_sig = ', '.join(wrapper_signature) src = [] dest = [] for wrapper_arg,expr_arg in zip(['space']+wrapper_arglist, exprargs): if wrapper_arg != expr_arg: src.append(wrapper_arg) dest.append(expr_arg) renaming = ', '.join(dest) +" = "+', '.join(src) if allow_NotImplemented_results and (len(multimethod.specialnames) > 1 or multimethod.name.startswith('inplace_')): # turn FailedToImplement into NotImplemented code = """def %s_perform_call(space, %s): %s try: return %s except FailedToImplement, e: if e.get_w_type(space) is not None: raise OperationError(e.w_type, e.get_w_value(space)) else: return space.w_NotImplemented """ % (prefix, wrapper_sig, renaming, expr) else: # turn FailedToImplement into nice TypeErrors code = """def %s_perform_call(space, %s): %s try: w_res = %s except FailedToImplement, e: if e.get_w_type(space) is not None: raise OperationError(e.w_type, e.get_w_value(space)) else: raise gettypeerror(space, %r, %s) if w_res is None: w_res = space.w_None return w_res """ % (prefix, wrapper_sig, renaming, expr, multimethod.operatorsymbol, ', '.join(solid_arglist)) exec compile2(code, '', 'exec') in miniglobals func = miniglobals["%s_perform_call" % prefix] if unwrap_spec_kwds: func = gateway.unwrap_spec(**unwrap_spec_kwds)(func) return func
def build_function(self, target, funcname, func_selfarg_index, things_to_call): # support for inventing names for the entries in things_to_call # which are real function objects instead of strings miniglobals = { 'FailedToImplement': FailedToImplement, '__name__': __name__ } def invent_name(obj): if isinstance(obj, str): return obj name = obj.__name__ n = 1 while name in miniglobals: n += 1 name = '%s%d' % (obj.__name__, n) miniglobals[name] = obj return name funcargs = ['arg%d' % i for i in range(self.multimethod.arity)] bodylines = [] for conversion, call, call_selfarg_index in things_to_call: callargs = funcargs[:] if conversion is not None: to_convert = func_selfarg_index convert_callargs = (self.multimethod.argnames_before + [callargs[to_convert]]) callargs[to_convert] = '%s(%s)' % (invent_name(conversion), ', '.join(convert_callargs)) callname = invent_name(call) if call_selfarg_index is not None: # fallback on root_class self.build_function(self.multimethod.root_class, callname, call_selfarg_index, []) callname = '%s.%s' % (callargs.pop(call_selfarg_index), callname) callargs = (self.multimethod.argnames_before + callargs + self.multimethod.argnames_after) bodylines.append('return %s(%s)' % (callname, ', '.join(callargs))) fallback = False if not bodylines: miniglobals['raiseFailedToImplement'] = raiseFailedToImplement bodylines = ['return raiseFailedToImplement()'] fallback = True # NB. make sure that there is only one fallback function object, # i.e. the key used in the mmfunccache below is always the same # for all functions with the same name and an empty bodylines. # protect all lines apart from the last one by a try:except: for i in range(len(bodylines) - 2, -1, -1): bodylines[i:i + 1] = [ 'try:', ' ' + bodylines[i], 'except FailedToImplement:', ' pass' ] if func_selfarg_index is not None: selfargs = [funcargs.pop(func_selfarg_index)] else: selfargs = [] funcargs = (selfargs + self.multimethod.argnames_before + funcargs + self.multimethod.argnames_after) if target is None and not self.baked_perform_call: return funcargs, bodylines[0][len('return ' ):], miniglobals, fallback # indent mode bodylines = [' ' + line for line in bodylines] bodylines.insert(0, 'def %s(%s):' % (funcname, ', '.join(funcargs))) bodylines.append('') source = '\n'.join(bodylines) # XXX find a better place (or way) to avoid duplicate functions l = miniglobals.items() l.sort() l = tuple(l) key = (source, l) try: func = self.mmfunccache[key] except KeyError: exec compile2(source) in miniglobals func = miniglobals[funcname] self.mmfunccache[key] = func #else: # print "avoided duplicate function", func self.to_install.append((target, funcname, func, source, fallback)) return func
w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: raise operationerrfmt(space.w_TypeError, "unsupported operand type for %(targetname)s(): '%%T'", w_obj) w_result = space.get_and_call_function(w_impl, w_obj) if %(checker)s: return w_result msg = "%(specialname)s returned non-%(targetname)s (type '%%T')" raise operationerrfmt(space.w_TypeError, msg, w_result) assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s \n""" % locals() exec compile2(source) for targetname, specialname in [ ('str', '__str__'), ('repr', '__repr__'), ('oct', '__oct__'), ('hex', '__hex__')]: source = """if 1: def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: raise operationerrfmt(space.w_TypeError, "unsupported operand type for %(targetname)s(): '%%T'", w_obj) w_result = space.get_and_call_function(w_impl, w_obj)
def build_function(self, target, funcname, func_selfarg_index, things_to_call): # support for inventing names for the entries in things_to_call # which are real function objects instead of strings miniglobals = {'FailedToImplement': FailedToImplement, '__name__': __name__} def invent_name(obj): if isinstance(obj, str): return obj name = obj.__name__ n = 1 while name in miniglobals: n += 1 name = '%s%d' % (obj.__name__, n) miniglobals[name] = obj return name funcargs = ['arg%d' % i for i in range(self.multimethod.arity)] bodylines = [] for conversion, call, call_selfarg_index in things_to_call: callargs = funcargs[:] if conversion is not None: to_convert = func_selfarg_index convert_callargs = (self.multimethod.argnames_before + [callargs[to_convert]]) callargs[to_convert] = '%s(%s)' % ( invent_name(conversion), ', '.join(convert_callargs)) callname = invent_name(call) if call_selfarg_index is not None: # fallback on root_class self.build_function(self.multimethod.root_class, callname, call_selfarg_index, []) callname = '%s.%s' % (callargs.pop(call_selfarg_index), callname) callargs = (self.multimethod.argnames_before + callargs + self.multimethod.argnames_after) bodylines.append('return %s(%s)' % (callname, ', '.join(callargs))) fallback = False if not bodylines: miniglobals['raiseFailedToImplement'] = raiseFailedToImplement bodylines = ['return raiseFailedToImplement()'] fallback = True # NB. make sure that there is only one fallback function object, # i.e. the key used in the mmfunccache below is always the same # for all functions with the same name and an empty bodylines. # protect all lines apart from the last one by a try:except: for i in range(len(bodylines)-2, -1, -1): bodylines[i:i+1] = ['try:', ' ' + bodylines[i], 'except FailedToImplement:', ' pass'] if func_selfarg_index is not None: selfargs = [funcargs.pop(func_selfarg_index)] else: selfargs = [] funcargs = (selfargs + self.multimethod.argnames_before + funcargs + self.multimethod.argnames_after) if target is None and not self.baked_perform_call: return funcargs, bodylines[0][len('return '):], miniglobals, fallback # indent mode bodylines = [' ' + line for line in bodylines] bodylines.insert(0, 'def %s(%s):' % (funcname, ', '.join(funcargs))) bodylines.append('') source = '\n'.join(bodylines) # XXX find a better place (or way) to avoid duplicate functions l = miniglobals.items() l.sort() l = tuple(l) key = (source, l) try: func = self.mmfunccache[key] except KeyError: exec compile2(source) in miniglobals func = miniglobals[funcname] self.mmfunccache[key] = func #else: # print "avoided duplicate function", func self.to_install.append((target, funcname, func, source, fallback)) return func
def inplace_add(x, y): x += y return x def inplace_sub(x, y): x -= y return x def inplace_mul(x, y): x *= y return x exec compile2(""" def inplace_truediv(x, y): x /= y return x """, flags=__future__.CO_FUTURE_DIVISION, dont_inherit=1) # makes an INPLACE_TRUE_DIVIDE def inplace_floordiv(x, y): x //= y return x exec compile2(""" def inplace_div(x, y): x /= y return x """, flags=0, dont_inherit=1) # makes an INPLACE_DIVIDE def inplace_mod(x, y):
def __init__(self, func, unwrap_spec=None, self_type=None, descrmismatch=None, doc=None): "NOT_RPYTHON" # 'implfunc' is the interpreter-level function. # Note that this uses a lot of (construction-time) introspection. Code.__init__(self, func.__name__) self.docstring = doc or func.__doc__ self.identifier = "%s-%s-%s" % (func.__module__, func.__name__, getattr(self_type, '__name__', '*')) # unwrap_spec can be passed to interp2app or # attached as an attribute to the function. # It is a list of types or singleton objects: # baseobjspace.ObjSpace is used to specify the space argument # baseobjspace.W_Root is for wrapped arguments to keep wrapped # argument.Arguments is for a final rest arguments Arguments object # 'args_w' for fixedview applied to rest arguments # 'w_args' for rest arguments passed as wrapped tuple # str,int,float: unwrap argument as such type # (function, cls) use function to check/unwrap argument of type cls # First extract the signature from the (CPython-level) code object from pypy.interpreter import pycode argnames, varargname, kwargname = pycode.cpython_code_signature(func.func_code) self._argnames = argnames if unwrap_spec is None: unwrap_spec = build_unwrap_spec(func, argnames, self_type) if self_type: assert unwrap_spec[0] == 'self', "self_type without 'self' spec element" unwrap_spec = list(unwrap_spec) if descrmismatch is not None: assert issubclass(self_type, W_Root) unwrap_spec[0] = ('INTERNAL:self', self_type) self.descrmismatch_op = descrmismatch self.descr_reqcls = self_type else: unwrap_spec[0] = self_type else: assert descrmismatch is None, ( "descrmismatch without a self-type specified") orig_sig = SignatureBuilder(func, argnames, varargname, kwargname) app_sig = SignatureBuilder(func) UnwrapSpec_Check(orig_sig).apply_over(unwrap_spec, app_sig) self.sig = argnames, varargname, kwargname = app_sig.signature() self.minargs = len(argnames) if varargname: self.maxargs = sys.maxint else: self.maxargs = self.minargs self.activation = UnwrapSpec_EmitRun.make_activation(unwrap_spec, func) self._bltin = func self._unwrap_spec = unwrap_spec # speed hack if 0 <= len(unwrap_spec) <= 5: try: arity, fastfunc = UnwrapSpec_FastFunc_Unwrap.make_fastfunc( unwrap_spec, func) except FastFuncNotSupported: if unwrap_spec == [ObjSpace, Arguments]: self.__class__ = BuiltinCodePassThroughArguments0 self.func__args__ = func elif unwrap_spec == [ObjSpace, W_Root, Arguments]: self.__class__ = BuiltinCodePassThroughArguments1 self.func__args__ = func elif unwrap_spec == [self_type, ObjSpace, Arguments]: self.__class__ = BuiltinCodePassThroughArguments1 miniglobals = {'func': func, 'self_type': self_type} d = {} source = """if 1: def _call(space, w_obj, args): self = space.descr_self_interp_w(self_type, w_obj) return func(self, space, args) \n""" exec compile2(source) in miniglobals, d self.func__args__ = d['_call'] else: self.__class__ = globals()['BuiltinCode%d' % arity] setattr(self, 'fastfunc_%d' % arity, fastfunc)