Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit