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