From 070a9c73083d53ae38039f1675cade027bf02f75 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Mon, 31 Oct 2016 14:58:08 -0400 Subject: [PATCH] WIP [ci skip] --- base/reflection.jl | 15 +++++++++------ src/cgutils.cpp | 35 ++++++++++++++++++++++------------- src/codegen.cpp | 14 ++++++-------- src/jltypes.c | 2 +- src/julia.h | 2 ++ 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/base/reflection.jl b/base/reflection.jl index 7bdad51c5c60f0..d19d44aba482cb 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -495,11 +495,14 @@ end # this type mirrors jl_cghooks_t (documented in julia.h) immutable CodegenHooks - module_setup::Any - module_activation::Any + module_setup::Ptr{Void} + module_activation::Ptr{Void} + raise_exception::Ptr{Void} - CodegenHooks(;module_setup=nothing, module_activation=nothing) = - new(module_setup, module_activation) + CodegenHooks(;module_setup=nothing, module_activation=nothing, raise_exception=nothing) = + new(pointer_from_objref(module_setup), + pointer_from_objref(module_activation), + pointer_from_objref(raise_exception)) end # this type mirrors jl_cgparams_t (documented in julia.h) @@ -555,9 +558,9 @@ function _dump_function(linfo::Core.MethodInstance, native::Bool, wrapper::Bool, throw(ArgumentError("'syntax' must be either :intel or :att")) end if native - llvmf = ccall(:jl_get_llvmf_decl, Ptr{Void}, (Any, Bool, CodegenParams, CodegenHooks), linfo, wrapper, params, params.hooks) + llvmf = ccall(:jl_get_llvmf_decl, Ptr{Void}, (Any, Bool, CodegenParams), linfo, wrapper, params) else - llvmf = ccall(:jl_get_llvmf_defn, Ptr{Void}, (Any, Bool, Bool, CodegenParams, CodegenHooks), linfo, wrapper, optimize, params, params.hooks) + llvmf = ccall(:jl_get_llvmf_defn, Ptr{Void}, (Any, Bool, Bool, CodegenParams), linfo, wrapper, optimize, params) end if llvmf == C_NULL error("could not compile the specified method") diff --git a/src/cgutils.cpp b/src/cgutils.cpp index a8001de13530af..c56406df9aabec 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -40,17 +40,20 @@ static Value *prepare_call(Value *Callee) // --- hook checks --- -#define JL_HOOK_TEST(params,hook) \ - ((params)->hooks.hook != jl_nothing) - -// NOTE: this is just a throwing version of jl_call1... -#define JL_HOOK_CALL1(params,hook,arg1) \ - jl_value_t **argv; \ - JL_GC_PUSHARGS(argv, 2); \ - argv[0] = (params)->hooks.hook; \ - argv[1] = arg1; \ - jl_apply(argv, 2); \ +#define JL_HOOK_TEST(params,hook) ((params)->hooks.hook != jl_nothing) + +#define JL_HOOK_CALL(params,hook,argc,...) \ + _hook_call((params)->hooks.hook, {__VA_ARGS__}); +template +static inline void _hook_call(jl_value_t *hook, std::array args) { + jl_value_t **argv; + JL_GC_PUSHARGS(argv, N+1); + argv[0] = hook; + for (int i = 0; i < N; i++) + argv[i+1] = args[i]; + jl_apply(argv, N+1); JL_GC_POP(); +} // --- string constants --- @@ -687,12 +690,18 @@ static void error_unless(Value *cond, const std::string &msg, jl_codectx_t *ctx) static void raise_exception(Value *exc, jl_codectx_t *ctx, BasicBlock *contBB=nullptr) { - JL_FEAT_REQUIRE(ctx, runtime); + if (JL_HOOK_TEST(ctx->params, raise_exception)) { + JL_HOOK_CALL(ctx->params, raise_exception, 2, + jl_box_voidpointer(wrap(builder.GetInsertBlock())), + jl_box_voidpointer(wrap(exc))); + } else { + JL_FEAT_REQUIRE(ctx, runtime); #if JL_LLVM_VERSION >= 30700 - builder.CreateCall(prepare_call(jlthrow_func), { exc }); + builder.CreateCall(prepare_call(jlthrow_func), { exc }); #else - builder.CreateCall(prepare_call(jlthrow_func), exc); + builder.CreateCall(prepare_call(jlthrow_func), exc); #endif + } builder.CreateUnreachable(); if (!contBB) { contBB = BasicBlock::Create(jl_LLVMContext, "after_throw", ctx->f); diff --git a/src/codegen.cpp b/src/codegen.cpp index c20d47bf7b3605..5a04510eb2c0a9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -925,7 +925,7 @@ jl_llvm_functions_t jl_compile_linfo(jl_method_instance_t *li, jl_code_info_t *s if (JL_HOOK_TEST(params, module_activation)) { - JL_HOOK_CALL1(params, module_activation, jl_box_voidpointer(wrap(m.release()))); + JL_HOOK_CALL(params, module_activation, 1, jl_box_voidpointer(wrap(m.release()))); } else { // Step 4. Prepare debug info to receive this function // record that this function name came from this linfo, @@ -996,7 +996,7 @@ static Value *getModuleFlag(Module *m, StringRef Key) static void jl_setup_module(Module *m, jl_cgparams_t *params = &jl_default_cgparams) { if (JL_HOOK_TEST(params, module_setup)) { - JL_HOOK_CALL1(params, module_setup, jl_box_voidpointer(wrap(m))); + JL_HOOK_CALL(params, module_setup, 1, jl_box_voidpointer(wrap(m))); return; } @@ -1266,9 +1266,8 @@ void jl_extern_c(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name) // this is paired with jl_dump_function_ir and jl_dump_function_asm in particular ways: // misuse will leak memory or cause read-after-free extern "C" JL_DLLEXPORT -void *jl_get_llvmf_defn(jl_method_instance_t *linfo, bool getwrapper, bool optimize, jl_cgparams_t params, jl_cghooks_t _hooks) +void *jl_get_llvmf_defn(jl_method_instance_t *linfo, bool getwrapper, bool optimize, jl_cgparams_t params) { - params.hooks = _hooks; // ccall doesn't know how to pass the nested jl_cghooks_t // `source` is `NULL` for generated functions. // The `isstaged` check can be removed if that is not the case anymore. if (linfo->def && linfo->def->source == NULL && !linfo->def->isstaged) { @@ -1349,9 +1348,8 @@ void *jl_get_llvmf_defn(jl_method_instance_t *linfo, bool getwrapper, bool optim extern "C" JL_DLLEXPORT -void *jl_get_llvmf_decl(jl_method_instance_t *linfo, bool getwrapper, jl_cgparams_t params, jl_cghooks_t _hooks) +void *jl_get_llvmf_decl(jl_method_instance_t *linfo, bool getwrapper, jl_cgparams_t params) { - params.hooks = _hooks; // ccall doesn't know how to pass the nested jl_cghooks_t // `source` is `NULL` for generated functions. // The `isstaged` check can be removed if that is not the case anymore. if (linfo->def && linfo->def->source == NULL && !linfo->def->isstaged) { @@ -1409,9 +1407,9 @@ void *jl_get_llvmf(jl_tupletype_t *tt, bool getwrapper, bool getdeclarations) } void *f; if (getdeclarations) - f = jl_get_llvmf_decl(linfo, getwrapper, jl_default_cgparams, jl_no_cghooks); + f = jl_get_llvmf_decl(linfo, getwrapper, jl_default_cgparams); else - f = jl_get_llvmf_defn(linfo, getwrapper, true, jl_default_cgparams, jl_no_cghooks); + f = jl_get_llvmf_defn(linfo, getwrapper, true, jl_default_cgparams); JL_GC_POP(); return f; } diff --git a/src/jltypes.c b/src/jltypes.c index b4c4498b12f150..105df0d07d443e 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3532,7 +3532,7 @@ void jl_init_types(void) jl_type_type_mt = jl_new_method_table(jl_type_type->name->name, ptls->current_module); jl_type_type->name->mt = jl_type_type_mt; - jl_no_cghooks = (jl_cghooks_t){jl_nothing, jl_nothing}; + jl_no_cghooks = (jl_cghooks_t){jl_nothing, jl_nothing, jl_nothing}; jl_default_cgparams = (jl_cgparams_t){1, 1, 1, 1, 1, 1, 1, jl_no_cghooks}; // initialize them. lots of cycles. diff --git a/src/julia.h b/src/julia.h index 7ceee216bb9e52..9fcb7c588dcae3 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1767,6 +1767,8 @@ typedef struct { // parameters: LLVMModuleRef as Ptr{Void} // return value: none jl_value_t *module_activation; + + jl_value_t *raise_exception; } jl_cghooks_t; extern JL_DLLEXPORT jl_cghooks_t jl_no_cghooks;