Skip to content

Commit b797ba3

Browse files
committed
fallback to dynamic ccall if library was not statically found
1 parent d92f2ff commit b797ba3

File tree

2 files changed

+36
-33
lines changed

2 files changed

+36
-33
lines changed

src/ccall.cpp

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -663,22 +663,18 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg
663663
}
664664
else {
665665
void *symaddr;
666-
if (!jl_dlsym(jl_get_library(sym.f_lib), sym.f_name, &symaddr, 0)) {
667-
std::stringstream msg;
668-
msg << "cglobal: could not find symbol ";
669-
msg << sym.f_name;
670-
if (sym.f_lib != NULL) {
671-
#ifdef _OS_WINDOWS_
672-
assert(sym.f_lib != JL_EXE_LIBNAME && sym.f_lib != JL_DL_LIBNAME);
673-
#endif
674-
msg << " in library ";
675-
msg << sym.f_lib;
676-
}
677-
emit_error(ctx, msg.str());
666+
667+
void* libsym = jl_get_library_(sym.f_lib, 0);
668+
if (!libsym || !jl_dlsym(libsym, sym.f_name, &symaddr, 0)) {
669+
// Error mode, either the library or the symbol couldn't be find during compiletime.
670+
// Fallback to a runtime symbol lookup.
671+
res = runtime_sym_lookup(ctx, cast<PointerType>(T_pint8), sym.f_lib, sym.f_name, ctx.f);
672+
res = ctx.builder.CreatePtrToInt(res, lrt);
673+
} else {
674+
// since we aren't saving this code, there's no sense in
675+
// putting anything complicated here: just JIT the address of the cglobal
676+
res = ConstantInt::get(lrt, (uint64_t)symaddr);
678677
}
679-
// since we aren't saving this code, there's no sense in
680-
// putting anything complicated here: just JIT the address of the cglobal
681-
res = ConstantInt::get(lrt, (uint64_t)symaddr);
682678
}
683679
}
684680

@@ -1877,23 +1873,17 @@ jl_cgval_t function_sig_t::emit_a_ccall(
18771873
}
18781874
else {
18791875
void *symaddr;
1880-
if (!jl_dlsym(jl_get_library(symarg.f_lib), symarg.f_name, &symaddr, 0)) {
1881-
std::stringstream msg;
1882-
msg << "ccall: could not find function ";
1883-
msg << symarg.f_name;
1884-
if (symarg.f_lib != NULL) {
1885-
#ifdef _OS_WINDOWS_
1886-
assert(symarg.f_lib != JL_EXE_LIBNAME && symarg.f_lib != JL_DL_LIBNAME);
1887-
#endif
1888-
msg << " in library ";
1889-
msg << symarg.f_lib;
1890-
}
1891-
emit_error(ctx, msg.str());
1892-
return jl_cgval_t();
1876+
1877+
void* libsym = jl_get_library_(symarg.f_lib, 0);
1878+
if (!libsym || !jl_dlsym(libsym, symarg.f_name, &symaddr, 0)) {
1879+
// either the library or the symbol could not be found, place a runtime
1880+
// lookup here instead.
1881+
llvmf = runtime_sym_lookup(ctx, funcptype, symarg.f_lib, symarg.f_name, ctx.f);
1882+
} else {
1883+
// since we aren't saving this code, there's no sense in
1884+
// putting anything complicated here: just JIT the function address
1885+
llvmf = literal_static_pointer_val(ctx, symaddr, funcptype);
18931886
}
1894-
// since we aren't saving this code, there's no sense in
1895-
// putting anything complicated here: just JIT the function address
1896-
llvmf = literal_static_pointer_val(ctx, symaddr, funcptype);
18971887
}
18981888
}
18991889

stdlib/InteractiveUtils/test/runtests.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,25 @@ end
251251
@which get_A18434()(1, y=2)
252252
@test counter18434 == 2
253253

254+
@eval function f_invalid(x)
255+
Base.@_noinline_meta
256+
$(Expr(:loopinfo, 1.0f0)) # some expression that throws an error in codegen
257+
x
258+
end
259+
260+
let _true = Ref(true), g, h
261+
@noinline g() = _true[] ? 0 : h()
262+
@noinline h() = (g(); f_invalid(_true[]))
263+
@test_throws ErrorException @code_native h() # due to a failure to compile f()
264+
@test g() == 0
265+
end
266+
254267
let _true = Ref(true), f, g, h
255-
@noinline f() = ccall((:time, "error_library_doesnt_exist\0"), Cvoid, ()) # some expression that throws an error in codegen
268+
@noinline f() = ccall((:time, "error_library_doesnt_exist\0"), Cvoid, ()) # should throw error during runtime
256269
@noinline g() = _true[] ? 0 : h()
257270
@noinline h() = (g(); f())
258-
@test_throws ErrorException @code_native h() # due to a failure to compile f()
259271
@test g() == 0
272+
@test_throws ErrorException h()
260273
end
261274

262275
module ReflectionTest

0 commit comments

Comments
 (0)