[pypy-svn] r22227 - pypy/branch/arre-experiments/pypy/interpreter

ac at codespeak.net ac at codespeak.net
Mon Jan 16 17:29:58 CET 2006


Author: ac
Date: Mon Jan 16 17:29:58 2006
New Revision: 22227

Modified:
   pypy/branch/arre-experiments/pypy/interpreter/argument.py
   pypy/branch/arre-experiments/pypy/interpreter/miscutils.py
   pypy/branch/arre-experiments/pypy/interpreter/pyopcode.py
Log:
Specialcase positional arguments on valuestack.

Modified: pypy/branch/arre-experiments/pypy/interpreter/argument.py
==============================================================================
--- pypy/branch/arre-experiments/pypy/interpreter/argument.py	(original)
+++ pypy/branch/arre-experiments/pypy/interpreter/argument.py	Mon Jan 16 17:29:58 2006
@@ -5,6 +5,17 @@
 from pypy.interpreter.error import OperationError
 
 class AbstractArguments:
+
+    def parse(self, fnname, signature, defaults_w=[]):
+        """Parse args and kwargs to initialize a frame
+        according to the signature of code object.
+        """
+        try:
+            return self.match_signature(signature, defaults_w)
+        except ArgErr, e:
+            raise OperationError(self.space.w_TypeError,
+                                 self.space.wrap(e.getmsg(fnname)))
+
     def frompacked(space, w_args=None, w_kwds=None):
         """Convenience static method to build an Arguments
            from a wrapped sequence and a wrapped dictionary."""
@@ -37,6 +48,7 @@
     
 class ArgumentsPrepended(AbstractArguments):
     def __init__(self, args, w_firstarg):
+        self.space = args.space
         self.args = args
         self.w_firstarg = w_firstarg
         
@@ -62,16 +74,6 @@
     def _rawshape(self, nextra=0):
         return self.args._rawshape(nextra + 1)
 
-    def parse(self, fnname, signature, defaults_w=[]):
-        """Parse args and kwargs to initialize a frame
-        according to the signature of code object.
-        """
-        try:
-            return self.match_signature(signature, defaults_w)
-        except ArgErr, e:
-            raise OperationError(self.args.space.w_TypeError,
-                                 self.args.space.wrap(e.getmsg(fnname)))
-
     def match_signature(self, signature, defaults_w=[]):
         """Parse args and kwargs according to the signature of a code object,
         or raise an ArgErr in case of failure.
@@ -106,6 +108,100 @@
     def num_kwds(self):
         return self.args.num_kwds()
     
+class ArgumentsFromValuestack(AbstractArguments):
+    """
+    Collects the arguments of a fuction call as stored on a PyFrame valuestack.
+
+    Only for the case of purely positional arguments, for now.
+    """
+
+    def __init__(self, space, valuestack, nargs=0):
+       self.space = space
+       self.valuestack = valuestack
+       self.nargs = nargs
+
+    def firstarg(self):
+        if self.nargs <= 0:
+            return None
+        return valuestack.top(nargs - 1)
+
+    def __repr__(self):
+        return 'ArgumentsFromValuestack(%r, %r)' % (self.valuestack, self.nargs)
+
+    def has_keywords(self):
+        return False
+
+    def unpack(self):
+        args_w = [None] * self.nargs
+        for i in range(self.nargs):
+            args_w[i] = self.valuestack.top(self.nargs - 1 - i)
+        return args_w, {}
+
+    def fixedunpack(self, argcount):
+        if self.nargs > argcount:
+            raise ValueError, "too many arguments (%d expected)" % argcount
+        elif self.nargs < argcount:
+            raise ValueError, "not enough arguments (%d expected)" % argcount
+        data_w = [None] * self.nargs
+        for i in range(self.nargs):
+            data_w[i] = self.valuestack.top(nargs - 1 - i)
+        return data_w
+
+    def _rawshape(self, nextra=0):
+        return nextra + self.nargs, (), False, False
+
+    def match_signature(self, signature, defaults_w=[]):
+        argnames, varargname, kwargname = signature
+        co_argcount = len(argnames)
+        if self.nargs + len(defaults_w) < co_argcount:
+            raise ArgErrCount(self, signature, defaults_w,
+                              co_argcount - self.nargs - len(defaults_w))
+        if self.nargs > co_argcount and varargname is None:
+            raise ArgErrCount(self, signature, defaults_w, 0)
+
+        scopesize = co_argcount
+        if varargname:
+            scopesize += 1
+        if kwargname:
+            scopesize += 1
+        scope_w = [None] * scopesize
+        if self.nargs >= co_argcount:
+            for i in range(co_argcount):
+                scope_w[i] = self.valuestack.top(self.nargs - 1 - i)
+            if varargname is not None:
+                stararg_w = [None] * (self.nargs - co_argcount)
+                for i in range(co_argcount, self.nargs):
+                    stararg_w[i - co_argcount] = self.valuestack.top(self.nargs - 1 - i)
+                scope_w[co_argcount] = self.space.newtuple(stararg_w)
+                co_argcount += 1
+        else:
+            for i in range(self.nargs):
+                scope_w[i] = self.valuestack.top(self.nargs - 1 - i)
+            ndefaults = len(defaults_w)
+            missing = co_argcount - self.nargs
+            first_default = ndefaults - missing
+            for i in range(missing):
+                scope_w[self.nargs + i] = defaults_w[first_default + i]
+            if varargname is not None:
+                scope_w[co_argcount] = self.space.newtuple([])
+                co_argcount += 1
+
+        if kwargname is not None:
+            scope_w[co_argcount] = self.space.newdict([])
+        return scope_w
+
+    def flatten(self):
+        data_w = [None] * self.nargs
+        for i in range(self.nargs):
+            data_w[i] = self.valuestack.top(nargs - 1 - i)
+        return nextra + self.nargs, (), False, False, data_w
+
+    def num_args(self):
+        return self.nargs
+
+    def num_kwds(self):
+        return 0
+
 class Arguments(AbstractArguments):
     """
     Collects the arguments of a function call.
