Пример #1
0
def update_all_slots(space, w_type, pto):
    # fill slots in pto
    # Not very sure about it, but according to
    # test_call_tp_dealloc, we should not
    # overwrite slots that are already set: these ones are probably
    # coming from a parent C type.

    typedef = w_type.layout.typedef
    for method_name, slot_name, slot_names, slot_apifunc in slotdefs_for_tp_slots:
        w_descr = w_type.lookup(method_name)
        if w_descr is None:
            # XXX special case iternext
            continue

        if slot_apifunc is None and typedef is not None:
            slot_apifunc = get_slot_tp_function(space, typedef, slot_name)
        if not slot_apifunc:
            if WARN_ABOUT_MISSING_SLOT_FUNCTIONS:
                os.write(2,
                    "%s defined by %s but no slot function defined!\n" % (
                        method_name, w_type.getname(space)))
            continue
        slot_func_helper = slot_apifunc.get_llhelper(space)

        # XXX special case wrapper-functions and use a "specific" slot func

        if len(slot_names) == 1:
            if not getattr(pto, slot_names[0]):
                setattr(pto, slot_names[0], slot_func_helper)
        elif ((w_type is space.w_list or w_type is space.w_tuple) and
              slot_names[0] == 'c_tp_as_number'):
            # XXX hack - hwo can we generalize this? The problem is method
            # names like __mul__ map to more than one slot, and we have no
            # convenient way to indicate which slots CPython have filled
            #
            # We need at least this special case since Numpy checks that
            # (list, tuple) do __not__ fill tp_as_number
            pass
        else:
            assert len(slot_names) == 2
            struct = getattr(pto, slot_names[0])
            if not struct:
                #assert not space.config.translating
                assert not pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE
                if slot_names[0] == 'c_tp_as_number':
                    STRUCT_TYPE = PyNumberMethods
                elif slot_names[0] == 'c_tp_as_sequence':
                    STRUCT_TYPE = PySequenceMethods
                elif slot_names[0] == 'c_tp_as_buffer':
                    STRUCT_TYPE = PyBufferProcs
                else:
                    raise AssertionError(
                        "Structure not allocated: %s" % (slot_names[0],))
                struct = lltype.malloc(STRUCT_TYPE, flavor='raw', zero=True)
                setattr(pto, slot_names[0], struct)

            if not getattr(struct, slot_names[1]):
                setattr(struct, slot_names[1], slot_func_helper)
Пример #2
0
def update_all_slots_builtin(space, w_type, pto):
    typedef = w_type.layout.typedef
    for method_name, slot_name, slot_names, slot_apifunc in slotdefs_for_tp_slots:
        slot_apifunc = get_slot_tp_function(space, typedef, slot_name, method_name)
        if not slot_apifunc:
            warn_missing_slot(space, method_name, slot_name, w_type)
            continue
        slot_llfunc = slot_apifunc.get_llhelper(space)
        fill_slot(space, pto, w_type, slot_names, slot_llfunc)
Пример #3
0
def update_all_slots(space, w_type, pto):
    #  XXX fill slots in pto

    typedef = w_type.instancetypedef
    for method_name, slot_name, slot_names, slot_func in slotdefs_for_tp_slots:
        w_descr = w_type.lookup(method_name)
        if w_descr is None:
            # XXX special case iternext
            continue

        slot_func_helper = None

        if slot_func is None and typedef is not None:
            get_slot = get_slot_tp_function(space, typedef, slot_name)
            if get_slot:
                slot_func_helper = get_slot()
        elif slot_func:
            slot_func_helper = llhelper(slot_func.api_func.functype,
                                        slot_func.api_func.get_wrapper(space))

        if slot_func_helper is None:
            if WARN_ABOUT_MISSING_SLOT_FUNCTIONS:
                os.write(
                    2, method_name +
                    " defined by the type but no slot function defined!\n")
            continue

        # XXX special case wrapper-functions and use a "specific" slot func

        if len(slot_names) == 1:
            setattr(pto, slot_names[0], slot_func_helper)
        else:
            assert len(slot_names) == 2
            struct = getattr(pto, slot_names[0])
            if not struct:
                assert not space.config.translating
                assert not pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE
                if slot_names[0] == 'c_tp_as_number':
                    STRUCT_TYPE = PyNumberMethods
                elif slot_names[0] == 'c_tp_as_sequence':
                    STRUCT_TYPE = PySequenceMethods
                else:
                    raise AssertionError("Structure not allocated: %s" %
                                         (slot_names[0], ))
                struct = lltype.malloc(STRUCT_TYPE, flavor='raw', zero=True)
                setattr(pto, slot_names[0], struct)

            setattr(struct, slot_names[1], slot_func_helper)
