From 16d563840947ffcf7e3b14ecaade7d457e97bd82 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Fri, 17 Nov 2023 13:23:55 -0500 Subject: [PATCH 1/4] Turn Method Overwritten Error into a PrecompileError -- turning off caching --- src/gf.c | 6 ++++-- test/precompile.jl | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/gf.c b/src/gf.c index f964927aa3368..76ccfc3182739 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1578,8 +1578,10 @@ static void method_overwrite(jl_typemap_entry_t *newentry, jl_method_t *oldvalue jl_printf(s, ".\n"); jl_uv_flush(s); } - if (jl_generating_output()) - jl_error("Method overwriting is not permitted during Module precompile."); + if (jl_generating_output()) { + jl_printf(JL_STDERR, "ERROR: Method overwriting is not permitted during Module precompile.\n"); + jl_exit(125); + } } static void update_max_args(jl_methtable_t *mt, jl_value_t *type) diff --git a/test/precompile.jl b/test/precompile.jl index bb87e1f6b1dc7..c3425fc19bf67 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -571,6 +571,16 @@ precompile_test_harness(false) do dir @test Base.compilecache(Base.PkgId("Baz")) == Base.PrecompilableError() # due to __precompile__(false) + Baz_file = joinpath(dir, "OverwriteMethodError.jl") + write(OverwriteMethodError_file, + """ + module OverwriteMethodError + Base.:(+)(x::Bool, y::Bool) = false + end + """) + + @test Base.compilecache(Base.PkgId("OverwriteMethodError")) == Base.PrecompilableError() # due to piracy + UseBaz_file = joinpath(dir, "UseBaz.jl") write(UseBaz_file, """ From 9d26f56f38b73229af9b83d4fb0420245ed7a263 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 20 Nov 2023 14:01:45 -0500 Subject: [PATCH 2/4] Throw PrecompilableError instead of jl_exit(125) --- base/boot.jl | 2 ++ base/loading.jl | 2 +- src/gf.c | 4 ++-- src/jl_exported_data.inc | 1 + src/jltypes.c | 1 + src/julia.h | 1 + 6 files changed, 8 insertions(+), 3 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index ff3502c2f418e..e30eb7ec7e64e 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -413,6 +413,8 @@ struct InitError <: WrappedException error end +struct PrecompilableError <: Exception end + String(s::String) = s # no constructor yet const Cvoid = Nothing diff --git a/base/loading.jl b/base/loading.jl index 021c32b7c2654..a154d5441b5de 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1745,7 +1745,7 @@ function include_dependency(path::AbstractString) end # we throw PrecompilableError when a module doesn't want to be precompiled -struct PrecompilableError <: Exception end +import Core: PrecompilableError function show(io::IO, ex::PrecompilableError) print(io, "Declaring __precompile__(false) is not allowed in files that are being precompiled.") end diff --git a/src/gf.c b/src/gf.c index 76ccfc3182739..8d9ad12df020c 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1579,8 +1579,8 @@ static void method_overwrite(jl_typemap_entry_t *newentry, jl_method_t *oldvalue jl_uv_flush(s); } if (jl_generating_output()) { - jl_printf(JL_STDERR, "ERROR: Method overwriting is not permitted during Module precompile.\n"); - jl_exit(125); + jl_printf(JL_STDERR, "ERROR: Method overwriting is not permitted during Module precompilation. Use `__precompile__(false)` to opt-out of precompilation.\n"); + jl_throw(jl_precompilable_error); } } diff --git a/src/jl_exported_data.inc b/src/jl_exported_data.inc index b6b9774c1538e..1a843c71f0e1e 100644 --- a/src/jl_exported_data.inc +++ b/src/jl_exported_data.inc @@ -145,6 +145,7 @@ XX(jl_weakref_type) \ XX(jl_libdl_module) \ XX(jl_libdl_dlopen_func) \ + XX(jl_precompilable_error) \ // Data symbols that are defined inside the public libjulia #define JL_EXPORTED_DATA_SYMBOLS(XX) \ diff --git a/src/jltypes.c b/src/jltypes.c index b1830ec4e765e..82e69465400a7 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3508,6 +3508,7 @@ void post_boot_hooks(void) jl_loaderror_type = (jl_datatype_t*)core("LoadError"); jl_initerror_type = (jl_datatype_t*)core("InitError"); jl_missingcodeerror_type = (jl_datatype_t*)core("MissingCodeError"); + jl_precompilable_error = jl_new_struct_uninit((jl_datatype_t*)core("PrecompilableError")); jl_pair_type = core("Pair"); jl_kwcall_func = core("kwcall"); jl_kwcall_mt = ((jl_datatype_t*)jl_typeof(jl_kwcall_func))->name->mt; diff --git a/src/julia.h b/src/julia.h index acb700c0bd936..ddef4e7cce62e 100644 --- a/src/julia.h +++ b/src/julia.h @@ -836,6 +836,7 @@ extern JL_DLLIMPORT jl_value_t *jl_readonlymemory_exception JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_diverror_exception JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_undefref_exception JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_interrupt_exception JL_GLOBALLY_ROOTED; +extern JL_DLLIMPORT jl_value_t *jl_precompilable_error JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_boundserror_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_an_empty_vec_any JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_an_empty_memory_any JL_GLOBALLY_ROOTED; From 056a301b4f7f6b2fd458d677606974b3ca7b1a6d Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 20 Nov 2023 14:34:09 -0500 Subject: [PATCH 3/4] fixup! Throw PrecompilableError instead of jl_exit(125) --- src/staticdata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/staticdata.c b/src/staticdata.c index 42a5fdb63b63e..52a354b4933d7 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -98,7 +98,7 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 174 +#define NUM_TAGS 175 // An array of references that need to be restored from the sysimg // This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C. @@ -237,6 +237,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_readonlymemory_exception); INSERT_TAG(jl_atomicerror_type); INSERT_TAG(jl_missingcodeerror_type); + INSERT_TAG(jl_precompilable_error); // other special values INSERT_TAG(jl_emptysvec); From f40bd83ff786bb3b4dad4e64f1245983251eb0ab Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 21 Nov 2023 13:12:32 -0500 Subject: [PATCH 4/4] fixup --- test/precompile.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/precompile.jl b/test/precompile.jl index c3425fc19bf67..829d85bbc740e 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -571,7 +571,7 @@ precompile_test_harness(false) do dir @test Base.compilecache(Base.PkgId("Baz")) == Base.PrecompilableError() # due to __precompile__(false) - Baz_file = joinpath(dir, "OverwriteMethodError.jl") + OverwriteMethodError_file = joinpath(dir, "OverwriteMethodError.jl") write(OverwriteMethodError_file, """ module OverwriteMethodError