示例#1
0
def gc_pointers_inside(v, adr, mutable_only=False):
    t = lltype.typeOf(v)
    if isinstance(t, lltype.Struct):
        skip = ()
        if mutable_only:
            if t._hints.get('immutable'):
                return
            if 'immutable_fields' in t._hints:
                skip = t._hints['immutable_fields'].all_immutable_fields()
        for n, t2 in t._flds.iteritems():
            if isinstance(t2, lltype.Ptr) and t2.TO._gckind == 'gc':
                if n not in skip:
                    yield adr + llmemory.offsetof(t, n)
            elif isinstance(t2, (lltype.Array, lltype.Struct)):
                for a in gc_pointers_inside(getattr(v, n),
                                            adr + llmemory.offsetof(t, n),
                                            mutable_only):
                    yield a
    elif isinstance(t, lltype.Array):
        if mutable_only and t._hints.get('immutable'):
            return
        if isinstance(t.OF, lltype.Ptr) and t.OF.TO._gckind == 'gc':
            for i in range(len(v.items)):
                yield adr + llmemory.itemoffsetof(t, i)
        elif isinstance(t.OF, lltype.Struct):
            for i in range(len(v.items)):
                for a in gc_pointers_inside(v.items[i],
                                            adr + llmemory.itemoffsetof(t, i),
                                            mutable_only):
                    yield a
示例#2
0
def gc_pointers_inside(v, adr, mutable_only=False):
    t = lltype.typeOf(v)
    if isinstance(t, lltype.Struct):
        skip = ()
        if mutable_only:
            if t._hints.get('immutable'):
                return
            if 'immutable_fields' in t._hints:
                skip = t._hints['immutable_fields'].all_immutable_fields()
        for n, t2 in t._flds.iteritems():
            if isinstance(t2, lltype.Ptr) and t2.TO._gckind == 'gc':
                if n not in skip:
                    yield adr + llmemory.offsetof(t, n)
            elif isinstance(t2, (lltype.Array, lltype.Struct)):
                for a in gc_pointers_inside(getattr(v, n),
                                            adr + llmemory.offsetof(t, n),
                                            mutable_only):
                    yield a
    elif isinstance(t, lltype.Array):
        if mutable_only and t._hints.get('immutable'):
            return
        if isinstance(t.OF, lltype.Ptr) and t.OF.TO._gckind == 'gc':
            for i in range(len(v.items)):
                yield adr + llmemory.itemoffsetof(t, i)
        elif isinstance(t.OF, lltype.Struct):
            for i in range(len(v.items)):
                for a in gc_pointers_inside(v.items[i],
                                            adr + llmemory.itemoffsetof(t, i),
                                            mutable_only):
                    yield a
示例#3
0
文件: rstr.py 项目: soIu/rpython
 def ll_string2list(RESLIST, src):
     length = len(src.chars)
     lst = RESLIST.ll_newlist(length)
     dst = lst.ll_items()
     SRC = typeOf(src).TO  # STR or UNICODE
     DST = typeOf(dst).TO  # GcArray
     assert DST.OF is SRC.chars.OF
     #
     # If the 'split_gc_address_space' option is set, we must copy
     # manually, character-by-character
     if rgc.must_split_gc_address_space():
         i = 0
         while i < length:
             dst[i] = src.chars[i]
             i += 1
         return lst
     #
     # from here, no GC operations can happen
     asrc = llmemory.cast_ptr_to_adr(src) + (llmemory.offsetof(
         SRC, 'chars') + llmemory.itemoffsetof(SRC.chars, 0))
     adst = llmemory.cast_ptr_to_adr(dst) + llmemory.itemoffsetof(DST, 0)
     llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(DST.OF) * length)
     # end of "no GC" section
     keepalive_until_here(src)
     keepalive_until_here(dst)
     return lst
示例#4
0
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
示例#5
0
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 "finalizer" in fptrs:
            info.finalizer = fptrs["finalizer"]
        if "light_finalizer" in fptrs:
            info.finalizer = fptrs["light_finalizer"]
            infobits |= T_HAS_LIGHTWEIGHT_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
示例#6
0
文件: rgc.py 项目: sota/pypy
def ll_arraycopy(source, dest, source_start, dest_start, length):
    from rpython.rtyper.lltypesystem.lloperation import llop
    from rpython.rlib.objectmodel import keepalive_until_here

    # XXX: Hack to ensure that we get a proper effectinfo.write_descrs_arrays
    # and also, maybe, speed up very small cases
    if length <= 1:
        if length == 1:
            copy_item(source, dest, source_start, dest_start)
        return

    # supports non-overlapping copies only
    if not we_are_translated():
        if source == dest:
            assert (source_start + length <= dest_start or
                    dest_start + length <= source_start)

    TP = lltype.typeOf(source).TO
    assert TP == lltype.typeOf(dest).TO

    slowpath = False
    if must_split_gc_address_space():
        slowpath = True
    elif _contains_gcptr(TP.OF):
        # perform a write barrier that copies necessary flags from
        # source to dest
        if not llop.gc_writebarrier_before_copy(lltype.Bool, source, dest,
                                                source_start, dest_start,
                                                length):
            slowpath = True
    if slowpath:
        # if the write barrier is not supported, or if we translate with
        # the option 'split_gc_address_space', then copy by hand
        i = 0
        while i < length:
            copy_item(source, dest, i + source_start, i + dest_start)
            i += 1
        return
    source_addr = llmemory.cast_ptr_to_adr(source)
    dest_addr   = llmemory.cast_ptr_to_adr(dest)
    cp_source_addr = (source_addr + llmemory.itemoffsetof(TP, 0) +
                      llmemory.sizeof(TP.OF) * source_start)
    cp_dest_addr = (dest_addr + llmemory.itemoffsetof(TP, 0) +
                    llmemory.sizeof(TP.OF) * dest_start)

    llmemory.raw_memcopy(cp_source_addr, cp_dest_addr,
                         llmemory.sizeof(TP.OF) * length)
    keepalive_until_here(source)
    keepalive_until_here(dest)