Пример #4
0
def update_all_slots(space, w_type, pto):
    #  XXX fill slots in pto

    typedef = w_type.instancetypedef
    for method_name, slot_name, slot_names, slot_func in slotdefs_for_tp_slots:
        w_descr = w_type.lookup(method_name)
        if w_descr is None:
            # XXX special case iternext
            continue

        slot_func_helper = None

        if slot_func is None and typedef is not None:
            get_slot = get_slot_tp_function(space, typedef, slot_name)
            if get_slot:
                slot_func_helper = get_slot()
        elif slot_func:
            slot_func_helper = llhelper(slot_func.api_func.functype,
                                        slot_func.api_func.get_wrapper(space))

        if slot_func_helper is None:
            if WARN_ABOUT_MISSING_SLOT_FUNCTIONS:
                os.write(2, method_name + " defined by the type but no slot function defined!\n")
            continue

        # XXX special case wrapper-functions and use a "specific" slot func

        if len(slot_names) == 1:
            setattr(pto, slot_names[0], slot_func_helper)
        else:
            assert len(slot_names) == 2
            struct = getattr(pto, slot_names[0])
            if not struct:
                assert not space.config.translating
                assert not pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE
                if slot_names[0] == 'c_tp_as_number':
                    STRUCT_TYPE = PyNumberMethods
                elif slot_names[0] == 'c_tp_as_sequence':
                    STRUCT_TYPE = PySequenceMethods
                else:
                    raise AssertionError(
                        "Structure not allocated: %s" % (slot_names[0],))
                struct = lltype.malloc(STRUCT_TYPE, flavor='raw', zero=True)
                setattr(pto, slot_names[0], struct)

            setattr(struct, slot_names[1], slot_func_helper)
Пример #5
0
def update_all_slots(space, w_type, pto):
    # fill slots in pto
    # Not very sure about it, but according to
    # test_call_tp_dealloc, we should not
    # overwrite slots that are already set: these ones are probably
    # coming from a parent C type.

    if w_type.is_heaptype():
        typedef = None
        search_dict_w = w_type.dict_w
    else:
        typedef = w_type.layout.typedef
        search_dict_w = None

    for method_name, slot_name, slot_names, slot_apifunc in slotdefs_for_tp_slots:
        slot_func_helper = None
        if search_dict_w is None:
            # built-in types: expose as many slots as possible, even
            # if it happens to come from some parent class
            slot_apifunc = None # use get_slot_tp_function
        else:
            # For heaptypes, w_type.layout.typedef will be object's typedef, and
            # get_slot_tp_function will fail
            w_descr = search_dict_w.get(method_name, None)
            if w_descr:
                # use the slot_apifunc (userslots) to lookup at runtime
                pass
            elif len(slot_names) ==1:
                # 'inherit' from tp_base
                slot_func_helper = getattr(pto.c_tp_base, slot_names[0])
            else:
                struct = getattr(pto.c_tp_base, slot_names[0])
                if struct:
                    slot_func_helper = getattr(struct, slot_names[1])

        if not slot_func_helper:
            if typedef is not None:
                if slot_apifunc is None:
                    slot_apifunc = get_slot_tp_function(space, typedef, slot_name)
            if not slot_apifunc:
                if not we_are_translated():
                    if slot_name not in missing_slots:
                        missing_slots[slot_name] = w_type.getname(space)
                        print "missing slot %r/%r, discovered on %r" % (
                            method_name, slot_name, w_type.getname(space))
                continue
            slot_func_helper = slot_apifunc.get_llhelper(space)

        # XXX special case wrapper-functions and use a "specific" slot func

        if len(slot_names) == 1:
            if not getattr(pto, slot_names[0]):
                setattr(pto, slot_names[0], slot_func_helper)
        elif ((w_type is space.w_list or w_type is space.w_tuple) and
              slot_names[0] == 'c_tp_as_number'):
            # XXX hack - how can we generalize this? The problem is method
            # names like __mul__ map to more than one slot, and we have no
            # convenient way to indicate which slots CPython have filled
            #
            # We need at least this special case since Numpy checks that
            # (list, tuple) do __not__ fill tp_as_number
            pass
        elif (space.issubtype_w(w_type, space.w_basestring) and
                slot_names[0] == 'c_tp_as_number'):
            # like above but for any str type
            pass
        else:
            assert len(slot_names) == 2
            struct = getattr(pto, slot_names[0])
            if not struct:
                #assert not space.config.translating
                assert not pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE
                if slot_names[0] == 'c_tp_as_number':
                    STRUCT_TYPE = PyNumberMethods
                elif slot_names[0] == 'c_tp_as_sequence':
                    STRUCT_TYPE = PySequenceMethods
                elif slot_names[0] == 'c_tp_as_buffer':
                    STRUCT_TYPE = PyBufferProcs
                elif slot_names[0] == 'c_tp_as_mapping':
                    STRUCT_TYPE = PyMappingMethods
                else:
                    raise AssertionError(
                        "Structure not allocated: %s" % (slot_names[0],))
                struct = lltype.malloc(STRUCT_TYPE, flavor='raw', zero=True)
                setattr(pto, slot_names[0], struct)

            if not getattr(struct, slot_names[1]):
                setattr(struct, slot_names[1], slot_func_helper)