Skip to content

Commit

Permalink
fallback to dynamic ccall if library was not statically found
Browse files Browse the repository at this point in the history
  • Loading branch information
vchuravy committed Dec 20, 2019
1 parent d92f2ff commit b797ba3
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 33 deletions.
52 changes: 21 additions & 31 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,22 +663,18 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg
}
else {
void *symaddr;
if (!jl_dlsym(jl_get_library(sym.f_lib), sym.f_name, &symaddr, 0)) {
std::stringstream msg;
msg << "cglobal: could not find symbol ";
msg << sym.f_name;
if (sym.f_lib != NULL) {
#ifdef _OS_WINDOWS_
assert(sym.f_lib != JL_EXE_LIBNAME && sym.f_lib != JL_DL_LIBNAME);
#endif
msg << " in library ";
msg << sym.f_lib;
}
emit_error(ctx, msg.str());

void* libsym = jl_get_library_(sym.f_lib, 0);
if (!libsym || !jl_dlsym(libsym, sym.f_name, &symaddr, 0)) {
// Error mode, either the library or the symbol couldn't be find during compiletime.
// Fallback to a runtime symbol lookup.
res = runtime_sym_lookup(ctx, cast<PointerType>(T_pint8), sym.f_lib, sym.f_name, ctx.f);
res = ctx.builder.CreatePtrToInt(res, lrt);
} else {
// since we aren't saving this code, there's no sense in
// putting anything complicated here: just JIT the address of the cglobal
res = ConstantInt::get(lrt, (uint64_t)symaddr);
}
// since we aren't saving this code, there's no sense in
// putting anything complicated here: just JIT the address of the cglobal
res = ConstantInt::get(lrt, (uint64_t)symaddr);
}
}

Expand Down Expand Up @@ -1877,23 +1873,17 @@ jl_cgval_t function_sig_t::emit_a_ccall(
}
else {
void *symaddr;
if (!jl_dlsym(jl_get_library(symarg.f_lib), symarg.f_name, &symaddr, 0)) {
std::stringstream msg;
msg << "ccall: could not find function ";
msg << symarg.f_name;
if (symarg.f_lib != NULL) {
#ifdef _OS_WINDOWS_
assert(symarg.f_lib != JL_EXE_LIBNAME && symarg.f_lib != JL_DL_LIBNAME);
#endif
msg << " in library ";
msg << symarg.f_lib;
}
emit_error(ctx, msg.str());
return jl_cgval_t();

void* libsym = jl_get_library_(symarg.f_lib, 0);
if (!libsym || !jl_dlsym(libsym, symarg.f_name, &symaddr, 0)) {
// either the library or the symbol could not be found, place a runtime
// lookup here instead.
llvmf = runtime_sym_lookup(ctx, funcptype, symarg.f_lib, symarg.f_name, ctx.f);
} else {
// since we aren't saving this code, there's no sense in
// putting anything complicated here: just JIT the function address
llvmf = literal_static_pointer_val(ctx, symaddr, funcptype);
}
// since we aren't saving this code, there's no sense in
// putting anything complicated here: just JIT the function address
llvmf = literal_static_pointer_val(ctx, symaddr, funcptype);
}
}

Expand Down
17 changes: 15 additions & 2 deletions stdlib/InteractiveUtils/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,25 @@ end
@which get_A18434()(1, y=2)
@test counter18434 == 2

@eval function f_invalid(x)
Base.@_noinline_meta
$(Expr(:loopinfo, 1.0f0)) # some expression that throws an error in codegen
x
end

let _true = Ref(true), g, h
@noinline g() = _true[] ? 0 : h()
@noinline h() = (g(); f_invalid(_true[]))
@test_throws ErrorException @code_native h() # due to a failure to compile f()
@test g() == 0
end

let _true = Ref(true), f, g, h
@noinline f() = ccall((:time, "error_library_doesnt_exist\0"), Cvoid, ()) # some expression that throws an error in codegen
@noinline f() = ccall((:time, "error_library_doesnt_exist\0"), Cvoid, ()) # should throw error during runtime
@noinline g() = _true[] ? 0 : h()
@noinline h() = (g(); f())
@test_throws ErrorException @code_native h() # due to a failure to compile f()
@test g() == 0
@test_throws ErrorException h()
end

module ReflectionTest
Expand Down

0 comments on commit b797ba3

Please sign in to comment.