Esempio n. 1
0
def _PyString_Resize(space, ref, newsize):
    """A way to resize a string object even though it is "immutable". Only use this to
    build up a brand new string object; don't use this if the string may already be
    known in other parts of the code.  It is an error to call this function if the
    refcount on the input string object is not one. Pass the address of an existing
    string object as an lvalue (it may be written into), and the new size desired.
    On success, *string holds the resized string object and 0 is returned;
    the address in *string may differ from its input value.  If the reallocation
    fails, the original string object at *string is deallocated, *string is
    set to NULL, a memory exception is set, and -1 is returned.
    """
    # XXX always create a new string so far
    py_str = rffi.cast(PyStringObject, ref[0])
    if not py_str.c_buffer:
        raise OperationError(space.w_SystemError, space.wrap(
            "_PyString_Resize called on already created string"))
    try:
        py_newstr = new_empty_str(space, newsize)
    except MemoryError:
        Py_DecRef(space, ref[0])
        ref[0] = lltype.nullptr(PyObject.TO)
        raise
    to_cp = newsize
    oldsize = py_str.c_size
    if oldsize < newsize:
        to_cp = oldsize
    for i in range(to_cp):
        py_newstr.c_buffer[i] = py_str.c_buffer[i]
    Py_DecRef(space, ref[0])
    ref[0] = rffi.cast(PyObject, py_newstr)
    return 0
Esempio n. 2
0
def frame_dealloc(space, py_obj):
    py_frame = rffi.cast(PyFrameObject, py_obj)
    py_code = rffi.cast(PyObject, py_frame.c_f_code)
    Py_DecRef(space, py_code)
    Py_DecRef(space, py_frame.c_f_globals)
    from pypy.module.cpyext.object import PyObject_dealloc
    PyObject_dealloc(space, py_obj)
Esempio n. 3
0
def PyErr_SetExcInfo(space, w_type, w_value, w_traceback):
    """---Cython extension---

    Set the exception info, as known from ``sys.exc_info()``.  This refers
    to an exception that was already caught, not to an exception that was
    freshly raised.  This function steals the references of the arguments.
    To clear the exception state, pass *NULL* for all three arguments.
    For general rules about the three arguments, see :c:func:`PyErr_Restore`.
 
    .. note::
 
       This function is not normally used by code that wants to handle
       exceptions.  Rather, it can be used when code needs to save and
       restore the exception state temporarily.  Use
       :c:func:`PyErr_GetExcInfo` to read the exception state.
    """
    if w_value is None or space.is_w(w_value, space.w_None):
        operror = None
    else:
        tb = None
        if w_traceback is not None:
            try:
                tb = pytraceback.check_traceback(space, w_traceback, '?')
            except OperationError:  # catch and ignore bogus objects
                pass
        operror = OperationError(w_type, w_value, tb)
    #
    ec = space.getexecutioncontext()
    ec.set_sys_exc_info(operror)
    Py_DecRef(space, w_type)
    Py_DecRef(space, w_value)
    Py_DecRef(space, w_traceback)
Esempio n. 4
0
def slice_dealloc(space, py_obj):
    """Frees allocated PyStringObject resources.
    """
    py_slice = rffi.cast(PySliceObject, py_obj)
    Py_DecRef(space, py_slice.c_start)
    Py_DecRef(space, py_slice.c_stop)
    Py_DecRef(space, py_slice.c_step)
    from pypy.module.cpyext.object import PyObject_dealloc
    PyObject_dealloc(space, py_obj)
Esempio n. 5
0
def PyErr_NormalizeException(space, exc_p, val_p, tb_p):
    """Under certain circumstances, the values returned by PyErr_Fetch() below
    can be "unnormalized", meaning that *exc is a class object but *val is
    not an instance of the  same class.  This function can be used to instantiate
    the class in that case.  If the values are already normalized, nothing happens.
    The delayed normalization is implemented to improve performance."""
    operr = OperationError(from_ref(space, exc_p[0]),
                           from_ref(space, val_p[0]))
    operr.normalize_exception(space)
    Py_DecRef(space, exc_p[0])
    Py_DecRef(space, val_p[0])
    exc_p[0] = make_ref(space, operr.w_type)
    val_p[0] = make_ref(space, operr.get_w_value(space))
