Author: Armin Rigo <[email protected]>
Branch: rpython-hash
Changeset: r89827:7b2e8a4c0b4b
Date: 2017-01-29 17:45 +0100
http://bitbucket.org/pypy/pypy/changeset/7b2e8a4c0b4b/

Log:    A mechanism to add a function to call at program start-up. This
        version uses different trade-offs than call_initial_function() from
        translator/unsimplify.py. Notably, it ensures it is called even if
        the main entry point is not (embedding).

diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -513,6 +513,9 @@
     # __________________________________________________________
     # misc LL operation implementations
 
+    def op_call_at_startup(self, *args):
+        pass
+
     def op_debug_view(self, *ll_objects):
         from rpython.translator.tool.lltracker import track
         track(*ll_objects)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py 
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -539,6 +539,7 @@
     'decode_arg_def':       LLOp(canraise=(Exception,)),
     'getslice':             LLOp(canraise=(Exception,)),
     'check_and_clear_exc':  LLOp(),
+    'call_at_startup':      LLOp(),
 
     'threadlocalref_addr':  LLOp(),                   # get (or make) addr of 
tl
     'threadlocalref_get':   LLOp(sideeffects=False),  # read field (no check)
diff --git a/rpython/translator/c/database.py b/rpython/translator/c/database.py
--- a/rpython/translator/c/database.py
+++ b/rpython/translator/c/database.py
@@ -60,6 +60,7 @@
         self.completed = False
 
         self.instrument_ncounter = 0
+        self.call_at_startup = set()
 
     def gettypedefnode(self, T, varlength=None):
         if varlength is None:
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -940,3 +940,9 @@
                 cdecl(typename, ''),
                 self.expr(op.args[0]),
                 self.expr(op.result))
+
+    def OP_CALL_AT_STARTUP(self, op):
+        assert isinstance(op.args[0], Constant)
+        func = self.expr(op.args[0])
+        self.db.call_at_startup.add(func)
+        return '/* call_at_startup %s */' % (func,)
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -822,6 +822,9 @@
             for line in lines:
                 print >> f, '\t'+line
 
+    for extra in database.call_at_startup:
+        print >> f, '\t%s();\t/* call_at_startup */' % (extra,)
+
     print >> f, '}'
 
 def commondefs(defines):
diff --git a/rpython/translator/c/test/test_standalone.py 
b/rpython/translator/c/test/test_standalone.py
--- a/rpython/translator/c/test/test_standalone.py
+++ b/rpython/translator/c/test/test_standalone.py
@@ -1062,6 +1062,28 @@
         out = cbuilder.cmdexec('')
         assert out.strip() == expected
 
+    def test_call_at_startup(self):
+        from rpython.rtyper.lltypesystem import lltype
+        from rpython.rtyper.lltypesystem.lloperation import llop
+        from rpython.rtyper.annlowlevel import llhelper
+        class State:
+            seen = 0
+        state = State()
+        def startup():
+            state.seen += 1
+        F = lltype.Ptr(lltype.FuncType([], lltype.Void))
+        def entry_point(argv):
+            state.seen += 100
+            assert state.seen == 101
+            print 'ok'
+            ll = llhelper(F, startup)
+            llop.call_at_startup(lltype.Void, ll)
+            return 0
+
+        t, cbuilder = self.compile(entry_point)
+        out = cbuilder.cmdexec('')
+        assert out.strip() == 'ok'
+
 
 class TestMaemo(TestStandalone):
     def setup_class(cls):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to