[pypy-svn] r70556 - in pypy/branch/separate-compilation/pypy/translator/c: . test
afa at codespeak.net
afa at codespeak.net
Wed Jan 13 14:52:39 CET 2010
Author: afa
Date: Wed Jan 13 14:52:37 2010
New Revision: 70556
Modified:
pypy/branch/separate-compilation/pypy/translator/c/separate.py
pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py
Log:
Expose the constructor directly.
Next step: access to struct members
Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py
==============================================================================
--- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original)
+++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Wed Jan 13 14:52:37 2010
@@ -1,23 +1,36 @@
from pypy.annotation import model, description
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.objectmodel import instantiate
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.typesystem import getfunctionptr
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rpython.extregistry import ExtRegistryEntry
-
+import py
import types
+def make_wrapper_for_constructor(cls, name):
+ nbargs = len(cls.__init__.argtypes)
+ args = ', '.join(['arg%d' % d for d in range(nbargs)])
+
+ source = py.code.Source(r"""
+ def wrapper(%s):
+ obj = instantiate(cls)
+ obj.__init__(%s)
+ return obj
+ """ % (args, args))
+ miniglobals = {'cls': cls, 'instantiate': instantiate}
+ exec source.compile() in miniglobals
+ wrapper = miniglobals['wrapper']
+ wrapper._annspecialcase_ = 'specialize:ll'
+ wrapper._always_inline_ = True
+ return func_with_new_name(wrapper, name)
+
def annotate_exported_functions(annotator, exports):
bk = annotator.bookkeeper
- # annotate functions with signatures
- for funcname, func in exports.items():
- if hasattr(func, 'argtypes'):
- annotator.build_types(func, func.argtypes,
- complete_now=False)
# annotate classes
- for funcname, cls in exports.items():
+ for clsname, cls in exports.items():
if not isinstance(cls, (type, types.ClassType)):
continue
desc = bk.getdesc(cls)
@@ -26,11 +39,17 @@
if isinstance(s_init, model.SomeImpossibleValue):
continue
- argtypes = (model.SomeInstance(classdef),)
- argtypes += tuple(cls.__init__.argtypes)
- annotator.build_types(cls.__init__.im_func, argtypes,
+ wrapper = make_wrapper_for_constructor(cls, clsname)
+ exports[clsname] = wrapper
+
+ annotator.build_types(wrapper, cls.__init__.argtypes,
complete_now=False)
+ # annotate functions with signatures
+ for funcname, func in exports.items():
+ if hasattr(func, 'argtypes'):
+ annotator.build_types(func, func.argtypes,
+ complete_now=False)
annotator.complete()
# ensure that functions without signature are not constant-folded
@@ -51,14 +70,15 @@
bk = annotator.bookkeeper
exported_funcptr = {}
- for funcname, func in exports.items():
- desc = bk.getdesc(func)
- if not isinstance(desc, description.FunctionDesc):
+ for itemname, item in exports.items():
+ desc = bk.getdesc(item)
+ if isinstance(desc, description.FunctionDesc):
+ graph = desc.getuniquegraph()
+ funcptr = getfunctionptr(graph)
+ elif isinstance(desc, description.ClassDesc):
continue
- graph = desc.getuniquegraph()
- funcptr = getfunctionptr(graph)
- exported_funcptr[funcname] = funcptr
+ exported_funcptr[itemname] = funcptr
return exported_funcptr
def make_import_module(builder):
Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py
==============================================================================
--- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original)
+++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 13 14:52:37 2010
@@ -7,6 +7,25 @@
import sys, os
class TestSeparation:
+ def setup_method(self, method):
+ class S:
+ @export(float)
+ def __init__(self, x):
+ self.x = x
+
+ # functions exported from the 'first' module
+ @export(float)
+ def newS(x):
+ return S(x)
+
+ @export(S, S, int)
+ def f2S(s, t, v):
+ return s.x + t.x + v
+
+ self.S = S
+ self.newS = newS
+ self.f2S = f2S
+
def compile_function(self, func, argtypes):
t = TranslationContext()
t.buildannotator().build_types(func, argtypes)
@@ -92,16 +111,8 @@
assert c_fn() == 42.5
def test_pass_structure(self):
- class S:
- @export(float)
- def __init__(self, x):
- self.x = x
-
- # function exported from the 'first' module
- @export(S, S, int)
- def f(s, t, v):
- return s.x + t.x + v
- firstmodule = self.compile_separated("first", f=f, S=S)
+ firstmodule = self.compile_separated("first", f=self.f2S, S=self.S)
+ S = self.S
# call it from a function compiled in another module
@export()
@@ -123,26 +134,15 @@
assert c_fn() == 73.5
def test_create_structure(self):
- class S:
- @export(float)
- def __init__(self, x):
- self.x = x
-
- # functions exported from the 'first' module
- @export(float)
- def newS(x):
- return S(x)
-
- @export(S)
- def f(s):
- return s.x + 1.5
- firstmodule = self.compile_separated("first", newS=newS, f=f)
+ firstmodule = self.compile_separated(
+ "first", newS=self.newS, S=self.S, f=self.f2S)
# call them from a function compiled in another module
@export()
def g():
s = firstmodule.newS(41.0)
- return firstmodule.f(s)
+ t = firstmodule.S(25.5)
+ return firstmodule.f(s, t, 7)
secondmodule = self.compile_separated("second", g=g)
def fn():
@@ -152,7 +152,7 @@
filepath = os.path.dirname(firstmodule.__file__)
os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH'])
- assert fn() == 42.5
+ assert fn() == 73.5
c_fn = self.compile_function(fn, [])
- assert c_fn() == 42.5
+ assert c_fn() == 73.5
More information about the Pypy-commit
mailing list