示例#7
0
文件: func.py 项目: sota/pypy
def get_raw_address_of_string(space, w_x):
    """Special case for ffi.from_buffer(string).  Returns a 'char *' that
    is valid as long as the string object is alive.  Two calls to
    ffi.from_buffer(same_string) are guaranteed to return the same pointer.
    """
    from rpython.rtyper.annlowlevel import llstr
    from rpython.rtyper.lltypesystem.rstr import STR
    from rpython.rtyper.lltypesystem import llmemory
    from rpython.rlib import rgc

    cache = space.fromcache(RawBytesCache)
    rawbytes = cache.wdict.get(w_x)
    if rawbytes is None:
        data = space.bytes_w(w_x)
        if (we_are_translated() and not rgc.can_move(data)
                and not rgc.must_split_gc_address_space()):
            lldata = llstr(data)
            data_start = (llmemory.cast_ptr_to_adr(lldata) +
                          rffi.offsetof(STR, 'chars') +
                          llmemory.itemoffsetof(STR.chars, 0))
            data_start = rffi.cast(rffi.CCHARP, data_start)
            data_start[len(data)] = '\x00'  # write the final extra null
            return data_start
        rawbytes = RawBytes(data)
        cache.wdict.set(w_x, rawbytes)
    return rawbytes.ptr
示例#8
0
文件: rffi.py 项目: Darriall/pypy
 def alloc_buffer(count):
     """
     Returns a (raw_buffer, gc_buffer, case_num) triple,
     allocated with count bytes.
     The raw_buffer can be safely passed to a native function which expects
     it to not move. Call str_from_buffer with the returned values to get a
     safe high-level string. When the garbage collector cooperates, this
     allows for the process to be performed without an extra copy.
     Make sure to call keep_buffer_alive_until_here on the returned values.
     """
     new_buf = mallocfn(count)
     pinned = 0
     if rgc.can_move(new_buf):
         if rgc.pin(new_buf):
             pinned = 1
         else:
             raw_buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
             return raw_buf, new_buf, 2
     #
     # following code is executed if:
     # - rgc.can_move(data) and rgc.pin(data) both returned true
     # - rgc.can_move(data) returned false
     data_start = cast_ptr_to_adr(new_buf) + \
         offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
     return cast(TYPEP, data_start), new_buf, pinned
示例#9
0
文件: func.py 项目: mozillazg/pypy
def get_raw_address_of_string(space, w_x):
    """Special case for ffi.from_buffer(string).  Returns a 'char *' that
    is valid as long as the string object is alive.  Two calls to
    ffi.from_buffer(same_string) are guaranteed to return the same pointer.
    """
    from rpython.rtyper.annlowlevel import llstr
    from rpython.rtyper.lltypesystem.rstr import STR
    from rpython.rtyper.lltypesystem import llmemory
    from rpython.rlib import rgc

    cache = space.fromcache(RawBytesCache)
    rawbytes = cache.wdict.get(w_x)
    if rawbytes is None:
        data = space.str_w(w_x)
        if we_are_translated() and not rgc.can_move(data):
            lldata = llstr(data)
            data_start = (llmemory.cast_ptr_to_adr(lldata) +
                          rffi.offsetof(STR, 'chars') +
                          llmemory.itemoffsetof(STR.chars, 0))
            data_start = rffi.cast(rffi.CCHARP, data_start)
            data_start[len(data)] = '\x00'   # write the final extra null
            return data_start
        rawbytes = RawBytes(data)
        cache.wdict.set(w_x, rawbytes)
    return rawbytes.ptr
示例#10
0
 def ll_string2list(RESLIST, src):
     length = len(src.chars)
     lst = RESLIST.ll_newlist(length)
     dst = lst.ll_items()
     SRC = typeOf(src).TO  # STR or UNICODE
     DST = typeOf(dst).TO  # GcArray
     assert DST.OF is SRC.chars.OF
     # from here, no GC operations can happen
     asrc = llmemory.cast_ptr_to_adr(src) + (llmemory.offsetof(
         SRC, 'chars') + llmemory.itemoffsetof(SRC.chars, 0))
     adst = llmemory.cast_ptr_to_adr(dst) + llmemory.itemoffsetof(DST, 0)
     llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(DST.OF) * length)
     # end of "no GC" section
     keepalive_until_here(src)
     keepalive_until_here(dst)
     return lst
示例#11
0
文件: rgc.py 项目: yuanleilei/pypy
def ll_shrink_array(p, smallerlength):
    from rpython.rtyper.lltypesystem.lloperation import llop
    from rpython.rlib.objectmodel import keepalive_until_here

    if llop.shrink_array(lltype.Bool, p, smallerlength):
        return p  # done by the GC
    # XXX we assume for now that the type of p is GcStruct containing a
    # variable array, with no further pointers anywhere, and exactly one
    # field in the fixed part -- like STR and UNICODE.

    TP = lltype.typeOf(p).TO
    newp = lltype.malloc(TP, smallerlength)

    assert len(TP._names) == 2
    field = getattr(p, TP._names[0])
    setattr(newp, TP._names[0], field)

    ARRAY = getattr(TP, TP._arrayfld)
    offset = (llmemory.offsetof(TP, TP._arrayfld) +
              llmemory.itemoffsetof(ARRAY, 0))
    source_addr = llmemory.cast_ptr_to_adr(p) + offset
    dest_addr = llmemory.cast_ptr_to_adr(newp) + offset
    llmemory.raw_memcopy(source_addr, dest_addr,
                         llmemory.sizeof(ARRAY.OF) * smallerlength)

    keepalive_until_here(p)
    keepalive_until_here(newp)
    return newp
