[pypy-svn] r23520 - in pypy/dist/pypy: annotation rpython rpython/memory rpython/test

arigo at codespeak.net arigo at codespeak.net
Mon Feb 20 18:25:30 CET 2006


Author: arigo
Date: Mon Feb 20 18:25:28 2006
New Revision: 23520

Modified:
   pypy/dist/pypy/annotation/annrpython.py
   pypy/dist/pypy/rpython/annlowlevel.py
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/test/test_normalizecalls.py
Log:
(pedronis, arigo)

Put the mixed-level helper logic in a class.  This encapsulates the delayed
annotation in a less magical way, and it also makes the usage more natural.
The motivation is to allow gendirectcalls() between mix-level helpers.

Fixed test_normalizecalls, which we forgot last time.



Modified: pypy/dist/pypy/annotation/annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/annrpython.py	(original)
+++ pypy/dist/pypy/annotation/annrpython.py	Mon Feb 20 18:25:28 2006
@@ -104,7 +104,8 @@
             self.added_blocks = {}
             desc = self.bookkeeper.getdesc(function)
             graph = desc.specialize(args_s)
-            s = self.build_graph_types(graph, args_s, complete_now=complete_now)
+            if complete_now:
+                self.build_graph_types(graph, args_s)
             # invoke annotation simplifications for the new blocks
             self.simplify(block_subset=self.added_blocks)
         finally:

Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py	(original)
+++ pypy/dist/pypy/rpython/annlowlevel.py	Mon Feb 20 18:25:28 2006
@@ -112,19 +112,45 @@
         return funcdesc.cachedgraph(key, alt_name=valid_identifier(alt_name))        
 
 
-def pre_annotate_mixlevel_helper(rtyper, ll_function, args_s, s_result):
-    # get the graph of the mix-level helper ll_function and prepare it for
-    # being annotated.  Annotation and RTyping should be done in a single shot
-    # at the end with finish_mixlevel_helpers().
-    pol = MixLevelAnnotatorPolicy(rtyper)
-    graph = rtyper.annotator.annotate_helper(ll_function, args_s, policy=pol,
-                                             complete_now=False)
-    rtyper.annotator.setbinding(graph.getreturnvar(), s_result)
-    return graph
+class MixLevelHelperAnnotator:
 
-def finish_mixlevel_helpers(rtyper):
-    pol = MixLevelAnnotatorPolicy(rtyper)
-    rtyper.annotator.complete_helpers(pol)
-    # XXX maybe check that the promized s_results are correct?
-    rtyper.type_system.perform_normalizations(rtyper)
-    rtyper.specialize_more_blocks()
+    def __init__(self, rtyper):
+        self.rtyper = rtyper
+        self.policy = MixLevelAnnotatorPolicy(rtyper)
+        self.pending = []     # list of (graph, args_s, s_result)
+
+    def getgraph(self, ll_function, args_s, s_result):
+        # get the graph of the mix-level helper ll_function and prepare it for
+        # being annotated.  Annotation and RTyping should be done in a single shot
+        # at the end with finish().
+        graph = self.rtyper.annotator.annotate_helper(ll_function, args_s,
+                                                      policy = self.policy,
+                                                      complete_now = False)
+        for v_arg, s_arg in zip(graph.getargs(), args_s):
+            self.rtyper.annotator.setbinding(v_arg, s_arg)
+        self.rtyper.annotator.setbinding(graph.getreturnvar(), s_result)
+        self.pending.append((graph, args_s, s_result))
+        return graph
+
+    def finish(self):
+        # push all the graphs into the annotator's pending blocks dict at once
+        rtyper = self.rtyper
+        ann = rtyper.annotator
+        for graph, args_s, s_result in self.pending:
+            # mark the return block as already annotated, because the return var
+            # annotation was forced in getgraph() above.  This prevents temporary
+            # less general values reaching the return block from crashing the
+            # annotator (on the assert-that-new-binding-is-not-less-general).
+            ann.annotated[graph.returnblock] = graph
+            ann.build_graph_types(graph, args_s, complete_now=False)
+        ann.complete_helpers(self.policy)
+        for graph, args_s, s_result in self.pending:
+            s_real_result = ann.binding(graph.getreturnvar())
+            if s_real_result != s_result:
+                raise Exception("wrong annotation for the result of %r:\n"
+                                "originally specified: %r\n"
+                                " found by annotating: %r" %
+                                (graph, s_result, s_real_result))
+        rtyper.type_system.perform_normalizations(rtyper)
+        rtyper.specialize_more_blocks()
+        del self.pending[:]

Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Mon Feb 20 18:25:28 2006
@@ -666,26 +666,22 @@
             gcdata.root_stack_top = top
             return result
 
