|
1 |
| -const PYJLGCCACHE = Dict{PyPtr, Base.RefValue{Any}}() |
| 1 | +# we store the actual julia values here |
| 2 | +# the `value` field of `PyJuliaValueObject` indexes into here |
| 3 | +const PYJLVALUES = [] |
| 4 | +# unused indices in PYJLVALUES |
| 5 | +const PYJLFREEVALUES = Int[] |
2 | 6 |
|
3 | 7 | function _pyjl_new(t::PyPtr, ::PyPtr, ::PyPtr)
|
4 | 8 | o = ccall(UnsafePtr{PyTypeObject}(t).alloc[!], PyPtr, (PyPtr, Py_ssize_t), t, 0)
|
5 | 9 | o == PyNULL && return PyNULL
|
6 | 10 | UnsafePtr{PyJuliaValueObject}(o).weaklist[] = PyNULL
|
7 |
| - UnsafePtr{PyJuliaValueObject}(o).value[] = C_NULL |
| 11 | + UnsafePtr{PyJuliaValueObject}(o).value[] = 0 |
8 | 12 | return o
|
9 | 13 | end
|
10 | 14 |
|
11 | 15 | function _pyjl_dealloc(o::PyPtr)
|
12 |
| - delete!(PYJLGCCACHE, o) |
| 16 | + idx = UnsafePtr{PyJuliaValueObject}(o).value[] |
| 17 | + if idx != 0 |
| 18 | + PYJLVALUES[idx] = nothing |
| 19 | + push!(PYJLFREEVALUES, idx) |
| 20 | + end |
13 | 21 | UnsafePtr{PyJuliaValueObject}(o).weaklist[!] == PyNULL || PyObject_ClearWeakRefs(o)
|
14 | 22 | ccall(UnsafePtr{PyTypeObject}(Py_Type(o)).free[!], Cvoid, (PyPtr,), o)
|
15 | 23 | nothing
|
@@ -281,18 +289,28 @@ function init_jlwrap()
|
281 | 289 | end
|
282 | 290 | end
|
283 | 291 |
|
284 |
| -PyJuliaValue_IsNull(o::PyPtr) = UnsafePtr{PyJuliaValueObject}(o).value[!] == C_NULL |
| 292 | +PyJuliaValue_IsNull(o::PyPtr) = UnsafePtr{PyJuliaValueObject}(o).value[] == 0 |
285 | 293 |
|
286 |
| -PyJuliaValue_GetValue(o::PyPtr) = (Base.unsafe_pointer_to_objref(UnsafePtr{PyJuliaValueObject}(o).value[!])::Base.RefValue{Any})[] |
| 294 | +PyJuliaValue_GetValue(o::PyPtr) = PYJLVALUES[UnsafePtr{PyJuliaValueObject}(o).value[]] |
287 | 295 |
|
288 |
| -PyJuliaValue_SetValue(o::PyPtr, v) = begin |
289 |
| - ref = Base.RefValue{Any}(v) |
290 |
| - PYJLGCCACHE[o] = ref |
291 |
| - UnsafePtr{PyJuliaValueObject}(o).value[] = Base.pointer_from_objref(ref) |
| 296 | +PyJuliaValue_SetValue(o::PyPtr, @nospecialize(v)) = begin |
| 297 | + idx = UnsafePtr{PyJuliaValueObject}(o).value[] |
| 298 | + if idx == 0 |
| 299 | + if isempty(PYJLFREEVALUES) |
| 300 | + push!(PYJLVALUES, v) |
| 301 | + idx = length(PYJLVALUES) |
| 302 | + else |
| 303 | + idx = pop!(PYJLFREEVALUES) |
| 304 | + PYJLVALUES[idx] = v |
| 305 | + end |
| 306 | + UnsafePtr{PyJuliaValueObject}(o).value[] = idx |
| 307 | + else |
| 308 | + PYJLVALUES[idx] = v |
| 309 | + end |
292 | 310 | nothing
|
293 | 311 | end
|
294 | 312 |
|
295 |
| -PyJuliaValue_New(t::PyPtr, v) = begin |
| 313 | +PyJuliaValue_New(t::PyPtr, @nospecialize(v)) = begin |
296 | 314 | if PyType_IsSubtype(t, POINTERS.PyJuliaBase_Type) != 1
|
297 | 315 | PyErr_SetString(POINTERS.PyExc_TypeError, "Expecting a subtype of 'juliacall.ValueBase'")
|
298 | 316 | return PyNULL
|
|
0 commit comments