示例#12
0
文件: rffi.py 项目: Darriall/pypy
    def get_nonmovingbuffer(data):
        """
        Either returns a non-moving copy or performs neccessary pointer
        arithmetic to return a pointer to the characters of a string if the
        string is already nonmovable or could be pinned.  Must be followed by a
        free_nonmovingbuffer call.

        First bool returned indicates if 'data' was pinned. Second bool returned
        indicates if we did a raw alloc because pinning failed. Both bools
        should never be true at the same time.
        """

        lldata = llstrtype(data)
        count = len(data)

        pinned = False
        if rgc.can_move(data):
            if rgc.pin(data):
                pinned = True
            else:
                buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
                copy_string_to_raw(lldata, buf, 0, count)
                return buf, pinned, True
                # ^^^ raw malloc used to get a nonmovable copy
        #
        # following code is executed if:
        # - rgc.can_move(data) and rgc.pin(data) both returned true
        # - rgc.can_move(data) returned false
        data_start = cast_ptr_to_adr(lldata) + \
            offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)

        return cast(TYPEP, data_start), pinned, False
示例#13
0
文件: rstr.py 项目: soIu/rpython
 def copy_string_to_raw(src, ptrdst, srcstart, length):
     """
     Copies 'length' characters from the 'src' string to the 'ptrdst'
     buffer, starting at position 'srcstart'.
     'ptrdst' must be a non-gc Array of Char.
     """
     # xxx Warning: same note as above apply: don't do this at home
     assert length >= 0
     #
     # If the 'split_gc_address_space' option is set, we must copy
     # manually, character-by-character
     if rgc.must_split_gc_address_space():
         i = 0
         while i < length:
             ptrdst[i] = src.chars[srcstart + i]
             i += 1
         return
     #
     # from here, no GC operations can happen
     asrc = _get_raw_buf(SRC_TP, src, srcstart)
     adst = llmemory.cast_ptr_to_adr(ptrdst)
     adst = adst + llmemory.itemoffsetof(typeOf(ptrdst).TO, 0)
     llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(CHAR_TP) * length)
     # end of "no GC" section
     keepalive_until_here(src)
示例#14
0
def ll_shrink_array(p, smallerlength):
    from rpython.rtyper.lltypesystem.lloperation import llop
    from rpython.rlib.objectmodel import keepalive_until_here

    if llop.shrink_array(lltype.Bool, p, smallerlength):
        return p  # done by the GC
    # XXX we assume for now that the type of p is GcStruct containing a
    # variable array, with no further pointers anywhere, and exactly one
    # field in the fixed part -- like STR and UNICODE.

    TP = lltype.typeOf(p).TO
    newp = lltype.malloc(TP, smallerlength)

    assert len(TP._names) == 2
    field = getattr(p, TP._names[0])
    setattr(newp, TP._names[0], field)

    ARRAY = getattr(TP, TP._arrayfld)
    offset = llmemory.offsetof(TP, TP._arrayfld) + llmemory.itemoffsetof(ARRAY, 0)
    source_addr = llmemory.cast_ptr_to_adr(p) + offset
    dest_addr = llmemory.cast_ptr_to_adr(newp) + offset
    llmemory.raw_memcopy(source_addr, dest_addr, llmemory.sizeof(ARRAY.OF) * smallerlength)

    keepalive_until_here(p)
    keepalive_until_here(newp)
    return newp
示例#15
0
 def f():
     a = llstr("xyz")
     b = (llmemory.cast_ptr_to_adr(a) +
          llmemory.offsetof(STR, 'chars') +
          llmemory.itemoffsetof(STR.chars, 0))
     buf = rffi.cast(rffi.VOIDP, b)
     return buf[2]
示例#16
0
文件: rffi.py 项目: sota/pypy-old
 def alloc_buffer(count):
     """
     Returns a (raw_buffer, gc_buffer, case_num) triple,
     allocated with count bytes.
     The raw_buffer can be safely passed to a native function which expects
     it to not move. Call str_from_buffer with the returned values to get a
     safe high-level string. When the garbage collector cooperates, this
     allows for the process to be performed without an extra copy.
     Make sure to call keep_buffer_alive_until_here on the returned values.
     """
     new_buf = mallocfn(count)
     pinned = 0
     if rgc.can_move(new_buf):
         if rgc.pin(new_buf):
             pinned = 1
         else:
             raw_buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
             return raw_buf, new_buf, 2
     #
     # following code is executed if:
     # - rgc.can_move(data) and rgc.pin(data) both returned true
     # - rgc.can_move(data) returned false
     data_start = cast_ptr_to_adr(new_buf) + \
         offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
     return cast(TYPEP, data_start), new_buf, pinned
示例#17
0
文件: rffi.py 项目: sota/pypy-old
    def get_nonmovingbuffer(data):
        """
        Either returns a non-moving copy or performs neccessary pointer
        arithmetic to return a pointer to the characters of a string if the
        string is already nonmovable or could be pinned.  Must be followed by a
        free_nonmovingbuffer call.

        First bool returned indicates if 'data' was pinned. Second bool returned
        indicates if we did a raw alloc because pinning failed. Both bools
        should never be true at the same time.
        """

        lldata = llstrtype(data)
        count = len(data)

        pinned = False
        if rgc.can_move(data):
            if rgc.pin(data):
                pinned = True
            else:
                buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
                copy_string_to_raw(lldata, buf, 0, count)
                return buf, pinned, True
                # ^^^ raw malloc used to get a nonmovable copy
        #
        # following code is executed if:
        # - rgc.can_move(data) and rgc.pin(data) both returned true
        # - rgc.can_move(data) returned false
        data_start = cast_ptr_to_adr(lldata) + \
            offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)

        return cast(TYPEP, data_start), pinned, False
示例#18
0
文件: misc.py 项目: kipras/pypy
def _raw_memcopy_opaque(source, dest, size):
    # push push push at the llmemory interface (with hacks that are all
    # removed after translation)
    zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
    llmemory.raw_memcopy(
        llmemory.cast_ptr_to_adr(source) + zero,
        llmemory.cast_ptr_to_adr(dest) + zero,
        size * llmemory.sizeof(lltype.Char))
示例#19
0
def _raw_memcopy_opaque(source, dest, size):
    # push push push at the llmemory interface (with hacks that are all
    # removed after translation)
    zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
    llmemory.raw_memcopy(
        llmemory.cast_ptr_to_adr(source) + zero,
        llmemory.cast_ptr_to_adr(dest) + zero,
        size * llmemory.sizeof(lltype.Char))
示例#20
0
文件: rstr.py 项目: mozillazg/pypy
 def ll_string2list(RESLIST, src):
     length = len(src.chars)
     lst = RESLIST.ll_newlist(length)
     dst = lst.ll_items()
     SRC = typeOf(src).TO     # STR or UNICODE
     DST = typeOf(dst).TO     # GcArray
     assert DST.OF is SRC.chars.OF
     # from here, no GC operations can happen
     asrc = llmemory.cast_ptr_to_adr(src) + (
         llmemory.offsetof(SRC, 'chars') +
         llmemory.itemoffsetof(SRC.chars, 0))
     adst = llmemory.cast_ptr_to_adr(dst) + llmemory.itemoffsetof(DST, 0)
     llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(DST.OF) * length)
     # end of "no GC" section
     keepalive_until_here(src)
     keepalive_until_here(dst)
     return lst
示例#21
0
def str_storage_getitem(TP, s, byte_offset):
    # WARNING: the 'byte_offset' is, as its name says, measured in bytes;
    # however, it should be aligned for TP, otherwise on some platforms this
    # code will crash!
    lls = llstr(s)
    base_ofs = (llmemory.offsetof(STR, 'chars') +
                llmemory.itemoffsetof(STR.chars, 0))
    scale_factor = llmemory.sizeof(lltype.Char)
    return llop.gc_load_indexed(TP, lls, byte_offset, scale_factor, base_ofs)
示例#22
0
def str_storage_getitem(TP, s, byte_offset):
    # WARNING: the 'byte_offset' is, as its name says, measured in bytes;
    # however, it should be aligned for TP, otherwise on some platforms this
    # code will crash!
    lls = llstr(s)
    base_ofs = (llmemory.offsetof(STR, 'chars') +
                llmemory.itemoffsetof(STR.chars, 0))
    scale_factor = llmemory.sizeof(lltype.Char)
    return llop.gc_load_indexed(TP, lls, byte_offset,
                                scale_factor, base_ofs)
示例#23
0
文件: rgc.py 项目: yuanleilei/pypy
def ll_arrayclear(p):
    # Equivalent to memset(array, 0).  Only for GcArray(primitive-type) for now.
    from rpython.rlib.objectmodel import keepalive_until_here

    length = len(p)
    ARRAY = lltype.typeOf(p).TO
    offset = llmemory.itemoffsetof(ARRAY, 0)
    dest_addr = llmemory.cast_ptr_to_adr(p) + offset
    llmemory.raw_memclear(dest_addr, llmemory.sizeof(ARRAY.OF) * length)
    keepalive_until_here(p)
示例#24
0
def ll_arrayclear(p):
    # Equivalent to memset(array, 0).  Only for GcArray(primitive-type) for now.
    from rpython.rlib.objectmodel import keepalive_until_here

    length = len(p)
    ARRAY = lltype.typeOf(p).TO
    offset = llmemory.itemoffsetof(ARRAY, 0)
    dest_addr = llmemory.cast_ptr_to_adr(p) + offset
    llmemory.raw_memclear(dest_addr, llmemory.sizeof(ARRAY.OF) * length)
    keepalive_until_here(p)
