[pypy-svn] r36571 - in pypy/dist/pypy: jit/codegen/llgraph jit/codegen/llgraph/test rpython rpython/lltypesystem

pedronis at codespeak.net pedronis at codespeak.net
Fri Jan 12 14:14:50 CET 2007


Author: pedronis
Date: Fri Jan 12 14:14:46 2007
New Revision: 36571

Modified:
   pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
   pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
   pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
Log:
(arre, pedronis)

add support for reading vars out of runtime frames for llinterp and codegen/llgraph



Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py	Fri Jan 12 14:14:46 2007
@@ -543,3 +543,35 @@
 #setannotation(placeholder,    s_ConstOrVar, specialize_as_constant=True)
 
 setannotation(show_incremental_progress, None)
+
+# read frame var support
+
+def read_frame_var(T, base, info, index):
+    vars = info._obj.vars
+    v = vars[index]
+    if isinstance(v, flowmodel.Constant):
+        val = v.value
+    else:
+        llframe = base.ptr
+        val = llframe.bindings[v]
+    assert lltype.typeOf(val) == T
+    return val
+        
+
+class ReadFrameVarEntry(ExtRegistryEntry):
+        "Annotation and specialization for calls to 'func'."
+        _about_ = read_frame_var
+
+        def compute_result_annotation(self, *args_s):
+            T = args_s[0].const
+            return annmodel.lltype_to_annotation(T)
+
+        # specialize as direct_call
+        def specialize_call(self, hop):
+            FUNCTYPE = lltype.FuncType([r.lowleveltype for r in hop.args_r],
+                                       hop.r_result.lowleveltype)
+            args_v = hop.inputargs(*hop.args_r)
+            funcptr = lltype.functionptr(FUNCTYPE, 'read_frame_var',
+                                         _callable=read_frame_var)
+            cfunc = hop.inputconst(lltype.Ptr(FUNCTYPE), funcptr)
+            return hop.genop('direct_call', [cfunc] + args_v, hop.r_result)

Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	Fri Jan 12 14:14:46 2007
@@ -1,5 +1,5 @@
 from pypy.rlib.objectmodel import specialize
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
 from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
 from pypy.jit.codegen.llgraph import llimpl
@@ -39,6 +39,8 @@
 gv_Signed = gv_TYPE(lltype.Signed)
 gv_dummy_placeholder = LLConst(llimpl.dummy_placeholder)
 
+gv_Address = gv_TYPE(llmemory.Address)
+gv_GCREF = gv_TYPE(llmemory.GCREF)
 
 class LLLabel(GenLabel):
     def __init__(self, b, g):
@@ -220,6 +222,16 @@
         llimpl.show_incremental_progress(self.gv_f)
 
 
+    # read_frame_var support
+
+    def get_frame_base(self):
+        return LLVar(llimpl.genop(self.b, 'get_frame_base', [],
+                                  gv_Address.v))
+
+    def get_frame_info(self, vars):
+        return LLVar(llimpl.genop(self.b, 'get_frame_info', vars,
+                                  gv_GCREF.v))
+
 class RGenOp(AbstractRGenOp):
     gv_Void = gv_Void
 
@@ -302,5 +314,10 @@
     def _freeze_(self):
         return True    # no real point in using a full class in llgraph
 
+    @staticmethod
+    @specialize.arg(0)
+    def read_frame_var(T, base, info, index):
+        return llimpl.read_frame_var(T, base, info, index)
+
 
 rgenop = RGenOp()      # no real point in using a full class in llgraph

Modified: pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py	Fri Jan 12 14:14:46 2007
@@ -1,9 +1,9 @@
 import py
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.jit.codegen.llgraph.rgenop import RGenOp
 from pypy.jit.codegen.llgraph.llimpl import testgengraph
 from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests
-from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test.test_llinterp import gengraph, interpret
 
 
 class TestLLGraphRGenop(AbstractRGenOpTests):
@@ -23,3 +23,35 @@
 
     # for the individual tests see
     # ====> ../../test/rgenop_tests.py