-        frameworkgc_setup_graph = self.mixlevel_helper(
-            frameworkgc_setup, [], annmodel.s_ImpossibleValue)
-        push_root_graph = self.mixlevel_helper(push_root,
-                                               [annmodel.SomeAddress()],
-                                               annmodel.s_ImpossibleValue)
-        pop_root_graph = self.mixlevel_helper(pop_root, [],
-                                              annmodel.SomeAddress())
-        annlowlevel.finish_mixlevel_helpers(self.translator.rtyper)
+        annhelper = annlowlevel.MixLevelHelperAnnotator(self.translator.rtyper)
+        frameworkgc_setup_graph = annhelper.getgraph(frameworkgc_setup, [],
+                                                     annmodel.s_None)
+        push_root_graph = annhelper.getgraph(push_root,
+                                             [annmodel.SomeAddress()],
+                                             annmodel.s_None)
+        pop_root_graph = annhelper.getgraph(pop_root, [],
+                                            annmodel.SomeAddress())
+        annhelper.finish()   # at this point, annotate all mix-level helpers
         self.frameworkgc_setup_ptr = self.graph2funcptr(frameworkgc_setup_graph,
                                                         attach_empty_cleanup=True)
         self.push_root_ptr = self.graph2funcptr(push_root_graph)
         self.pop_root_ptr  = self.graph2funcptr(pop_root_graph)
 
-    def mixlevel_helper(self, helper, args_s, result_s):
-        graph = annlowlevel.pre_annotate_mixlevel_helper(self.translator.rtyper,
-                                                         helper, args_s, result_s)
-        self.seen_graphs[graph] = True
-        return graph
-
     def graph2funcptr(self, graph, attach_empty_cleanup=False):
+        self.seen_graphs[graph] = True
         if attach_empty_cleanup:
             MinimalGCTransformer(self.translator).transform_graph(graph)
         return const_funcptr_fromgraph(graph)

Modified: pypy/dist/pypy/rpython/test/test_normalizecalls.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_normalizecalls.py	(original)
+++ pypy/dist/pypy/rpython/test/test_normalizecalls.py	Mon Feb 20 18:25:28 2006
@@ -10,9 +10,11 @@
 
 class TestNormalize(object):
 
-    def rtype(self, fn, argtypes=[]):
+    def rtype(self, fn, argtypes, resulttype):
         t = TranslationContext()
-        t.buildannotator().build_types(fn, argtypes)
+        a = t.buildannotator()
+        s = a.build_types(fn, argtypes)
+        assert s == a.typeannotation(resulttype)
         typer = t.buildrtyper()
         typer.specialize()
         #t.view()
@@ -44,7 +46,7 @@
         #
         # But all lines get compressed to a single line.
 
-        translator = self.rtype(g, [int])
+        translator = self.rtype(g, [int], annmodel.s_None)
         f1graph = graphof(translator, f1)
         f2graph = graphof(translator, f2)
         s_l1 = translator.annotator.binding(f1graph.getargs()[0])
@@ -65,7 +67,7 @@
                 f = f2
             f(a=5, b=6)
 
-        translator = self.rtype(g, [int])
+        translator = self.rtype(g, [int], annmodel.s_None)
         f1graph = graphof(translator, f1)
         f2graph = graphof(translator, f2)
         assert len(f1graph.getargs()) == 2
@@ -104,7 +106,7 @@
             except ValueError:
                 return -1
 
-        translator = self.rtype(dummyfn, [int, int])
+        translator = self.rtype(dummyfn, [int, int], int)
         add_one_graph = graphof(translator, add_one)
         oups_graph    = graphof(translator, oups)
         assert add_one_graph.getreturnvar().concretetype == lltype.Signed
@@ -120,7 +122,7 @@
                 return 1
         class Sub2(Base):
             def fn(self):
-                return 2
+                return -2
         def dummyfn(n):
             if n == 1:
                 x = Sub1()
@@ -128,7 +130,7 @@
                 x = Sub2()
             return x.fn()
 
-        translator = self.rtype(dummyfn, [int])
+        translator = self.rtype(dummyfn, [int], int)
         base_graph = graphof(translator, Base.fn.im_func)
         sub1_graph = graphof(translator, Sub1.fn.im_func)
         sub2_graph = graphof(translator, Sub2.fn.im_func)
@@ -140,11 +142,11 @@
         res = llinterp.eval_graph(graphof(translator, dummyfn), [1])
         assert res == 1
         res = llinterp.eval_graph(graphof(translator, dummyfn), [2])
-        assert res == 2
+        assert res == -2
 
 class TestNormalizeAfterTheFact(TestNormalize):
 
-    def rtype(self, fn, argtypes=[]):
+    def rtype(self, fn, argtypes, resulttype):
         class Base:
             def fn(self):
                 raise NotImplementedError
@@ -168,12 +170,14 @@
         typer.specialize()
         #t.view()
 
+        s_result = a.typeannotation(resulttype)
+
         from pypy.rpython import annlowlevel
-        # normalize and rtype fn after the fact
-        graph = annlowlevel.annotate_mixlevel_helper(typer, fn, [a.typeannotation(argtype) for argtype in argtypes])
-        from pypy.rpython.normalizecalls import perform_normalizations
-        perform_normalizations(typer)
-        typer.specialize_more_blocks()
+        # annotate, normalize and rtype fn after the fact
+        annhelper = annlowlevel.MixLevelHelperAnnotator(typer)               
+        graph = annhelper.getgraph(fn, [a.typeannotation(argtype) for argtype in argtypes],
+                                   s_result)
+        annhelper.finish()
 
         # sanity check prefn
         llinterp = LLInterpreter(typer)



More information about the Pypy-commit mailing list