示例#25
0
文件: rgc.py 项目: Qointum/pypy
def ll_arraycopy(source, dest, source_start, dest_start, length):
    from rpython.rtyper.lltypesystem.lloperation import llop
    from rpython.rlib.objectmodel import keepalive_until_here

    # XXX: Hack to ensure that we get a proper effectinfo.write_descrs_arrays
    # and also, maybe, speed up very small cases
    if length <= 1:
        if length == 1:
            copy_item(source, dest, source_start, dest_start)
        return

    # supports non-overlapping copies only
    if not we_are_translated():
        if source == dest:
            assert (source_start + length <= dest_start or
                    dest_start + length <= source_start)

    TP = lltype.typeOf(source).TO
    assert TP == lltype.typeOf(dest).TO
    if _contains_gcptr(TP.OF):
        # perform a write barrier that copies necessary flags from
        # source to dest
        if not llop.gc_writebarrier_before_copy(lltype.Bool, source, dest,
                                                source_start, dest_start,
                                                length):
            # if the write barrier is not supported, copy by hand
            i = 0
            while i < length:
                copy_item(source, dest, i + source_start, i + dest_start)
                i += 1
            return
    source_addr = llmemory.cast_ptr_to_adr(source)
    dest_addr   = llmemory.cast_ptr_to_adr(dest)
    cp_source_addr = (source_addr + llmemory.itemoffsetof(TP, 0) +
                      llmemory.sizeof(TP.OF) * source_start)
    cp_dest_addr = (dest_addr + llmemory.itemoffsetof(TP, 0) +
                    llmemory.sizeof(TP.OF) * dest_start)

    llmemory.raw_memcopy(cp_source_addr, cp_dest_addr,
                         llmemory.sizeof(TP.OF) * length)
    keepalive_until_here(source)
    keepalive_until_here(dest)
示例#26
0
def longername(a, b, size):
    if 1:
        baseofs = itemoffsetof(TP, 0)
        onesize = sizeof(TP.OF)
        size = baseofs + onesize * (size - 1)
        raw_memcopy(cast_ptr_to_adr(b) + baseofs, cast_ptr_to_adr(a) + baseofs, size)
    else:
        a = []
        for i in range(x):
            a.append(i)
    return 0
示例#27
0
    def copy_raw_to_string(ptrsrc, dst, dststart, length):
        # xxx Warning: same note as above apply: don't do this at home
        assert length >= 0
        # from here, no GC operations can happen
        adst = _get_raw_buf(SRC_TP, dst, dststart)
        asrc = llmemory.cast_ptr_to_adr(ptrsrc)

        asrc = asrc + llmemory.itemoffsetof(typeOf(ptrsrc).TO, 0)
        llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(CHAR_TP) * length)
        # end of "no GC" section
        keepalive_until_here(dst)
示例#28
0
文件: rstr.py 项目: mozillazg/pypy
    def copy_raw_to_string(ptrsrc, dst, dststart, length):
        # xxx Warning: same note as above apply: don't do this at home
        assert length >= 0
        # from here, no GC operations can happen
        adst = _get_raw_buf(SRC_TP, dst, dststart)
        asrc = llmemory.cast_ptr_to_adr(ptrsrc)

        asrc = asrc + llmemory.itemoffsetof(typeOf(ptrsrc).TO, 0)
        llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(CHAR_TP) * length)
        # end of "no GC" section
        keepalive_until_here(dst)
示例#29
0
文件: llinterp.py 项目: pypyjs/pypy
 def getinneraddr(self, obj, *offsets):
     TYPE = lltype.typeOf(obj).TO
     addr = llmemory.cast_ptr_to_adr(obj)
     for o in offsets:
         if isinstance(o, str):
             addr += llmemory.offsetof(TYPE, o)
             TYPE = getattr(TYPE, o)
         else:
             addr += llmemory.itemoffsetof(TYPE, o)
             TYPE = TYPE.OF
     return addr, TYPE
示例#30
0
 def getinneraddr(self, obj, *offsets):
     TYPE = lltype.typeOf(obj).TO
     addr = llmemory.cast_ptr_to_adr(obj)
     for o in offsets:
         if isinstance(o, str):
             addr += llmemory.offsetof(TYPE, o)
             TYPE = getattr(TYPE, o)
         else:
             addr += llmemory.itemoffsetof(TYPE, o)
             TYPE = TYPE.OF
     return addr, TYPE
示例#31
0
文件: test_llop.py 项目: soIu/rpython
def newlist_and_gc_store(TYPE, value):
    size = rffi.sizeof(TYPE)
    lst = resizable_list_supporting_raw_ptr(['\x00'] * size)
    ll_data = ll_for_resizable_list(lst)
    ll_items = ll_data.items
    LIST = lltype.typeOf(ll_data).TO  # rlist.LIST_OF(lltype.Char)
    base_ofs = llmemory.itemoffsetof(LIST.items.TO, 0)
    scale_factor = llmemory.sizeof(lltype.Char)
    value = lltype.cast_primitive(TYPE, value)
    llop.gc_store_indexed(lltype.Void, ll_items, 0, value, scale_factor,
                          base_ofs)
    return lst
示例#32
0
def test_offsetof_nogc():
    ARR = lltype.Array(lltype.Signed)
    offsetx = llmemory.arraylengthoffset(ARR)
    offsety = llmemory.itemoffsetof(ARR, 0)
    ARR2 = lltype.GcArray(lltype.Signed)
    offsetx2 = llmemory.arraylengthoffset(ARR2)
    offsety2 = llmemory.itemoffsetof(ARR2, 0)

    def f():
        a = lltype.malloc(ARR, 5, flavor='raw')
        a2 = lltype.malloc(ARR2, 6, flavor='raw')
        a2[0] = 1
        a[0] = 3
        adr = llmemory.cast_ptr_to_adr(a)
        adr2 = llmemory.cast_ptr_to_adr(a2)
        return ((adr + offsetx).signed[0] * 1000 +
                (adr + offsety).signed[0] * 100 +
                (adr2 + offsetx2).signed[0] * 10 + (adr2 + offsety2).signed[0])

    fn = compile(f, [])
    res = fn()
    assert res == 5361
