Author: Armin Rigo <[email protected]>
Branch: all_ordered_dicts
Changeset: r75389:95b1d6cff0ee
Date: 2015-01-16 16:28 +0100
http://bitbucket.org/pypy/pypy/changeset/95b1d6cff0ee/
Log: Add a custom ll operation to read the length of any ("simple
enough") GC array.
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -740,6 +740,10 @@
return lltype.cast_opaque_ptr(RESTYPE, obj)
op_cast_opaque_ptr.need_result_type = True
+ def op_length_of_simple_gcarray_from_opaque(self, obj):
+ checkptr(obj)
+ return lltype.length_of_simple_gcarray_from_opaque(obj)
+
def op_cast_ptr_to_adr(self, ptr):
checkptr(ptr)
return llmemory.cast_ptr_to_adr(ptr)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -396,6 +396,7 @@
'direct_arrayitems': LLOp(canfold=True),
'direct_ptradd': LLOp(canfold=True),
'cast_opaque_ptr': LLOp(sideeffects=False),
+ 'length_of_simple_gcarray_from_opaque': LLOp(sideeffects=False),
# __________ address operations __________
diff --git a/rpython/rtyper/lltypesystem/lltype.py
b/rpython/rtyper/lltypesystem/lltype.py
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -1025,6 +1025,21 @@
return SomePtr(ll_ptrtype=typeOf(cast_p))
+def length_of_simple_gcarray_from_opaque(opaque_ptr):
+ CURTYPE = typeOf(opaque_ptr)
+ if not isinstance(CURTYPE, Ptr):
+ raise TypeError("can only cast pointers to other pointers")
+ if not isinstance(CURTYPE.TO, GcOpaqueType):
+ raise TypeError("expected a GcOpaqueType")
+ return opaque_ptr._obj.container.getlength()
+
+@analyzer_for(length_of_simple_gcarray_from_opaque)
+def ann_length_of_simple_gcarray_from_opaque(s_p):
+ assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
+ assert isinstance(s_p.ll_ptrtype.TO, GcOpaqueType)
+ return SomeInteger(nonneg=True)
+
+
def direct_fieldptr(structptr, fieldname):
"""Get a pointer to a field in the struct. The resulting
pointer is actually of type Ptr(FixedSizeArray(FIELD, 1)).
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py
b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -604,7 +604,7 @@
# xxx Haaaack: returns len(d.indexes). Works independently of
# the exact type pointed to by d, using a forced cast...
# Must only be called by @jit.dont_look_inside functions.
- return len(rffi.cast(DICTINDEX_BYTE, d.indexes))
+ return lltype.length_of_simple_gcarray_from_opaque(d.indexes)
def _overallocate_entries_len(baselen):
# This over-allocates proportional to the list size, making room
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -445,6 +445,14 @@
return hop.genop('cast_opaque_ptr', [v_input], # v_type implicit in
r_result
resulttype = hop.r_result.lowleveltype)
+@typer_for(lltype.length_of_simple_gcarray_from_opaque)
+def rtype_length_of_simple_gcarray_from_opaque(hop):
+ assert isinstance(hop.args_r[0], rptr.PtrRepr)
+ v_opaque_ptr, = hop.inputargs(hop.args_r[0])
+ hop.exception_cannot_occur()
+ return hop.genop('length_of_simple_gcarray_from_opaque', [v_opaque_ptr],
+ resulttype = hop.r_result.lowleveltype)
+
@typer_for(lltype.direct_fieldptr)
def rtype_direct_fieldptr(hop):
assert isinstance(hop.args_r[0], rptr.PtrRepr)
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -653,6 +653,11 @@
OP_CAST_ADR_TO_PTR = OP_CAST_POINTER
OP_CAST_OPAQUE_PTR = OP_CAST_POINTER
+ def OP_LENGTH_OF_SIMPLE_GCARRAY_FROM_OPAQUE(self, op):
+ return ('%s = *(long *)(((char *)%s) + sizeof(struct pypy_header0));'
+ ' /* length_of_simple_gcarray_from_opaque */'
+ % (self.expr(op.result), self.expr(op.args[0])))
+
def OP_CAST_INT_TO_PTR(self, op):
TYPE = self.lltypemap(op.result)
typename = self.db.gettype(TYPE)
diff --git a/rpython/translator/c/test/test_lladdresses.py
b/rpython/translator/c/test/test_lladdresses.py
--- a/rpython/translator/c/test/test_lladdresses.py
+++ b/rpython/translator/c/test/test_lladdresses.py
@@ -246,3 +246,13 @@
assert res == 456
res = fc(77)
assert res == 123
+
+def test_gcarray_length():
+ A = lltype.GcArray(lltype.Char)
+ def f():
+ a = lltype.malloc(A, 117)
+ p = lltype.cast_opaque_ptr(GCREF, a)
+ return lltype.length_of_simple_gcarray_from_opaque(p)
+ fc = compile(f, [])
+ res = fc()
+ assert res == 117
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit