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 test_null_padding(self): py.test.skip("we no longer pad our RPython strings with a final NUL") from rpython.rtyper.lltypesystem import llmemory from rpython.rtyper.lltypesystem import rstr chars_offset = llmemory.FieldOffset(rstr.STR, 'chars') + \ llmemory.ArrayItemsOffset(rstr.STR.chars) # sadly, there's no way of forcing this to fail if the strings # are allocated in a region of memory such that they just # happen to get a NUL byte anyway :/ (a debug build will # always fail though) def trailing_byte(s): adr_s = llmemory.cast_ptr_to_adr(s) return (adr_s + chars_offset).char[len(s)] def f(x): r = 0 for i in range(x): r += ord(trailing_byte(' '*(100-x*x))) return r fn = self.getcompiled(f, [int]) res = fn(10) assert res == 0