Skip to content

Commit 46c2a5c

Browse files
authored
fix runtime cglobal builtin function implementation (#59210)
This had failed to be updated for the LazyLibrary changes to codegen.
1 parent 80f7db8 commit 46c2a5c

File tree

3 files changed

+35
-29
lines changed

3 files changed

+35
-29
lines changed

src/ccall.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,9 @@ static void interpret_symbol_arg(jl_codectx_t &ctx, native_sym_arg_t &out, jl_va
606606
arg1 = update_julia_type(ctx, arg1, (jl_value_t*)jl_voidpointer_type);
607607
jl_ptr = emit_unbox(ctx, ctx.types().T_ptr, arg1, (jl_value_t*)jl_voidpointer_type);
608608
}
609+
else if (jl_is_cpointer_type(jl_typeof(ptr))) {
610+
fptr = *(void(**)(void))jl_data_ptr(ptr);
611+
}
609612
else {
610613
out.gcroot = ptr;
611614
if (jl_is_tuple(ptr) && jl_nfields(ptr) == 1) {
@@ -633,9 +636,6 @@ static void interpret_symbol_arg(jl_codectx_t &ctx, native_sym_arg_t &out, jl_va
633636
}
634637
}
635638
}
636-
else if (jl_is_cpointer_type(jl_typeof(ptr))) {
637-
fptr = *(void(**)(void))jl_data_ptr(ptr);
638-
}
639639
else if (jl_is_tuple(ptr) && jl_nfields(ptr) > 1) {
640640
jl_value_t *t0 = jl_fieldref(ptr, 0);
641641
if (jl_is_symbol(t0))

src/runtime_intrinsics.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,6 @@ JL_DLLEXPORT jl_value_t *jl_atomic_fence(jl_value_t *order_sym)
634634
JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty)
635635
{
636636
JL_TYPECHK(cglobal, type, ty);
637-
JL_GC_PUSH1(&v);
638637
jl_value_t *rt =
639638
ty == (jl_value_t*)jl_nothing_type ? (jl_value_t*)jl_voidpointer_type : // a common case
640639
(jl_value_t*)jl_apply_type1((jl_value_t*)jl_pointer_type, ty);
@@ -643,24 +642,16 @@ JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty)
643642
if (!jl_is_concrete_type(rt))
644643
jl_error("cglobal: type argument not concrete");
645644

645+
if (jl_is_pointer(v))
646+
return jl_bitcast(rt, v);
647+
646648
if (jl_is_tuple(v) && jl_nfields(v) == 1)
647649
v = jl_fieldref(v, 0);
648650

649-
if (jl_is_pointer(v)) {
650-
v = jl_bitcast(rt, v);
651-
JL_GC_POP();
652-
return v;
653-
}
654-
655-
char *f_lib = NULL;
651+
jl_value_t *f_lib = NULL;
652+
JL_GC_PUSH2(&v, &f_lib);
656653
if (jl_is_tuple(v) && jl_nfields(v) > 1) {
657-
jl_value_t *t1 = jl_fieldref(v, 1);
658-
if (jl_is_symbol(t1))
659-
f_lib = jl_symbol_name((jl_sym_t*)t1);
660-
else if (jl_is_string(t1))
661-
f_lib = jl_string_data(t1);
662-
else
663-
JL_TYPECHK(cglobal, symbol, t1)
654+
f_lib = jl_fieldref(v, 1);
664655
v = jl_fieldref(v, 0);
665656
}
666657

@@ -672,14 +663,18 @@ JL_DLLEXPORT jl_value_t *jl_cglobal(jl_value_t *v, jl_value_t *ty)
672663
else
673664
JL_TYPECHK(cglobal, symbol, v)
674665

675-
if (!f_lib)
676-
f_lib = (char*)jl_dlfind(f_name);
677-
678666
void *ptr;
679-
jl_dlsym(jl_get_library(f_lib), f_name, &ptr, 1);
667+
if (f_lib) {
668+
ptr = jl_lazy_load_and_lookup(f_lib, f_name);
669+
}
670+
else {
671+
void *handle = jl_get_library((char*)jl_dlfind(f_name));
672+
jl_dlsym(handle, f_name, &ptr, 1);
673+
}
674+
JL_GC_POP();
675+
680676
jl_value_t *jv = jl_gc_alloc(jl_current_task->ptls, sizeof(void*), rt);
681677
*(void**)jl_data_ptr(jv) = ptr;
682-
JL_GC_POP();
683678
return jv;
684679
}
685680

