Skip to content

Commit aca5a3e

Browse files
committed
_apply_in_world builtin
New builtin Core._apply_in_world to allow frozen-world APIs to be implemented in pure Julia code.
1 parent 65869b1 commit aca5a3e

File tree

6 files changed

+33
-1
lines changed

6 files changed

+33
-1
lines changed

src/builtin_proto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ DECLARE_BUILTIN(typeof); DECLARE_BUILTIN(sizeof);
2424
DECLARE_BUILTIN(issubtype); DECLARE_BUILTIN(isa);
2525
DECLARE_BUILTIN(_apply); DECLARE_BUILTIN(_apply_pure);
2626
DECLARE_BUILTIN(_apply_latest); DECLARE_BUILTIN(_apply_iterate);
27+
DECLARE_BUILTIN(_apply_in_world);
2728
DECLARE_BUILTIN(isdefined); DECLARE_BUILTIN(nfields);
2829
DECLARE_BUILTIN(tuple); DECLARE_BUILTIN(svec);
2930
DECLARE_BUILTIN(getfield); DECLARE_BUILTIN(setfield);

src/builtins.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,24 @@ JL_CALLABLE(jl_f__apply_latest)
707707
return ret;
708708
}
709709

710+
// Like `_apply`, but runs in the specified world.
711+
// If world > jl_world_counter, run in the latest world.
712+
JL_CALLABLE(jl_f__apply_in_world)
713+
{
714+
JL_NARGSV(_apply_in_world, 2);
715+
jl_ptls_t ptls = jl_get_ptls_states();
716+
size_t last_age = ptls->world_age;
717+
JL_TYPECHK(_apply_in_world, ulong, args[0]);
718+
size_t world = jl_unbox_ulong(args[0]);
719+
world = world <= jl_world_counter ? world : jl_world_counter;
720+
if (!ptls->in_pure_callback) {
721+
ptls->world_age = world;
722+
}
723+
jl_value_t *ret = do_apply(NULL, args+1, nargs-1, NULL);
724+
ptls->world_age = last_age;
725+
return ret;
726+
}
727+
710728
// tuples ---------------------------------------------------------------------
711729

712730
JL_CALLABLE(jl_f_tuple)
@@ -1529,6 +1547,7 @@ void jl_init_primitives(void) JL_GC_DISABLED
15291547
jl_builtin_svec = add_builtin_func("svec", jl_f_svec);
15301548
add_builtin_func("_apply_pure", jl_f__apply_pure);
15311549
add_builtin_func("_apply_latest", jl_f__apply_latest);
1550+
add_builtin_func("_apply_in_world", jl_f__apply_in_world);
15321551
add_builtin_func("_typevar", jl_f__typevar);
15331552
add_builtin_func("_structtype", jl_f__structtype);
15341553
add_builtin_func("_abstracttype", jl_f__abstracttype);

src/codegen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7018,6 +7018,7 @@ static void init_julia_llvm_env(Module *m)
70187018
builtin_func_map[jl_f__apply_iterate] = jlcall_func_to_llvm("jl_f__apply_iterate", &jl_f__apply_iterate, m);
70197019
builtin_func_map[jl_f__apply_pure] = jlcall_func_to_llvm("jl_f__apply_pure", &jl_f__apply_pure, m);
70207020
builtin_func_map[jl_f__apply_latest] = jlcall_func_to_llvm("jl_f__apply_latest", &jl_f__apply_latest, m);
7021+
builtin_func_map[jl_f__apply_in_world] = jlcall_func_to_llvm("jl_f__apply_in_world", &jl_f__apply_in_world, m);
70217022
builtin_func_map[jl_f_throw] = jlcall_func_to_llvm("jl_f_throw", &jl_f_throw, m);
70227023
builtin_func_map[jl_f_tuple] = jlcall_func_to_llvm("jl_f_tuple", &jl_f_tuple, m);
70237024
builtin_func_map[jl_f_svec] = jlcall_func_to_llvm("jl_f_svec", &jl_f_svec, m);

src/julia.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,7 @@ JL_DLLEXPORT int jl_get_size(jl_value_t *val, size_t *pnt);
13121312
#define jl_unbox_long(x) jl_unbox_int64(x)
13131313
#define jl_unbox_ulong(x) jl_unbox_uint64(x)
13141314
#define jl_is_long(x) jl_is_int64(x)
1315+
#define jl_is_ulong(x) jl_is_uint64(x)
13151316
#define jl_long_type jl_int64_type
13161317
#define jl_ulong_type jl_uint64_type
13171318
#else
@@ -1320,6 +1321,7 @@ JL_DLLEXPORT int jl_get_size(jl_value_t *val, size_t *pnt);
13201321
#define jl_unbox_long(x) jl_unbox_int32(x)
13211322
#define jl_unbox_ulong(x) jl_unbox_uint32(x)
13221323
#define jl_is_long(x) jl_is_int32(x)
1324+
#define jl_is_ulong(x) jl_is_uint32(x)
13231325
#define jl_long_type jl_int32_type
13241326
#define jl_ulong_type jl_uint32_type
13251327
#endif

src/staticdata.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ void *native_functions;
117117
// This is a manually constructed dual of the fvars array, which would be produced by codegen for Julia code, for C.
118118
static const jl_fptr_args_t id_to_fptrs[] = {
119119
&jl_f_throw, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa,
120-
&jl_f_typeassert, &jl_f__apply, &jl_f__apply_iterate, &jl_f__apply_pure, &jl_f__apply_latest, &jl_f_isdefined,
120+
&jl_f_typeassert, &jl_f__apply, &jl_f__apply_iterate, &jl_f__apply_pure,
121+
&jl_f__apply_latest, &jl_f__apply_in_world, &jl_f_isdefined,
121122
&jl_f_tuple, &jl_f_svec, &jl_f_intrinsic_call, &jl_f_invoke_kwsorter,
122123
&jl_f_getfield, &jl_f_setfield, &jl_f_fieldtype, &jl_f_nfields,
123124
&jl_f_arrayref, &jl_f_const_arrayref, &jl_f_arrayset, &jl_f_arraysize, &jl_f_apply_type,

test/worlds.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,11 @@ end
199199
notify(c26506_1)
200200
wait(c26506_2)
201201
@test result26506[1] == 3
202+
203+
# _apply_in_world builtin
204+
f_aiw(x) = "world one; x=$x"
205+
wc_aiw1 = get_world_counter()
206+
f_aiw(x) = "world two; x=$x"
207+
wc_aiw2 = get_world_counter()
208+
@test Core._apply_in_world(wc_aiw1, f_aiw, (2,)) == "world one; x=2"
209+
@test Core._apply_in_world(wc_aiw2, f_aiw, (2,)) == "world two; x=2"

0 commit comments

Comments
 (0)