Ejemplo n.º 1
0
 def __init__(self,
              bookkeeper,
              pyobj=None,
              name=None,
              signature=None,
              defaults=None,
              specializer=None):
     super(FunctionDesc, self).__init__(bookkeeper, pyobj)
     if name is None:
         name = pyobj.func_name
     if signature is None:
         if hasattr(pyobj, '_generator_next_method_of_'):
             from pypy.interpreter.argument import Signature
             signature = Signature(['entry'])  # haaaaaack
             defaults = ()
         else:
             signature = cpython_code_signature(pyobj.func_code)
     if defaults is None:
         defaults = pyobj.func_defaults
     self.name = name
     self.signature = signature
     self.defaults = defaults or ()
     # 'specializer' is a function with the following signature:
     #      specializer(funcdesc, args_s) => graph
     #                                 or => s_result (overridden/memo cases)
     self.specializer = specializer
     self._cache = {}  # convenience for the specializer
Ejemplo n.º 2
0
    def build(cache, func):
        space = cache.space
        # make a built-in function
        assert isinstance(func.code, BuiltinCode)   # XXX
        bltin = func.code._bltin
        unwrap_spec = func.code._unwrap_spec
        from pypy.interpreter import pycode
        argnames, varargname, kwargname = pycode.cpython_code_signature(
            bltin.func_code)
        orig_sig = Signature(bltin, argnames, varargname, kwargname)

        tramp = UnwrapSpec_Trampoline(orig_sig)
        tramp.miniglobals = {
            '___space':           space,
            '___W_Object':        CPyObjSpace.W_Object,
            '___bltin':           bltin,
            '___OperationError':  OperationError,
            '___reraise':         reraise,
            }
        tramp.apply_over(unwrap_spec)

        sourcelines = ['def trampoline(%s):' % (', '.join(tramp.inputargs),)]
        # this description is to aid viewing in graphviewer
        sourcelines.append('    "wrapper for fn: %s"' % func.name)
        for line in tramp.wrappings:
            sourcelines.append('    ' + line)
        sourcelines.append('    try:')
        sourcelines.append('        w_result = ___bltin(%s)' % (
            ', '.join(tramp.passedargs),))
        sourcelines.append('    except ___OperationError, e:')
        sourcelines.append('        ___reraise(e)')
        # the following line is not reached, unless we are translated
        # in which case it makes the function return (PyObject*)NULL.
        sourcelines.append('        w_result = ___W_Object()')
        sourcelines.append('    else:')
        #                           # convert None to Py_None
        sourcelines.append('        if w_result is None:')
        sourcelines.append('            return None')
        sourcelines.append('    return w_result.value')
        sourcelines.append('')

        miniglobals = tramp.miniglobals
        exec py.code.Source('\n'.join(sourcelines)).compile() in miniglobals

        trampoline = miniglobals['trampoline']
        trampoline = func_with_new_name(trampoline, func.name)
        trampoline.nb_args = len(tramp.inputargs)
        trampoline.star_arg = tramp.star_arg
        trampoline.allow_someobjects = True    # annotator hint
        trampoline._annspecialcase_ = "specialize:all_someobjects"
        if func.defs_w:
            trampoline.func_defaults = tuple([space.unwrap(w_x)
                                              for w_x in func.defs_w])
        w_result = W_Object(trampoline)
        space.wrap_cache[id(w_result)] = w_result, func, follow_annotations
        return w_result
Ejemplo n.º 3
0
 def __init__(self, bookkeeper, pyobj=None, name=None, signature=None, defaults=None, specializer=None):
     super(FunctionDesc, self).__init__(bookkeeper, pyobj)
     if name is None:
         name = pyobj.func_name
     if signature is None:
         signature = cpython_code_signature(pyobj.func_code)
     if defaults is None:
         defaults = pyobj.func_defaults
     self.name = name
     self.signature = signature
     self.defaults = defaults or ()
     # 'specializer' is a function with the following signature:
     #      specializer(funcdesc, args_s) => graph
     #                                 or => s_result (overridden/memo cases)
     self.specializer = specializer
     self._cache = {}  # convenience for the specializer
