[pypy-svn] r10263 - in pypy/dist/pypy/translator: . genc
arigo at codespeak.net
arigo at codespeak.net
Sun Apr 3 00:43:42 CEST 2005
Author: arigo
Date: Sun Apr 3 00:43:42 2005
New Revision: 10263
Added:
pypy/dist/pypy/translator/genc/parametric.py (contents, props changed)
pypy/dist/pypy/translator/genc/t_func.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/genc/ctyper.py
pypy/dist/pypy/translator/genc/funcdef.py
pypy/dist/pypy/translator/typer.py
Log:
(Draft) support for the type "function pointer", which allows direct
shortcutting calls between generated functions to be reintroduced.
Uses a parametrization mecanism: for each C type "function taking arguments of
type T1,..,Tn and returning a T", there is a corresponding Python class that
is a dynamically created subclass, using the [] operator:
pypy.translator.genc.t_func.CType_FuncPtr[T1, .., Tn, T]
Modified: pypy/dist/pypy/translator/genc/ctyper.py
==============================================================================
--- pypy/dist/pypy/translator/genc/ctyper.py (original)
+++ pypy/dist/pypy/translator/genc/ctyper.py Sun Apr 3 00:43:42 2005
@@ -3,9 +3,12 @@
"""
from pypy.translator.typer import Specializer, TypeMatch
-from pypy.annotation.model import SomeInteger
+from pypy.annotation.model import SomeInteger, SomePBC
from pypy.translator.genc.t_pyobj import CType_PyObject
from pypy.translator.genc.t_int import CType_Int
+from pypy.translator.genc.t_func import CType_FuncPtr
+import types
+from pypy.interpreter.pycode import CO_VARARGS
class GenCSpecializer(Specializer):
@@ -14,8 +17,42 @@
defaulttypecls = CType_PyObject
specializationtable = [
- ## op specialized op arg types concrete return type
- ('add', 'int_add', TInt, TInt, CType_Int),
- ('sub', 'int_sub', TInt, TInt, CType_Int),
- ('is_true', 'int_is_true', TInt, CType_Int),
+ ## op specialized op arg types concrete return type
+ ('add', 'int_add', TInt, TInt, CType_Int),
+ ('inplace_add', 'int_add', TInt, TInt, CType_Int),
+ ('sub', 'int_sub', TInt, TInt, CType_Int),
+ ('inplace_sub', 'int_sub', TInt, TInt, CType_Int),
+ ('is_true', 'int_is_true', TInt, CType_Int),
]
+
+ def annotation2typecls(self, s_value):
+ besttype = Specializer.annotation2typecls(self, s_value)
+ if besttype is None:
+
+ if isinstance(s_value, SomePBC):
+ # XXX! must be somehow unified with bookkeeper.pycall()!
+ # XXX for now, we support the very simplest case only.
+ if (s_value.is_constant() and
+ isinstance(s_value.const, types.FunctionType) and
+ not (s_value.const.func_code.co_flags & CO_VARARGS) and
+ s_value.const in self.annotator.translator.flowgraphs):
+
+ graph = self.annotator.translator.flowgraphs[s_value.const]
+ args_ct = [self.setbesttype(a) for a in graph.getargs()]
+ res_ct = self.setbesttype(graph.getreturnvar())
+ key = tuple(args_ct + [res_ct])
+ besttype = CType_FuncPtr[key]
+
+ return besttype
+
+ def getspecializedop(self, op, bindings):
+ if op.opname == 'simple_call':
+ s_callable = self.annotator.binding(op.args[0], True)
+ if s_callable is not None:
+ ct = self.annotation2typecls(s_callable)
+ if ct is not None and issubclass(ct, CType_FuncPtr):
+ args_typecls = [ct]
+ args_typecls += ct.args_typecls
+ return 'direct_call', args_typecls, ct.return_typecls
+
+ return Specializer.getspecializedop(self, op, bindings)
Modified: pypy/dist/pypy/translator/genc/funcdef.py
==============================================================================
--- pypy/dist/pypy/translator/genc/funcdef.py (original)
+++ pypy/dist/pypy/translator/genc/funcdef.py Sun Apr 3 00:43:42 2005
@@ -475,6 +475,11 @@
args = [arg.compute() for arg in args]
return 'OP_CALL_ARGS((%s), %s, %s)' % (', '.join(args), r, err)
+ def OP_DIRECT_CALL(self, args, r, err):
+ args = [arg.compute() for arg in args]
+ return '%s = %s(%s); if (PyErr_Occurred()) FAIL(%s)' % (
+ r, args[0], ', '.join(args[1:]), err)
+
# ____________________________________________________________
class lazy:
Added: pypy/dist/pypy/translator/genc/parametric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/parametric.py Sun Apr 3 00:43:42 2005
@@ -0,0 +1,41 @@
+import types
+
+
+class parametrictype(type):
+ """The metaclass of parametric type classes."""
+
+ def __getitem__(cls, key):
+ if '_parametrizedinstances_' not in cls.__dict__:
+ cls._parametrizedinstances_ = {}
+ elif cls._parametrizedinstances_ is None:
+ raise TypeError, "'%s' is already specialized" % cls.__name__
+ try:
+ return cls._parametrizedinstances_[key]
+ except KeyError:
+ keyrepr = recrepr(key)
+ if keyrepr.startswith('(') and keyrepr.endswith(')') and key != ():
+ keyrepr = keyrepr[1:-1]
+ newname = '%s[%s]' % (cls.__name__, keyrepr)
+ CType_Parametrized = type(cls)(newname, (cls,), {
+ '_parametrizedinstances_': None,
+ '__module__': cls.__module__,
+ })
+ cls._parametrizedinstances_[key] = CType_Parametrized
+ for basecls in CType_Parametrized.__mro__:
+ raw = basecls.__dict__.get('__initsubclass__')
+ if isinstance(raw, types.FunctionType):
+ raw(CType_Parametrized, key) # call it as a class method
+ return CType_Parametrized
+
+
+def recrepr(key):
+ if isinstance(key, tuple):
+ items = [recrepr(x) for x in key]
+ if len(items) == 1:
+ return '(%s,)' % (items[0],)
+ else:
+ return '(%s)' % (', '.join(items),)
+ try:
+ return key.__name__
+ except AttributeError:
+ return repr(key)
Added: pypy/dist/pypy/translator/genc/t_func.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/t_func.py Sun Apr 3 00:43:42 2005
@@ -0,0 +1,19 @@
+from pypy.translator.genc.parametric import parametrictype
+
+
+class CType_FuncPtr:
+ __metaclass__ = parametrictype
+
+ def __initsubclass__(cls, key):
+ cls.args_typecls = key[:-1]
+ cls.return_typecls = key[-1]
+ arglist = [tc.ctypetemplate % ('',) for tc in cls.args_typecls]
+ argtemplate = ', '.join(arglist or ['void'])
+ header = '(*%s)(' + argtemplate + ')'
+ cls.ctypetemplate = cls.return_typecls.ctypetemplate % (header,)
+
+ def __init__(self, genc):
+ self.genc = genc
+
+ def nameof(self, func, debug=None):
+ return self.genc.getfuncdef(func).fast_name
Modified: pypy/dist/pypy/translator/typer.py
==============================================================================
--- pypy/dist/pypy/translator/typer.py (original)
+++ pypy/dist/pypy/translator/typer.py Sun Apr 3 00:43:42 2005
@@ -50,13 +50,16 @@
besttype = self.defaulttypecls
s_value = self.annotator.binding(a, True)
if s_value is not None:
- for tmatch in self.typematches:
- if tmatch.s_type.contains(s_value):
- besttype = tmatch.type_cls
- break
+ besttype = self.annotation2typecls(s_value) or besttype
self.settype(a, besttype)
return besttype
+ def annotation2typecls(self, s_value):
+ for tmatch in self.typematches:
+ if tmatch.s_type.contains(s_value):
+ return tmatch.type_cls
+ return None
+
def convertvar(self, v, type_cls):
"""Get the operation(s) needed to convert 'v' to the given type."""
ops = []
@@ -111,6 +114,7 @@
# look for a specialized version of the current operation
opname2, argtypes, restypecls = self.getspecializedop(op, bindings)
+ assert len(argtypes) == len(args)
# type-convert the input arguments
for i in indices:
More information about the Pypy-commit
mailing list