Esempio n. 6
0
def finish_type_2(space, pto, w_obj):
    """
    Sets up other attributes, when the interpreter type has been created.
    """
    pto.c_tp_mro = make_ref(space, space.newtuple(w_obj.mro_w))
    base = pto.c_tp_base
    if base:
        inherit_special(space, pto, base)
    for w_base in space.fixedview(from_ref(space, pto.c_tp_bases)):
        inherit_slots(space, pto, w_base)

    if not pto.c_tp_setattro:
        from pypy.module.cpyext.object import PyObject_GenericSetAttr
        pto.c_tp_setattro = llhelper(
            PyObject_GenericSetAttr.api_func.functype,
            PyObject_GenericSetAttr.api_func.get_wrapper(space))

    if not pto.c_tp_getattro:
        from pypy.module.cpyext.object import PyObject_GenericGetAttr
        pto.c_tp_getattro = llhelper(
            PyObject_GenericGetAttr.api_func.functype,
            PyObject_GenericGetAttr.api_func.get_wrapper(space))

    if w_obj.is_cpytype():
        Py_DecRef(space, pto.c_tp_dict)
        w_dict = w_obj.getdict(space)
        pto.c_tp_dict = make_ref(space, w_dict)
Esempio n. 7
0
def _PyTuple_Resize(space, ref, newsize):
    """Can be used to resize a tuple.  newsize will be the new length of the tuple.
    Because tuples are supposed to be immutable, this should only be used if there
    is only one reference to the object.  Do not use this if the tuple may already
    be known to some other part of the code.  The tuple will always grow or shrink
    at the end.  Think of this as destroying the old tuple and creating a new one,
    only more efficiently.  Returns 0 on success. Client code should never
    assume that the resulting value of *p will be the same as before calling
    this function. If the object referenced by *p is replaced, the original
    *p is destroyed.  On failure, returns -1 and sets *p to NULL, and
    raises MemoryError or SystemError."""
    py_tuple = from_ref(space, ref[0])
    if not PyTuple_Check(space, py_tuple):
        PyErr_BadInternalCall(space)
    py_newtuple = PyTuple_New(space, newsize)

    to_cp = newsize
    oldsize = space.int_w(space.len(py_tuple))
    if oldsize < newsize:
        to_cp = oldsize
    for i in range(to_cp):
        _setitem_tuple(py_newtuple, i, space.getitem(py_tuple, space.wrap(i)))
    Py_DecRef(space, ref[0])
    ref[0] = make_ref(space, py_newtuple)
    return 0
Esempio n. 8
0
def PyTuple_SetItem(space, w_t, pos, w_obj):
    if not PyTuple_Check(space, w_t):
        # XXX this should also steal a reference, test it!!!
        PyErr_BadInternalCall(space)
    _setitem_tuple(w_t, pos, w_obj)
    Py_DecRef(space, w_obj)  # SetItem steals a reference!
    return 0
Esempio n. 9
0
def PyObject_AsCharBuffer(space, obj, bufferp, sizep):
    """Returns a pointer to a read-only memory location usable as
    character-based input.  The obj argument must support the single-segment
    character buffer interface.  On success, returns 0, sets buffer to the
    memory location and size to the buffer length.  Returns -1 and sets a
    TypeError on error.
    """
    pto = obj.c_ob_type

    pb = pto.c_tp_as_buffer
    if not (pb and pb.c_bf_getbuffer):
        raise OperationError(
            space.w_TypeError,
            space.wrap("expected an object with the buffer interface"))
    with lltype.scoped_alloc(Py_buffer) as view:
        ret = generic_cpy_call(space, pb.c_bf_getbuffer, obj, view,
                               rffi.cast(rffi.INT_real, PyBUF_SIMPLE))
        if rffi.cast(lltype.Signed, ret) == -1:
            return -1

        bufferp[0] = rffi.cast(rffi.CCHARP, view.c_buf)
        sizep[0] = view.c_len

        if pb.c_bf_releasebuffer:
            generic_cpy_call(space, pb.c_bf_releasebuffer, obj, view)
        Py_DecRef(space, view.c_obj)
    return 0