Ejemplo n.º 4
0
def _make_descr_typecheck_wrapper(tag, func, extraargs, cls, use_closure):
    # - if cls is None, the wrapped object is passed to the function
    # - if cls is a class, an unwrapped instance is passed
    # - if cls is a string, XXX unused?
    if cls is None and use_closure:
        return func
    if hasattr(func, 'im_func'):
        assert func.im_class is cls
        func = func.im_func

    miniglobals = {
         func.__name__: func,
        'OperationError': OperationError
        }
    if cls is None:
        source = """
        def descr_typecheck_%(name)s(closure, space, obj, %(extra)s):
            return %(name)s(%(args)s, %(extra)s)
        """
    else:
        cls_name = cls.__name__
        assert issubclass(cls, W_Root)
        source = """
        def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s):
            obj = space.descr_self_interp_w(%(cls_name)s, w_obj)
            return %(name)s(%(args)s, %(extra)s)
        """
        miniglobals[cls_name] = cls

    name = func.__name__
    extra = ', '.join(extraargs)
    from pypy.interpreter import pycode
    sig = pycode.cpython_code_signature(func.func_code)
    argnames = sig.argnames
    if use_closure:
        if argnames[1] == 'space':
            args = "closure, space, obj"
        else:
            args = "closure, obj, space"
    else:
        if argnames[0] == 'space':
            args = "space, obj"
        else:
            args = "obj, space"
    source = py.code.Source(source % locals())
    exec source.compile() in miniglobals
    return miniglobals['descr_typecheck_%s' % func.__name__]
Ejemplo n.º 5
0
def _make_descr_typecheck_wrapper(tag, func, extraargs, cls, use_closure):
    # - if cls is None, the wrapped object is passed to the function
    # - if cls is a class, an unwrapped instance is passed
    # - if cls is a string, XXX unused?
    if cls is None and use_closure:
        return func
    if hasattr(func, 'im_func'):
        assert func.im_class is cls
        func = func.im_func

    miniglobals = {
         func.__name__: func,
        'OperationError': OperationError
        }
    if cls is None:
        source = """
        def descr_typecheck_%(name)s(closure, space, obj, %(extra)s):
            return %(name)s(%(args)s, %(extra)s)
        """
    else:
        cls_name = cls.__name__
        assert issubclass(cls, Wrappable)
        source = """
        def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s):
            obj = space.descr_self_interp_w(%(cls_name)s, w_obj)
            return %(name)s(%(args)s, %(extra)s)
        """
        miniglobals[cls_name] = cls
    
    name = func.__name__
    extra = ', '.join(extraargs)
    from pypy.interpreter import pycode
    argnames, _, _ = pycode.cpython_code_signature(func.func_code)
    if use_closure:
        if argnames[1] == 'space':
            args = "closure, space, obj"
        else:
            args = "closure, obj, space"
    else:
        if argnames[0] == 'space':
            args = "space, obj"
        else:
            args = "obj, space"
    source = py.code.Source(source % locals())
    exec source.compile() in miniglobals
    return miniglobals['descr_typecheck_%s' % func.__name__]
Ejemplo n.º 6
0
    def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED,
                 c_name=None):
        self.argtypes = argtypes
        self.restype = restype
        self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
        self.callable = callable
        if error is not _NOT_SPECIFIED:
            self.error_value = error
        self.c_name = c_name

        # extract the signature from the (CPython-level) code object
        from pypy.interpreter import pycode
        argnames, varargname, kwargname = pycode.cpython_code_signature(callable.func_code)

        assert argnames[0] == 'space'
        self.argnames = argnames[1:]
        assert len(self.argnames) == len(self.argtypes)
Ejemplo n.º 7
0
Archivo: api.py Proyecto: juokaz/pypy
    def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED,
                 c_name=None):
        self.argtypes = argtypes
        self.restype = restype
        self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
        self.callable = callable
        if error is not _NOT_SPECIFIED:
            self.error_value = error
        self.c_name = c_name

        # extract the signature from the (CPython-level) code object
        from pypy.interpreter import pycode
        argnames, varargname, kwargname = pycode.cpython_code_signature(callable.func_code)

        assert argnames[0] == 'space'
        self.argnames = argnames[1:]
        assert len(self.argnames) == len(self.argtypes)
