[pypy-svn] r8400 - pypy/branch/src-typedunwrap/pypy/interpreter

pedronis at codespeak.net pedronis at codespeak.net
Tue Jan 18 19:47:37 CET 2005


Author: pedronis
Date: Tue Jan 18 19:47:37 2005
New Revision: 8400

Modified:
   pypy/branch/src-typedunwrap/pypy/interpreter/gateway.py
Log:
start of spec based unwrapping for interp2app gateways.

Needs refactoring to:
- get nicer
- use just one BuiltinFrame subclass for unwrap signature not per gateways

need to add handlers that effectivily do unwrapping.



Modified: pypy/branch/src-typedunwrap/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/src-typedunwrap/pypy/interpreter/gateway.py	(original)
+++ pypy/branch/src-typedunwrap/pypy/interpreter/gateway.py	Tue Jan 18 19:47:37 2005
@@ -15,17 +15,149 @@
 from pypy.interpreter.error import OperationError 
 from pypy.interpreter import eval, pycode
 from pypy.interpreter.function import Function, Method
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import W_Root,ObjSpace,Wrappable
 from pypy.interpreter.argument import Arguments
 from pypy.tool.cache import Cache 
 
+class Signature:
+    def __init__(self, func=None, argnames=None, varargname=None, kwargname=None):
+        self.func = func
+        if argnames is None:
+            argnames = []
+        self.argnames = argnames
+        self.varargname = varargname
+        self.kwargname = kwargname
+        self.rewind()
+
+    def rewind(self):
+        self._iter = iter(self.argnames)
+        
+    def __iter__(self):
+        return self
+
+    def next(self):
+        return self._iter.next()
+
+    def append(self, argname):
+        self.argnames.append(argname)
+
+    def signature(self):
+        return self.argnames, self.varargname, self.kwargname
+
+def parse_unwrap_spec(unwrap_spec, func, argnames, varargname, kwargname,
+                      new_sig):
+    orig_sig = Signature(func, argnames, varargname, kwargname)
+
+    for el in unwrap_spec:
+        to_unwrap_spec_element[el](orig_sig, new_sig)
+
+    return new_sig
+
+
+class BuiltinCodeSignature(Signature):
+
+    def __init__(self,*args,**kwds):
+        Signature.__init__(self,*args,**kwds)
+        self.setfastscope = []
+        self.run_args = []
+        self.through_scope_w = 0
+
+
+    def make_frame_class(self):
+        setfastscope = self.setfastscope
+        if not setfastscope:
+            setfastscope = ["pass"]
+        setfastscope = ["def setfastscope(self, scope_w):"] + setfastscope
+        setfastscope = '\n  '.join(setfastscope)
+        d = {}
+        exec setfastscope in globals(),d
+        exec """
+def run(self):
+    w_result = self.code.func(%s)
+    if w_result is None:
+        w_result = self.space.w_None
+    return w_result
+""" % ','.join(self.run_args) in globals(),d
+        return type("BuiltinFrame_for_%s" % self.func.__name__,
+                    (BuiltinFrame,),d)
+        
+    
+def unwrap_spec_space(orig_sig, new_sig):
+    orig_sig.next()
+    #
+    new_sig.run_args.append('self.space')
+    
+def unwrap_spec_self(orig_sig, new_sig):
+    argname = orig_sig.next()
+    new_sig.append(argname)
+    #
+    new_sig.setfastscope.append(
+        "self.arg_%s = self.space.unwrap_builtin(scope_w[%d])" %
+            (argname, new_sig.through_scope_w))
+    new_sig.through_scope_w += 1
+    new_sig.run_args.append("self.arg_%s" % argname)
+        
+        
+def unwrap_spec_wrapped(orig_sig, new_sig):
+    argname = orig_sig.next()
+    assert argname.startswith('w_'), (
+        "argument %s of built-in function %r should "
+        "start with 'w_'" % (argname, orig_sig.func))
+    new_sig.append(argname[2:])
+    #
+    new_sig.setfastscope.append(
+        "self.arg_%s = scope_w[%d]" % (argname, new_sig.through_scope_w))
+    new_sig.through_scope_w += 1
+    new_sig.run_args.append("self.arg_%s" % argname)
+
+def unwrap_spec_arguments(orig_sig, new_sig):
+    argname = orig_sig.next()
+    assert new_sig.varargname is None,(
+        "built-in function %r has conflicting rest args specs" % orig_sig.func)
+    new_sig.varargname = 'args'
+    new_sig.kwargname = 'keywords'
+    #
+    cur = new_sig.through_scope_w
+    next = cur+1
+    new_sig.through_scope_w += 2
+    new_sig.setfastscope.append(
+        "self.arg_%s = "
+        "Arguments.frompacked(self.space,scope_w[%d],scope_w[%d])"
+            % (argname, cur, next))
+    new_sig.run_args.append("self.arg_%s" % argname)
+        
+def unwrap_spec_starargs(orig_sig, new_sig):
+    varargname = orig_sig.varargname
+    assert varargname.endswith('_w'), (
+        "argument *%s of built-in function %r should end in '_w'" %
+        (varargname, orig_sig.func))
+    assert new_sig.varargname is None,(
+        "built-in function %r has conflicting rest args specs" % orig_sig.func)
+    new_sig.varargname = varargname[:-2]
+    #
+    new_sig.setfastscope.append(
+        "self.arg_%s = self.space.unpacktuple(scope_w[%d])" %
+            (varargname, new_sig.through_scope_w))
+    new_sig.through_scope_w += 1
+    new_sig.run_args.append("*self.arg_%s" % varargname)
+        
+
+to_unwrap_spec_element = {
+    ObjSpace: unwrap_spec_space,
+    'self': unwrap_spec_self,
+    W_Root: unwrap_spec_wrapped,
+    Arguments: unwrap_spec_arguments,
+    '*': unwrap_spec_starargs,
+}
+
+
 class BuiltinCode(eval.Code):
     "The code object implementing a built-in (interpreter-level) hook."
 
     # When a BuiltinCode is stored in a Function object,
     # you get the functionality of CPython's built-in function type.
 