Esempio n. 10
0
def type_alloc(space, w_metatype, itemsize=0):
    metatype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_metatype))
    # Don't increase refcount for non-heaptypes
    if metatype:
        flags = rffi.cast(lltype.Signed, metatype.c_tp_flags)
        if not flags & Py_TPFLAGS_HEAPTYPE:
            Py_DecRef(space, w_metatype)

    heaptype = lltype.malloc(PyHeapTypeObject.TO,
                             flavor='raw',
                             zero=True,
                             add_memory_pressure=True)
    pto = heaptype.c_ht_type
    pto.c_ob_refcnt = 1
    pto.c_ob_pypy_link = 0
    pto.c_ob_type = metatype
    pto.c_tp_flags |= Py_TPFLAGS_HEAPTYPE
    pto.c_tp_as_number = heaptype.c_as_number
    pto.c_tp_as_sequence = heaptype.c_as_sequence
    pto.c_tp_as_mapping = heaptype.c_as_mapping
    pto.c_tp_as_buffer = heaptype.c_as_buffer
    pto.c_tp_basicsize = -1  # hopefully this makes malloc bail out
    pto.c_tp_itemsize = 0

    return rffi.cast(PyObject, heaptype)
Esempio n. 11
0
def _type_realize(space, py_obj):
    """
    Creates an interpreter type from a PyTypeObject structure.
    """
    # missing:
    # inheriting tp_as_* slots
    # unsupported:
    # tp_mro, tp_subclasses
    py_type = rffi.cast(PyTypeObjectPtr, py_obj)

    if not py_type.c_tp_base:
        # borrowed reference, but w_object is unlikely to disappear
        base = make_ref(space, space.w_object)
        Py_DecRef(space, base)
        py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base)

    finish_type_1(space, py_type)

    w_metatype = from_ref(space, rffi.cast(PyObject, py_type.c_ob_type))

    w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype)
    track_reference(space, py_obj, w_obj)
    w_obj.__init__(space, py_type)
    w_obj.ready()

    finish_type_2(space, py_type, w_obj)

    state = space.fromcache(RefcountState)
    state.non_heaptypes_w.append(w_obj)

    return w_obj
Esempio n. 12
0
def PyString_ConcatAndDel(space, ref, newpart):
    """Create a new string object in *string containing the contents of newpart
    appended to string.  This version decrements the reference count of newpart."""
    try:
        PyString_Concat(space, ref, newpart)
    finally:
        Py_DecRef(space, newpart)
Esempio n. 13
0
def finish_type_2(space, pto, w_obj):
    """
    Sets up other attributes, when the interpreter type has been created.
    """
    pto.c_tp_mro = make_ref(space, space.newtuple(w_obj.mro_w))
    base = pto.c_tp_base
    if base:
        inherit_special(space, pto, w_obj, base)
    for w_base in space.fixedview(from_ref(space, pto.c_tp_bases)):
        if isinstance(w_base, W_TypeObject):
            inherit_slots(space, pto, w_base)
        #else:
        #   w_base is a W_ClassObject, ignore it

    if not pto.c_tp_setattro:
        from pypy.module.cpyext.object import PyObject_GenericSetAttr
        pto.c_tp_setattro = llslot(space, PyObject_GenericSetAttr)

    if not pto.c_tp_getattro:
        from pypy.module.cpyext.object import PyObject_GenericGetAttr
        pto.c_tp_getattro = llslot(space, PyObject_GenericGetAttr)

    if w_obj.is_cpytype():
        Py_DecRef(space, pto.c_tp_dict)
    w_dict = w_obj.getdict(space)
    # pass in the w_obj to convert any values that are
    # unbound GetSetProperty into bound PyGetSetDescrObject
    pto.c_tp_dict = make_ref(space, w_dict, w_obj)
Esempio n. 14
0
def buffer_dealloc(space, py_obj):
    py_buf = rffi.cast(PyBufferObject, py_obj)
    if py_buf.c_b_base:
        Py_DecRef(space, py_buf.c_b_base)
    else:
        rffi.free_charp(rffi.cast(rffi.CCHARP, py_buf.c_b_ptr))
    from pypy.module.cpyext.object import _dealloc
    _dealloc(space, py_obj)
Esempio n. 15
0
 def wrap_result(self, space, lresult):
     space.getbuiltinmodule("cpyext")
     from pypy.module.cpyext.pyobject import PyObject, from_ref, make_ref, Py_DecRef
     result = rffi.cast(PyObject, lresult)
     w_obj = from_ref(space, result)
     if result:
         Py_DecRef(space, result)
     return w_obj
