[pypy-commit] pypy sepcomp2: No need to call functions and classes through the "import module",

amauryfa noreply at buildbot.pypy.org
Wed Feb 22 21:19:42 CET 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: sepcomp2
Changeset: r52773:8c0e4f28c231
Date: 2012-02-22 21:17 +0100
http://bitbucket.org/pypy/pypy/changeset/8c0e4f28c231/

Log:	No need to call functions and classes through the "import module",
	the original RPython objects are correctly annotated to redirect
	calls.

diff --git a/pypy/translator/c/exportinfo.py b/pypy/translator/c/exportinfo.py
--- a/pypy/translator/c/exportinfo.py
+++ b/pypy/translator/c/exportinfo.py
@@ -1,9 +1,11 @@
 from pypy.annotation import model, description
+from pypy.annotation.signature import annotation
 from pypy.rpython.typesystem import getfunctionptr
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rpython.controllerentry import (
     Controller, ControllerEntry, SomeControlledInstance)
 from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.rpython.extfunc import ExtFuncEntry
 from pypy.rlib.objectmodel import instantiate, specialize
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.tool.sourcetools import func_with_new_name
@@ -67,6 +69,19 @@
         self.external_name = builder.db.get(funcptr)
         self.functype = lltype.typeOf(funcptr)
 
+    def register_external(self, eci):
+        llimpl = self.make_llexternal_function(eci)
+        functype = self.functype
+        class FuncEntry(ExtFuncEntry):
+            _about_ = self.func
+            name = self.name
+            def normalize_args(self, *args_s):
+                return args_s    # accept any argument unmodified
+            signature_result = annotation(functype.TO.RESULT)
+            lltypeimpl = staticmethod(llimpl)
+            
+        return llimpl
+
     def make_llexternal_function(self, eci):
         functype = self.functype
         imported_func = rffi.llexternal(
@@ -244,7 +259,7 @@
             __file__ = builder.so_name
         mod = Module()
         for name, func_info in self.functions.items():
-            funcptr = func_info.make_llexternal_function(import_eci)
+            funcptr = func_info.register_external(import_eci)
             setattr(mod, name, funcptr)
         for name, class_info in self.classes.items():
             structptr = class_info.make_controller(mod)
diff --git a/pypy/translator/c/test/test_export.py b/pypy/translator/c/test/test_export.py
--- a/pypy/translator/c/test/test_export.py
+++ b/pypy/translator/c/test/test_export.py
@@ -3,6 +3,8 @@
 from pypy.translator.c.dlltool import CLibraryBuilder
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.translator.backendopt.all import backend_optimizations
+from pypy.rlib.objectmodel import we_are_translated
+from pypy.rpython.test.test_llinterp import interpret
 import sys
 import types
 
@@ -101,3 +103,25 @@
             # Bad argument type, should not translate
             return firstmodule.f(1, 2, 3)
         raises(TypeError, self.compile_module, "third", g2=g2)
+
+    def test_without_module_container(self):
+        # It's not necessary to fetch the functions from some
+        # container, the RPython calls are automatically redirected.
+        class Struct:
+            @export(float)
+            def __init__(self, x):
+                self.x = x + 23.4
+        @export(Struct, Struct, int)
+        def f(s, t, v):
+            assert we_are_translated()
+            return s.x + t.x + v
+        self.compile_module("first", f=f, Struct=Struct)
+        
+        @export()
+        def g():
+            s = Struct(3.0)
+            t = Struct(5.5)
+            return f(s, t, 7)
+        mod = self.compile_module("second", g=g)
+        assert mod.g() == 62.3
+        # XXX How can we check that the code of f() was not translated again?


More information about the pypy-commit mailing list