示例#33
0
def longername(a, b, size):
    if 1:
        baseofs = itemoffsetof(TP, 0)
        onesize = sizeof(TP.OF)
        size = baseofs + onesize * (size - 1)
        raw_memcopy(
            cast_ptr_to_adr(b) + baseofs,
            cast_ptr_to_adr(a) + baseofs, size)
    else:
        a = []
        for i in range(x):
            a.append(i)
    return 0
示例#34
0
def test_offsetof_nogc():
    ARR = lltype.Array(lltype.Signed)
    offsetx = llmemory.arraylengthoffset(ARR)
    offsety = llmemory.itemoffsetof(ARR, 0)
    ARR2 = lltype.GcArray(lltype.Signed)
    offsetx2 = llmemory.arraylengthoffset(ARR2)
    offsety2 = llmemory.itemoffsetof(ARR2, 0)

    def f():
        a = lltype.malloc(ARR, 5, flavor='raw')
        a2 = lltype.malloc(ARR2, 6, flavor='raw')
        a2[0] = 1
        a[0] = 3
        adr = llmemory.cast_ptr_to_adr(a)
        adr2 = llmemory.cast_ptr_to_adr(a2)
        return ((adr + offsetx).signed[0] * 1000 +
                (adr + offsety).signed[0] * 100 +
                (adr2 + offsetx2).signed[0] * 10 + (adr2 + offsety2).signed[0])

    fn = compile(f, [])
    res = fn()
    assert res == 5361
示例#35
0
文件: rffi.py 项目: charred/pypy
    def str_from_buffer(raw_buf, gc_buf, allocated_size, needed_size):
        """
        Converts from a pair returned by alloc_buffer to a high-level string.
        The returned string will be truncated to needed_size.
        """
        assert allocated_size >= needed_size

        if gc_buf and (allocated_size == needed_size):
            return hlstrtype(gc_buf)

        new_buf = lltype.malloc(STRTYPE, needed_size)
        str_chars_offset = (offsetof(STRTYPE, 'chars') + \
                            itemoffsetof(STRTYPE.chars, 0))
        if gc_buf:
            src = cast_ptr_to_adr(gc_buf) + str_chars_offset
        else:
            src = cast_ptr_to_adr(raw_buf) + itemoffsetof(TYPEP.TO, 0)
        dest = cast_ptr_to_adr(new_buf) + str_chars_offset
        raw_memcopy(src, dest,
                    llmemory.sizeof(ll_char_type) * needed_size)
        keepalive_until_here(gc_buf)
        keepalive_until_here(new_buf)
        return hlstrtype(new_buf)
示例#36
0
文件: rgc.py 项目: yuanleilei/pypy
def ll_write_final_null_char(s):
    """'s' is a low-level STR; writes a terminating NULL character after
    the other characters in 's'.  Warning, this only works because of
    the 'extra_item_after_alloc' hack inside the definition of STR.
    """
    from rpython.rtyper.lltypesystem import rffi
    PSTR = lltype.typeOf(s)
    assert has_final_null_char(PSTR) == 1
    n = llmemory.offsetof(PSTR.TO, 'chars')
    n += llmemory.itemoffsetof(PSTR.TO.chars, 0)
    n = llmemory.raw_malloc_usage(n)
    n += len(s.chars)
    # no GC operation from here!
    ptr = rffi.cast(rffi.CCHARP, s)
    ptr[n] = '\x00'
示例#37
0
文件: rstr.py 项目: mozillazg/pypy
 def copy_string_to_raw(src, ptrdst, srcstart, length):
     """
     Copies 'length' characters from the 'src' string to the 'ptrdst'
     buffer, starting at position 'srcstart'.
     'ptrdst' must be a non-gc Array of Char.
     """
     # xxx Warning: same note as above apply: don't do this at home
     assert length >= 0
     # from here, no GC operations can happen
     asrc = _get_raw_buf(SRC_TP, src, srcstart)
     adst = llmemory.cast_ptr_to_adr(ptrdst)
     adst = adst + llmemory.itemoffsetof(typeOf(ptrdst).TO, 0)
     llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(CHAR_TP) * length)
     # end of "no GC" section
     keepalive_until_here(src)
示例#38
0
 def copy_string_to_raw(src, ptrdst, srcstart, length):
     """
     Copies 'length' characters from the 'src' string to the 'ptrdst'
     buffer, starting at position 'srcstart'.
     'ptrdst' must be a non-gc Array of Char.
     """
     # xxx Warning: same note as above apply: don't do this at home
     assert length >= 0
     # from here, no GC operations can happen
     asrc = _get_raw_buf(SRC_TP, src, srcstart)
     adst = llmemory.cast_ptr_to_adr(ptrdst)
     adst = adst + llmemory.itemoffsetof(typeOf(ptrdst).TO, 0)
     llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(CHAR_TP) * length)
     # end of "no GC" section
     keepalive_until_here(src)
示例#39
0
文件: rgc.py 项目: mozillazg/pypy
def ll_write_final_null_char(s):
    """'s' is a low-level STR; writes a terminating NULL character after
    the other characters in 's'.  Warning, this only works because of
    the 'extra_item_after_alloc' hack inside the definition of STR.
    """
    from rpython.rtyper.lltypesystem import rffi
    PSTR = lltype.typeOf(s)
    assert has_final_null_char(PSTR) == 1
    n = llmemory.offsetof(PSTR.TO, 'chars')
    n += llmemory.itemoffsetof(PSTR.TO.chars, 0)
    n = llmemory.raw_malloc_usage(n)
    n += len(s.chars)
    # no GC operation from here!
    ptr = rffi.cast(rffi.CCHARP, s)
    ptr[n] = '\x00'
