Skip to content

Commit

Permalink
builtins: add Core.throw_methoderror
Browse files Browse the repository at this point in the history
This allows us to simulate/mark calls that are known-to-fail.
  • Loading branch information
topolarity committed Sep 6, 2024
1 parent 6f04ee0 commit 1c50356
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 1 deletion.
14 changes: 14 additions & 0 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2226,6 +2226,18 @@ function abstract_throw(interp::AbstractInterpreter, argtypes::Vector{Any}, ::Ab
return CallMeta(Union{}, exct, EFFECTS_THROWS, NoCallInfo())
end

function abstract_throw_methoderror(interp::AbstractInterpreter, argtypes::Vector{Any}, ::AbsIntState)
na = length(argtypes)
exct = if na == 1
ArgumentError
elseif !isvarargtype(argtypes[2])
MethodError
else
tmerge(𝕃ᵢ, MethodError, ArgumentError)
end
return CallMeta(Union{}, exct, Effect(EFFECTS_THROWS; consistent=false), NoCallInfo())
end

# call where the function is known exactly
function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState,
Expand All @@ -2246,6 +2258,8 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
return abstract_applicable(interp, argtypes, sv, max_methods)
elseif f === throw
return abstract_throw(interp, argtypes, sv)
elseif f === Core.throw_methoderror
return abstract_throw_methoderror(interp, argtypes, sv)
end
rt = abstract_call_builtin(interp, f, arginfo, sv)
ft = popfirst!(argtypes)
Expand Down
1 change: 1 addition & 0 deletions base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,7 @@ escape_builtin!(::typeof(Core.donotdelete), _...) = false
# not really safe, but `ThrownEscape` will be imposed later
escape_builtin!(::typeof(isdefined), _...) = false
escape_builtin!(::typeof(throw), _...) = false
escape_builtin!(::typeof(Core.throw_methoderror), _...) = false

function escape_builtin!(::typeof(ifelse), astate::AnalysisState, pc::Int, args::Vector{Any})
length(args) == 4 || return false
Expand Down
3 changes: 3 additions & 0 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ function add_tfunc(@nospecialize(f::Builtin), minarg::Int, maxarg::Int, @nospeci
end

add_tfunc(throw, 1, 1, @nospecs((𝕃::AbstractLattice, x)->Bottom), 0)
add_tfunc(Core.throw_methoderror, 1, INT_INF, @nospecs((𝕃::AbstractLattice, x)->Bottom), 0)

# the inverse of typeof_tfunc
# returns (type, isexact, isconcrete, istype)
Expand Down Expand Up @@ -2335,6 +2336,7 @@ const _EFFECT_FREE_BUILTINS = [
(<:),
typeassert,
throw,
Core.throw_methoderror,
getglobal,
compilerbarrier,
]
Expand All @@ -2350,6 +2352,7 @@ const _INACCESSIBLEMEM_BUILTINS = Any[
isa,
nfields,
throw,
Core.throw_methoderror,
tuple,
typeassert,
typeof,
Expand Down
1 change: 1 addition & 0 deletions src/builtin_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ DECLARE_BUILTIN(svec);
DECLARE_BUILTIN(swapfield);
DECLARE_BUILTIN(swapglobal);
DECLARE_BUILTIN(throw);
DECLARE_BUILTIN(throw_methoderror);
DECLARE_BUILTIN(tuple);
DECLARE_BUILTIN(typeassert);
DECLARE_BUILTIN(typeof);
Expand Down
9 changes: 9 additions & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,14 @@ JL_CALLABLE(jl_f_throw)
return jl_nothing;
}

JL_CALLABLE(jl_f_throw_methoderror)
{
JL_NARGSV(throw_methoderror, 1);
size_t world = jl_get_tls_world_age();
jl_method_error((jl_function_t *)args[0], &args[1], nargs, world);
return jl_nothing;
}

JL_CALLABLE(jl_f_ifelse)
{
JL_NARGS(ifelse, 3, 3);
Expand Down Expand Up @@ -2437,6 +2445,7 @@ void jl_init_primitives(void) JL_GC_DISABLED
add_builtin_func("_compute_sparams", jl_f__compute_sparams);
add_builtin_func("_svec_ref", jl_f__svec_ref);
add_builtin_func("current_scope", jl_f_current_scope);
add_builtin_func("throw_methoderror", jl_f_throw_methoderror);

// builtin types
add_builtin("Any", (jl_value_t*)jl_any_type);
Expand Down
2 changes: 1 addition & 1 deletion src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ static htable_t relocatable_ext_cis;
// (reverse of fptr_to_id)
// This is a manually constructed dual of the fvars array, which would be produced by codegen for Julia code, for C.
static const jl_fptr_args_t id_to_fptrs[] = {
&jl_f_throw, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa,
&jl_f_throw, &jl_f_throw_methoderror, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa,
&jl_f_typeassert, &jl_f__apply_iterate, &jl_f__apply_pure,
&jl_f__call_latest, &jl_f__call_in_world, &jl_f__call_in_world_total, &jl_f_isdefined,
&jl_f_tuple, &jl_f_svec, &jl_f_intrinsic_call,
Expand Down

0 comments on commit 1c50356

Please sign in to comment.