[pypy-svn] r8418 - pypy/branch/src-typedunwrap/pypy/interpreter
pedronis at codespeak.net
pedronis at codespeak.net
Wed Jan 19 15:15:20 CET 2005
Author: pedronis
Date: Wed Jan 19 15:15:20 2005
New Revision: 8418
Modified:
pypy/branch/src-typedunwrap/pypy/interpreter/gateway.py
Log:
refactored unwrap_spec support for interp2app gateways,
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
'self' is used to specify a self method argument
baseobjspace.W_Root is for wrapped arguments to keep wrapped
argument.Arguments is for a final rest arguments Arguments object
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 Wed Jan 19 15:15:20 2005
@@ -20,8 +20,13 @@
from pypy.tool.cache import Cache
class Signature:
- def __init__(self, func=None, argnames=None, varargname=None, kwargname=None):
+ def __init__(self, func=None, argnames=None, varargname=None,
+ kwargname=None, name = None):
self.func = func
+ if func is not None:
+ self.name = func.__name__
+ else:
+ self.name = name
if argnames is None:
argnames = []
self.argnames = argnames
@@ -44,13 +49,9 @@
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)
-
+def apply_unwrap_spec(unwrap_spec, orig_sig, new_sig, recipes):
for el in unwrap_spec:
- to_unwrap_spec_element[el](orig_sig, new_sig)
-
+ recipes[el](orig_sig, new_sig)
return new_sig
@@ -62,7 +63,6 @@
self.run_args = []
self.through_scope_w = 0
-
def make_frame_class(self):
setfastscope = self.setfastscope
if not setfastscope:
@@ -78,55 +78,33 @@
w_result = self.space.w_None
return w_result
""" % ','.join(self.run_args) in globals(),d
- return type("BuiltinFrame_for_%s" % self.func.__name__,
+ return type("BuiltinFrame_for_%s" % self.name,
(BuiltinFrame,),d)
-def unwrap_spec_space(orig_sig, new_sig):
+def unwrap_spec_check_space(orig_sig, new_sig):
orig_sig.next()
- #
- new_sig.run_args.append('self.space')
-def unwrap_spec_self(orig_sig, new_sig):
+def unwrap_spec_check_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):
+def unwrap_spec_check_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):
+def unwrap_spec_check_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):
+def unwrap_spec_check_starargs(orig_sig, new_sig):
varargname = orig_sig.varargname
assert varargname.endswith('_w'), (
"argument *%s of built-in function %r should end in '_w'" %
@@ -134,22 +112,73 @@
assert new_sig.varargname is None,(
"built-in function %r has conflicting rest args specs" % orig_sig.func)
new_sig.varargname = varargname[:-2]
- #
+
+# recipes for checking interp2app func argumes wrt unwrap_spec
+unwrap_spec_checks = {
+ ObjSpace: unwrap_spec_check_space,
+ 'self': unwrap_spec_check_self,
+ W_Root: unwrap_spec_check_wrapped,
+ Arguments: unwrap_spec_check_arguments,
+ '*': unwrap_spec_check_starargs,
+}
+
+def unwrap_spec_emit_space(orig_sig, new_sig):
+ new_sig.run_args.append('self.space')
+
+def unwrap_spec_emit_self(orig_sig, new_sig):
new_sig.setfastscope.append(
- "self.arg_%s = self.space.unpacktuple(scope_w[%d])" %
- (varargname, new_sig.through_scope_w))
+ "self.self_arg = self.space.unwrap_builtin(scope_w[%d])" %
+ (new_sig.through_scope_w))
new_sig.through_scope_w += 1
- new_sig.run_args.append("*self.arg_%s" % varargname)
+ new_sig.run_args.append("self.self_arg")
+
+def unwrap_spec_emit_wrapped(orig_sig, new_sig):
+ cur = new_sig.through_scope_w
+ new_sig.setfastscope.append(
+ "self.w_arg%d = scope_w[%d]" % (cur,cur))
+ new_sig.through_scope_w += 1
+ new_sig.run_args.append("self.w_arg%d" % cur)
-to_unwrap_spec_element = {
- ObjSpace: unwrap_spec_space,
- 'self': unwrap_spec_self,
- W_Root: unwrap_spec_wrapped,
- Arguments: unwrap_spec_arguments,
- '*': unwrap_spec_starargs,
+def unwrap_spec_emit_arguments(orig_sig, new_sig):
+ cur = new_sig.through_scope_w
+ new_sig.through_scope_w += 2
+ new_sig.setfastscope.append(
+ "self.arguments_arg = "
+ "Arguments.frompacked(self.space,scope_w[%d],scope_w[%d])"
+ % (cur, cur+1))
+ new_sig.run_args.append("self.arguments_arg")
+
+def unwrap_spec_emit_starargs(orig_sig, new_sig):
+ new_sig.setfastscope.append(
+ "self.starargs_arg_w = self.space.unpacktuple(scope_w[%d])" %
+ (new_sig.through_scope_w))
+ new_sig.through_scope_w += 1
+ new_sig.run_args.append("*self.starargs_arg_w")
+
+# recipes for emitting unwrapping code for arguments of a interp2app func
+# wrt a unwrap_spec
+unwrap_spec_emit = {
+ ObjSpace: unwrap_spec_emit_space,
+ 'self': unwrap_spec_emit_self,
+ W_Root: unwrap_spec_emit_wrapped,
+ Arguments: unwrap_spec_emit_arguments,
+ '*': unwrap_spec_emit_starargs,
}
+def make_builtin_frame_class_for_unwrap_spec(unwrap_spec, cache={}):
+ "NOT_RPYTHON"
+ key = tuple(unwrap_spec)
+ try:
+ return cache[key]
+ except KeyError:
+ emit_sig = apply_unwrap_spec(unwrap_spec, None,
+ BuiltinCodeSignature(name=repr(key)),
+ unwrap_spec_emit)
+
+ cache[key] = cls = emit_sig.make_frame_class()
+ return cls
+
class BuiltinCode(eval.Code):
"The code object implementing a built-in (interpreter-level) hook."
@@ -164,15 +193,29 @@
eval.Code.__init__(self, func.__name__)
self.func = func
self.docstring = func.__doc__
- # signature-based hacks: renaming arguments from w_xyz to xyz.
+ # signature-based hacks if unwrap_spec is not specified:
+ # renaming arguments from w_xyz to xyz.
# Currently we enforce the following signature tricks:
# * the first arg must be either 'self' or 'space'
# * 'w_' prefixes for the rest
# * '_w' suffix for the optional '*' argument
# * alternatively a final '__args__' means an Arguments()
# Not exactly a clean approach XXX.
+ # --
+ # 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
+ # 'self' is used to specify a self method argument
+ # baseobjspace.W_Root is for wrapped arguments to keep wrapped
+ # argument.Arguments is for a final rest arguments Arguments object
+
# First extract the signature from the (CPython-level) code object
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 = []
@@ -209,14 +252,16 @@
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))
+ assert not ismethod, ("if unwrap_spec is specified, "
+ "ismethod is not expected")
+ assert not spacearg, ("if unwrap_spec is specified, "
+ "spacearg is not expected")
+
+ orig_sig = Signature(func, argnames, varargname, kwargname)
+
+ new_sig = apply_unwrap_spec(unwrap_spec, orig_sig,
+ Signature(func),
+ unwrap_spec_checks)
self.sig = argnames, varargname, kwargname = new_sig.signature()
@@ -226,7 +271,7 @@
else:
self.maxargs = self.minargs
- self.framecls = new_sig.make_frame_class()
+ self.framecls = make_builtin_frame_class_for_unwrap_spec(unwrap_spec)
def create_frame(self, space, w_globals, closure=None):
return self.framecls(space, self, w_globals)
@@ -245,33 +290,16 @@
# via the interface defined in eval.Frame.
def setfastscope(self, scope_w):
- 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
+ """Subclasses with behavior specific for an unwrap spec are generated"""
+ raise TypeError, "abstract"
def getfastscope(self):
raise OperationError(self.space.w_TypeError,
self.space.wrap("cannot get fastscope of a BuiltinFrame"))
def run(self):
- pass
-## argarray = self.argarray
-## if self.code.spacearg:
-## w_result = self.code.func(self.space, *argarray)
-## else:
-## w_result = self.code.func(*argarray)
-## if w_result is None:
-## w_result = self.space.w_None
-## return w_result
+ """Subclasses with behavior specific for an unwrap spec are generated"""
+ raise TypeError, "abstract"
class Gateway(Wrappable):
More information about the Pypy-commit
mailing list