[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