Exemple #1
0
WEAKREF = lltype.GcStruct("weakref", ("weakptr", llmemory.Address))
WEAKREFPTR = lltype.Ptr(WEAKREF)
sizeof_weakref = llmemory.sizeof(WEAKREF)
empty_weakref = lltype.malloc(WEAKREF, immortal=True)
empty_weakref.weakptr = llmemory.NULL
weakptr_offset = llmemory.offsetof(WEAKREF, "weakptr")


def ll_weakref_deref(wref):
    wref = llmemory.cast_weakrefptr_to_ptr(WEAKREFPTR, wref)
    return wref.weakptr


def convert_weakref_to(targetptr):
    # Prebuilt weakrefs don't really need to be weak at all,
    # but we need to emulate the structure expected by ll_weakref_deref().
    if not targetptr:
        return empty_weakref
    else:
        link = lltype.malloc(WEAKREF, immortal=True)
        link.weakptr = llmemory.cast_ptr_to_adr(targetptr)
        return link


########## finalizers ##########

FIN_TRIGGER_FUNC = lltype.FuncType([], lltype.Void)
FIN_HANDLER_ARRAY = lltype.Array(('deque', llmemory.Address),
                                 ('trigger', lltype.Ptr(FIN_TRIGGER_FUNC)))
Exemple #2
0
class GCData(object):
    """The GC information tables, and the query functions that the GC
    calls to decode their content.  The encoding of this information
    is done by encode_type_shape().  These two places should be in sync,
    obviously, but in principle no other code should depend on the
    details of the encoding in TYPE_INFO.
    """
    _alloc_flavor_ = 'raw'

    OFFSETS_TO_GC_PTR = lltype.Array(lltype.Signed)

    # A CUSTOM_FUNC is either a destructor, or a custom tracer.
    # A destructor is called when the object is about to be freed.
    # A custom tracer (CT) enumerates the addresses that contain GCREFs.
    # Both are called with the address of the object as only argument.
    # They're embedded in a struct that has raw_memory_offset as another
    # argument, which is only valid if T_HAS_MEMORY_PRESSURE is set
    CUSTOM_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
    CUSTOM_FUNC_PTR = lltype.Ptr(CUSTOM_FUNC)
    CUSTOM_DATA_STRUCT = lltype.Struct(
        'custom_data',
        ('customfunc', CUSTOM_FUNC_PTR),
        ('memory_pressure_offset',
         lltype.Signed),  # offset to where the amount
        # of owned memory pressure is stored
    )
    CUSTOM_DATA_STRUCT_PTR = lltype.Ptr(CUSTOM_DATA_STRUCT)

    # structure describing the layout of a typeid
    TYPE_INFO = lltype.Struct(
        "type_info",
        ("infobits", lltype.Signed),  # combination of the T_xxx consts
        ("customdata", CUSTOM_DATA_STRUCT_PTR),
        ("fixedsize", lltype.Signed),
        ("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
        hints={'immutable': True},
    )
    VARSIZE_TYPE_INFO = lltype.Struct(
        "varsize_type_info",
        ("header", TYPE_INFO),
        ("varitemsize", lltype.Signed),
        ("ofstovar", lltype.Signed),
        ("ofstolength", lltype.Signed),
        ("varofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
        hints={'immutable': True},
    )
    TYPE_INFO_PTR = lltype.Ptr(TYPE_INFO)
    VARSIZE_TYPE_INFO_PTR = lltype.Ptr(VARSIZE_TYPE_INFO)

    def __init__(self, type_info_group):
        assert isinstance(type_info_group, llgroup.group)
        self.type_info_group = type_info_group
        self.type_info_group_ptr = type_info_group._as_ptr()

    def get(self, typeid):
        res = llop.get_group_member(GCData.TYPE_INFO_PTR,
                                    self.type_info_group_ptr, typeid)
        _check_valid_type_info(res)
        return res

    def get_varsize(self, typeid):
        res = llop.get_group_member(GCData.VARSIZE_TYPE_INFO_PTR,
                                    self.type_info_group_ptr, typeid)
        _check_valid_type_info_varsize(res)
        return res

    def q_is_varsize(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_IS_VARSIZE) != 0

    def q_has_gcptr_in_varsize(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_HAS_GCPTR_IN_VARSIZE) != 0

    def q_has_gcptr(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_HAS_GCPTR) != 0

    def q_is_gcarrayofgcptr(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_IS_GCARRAY_OF_GCPTR) != 0

    def q_cannot_pin(self, typeid):
        typeinfo = self.get(typeid)
        ANY = (T_HAS_GCPTR | T_IS_WEAKREF)
        return (typeinfo.infobits & ANY) != 0 or bool(typeinfo.customdata)

    def q_finalizer_handlers(self):
        adr = self.finalizer_handlers  # set from framework.py or gcwrapper.py
        return llmemory.cast_adr_to_ptr(adr, lltype.Ptr(FIN_HANDLER_ARRAY))

    def q_destructor_or_custom_trace(self, typeid):
        if not self.get(typeid).customdata:
            return lltype.nullptr(GCData.CUSTOM_FUNC_PTR.TO)
        return self.get(typeid).customdata.customfunc

    def q_is_old_style_finalizer(self, typeid):
        typeinfo = self.get(typeid)
        return (typeinfo.infobits & T_HAS_OLDSTYLE_FINALIZER) != 0

    def q_offsets_to_gc_pointers(self, typeid):
        return self.get(typeid).ofstoptrs

    def q_fixed_size(self, typeid):
        return self.get(typeid).fixedsize

    def q_varsize_item_sizes(self, typeid):
        return self.get_varsize(typeid).varitemsize

    def q_varsize_offset_to_variable_part(self, typeid):
        return self.get_varsize(typeid).ofstovar

    def q_varsize_offset_to_length(self, typeid):
        return self.get_varsize(typeid).ofstolength

    def q_varsize_offsets_to_gcpointers_in_var_part(self, typeid):
        return self.get_varsize(typeid).varofstoptrs

    def q_weakpointer_offset(self, typeid):
        infobits = self.get(typeid).infobits
        if infobits & T_IS_WEAKREF:
            return weakptr_offset
        return -1

    def q_member_index(self, typeid):
        infobits = self.get(typeid).infobits
        return infobits & T_MEMBER_INDEX

    def q_is_rpython_class(self, typeid):
        infobits = self.get(typeid).infobits
        return infobits & T_IS_RPYTHON_INSTANCE != 0

    def q_has_custom_trace(self, typeid):
        infobits = self.get(typeid).infobits
        return infobits & T_HAS_CUSTOM_TRACE != 0

    def q_fast_path_tracing(self, typeid):
        # return True if none of the flags T_HAS_GCPTR_IN_VARSIZE,
        # T_IS_GCARRAY_OF_GCPTR or T_HAS_CUSTOM_TRACE is set
        T_ANY_SLOW_FLAG = (T_HAS_GCPTR_IN_VARSIZE | T_IS_GCARRAY_OF_GCPTR
                           | T_HAS_CUSTOM_TRACE)
        infobits = self.get(typeid).infobits
        return infobits & T_ANY_SLOW_FLAG == 0

    def q_has_memory_pressure(self, typeid):
        infobits = self.get(typeid).infobits
        return infobits & T_HAS_MEMORY_PRESSURE != 0

    def q_get_memory_pressure_ofs(self, typeid):
        infobits = self.get(typeid).infobits
        assert infobits & T_HAS_MEMORY_PRESSURE != 0
        return self.get(typeid).customdata.memory_pressure_offset

    def set_query_functions(self, gc):
        gc.set_query_functions(
            self.q_is_varsize, self.q_has_gcptr_in_varsize,
            self.q_is_gcarrayofgcptr, self.q_finalizer_handlers,
            self.q_destructor_or_custom_trace, self.q_is_old_style_finalizer,
            self.q_offsets_to_gc_pointers, self.q_fixed_size,
            self.q_varsize_item_sizes, self.q_varsize_offset_to_variable_part,
            self.q_varsize_offset_to_length,
            self.q_varsize_offsets_to_gcpointers_in_var_part,
            self.q_weakpointer_offset, self.q_member_index,
            self.q_is_rpython_class, self.q_has_custom_trace,
            self.q_fast_path_tracing, self.q_has_gcptr, self.q_cannot_pin,
            self.q_has_memory_pressure, self.q_get_memory_pressure_ofs)

    def _has_got_custom_trace(self, typeid):
        type_info = self.get(typeid)
        type_info.infobits |= (T_HAS_CUSTOM_TRACE | T_HAS_GCPTR)
Exemple #3
0
        return space.w_False
    if arr1.len == arr2.len:
        if comp_op == LT or comp_op == GT:
            return space.w_False
        return space.w_True
    if comp_op == LT or comp_op == LE:
        if arr1.len < arr2.len:
            return space.w_True
        return space.w_False
    if arr1.len > arr2.len:
        return space.w_True
    return space.w_False


UNICODE_ARRAY = lltype.Ptr(
    lltype.Array(lltype.UniChar, hints={'nolength': True}))


class W_ArrayBase(W_Root):
    _attrs_ = ('space', 'len', 'allocated', '_lifeline_', '_buffer')

    def __init__(self, space):
        self.space = space
        self.len = 0
        self.allocated = 0
        self._buffer = lltype.nullptr(rffi.CCHARP.TO)

    @rgc.must_be_light_finalizer
    def __del__(self):
        if self._buffer:
            lltype.free(self._buffer, flavor='raw')
Exemple #4
0
    uLong = rffi_platform.SimpleType('uLong', rffi.ULONG)
    Bytef = rffi_platform.SimpleType('Bytef', rffi.UCHAR)
    voidpf = rffi_platform.SimpleType('voidpf', rffi.VOIDP)

    ZLIB_VERSION = rffi_platform.DefinedConstantString('ZLIB_VERSION')


for _name in constantnames:
    setattr(SimpleCConfig, _name, rffi_platform.ConstantInteger(_name))

config = rffi_platform.configure(SimpleCConfig)
voidpf = config['voidpf']
uInt = config['uInt']
uLong = config['uLong']
Bytef = config['Bytef']
Bytefp = lltype.Ptr(lltype.Array(Bytef, hints={'nolength': True}))

ZLIB_VERSION = config['ZLIB_VERSION']

for _name in constantnames:
    globals()[_name] = config[_name]

# The following parameter is copied from zutil.h, version 0.95,
# according to CPython's zlibmodule.c
DEFLATED = Z_DEFLATED
if MAX_MEM_LEVEL >= 8:
    DEF_MEM_LEVEL = 8
else:
    DEF_MEM_LEVEL = MAX_MEM_LEVEL

OUTPUT_BUFFER_SIZE = 32 * 1024
Exemple #5
0
from rpython.rtyper.lltypesystem import llmemory, lltype, rffi
from rpython.rtyper.tool import rffi_platform as platform
from rpython.rtyper.annlowlevel import llhelper
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from Builtins import *
from Core import *
import Config, Target


eci                        = ExternalCompilationInfo(includes=["libxml/parser.h"], \
                               include_dirs=Config.LIBXML2_INCLUDE_DIRS, \
                               library_dirs=Config.LIBXML2_LIBRARY_DIRS, \
                               libraries=Config.LIBXML2_LIBRARIES, \
                               link_extra=Config.LIBXML2_LINK_FLAGS, \
                               link_files=[Config.LIBXML2_A])
xmlCharP = lltype.Ptr(lltype.Array(rffi.UCHAR, hints={'nolength': True}))
xmlCharPP = lltype.Ptr(lltype.Array(xmlCharP, hints={'nolength': True}))
charactersSAXFunc = lltype.FuncType((rffi.VOIDP, xmlCharP, rffi.INT),
                                    lltype.Void)
charactersSAXFuncP = lltype.Ptr(charactersSAXFunc)
startElementNsSAX2Func     = lltype.FuncType((rffi.VOIDP, xmlCharP, xmlCharP, xmlCharP, rffi.INT, \
                               xmlCharPP, rffi.INT, rffi.INT, xmlCharPP), lltype.Void)
startElementNsSAX2FuncP = lltype.Ptr(startElementNsSAX2Func)
endElementNsSAX2Func = lltype.FuncType(
    (rffi.VOIDP, xmlCharP, xmlCharP, xmlCharP), lltype.Void)
endElementNsSAX2FuncP = lltype.Ptr(endElementNsSAX2Func)


class CConfig:
    _compilation_info_ = eci
    xmlSAXHandler          = platform.Struct("struct _xmlSAXHandler", \
Exemple #6
0
eci = ExternalCompilationInfo(
    includes=[cwd.join('locale_codec.h')],
    include_dirs=[str(cwd), cdir],
    separate_module_files=[cwd.join('locale_codec.c')])


def llexternal(*args, **kwargs):
    kwargs.setdefault('compilation_info', eci)
    kwargs.setdefault('sandboxsafe', True)
    kwargs.setdefault('_nowrapper', True)
    return rffi.llexternal(*args, **kwargs)


# An actual wchar_t*, rffi.CWCHARP is an array of UniChar (possibly on a
# narrow build)
RAW_WCHARP = lltype.Ptr(lltype.Array(rffi.WCHAR_T, hints={'nolength': True}))
pypy_char2wchar = llexternal('pypy_char2wchar', [rffi.CCHARP, rffi.SIZE_TP],
                             RAW_WCHARP)
pypy_char2wchar_strict = llexternal('pypy_char2wchar_strict',
                                    [rffi.CCHARP, rffi.SIZE_TP], RAW_WCHARP)
pypy_char2wchar_free = llexternal('pypy_char2wchar_free', [RAW_WCHARP],
                                  lltype.Void)
pypy_wchar2char = llexternal('pypy_wchar2char', [RAW_WCHARP, rffi.SIZE_TP],
                             rffi.CCHARP)
pypy_wchar2char_strict = llexternal('pypy_wchar2char_strict',
                                    [RAW_WCHARP, rffi.SIZE_TP], rffi.CCHARP)
pypy_wchar2char_free = llexternal('pypy_wchar2char_free', [rffi.CCHARP],
                                  lltype.Void)


def utf8_encode_locale_strict(utf8, ulen):
Exemple #7
0
                                         as_pyobj)
from pypy.module.cpyext.bytesobject import PyBytes_Check, PyBytes_FromObject
from pypy.module._codecs.interp_codecs import (CodecState, latin_1_decode,
                                               utf_16_decode, utf_32_decode)
from pypy.interpreter import unicodehelper
from pypy.objspace.std import unicodeobject
from rpython.rlib import rstring, runicode
from rpython.tool.sourcetools import func_renamer
import sys

## See comment in bytesobject.py.

cts.parse_header(parse_dir / 'cpyext_unicodeobject.h')
PyUnicodeObject = cts.gettype('PyUnicodeObject*')
Py_UNICODE = cts.gettype('Py_UNICODE')
INT_realP = lltype.Ptr(lltype.Array(rffi.INT_real, hints={'nolength': True}))


@bootstrap_function
def init_unicodeobject(space):
    make_typedescr(space.w_unicode.layout.typedef,
                   basestruct=PyUnicodeObject.TO,
                   attach=unicode_attach,
                   dealloc=unicode_dealloc,
                   realize=unicode_realize)


# Buffer for the default encoding (used by PyUnicode_GetDefaultEncoding)
DEFAULT_ENCODING_SIZE = 100
default_encoding = lltype.malloc(rffi.CCHARP.TO,
                                 DEFAULT_ENCODING_SIZE,
Exemple #8
0
    cnt = 0
    for i in range(arr.len):
        index_count_jd.jit_merge_point(
            tp_item=tp_item, count=count,
            arrclass=arrclass)
        w_item = arr.w_getitem(space, i)
        if space.eq_w(w_item, w_val):
            if count:
                cnt += 1
            else:
                return i
    if count:
        return cnt
    return -1

UNICODE_ARRAY = lltype.Ptr(lltype.Array(lltype.UniChar,
                                        hints={'nolength': True}))

class W_ArrayBase(W_Root):
    _attrs_ = ('space', 'len', 'allocated', '_lifeline_', '_buffer')

    def __init__(self, space):
        self.space = space
        self.len = 0
        self.allocated = 0
        self._buffer = lltype.nullptr(rffi.CCHARP.TO)

    @rgc.must_be_light_finalizer
    def __del__(self):
        if self._buffer:
            lltype.free(self._buffer, flavor='raw')
Exemple #9
0
# ____________________________________________________________
# Access to the 'environ' external variable
prefix = ''
if sys.platform.startswith('darwin'):
    CCHARPPP = rffi.CArrayPtr(rffi.CCHARPP)
    _os_NSGetEnviron = rffi.llexternal(
        '_NSGetEnviron', [],
        CCHARPPP,
        compilation_info=ExternalCompilationInfo(includes=['crt_externs.h']))

    def os_get_environ():
        return _os_NSGetEnviron()[0]
elif _WIN32:
    eci = ExternalCompilationInfo(includes=['stdlib.h'])
    CWCHARPP = lltype.Ptr(lltype.Array(rffi.CWCHARP, hints={'nolength': True}))

    os_get_environ, _os_set_environ = rffi.CExternVariable(
        rffi.CCHARPP, '_environ', eci)
    get__wenviron, _set__wenviron = rffi.CExternVariable(CWCHARPP,
                                                         '_wenviron',
                                                         eci,
                                                         c_type='wchar_t **')
    prefix = '_'
else:
    os_get_environ, _os_set_environ = rffi.CExternVariable(
        rffi.CCHARPP, 'environ', ExternalCompilationInfo())

# ____________________________________________________________
#
# Lower-level interface: dummy placeholders and external registations
Exemple #10
0
class LLtypeMixin(object):
    type_system = 'lltype'

    def get_class_of_box(self, box):
        return box.getref(rclass.OBJECTPTR).typeptr

    node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    node_vtable.name = rclass.alloc_array_name('node')
    node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
    node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True)
    node_vtable2.name = rclass.alloc_array_name('node2')
    node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2)
    cpu = runner.LLGraphCPU(None)

    NODE = lltype.GcForwardReference()
    NODE.become(
        lltype.GcStruct('NODE', ('parent', OBJECT), ('value', lltype.Signed),
                        ('floatval', lltype.Float), ('charval', lltype.Char),
                        ('next', lltype.Ptr(NODE))))
    NODE2 = lltype.GcStruct('NODE2', ('parent', NODE),
                            ('other', lltype.Ptr(NODE)))
    node = lltype.malloc(NODE)
    node.parent.typeptr = node_vtable
    node2 = lltype.malloc(NODE2)
    node2.parent.parent.typeptr = node_vtable2
    nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
    myptr = nodebox.value
    myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE))
    nullptr = lltype.nullptr(llmemory.GCREF.TO)
    nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node2))
    nodesize = cpu.sizeof(NODE)
    nodesize2 = cpu.sizeof(NODE2)
    valuedescr = cpu.fielddescrof(NODE, 'value')
    floatdescr = cpu.fielddescrof(NODE, 'floatval')
    chardescr = cpu.fielddescrof(NODE, 'charval')
    nextdescr = cpu.fielddescrof(NODE, 'next')
    otherdescr = cpu.fielddescrof(NODE2, 'other')

    accessor = FieldListAccessor()
    accessor.initialize(None, {'inst_field': IR_QUASIIMMUTABLE})
    QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed),
                            ('mutate_field', rclass.OBJECTPTR),
                            hints={'immutable_fields': accessor})
    quasisize = cpu.sizeof(QUASI)
    quasi = lltype.malloc(QUASI, immortal=True)
    quasi.inst_field = -4247
    quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
    quasibox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, quasi))
    quasiptr = quasibox.value
    quasiimmutdescr = QuasiImmutDescr(cpu, quasibox, quasifielddescr,
                                      cpu.fielddescrof(QUASI, 'mutate_field'))

    NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT),
                              ('ref', lltype.Ptr(OBJECT)))
    nodeobj = lltype.malloc(NODEOBJ)
    nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj)
    refdescr = cpu.fielddescrof(NODEOBJ, 'ref')

    INTOBJ_NOIMMUT = lltype.GcStruct('INTOBJ_NOIMMUT', ('parent', OBJECT),
                                     ('intval', lltype.Signed))
    INTOBJ_IMMUT = lltype.GcStruct('INTOBJ_IMMUT', ('parent', OBJECT),
                                   ('intval', lltype.Signed),
                                   hints={'immutable': True})
    intobj_noimmut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    intobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    noimmut_intval = cpu.fielddescrof(INTOBJ_NOIMMUT, 'intval')
    immut_intval = cpu.fielddescrof(INTOBJ_IMMUT, 'intval')

    PTROBJ_IMMUT = lltype.GcStruct('PTROBJ_IMMUT', ('parent', OBJECT),
                                   ('ptrval', lltype.Ptr(OBJECT)),
                                   hints={'immutable': True})
    ptrobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    immut_ptrval = cpu.fielddescrof(PTROBJ_IMMUT, 'ptrval')

    arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
    floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float))

    # a GcStruct not inheriting from OBJECT
    S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('b', lltype.Ptr(NODE)))
    ssize = cpu.sizeof(S)
    adescr = cpu.fielddescrof(S, 'a')
    bdescr = cpu.fielddescrof(S, 'b')
    sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
    arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S)))

    T = lltype.GcStruct('TUPLE', ('c', lltype.Signed),
                        ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
    tsize = cpu.sizeof(T)
    cdescr = cpu.fielddescrof(T, 'c')
    ddescr = cpu.fielddescrof(T, 'd')
    arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE)))

    U = lltype.GcStruct('U', ('parent', OBJECT),
                        ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
    u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable)
    usize = cpu.sizeof(U)
    onedescr = cpu.fielddescrof(U, 'one')

    FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
    plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                     EffectInfo.MOST_GENERAL)
    elidablecalldescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([valuedescr], [], [], [valuedescr], [], [],
                   EffectInfo.EF_ELIDABLE_CANNOT_RAISE))
    elidable2calldescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([valuedescr], [], [], [valuedescr], [], [],
                   EffectInfo.EF_ELIDABLE_OR_MEMORYERROR))
    elidable3calldescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([valuedescr], [], [], [valuedescr], [], [],
                   EffectInfo.EF_ELIDABLE_CAN_RAISE))
    nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                    EffectInfo([], [], [], [], [], []))
    writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                  EffectInfo([], [], [], [adescr], [], []))
    writearraydescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [adescr], [arraydescr], []))
    readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                 EffectInfo([adescr], [], [], [], [], []))
    mayforcevirtdescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([nextdescr], [], [], [], [], [],
                   EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE,
                   can_invalidate=True))
    arraycopydescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [arraydescr], [], [], [arraydescr], [],
                   EffectInfo.EF_CANNOT_RAISE,
                   oopspecindex=EffectInfo.OS_ARRAYCOPY))

    raw_malloc_descr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [], [], [],
                   EffectInfo.EF_CAN_RAISE,
                   oopspecindex=EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR))
    raw_free_descr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [], [], [],
                   EffectInfo.EF_CANNOT_RAISE,
                   oopspecindex=EffectInfo.OS_RAW_FREE))

    chararray = lltype.GcArray(lltype.Char)
    chararraydescr = cpu.arraydescrof(chararray)
    u2array = lltype.GcArray(rffi.USHORT)
    u2arraydescr = cpu.arraydescrof(u2array)

    # array of structs (complex data)
    complexarray = lltype.GcArray(
        lltype.Struct(
            "complex",
            ("real", lltype.Float),
            ("imag", lltype.Float),
        ))
    complexarraydescr = cpu.arraydescrof(complexarray)
    complexrealdescr = cpu.interiorfielddescrof(complexarray, "real")
    compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag")
    complexarraycopydescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [complexarraydescr], [], [], [complexarraydescr], [],
                   EffectInfo.EF_CANNOT_RAISE,
                   oopspecindex=EffectInfo.OS_ARRAYCOPY))

    rawarraydescr = cpu.arraydescrof(
        lltype.Array(lltype.Signed, hints={'nolength': True}))
    rawarraydescr_char = cpu.arraydescrof(
        lltype.Array(lltype.Char, hints={'nolength': True}))
    rawarraydescr_float = cpu.arraydescrof(
        lltype.Array(lltype.Float, hints={'nolength': True}))

    fc_array = lltype.GcArray(
        lltype.Struct("floatchar", ("float", lltype.Float),
                      ("char", lltype.Char)))
    fc_array_descr = cpu.arraydescrof(fc_array)
    fc_array_floatdescr = cpu.interiorfielddescrof(fc_array, "float")
    fc_array_chardescr = cpu.interiorfielddescrof(fc_array, "char")

    for _name, _os in [
        ('strconcatdescr', 'OS_STR_CONCAT'),
        ('strslicedescr', 'OS_STR_SLICE'),
        ('strequaldescr', 'OS_STR_EQUAL'),
        ('streq_slice_checknull_descr', 'OS_STREQ_SLICE_CHECKNULL'),
        ('streq_slice_nonnull_descr', 'OS_STREQ_SLICE_NONNULL'),
        ('streq_slice_char_descr', 'OS_STREQ_SLICE_CHAR'),
        ('streq_nonnull_descr', 'OS_STREQ_NONNULL'),
        ('streq_nonnull_char_descr', 'OS_STREQ_NONNULL_CHAR'),
        ('streq_checknull_char_descr', 'OS_STREQ_CHECKNULL_CHAR'),
        ('streq_lengthok_descr', 'OS_STREQ_LENGTHOK'),
    ]:
        if _name in ('strconcatdescr', 'strslicedescr'):
            _extra = EffectInfo.EF_ELIDABLE_OR_MEMORYERROR
        else:
            _extra = EffectInfo.EF_ELIDABLE_CANNOT_RAISE
        _oopspecindex = getattr(EffectInfo, _os)
        locals()[_name] = \
            cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                EffectInfo([], [], [], [], [], [], _extra,
                           oopspecindex=_oopspecindex))
        #
        _oopspecindex = getattr(EffectInfo, _os.replace('STR', 'UNI'))
        locals()[_name.replace('str', 'unicode')] = \
            cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                EffectInfo([], [], [], [], [], [], _extra,
                           oopspecindex=_oopspecindex))

    s2u_descr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [], [], [],
                   EffectInfo.EF_ELIDABLE_CAN_RAISE,
                   oopspecindex=EffectInfo.OS_STR2UNICODE))

    #

    class LoopToken(AbstractDescr):
        pass

    asmdescr = LoopToken()  # it can be whatever, it's not a descr though

    from rpython.jit.metainterp.virtualref import VirtualRefInfo

    class FakeWarmRunnerDesc:
        pass

    FakeWarmRunnerDesc.cpu = cpu
    vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc)
    virtualtokendescr = vrefinfo.descr_virtual_token
    virtualforceddescr = vrefinfo.descr_forced
    FUNC = lltype.FuncType([], lltype.Void)
    ei = EffectInfo([], [], [], [], [], [],
                    EffectInfo.EF_CANNOT_RAISE,
                    can_invalidate=False,
                    oopspecindex=EffectInfo.OS_JIT_FORCE_VIRTUALIZABLE)
    clear_vable = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)

    jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
    jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)

    register_known_gctype(cpu, node_vtable, NODE)
    register_known_gctype(cpu, node_vtable2, NODE2)
    register_known_gctype(cpu, u_vtable, U)
    register_known_gctype(cpu, jit_virtual_ref_vtable,
                          vrefinfo.JIT_VIRTUAL_REF)
    register_known_gctype(cpu, intobj_noimmut_vtable, INTOBJ_NOIMMUT)
    register_known_gctype(cpu, intobj_immut_vtable, INTOBJ_IMMUT)
    register_known_gctype(cpu, ptrobj_immut_vtable, PTROBJ_IMMUT)

    namespace = locals()

