def varsize_malloc_helper(self, hop, flags, meth, extraargs): def intconst(c): return rmodel.inputconst(lltype.Signed, c) op = hop.spaceop TYPE = op.result.concretetype.TO assert TYPE._is_varsize() if isinstance(TYPE, lltype.Struct): ARRAY = TYPE._flds[TYPE._arrayfld] else: ARRAY = TYPE assert isinstance(ARRAY, lltype.Array) c_const_size = intconst(llmemory.sizeof(TYPE, 0)) c_item_size = intconst(llmemory.sizeof(ARRAY.OF)) if ARRAY._hints.get("nolength", False): c_offset_to_length = None else: if isinstance(TYPE, lltype.Struct): offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \ llmemory.ArrayLengthOffset(ARRAY) else: offset_to_length = llmemory.ArrayLengthOffset(ARRAY) c_offset_to_length = intconst(offset_to_length) args = [hop] + extraargs + [flags, TYPE, op.args[-1], c_const_size, c_item_size, c_offset_to_length] v_raw = meth(*args) hop.cast_result(v_raw)
def get_array_token(T, translate_support_code): # T can be an array or a var-sized structure if translate_support_code: basesize = llmemory.sizeof(T, 0) if isinstance(T, lltype.Struct): SUBARRAY = getattr(T, T._arrayfld) itemsize = llmemory.sizeof(SUBARRAY.OF) ofs_length = (llmemory.offsetof(T, T._arrayfld) + llmemory.ArrayLengthOffset(SUBARRAY)) else: if T._hints.get('nolength', None): ofs_length = -1 else: ofs_length = llmemory.ArrayLengthOffset(T) itemsize = llmemory.sizeof(T.OF) else: if isinstance(T, lltype.Struct): assert T._arrayfld is not None, "%r is not variable-sized" % (T, ) cstruct = ll2ctypes.get_ctypes_type(T) cfield = getattr(cstruct, T._arrayfld) before_array_part = cfield.offset T = getattr(T, T._arrayfld) else: before_array_part = 0 carray = ll2ctypes.get_ctypes_type(T) if T._hints.get('nolength', None): ofs_length = -1 else: assert carray.length.size == WORD ofs_length = before_array_part + carray.length.offset basesize = before_array_part + carray.items.offset carrayitem = ll2ctypes.get_ctypes_type(T.OF) itemsize = ctypes.sizeof(carrayitem) return basesize, itemsize, ofs_length
def encode_type_shape(builder, info, TYPE, index): """Encode the shape of the TYPE into the TYPE_INFO structure 'info'.""" offsets = offsets_to_gc_pointers(TYPE) infobits = index info.ofstoptrs = builder.offsets2table(offsets, TYPE) if len(offsets) > 0: infobits |= T_HAS_GCPTR # fptrs = builder.special_funcptr_for_type(TYPE) if fptrs: if "destructor" in fptrs: info.customfunc = fptrs["destructor"] if "old_style_finalizer" in fptrs: info.customfunc = fptrs["old_style_finalizer"] infobits |= T_HAS_OLDSTYLE_FINALIZER # if not TYPE._is_varsize(): info.fixedsize = llarena.round_up_for_allocation( llmemory.sizeof(TYPE), builder.GCClass.object_minimal_size) # note about round_up_for_allocation(): in the 'info' table # we put a rounded-up size only for fixed-size objects. For # varsize ones, the GC must anyway compute the size at run-time # and round up that result. else: infobits |= T_IS_VARSIZE varinfo = lltype.cast_pointer(GCData.VARSIZE_TYPE_INFO_PTR, info) info.fixedsize = llmemory.sizeof(TYPE, 0) if isinstance(TYPE, lltype.Struct): ARRAY = TYPE._flds[TYPE._arrayfld] ofs1 = llmemory.offsetof(TYPE, TYPE._arrayfld) varinfo.ofstolength = ofs1 + llmemory.ArrayLengthOffset(ARRAY) varinfo.ofstovar = ofs1 + llmemory.itemoffsetof(ARRAY, 0) else: assert isinstance(TYPE, lltype.GcArray) ARRAY = TYPE if (isinstance(ARRAY.OF, lltype.Ptr) and ARRAY.OF.TO._gckind == 'gc'): infobits |= T_IS_GCARRAY_OF_GCPTR varinfo.ofstolength = llmemory.ArrayLengthOffset(ARRAY) varinfo.ofstovar = llmemory.itemoffsetof(TYPE, 0) assert isinstance(ARRAY, lltype.Array) if ARRAY.OF != lltype.Void: offsets = offsets_to_gc_pointers(ARRAY.OF) else: offsets = () if len(offsets) > 0: infobits |= T_HAS_GCPTR_IN_VARSIZE | T_HAS_GCPTR varinfo.varofstoptrs = builder.offsets2table(offsets, ARRAY.OF) varinfo.varitemsize = llmemory.sizeof(ARRAY.OF) if builder.is_weakref_type(TYPE): infobits |= T_IS_WEAKREF if is_subclass_of_object(TYPE): infobits |= T_IS_RPYTHON_INSTANCE info.infobits = infobits | T_KEY_VALUE