Esempio n. 16
0
def unicode_dealloc(space, py_obj):
    py_unicode = rffi.cast(PyUnicodeObject, py_obj)
    Py_DecRef(space, py_unicode.c_defenc)
    if py_unicode.c_str:
        lltype.free(py_unicode.c_str, flavor="raw")

    from pypy.module.cpyext.object import _dealloc
    _dealloc(space, py_obj)
Esempio n. 17
0
 def test_coerce(self, space):
     w_obj1 = space.wrap(123)
     w_obj2 = space.wrap(456.789)
     pp1 = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
     pp1[0] = make_ref(space, w_obj1)
     pp2 = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
     pp2[0] = make_ref(space, w_obj2)
     assert PyNumber_Coerce(space, pp1, pp2) == 0
     assert space.str_w(space.repr(from_ref(space, pp1[0]))) == '123.0'
     assert space.str_w(space.repr(from_ref(space, pp2[0]))) == '456.789'
     Py_DecRef(space, pp1[0])
     Py_DecRef(space, pp2[0])
     lltype.free(pp1, flavor='raw')
     # Yes, decrement twice since we decoupled between w_obj* and pp*[0].
     Py_DecRef(space, w_obj1)
     Py_DecRef(space, w_obj2)
     lltype.free(pp2, flavor='raw')
Esempio n. 18
0
def PyBuffer_Release(space, view):
    """
    Releases a Py_buffer obtained from getbuffer ParseTuple's s*.

    This is not a complete re-implementation of the CPython API; it only
    provides a subset of CPython's behavior.
    """
    Py_DecRef(space, view.c_obj)
Esempio n. 19
0
def inherit_special(space, pto, base_pto):
    # XXX missing: copy basicsize and flags in a magical way
    flags = rffi.cast(lltype.Signed, pto.c_tp_flags)
    base_object_pyo = make_ref(space, space.w_object)
    base_object_pto = rffi.cast(PyTypeObjectPtr, base_object_pyo)
    if base_pto != base_object_pto or flags & Py_TPFLAGS_HEAPTYPE:
        if not pto.c_tp_new:
            pto.c_tp_new = base_pto.c_tp_new
    Py_DecRef(space, base_object_pyo)
Esempio n. 20
0
def _dealloc(space, obj):
    # This frees an object after its refcount dropped to zero, so we
    # assert that it is really zero here.
    assert obj.c_ob_refcnt == 0
    pto = obj.c_ob_type
    obj_voidp = rffi.cast(rffi.VOIDP, obj)
    generic_cpy_call(space, pto.c_tp_free, obj_voidp)
    if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
        Py_DecRef(space, rffi.cast(PyObject, pto))
Esempio n. 21
0
 def member_setter(self, space, w_self, w_value):
     assert isinstance(self, W_MemberDescr)
     check_descr(space, w_self, self.w_type)
     pyref = make_ref(space, w_self)
     try:
         PyMember_SetOne(
             space, rffi.cast(rffi.CCHARP, pyref), self.member, w_value)
     finally:
         Py_DecRef(space, pyref)
Esempio n. 22
0
def PyException_SetCause(space, w_exc, cause):
    """Set the cause associated with the exception to cause.  Use NULL to clear
    it.  There is no type check to make sure that cause is an exception instance.
    This steals a reference to cause."""
    if cause:
        w_cause = from_ref(space, cause)
        Py_DecRef(space, cause)
    else:
        w_cause = space.w_None
    space.setattr(w_exc, space.wrap('__cause__'), w_cause)
Esempio n. 23
0
def PyException_SetContext(space, w_exc, ctx):
    """Set the context associated with the exception to ctx.  Use NULL to clear
    it.  There is no type check to make sure that ctx is an exception instance.
    This steals a reference to ctx."""
    if ctx:
        w_ctx = from_ref(space, ctx)
        Py_DecRef(space, ctx)
    else:
        w_ctx = space.w_None
    space.setattr(w_exc, space.wrap('__context__'), w_ctx)
