[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