@@ -226,17 +322,6 @@
 
     ###  Parsing for function calls  ###
 
-    def parse(self, fnname, signature, defaults_w=[]):
-        """Parse args and kwargs to initialize a frame
-        according to the signature of code object.
-        """
-        try:
-            return self.match_signature(signature, defaults_w)
-        except ArgErr, e:
-            raise OperationError(self.space.w_TypeError,
-                                 self.space.wrap(e.getmsg(fnname)))
-
-
     def match_signature(self, signature, defaults_w=[]):
         """Parse args and kwargs according to the signature of a code object,
         or raise an ArgErr in case of failure.

Modified: pypy/branch/arre-experiments/pypy/interpreter/miscutils.py
==============================================================================
--- pypy/branch/arre-experiments/pypy/interpreter/miscutils.py	(original)
+++ pypy/branch/arre-experiments/pypy/interpreter/miscutils.py	Mon Jan 16 17:29:58 2006
@@ -33,6 +33,10 @@
     def pop(self):
         return self.items.pop()
 
+    def drop(self, n):
+        if n > 0:
+            del self.items[-n:]
+
     def top(self, position=0):
         """'position' is 0 for the top of the stack, 1 for the item below,
         and so on.  It must not be negative."""
@@ -84,6 +88,12 @@
         self.ptr = ptr
         return ret
 
+    def drop(self, n):
+        while n > 0:
+            n -= 1
+            self.ptr -= 1
+            self.items[self.ptr] = None
+
     def top(self, position=0):
         # for a fixed stack, we assume correct indices
         return self.items[self.ptr + ~position]

Modified: pypy/branch/arre-experiments/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/arre-experiments/pypy/interpreter/pyopcode.py	(original)
+++ pypy/branch/arre-experiments/pypy/interpreter/pyopcode.py	Mon Jan 16 17:29:58 2006
@@ -9,7 +9,7 @@
 from pypy.interpreter import gateway, function, eval
 from pypy.interpreter import pyframe, pytraceback
 from pypy.interpreter.miscutils import InitializedClass
-from pypy.interpreter.argument import Arguments
+from pypy.interpreter.argument import Arguments, ArgumentsFromValuestack
 from pypy.interpreter.pycode import PyCode
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rpython.objectmodel import we_are_translated
@@ -678,6 +678,14 @@
             w_function = f.valuestack.pop()
             w_result = f.space.call_function(w_function, w_arg1, w_arg2, w_arg3)
             f.valuestack.push(w_result)
+        elif (oparg >> 8) & 0xff == 0:
+            # Only positional arguments
+            nargs = oparg & 0xff
+            args = ArgumentsFromValuestack(f.space, f.valuestack, nargs)
+            w_function = f.valuestack.top(nargs)
+            w_result = f.space.call_args(w_function, args)
+            f.valuestack.drop(nargs + 1)
+            f.valuestack.push(w_result)
         # XXX end of hack for performance
         else:
             # general case



More information about the Pypy-commit mailing list