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)
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)
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)
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)
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)