Ejemplo n.º 8
0
    def build_flow(self, func, constargs={}):
        """
        """
        if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
            raise Exception, "%r is tagged as NOT_RPYTHON" % (func, )
        code = func.func_code
        if code.co_flags & 32:
            # generator
            raise TypeError("%r is a generator" % (func, ))
        code = PyCode._from_code(self, code)
        if func.func_closure is None:
            closure = None
        else:
            closure = [
                extract_cell_content(c, name, func) for c, name in zip(
                    func.func_closure, func.func_code.co_freevars)
            ]
        # CallableFactory.pycall may add class_ to functions that are methods
        name = func.func_name
        class_ = getattr(func, 'class_', None)
        if class_ is not None:
            name = '%s.%s' % (class_.__name__, name)
        for c in "<>&!":
            name = name.replace(c, '_')
        ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
                                              constargs, closure, name)
        graph = ec.graph
        graph.func = func
        # attach a signature and defaults to the graph
        # so that it becomes even more interchangeable with the function
        # itself
        graph.signature = cpython_code_signature(code)
        graph.defaults = func.func_defaults or ()
        self.setup_executioncontext(ec)

        from pypy.tool.error import FlowingError, format_global_error

        try:
            ec.build_flow()
        except FlowingError, a:
            # attach additional source info to AnnotatorError
            _, _, tb = sys.exc_info()
            e = FlowingError(
                format_global_error(ec.graph, ec.crnt_offset, str(a)))
            raise FlowingError, e, tb
Ejemplo n.º 9
0
 def __init__(self, bookkeeper, pyobj=None,
              name=None, signature=None, defaults=None,
              specializer=None):
     super(FunctionDesc, self).__init__(bookkeeper, pyobj)
     if name is None:
         name = pyobj.func_name
     if signature is None:
         signature = cpython_code_signature(pyobj.func_code)
     if defaults is None:
         defaults = pyobj.func_defaults
     self.name = name
     self.signature = signature
     self.defaults = defaults or ()
     # 'specializer' is a function with the following signature:
     #      specializer(funcdesc, args_s) => graph
     #                                 or => s_result (overridden/memo cases)
     self.specializer = specializer
     self._cache = {}     # convenience for the specializer
Ejemplo n.º 10
0
    def build_flow(self, func, constargs={}, tweak_for_generator=True):
        """
        """
        if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
            raise Exception, "%r is tagged as NOT_RPYTHON" % (func, )
        code = func.func_code
        is_generator = bool(code.co_flags & CO_GENERATOR)
        code = PyCode._from_code(self, code)
        if func.func_closure is None:
            cl = None
        else:
            cl = [extract_cell_content(c) for c in func.func_closure]
        # CallableFactory.pycall may add class_ to functions that are methods
        name = func.func_name
        class_ = getattr(func, 'class_', None)
        if class_ is not None:
            name = '%s.%s' % (class_.__name__, name)
        for c in "<>&!":
            name = name.replace(c, '_')

        class outerfunc:  # hack
            closure = cl

        ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
                                              constargs, outerfunc, name,
                                              is_generator)
        graph = ec.graph
        graph.func = func
        # attach a signature and defaults to the graph
        # so that it becomes even more interchangeable with the function
        # itself
        graph.signature = cpython_code_signature(code)
        graph.defaults = func.func_defaults or ()
        self.setup_executioncontext(ec)

        try:
            ec.build_flow()
        except error.FlowingError, a:
            # attach additional source info to AnnotatorError
            _, _, tb = sys.exc_info()
            formated = error.format_global_error(ec.graph, ec.crnt_offset,
                                                 str(a))
            e = error.FlowingError(formated)
            raise error.FlowingError, e, tb
Ejemplo n.º 11
0
    def build_flow(self, func, constargs={}):
        """
        """
        if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
            raise Exception, "%r is tagged as NOT_RPYTHON" % (func,)
        code = func.func_code
        if code.co_flags & 32:
            # generator
            raise TypeError("%r is a generator" % (func,))
        code = PyCode._from_code(self, code)
        if func.func_closure is None:
            closure = None
        else:
            closure = [extract_cell_content(c, name, func)
                       for c, name in zip(func.func_closure,
                                          func.func_code.co_freevars)]
        # CallableFactory.pycall may add class_ to functions that are methods
        name = func.func_name
        class_ = getattr(func, 'class_', None)
        if class_ is not None:
            name = '%s.%s' % (class_.__name__, name)
        for c in "<>&!":
            name = name.replace(c, '_')
        ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
                                              constargs, closure, name)
        graph = ec.graph
        graph.func = func
        # attach a signature and defaults to the graph
        # so that it becomes even more interchangeable with the function
        # itself
        graph.signature = cpython_code_signature(code)
        graph.defaults = func.func_defaults or ()
        self.setup_executioncontext(ec)

        from pypy.tool.error import FlowingError, format_global_error

        try:
            ec.build_flow()
        except FlowingError, a:
            # attach additional source info to AnnotatorError
            _, _, tb = sys.exc_info()
            e = FlowingError(format_global_error(ec.graph, ec.crnt_offset, str(a)))
            raise FlowingError, e, tb
