def get_instances_array_gc(interp, w_class=None): space = interp.space from rpython.rlib import rgc result_w = [] roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] pending = roots[:] while pending: gcref = pending.pop() if not rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) w_obj = rgc.try_cast_gcref_to_instance(W_Object, gcref) if w_obj is not None and w_obj.has_class(): w_cls = w_obj.getclass(space) if w_cls is not None: # XXX: should not return SmallFloat64 on Spur64... if ((not w_cls.is_same_object(space.w_SmallInteger)) and (not (space.is_spur.is_set() and w_cls.is_same_object(space.w_Character))) and (w_class is None or w_cls.is_same_object(w_class))): result_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) rgc.clear_gcflag_extra(roots) rgc.assert_no_more_gcflags() return result_w
def test_get_referents(): class X(object): __slots__ = ['stuff'] x1 = X() x1.stuff = X() x2 = X() lst = rgc.get_rpy_referents(rgc.cast_instance_to_gcref(x1)) lst2 = [rgc.try_cast_gcref_to_instance(X, x) for x in lst] assert x1.stuff in lst2 assert x2 not in lst2
def _reveal(space, ptr): addr = rffi.cast(llmemory.Address, ptr) gcref = rgc.reveal_gcref(addr) if not gcref: raise oefmt(space.w_RuntimeError, "cannot use from_handle() on NULL pointer") cd = rgc.try_cast_gcref_to_instance(cdataobj.W_CDataHandle, gcref) if cd is None: raise oefmt(space.w_SystemError, "ffi.from_handle(): dead or bogus object handle") return cd.w_keepalive
def try_cast_gcref_to_w_root(gcref): w_obj = rgc.try_cast_gcref_to_instance(W_Root, gcref) # Ignore the instances of W_Root that are not really valid as Python # objects. There is e.g. WeakrefLifeline in module/_weakref that # inherits from W_Root for internal reasons. Such instances don't # have a typedef at all (or have a null typedef after translation). if not we_are_translated(): if getattr(w_obj, 'typedef', None) is None: return None else: if w_obj is None or not w_obj.typedef: return None return w_obj
def try_cast_gcref_to_w_root(gcref): w_obj = rgc.try_cast_gcref_to_instance(W_Root, gcref) # Ignore the instances of W_Root that are not really valid as Python # objects. There is e.g. WeakrefLifeline in module/_weakref that # inherits from W_Root for internal reasons. Such instances don't # have a typedef at all (or have a null typedef after translation). if not we_are_translated(): if not hasattr(w_obj, "typedef"): return None else: if w_obj is None or not w_obj.typedef: return None return w_obj
def fn(): foo = Foo() gcref1 = rgc.cast_instance_to_gcref(foo) assert rgc.try_cast_gcref_to_instance(Foo, gcref1) is foo assert rgc.try_cast_gcref_to_instance(FooBar, gcref1) is None assert rgc.try_cast_gcref_to_instance(Biz, gcref1) is None foobar = FooBar() gcref2 = rgc.cast_instance_to_gcref(foobar) assert rgc.try_cast_gcref_to_instance(Foo, gcref2) is foobar assert rgc.try_cast_gcref_to_instance(FooBar, gcref2) is foobar assert rgc.try_cast_gcref_to_instance(Biz, gcref2) is None s = lltype.malloc(S) gcref3 = lltype.cast_opaque_ptr(llmemory.GCREF, s) assert rgc.try_cast_gcref_to_instance(Foo, gcref3) is None assert rgc.try_cast_gcref_to_instance(FooBar, gcref3) is None assert rgc.try_cast_gcref_to_instance(Biz, gcref3) is None return 0
def getMonteObjects(): roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] pending = roots[:] result_w = [] while pending: gcref = pending.pop() if not rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) w_obj = rgc.try_cast_gcref_to_instance(Object, gcref) if w_obj is not None: result_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) clear_gcflag_extra(roots) rgc.assert_no_more_gcflags() return result_w
def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. ffi_cif - something ffi specific, don't care ll_args - rffi.VOIDPP - pointer to array of pointers to args ll_res - rffi.VOIDP - pointer to result ll_userdata - a special structure which holds necessary information (what the real callback is for example), casted to VOIDP """ # Reveal the callback. addr = rffi.cast(llmemory.Address, ll_userdata) gcref = rgc.reveal_gcref(addr) callback = rgc.try_cast_gcref_to_instance(Callback, gcref) if callback is None: try: os.write(STDERR, "Critical error: invoking a callback that was already freed\n") except: pass # We cannot do anything here. else: #must_leave = False try: # must_leave = space.threadlocals.try_enter_thread(space) # Should check for separate threads here and crash # if the callback comes from a thread that has no execution context. cfunc = callback.cfunc argv = [] for i in range(0, len(cfunc.argtypes)): argv.append( cfunc.argtypes[i].load(ll_args[i], False) ) value = callback.callback.call(argv) if isinstance(cfunc.restype, Type): cfunc.restype.store(None, ll_res, value) except Unwinder as unwinder: core.root_unwind(unwinder) except Exception as e: try: os.write(STDERR, "SystemError: callback raised ") os.write(STDERR, str(e)) os.write(STDERR, "\n") except: pass
def try_cast_to_code(gcref): return rgc.try_cast_gcref_to_instance(CodeClass, gcref)
def reveal_object(Class, raw_ptr): addr = rffi.cast(llmemory.Address, raw_ptr) gcref = rgc.reveal_gcref(addr) return rgc.try_cast_gcref_to_instance(Class, gcref)
def try_cast_gcref_to_w_baseobject(gcref): return rgc.try_cast_gcref_to_instance(W_BaseObject, gcref)
def reveal_callback(raw_ptr): addr = rffi.cast(llmemory.Address, raw_ptr) gcref = rgc.reveal_gcref(addr) return rgc.try_cast_gcref_to_instance(W_ExternPython, gcref)
def try_cast_to_pycode(gcref): return rgc.try_cast_gcref_to_instance(PyCode, gcref)