[pypy-svn] r22265 - pypy/branch/arre-experiments/pypy/interpreter
ac at codespeak.net
ac at codespeak.net
Wed Jan 18 00:54:40 CET 2006
Author: ac
Date: Wed Jan 18 00:54:39 2006
New Revision: 22265
Modified:
pypy/branch/arre-experiments/pypy/interpreter/argument.py
pypy/branch/arre-experiments/pypy/interpreter/function.py
pypy/branch/arre-experiments/pypy/interpreter/gateway.py
pypy/branch/arre-experiments/pypy/interpreter/pyopcode.py
Log:
Some nice progress on the Arguments handling.
the microbench for object creation is now down to a factor of ~20
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 Wed Jan 18 00:54:39 2006
@@ -3,6 +3,7 @@
"""
from pypy.interpreter.error import OperationError
+import os
class AbstractArguments:
@@ -16,6 +17,22 @@
raise OperationError(self.space.w_TypeError,
self.space.wrap(e.getmsg(fnname)))
+ def parse_into_scope(self, scope_w, fnname, signature, defaults_w=[]):
+ """Parse args and kwargs to initialize a frame
+ according to the signature of code object.
+ Store the argumentvalues into scope_w.
+ scope_w must be big enough for signature.
+ """
+ argnames, varargname, kwargname = signature
+ has_vararg = varargname is not None
+ has_kwarg = kwargname is not None
+ try:
+ self._match_signature(scope_w, argnames, has_vararg, has_kwarg,
+ defaults_w, 0, [])
+ 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."""
@@ -45,6 +62,22 @@
def prepend(self, w_firstarg):
"Return a new Arguments with a new argument inserted first."
return ArgumentsPrepended(self, w_firstarg)
+
+ 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.
+ """
+ argnames, varargname, kwargname = signature
+ scopelen = len(argnames)
+ has_vararg = varargname is not None
+ has_kwarg = kwargname is not None
+ if has_vararg:
+ scopelen += 1
+ if has_kwarg:
+ scopelen += 1
+ scope_w = [None] * scopelen
+ self._match_signature(scope_w, argnames, has_vararg, has_kwarg, defaults_w, 0, [])
+ return scope_w
class ArgumentsPrepended(AbstractArguments):
def __init__(self, args, w_firstarg):
@@ -74,28 +107,13 @@
def _rawshape(self, nextra=0):
return self.args._rawshape(nextra + 1)
- 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.
- """
- argnames, varargname, kwargname = signature
- try:
- scope_w = self.args.match_signature((argnames[1:], varargname, kwargname), defaults_w)
- except ArgErrCount, e:
- e.num_args += 1 # Add our first arg
- raise
-
- if len(argnames) == 0:
- if varargname is None:
- raise ArgErrCount(self, signature, defaults_w, 0)
- space = self.args.space
- if kwargname is not None:
- scope_w[-2] = space.newtuple([self.w_firstarg] + space.unpackiterable(scope_w[-2]))
- else:
- scope_w[-1] = space.newtuple([self.w_firstarg] + space.unpackiterable(scope_w[-1]))
+ def _match_signature(self, scope_w, argnames, has_vararg=False, has_kwarg=False, defaults_w=[], blindargs=0, extravarargs=[]):
+ if blindargs < len(argnames):
+ scope_w[blindargs] = self.w_firstarg
else:
- scope_w.insert(0, self.w_firstarg)
- return scope_w
+ extravarargs.append(self.w_firstarg)
+ self.args._match_signature(scope_w, argnames, has_vararg, has_kwarg,
+ defaults_w, blindargs + 1, extravarargs)
def flatten(self):
(shape_cnt, shape_keys, shape_star, shape_stst), data_w = self.args.flatten()
@@ -150,45 +168,46 @@
def _rawshape(self, nextra=0):
return nextra + self.nargs, (), False, False
- def match_signature(self, signature, defaults_w=[]):
- argnames, varargname, kwargname = signature
+ def _match_signature(self, scope_w, argnames, has_vararg=False, has_kwarg=False, defaults_w=[], blindargs=0, extravarargs=[]):
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)
+ if blindargs + self.nargs + len(defaults_w) < co_argcount:
+ raise ArgErrCount(blindargs + self.nargs , 0,
+ (co_argcount, has_vararg, has_kwarg),
+ defaults_w, co_argcount - blindargs -
+ self.nargs - len(defaults_w))
+ if self.nargs > co_argcount and has_vararg:
+ raise ArgErrCount(blindargs + self.nargs, 0,
+ (co_argcount, has_vararg, has_kwarg),
+ defaults_w, 0)
+
+ if blindargs + self.nargs >= co_argcount:
+ for i in range(co_argcount - blindargs):
+ scope_w[i + blindargs] = self.valuestack.top(self.nargs - 1 - i)
+ if has_vararg:
+ if blindargs > co_argcount:
+ startarg_w = extravararg
+ for i in range(self.nargs):
+ startarg_w.append(self.valuestack.top(self.nargs - 1 - i))
+ else:
+ stararg_w = [None] * (self.nargs + blindargs - co_argcount)
+ for i in range(co_argcount - blindargs, self.nargs):
+ stararg_w[i - co_argcount + blindargs] = 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)
+ scope_w[i + blindargs] = self.valuestack.top(self.nargs - 1 - i)
ndefaults = len(defaults_w)
- missing = co_argcount - self.nargs
+ missing = co_argcount - self.nargs - blindargs
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[self.nargs + blindargs + i] = defaults_w[first_default + i]
+ if has_vararg:
scope_w[co_argcount] = self.space.newtuple([])
co_argcount += 1
- if kwargname is not None:
+ if has_kwarg:
scope_w[co_argcount] = self.space.newdict([])
- return scope_w
def flatten(self):
data_w = [None] * self.nargs
@@ -322,11 +341,13 @@
### Parsing for function calls ###
- def match_signature(self, signature, defaults_w=[]):
+ def _match_signature(self, scope_w, argnames, has_vararg=False,
+ has_kwarg=False, defaults_w=[], blindargs=0,
+ extravarargs=[]):
"""Parse args and kwargs according to the signature of a code object,
or raise an ArgErr in case of failure.
"""
- argnames, varargname, kwargname = signature
+
#
# args_w = list of the normal actual parameters, wrapped
# kwds_w = real dictionary {'keyword': wrapped parameter}
@@ -337,8 +358,8 @@
if self.w_stararg is not None:
# There is a case where we don't have to unpack() a w_stararg:
# if it matches exactly a *arg in the signature.
- if (len(self.arguments_w) == co_argcount and
- varargname is not None and
+ if (len(self.arguments_w) + blindargs == co_argcount and
+ has_vararg and
self.space.is_w(self.space.type(self.w_stararg),
self.space.w_tuple)):
pass
@@ -350,10 +371,22 @@
args_w = self.arguments_w
kwds_w = self.kwds_w
-
+ num_kwds = 0
+ if kwds_w is not None:
+ num_kwds = len(kwds_w)
+
# put as many positional input arguments into place as available
- scope_w = args_w[:co_argcount]
- input_argcount = len(scope_w)
+ if blindargs >= co_argcount:
+ input_argcount = co_argcount
+ elif len(args_w) + blindargs > co_argcount:
+ for i in range(co_argcount - blindargs):
+ scope_w[i + blindargs] = args_w[i]
+ input_argcount = co_argcount
+ next_arg = co_argcount - blindargs
+ else:
+ for i in range(len(args_w)):
+ scope_w[i + blindargs] = args_w[i]
+ input_argcount = len(args_w) + blindargs
# check that no keyword argument conflicts with these
# note that for this purpose we ignore the first blind_arguments,
@@ -376,42 +409,52 @@
for i in range(input_argcount, co_argcount):
name = argnames[i]
if name in remainingkwds_w:
- scope_w.append(remainingkwds_w[name])
+ scope_w[i] = remainingkwds_w[name]
del remainingkwds_w[name]
elif i >= def_first:
- scope_w.append(defaults_w[i-def_first])
+ scope_w[i] = defaults_w[i-def_first]
else:
# error: not enough arguments. Don't signal it immediately
# because it might be related to a problem with */** or
# keyword arguments, which will be checked for below.
missing += 1
+
# collect extra positional arguments into the *vararg
- if varargname is not None:
+ if has_vararg:
if self.w_stararg is None: # common case
- if len(args_w) > co_argcount: # check required by rpython
- starargs_w = args_w[co_argcount:]
+ args_left = co_argcount - blindargs
+ if args_left < 0: # check required by rpython
+ starargs_w = extravarargs
+ if len(args_w):
+ starargs_w.extend(args_w)
+ elif len(args_w) > args_left:
+ starargs_w = args_w[args_left:]
else:
starargs_w = []
- scope_w.append(self.space.newtuple(starargs_w))
+ scope_w[co_argcount] = self.space.newtuple(starargs_w)
else: # shortcut for the non-unpack() case above
- scope_w.append(self.w_stararg)
- elif len(args_w) > co_argcount:
- raise ArgErrCount(self, signature, defaults_w, 0)
+ scope_w[co_argcount] = self.w_stararg
+ elif len(args_w) + blindargs > co_argcount:
+ raise ArgErrCount(len(args_w) + blindargs, num_kwds,
+ (co_argcount, has_vararg, has_kwarg),
+ defaults_w, 0)
# collect extra keyword arguments into the **kwarg
- if kwargname is not None:
+ if has_kwarg:
w_kwds = self.space.newdict([])
if remainingkwds_w:
for key, w_value in remainingkwds_w.items():
self.space.setitem(w_kwds, self.space.wrap(key), w_value)
- scope_w.append(w_kwds)
+ scope_w[co_argcount + has_vararg] = w_kwds
elif remainingkwds_w:
raise ArgErrUnknownKwds(remainingkwds_w)
if missing:
- raise ArgErrCount(self, signature, defaults_w, missing)
- return scope_w
+ raise ArgErrCount(len(args_w) + blindargs, num_kwds,
+ (co_argcount, has_vararg, has_kwarg),
+ defaults_w, missing)
+
### Argument <-> list of w_objects together with "shape" information
@@ -451,36 +494,36 @@
class ArgErrCount(ArgErr):
- def __init__(self, args, signature, defaults_w, missing_args):
+ def __init__(self, nargs, nkwds, signature, defaults_w, missing_args):
self.signature = signature
- self.defaults_w = defaults_w
+ self.num_defaults = len(defaults_w)
self.missing_args = missing_args
- self.num_args = args.num_args()
- self.num_kwds = args.num_kwds()
+ self.num_args = nargs
+ self.num_kwds = nkwds
def getmsg(self, fnname):
args = None
- argnames, varargname, kwargname = self.signature
+ num_args, has_vararg, has_kwarg = self.signature
#args_w, kwds_w = args.unpack()
- if kwargname is not None or (self.num_kwds and self.defaults_w):
+ if has_kwarg or (self.num_kwds and self.num_defaults):
msg2 = "non-keyword "
if self.missing_args:
- required_args = len(argnames) - len(self.defaults_w)
+ required_args = num_args - self.num_defaults
nargs = required_args - self.missing_args
else:
nargs = self.num_args
else:
msg2 = ""
nargs = self.num_args + self.num_kwds
- n = len(argnames)
+ n = num_args
if n == 0:
msg = "%s() takes no %sargument (%d given)" % (
fnname,
msg2,
nargs)
else:
- defcount = len(self.defaults_w)
- if defcount == 0 and varargname is None:
+ defcount = self.num_defaults
+ if defcount == 0 and has_vararg:
msg1 = "exactly"
elif not self.missing_args:
msg1 = "at most"
Modified: pypy/branch/arre-experiments/pypy/interpreter/function.py
==============================================================================
--- pypy/branch/arre-experiments/pypy/interpreter/function.py (original)
+++ pypy/branch/arre-experiments/pypy/interpreter/function.py Wed Jan 18 00:54:39 2006
@@ -9,6 +9,7 @@
from pypy.interpreter.error import OperationError
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.eval import Code
+from pypy.interpreter.pyframe import PyFrame
class Function(Wrappable):
"""A function is a code object captured with some environment:
@@ -34,7 +35,7 @@
def call_args(self, args):
scope_w = args.parse(self.name, self.code.signature(), self.defs_w)
frame = self.code.create_frame(self.space, self.w_func_globals,
- self.closure)
+ self.closure)
frame.setfastscope(scope_w)
return frame.run()
Modified: pypy/branch/arre-experiments/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/arre-experiments/pypy/interpreter/gateway.py (original)
+++ pypy/branch/arre-experiments/pypy/interpreter/gateway.py Wed Jan 18 00:54:39 2006
@@ -312,9 +312,14 @@
del d['setfastscope_UWS_%s' % label]
self.miniglobals['OperationError'] = OperationError
+ self.miniglobals['os'] = os
source = """if 1:
def _run_UWS_%s(self):
- return self.behavior(%s)
+ try:
+ return self.behavior(%s)
+ except MemoryError:
+ os.write(2, 'Fail in _run() of ' + self.b_name + '\\n')
+ raise
\n""" % (label, ','.join(self.run_args))
exec compile2(source) in self.miniglobals, d
d['_run'] = d['_run_UWS_%s' % label]
@@ -327,6 +332,7 @@
def create(self, space, code, w_globals):
newframe = frame_cls(space, code, w_globals)
newframe.behavior = self.behavior
+ newframe.b_name = self.b_name
return newframe
MyBuiltinFrameFactory.__name__ = 'BuiltinFrameFactory_UwS_%s' % label
@@ -339,6 +345,7 @@
factory = frame_uw_factory_cls()
factory.behavior = func
+ factory.b_name = func.__name__
return factory
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 Wed Jan 18 00:54:39 2006
@@ -678,7 +678,7 @@
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:
+ elif False and (oparg >> 8) & 0xff == 0:
# Only positional arguments
nargs = oparg & 0xff
args = ArgumentsFromValuestack(f.space, f.valuestack, nargs)
@@ -686,6 +686,7 @@
try:
w_result = f.space.call_args(w_function, args)
finally:
+ args.valuestack = None
f.valuestack.drop(nargs + 1)
f.valuestack.push(w_result)
# XXX end of hack for performance
More information about the Pypy-commit
mailing list