示例#40
0
 def free_nonmovingbuffer(data, buf):
     """
     Either free a non-moving buffer or keep the original storage alive.
     """
     # We cannot rely on rgc.can_move(data) here, because its result
     # might have changed since get_nonmovingbuffer().  Instead we check
     # if 'buf' points inside 'data'.  This is only possible if we
     # followed the 2nd case in get_nonmovingbuffer(); in the first case,
     # 'buf' points to its own raw-malloced memory.
     data = llstrtype(data)
     data_start = cast_ptr_to_adr(data) + \
         offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
     followed_2nd_path = (buf == cast(TYPEP, data_start))
     keepalive_until_here(data)
     if not followed_2nd_path:
         lltype.free(buf, flavor='raw')
示例#41
0
 def get_nonmovingbuffer(data):
     """
     Either returns a non-moving copy or performs neccessary pointer
     arithmetic to return a pointer to the characters of a string if the
     string is already nonmovable.  Must be followed by a
     free_nonmovingbuffer call.
     """
     lldata = llstrtype(data)
     if rgc.can_move(data):
         count = len(data)
         buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
         copy_string_to_raw(lldata, buf, 0, count)
         return buf
     else:
         data_start = cast_ptr_to_adr(lldata) + \
             offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
         return cast(TYPEP, data_start)
示例#42
0
文件: rgc.py 项目: sota/pypy
def ll_arrayclear(p):
    # Equivalent to memset(array, 0).  Only for GcArray(primitive-type) for now.
    from rpython.rlib.objectmodel import keepalive_until_here

    length = len(p)
    ARRAY = lltype.typeOf(p).TO
    if must_split_gc_address_space():
        # do the clearing element by element
        from rpython.rtyper.lltypesystem import rffi
        ZERO = rffi.cast(ARRAY.OF, 0)
        i = 0
        while i < length:
            p[i] = ZERO
            i += 1
    else:
        offset = llmemory.itemoffsetof(ARRAY, 0)
        dest_addr = llmemory.cast_ptr_to_adr(p) + offset
        llmemory.raw_memclear(dest_addr, llmemory.sizeof(ARRAY.OF) * length)
    keepalive_until_here(p)
示例#43
0
def test_itemoffsetof_fixedsizearray():
    ARRAY = lltype.FixedSizeArray(lltype.Signed, 5)
    itemoffsets = [llmemory.itemoffsetof(ARRAY, i) for i in range(5)]
    a = lltype.malloc(ARRAY, immortal=True)
    def f():
        adr = llmemory.cast_ptr_to_adr(a)
        result = 0
        for i in range(5):
            a[i] = i + 1
        for i in range(5):
            result = result * 10 + (adr + itemoffsets[i]).signed[0]
        for i in range(5):
            (adr + itemoffsets[i]).signed[0] = i
        for i in range(5):
            result = 10 * result + a[i]
        return result
    fn = compile(f, [])
    res = fn()
    assert res == 1234501234
示例#44
0
def test_itemoffsetof_fixedsizearray():
    ARRAY = lltype.FixedSizeArray(lltype.Signed, 5)
    itemoffsets = [llmemory.itemoffsetof(ARRAY, i) for i in range(5)]
    a = lltype.malloc(ARRAY, immortal=True)

    def f():
        adr = llmemory.cast_ptr_to_adr(a)
        result = 0
        for i in range(5):
            a[i] = i + 1
        for i in range(5):
            result = result * 10 + (adr + itemoffsets[i]).signed[0]
        for i in range(5):
            (adr + itemoffsets[i]).signed[0] = i
        for i in range(5):
            result = 10 * result + a[i]
        return result

    fn = compile(f, [])
    res = fn()
    assert res == 1234501234
示例#45
0
文件: rstr.py 项目: soIu/rpython
    def copy_raw_to_string(ptrsrc, dst, dststart, length):
        # xxx Warning: same note as above apply: don't do this at home
        assert length >= 0
        #
        # If the 'split_gc_address_space' option is set, we must copy
        # manually, character-by-character
        if rgc.must_split_gc_address_space():
            i = 0
            while i < length:
                dst.chars[dststart + i] = ptrsrc[i]
                i += 1
            return
        #
        # from here, no GC operations can happen
        adst = _get_raw_buf(SRC_TP, dst, dststart)
        asrc = llmemory.cast_ptr_to_adr(ptrsrc)

        asrc = asrc + llmemory.itemoffsetof(typeOf(ptrsrc).TO, 0)
        llmemory.raw_memcopy(asrc, adst, llmemory.sizeof(CHAR_TP) * length)
        # end of "no GC" section
        keepalive_until_here(dst)
示例#46
0
 def test_structarray_add(self):
     from rpython.rtyper.lltypesystem import llmemory
     S = Struct("S", ("x", Signed))
     PS = Ptr(S)
     size = llmemory.sizeof(S)
     A = GcArray(S)
     itemoffset = llmemory.itemoffsetof(A, 0)
     def llf(n):
         a = malloc(A, 5)
         a[0].x = 1
         a[1].x = 2
         a[2].x = 3
         a[3].x = 42
         a[4].x = 4
         adr_s = llmemory.cast_ptr_to_adr(a)
         adr_s += itemoffset + size * n
         s = llmemory.cast_adr_to_ptr(adr_s, PS)
         return s.x
     fn = self.getcompiled(llf, [int])
     res = fn(3)
     assert res == 42
