From 72e5017148134a5ac56b884c82dea44c4ef7d61b Mon Sep 17 00:00:00 2001 From: Amyas Chew Date: Fri, 30 Oct 2015 10:51:55 -0400 Subject: [PATCH] Added weak references support to jlwrap types (for #21 and #158) --- src/pyinit.jl | 3 +++ src/pytype.jl | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/pyinit.jl b/src/pyinit.jl index 7b33a2bb..28058dba 100644 --- a/src/pyinit.jl +++ b/src/pyinit.jl @@ -122,6 +122,9 @@ function __init__() PyMemberDef[ PyMemberDef(pyjlwrap_membername, T_PYSSIZET, sizeof_PyObject_HEAD, READONLY, pyjlwrap_doc), + PyMemberDef(weakreflist_membername, + T_OBJECT_EX, sizeof_PyObject_HEAD+sizeof(PyPtr), 0, + weakreflist_doc), PyMemberDef(C_NULL,0,0,0,C_NULL) ] init_datetime() diff --git a/src/pytype.jl b/src/pytype.jl index 5acb3dd5..34bb98d8 100644 --- a/src/pytype.jl +++ b/src/pytype.jl @@ -340,12 +340,17 @@ immutable Py_jlWrap # PyObject_HEAD (for non-Py_TRACE_REFS build): ob_refcnt::Int ob_type::PyPtr - + jl_value::Any + ob_weakreflist::PyPtr #list of weak references end # destructor for jlwrap instance, assuming it was created with pyjlwrap_new function pyjlwrap_dealloc(o::PyPtr) + #Delete weak reference list + ccall((@pysym :PyObject_ClearWeakRefs), Void, + (PyPtr,), o) + delete!(pycall_gc, o) return nothing end @@ -379,6 +384,8 @@ end # constant strings (must not be gc'ed) for pyjlwrap_members const pyjlwrap_membername = "jl_value" const pyjlwrap_doc = "Julia jl_value_t* (Any object)" +const weakreflist_membername = "ob_weakreflist" +const weakreflist_doc = "List of weak references" # called in __init__ function pyjlwrap_init() @@ -391,6 +398,8 @@ function pyjlwrap_init() t.tp_repr = pyjlwrap_repr_ptr t.tp_hash = sizeof(Py_hash_t) < sizeof(Int) ? pyjlwrap_hash32_ptr : pyjlwrap_hash_ptr + t.tp_weaklistoffset = fieldoffsets(Py_jlWrap)[4] #set to actual offset + t.tp_flags |= Py_TPFLAGS_HAVE_WEAKREFS #set weak refs bit end) end @@ -416,6 +425,7 @@ function pyjlwrap_new(pyT::PyTypeObject, value::Any) pycall_gc[o.o] = value p = convert(Ptr{Ptr{Void}}, o.o) unsafe_store!(p, ccall(:jl_value_ptr, Ptr{Void}, (Any,), value), 3) + unsafe_store!(p, C_NULL, 4) #initiate weakreflist as NULL return o end