[pypy-svn] r18427 - in pypy/dist/pypy: rpython rpython/module translator translator/c/src translator/c/test

adim at codespeak.net adim at codespeak.net
Tue Oct 11 19:00:51 CEST 2005


Author: adim
Date: Tue Oct 11 19:00:46 2005
New Revision: 18427

Modified:
   pypy/dist/pypy/rpython/extfunctable.py
   pypy/dist/pypy/rpython/module/ll_stackless.py
   pypy/dist/pypy/rpython/objectmodel.py
   pypy/dist/pypy/translator/c/src/ll_stackless.h
   pypy/dist/pypy/translator/c/test/test_standalone.py
   pypy/dist/pypy/translator/transform.py
Log:
(arigo, adim)
automatically add stack_unwind() when recursion is detected


Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py	(original)
+++ pypy/dist/pypy/rpython/extfunctable.py	Tue Oct 11 19:00:46 2005
@@ -210,6 +210,7 @@
 from pypy.rpython import objectmodel
 declare(objectmodel.stack_frames_depth, int, 'll_stackless/stack_frames_depth')
 declare(objectmodel.stack_too_big, bool, 'll_stackless/stack_too_big')
+declare(objectmodel.auto_stack_unwind, noneannotation, 'll_stackless/auto_stack_unwind')
 
 # ___________________________________________________________
 # the exceptions that can be implicitely raised by some operations

Modified: pypy/dist/pypy/rpython/module/ll_stackless.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_stackless.py	(original)
+++ pypy/dist/pypy/rpython/module/ll_stackless.py	Tue Oct 11 19:00:46 2005
@@ -12,3 +12,7 @@
 def ll_stackless_stack_too_big():
     return objectmodel.stack_too_big()
 ll_stackless_stack_too_big.suggested_primitive = True
+
+def ll_stackless_auto_stack_unwind():
+    if ll_stackless_stack_too_big():
+        ll_stackless_stack_unwind()

Modified: pypy/dist/pypy/rpython/objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/objectmodel.py	(original)
+++ pypy/dist/pypy/rpython/objectmodel.py	Tue Oct 11 19:00:46 2005
@@ -43,9 +43,13 @@
 
 def stack_frames_depth():
     return len(inspect.stack())
+
 def stack_too_big():
     return False
 
+def auto_stack_unwind():
+    if stack_too_big():
+        stack_unwind()
 # ____________________________________________________________
 
 

Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_stackless.h	(original)
+++ pypy/dist/pypy/translator/c/src/ll_stackless.h	Tue Oct 11 19:00:46 2005
@@ -115,6 +115,7 @@
   }
   return 1;
 }
+
 #include "slp_state_decoding.h"
 
 

Modified: pypy/dist/pypy/translator/c/test/test_standalone.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_standalone.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_standalone.py	Tue Oct 11 19:00:46 2005
@@ -1,5 +1,6 @@
 from pypy.translator.translator import Translator
-from pypy.translator.tool.cbuild import build_executable 
+from pypy.translator.tool.cbuild import build_executable
+from pypy.translator.transform import insert_stackcheck
 from pypy.annotation.model import SomeList, SomeString
 from pypy.annotation.listdef import ListDef
 from pypy.rpython.objectmodel import stack_unwind, stack_frames_depth, stack_too_big
@@ -111,34 +112,39 @@
 
 
     
-def wrap_stackless_function(fn):
+def wrap_stackless_function(fn, stackcheck=False):
     def entry_point(argv):
         os.write(1, str(fn())+"\n")
         return 0
 
     t = Translator(entry_point)
     s_list_of_strings = SomeList(ListDef(None, SomeString()))
-    t.annotate([s_list_of_strings])
+    ann = t.annotate([s_list_of_strings])
+    if stackcheck:
+        insert_stackcheck(ann)
     t.specialize()
     cbuilder = t.cbuilder(standalone=True)
     cbuilder.stackless = True
     cbuilder.generate_source()
     cbuilder.compile() 
-    data = cbuilder.cmdexec('')
-    return data
+    return cbuilder.cmdexec('')
 
 def test_stack_unwind():
-    def entry_point(argv):
+    def f():
         stack_unwind()
-        return 0
+        return 42
 
-    t = Translator(entry_point)
-    s_list_of_strings = SomeList(ListDef(None, SomeString()))
-    t.annotate([s_list_of_strings])
-    t.specialize()
-    cbuilder = t.cbuilder(standalone=True)
-    cbuilder.stackless = True
-    cbuilder.generate_source()
-    cbuilder.compile()
-    data = cbuilder.cmdexec('')
-    return cbuilder.cmdexec('')
+    data = wrap_stackless_function(f)
+    assert int(data.strip()) == 42
+
+    
+def test_auto_stack_unwind():
+    def f(n):
+        if n == 1:
+            return 1 
+        return (n+f(n-1)) % 1291
+
+    def fn():
+        return f(10**6)
+    data = wrap_stackless_function(fn, stackcheck=True)
+    assert int(data.strip()) == 704

Modified: pypy/dist/pypy/translator/transform.py
==============================================================================
--- pypy/dist/pypy/translator/transform.py	(original)
+++ pypy/dist/pypy/translator/transform.py	Tue Oct 11 19:00:46 2005
@@ -14,7 +14,7 @@
 from pypy.translator.annrpython import CannotSimplify
 from pypy.annotation import model as annmodel
 from pypy.annotation.specialize import MemoTable
-
+from pypy.rpython.objectmodel import auto_stack_unwind
 
 def checkgraphs(self, blocks):
     seen = {}
@@ -187,6 +187,30 @@
                                 else:
                                     op.opname = intern('call_specialcase')
 
+def insert_stackcheck(ann):
+    from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles
+    edges = []
+    for callposition, (caller, callee) in ann.translator.callgraph.items():
+        edge = Edge(caller, callee)
+        edge.callposition = callposition
+        edges.append(edge)
+    edgedict = make_edge_dict(edges)
+    for edge in break_cycles(edgedict, edgedict):
+        caller = edge.source
+        _, _, call_tag = edge.callposition
+        if call_tag:
+            _, caller_block, _ = call_tag
+        else:
+            ann.warning("cycle detected but no information on where to insert "
+                        "auto_stack_unwind()")
+            continue
+        # caller block found, insert auto_stack_unwind()
+        v = Variable()
+        # push annotation on v
+        ann.setbinding(v, annmodel.SomeImpossibleValue())
+        unwind_op = SpaceOperation('simple_call', [Constant(auto_stack_unwind)], v)
+        caller_block.operations.insert(0, unwind_op)
+
 default_extra_passes = [
     transform_specialization,
     transform_allocate,



More information about the Pypy-commit mailing list