+
+
+def test_read_frame_var():
+    from pypy.annotation import model as annmodel
+
+    def reader(base, info):
+        return RGenOp.read_frame_var(lltype.Signed, base, info, 0)
+
+    t, rtyper, reader_graph = gengraph(reader,
+                                       [annmodel.SomeAddress(),
+                                        annmodel.SomePtr(llmemory.GCREF)])
+    reader_ptr = rtyper.getcallable(reader_graph)
+
+    F1 = lltype.FuncType([lltype.Signed], lltype.Signed)
+    rgenop = RGenOp()
+    signed_kind = rgenop.kindToken(lltype.Signed)
+    sigtoken = rgenop.sigToken(F1)
+    gv_reader = RGenOp.constPrebuiltGlobal(reader_ptr)
+    readertoken = rgenop.sigToken(lltype.typeOf(reader_ptr).TO)
+
+    builder, gv_f, [gv_x] = rgenop.newgraph(sigtoken, "f")
+
+    gv_y = builder.genop2("int_mul", gv_x, rgenop.genconst(2))
+    gv_base = builder.get_frame_base()
+    gv_info = builder.get_frame_info([gv_y])
+    gv_z = builder.genop_call(readertoken, gv_reader, [gv_base, gv_info])
+    builder.finish_and_return(sigtoken, gv_z)
+    builder.end()
+
+    ptr = gv_f.revealconst(lltype.Ptr(F1))
+    res = testgengraph(ptr._obj.graph, [21])
+    assert res == 42

Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Fri Jan 12 14:14:46 2007
@@ -356,24 +356,27 @@
             assert isinstance(operation.args[0], Constant)
         elif operation.opname == 'indirect_call':
             assert isinstance(operation.args[0], Variable)
-        vals = [self.getval(x) for x in operation.args]
-        if getattr(ophandler, 'need_result_type', False):
-            vals.insert(0, operation.result.concretetype)
-        try:
-            retval = ophandler(*vals)
-        except LLException, e:
-            # safety check check that the operation is allowed to raise that
-            # exception
-            if operation.opname in lloperation.LL_OPERATIONS:
-                canraise = lloperation.LL_OPERATIONS[operation.opname].canraise
-                if Exception not in canraise:
-                    exc = self.llinterpreter.find_exception(e)
-                    for canraiseexc in canraise:
-                        if issubclass(exc, canraiseexc):
-                            break
-                    else:
-                        raise TypeError("the operation %s is not expected to raise %s" % (operation, exc))
-            raise
+        if getattr(ophandler, 'specialform', False):
+            retval = ophandler(*operation.args)
+        else:
+            vals = [self.getval(x) for x in operation.args]
+            if getattr(ophandler, 'need_result_type', False):
+                vals.insert(0, operation.result.concretetype)
+            try:
+                retval = ophandler(*vals)
+            except LLException, e:
+                # safety check check that the operation is allowed to raise that
+                # exception
+                if operation.opname in lloperation.LL_OPERATIONS:
+                    canraise = lloperation.LL_OPERATIONS[operation.opname].canraise
+                    if Exception not in canraise:
+                        exc = self.llinterpreter.find_exception(e)
+                        for canraiseexc in canraise:
+                            if issubclass(exc, canraiseexc):
+                                break
+                        else:
+                            raise TypeError("the operation %s is not expected to raise %s" % (operation, exc))
+                raise
         self.setvar(operation.result, retval)
         if tracer:
             if retval is None:
@@ -857,6 +860,17 @@
         except OverflowError:
             self.make_llexception()
 
+    # read frame var support
+
+    def op_get_frame_base(self):
+        return llmemory.fakeaddress(self)
+
+    def op_get_frame_info(self, *vars):
+        return lltype.opaqueptr(llmemory.GCREF.TO,
+                                'frame_info',
+                                vars=vars)
+    op_get_frame_info.specialform = True
+ 
     #Operation of ootype
 
     def op_new(self, INST):

Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Fri Jan 12 14:14:46 2007
@@ -428,6 +428,10 @@
     'ooparse_int':          LLOp(oo=True, canraise=(ValueError,)),
     'ooparse_float':          LLOp(oo=True, canraise=(ValueError,)),
     'oohash':               LLOp(oo=True, sideeffects=False),
+
+    # _____ read frame var support ___
+    'get_frame_base':       LLOp(),
+    'get_frame_info':       LLOp(),
 }
 # ***** Run test_lloperation after changes. *****
 



More information about the Pypy-commit mailing list