示例#47
0
文件: rffi.py 项目: mozillazg/pypy
    def get_nonmovingbuffer(data):
        """
        Either returns a non-moving copy or performs neccessary pointer
        arithmetic to return a pointer to the characters of a string if the
        string is already nonmovable or could be pinned.  Must be followed by a
        free_nonmovingbuffer call.

        Also returns a char:
         * \4: no pinning, returned pointer is inside 'data' which is nonmovable
         * \5: 'data' was pinned, returned pointer is inside
         * \6: pinning failed, returned pointer is raw malloced

        For strings (not unicodes), the len()th character of the resulting
        raw buffer is available, but not initialized.  Use
        get_nonmovingbuffer_final_null() instead of get_nonmovingbuffer()
        to get a regular null-terminated "char *".
        """

        lldata = llstrtype(data)
        count = len(data)

        if we_are_translated_to_c() and not rgc.can_move(data):
            flag = '\x04'
        else:
            if we_are_translated_to_c() and rgc.pin(data):
                flag = '\x05'
            else:
                buf = lltype.malloc(TYPEP.TO, count + (TYPEP is CCHARP),
                                    flavor='raw')
                copy_string_to_raw(lldata, buf, 0, count)
                return buf, '\x06'
                # ^^^ raw malloc used to get a nonmovable copy
        #
        # following code is executed after we're translated to C, if:
        # - rgc.can_move(data) and rgc.pin(data) both returned true
        # - rgc.can_move(data) returned false
        data_start = cast_ptr_to_adr(lldata) + \
            offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)

        return cast(TYPEP, data_start), flag
示例#48
0
def get_raw_buf(ptr):
    ofs = llmemory.itemoffsetof(lltype.typeOf(ptr).TO, 0)
    return llmemory.cast_ptr_to_adr(ptr) + ofs
示例#49
0
 def _get_gc_data_offset():
     return (llmemory.offsetof(STR, 'chars') +
             llmemory.itemoffsetof(STR.chars, 0))
示例#50
0
 def _str_ofs(TP, item):
     return (llmemory.offsetof(TP, 'chars') +
             llmemory.itemoffsetof(TP.chars, 0) +
             llmemory.sizeof(CHAR_TP) * item)
示例#51
0
 def f():
     a = llstr("xyz")
     b = (llmemory.cast_ptr_to_adr(a) + llmemory.offsetof(STR, 'chars')
          + llmemory.itemoffsetof(STR.chars, 0))
     buf = rffi.cast(rffi.VOIDP, b)
     return buf[2]
示例#52
0
文件: rstr.py 项目: mozillazg/pypy
 def _str_ofs(TP, item):
     return (llmemory.offsetof(TP, 'chars') +
             llmemory.itemoffsetof(TP.chars, 0) +
             llmemory.sizeof(CHAR_TP) * item)
示例#53
0
文件: jitframe.py 项目: Darriall/pypy
    ('jf_frame', lltype.Array(lltype.Signed)),
    # note that we keep length field, because it's crucial to have the data
    # about GCrefs here and not in frame info which might change
    adtmeths = {
        'allocate': jitframe_allocate,
        'resolve': jitframe_resolve,
    },
    rtti = True,
))

@specialize.memo()
def getofs(name):
    return llmemory.offsetof(JITFRAME, name)

GCMAPLENGTHOFS = llmemory.arraylengthoffset(GCMAP)
GCMAPBASEOFS = llmemory.itemoffsetof(GCMAP, 0)
BASEITEMOFS = llmemory.itemoffsetof(JITFRAME.jf_frame, 0)
LENGTHOFS = llmemory.arraylengthoffset(JITFRAME.jf_frame)
SIGN_SIZE = llmemory.sizeof(lltype.Signed)
UNSIGN_SIZE = llmemory.sizeof(lltype.Unsigned)
STACK_DEPTH_OFS = getofs('jf_extra_stack_depth')

def jitframe_trace(gc, obj_addr, callback, arg):
    gc._trace_callback(callback, arg, obj_addr + getofs('jf_descr'))
    gc._trace_callback(callback, arg, obj_addr + getofs('jf_force_descr'))
    gc._trace_callback(callback, arg, obj_addr + getofs('jf_savedata'))
    gc._trace_callback(callback, arg, obj_addr + getofs('jf_guard_exc'))
    gc._trace_callback(callback, arg, obj_addr + getofs('jf_forward'))

    if IS_32BIT:
        MAX = 32
示例#54
0
 def setarrayitem(self, array, index, newitem):
     ARRAY = lltype.typeOf(array).TO
     addr = llmemory.cast_ptr_to_adr(array)
     addr += llmemory.itemoffsetof(ARRAY, index)
     self.setinterior(array, addr, ARRAY.OF, newitem, (index,))
示例#55
0
def get_raw_buf(ptr):
    ofs = llmemory.itemoffsetof(lltype.typeOf(ptr).TO, 0)
    return llmemory.cast_ptr_to_adr(ptr) + ofs
示例#56
0
文件: test_llop.py 项目: soIu/rpython
def str_gc_load(TYPE, buf, offset):
    base_ofs = (llmemory.offsetof(STR, 'chars') +
                llmemory.itemoffsetof(STR.chars, 0))
    scale_factor = llmemory.sizeof(lltype.Char)
    lls = llstr(buf)
    return llop.gc_load_indexed(TYPE, lls, offset, scale_factor, base_ofs)
示例#57
0
def get_gc_data_offset_for_list_of_chars():
    LIST = LIST_OF(lltype.Char)
    return llmemory.itemoffsetof(LIST.items.TO, 0)