示例#1
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
示例#2
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
示例#3
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
示例#4
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
示例#5
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
示例#6
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
示例#7
0
 def func():
     #try:
     a = rgc.malloc_nonmovable(TP, 3, zero=True)
     rgc.collect()
     if a:
         assert not rgc.can_move(a)
         return 1
     return 0
示例#8
0
 def fn(n):
     s = str(n)
     if not rgc.can_move(s):
         return 13
     res = int(rgc.pin(s))
     if res:
         rgc.unpin(s)
     return res
 def fn():
     a1 = A()
     a = objectmodel.instantiate(A, nonmovable=True)
     a.next = a1  # 'a' is known young here, so no write barrier emitted
     res = rgc.can_move(annlowlevel.cast_instance_to_base_ptr(a))
     rgc.collect()
     objectmodel.keepalive_until_here(a)
     return res
示例#10
0
 def fn(n):
     s = str(n)
     if not rgc.can_move(s):
         return 13
     res = int(rgc.pin(s))
     if res:
         rgc.unpin(s)
     return res
示例#11
0
 def fn():
     a1 = A()
     a = objectmodel.instantiate(A, nonmovable=True)
     a.next = a1  # 'a' is known young here, so no write barrier emitted
     res = rgc.can_move(annlowlevel.cast_instance_to_base_ptr(a))
     rgc.collect()
     objectmodel.keepalive_until_here(a)
     return res
示例#12
0
 def func():
     try:
         a = rgc.malloc_nonmovable(TP)
         rgc.collect()
         if a:
             assert not rgc.can_move(a)
             return 1
         return 0
     except Exception:
         return 2
示例#13
0
 def fn(n):
     from rpython.rlib.debug import debug_print
     s = str(n)
     if not rgc.can_move(s):
         return 13
     res = int(rgc.pin(s))
     if res:
         res += int(rgc._is_pinned(s))
         rgc.unpin(s)
     return res
示例#14
0
 def fn(n):
     from rpython.rlib.debug import debug_print
     s = str(n)
     if not rgc.can_move(s):
         return 13
     res = int(rgc.pin(s))
     if res:
         res += int(rgc._is_pinned(s))
         rgc.unpin(s)
     return res
示例#15
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)
示例#16
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
示例#17
0
 def func():
     a = rgc.malloc_nonmovable(TP, 3)
     if a:
         assert not rgc.can_move(a)
         return 1
     return 0
示例#18
0
 def func():
     return rgc.can_move(lltype.malloc(TP, 1))
示例#19
0
 def fn():
     return rgc.can_move(A())
示例#20
0
文件: test_rgc.py 项目: sota/pypy-old
 def f(i):
     if i:
         return rgc.can_move(lltype.malloc(T0))
     else:
         return rgc.can_move(lltype.malloc(T1, 1))
示例#21
0
 def fn():
     return rgc.can_move(A())
示例#22
0
 def f(i):
     if i:
         return rgc.can_move(lltype.malloc(T0))
     else:
         return rgc.can_move(lltype.malloc(T1, 1))
示例#23
0
 def func():
     return rgc.can_move(lltype.malloc(TP, 1))