Skip to content

Commit ccece94

Browse files
JeffBezansontopolarity
authored andcommitted
add the ability to specify the external name of a ccallable
1 parent 925d41c commit ccece94

File tree

13 files changed

+55
-27
lines changed

13 files changed

+55
-27
lines changed

Compiler/src/typeinfer.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,8 +1373,7 @@ function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim_m
13731373
end
13741374
# additionally enqueue the ccallable entrypoint / adapter, which implicitly
13751375
# invokes the above ci
1376-
push!(codeinfos, rt)
1377-
push!(codeinfos, sig)
1376+
push!(codeinfos, item)
13781377
end
13791378
end
13801379
while !isempty(tocompile)

Compiler/src/verifytrim.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ function get_verify_typeinf_trim(codeinfos::Vector{Any})
261261
caches = IdDict{MethodInstance,CodeInstance}()
262262
errors = ErrorList()
263263
parents = ParentMap()
264-
for i = 1:2:length(codeinfos)
264+
for i = 1:length(codeinfos)
265265
item = codeinfos[i]
266266
if item isa CodeInstance
267267
push!(inspected, item)
@@ -273,14 +273,14 @@ function get_verify_typeinf_trim(codeinfos::Vector{Any})
273273
end
274274
end
275275
end
276-
for i = 1:2:length(codeinfos)
276+
for i = 1:length(codeinfos)
277277
item = codeinfos[i]
278278
if item isa CodeInstance
279279
src = codeinfos[i + 1]::CodeInfo
280280
verify_codeinstance!(item, src, inspected, caches, parents, errors)
281-
else
282-
rt = item::Type
283-
sig = codeinfos[i + 1]::Type
281+
elseif item isa SimpleVector
282+
rt = item[1]::Type
283+
sig = item[2]::Type
284284
ptr = ccall(:jl_get_specialization1,
285285
#= MethodInstance =# Ptr{Cvoid}, (Any, Csize_t, Cint),
286286
sig, this_world, #= mt_cache =# 0)

Compiler/test/verifytrim.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ let infos = typeinf_ext_toplevel(Any[Core.svec(Base.SecretBuffer, Tuple{Type{Bas
4444
4545
$""", repr)
4646

47-
resize!(infos, 2)
48-
@test infos[1] isa Type && infos[2] isa Type
47+
resize!(infos, 1)
48+
@test infos[1] isa Core.SimpleVector && infos[1][1] isa Type && infos[1][2] isa Type
4949
errors, parents = get_verify_typeinf_trim(infos)
5050
desc = only(errors)
5151
@test !desc.first

base/c.jl

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,11 @@ function exit_on_sigint(on::Bool)
203203
ccall(:jl_exit_on_sigint, Cvoid, (Cint,), on)
204204
end
205205

206-
function _ccallable(rt::Type, sigt::Type)
207-
ccall(:jl_extern_c, Cvoid, (Any, Any), rt, sigt)
206+
function _ccallable(name::Union{Nothing, String}, rt::Type, sigt::Type)
207+
ccall(:jl_extern_c, Cvoid, (Any, Any, Any), name, rt, sigt)
208208
end
209209

210-
function expand_ccallable(rt, def)
210+
function expand_ccallable(name, rt, def)
211211
if isa(def,Expr) && (def.head === :(=) || def.head === :function)
212212
sig = def.args[1]
213213
if sig.head === :(::)
@@ -235,24 +235,30 @@ function expand_ccallable(rt, def)
235235
end
236236
return quote
237237
@__doc__ $(esc(def))
238-
_ccallable($(esc(rt)), $(Expr(:curly, :Tuple, esc(f), map(esc, at)...)))
238+
_ccallable($name, $(esc(rt)), $(Expr(:curly, :Tuple, esc(f), map(esc, at)...)))
239239
end
240240
end
241241
end
242242
error("expected method definition in @ccallable")
243243
end
244244

245245
"""
246-
@ccallable(def)
246+
@ccallable ["name"] function f(...)::RetType ... end
247247
248248
Make the annotated function be callable from C using its name. This can, for example,
249-
be used to expose functionality as a C-API when creating a custom Julia sysimage.
249+
be used to expose functionality as a C API when creating a custom Julia sysimage.
250+
251+
If the first argument is a string, it is used as the external name of the function.
250252
"""
251253
macro ccallable(def)
252-
expand_ccallable(nothing, def)
254+
expand_ccallable(nothing, nothing, def)
253255
end
254256
macro ccallable(rt, def)
255-
expand_ccallable(rt, def)
257+
if rt isa String
258+
expand_ccallable(rt, nothing, def)
259+
else
260+
expand_ccallable(nothing, rt, def)
261+
end
256262
end
257263

258264
# @ccall implementation

src/aotcompile.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -798,9 +798,12 @@ void *jl_emit_native_impl(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvm
798798
compiled_functions[codeinst] = {std::move(result_m), std::move(decls)};
799799
}
800800
else {
801-
jl_value_t *sig = jl_array_ptr_ref(codeinfos, ++i);
802-
assert(jl_is_type(item) && jl_is_type(sig));
803-
jl_generate_ccallable(clone.getModuleUnlocked(), nullptr, item, sig, params);
801+
assert(jl_is_simplevector(item));
802+
jl_value_t *rt = jl_svecref(item, 0);
803+
jl_value_t *sig = jl_svecref(item, 1);
804+
jl_value_t *nameval = jl_svec_len(item) == 2 ? jl_nothing : jl_svecref(item, 2);
805+
assert(jl_is_type(rt) && jl_is_type(sig));
806+
jl_generate_ccallable(clone.getModuleUnlocked(), nullptr, nameval, rt, sig, params);
804807
}
805808
}
806809
// finally, make sure all referenced methods get fixed up, particularly if the user declined to compile them

src/codegen-stubs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ JL_DLLEXPORT uint32_t jl_get_LLVM_VERSION_fallback(void)
7070
return 0;
7171
}
7272

73-
JL_DLLEXPORT int jl_compile_extern_c_fallback(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
73+
JL_DLLEXPORT int jl_compile_extern_c_fallback(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *name, jl_value_t *declrt, jl_value_t *sigt)
7474
{
7575
// Assume we were able to register the ccallable with the JIT. The
7676
// fact that we didn't is not observable since we cannot compile

src/codegen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7696,14 +7696,14 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con
76967696

76977697
// do codegen to create a C-callable alias/wrapper, or if sysimg_handle is set,
76987698
// restore one from a loaded system image.
7699-
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params)
7699+
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *nameval, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params)
77007700
{
77017701
++GeneratedCCallables;
77027702
jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt);
77037703
assert(jl_is_datatype(ft));
77047704
jl_value_t *ff = ft->instance;
77057705
assert(ff);
7706-
const char *name = jl_symbol_name(ft->name->mt->name);
7706+
const char *name = !jl_is_string(nameval) ? jl_symbol_name(ft->name->mt->name) : jl_string_data(nameval);
77077707
jl_value_t *crt = declrt;
77087708
if (jl_is_abstract_ref_type(declrt)) {
77097709
declrt = jl_tparam0(declrt);

src/gf.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4644,7 +4644,7 @@ JL_DLLEXPORT void jl_typeinf_timing_end(uint64_t start, int is_recompile)
46444644
}
46454645

46464646
// declare a C-callable entry point; called during code loading from the toplevel
4647-
JL_DLLEXPORT void jl_extern_c(jl_value_t *declrt, jl_tupletype_t *sigt)
4647+
JL_DLLEXPORT void jl_extern_c(jl_value_t *name, jl_value_t *declrt, jl_tupletype_t *sigt)
46484648
{
46494649
// validate arguments. try to do as many checks as possible here to avoid
46504650
// throwing errors later during codegen.
@@ -4675,7 +4675,10 @@ JL_DLLEXPORT void jl_extern_c(jl_value_t *declrt, jl_tupletype_t *sigt)
46754675
if (!jl_is_method(meth))
46764676
jl_error("@ccallable: could not find requested method");
46774677
JL_GC_PUSH1(&meth);
4678-
meth->ccallable = jl_svec2(declrt, (jl_value_t*)sigt);
4678+
if (name == jl_nothing)
4679+
meth->ccallable = jl_svec2(declrt, (jl_value_t*)sigt);
4680+
else
4681+
meth->ccallable = jl_svec3(declrt, (jl_value_t*)sigt, name);
46794682
jl_gc_wb(meth, meth->ccallable);
46804683
JL_GC_POP();
46814684
}

src/jitlayers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ struct jl_codegen_params_t {
284284
~jl_codegen_params_t() JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE = default;
285285
};
286286

287-
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params);
287+
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *nameval, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params);
288288

289289
jl_llvm_functions_t jl_emit_code(
290290
orc::ThreadSafeModule &M,

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_new_method_instance_uninit(void);
19431943
JL_DLLEXPORT jl_svec_t *jl_svec(size_t n, ...) JL_MAYBE_UNROOTED;
19441944
JL_DLLEXPORT jl_svec_t *jl_svec1(void *a);
19451945
JL_DLLEXPORT jl_svec_t *jl_svec2(void *a, void *b);
1946+
JL_DLLEXPORT jl_svec_t *jl_svec3(void *a, void *b, void *c);
19461947
JL_DLLEXPORT jl_svec_t *jl_alloc_svec(size_t n);
19471948
JL_DLLEXPORT jl_svec_t *jl_alloc_svec_uninit(size_t n);
19481949
JL_DLLEXPORT jl_svec_t *jl_svec_copy(jl_svec_t *a);

0 commit comments

Comments
 (0)