Esempio n. 24
0
def PyThreadState_Clear(space, tstate):
    """Reset all information in a thread state object.  The global
    interpreter lock must be held."""
    if not space.config.translation.thread:
        raise NoThreads
    Py_DecRef(space, tstate.c_dict)
    tstate.c_dict = lltype.nullptr(PyObject.TO)
    space.threadlocals.leave_thread(space)
    space.getexecutioncontext().cleanup_cpyext_state()
    rthread.gc_thread_die()
    def test_fromstring(self, space):
        s = rffi.str2charp(u'sp\x09m'.encode("utf-8"))
        w_res = PyUnicode_FromString(space, s)
        assert space.unwrap(w_res) == u'sp\x09m'

        res = PyUnicode_FromStringAndSize(space, s, 4)
        w_res = from_ref(space, res)
        Py_DecRef(space, res)
        assert space.unwrap(w_res) == u'sp\x09m'
        rffi.free_charp(s)
Esempio n. 26
0
def str_getcharbuffer(space, w_str, segment, ref):
    from pypy.module.cpyext.stringobject import PyString_AsString
    if segment != 0:
        raise OperationError(space.w_SystemError, space.wrap
                             ("accessing non-existent string segment"))
    pyref = make_ref(space, w_str)
    ref[0] = PyString_AsString(space, pyref)
    # Stolen reference: the object has better exist somewhere else
    Py_DecRef(space, pyref)
    return space.len_w(w_str)
Esempio n. 27
0
def PyString_Concat(space, ref, w_newpart):
    """Create a new string object in *string containing the contents of newpart
    appended to string; the caller will own the new reference.  The reference to
    the old value of string will be stolen.  If the new string cannot be created,
    the old reference to string will still be discarded and the value of
    *string will be set to NULL; the appropriate exception will be set."""

    if not ref[0]:
        return

    if w_newpart is None or not PyString_Check(space, ref[0]) or \
            not PyString_Check(space, w_newpart):
        Py_DecRef(space, ref[0])
        ref[0] = lltype.nullptr(PyObject.TO)
        return
    w_str = from_ref(space, ref[0])
    w_newstr = space.add(w_str, w_newpart)
    Py_DecRef(space, ref[0])
    ref[0] = make_ref(space, w_newstr)
Esempio n. 28
0
def wrap_binaryfunc_r(space, w_self, w_args, func):
    func_binary = rffi.cast(binaryfunc, func)
    check_num_args(space, w_args, 1)
    args_w = space.fixedview(w_args)
    ref = make_ref(space, w_self)
    if (not ref.c_ob_type.c_tp_flags & Py_TPFLAGS_CHECKTYPES and
        not space.is_true(space.issubtype(space.type(args_w[0]),
                                         space.type(w_self)))):
        return space.w_NotImplemented
    Py_DecRef(space, ref)
    return generic_cpy_call(space, func_binary, args_w[0], w_self)
Esempio n. 29
0
def unicode_getreadbuffer(space, w_str, segment, ref):
    from pypy.module.cpyext.unicodeobject import (
        PyUnicode_AS_UNICODE, PyUnicode_GET_DATA_SIZE)
    if segment != 0:
        raise oefmt(space.w_SystemError,
                    "accessing non-existent unicode segment")
    pyref = make_ref(space, w_str)
    ref[0] = PyUnicode_AS_UNICODE(space, pyref)
    # Stolen reference: the object has better exist somewhere else
    Py_DecRef(space, pyref)
    return PyUnicode_GET_DATA_SIZE(space, w_str)
Esempio n. 30
0
def PyUnicode_Resize(space, ref, newsize):
    # XXX always create a new string so far
    py_uni = rffi.cast(PyUnicodeObject, ref[0])
    if not py_uni.c_str:
        raise oefmt(space.w_SystemError,
                    "PyUnicode_Resize called on already created string")
    try:
        py_newuni = new_empty_unicode(space, newsize)
    except MemoryError:
        Py_DecRef(space, ref[0])
        ref[0] = lltype.nullptr(PyObject.TO)
        raise
    to_cp = newsize
    oldsize = py_uni.c_length
    if oldsize < newsize:
        to_cp = oldsize
    for i in range(to_cp):
        py_newuni.c_str[i] = py_uni.c_str[i]
    Py_DecRef(space, ref[0])
    ref[0] = rffi.cast(PyObject, py_newuni)
    return 0