[pypy-svn] r25412 - in pypy/dist/pypy: annotation rpython/rctypes rpython/rctypes/test
arigo at codespeak.net
arigo at codespeak.net
Wed Apr 5 20:06:55 CEST 2006
Author: arigo
Date: Wed Apr 5 20:06:52 2006
New Revision: 25412
Added:
pypy/dist/pypy/rpython/rctypes/rfunc.py
pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/rpython/rctypes/implementation.py
pypy/dist/pypy/rpython/rctypes/rmodel.py
pypy/dist/pypy/rpython/rctypes/rpointer.py
pypy/dist/pypy/rpython/rctypes/rprimitive.py
pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py
Log:
(arre, arigo) (dinner time!)
Completed an rarray test: missing conversion from ints to c_long.
Started function support (mostly by copying code from implementation.py).
Pushed and pulled a bit and 42 fell out.
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Wed Apr 5 20:06:52 2006
@@ -765,16 +765,10 @@
# Note: The following works for index either pointers and arrays,
# because both have a _type_ attribute that contains the type of the
# object pointed to or in the case of an array the element type.
- assert hasattr(s_cto.knowntype, '_type_')
- assert extregistry.is_registered_type(s_cto.knowntype._type_)
- entry = extregistry.lookup_type(s_cto.knowntype._type_)
- if hasattr(entry, 'lowleveltype'):
- # special case for reading primitives out of arrays
- return lltype_to_annotation(entry.lowleveltype)
- else:
- return SomeCTypesObject(
- s_cto.knowntype._type_,
- memorystate=SomeCTypesObject.MEMORYALIAS)
+ result_ctype = s_cto.knowntype._type_
+ s_result = SomeCTypesObject(result_ctype,
+ memorystate=SomeCTypesObject.MEMORYALIAS)
+ return s_result.return_annotation()
class __extend__(pairtype(SomeCTypesObject, SomeSlice)):
def setitem((s_cto, s_slice), s_iterable):
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Wed Apr 5 20:06:52 2006
@@ -443,6 +443,21 @@
def can_be_none(self):
return False
+ def return_annotation(self):
+ """Returns either 'self' or the annotation of the unwrapped version
+ of this ctype, following the logic used when ctypes operations
+ return a value.
+ """
+ from pypy.rpython import extregistry
+ assert extregistry.is_registered_type(self.knowntype)
+ entry = extregistry.lookup_type(self.knowntype)
+ if hasattr(entry, 'lowleveltype'):
+ # special case for returning primitives
+ return lltype_to_annotation(entry.lowleveltype)
+ else:
+ return self
+
+
class SomeImpossibleValue(SomeObject):
"""The empty set. Instances are placeholders for objects that
will never show up at run-time, e.g. elements of an empty list."""
Modified: pypy/dist/pypy/rpython/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rpython/rctypes/implementation.py Wed Apr 5 20:06:52 2006
@@ -24,6 +24,7 @@
import pypy.rpython.rctypes.rarray
import pypy.rpython.rctypes.rprimitive
import pypy.rpython.rctypes.rpointer
+import pypy.rpython.rctypes.rfunc
# ctypes_annotation_list contains various attributes that
# are used by the pypy annotation.
@@ -81,79 +82,6 @@
create_ctypes_annotations()
-CFuncPtrType = type(ctypes.CFUNCTYPE(None))
-
-def cfuncptrtype_compute_annotation(type, instance):
- from pypy.annotation.model import ll_to_annotation_map
-
- def compute_result_annotation(*args_s):
- """
- Answer the annotation of the external function's result
- """
-
- # results of external function calls *must* be in the registry
- # XXX: goden: check metatype too?
- assert extregistry.is_registered_type(instance.restype)
-
- entry = extregistry.lookup_type(instance.restype)
-
- # XXX: goden: this probably isn't right
- return ll_to_annotation_map.get(entry.lowleveltype)
-
- # Take 3, Check whether we can get away with the cheap
- # precomputed solution and if not it, use a special
- # attribute with the memory state
- try:
- return instance.restype.annotator_type
- except AttributeError:
- return SomeCTypesObject(
- instance.restype,
- instance.restype.external_function_result_memorystate )
- # Take 2, looks like we need another level of indirection
- # That's to complicated
- #o#return self.restype.compute_external_function_result_annotator_type()
- # TODO: Check whether the function returns a pointer
- # an correct the memory state appropriately
- try:
- return instance.restype.annotator_type
- except AttributeError:
- return SomeCTypesObject(instance.restype)
-
- return SomeBuiltin(compute_result_annotation,
- methodname=instance.__name__)
-
-def cfuncptrtype_specialize_call(hop):
- # this is necessary to get the original function pointer when specializing
- # the metatype
- cfuncptr = hop.spaceop.args[0].value
-
- def convert_params(backend, param_info_list):
- assert "c" == backend.lower()
- assert cfuncptr.argtypes is not None
- answer = []
- for ctype_type, (ll_type, arg_name) in zip(cfuncptr.argtypes,
- param_info_list):
- if ll_type == ctype_type.ll_type:
- answer.append(arg_name)
- else:
- answer.append(ctype_type.wrap_arg(ll_type, arg_name))
- return answer
-
- assert extregistry.is_registered_type(cfuncptr.restype)
-
- # results of external function calls *must* be in the registry
- entry = extregistry.lookup_type(cfuncptr.restype)
-
- return hop.llops.gencapicall(
- cfuncptr.__name__,
- hop.args_v,
- resulttype = entry.lowleveltype,
- _callable=None,
- convert_params = convert_params )
-
-extregistry.register_metatype(CFuncPtrType,
- compute_annotation=cfuncptrtype_compute_annotation,
- specialize_call=cfuncptrtype_specialize_call)
class FunctionPointerTranslation(object):
Added: pypy/dist/pypy/rpython/rctypes/rfunc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rctypes/rfunc.py Wed Apr 5 20:06:52 2006
@@ -0,0 +1,46 @@
+from pypy.annotation import model as annmodel
+from pypy.rpython import extregistry
+
+import ctypes
+
+
+CFuncPtrType = type(ctypes.CFUNCTYPE(None))
+
+def cfuncptrtype_compute_annotation(type, instance):
+
+ def compute_result_annotation(*args_s):
+ """
+ Answer the annotation of the external function's result
+ """
+ result_ctype = instance.restype
+ s_result = annmodel.SomeCTypesObject(result_ctype,
+ annmodel.SomeCTypesObject.OWNSMEMORY)
+ return s_result.return_annotation()
+
+ return annmodel.SomeBuiltin(compute_result_annotation,
+ methodname=instance.__name__)
+
+def cfuncptrtype_specialize_call(hop):
+ # this is necessary to get the original function pointer when specializing
+ # the metatype
+ assert hop.spaceop.opname == "simple_call"
+ cfuncptr = hop.spaceop.args[0].value
+
+ args_r = []
+ for ctype in cfuncptr.argtypes:
+ s_arg = annmodel.SomeCTypesObject(ctype,
+ annmodel.SomeCTypesObject.MEMORYALIAS)
+ r_arg = hop.rtyper.getrepr(s_arg)
+ args_r.append(r_arg)
+
+ vlist = hop.inputargs(*args_r)
+ unwrapped_args_v = [r_arg.getvalue(hop.llops, v)
+ for r_arg, v in zip(args_r, vlist)]
+
+ ll_func = cfuncptr.llinterp_friendly_version
+ v_result = hop.llops.gendirectcall(ll_func, *unwrapped_args_v)
+ return v_result
+
+extregistry.register_metatype(CFuncPtrType,
+ compute_annotation=cfuncptrtype_compute_annotation,
+ specialize_call=cfuncptrtype_specialize_call)
Modified: pypy/dist/pypy/rpython/rctypes/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rmodel.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rmodel.py Wed Apr 5 20:06:52 2006
@@ -26,8 +26,8 @@
# traked by our GC around the raw 'c_data_type'-shaped
# data.
#
- # * 'owner_lowleveltype' is the lowleveltype of the repr for the same
- # ctype but for ownsmemory=True.
+ # * 'r_memoryowner.lowleveltype' is the lowleveltype of the repr for the
+ # same ctype but for ownsmemory=True.
def __init__(self, rtyper, s_ctypesobject, ll_type):
# s_ctypesobject: the annotation to represent
@@ -49,20 +49,23 @@
self.c_data_type = self.get_c_data_type(ll_type)
content_keepalives = self.get_content_keepalives()
- self.owner_lowleveltype = lltype.Ptr(
- lltype.GcStruct( "CtypesBox_%s" % (ctype.__name__,),
- ( "c_data", self.c_data_type ),
- *content_keepalives
- )
- )
if self.ownsmemory:
- self.lowleveltype = self.owner_lowleveltype
+ self.r_memoryowner = self
+ self.lowleveltype = lltype.Ptr(
+ lltype.GcStruct( "CtypesBox_%s" % (ctype.__name__,),
+ ( "c_data", self.c_data_type ),
+ *content_keepalives
+ )
+ )
else:
+ s_memoryowner = SomeCTypesObject(ctype,
+ SomeCTypesObject.OWNSMEMORY)
+ self.r_memoryowner = rtyper.getrepr(s_memoryowner)
self.lowleveltype = lltype.Ptr(
lltype.GcStruct( "CtypesBox_%s" % (ctype.__name__,),
- ( "c_data_ref", lltype.Ptr(self.c_data_type) ),
- ( "c_data_owner_keepalive", self.owner_lowleveltype ),
- *content_keepalives
+ ( "c_data_ref", lltype.Ptr(self.c_data_type) ),
+ ( "c_data_owner_keepalive", self.r_memoryowner.lowleveltype ),
+ *content_keepalives
)
)
self.const_cache = {} # store generated const values+original value
@@ -88,7 +91,7 @@
inputargs = [v_box, inputconst(lltype.Void,
"c_data_owner_keepalive")]
return llops.genop('getfield', inputargs,
- self.owner_lowleveltype)
+ self.r_memoryowner.lowleveltype)
def allocate_instance(self, llops):
c1 = inputconst(lltype.Void, self.lowleveltype.TO)
@@ -104,7 +107,8 @@
inputargs = [v_box, inputconst(lltype.Void, "c_data_ref"), v_c_data]
llops.genop('setfield', inputargs)
if v_c_data_owner is not None:
- assert v_c_data_owner.concretetype == self.owner_lowleveltype
+ assert (v_c_data_owner.concretetype ==
+ self.r_memoryowner.lowleveltype)
inputargs = [v_box,
inputconst(lltype.Void, "c_data_owner_keepalive"),
v_c_data_owner]
Modified: pypy/dist/pypy/rpython/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpointer.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rpointer.py Wed Apr 5 20:06:52 2006
@@ -22,7 +22,8 @@
def get_content_keepalives(self):
"Return an extra keepalive field used for the pointer's contents."
- return [('keepalive_contents', self.r_contents.owner_lowleveltype)]
+ return [('keepalive_contents',
+ self.r_contents.r_memoryowner.lowleveltype)]
def setkeepalive(self, llops, v_box, v_owner):
inputargs = [v_box, inputconst(lltype.Void, 'keepalive_contents'),
Modified: pypy/dist/pypy/rpython/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rprimitive.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rprimitive.py Wed Apr 5 20:06:52 2006
@@ -6,7 +6,7 @@
from pypy.rpython.rmodel import Repr, inputconst
from pypy.rpython.lltypesystem import lltype
from pypy.annotation.pairtype import pairtype
-from pypy.rpython.rmodel import IntegerRepr
+from pypy.rpython.rmodel import IntegerRepr, FloatRepr, CharRepr
from pypy.rpython.error import TyperError
from pypy.rpython.rctypes.rmodel import CTypesValueRepr
@@ -49,7 +49,7 @@
try:
return self.const_cache[key][0]
except KeyError:
- p = lltype.malloc(self.owner_lowleveltype.TO)
+ p = lltype.malloc(self.r_memoryowner.lowleveltype.TO)
p.c_data.value = value
if self.ownsmemory:
result = p
@@ -78,6 +78,14 @@
self.setvalue(hop.llops, v_primitive, v_value)
+class __extend__(pairtype(IntegerRepr, PrimitiveRepr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ r_temp = r_to.r_memoryowner
+ v_owned_box = r_temp.allocate_instance(llops)
+ r_temp.setvalue(llops, v_owned_box, v)
+ return llops.convertvar(v_owned_box, r_temp, r_to)
+
+
def primitive_specialize_call(hop):
r_primitive = hop.r_result
v_result = r_primitive.allocate_instance(hop.llops)
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rarray.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rarray.py Wed Apr 5 20:06:52 2006
@@ -34,16 +34,17 @@
a.translator.view()
def test_annotate_array_access(self):
- def access_array():
+ def access_array(n):
my_array = c_int_10()
my_array[0] = c_int(1)
my_array[1] = 2
+ my_array[2] = n
return my_array[0]
t = TranslationContext()
a = t.buildannotator()
- s = a.build_types(access_array, [])
+ s = a.build_types(access_array, [int])
assert s.knowntype == int
if conftest.option.view:
@@ -114,14 +115,15 @@
assert len(c_data) == 10
def test_specialize_array_access(self):
- def access_array():
+ def access_array(n):
my_array = c_int_10()
my_array[0] = 1
my_array[1] = c_int(1)
+ my_array[2] = n
return my_array[0]
- res = interpret(access_array, [])
+ res = interpret(access_array, [44])
assert res == 1
class Test_compilation:
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py Wed Apr 5 20:06:52 2006
@@ -257,7 +257,7 @@
# result should be an integer
assert s.knowntype == int
- def test_specialize_simple(self):
+ def x_test_specialize_simple(self):
t = TranslationContext()
a = t.buildannotator()
s = a.build_types(o_atoi, [str])
Added: pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py Wed Apr 5 20:06:52 2006
@@ -0,0 +1,36 @@
+from pypy.annotation.annrpython import RPythonAnnotator
+from pypy.rpython.rctypes.test.test_rctypes import mylib
+from pypy.rpython.test.test_llinterp import interpret
+from pypy import conftest
+
+from ctypes import c_long
+
+
+labs = mylib.labs
+labs.restype = c_long
+labs.argtypes = [c_long]
+
+def ll_labs(n):
+ return abs(n)
+
+labs.llinterp_friendly_version = ll_labs
+
+
+def test_labs(n=6):
+ assert labs(n) == abs(n)
+ assert labs(c_long(0)) == 0
+ assert labs(-42) == 42
+ return labs(n)
+
+class Test_annotation:
+ def test_annotate_labs(self):
+ a = RPythonAnnotator()
+ s = a.build_types(test_labs, [int])
+ assert s.knowntype == int
+ if conftest.option.view:
+ a.translator.view()
+
+class Test_specialization:
+ def test_specialize_labs(self):
+ res = interpret(test_labs, [-11])
+ assert res == 11
More information about the Pypy-commit
mailing list