Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

define Core.Closure and make compiler-generated closures subtype of it #56928

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -2531,6 +2531,7 @@ void jl_init_primitives(void) JL_GC_DISABLED
add_builtin("IntrinsicFunction", (jl_value_t*)jl_intrinsic_type);
add_builtin("Function", (jl_value_t*)jl_function_type);
add_builtin("Builtin", (jl_value_t*)jl_builtin_type);
add_builtin("Closure", (jl_value_t*)jl_closure_type);
add_builtin("MethodInstance", (jl_value_t*)jl_method_instance_type);
add_builtin("CodeInfo", (jl_value_t*)jl_code_info_type);
add_builtin("LLVMPtr", (jl_value_t*)jl_llvmpointer_type);
Expand Down
3 changes: 2 additions & 1 deletion src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,8 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype(
}
else {
tn = jl_new_typename_in((jl_sym_t*)name, module, abstract, mutabl);
if (super == jl_function_type || super == jl_builtin_type || is_anonfn_typename(jl_symbol_name(name))) {
if (super == jl_function_type || super == jl_builtin_type ||
super == jl_closure_type || is_anonfn_typename(jl_symbol_name(name))) {
// Callable objects (including compiler-generated closures) get independent method tables
// as an optimization
tn->mt = jl_new_method_table(name, module);
Expand Down
2 changes: 1 addition & 1 deletion src/ircode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1602,7 +1602,7 @@ void jl_init_serializer(void)
jl_pointer_type, jl_abstractarray_type, jl_nothing_type,
jl_vararg_type,
jl_densearray_type, jl_function_type, jl_typename_type,
jl_builtin_type, jl_task_type, jl_uniontype_type,
jl_builtin_type, jl_closure_type, jl_task_type, jl_uniontype_type,
jl_array_any_type, jl_intrinsic_type,
jl_methtable_type, jl_typemap_level_type,
jl_voidpointer_type, jl_newvarnode_type, jl_abstractstring_type,
Expand Down
1 change: 1 addition & 0 deletions src/jl_exported_data.inc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
XX(jl_bottom_type) \
XX(jl_boundserror_type) \
XX(jl_builtin_type) \
XX(jl_closure_type) \
XX(jl_char_type) \
XX(jl_code_info_type) \
XX(jl_code_instance_type) \
Expand Down
2 changes: 2 additions & 0 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -3248,8 +3248,10 @@ void jl_init_types(void) JL_GC_DISABLED

jl_function_type = jl_new_abstracttype((jl_value_t*)jl_symbol("Function"), core, jl_any_type, jl_emptysvec);
jl_builtin_type = jl_new_abstracttype((jl_value_t*)jl_symbol("Builtin"), core, jl_function_type, jl_emptysvec);
jl_closure_type = jl_new_abstracttype((jl_value_t*)jl_symbol("Closure"), core, jl_function_type, jl_emptysvec);
jl_function_type->name->mt = NULL; // subtypes of Function have independent method tables
jl_builtin_type->name->mt = NULL; // so they don't share the Any type table
jl_closure_type->name->mt = NULL;

jl_svec_t *tv;

Expand Down
4 changes: 2 additions & 2 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -4232,8 +4232,8 @@ f(x) = yt(x)
(filter ssavalue? fieldtypes)))
(fieldnames (append closure-param-names (filter (lambda (v) (not (is-var-boxed? v lam))) capt-vars))))
(if (null? para)
(type-for-closure type-name capt-vars '(core Function))
(type-for-closure-parameterized type-name para fieldnames capt-vars fieldtypes '(core Function)))))
(type-for-closure type-name capt-vars '(core Closure))
(type-for-closure-parameterized type-name para fieldnames capt-vars fieldtypes '(core Closure)))))
(mk-method ;; expression to make the method
(if short '()
(let* ((iskw ;; TODO jb/functions need more robust version of this
Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ extern JL_DLLIMPORT jl_unionall_t *jl_anytuple_type_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_vararg_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_function_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_builtin_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_datatype_t *jl_closure_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_unionall_t *jl_opaque_closure_type JL_GLOBALLY_ROOTED;
extern JL_DLLIMPORT jl_typename_t *jl_opaque_closure_typename JL_GLOBALLY_ROOTED;

Expand Down
3 changes: 2 additions & 1 deletion src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ extern "C" {
// TODO: put WeakRefs on the weak_refs list during deserialization
// TODO: handle finalizers

#define NUM_TAGS 195
#define NUM_TAGS 196

// 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.
Expand Down Expand Up @@ -162,6 +162,7 @@ jl_value_t **const*const get_tags(void) {
INSERT_TAG(jl_unionall_type);
INSERT_TAG(jl_typename_type);
INSERT_TAG(jl_builtin_type);
INSERT_TAG(jl_closure_type);
INSERT_TAG(jl_code_info_type);
INSERT_TAG(jl_opaque_closure_type);
INSERT_TAG(jl_task_type);
Expand Down
2 changes: 1 addition & 1 deletion stdlib/Serialization/src/Serialization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ function should_send_whole_type(s, t::DataType)
name = tn.mt.name
mod = tn.module
isanonfunction = mod === Main && # only Main
t.super === Function && # only Functions
t.super === Core.Closure && # only Functions
unsafe_load(unsafe_convert(Ptr{UInt8}, tn.name)) == UInt8('#') && # hidden type
(!isdefined(mod, name) || t != typeof(getglobal(mod, name))) # XXX: 95% accurate test for this being an inner function
# TODO: more accurate test? (tn.name !== "#" name)
Expand Down
10 changes: 10 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8398,3 +8398,13 @@ f_call_me() = invoke(f_invoke_me, f_invoke_me_ci)
f_invalidate_me() = 2
@test_throws ErrorException invoke(f_invoke_me, f_invoke_me_ci)
@test_throws ErrorException f_call_me()

function genenerate_closure(argtypes::Vector{Any})
local argtypesi
@inline function closure()
argtypesi = @noinline copy(argtypes)
return length(argtypesi)
end
return closure
end
@test genenerate_closure(Any[]) isa Core.Closure
Loading