-    def __init__(self, func, ismethod=None, spacearg=None):
+    def __init__(self, func, ismethod=None, spacearg=None, unwrap_spec = None):
         "NOT_RPYTHON"
         # 'implfunc' is the interpreter-level function.
         # Note that this uses a lot of (construction-time) introspection.
@@ -41,50 +173,63 @@
         # Not exactly a clean approach XXX.
         # First extract the signature from the (CPython-level) code object
         argnames, varargname, kwargname = pycode.cpython_code_signature(func.func_code)
-        argnames = list(argnames)
-        lookslikemethod = argnames[:1] == ['self']
-        if ismethod is None:
-            ismethod = lookslikemethod
-        if spacearg is None:
-            spacearg = not lookslikemethod
-        self.ismethod = ismethod
-        self.spacearg = spacearg
-        if spacearg:
-            del argnames[0]
-
-        assert kwargname is None, (
-            "built-in function %r should not take a ** argument" % func)
-
-        self.generalargs = argnames[-1:] == ['__args__']
-        self.starargs = varargname is not None
-        assert not (self.generalargs and self.starargs), (
-            "built-in function %r has both __args__ and a * argument" % func)
-        if self.generalargs:
-            del argnames[-1]
-            varargname = "args"
-            kwargname = "keywords"
-        elif self.starargs:
-            assert varargname.endswith('_w'), (
-                "argument *%s of built-in function %r should end in '_w'" %
-                (varargname, func))
-            varargname = varargname[:-2]
-
-        for i in range(ismethod, len(argnames)):
-            a = argnames[i]
-            assert a.startswith('w_'), (
-                "argument %s of built-in function %r should "
-                "start with 'w_'" % (a, func))
-            argnames[i] = a[2:]
+        if unwrap_spec is None:
+
+            unwrap_spec = []
+
+            argnames = list(argnames)
+            lookslikemethod = argnames[:1] == ['self']
+            if ismethod is None:
+                ismethod = lookslikemethod
+            if spacearg is None:
+                spacearg = not lookslikemethod
+            self.ismethod = ismethod
+            self.spacearg = spacearg
+            assert kwargname is None, (
+                "built-in function %r should not take a ** argument" % func)
+
+            n = len(argnames)
+
+            if self.ismethod:
+                unwrap_spec.append('self')
+                n -= 1
+            if self.spacearg:
+                unwrap_spec.append(ObjSpace)
+                n -= 1
+
+            self.generalargs = argnames[-1:] == ['__args__']
+            self.starargs = varargname is not None
+
+            if self.generalargs:
+                unwrap_spec.extend([W_Root] * (n-1))
+                unwrap_spec.append(Arguments)
+            else:
+                unwrap_spec.extend([W_Root] * n)
+
+            if self.starargs:
+                unwrap_spec.append('*')
+        else:
+            assert ismethod is None,("if unwrap_spec is specified,"
+                                     "ismethod is not expected")
+            assert spacearg is None,("if unwrap_spec is specified,"
+                                     "spacearg is not expected")
+
+        new_sig = parse_unwrap_spec(unwrap_spec, func, argnames,
+                                    varargname, kwargname,
+                                    BuiltinCodeSignature(func))
+
+        self.sig = argnames, varargname, kwargname = new_sig.signature()
 
-        self.sig = argnames, varargname, kwargname
         self.minargs = len(argnames)
         if self.starargs:
             self.maxargs = sys.maxint
         else:
             self.maxargs = self.minargs
 
+        self.framecls = new_sig.make_frame_class()
+
     def create_frame(self, space, w_globals, closure=None):
-        return BuiltinFrame(space, self, w_globals)
+        return self.framecls(space, self, w_globals)
 
     def signature(self):
         return self.sig
@@ -100,21 +245,23 @@
     # via the interface defined in eval.Frame.
 
     def setfastscope(self, scope_w):
-        argarray = list(scope_w)
-        if self.code.generalargs:
-            w_kwds = argarray.pop()
-            w_args = argarray.pop()
-            argarray.append(Arguments.frompacked(self.space, w_args, w_kwds))
-        elif self.code.starargs:
-            w_args = argarray.pop()
-            argarray += self.space.unpacktuple(w_args)
-        if self.code.ismethod:
-            argarray[0] = self.space.unwrap_builtin(argarray[0])
-        self.argarray = argarray
+        pass
+##         argarray = list(scope_w)
+##         if self.code.generalargs:
+##             w_kwds = argarray.pop()
+##             w_args = argarray.pop()
+##             argarray.append(Arguments.frompacked(self.space, w_args, w_kwds))
+##         elif self.code.starargs:
+##             w_args = argarray.pop()
+##             argarray += self.space.unpacktuple(w_args)
+##         if self.code.ismethod:
+##             argarray[0] = self.space.unwrap_builtin(argarray[0])
+##         self.argarray = argarray
 
     def getfastscope(self):
-        raise OperationError(self.space.w_TypeError,
-          self.space.wrap("cannot get fastscope of a BuiltinFrame"))
+        pass
+##         raise OperationError(self.space.w_TypeError,
+##           self.space.wrap("cannot get fastscope of a BuiltinFrame"))
 
     def run(self):
         argarray = self.argarray



More information about the Pypy-commit mailing list