def finalizer_funcptr_for_type(self, TYPE): if TYPE in self.finalizer_funcptrs: return self.finalizer_funcptrs[TYPE] rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] else: destrptr = None DESTR_ARG = None if type_contains_pyobjs(TYPE): if destrptr: raise Exception("can't mix PyObjects and __del__ with Boehm") static_body = '\n'.join( _static_deallocator_body_for_type('v', TYPE)) d = { 'pop_alive': LLTransformerOp(self.pop_alive), 'PTR_TYPE': lltype.Ptr(TYPE), 'cast_adr_to_ptr': llmemory.cast_adr_to_ptr } src = ("def ll_finalizer(addr):\n" " v = cast_adr_to_ptr(addr, PTR_TYPE)\n" "%s\n") % (static_body, ) exec src in d fptr = self.annotate_finalizer(d['ll_finalizer'], [llmemory.Address], lltype.Void) elif destrptr: EXC_INSTANCE_TYPE = self.translator.rtyper.exceptiondata.lltype_of_exception_value typename = TYPE.__name__ def ll_finalizer(addr): exc_instance = llop.gc_fetch_exception(EXC_INSTANCE_TYPE) v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) ll_call_destructor(destrptr, v, typename) llop.gc_restore_exception(lltype.Void, exc_instance) fptr = self.annotate_finalizer(ll_finalizer, [llmemory.Address], lltype.Void) else: fptr = lltype.nullptr(self.FINALIZER_PTR.TO) self.finalizer_funcptrs[TYPE] = fptr return fptr
def finalizer_funcptr_for_type(self, TYPE): if TYPE in self.finalizer_funcptrs: return self.finalizer_funcptrs[TYPE] rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] else: destrptr = None DESTR_ARG = None if type_contains_pyobjs(TYPE): if destrptr: raise Exception("can't mix PyObjects and __del__ with Boehm") static_body = '\n'.join(_static_deallocator_body_for_type('v', TYPE)) d = {'pop_alive': LLTransformerOp(self.pop_alive), 'PTR_TYPE':lltype.Ptr(TYPE), 'cast_adr_to_ptr': llmemory.cast_adr_to_ptr} src = ("def ll_finalizer(addr):\n" " v = cast_adr_to_ptr(addr, PTR_TYPE)\n" "%s\n")%(static_body,) exec src in d fptr = self.annotate_finalizer(d['ll_finalizer'], [llmemory.Address], lltype.Void) elif destrptr: EXC_INSTANCE_TYPE = self.translator.rtyper.exceptiondata.lltype_of_exception_value typename = TYPE.__name__ def ll_finalizer(addr): exc_instance = llop.gc_fetch_exception(EXC_INSTANCE_TYPE) v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG) ll_call_destructor(destrptr, v, typename) llop.gc_restore_exception(lltype.Void, exc_instance) fptr = self.annotate_finalizer(ll_finalizer, [llmemory.Address], lltype.Void) else: fptr = lltype.nullptr(self.FINALIZER_PTR.TO) self.finalizer_funcptrs[TYPE] = fptr return fptr
def static_deallocation_funcptr_for_type(self, TYPE): if TYPE in self.static_deallocator_funcptrs: return self.static_deallocator_funcptrs[TYPE] # print_call_chain(self) if TYPE._gckind == "cpy": return # you don't really have an RPython deallocator for PyObjects rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, "destructor_funcptr"): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] else: destrptr = None DESTR_ARG = None if destrptr is None and not find_gc_ptrs_in_type(TYPE): p = self.no_pointer_dealloc_ptr.value self.static_deallocator_funcptrs[TYPE] = p return p if destrptr is not None: body = "\n".join(_static_deallocator_body_for_type("v", TYPE, 3)) src = """ def ll_deallocator(addr): exc_instance = llop.gc_fetch_exception(EXC_INSTANCE_TYPE) try: v = cast_adr_to_ptr(addr, PTR_TYPE) gcheader = cast_adr_to_ptr(addr - gc_header_offset, HDRPTR) # refcount is at zero, temporarily bump it to 1: gcheader.refcount = 1 destr_v = cast_pointer(DESTR_ARG, v) ll_call_destructor(destrptr, destr_v) refcount = gcheader.refcount - 1 gcheader.refcount = refcount if refcount == 0: %s llop.%s_free(lltype.Void, addr) except: pass llop.gc_restore_exception(lltype.Void, exc_instance) pop_alive(exc_instance) # XXX layering of exceptiontransform versus gcpolicy """ % ( body, TYPE._gckind, ) else: call_del = None body = "\n".join(_static_deallocator_body_for_type("v", TYPE)) src = ( "def ll_deallocator(addr):\n v = cast_adr_to_ptr(addr, PTR_TYPE)\n" + body + "\n llop.%s_free(lltype.Void, addr)\n" % (TYPE._gckind,) ) d = { "pop_alive": LLTransformerOp(self.pop_alive), "llop": llop, "lltype": lltype, "destrptr": destrptr, "gc_header_offset": self.gcheaderbuilder.size_gc_header, "cast_adr_to_ptr": llmemory.cast_adr_to_ptr, "cast_pointer": lltype.cast_pointer, "PTR_TYPE": lltype.Ptr(TYPE), "DESTR_ARG": DESTR_ARG, "EXC_INSTANCE_TYPE": self.translator.rtyper.exceptiondata.lltype_of_exception_value, "ll_call_destructor": ll_call_destructor, "HDRPTR": lltype.Ptr(self.HDR), } exec src in d this = d["ll_deallocator"] fptr = self.annotate_finalizer(this, [llmemory.Address], lltype.Void) self.static_deallocator_funcptrs[TYPE] = fptr for p in find_gc_ptrs_in_type(TYPE): self.static_deallocation_funcptr_for_type(p.TO) return fptr
def static_deallocation_funcptr_for_type(self, TYPE): if TYPE in self.static_deallocator_funcptrs: return self.static_deallocator_funcptrs[TYPE] #print_call_chain(self) if TYPE._gckind == 'cpy': return # you don't really have an RPython deallocator for PyObjects rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] else: destrptr = None DESTR_ARG = None if destrptr is None and not find_gc_ptrs_in_type(TYPE): p = self.no_pointer_dealloc_ptr.value self.static_deallocator_funcptrs[TYPE] = p return p if destrptr is not None: body = '\n'.join(_static_deallocator_body_for_type('v', TYPE, 3)) src = """ def ll_deallocator(addr): exc_instance = llop.gc_fetch_exception(EXC_INSTANCE_TYPE) try: v = cast_adr_to_ptr(addr, PTR_TYPE) gcheader = cast_adr_to_ptr(addr - gc_header_offset, HDRPTR) # refcount is at zero, temporarily bump it to 1: gcheader.refcount = 1 destr_v = cast_pointer(DESTR_ARG, v) ll_call_destructor(destrptr, destr_v) refcount = gcheader.refcount - 1 gcheader.refcount = refcount if refcount == 0: %s llop.%s_free(lltype.Void, addr) except: pass llop.gc_restore_exception(lltype.Void, exc_instance) pop_alive(exc_instance) # XXX layering of exceptiontransform versus gcpolicy """ % (body, TYPE._gckind) else: call_del = None body = '\n'.join(_static_deallocator_body_for_type('v', TYPE)) src = ('def ll_deallocator(addr):\n v = cast_adr_to_ptr(addr, PTR_TYPE)\n' + body + '\n llop.%s_free(lltype.Void, addr)\n' % (TYPE._gckind,)) d = {'pop_alive': LLTransformerOp(self.pop_alive), 'llop': llop, 'lltype': lltype, 'destrptr': destrptr, 'gc_header_offset': self.gcheaderbuilder.size_gc_header, 'cast_adr_to_ptr': llmemory.cast_adr_to_ptr, 'cast_pointer': lltype.cast_pointer, 'PTR_TYPE': lltype.Ptr(TYPE), 'DESTR_ARG': DESTR_ARG, 'EXC_INSTANCE_TYPE': self.translator.rtyper.exceptiondata.lltype_of_exception_value, 'll_call_destructor': ll_call_destructor, 'HDRPTR':lltype.Ptr(self.HDR)} exec src in d this = d['ll_deallocator'] fptr = self.annotate_finalizer(this, [llmemory.Address], lltype.Void) self.static_deallocator_funcptrs[TYPE] = fptr for p in find_gc_ptrs_in_type(TYPE): self.static_deallocation_funcptr_for_type(p.TO) return fptr
def static_deallocation_funcptr_for_type(self, TYPE): if TYPE in self.static_deallocator_funcptrs: return self.static_deallocator_funcptrs[TYPE] #print_call_chain(self) rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0] else: destrptr = None DESTR_ARG = None if destrptr is None and not find_gc_ptrs_in_type(TYPE): #print repr(TYPE)[:80], 'is dealloc easy' p = self.no_pointer_dealloc_ptr.value self.static_deallocator_funcptrs[TYPE] = p return p if destrptr is not None: body = '\n'.join(_static_deallocator_body_for_type('v', TYPE, 3)) src = """ def ll_deallocator(addr): exc_instance = llop.gc_fetch_exception(EXC_INSTANCE_TYPE) try: v = cast_adr_to_ptr(addr, PTR_TYPE) gcheader = cast_adr_to_ptr(addr - gc_header_offset, HDRPTR) # refcount is at zero, temporarily bump it to 1: gcheader.refcount = 1 destr_v = cast_pointer(DESTR_ARG, v) ll_call_destructor(destrptr, destr_v) refcount = gcheader.refcount - 1 gcheader.refcount = refcount if refcount == 0: %s llop.gc_free(lltype.Void, addr) except: pass llop.gc_restore_exception(lltype.Void, exc_instance) pop_alive(exc_instance) # XXX layering of exceptiontransform versus gcpolicy """ % (body, ) else: call_del = None body = '\n'.join(_static_deallocator_body_for_type('v', TYPE)) src = ('def ll_deallocator(addr):\n v = cast_adr_to_ptr(addr, PTR_TYPE)\n' + body + '\n llop.gc_free(lltype.Void, addr)\n') d = {'pop_alive': LLTransformerOp(self.pop_alive), 'llop': llop, 'lltype': lltype, 'destrptr': destrptr, 'gc_header_offset': self.gcheaderbuilder.size_gc_header, 'cast_adr_to_ptr': llmemory.cast_adr_to_ptr, 'cast_pointer': lltype.cast_pointer, 'PTR_TYPE': lltype.Ptr(TYPE), 'DESTR_ARG': DESTR_ARG, 'EXC_INSTANCE_TYPE': self.translator.rtyper.exceptiondata.lltype_of_exception_value, 'll_call_destructor': ll_call_destructor, 'HDRPTR':lltype.Ptr(self.HDR)} exec src in d this = d['ll_deallocator'] fptr = self.annotate_helper(this, [llmemory.Address], lltype.Void) self.static_deallocator_funcptrs[TYPE] = fptr for p in find_gc_ptrs_in_type(TYPE): self.static_deallocation_funcptr_for_type(p.TO) return fptr