[pypy-svn] r32355 - pypy/branch/kill-keepalives/pypy/rpython/rctypes
arigo at codespeak.net
arigo at codespeak.net
Fri Sep 15 14:18:23 CEST 2006
Author: arigo
Date: Fri Sep 15 14:18:21 2006
New Revision: 32355
Modified:
pypy/branch/kill-keepalives/pypy/rpython/rctypes/rarray.py
pypy/branch/kill-keepalives/pypy/rpython/rctypes/rmodel.py
pypy/branch/kill-keepalives/pypy/rpython/rctypes/rstruct.py
Log:
More rctypes progress: a proper destructor, genreccopy() fixed and improved, ...
Modified: pypy/branch/kill-keepalives/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/rpython/rctypes/rarray.py (original)
+++ pypy/branch/kill-keepalives/pypy/rpython/rctypes/rarray.py Fri Sep 15 14:18:21 2006
@@ -105,11 +105,7 @@
v_c_array = self.get_c_data(llops, v_array)
genreccopy_arrayitem(llops, v_newvalue, v_c_array, v_index)
# copy the keepalive information too
- v_keepalive_array = self.getkeepalive(llops, v_array)
- if v_keepalive_array is not None:
- v_newkeepalive = self.r_item.getkeepalive(llops, v_item)
- genreccopy_arrayitem(llops, v_newkeepalive,
- v_keepalive_array, v_index)
+ self.r_item.copykeepalive(llops, v_item, v_array, (v_index,))
def initializeitems(self, llops, v_array, items_v):
for i, v_item in enumerate(items_v):
Modified: pypy/branch/kill-keepalives/pypy/rpython/rctypes/rmodel.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/rpython/rctypes/rmodel.py (original)
+++ pypy/branch/kill-keepalives/pypy/rpython/rctypes/rmodel.py Fri Sep 15 14:18:21 2006
@@ -83,10 +83,14 @@
llmemory.raw_free(llmemory.cast_ptr_to_adr(p))
args_s = [annmodel.SomePtr(self.lowleveltype)]
+ graph = self.rtyper.annotate_helper(ll_rctypes_query, args_s)
+ queryptr = self.rtyper.getcallable(graph)
+
+ args_s = [annmodel.SomePtr(self.lowleveltype)]
graph = self.rtyper.annotate_helper(ll_rctypes_free, args_s)
destrptr = self.rtyper.getcallable(graph)
lltype.attachRuntimeTypeInfo(self.lowleveltype.TO,
- destrptr = destrptr)
+ queryptr, destrptr)
def get_content_keepalive_type(self):
"""Return the type of the extra keepalive field used for the content
@@ -224,20 +228,19 @@
# XXX add v_c_data_owner
return self.allocate_instance_ref(llops, v_c_data)
- def getkeepalive(self, llops, v_box):
+ def copykeepalive(self, llops, v_box, v_destbox, destsuboffset=()):
+ # copy the 'keepalive' data over, unless it's an autofree
+ assert v_box.concretetype == self.lowleveltype
try:
TYPE = self.lowleveltype.TO.keepalive
except AttributeError:
- return None
+ pass
else:
- if isinstance(TYPE, lltype.ContainerType):
- TYPE = lltype.Ptr(TYPE)
- opname = 'getsubstruct'
- else:
- opname = 'getfield'
- c_name = inputconst(lltype.Void, 'keepalive')
- return llops.genop(opname, [v_box, c_name],
- resulttype = TYPE)
+ if 'keepalive' not in self.autofree_fields:
+ c_keepalive = inputconst(lltype.Void, 'keepalive')
+ genreccopy_rel(llops, TYPE,
+ v_box, (c_keepalive,),
+ v_destbox, (c_keepalive,) + destsuboffset)
class __extend__(pairtype(CTypesRepr, CTypesRepr)):
@@ -249,11 +252,9 @@
r_from.ownsmemory and not r_to.ownsmemory):
v_c_data = r_from.get_c_data(llops, v)
v_result = r_to.allocate_instance_ref(llops, v_c_data, v)
- # copy of the 'keepalive' field over
- v_keepalive = r_from.getkeepalive(llops, v)
- if v_keepalive is not None:
- genreccopy_structfield(llops, v_keepalive,
- v_result, 'keepalive')
+ # copy the 'keepalive' information
+ c_keepalive = inputconst(lltype.Void, 'keepalive')
+ r_from.copykeepalive(llops, v, v_result)
return v_result
else:
return NotImplemented
@@ -313,30 +314,27 @@
def rtype_is_true(self, hop):
[v_box] = hop.inputargs(self)
v_value = self.getvalue(hop.llops, v_box)
- if v_value.concretetype == llmemory.Address:
- llfn = ll_address_is_true
- else:
- llfn = ll_is_true
- return hop.gendirectcall(llfn, v_value)
+ return hop.gendirectcall(ll_is_true, v_value)
# ____________________________________________________________
def ll_is_true(x):
return bool(x)
-def ll_address_is_true(x):
- return x != llmemory.NULL
-
C_ZERO = inputconst(lltype.Signed, 0)
+def ll_rctypes_query(p):
+ S = lltype.typeOf(p).TO
+ return lltype.getRuntimeTypeInfo(S)
+
def reccopy(source, dest):
# copy recursively a structure or array onto another.
T = lltype.rawTypeOf(source).TO
assert T == lltype.rawTypeOf(dest).TO
if isinstance(T, (lltype.Array, lltype.FixedSizeArray)):
- assert len(source) == len(dest)
+ assert source._obj.getlength() == dest._obj.getlength()
ITEMTYPE = T.OF
- for i in range(len(source)):
+ for i in range(source._obj.getlength()):
if isinstance(ITEMTYPE, lltype.ContainerType):
subsrc = source[i]
subdst = dest[i]
@@ -366,67 +364,86 @@
else:
reccopy(source, destarray[destindex])
-def genreccopy(llops, v_source, v_dest):
- # helper to generate the llops that copy recursively a structure
- # or array onto another. 'v_source' and 'v_dest' can also be pairs
- # (v, i) to mean the ith item of the array that v points to.
- T = v_source.concretetype.TO
- assert T == v_dest.concretetype.TO
+def enum_interior_offsets(T, prefix=()):
+ # generate all (offsets-tuple, FIELD_TYPE) for all interior fields
+ # in TYPE and in substructs of TYPE. Not for arrays so far.
+
+ if isinstance(T, lltype.ContainerType):
+ if isinstance(T, lltype.FixedSizeArray):
+ # XXX don't do that if the length is large
+ ITEMTYPE = T.OF
+ for i in range(T.length):
+ c_i = inputconst(lltype.Signed, i)
+ offsets = prefix + (c_i,)
+ for access in enum_interior_offsets(ITEMTYPE, offsets):
+ yield access
+
+ elif isinstance(T, lltype.Array):
+ raise NotImplementedError("XXX genreccopy() for arrays")
+
+ elif isinstance(T, lltype.Struct):
+ for name in T._names:
+ FIELDTYPE = getattr(T, name)
+ cname = inputconst(lltype.Void, name)
+ offsets = prefix + (cname,)
+ for access in enum_interior_offsets(FIELDTYPE, offsets):
+ yield access
- if isinstance(T, lltype.FixedSizeArray):
- # XXX don't do that if the length is large
- ITEMTYPE = T.OF
- for i in range(T.length):
- c_i = inputconst(lltype.Signed, i)
- if isinstance(ITEMTYPE, lltype.ContainerType):
- RESTYPE = lltype.Ptr(ITEMTYPE)
- v_subsrc = llops.genop('getarraysubstruct', [v_source, c_i],
- resulttype = RESTYPE)
- v_subdst = llops.genop('getarraysubstruct', [v_dest, c_i],
- resulttype = RESTYPE)
- genreccopy(llops, v_subsrc, v_subdst)
- else:
- v_value = llops.genop('getarrayitem', [v_source, c_i],
- resulttype = ITEMTYPE)
- llops.genop('setarrayitem', [v_dest, c_i, v_value])
+ else:
+ raise TypeError(T)
- elif isinstance(T, lltype.Array):
- raise NotImplementedError("XXX genreccopy() for arrays")
+ else:
+ yield prefix, T
- elif isinstance(T, lltype.Struct):
- for name in T._names:
- FIELDTYPE = getattr(T, name)
- cname = inputconst(lltype.Void, name)
- if isinstance(FIELDTYPE, lltype.ContainerType):
- RESTYPE = lltype.Ptr(FIELDTYPE)
- v_subsrc = llops.genop('getsubstruct', [v_source, cname],
- resulttype = RESTYPE)
- v_subdst = llops.genop('getsubstruct', [v_dest, cname],
- resulttype = RESTYPE)
- genreccopy(llops, v_subsrc, v_subdst)
- else:
- v_value = llops.genop('getfield', [v_source, cname],
- resulttype = FIELDTYPE)
- llops.genop('setfield', [v_dest, cname, v_value])
- else:
- raise TypeError(T)
+def genreccopy_rel(llops, TYPE, v_source, sourceoffsets, v_dest, destoffsets):
+ # helper to generate the llops that copy recursively a structure
+ # or array onto another. The copy starts at the given tuple-of-offsets
+ # prefixes, e.g. (Constant(5),) to mean the 5th sub-element of a
+ # fixed-size array. This function doesn't work for general arrays yet.
+ # It works with primitive types too, as long as destoffsets != ().
+
+ for offsets, FIELDTYPE in enum_interior_offsets(TYPE):
+ if sourceoffsets or offsets:
+ args = [v_source]
+ args.extend(sourceoffsets)
+ args.extend(offsets)
+ v_value = llops.genop('getinteriorfield', args,
+ resulttype=FIELDTYPE)
+ else:
+ v_value = v_source
+ if destoffsets or offsets:
+ args = [v_dest]
+ args.extend(destoffsets)
+ args.extend(offsets)
+ args.append(v_value)
+ llops.genop('setinteriorfield', args)
+ else:
+ assert TYPE == v_dest.concretetype
+ raise TypeError("cannot copy into a v_dest of type %r" % (TYPE,))
+
+def genreccopy(llops, v_source, v_dest):
+ TYPE = v_source.concretetype.TO
+ assert TYPE == v_dest.concretetype.TO
+ genreccopy_rel(llops, TYPE, v_source, (), v_dest, ())
def genreccopy_arrayitem(llops, v_source, v_destarray, v_destindex):
ITEMTYPE = v_destarray.concretetype.TO.OF
if isinstance(ITEMTYPE, lltype.ContainerType):
- v_dest = llops.genop('getarraysubstruct', [v_destarray, v_destindex],
- resulttype = lltype.Ptr(ITEMTYPE))
- genreccopy(llops, v_source, v_dest)
+ # copy into the array's substructure
+ assert ITEMTYPE == v_source.concretetype.TO
else:
- llops.genop('setarrayitem', [v_destarray, v_destindex, v_source])
+ # copy a primitive or pointer value into the array item
+ assert ITEMTYPE == v_source.concretetype
+ genreccopy_rel(llops, ITEMTYPE, v_source, (), v_destarray, (v_destindex,))
def genreccopy_structfield(llops, v_source, v_deststruct, fieldname):
c_name = inputconst(lltype.Void, fieldname)
FIELDTYPE = getattr(v_deststruct.concretetype.TO, fieldname)
if isinstance(FIELDTYPE, lltype.ContainerType):
- v_dest = llops.genop('getsubstruct', [v_deststruct, c_name],
- resulttype = lltype.Ptr(FIELDTYPE))
- genreccopy(llops, v_source, v_dest)
+ # copy into the substructure
+ assert FIELDTYPE == v_source.concretetype.TO
else:
- llops.genop('setfield', [v_deststruct, c_name, v_source])
+ # copy a primitive or pointer value into the struct field
+ assert FIELDTYPE == v_source.concretetype
+ genreccopy_rel(llops, FIELDTYPE, v_source, (), v_deststruct, (c_name,))
Modified: pypy/branch/kill-keepalives/pypy/rpython/rctypes/rstruct.py
==============================================================================
--- pypy/branch/kill-keepalives/pypy/rpython/rctypes/rstruct.py (original)
+++ pypy/branch/kill-keepalives/pypy/rpython/rctypes/rstruct.py Fri Sep 15 14:18:21 2006
@@ -117,11 +117,8 @@
v_c_struct = self.get_c_data(llops, v_struct)
genreccopy_structfield(llops, v_newvalue, v_c_struct, cmangle(name))
# copy the keepalive information too
- v_newkeepalive = r_field.getkeepalive(llops, v_item)
- if v_newkeepalive is not None:
- v_keepalive_struct = self.getkeepalive(llops, v_struct)
- genreccopy_structfield(llops, v_newkeepalive,
- v_keepalive_struct, cmangle(name))
+ c_name = inputconst(lltype.Void, cmangle(name))
+ r_field.copykeepalive(llops, v_item, v_struct, (c_name,))
def cmangle(name):
# obscure: names starting with '_' are not allowed in
More information about the Pypy-commit
mailing list