[pypy-svn] r22849 - in pypy/dist/pypy/rpython/rctypes: . test
gromit at codespeak.net
gromit at codespeak.net
Sun Jan 29 17:47:31 CET 2006
Author: gromit
Date: Sun Jan 29 17:47:28 2006
New Revision: 22849
Modified:
pypy/dist/pypy/rpython/rctypes/implementation.py
pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py
Log:
ADD: We now can compile ctypes structures that manage their own memory.
Modified: pypy/dist/pypy/rpython/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rpython/rctypes/implementation.py Sun Jan 29 17:47:28 2006
@@ -11,7 +11,11 @@
from pypy.annotation.model import SomeInteger, SomeCTypesObject, \
SomeString, SomeFloat
from pypy.rpython.lltypesystem.lltype import Signed, SignedLongLong, \
- Unsigned, UnsignedLongLong, Char, Float
+ Unsigned, UnsignedLongLong, Char, Float, Ptr, GcStruct, \
+ Void
+from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst
+from pypy.rpython.error import TyperError
+
# ctypes_annotation_list contains various attributes that
# are used by the pypy annotation.
@@ -118,8 +122,12 @@
return SomeCTypesObject(cls)
compute_annotation = classmethod(compute_annotation)
- def specialize(self, hop):
- raise NotImplementedError
+ def specialize( cls, highLevelOperation ):
+ ctypesStructureType = highLevelOperation.r_result.lowleveltype
+ return highLevelOperation.llops.genop(
+ "malloc", [ inputconst( Void, ctypesStructureType ) ],
+ highLevelOperation.r_result )
+ specialize = classmethod(specialize)
def compute_result_annotation(cls, *args_s):
"""
@@ -128,6 +136,21 @@
return SomeCTypesObject(cls,SomeCTypesObject.OWNSMEMORY)
compute_result_annotation = classmethod(compute_result_annotation)
+ def createLowLevelRepresentation( rtyper, annotationObject ):
+ """
+ Answer the correspondending low level object.
+ """
+ if annotationObject.memorystate == annotationObject.OWNSMEMORY:
+ return CtypesMemoryOwningStructureRepresentation(
+ rtyper, annotationObject )
+ elif annotationObject.memorystate == annotationObject.MEMORYALIAS:
+ return CtypesMemoryAliasStructureRepresentation(
+ rtyper, annotationObject )
+ else:
+ raise TyperError( "Unkown memory state in %r" % annotationObject )
+ createLowLevelRepresentation = staticmethod( createLowLevelRepresentation )
+
+
class RByrefObj(object):
default_memorystate = SomeCTypesObject.MEMORYALIAS
@@ -158,6 +181,9 @@
assert answer is cls
return SomeCTypesObject(cls)
answer.compute_result_annotation = classmethod(compute_result_annotation)
+ # We specialcased accessing pointers be getting their contents attribute
+ # because we can't use the memory state from 'cls'.
+ # So the obvious way to do it is obsolete (#o#).
#o#answer._fields_def_ = {"contents": cls}
answer.default_memorystate = SomeCTypesObject.MEMORYALIAS
return answer
@@ -202,3 +228,61 @@
return answer
+class AbstractCtypesRepresentation( Repr ):
+ """
+ The abstract base class of all ctypes low level representations.
+ """
+
+
+class AbstractCtypesStructureRepresentation( AbstractCtypesRepresentation ):
+ """
+ The abstract base class of ctypes structures' low level representation.
+ """
+
+ def __init__( self, rtyper, annotationObject ):
+ # XXX This .ll_type may not work for pointers or structures
+ # conating structures
+ fields = [ ( name, ctypesType.ll_type )
+ for name, ctypesType in annotationObject.knowntype._fields_ ]
+ self.lowleveltype = Ptr(
+ GcStruct(
+ 'CtypesStructure_%s' %
+ annotationObject.knowntype.__name__, *fields ) )
+
+
+class CtypesMemoryOwningStructureRepresentation( AbstractCtypesStructureRepresentation ):
+ """
+ The lowlevel representation of a ctypes structure that owns its memory.
+ """
+
+ def rtype_setattr( self, highLevelOperation ):
+ #d#print highLevelOperation.args_v
+ #d#print highLevelOperation.args_r
+ #d#print highLevelOperation.args_s
+ highLevelOperation.genop(
+ "setfield",
+ highLevelOperation.inputargs(
+ *highLevelOperation.args_r[ :3 ] ) )
+
+ def rtype_getattr( self, highLevelOperation ):
+ return highLevelOperation.genop(
+ "getfield",
+ highLevelOperation.inputargs(
+ *highLevelOperation.args_r[ :2 ] ),
+ highLevelOperation.r_result )
+
+
+
+class CtypesMemoryAliasStructureRepresentation( AbstractCtypesStructureRepresentation ):
+ """
+ The lowlevel representation of a ctypes structure that is an alias to
+ someone else's memory.
+ """
+
+class __extend__( SomeCTypesObject ):
+ def rtyper_makerepr( self, rtyper ):
+ return self.knowntype.createLowLevelRepresentation( rtyper, self )
+
+ def rtyper_makekey( self ):
+ return self.__class__, self.knowntype, self.memorystate
+
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 Sun Jan 29 17:47:28 2006
@@ -1,10 +1,34 @@
import py.test
from pypy.annotation.annrpython import RPythonAnnotator
from pypy.translator.translator import TranslationContext
-from pypy.translator.c.test.test_genc import compile
+from pypy.translator.c.test.test_genc import compile, compile_db
+#o#from pypy.translator.c import compile
from pypy.translator.tool.cbuild import compile_c_module
from pypy.annotation.model import SomeCTypesObject, SomeObject
import sys
+
+
+def compile(fn, argtypes, view=False):
+ from pypy.translator.c.database import LowLevelDatabase
+ from pypy.rpython.lltypesystem.lltype import pyobjectptr
+ t = TranslationContext()
+ a = t.buildannotator()
+ a.build_types(fn, argtypes)
+ t.buildrtyper().specialize()
+ if view:
+ t.view()
+ #t#backend_optimizations(t)
+ db = LowLevelDatabase(t)
+ entrypoint = db.get(pyobjectptr(fn))
+ db.complete()
+ module = compile_db(db)
+ compiled_fn = getattr(module, entrypoint)
+ def checking_fn(*args, **kwds):
+ res = compiled_fn(*args, **kwds)
+ mallocs, frees = module.malloc_counters()
+ assert mallocs == frees
+ return res
+ return checking_fn
try:
import ctypes
@@ -174,6 +198,15 @@
return p.x
+def _py_test_compile_struct( p, x, y ):
+ p.x = x
+ p.y = y
+
+ return p
+
+def py_test_compile_struct( x, y ):
+ return _py_test_compile_struct( tagpoint(), x, y ).x
+
class Test_rctypes:
@@ -321,14 +354,34 @@
s = a.build_types(py_test_simple_ctypes_non_const,[])
assert s.knowntype == c_float
- def x_test_specialize_struct(self):
+ def test_specialize_struct(self):
t = TranslationContext()
a = t.buildannotator()
s = a.build_types(py_test_specialize_struct, [])
# result should be an integer
assert s.knowntype == int
- t.buildrtyper().specialize()
+ try:
+ t.buildrtyper().specialize()
+ finally:
+ #d#t.view()
+ pass
+
+ def test_specialize_struct_1(self):
+ t = TranslationContext()
+ a = t.buildannotator()
+ s = a.build_types( py_test_compile_struct, [ int, int ] )
#d#t.view()
+ try:
+ t.buildrtyper().specialize()
+ finally:
+ #d#t.view()
+ pass
+
+ def test_compile_struct(self):
+ fn = compile( py_test_compile_struct, [ int, int ], True )
+ res = fn( 42, -42 )
+ assert res == 42
+
class Test_array:
@@ -357,13 +410,13 @@
a = t.buildannotator()
s = a.build_types(py_test_annotate_pointer_content,[])
assert s.knowntype == int
- #t#t.view()
+ #d#t.view()
def test_annotate_array_slice_access(self):
t = TranslationContext()
a = t.buildannotator()
s = a.build_types(py_test_annotate_array_slice_content,[])
- #t#t.view()
+ #d#t.view()
#d#print "v90:", s, type(s)
assert s.knowntype == list
s.listdef.listitem.s_value.knowntype == int
More information about the Pypy-commit
mailing list