Ejemplo n.º 12
0
    def build_flow(self, func, constargs={}, tweak_for_generator=True):
        """
        """
        if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
            raise Exception, "%r is tagged as NOT_RPYTHON" % (func,)
        code = func.func_code
        is_generator = bool(code.co_flags & CO_GENERATOR)
        code = PyCode._from_code(self, code)
        if func.func_closure is None:
            cl = None
        else:
            cl = [extract_cell_content(c) for c in func.func_closure]
        # CallableFactory.pycall may add class_ to functions that are methods
        name = func.func_name
        class_ = getattr(func, 'class_', None)
        if class_ is not None:
            name = '%s.%s' % (class_.__name__, name)
        for c in "<>&!":
            name = name.replace(c, '_')
        class outerfunc: # hack
            closure = cl
        ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
                                              constargs, outerfunc, name,
                                              is_generator)
        graph = ec.graph
        graph.func = func
        # attach a signature and defaults to the graph
        # so that it becomes even more interchangeable with the function
        # itself
        graph.signature = cpython_code_signature(code)
        graph.defaults = func.func_defaults or ()
        self.setup_executioncontext(ec)

        try:
            ec.build_flow()
        except error.FlowingError, a:
            # attach additional source info to AnnotatorError
            _, _, tb = sys.exc_info()
            formated = error.format_global_error(ec.graph, ec.crnt_offset,
                                                 str(a))
            e = error.FlowingError(formated)
            raise error.FlowingError, e, tb
Ejemplo n.º 13
0
    def __init__(self, bookkeeper, pyobj=None, name=None, signature=None, defaults=None, specializer=None):
        super(FunctionDesc, self).__init__(bookkeeper, pyobj)
        if name is None:
            name = pyobj.func_name
        if signature is None:
            if hasattr(pyobj, "_generator_next_method_of_"):
                from pypy.interpreter.argument import Signature

                signature = Signature(["entry"])  # haaaaaack
                defaults = ()
            else:
                signature = cpython_code_signature(pyobj.func_code)
        if defaults is None:
            defaults = pyobj.func_defaults
        self.name = name
        self.signature = signature
        self.defaults = defaults or ()
        # 'specializer' is a function with the following signature:
        #      specializer(funcdesc, args_s) => graph
        #                                 or => s_result (overridden/memo cases)
        self.specializer = specializer
        self._cache = {}  # convenience for the specializer
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
    def __init__(self, func, unwrap_spec=None, self_type=None, descrmismatch=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 = 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
            else:
                self.__class__ = globals()['BuiltinCode%d' % arity]
                setattr(self, 'fastfunc_%d' % arity, fastfunc)
Ejemplo n.º 16
0
    def __init__(self, func, unwrap_spec = None, self_type = None,
                 descrmismatch=None):
        "NOT_RPYTHON"
        # 'implfunc' is the interpreter-level function.
        # Note that this uses a lot of (construction-time) introspection.
        eval.Code.__init__(self, func.__name__)
        self.docstring = func.__doc__

        # 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
        #  baseobjspace.Wrappable subclasses imply interp_w and a typecheck
        #  argument.Arguments is for a final rest arguments Arguments object
        # 'args_w' for unpacktuple 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)

        if unwrap_spec is None:
            unwrap_spec = getattr(func,'unwrap_spec',None)

        if unwrap_spec is None:
            unwrap_spec = [ObjSpace]+ [W_Root] * (len(argnames)-1)

            if self_type:
                unwrap_spec = ['self'] + unwrap_spec[1:]
            
        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, Wrappable)
                unwrap_spec[0] = ('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 = Signature(func, argnames, varargname, kwargname)
        app_sig = Signature(func)

        UnwrapSpec_Check(orig_sig).apply_over(unwrap_spec,
                                              app_sig #to populate
                                              )
        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
            else:
                self.__class__ = globals()['BuiltinCode%d' % arity]
                setattr(self, 'fastfunc_%d' % arity, fastfunc)