Skip to content

Commit f3acf38

Browse files
author
Christopher Doris
committed
jlwrap now stores values in an array
1 parent ec33e56 commit f3acf38

File tree

3 files changed

+29
-133
lines changed

3 files changed

+29
-133
lines changed

src/cpython/consts.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,6 @@ end
326326

327327
@kwdef struct PyJuliaValueObject
328328
ob_base::PyObject = PyObject()
329-
value::Ptr{Cvoid} = C_NULL
329+
value::Int = 0
330330
weaklist::PyPtr = C_NULL
331331
end

src/cpython/jlwrap.jl

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
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[]
26

37
function _pyjl_new(t::PyPtr, ::PyPtr, ::PyPtr)
48
o = ccall(UnsafePtr{PyTypeObject}(t).alloc[!], PyPtr, (PyPtr, Py_ssize_t), t, 0)
59
o == PyNULL && return PyNULL
610
UnsafePtr{PyJuliaValueObject}(o).weaklist[] = PyNULL
7-
UnsafePtr{PyJuliaValueObject}(o).value[] = C_NULL
11+
UnsafePtr{PyJuliaValueObject}(o).value[] = 0
812
return o
913
end
1014

1115
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
1321
UnsafePtr{PyJuliaValueObject}(o).weaklist[!] == PyNULL || PyObject_ClearWeakRefs(o)
1422
ccall(UnsafePtr{PyTypeObject}(Py_Type(o)).free[!], Cvoid, (PyPtr,), o)
1523
nothing
@@ -281,18 +289,28 @@ function init_jlwrap()
281289
end
282290
end
283291

284-
PyJuliaValue_IsNull(o::PyPtr) = UnsafePtr{PyJuliaValueObject}(o).value[!] == C_NULL
292+
PyJuliaValue_IsNull(o::PyPtr) = UnsafePtr{PyJuliaValueObject}(o).value[] == 0
285293

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[]]
287295

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
292310
nothing
293311
end
294312

295-
PyJuliaValue_New(t::PyPtr, v) = begin
313+
PyJuliaValue_New(t::PyPtr, @nospecialize(v)) = begin
296314
if PyType_IsSubtype(t, POINTERS.PyJuliaBase_Type) != 1
297315
PyErr_SetString(POINTERS.PyExc_TypeError, "Expecting a subtype of 'juliacall.ValueBase'")
298316
return PyNULL

src/old/utils.jl

Lines changed: 0 additions & 122 deletions
This file was deleted.

0 commit comments

Comments
 (0)