stdlib/Libdl/test/runtests.jl

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ mktempdir() do dir
266266
end
267267

268268
## Tests for LazyLibrary
269-
@testset "LazyLibrary" begin; mktempdir() do dir
269+
@testset "LazyLibrary" begin
270270
lclf_path = joinpath(private_libdir, "libccalllazyfoo.$(Libdl.dlext)")
271271
lclb_path = joinpath(private_libdir, "libccalllazybar.$(Libdl.dlext)")
272272

@@ -278,7 +278,7 @@ end
278278
global lclf_loaded = false
279279
global lclb_loaded = false
280280

281-
# We don't provide `dlclose()` on `LazyLibrary`'s, you have to manage it yourself:
281+
# We don't provide `dlclose()` on `LazyLibrary`'s since it is dangerous, you have to manage it yourself:
282282
function close_libs()
283283
global lclf_loaded = false
284284
global lclb_loaded = false
@@ -294,8 +294,12 @@ end
294294
@test !any(contains.(dllist(), lclb_path))
295295
end
296296

297-
global libccalllazyfoo = LazyLibrary(lclf_path; on_load_callback=() -> global lclf_loaded = true)
298-
global libccalllazybar = LazyLibrary(lclb_path; dependencies=[libccalllazyfoo], on_load_callback=() -> global lclb_loaded = true)
297+
let libccalllazyfoo = LazyLibrary(lclf_path; on_load_callback=() -> global lclf_loaded = true),
298+
libccalllazybar = LazyLibrary(lclb_path; dependencies=[libccalllazyfoo], on_load_callback=() -> global lclb_loaded = true)
299+
eval(:(const libccalllazyfoo = $libccalllazyfoo))
300+
eval(:(const libccalllazybar = $libccalllazybar))
301+
end
302+
Core.@latestworld
299303

300304
# Creating `LazyLibrary` doesn't actually load anything
301305
@test !lclf_loaded
@@ -308,7 +312,8 @@ end
308312
close_libs()
309313

310314
# Test that the library gets loaded when you use `ccall()`
311-
@test ccall((:bar, libccalllazybar), Cint, (Cint,), 2) == 6
315+
compiled_bar() = ccall((:bar, libccalllazybar), Cint, (Cint,), 2)
316+
@test ccall((:bar, libccalllazybar), Cint, (Cint,), 2) == compiled_bar() == 6
312317
@test lclf_loaded
313318
@test lclb_loaded
314319
close_libs()
@@ -324,11 +329,17 @@ end
324329
@test lclf_loaded
325330
close_libs()
326331

332+
# Test that `cglobal()` works, both compiled and runtime emulation
333+
compiled_cglobal() = cglobal((:bar, libccalllazybar))
334+
@test cglobal((:bar, libccalllazybar)) === compiled_cglobal() === dlsym(dlopen(libccalllazybar), :bar)
335+
@test lclf_loaded
336+
close_libs()
337+
327338
# Test that we can use lazily-evaluated library names:
328339
libname = LazyLibraryPath(private_libdir, "libccalllazyfoo.$(Libdl.dlext)")
329340
lazy_name_lazy_lib = LazyLibrary(libname)
330341
@test dlpath(lazy_name_lazy_lib) == realpath(string(libname))
331-
end; end
342+
end
332343

333344
@testset "Docstrings" begin
334345
@test isempty(Docs.undocumented_names(Libdl))

0 commit comments

Comments
 (0)