@cpython_api([PyObject], rffi.SIZE_T, error=-1)
def _PyLong_NumBits(space, w_long):
    return space.uint_w(space.call_method(w_long, "bit_length"))


@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
def _PyLong_Sign(space, w_long):
    assert isinstance(w_long, W_LongObject)
    return w_long.num.sign


CONST_UCHARP = lltype.Ptr(
    lltype.Array(rffi.UCHAR, hints={
        'nolength': True,
        'render_as_const': True
    }))


@cpython_api([CONST_UCHARP, rffi.SIZE_T, rffi.INT_real, rffi.INT_real],
             PyObject)
def _PyLong_FromByteArray(space, bytes, n, little_endian, signed):
    little_endian = rffi.cast(lltype.Signed, little_endian)
    signed = rffi.cast(lltype.Signed, signed)
    s = rffi.charpsize2str(rffi.cast(rffi.CCHARP, bytes),
                           rffi.cast(lltype.Signed, n))
    if little_endian:
        byteorder = 'little'
    else:
        byteorder = 'big'
    result = rbigint.frombytes(s, byteorder, signed != 0)
Exemple #12
0
from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, rffi
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rlib.debug import ll_assert
from rpython.memory.gcheader import GCHeaderBuilder
from rpython.memory.support import DEFAULT_CHUNK_SIZE
from rpython.memory.support import get_address_stack, get_address_deque
from rpython.memory.support import AddressDict, null_address_dict
from rpython.memory.gc.hook import GcHooks
from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage
from rpython.rtyper.annlowlevel import cast_adr_to_nongc_instance

TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed),
                             ('size', lltype.Signed),
                             ('links', lltype.Array(lltype.Signed)))
ARRAY_TYPEID_MAP = lltype.GcArray(lltype.Ptr(TYPEID_MAP))


class GCBase(object):
    _alloc_flavor_ = "raw"
    moving_gc = False
    needs_write_barrier = False
    malloc_zero_filled = False
    prebuilt_gc_objects_are_static_roots = True
    can_usually_pin_objects = False
    object_minimal_size = 0
    gcflag_extra = 0  # or a dedicated GC flag that the GC initializes to 0
    gcflag_dummy = 0  # dedicated GC flag set only on rmodel.ll_dummy_value
    _totalroots_rpy = 0  # for inspector.py

    def __init__(self,
                 config,
Exemple #13
0
    return lltype.malloc(BYTEARRAY, size)


_, _, copy_bytearray_contents = rstr._new_copy_contents_fun(
    BYTEARRAY, BYTEARRAY, lltype.Char, 'bytearray')
_, _, copy_bytearray_contents_from_str = rstr._new_copy_contents_fun(
    rstr.STR, BYTEARRAY, lltype.Char, 'bytearray_from_str')


def _empty_bytearray():
    return empty


BYTEARRAY.become(
    lltype.GcStruct(
        'rpy_bytearray', ('chars', lltype.Array(lltype.Char)),
        adtmeths={
            'malloc':
            lltype.staticAdtMethod(mallocbytearray),
            'copy_contents':
            lltype.staticAdtMethod(copy_bytearray_contents),
            'copy_contents_from_str':
            lltype.staticAdtMethod(copy_bytearray_contents_from_str),
            'length':
            rstr.LLHelpers.ll_length,
            'empty':
            lltype.staticAdtMethod(_empty_bytearray),
        }))

empty = lltype.malloc(BYTEARRAY, 0, immortal=True)
Exemple #14
0
# SIZE_OF_FFI_ARG bytes, even if they may be smaller.  (Unlike ffi_call,
# we don't have any special rule about results that are integers smaller
# than SIZE_OF_FFI_ARG).

CIF_DESCRIPTION = lltype.Struct(
    'CIF_DESCRIPTION',
    ('cif', FFI_CIF),
    ('abi', lltype.Signed),  # these 4 fields could also be read directly
    ('nargs', lltype.Signed),  # from 'cif', but doing so adds a dependency
    ('rtype', FFI_TYPE_P),  # on the exact fields available from ffi_cif.
    ('atypes', FFI_TYPE_PP),  #
    ('exchange_size', lltype.Signed),
    ('exchange_result', lltype.Signed),
    ('exchange_args',
     lltype.Array(lltype.Signed, hints={
         'nolength': True,
         'immutable': True
     })),
    hints={'immutable': True})

CIF_DESCRIPTION_P = lltype.Ptr(CIF_DESCRIPTION)


def jit_ffi_prep_cif(cif_description):
    """Minimal wrapper around ffi_prep_cif().  Call this after
    cif_description is initialized, in order to fill the last field: 'cif'.
    """
    res = clibffi.c_ffi_prep_cif(cif_description.cif, cif_description.abi,
                                 cif_description.nargs, cif_description.rtype,
                                 cif_description.atypes)
    return rffi.cast(lltype.Signed, res)
Exemple #15
0
def jitframe_allocate(frame_info):
    frame = lltype.malloc(JITFRAME, frame_info.jfi_frame_depth, zero=True)
    frame.jf_frame_info = frame_info
    return frame

JITFRAME = lltype.GcStruct(
    'JITFRAME',
    ('hdr', lltype.Signed),
    ('jf_frame_info', lltype.Ptr(jitframe.JITFRAMEINFO)),
    ('jf_descr', llmemory.GCREF),
    ('jf_force_descr', llmemory.GCREF),
    ('jf_extra_stack_depth', lltype.Signed),
    ('jf_guard_exc', llmemory.GCREF),
    ('jf_gcmap', lltype.Ptr(jitframe.GCMAP)),
    ('jf_gc_trace_state', lltype.Signed),
    ('jf_frame', lltype.Array(lltype.Signed)),
    adtmeths = {
        'allocate': jitframe_allocate,
    },
)

JITFRAMEPTR = lltype.Ptr(JITFRAME)

class GCDescrShadowstackDirect(GcLLDescr_framework):
    layoutbuilder = None

    class GCClass:
        JIT_WB_IF_FLAG = 0

    def __init__(self):
        GcCache.__init__(self, False, None)
Exemple #16
0
see as the list of roots (stack and prebuilt objects).
"""

# XXX VERY INCOMPLETE, low coverage

import py
from rpython.rtyper.lltypesystem import lltype, llmemory
from rpython.memory.gctypelayout import TypeLayoutBuilder, FIN_HANDLER_ARRAY
from rpython.rlib.rarithmetic import LONG_BIT, is_valid_int
from rpython.memory.gc import minimark, incminimark
from rpython.memory.gctypelayout import zero_gc_pointers_inside, zero_gc_pointers
from rpython.rlib.debug import debug_print
import pdb
WORD = LONG_BIT // 8

ADDR_ARRAY = lltype.Array(llmemory.Address)
S = lltype.GcForwardReference()
S.become(
    lltype.GcStruct('S', ('x', lltype.Signed), ('prev', lltype.Ptr(S)),
                    ('next', lltype.Ptr(S))))
RAW = lltype.Struct('RAW', ('p', lltype.Ptr(S)), ('q', lltype.Ptr(S)))
VAR = lltype.GcArray(lltype.Ptr(S))
VARNODE = lltype.GcStruct('VARNODE', ('a', lltype.Ptr(VAR)))


class DirectRootWalker(object):
    def __init__(self, tester):
        self.tester = tester

    def walk_roots(self,
                   collect_stack_root,
Exemple #17
0
class LLtypeMixin(object):
    def get_class_of_box(self, box):
        base = box.getref_base()
        return lltype.cast_opaque_ptr(rclass.OBJECTPTR, base).typeptr

    node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    node_vtable.name = rclass.alloc_array_name('node')
    node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
    node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True)
    node_vtable2.name = rclass.alloc_array_name('node2')
    node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2)
    node_vtable3 = lltype.malloc(OBJECT_VTABLE, immortal=True)
    node_vtable3.name = rclass.alloc_array_name('node3')
    node_vtable3.subclassrange_min = 3
    node_vtable3.subclassrange_max = 3
    node_vtable_adr3 = llmemory.cast_ptr_to_adr(node_vtable3)
    cpu = runner.LLGraphCPU(None)

    NODE = lltype.GcForwardReference()
    S = lltype.GcForwardReference()
    NODE.become(
        lltype.GcStruct('NODE', ('parent', OBJECT), ('value', lltype.Signed),
                        ('floatval', lltype.Float), ('charval', lltype.Char),
                        ('nexttuple', lltype.Ptr(S)),
                        ('next', lltype.Ptr(NODE))))
    S.become(
        lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('abis', lltype.Signed),
                        ('b', lltype.Ptr(NODE))))
    NODE2 = lltype.GcStruct('NODE2', ('parent', NODE),
                            ('other', lltype.Ptr(NODE)))

    NODE3 = lltype.GcForwardReference()
    NODE3.become(
        lltype.GcStruct('NODE3', ('parent', OBJECT), ('value', lltype.Signed),
                        ('next', lltype.Ptr(NODE3)),
                        hints={'immutable': True}))

    big_fields = [('big' + i, lltype.Signed) for i in string.ascii_lowercase]
    BIG = lltype.GcForwardReference()
    BIG.become(lltype.GcStruct('BIG', *big_fields, hints={'immutable': True}))

    for field, _ in big_fields:
        locals()[field + 'descr'] = cpu.fielddescrof(BIG, field)

    node = lltype.malloc(NODE)
    node.value = 5
    node.next = node
    node.parent.typeptr = node_vtable
    nodeaddr = lltype.cast_opaque_ptr(llmemory.GCREF, node)
    #nodebox = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, node))
    node2 = lltype.malloc(NODE2)
    node2.parent.parent.typeptr = node_vtable2
    node2addr = lltype.cast_opaque_ptr(llmemory.GCREF, node2)
    myptr = lltype.cast_opaque_ptr(llmemory.GCREF, node)
    mynodeb = lltype.malloc(NODE)
    myarray = lltype.cast_opaque_ptr(
        llmemory.GCREF,
        lltype.malloc(lltype.GcArray(lltype.Signed), 13, zero=True))
    mynodeb.parent.typeptr = node_vtable
    myptrb = lltype.cast_opaque_ptr(llmemory.GCREF, mynodeb)
    myptr2 = lltype.malloc(NODE2)
    myptr2.parent.parent.typeptr = node_vtable2
    myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, myptr2)
    nullptr = lltype.nullptr(llmemory.GCREF.TO)

    mynode3 = lltype.malloc(NODE3)
    mynode3.parent.typeptr = node_vtable3
    mynode3.value = 7
    mynode3.next = mynode3
    myptr3 = lltype.cast_opaque_ptr(llmemory.GCREF, mynode3)  # a NODE2
    mynode4 = lltype.malloc(NODE3)
    mynode4.parent.typeptr = node_vtable3
    myptr4 = lltype.cast_opaque_ptr(llmemory.GCREF, mynode4)  # a NODE3

    nullptr = lltype.nullptr(llmemory.GCREF.TO)
    #nodebox2 = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, node2))
    nodesize = cpu.sizeof(NODE, node_vtable)
    node_tid = nodesize.get_type_id()
    nodesize2 = cpu.sizeof(NODE2, node_vtable2)
    nodesize3 = cpu.sizeof(NODE3, node_vtable3)
    valuedescr = cpu.fielddescrof(NODE, 'value')
    floatdescr = cpu.fielddescrof(NODE, 'floatval')
    chardescr = cpu.fielddescrof(NODE, 'charval')
    nextdescr = cpu.fielddescrof(NODE, 'next')
    nexttupledescr = cpu.fielddescrof(NODE, 'nexttuple')
    otherdescr = cpu.fielddescrof(NODE2, 'other')
    valuedescr3 = cpu.fielddescrof(NODE3, 'value')
    nextdescr3 = cpu.fielddescrof(NODE3, 'next')
    assert valuedescr3.is_always_pure()
    assert nextdescr3.is_always_pure()

    accessor = FieldListAccessor()
    accessor.initialize(None, {'inst_field': IR_QUASIIMMUTABLE})
    QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed),
                            ('mutate_field', rclass.OBJECTPTR),
                            hints={'immutable_fields': accessor})
    quasisize = cpu.sizeof(QUASI, None)
    quasi = lltype.malloc(QUASI, immortal=True)
    quasi.inst_field = -4247
    quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
    quasiptr = lltype.cast_opaque_ptr(llmemory.GCREF, quasi)
    quasiimmutdescr = QuasiImmutDescr(cpu, quasiptr, quasifielddescr,
                                      cpu.fielddescrof(QUASI, 'mutate_field'))

    NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT),
                              ('ref', lltype.Ptr(OBJECT)))
    nodeobj = lltype.malloc(NODEOBJ)
    nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj)
    refdescr = cpu.fielddescrof(NODEOBJ, 'ref')

    INTOBJ_NOIMMUT = lltype.GcStruct('INTOBJ_NOIMMUT', ('parent', OBJECT),
                                     ('intval', lltype.Signed))
    INTOBJ_IMMUT = lltype.GcStruct('INTOBJ_IMMUT', ('parent', OBJECT),
                                   ('intval', lltype.Signed),
                                   hints={'immutable': True})
    intobj_noimmut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    intobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    noimmut_intval = cpu.fielddescrof(INTOBJ_NOIMMUT, 'intval')
    immut_intval = cpu.fielddescrof(INTOBJ_IMMUT, 'intval')
    immut = lltype.malloc(INTOBJ_IMMUT, zero=True)
    immutaddr = lltype.cast_opaque_ptr(llmemory.GCREF, immut)
    noimmut_descr = cpu.sizeof(INTOBJ_NOIMMUT, intobj_noimmut_vtable)
    immut_descr = cpu.sizeof(INTOBJ_IMMUT, intobj_immut_vtable)

    PTROBJ_IMMUT = lltype.GcStruct('PTROBJ_IMMUT', ('parent', OBJECT),
                                   ('ptrval', lltype.Ptr(OBJECT)),
                                   hints={'immutable': True})
    ptrobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    ptrobj_immut_descr = cpu.sizeof(PTROBJ_IMMUT, ptrobj_immut_vtable)
    immut_ptrval = cpu.fielddescrof(PTROBJ_IMMUT, 'ptrval')

    arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
    int32arraydescr = cpu.arraydescrof(lltype.GcArray(rffi.INT))
    int16arraydescr = cpu.arraydescrof(lltype.GcArray(rffi.SHORT))
    float32arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.SingleFloat))
    arraydescr_tid = arraydescr.get_type_id()
    array = lltype.malloc(lltype.GcArray(lltype.Signed), 15, zero=True)
    arrayref = lltype.cast_opaque_ptr(llmemory.GCREF, array)
    array2 = lltype.malloc(lltype.GcArray(lltype.Ptr(S)), 15, zero=True)
    array2ref = lltype.cast_opaque_ptr(llmemory.GCREF, array2)
    gcarraydescr = cpu.arraydescrof(lltype.GcArray(llmemory.GCREF))
    gcarraydescr_tid = gcarraydescr.get_type_id()
    floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float))

    arrayimmutdescr = cpu.arraydescrof(
        lltype.GcArray(lltype.Signed, hints={"immutable": True}))
    immutarray = lltype.cast_opaque_ptr(
        llmemory.GCREF, lltype.malloc(arrayimmutdescr.A, 13, zero=True))
    gcarrayimmutdescr = cpu.arraydescrof(
        lltype.GcArray(llmemory.GCREF, hints={"immutable": True}))
    floatarrayimmutdescr = cpu.arraydescrof(
        lltype.GcArray(lltype.Float, hints={"immutable": True}))

    # a GcStruct not inheriting from OBJECT
    tpl = lltype.malloc(S, zero=True)
    tupleaddr = lltype.cast_opaque_ptr(llmemory.GCREF, tpl)
    nodefull2 = lltype.malloc(NODE, zero=True)
    nodefull2addr = lltype.cast_opaque_ptr(llmemory.GCREF, nodefull2)
    ssize = cpu.sizeof(S, None)
    adescr = cpu.fielddescrof(S, 'a')
    abisdescr = cpu.fielddescrof(S, 'abis')
    bdescr = cpu.fielddescrof(S, 'b')
    #sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
    arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S)))

    T = lltype.GcStruct('TUPLE', ('c', lltype.Signed),
                        ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))

    W_ROOT = lltype.GcStruct(
        'W_ROOT', ('parent', OBJECT), ('inst_w_seq', llmemory.GCREF),
        ('inst_index', lltype.Signed), ('inst_w_list', llmemory.GCREF),
        ('inst_length', lltype.Signed), ('inst_start', lltype.Signed),
        ('inst_step', lltype.Signed))
    inst_w_seq = cpu.fielddescrof(W_ROOT, 'inst_w_seq')
    inst_index = cpu.fielddescrof(W_ROOT, 'inst_index')
    inst_length = cpu.fielddescrof(W_ROOT, 'inst_length')
    inst_start = cpu.fielddescrof(W_ROOT, 'inst_start')
    inst_step = cpu.fielddescrof(W_ROOT, 'inst_step')
    inst_w_list = cpu.fielddescrof(W_ROOT, 'inst_w_list')
    w_root_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)

    tsize = cpu.sizeof(T, None)
    cdescr = cpu.fielddescrof(T, 'c')
    ddescr = cpu.fielddescrof(T, 'd')
    arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE3)))

    U = lltype.GcStruct('U', ('parent', OBJECT),
                        ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
    u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable)
    SIMPLE = lltype.GcStruct('simple', ('parent', OBJECT),
                             ('value', lltype.Signed))
    simplevalue = cpu.fielddescrof(SIMPLE, 'value')
    simple_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
    simpledescr = cpu.sizeof(SIMPLE, simple_vtable)
    simple = lltype.malloc(SIMPLE, zero=True)
    simpleaddr = lltype.cast_opaque_ptr(llmemory.GCREF, simple)
    #usize = cpu.sizeof(U, ...)
    onedescr = cpu.fielddescrof(U, 'one')

    FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
    plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                     EffectInfo.MOST_GENERAL)
    elidablecalldescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([valuedescr], [], [], [valuedescr], [], [],
                   EffectInfo.EF_ELIDABLE_CANNOT_RAISE))
    elidable2calldescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([valuedescr], [], [], [valuedescr], [], [],
                   EffectInfo.EF_ELIDABLE_OR_MEMORYERROR))
    elidable3calldescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([valuedescr], [], [], [valuedescr], [], [],
                   EffectInfo.EF_ELIDABLE_CAN_RAISE))
    nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                    EffectInfo([], [], [], [], [], []))
    writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                  EffectInfo([], [], [], [adescr], [], []))
    writearraydescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [adescr], [arraydescr], []))
    writevalue3descr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [valuedescr3], [], []))
    readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                                 EffectInfo([adescr], [], [], [], [], []))
    mayforcevirtdescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([nextdescr], [], [], [], [], [],
                   EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE,
                   can_invalidate=True))
    arraycopydescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [arraydescr], [], [], [arraydescr], [],
                   EffectInfo.EF_CANNOT_RAISE,
                   oopspecindex=EffectInfo.OS_ARRAYCOPY))

    raw_malloc_descr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [], [], [],
                   EffectInfo.EF_CAN_RAISE,
                   oopspecindex=EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR))
    raw_free_descr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [], [], [],
                   EffectInfo.EF_CANNOT_RAISE,
                   oopspecindex=EffectInfo.OS_RAW_FREE))

    chararray = lltype.GcArray(lltype.Char)
    chararraydescr = cpu.arraydescrof(chararray)
    u2array = lltype.GcArray(rffi.USHORT)
    u2arraydescr = cpu.arraydescrof(u2array)

    nodefull = lltype.malloc(NODE2, zero=True)
    nodefull.parent.next = lltype.cast_pointer(lltype.Ptr(NODE), nodefull)
    nodefull.parent.nexttuple = tpl
    nodefulladdr = lltype.cast_opaque_ptr(llmemory.GCREF, nodefull)

    # array of structs (complex data)
    complexarray = lltype.GcArray(
        lltype.Struct(
            "complex",
            ("real", lltype.Float),
            ("imag", lltype.Float),
        ))
    complexarraydescr = cpu.arraydescrof(complexarray)
    complexrealdescr = cpu.interiorfielddescrof(complexarray, "real")
    compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag")
    complexarraycopydescr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [complexarraydescr], [], [], [complexarraydescr], [],
                   EffectInfo.EF_CANNOT_RAISE,
                   oopspecindex=EffectInfo.OS_ARRAYCOPY))

    rawarraydescr = cpu.arraydescrof(
        lltype.Array(lltype.Signed, hints={'nolength': True}))
    rawarraydescr_char = cpu.arraydescrof(
        lltype.Array(lltype.Char, hints={'nolength': True}))
    rawarraydescr_float = cpu.arraydescrof(
        lltype.Array(lltype.Float, hints={'nolength': True}))

    fc_array = lltype.GcArray(
        lltype.Struct("floatchar", ("float", lltype.Float),
                      ("char", lltype.Char)))
    fc_array_descr = cpu.arraydescrof(fc_array)
    fc_array_floatdescr = cpu.interiorfielddescrof(fc_array, "float")
    fc_array_chardescr = cpu.interiorfielddescrof(fc_array, "char")

    for _name, _os in [
        ('strconcatdescr', 'OS_STR_CONCAT'),
        ('strslicedescr', 'OS_STR_SLICE'),
        ('strequaldescr', 'OS_STR_EQUAL'),
        ('streq_slice_checknull_descr', 'OS_STREQ_SLICE_CHECKNULL'),
        ('streq_slice_nonnull_descr', 'OS_STREQ_SLICE_NONNULL'),
        ('streq_slice_char_descr', 'OS_STREQ_SLICE_CHAR'),
        ('streq_nonnull_descr', 'OS_STREQ_NONNULL'),
        ('streq_nonnull_char_descr', 'OS_STREQ_NONNULL_CHAR'),
        ('streq_checknull_char_descr', 'OS_STREQ_CHECKNULL_CHAR'),
        ('streq_lengthok_descr', 'OS_STREQ_LENGTHOK'),
    ]:
        if _name in ('strconcatdescr', 'strslicedescr'):
            _extra = EffectInfo.EF_ELIDABLE_OR_MEMORYERROR
        else:
            _extra = EffectInfo.EF_ELIDABLE_CANNOT_RAISE
        _oopspecindex = getattr(EffectInfo, _os)
        locals()[_name] = \
            cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                EffectInfo([], [], [], [], [], [], _extra,
                           oopspecindex=_oopspecindex))
        #
        _oopspecindex = getattr(EffectInfo, _os.replace('STR', 'UNI'))
        locals()[_name.replace('str', 'unicode')] = \
            cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
                EffectInfo([], [], [], [], [], [], _extra,
                           oopspecindex=_oopspecindex))

    s2u_descr = cpu.calldescrof(
        FUNC, FUNC.ARGS, FUNC.RESULT,
        EffectInfo([], [], [], [], [], [],
                   EffectInfo.EF_ELIDABLE_CAN_RAISE,
                   oopspecindex=EffectInfo.OS_STR2UNICODE))

    #

    class LoopToken(AbstractDescr):
        pass

    asmdescr = LoopToken()  # it can be whatever, it's not a descr though

    from rpython.jit.metainterp.virtualref import VirtualRefInfo

    class FakeWarmRunnerDesc:
        pass

    FakeWarmRunnerDesc.cpu = cpu
    vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc)
    virtualtokendescr = vrefinfo.descr_virtual_token
    virtualforceddescr = vrefinfo.descr_forced
    FUNC = lltype.FuncType([], lltype.Void)
    ei = EffectInfo([], [], [], [], [], [],
                    EffectInfo.EF_CANNOT_RAISE,
                    can_invalidate=False,
                    oopspecindex=EffectInfo.OS_JIT_FORCE_VIRTUALIZABLE)
    clear_vable = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)

    jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
    jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)
    vref_descr = cpu.sizeof(vrefinfo.JIT_VIRTUAL_REF, jit_virtual_ref_vtable)

    FUNC = lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)
    ei = EffectInfo([], [], [], [], [], [],
                    EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
                    can_invalidate=False,
                    oopspecindex=EffectInfo.OS_INT_PY_DIV)
    int_py_div_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
    ei = EffectInfo([], [], [], [], [], [],
                    EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
                    can_invalidate=False,
                    oopspecindex=EffectInfo.OS_INT_UDIV)
    int_udiv_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
    ei = EffectInfo([], [], [], [], [], [],
                    EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
                    can_invalidate=False,
                    oopspecindex=EffectInfo.OS_INT_PY_MOD)
    int_py_mod_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)

    FUNC = lltype.FuncType([], llmemory.GCREF)
    ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CAN_RAISE)
    plain_r_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)

    namespace = locals()
Exemple #18
0
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rtyper.lltypesystem.lltype import Ptr, FuncType, Void
from pypy.module.cpyext.api import (cpython_struct, Py_ssize_t, Py_ssize_tP,
                                    PyVarObjectFields, PyTypeObject,
                                    PyTypeObjectPtr, FILEP,
                                    Py_TPFLAGS_READYING, Py_TPFLAGS_READY,
                                    Py_TPFLAGS_HEAPTYPE)
from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
from pypy.module.cpyext.modsupport import PyMethodDef

P, FT, PyO = Ptr, FuncType, PyObject
PyOPtr = Ptr(lltype.Array(PyO, hints={'nolength': True}))

freefunc = P(FT([rffi.VOIDP], Void))
destructor = P(FT([PyO], Void))
printfunc = P(FT([PyO, FILEP, rffi.INT_real], rffi.INT))
getattrfunc = P(FT([PyO, rffi.CCHARP], PyO))
getattrofunc = P(FT([PyO, PyO], PyO))
setattrfunc = P(FT([PyO, rffi.CCHARP, PyO], rffi.INT_real))
setattrofunc = P(FT([PyO, PyO, PyO], rffi.INT_real))
cmpfunc = P(FT([PyO, PyO], rffi.INT_real))
reprfunc = P(FT([PyO], PyO))
hashfunc = P(FT([PyO], lltype.Signed))
richcmpfunc = P(FT([PyO, PyO, rffi.INT_real], PyO))
getiterfunc = P(FT([PyO], PyO))
iternextfunc = P(FT([PyO], PyO))
descrgetfunc = P(FT([PyO, PyO, PyO], PyO))
descrsetfunc = P(FT([PyO, PyO, PyO], rffi.INT_real))
initproc = P(FT([PyO, PyO, PyO], rffi.INT_real))
newfunc = P(FT([PyTypeObjectPtr, PyO, PyO], PyO))
allocfunc = P(FT([PyTypeObjectPtr, Py_ssize_t], PyO))
Exemple #19
0
class GCData(object):
    """The GC information tables, and the query functions that the GC
    calls to decode their content.  The encoding of this information
    is done by encode_type_shape().  These two places should be in sync,
    obviously, but in principle no other code should depend on the
    details of the encoding in TYPE_INFO.
    """
    _alloc_flavor_ = 'raw'

    OFFSETS_TO_GC_PTR = lltype.Array(lltype.Signed)

    # A custom tracer (CT), enumerates the addresses that contain GCREFs.
    # It is called with the object as first argument, and the previous
    # returned address (or NULL the first time) as the second argument.
    FINALIZER_FUNC = lltype.FuncType([llmemory.Address], lltype.Void)
    FINALIZER = lltype.Ptr(FINALIZER_FUNC)

    # structure describing the layout of a typeid
    TYPE_INFO = lltype.Struct(
        "type_info",
        ("infobits", lltype.Signed),  # combination of the T_xxx consts
        ("finalizer", FINALIZER),
        ("fixedsize", lltype.Signed),
        ("ofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
        hints={'immutable': True},
    )
    VARSIZE_TYPE_INFO = lltype.Struct(
        "varsize_type_info",
        ("header", TYPE_INFO),
        ("varitemsize", lltype.Signed),
        ("ofstovar", lltype.Signed),
        ("ofstolength", lltype.Signed),
        ("varofstoptrs", lltype.Ptr(OFFSETS_TO_GC_PTR)),
        hints={'immutable': True},
    )
    TYPE_INFO_PTR = lltype.Ptr(TYPE_INFO)
    VARSIZE_TYPE_INFO_PTR = lltype.Ptr(VARSIZE_TYPE_INFO)

    def __init__(self, type_info_group):
        assert isinstance(type_info_group, llgroup.group)
        self.type_info_group = type_info_group
        self.type_info_group_ptr = type_info_group._as_ptr()

    def get(self, typeid):
        res = llop.get_group_member(GCData.TYPE_INFO_PTR,
                                    self.type_info_group_ptr, typeid)
        _check_valid_type_info(res)
        return res

    def get_varsize(self, typeid):
        res = llop.get_group_member(GCData.VARSIZE_TYPE_INFO_PTR,
                                    self.type_info_group_ptr, typeid)
        _check_valid_type_info_varsize(res)
        return res

    def q_is_varsize(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_IS_VARSIZE) != 0

    def q_has_gcptr_in_varsize(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_HAS_GCPTR_IN_VARSIZE) != 0

    def q_has_gcptr(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_HAS_GCPTR) != 0

    def q_is_gcarrayofgcptr(self, typeid):
        infobits = self.get(typeid).infobits
        return (infobits & T_IS_GCARRAY_OF_GCPTR) != 0

    def q_cannot_pin(self, typeid):
        typeinfo = self.get(typeid)
        ANY = (T_HAS_GCPTR | T_IS_WEAKREF)
        return (typeinfo.infobits & ANY) != 0 or bool(typeinfo.finalizer)

    def q_finalizer(self, typeid):
        return self.get(typeid).finalizer

    def q_light_finalizer(self, typeid):
        typeinfo = self.get(typeid)
        if typeinfo.infobits & T_HAS_LIGHTWEIGHT_FINALIZER:
            return typeinfo.finalizer
        return lltype.nullptr(GCData.FINALIZER_FUNC)

    def q_offsets_to_gc_pointers(self, typeid):
        return self.get(typeid).ofstoptrs

    def q_fixed_size(self, typeid):
        return self.get(typeid).fixedsize

    def q_varsize_item_sizes(self, typeid):
        return self.get_varsize(typeid).varitemsize

    def q_varsize_offset_to_variable_part(self, typeid):
        return self.get_varsize(typeid).ofstovar

    def q_varsize_offset_to_length(self, typeid):
        return self.get_varsize(typeid).ofstolength

    def q_varsize_offsets_to_gcpointers_in_var_part(self, typeid):
        return self.get_varsize(typeid).varofstoptrs

    def q_weakpointer_offset(self, typeid):
        infobits = self.get(typeid).infobits
        if infobits & T_IS_WEAKREF:
            return weakptr_offset
        return -1

    def q_member_index(self, typeid):
        infobits = self.get(typeid).infobits
        return infobits & T_MEMBER_INDEX

    def q_is_rpython_class(self, typeid):
        infobits = self.get(typeid).infobits
        return infobits & T_IS_RPYTHON_INSTANCE != 0

    def q_has_custom_trace(self, typeid):
        infobits = self.get(typeid).infobits
        return infobits & T_HAS_CUSTOM_TRACE != 0

    def q_fast_path_tracing(self, typeid):
        # return True if none of the flags T_HAS_GCPTR_IN_VARSIZE,
        # T_IS_GCARRAY_OF_GCPTR or T_HAS_CUSTOM_TRACE is set
        T_ANY_SLOW_FLAG = (T_HAS_GCPTR_IN_VARSIZE | T_IS_GCARRAY_OF_GCPTR
                           | T_HAS_CUSTOM_TRACE)
        infobits = self.get(typeid).infobits
        return infobits & T_ANY_SLOW_FLAG == 0

    def set_query_functions(self, gc):
        gc.set_query_functions(
            self.q_is_varsize, self.q_has_gcptr_in_varsize,
            self.q_is_gcarrayofgcptr, self.q_finalizer, self.q_light_finalizer,
            self.q_offsets_to_gc_pointers, self.q_fixed_size,
            self.q_varsize_item_sizes, self.q_varsize_offset_to_variable_part,
            self.q_varsize_offset_to_length,
            self.q_varsize_offsets_to_gcpointers_in_var_part,
            self.q_weakpointer_offset, self.q_member_index,
            self.q_is_rpython_class, self.q_has_custom_trace,
            self.q_fast_path_tracing, self.q_has_gcptr, self.q_cannot_pin)

    def _has_got_custom_trace(self, typeid):
        type_info = self.get(typeid)
        type_info.infobits |= (T_HAS_CUSTOM_TRACE | T_HAS_GCPTR)
Exemple #20
0
    assert gcref  # not NULL!
    try:
        _gcflag_extras.remove(gcref)
    except KeyError:
        _gcflag_extras.add(gcref)


toggle_gcflag_extra._subopnum = 3


def assert_no_more_gcflags():
    if not we_are_translated():
        assert not _gcflag_extras


ARRAY_OF_CHAR = lltype.Array(lltype.Char)
NULL_GCREF = lltype.nullptr(llmemory.GCREF.TO)


class _GcRef(object):
    # implementation-specific: there should not be any after translation
    __slots__ = ['_x']

    def __init__(self, x):
        self._x = x

    def __hash__(self):
        return object.__hash__(self._x)

    def __eq__(self, other):
        if isinstance(other, lltype._ptr):
Exemple #21
0
    c_ffi_call_return_type = rffi.INT
else:
    c_ffi_call_return_type = lltype.Void
c_ffi_call = external('ffi_call', [FFI_CIFP, rffi.VOIDP, rffi.VOIDP, VOIDPP],
                      c_ffi_call_return_type,
                      save_err=rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
# Note: the RFFI_ALT_ERRNO flag matches the one in pyjitpl.direct_libffi_call
CALLBACK_TP = rffi.CCallback([FFI_CIFP, rffi.VOIDP, rffi.VOIDPP, rffi.VOIDP],
                             lltype.Void)
c_ffi_prep_closure = external(
    'ffi_prep_closure', [FFI_CLOSUREP, FFI_CIFP, CALLBACK_TP, rffi.VOIDP],
    rffi.INT)

FFI_STRUCT_P = lltype.Ptr(
    lltype.Struct('FFI_STRUCT', ('ffistruct', FFI_TYPE_P.TO),
                  ('members', lltype.Array(FFI_TYPE_P))))


@specialize.arg(3)
def make_struct_ffitype_e(size, aligment, field_types, track_allocation=True):
    """Compute the type of a structure.  Returns a FFI_STRUCT_P out of
       which the 'ffistruct' member is a regular FFI_TYPE.
    """
    tpe = lltype.malloc(FFI_STRUCT_P.TO,
                        len(field_types) + 1,
                        flavor='raw',
                        track_allocation=track_allocation)
    tpe.ffistruct.c_type = rffi.cast(rffi.USHORT, FFI_TYPE_STRUCT)
    tpe.ffistruct.c_size = rffi.cast(rffi.SIZE_T, size)
    tpe.ffistruct.c_alignment = rffi.cast(rffi.USHORT, aligment)
    tpe.ffistruct.c_elements = rffi.cast(FFI_TYPE_PP,