[pypy-svn] r31607 - in pypy/dist/pypy/rpython: . test

arigo at codespeak.net arigo at codespeak.net
Thu Aug 24 15:36:08 CEST 2006


Author: arigo
Date: Thu Aug 24 15:36:06 2006
New Revision: 31607

Modified:
   pypy/dist/pypy/rpython/annlowlevel.py
   pypy/dist/pypy/rpython/test/test_llann.py
Log:
(pedronis, arigo)

pypy.rpython.annlowlevel.PseudoHighLevelCallable: a gateway to a
low-level function pointer.  To high-level RPython code it looks like a
normal function, taking high-level arguments and returning a high-level
result.



Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py	(original)
+++ pypy/dist/pypy/rpython/annlowlevel.py	Thu Aug 24 15:36:06 2006
@@ -7,7 +7,7 @@
 from pypy.annotation import model as annmodel
 from pypy.annotation.policy import AnnotatorPolicy
 from pypy.rpython.lltypesystem import lltype
-from pypy.rpython import extfunctable
+from pypy.rpython import extfunctable, extregistry
 from pypy.objspace.flow.model import Constant
 
 def not_const(s_obj): # xxx move it somewhere else
@@ -186,6 +186,13 @@
         self.delayedreprs.append(r)
         return r
 
+    def s_r_instanceof(self, cls, can_be_None=True):
+        classdesc = self.rtyper.annotator.bookkeeper.getdesc(cls)
+        classdef = classdesc.getuniqueclassdef()
+        s_instance = annmodel.SomeInstance(classdef, can_be_None)
+        r_instance = self.getdelayedrepr(s_instance)
+        return s_instance, r_instance
+
     def delayedconst(self, repr, obj):
         if repr.is_setup_delayed():
             # record the existence of this 'obj' for the bookkeeper - e.g.
@@ -250,3 +257,34 @@
         newgraphs = translator.graphs[self.original_graph_count:]
         self.original_graph_count = len(translator.graphs)
         backend_optimizations(translator, newgraphs, **flags)
+
+# ____________________________________________________________
+
+class PseudoHighLevelCallable(object):
+    """A gateway to a low-level function pointer.  To high-level RPython
+    code it looks like a normal function, taking high-level arguments
+    and returning a high-level result.
+    """
+    def __init__(self, llfnptr, args_s, s_result):
+        self.llfnptr = llfnptr
+        self.args_s = args_s
+        self.s_result = s_result
+
+    def __call__(self, *args):
+        raise Exception("PseudoHighLevelCallable objects are not really "
+                        "callable directly")
+
+class Entry(extregistry.ExtRegistryEntry):
+    _type_ = PseudoHighLevelCallable
+
+    def compute_result_annotation(self, *args_s):
+        return self.instance.s_result
+
+    def specialize_call(self, hop):
+        args_r = [hop.rtyper.getrepr(s) for s in self.instance.args_s]
+        r_res = hop.rtyper.getrepr(self.instance.s_result)
+        vlist = hop.inputargs(*args_r)
+        p = self.instance.llfnptr
+        c_func = Constant(p, lltype.typeOf(p))
+        hop.exception_is_here()
+        return hop.genop('direct_call', [c_func] + vlist, resulttype = r_res)

Modified: pypy/dist/pypy/rpython/test/test_llann.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_llann.py	(original)
+++ pypy/dist/pypy/rpython/test/test_llann.py	Thu Aug 24 15:36:06 2006
@@ -1,6 +1,10 @@
 from pypy.rpython.lltypesystem.lltype import *
+from pypy.translator.translator import TranslationContext
 from pypy.annotation import model as annmodel
 from pypy.rpython.annlowlevel import annotate_lowlevel_helper
+from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
+from pypy.rpython.annlowlevel import PseudoHighLevelCallable
+from pypy.rpython.llinterp import LLInterpreter
 from pypy.objspace.flow import FlowObjSpace 
 
 # helpers
@@ -308,3 +312,36 @@
         assert s.unsigned == True
 
  
+def test_pseudohighlevelcallable():
+    t = TranslationContext()
+    t.buildannotator()
+    rtyper = t.buildrtyper()
+    rtyper.specialize()
+    a = MixLevelHelperAnnotator(rtyper)
+
+    class A:
+        value = 5
+        def double(self):
+            return self.value * 2
+
+    def fn1(a):
+        a2 = A()
+        a2.value = a.double()
+        return a2
+
+    s_A, r_A = a.s_r_instanceof(A)
+    fn1ptr = a.delayedfunction(fn1, [s_A], s_A)
+    pseudo = PseudoHighLevelCallable(fn1ptr, [s_A], s_A)
+
+    def fn2(n):
+        a = A()
+        a.value = n
+        a2 = pseudo(a)
+        return a2.value
+
+    graph = a.getgraph(fn2, [annmodel.SomeInteger()], annmodel.SomeInteger())
+    a.finish()
+
+    llinterp = LLInterpreter(rtyper)
+    res = llinterp.eval_graph(graph, [21])
+    assert res == 42



More information about the Pypy-commit mailing list