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

add jl_expand_in_world #37902

Merged
merged 3 commits into from
Oct 8, 2020
Merged
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
38 changes: 22 additions & 16 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct macroctx_stack {

static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mod);
static value_t julia_to_scm(fl_context_t *fl_ctx, jl_value_t *v);
static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel);
static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel, size_t world);

static value_t fl_defined_julia_global(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
{
Expand Down Expand Up @@ -947,7 +947,7 @@ int jl_has_meta(jl_array_t *body, jl_sym_t *sym) JL_NOTSAFEPOINT
return 0;
}

static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule, jl_module_t **ctx)
static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule, jl_module_t **ctx, size_t world)
{
jl_ptls_t ptls = jl_get_ptls_states();
JL_TIMING(MACRO_INVOCATION);
Expand All @@ -968,8 +968,7 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
margs[i] = jl_array_ptr_ref(args, i - 1);

size_t last_age = ptls->world_age;
size_t world = jl_world_counter;
ptls->world_age = world;
ptls->world_age = world < jl_world_counter ? world : jl_world_counter;
jl_value_t *result;
JL_TRY {
margs[0] = jl_toplevel_eval(*ctx, margs[0]);
Expand Down Expand Up @@ -1003,7 +1002,7 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
return result;
}

static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel)
static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel, size_t world)
{
if (!expr || !jl_is_expr(expr))
return expr;
Expand All @@ -1023,7 +1022,7 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
jl_array_ptr_set(e2->args, 0, expr);
expr = (jl_value_t*)e2;
}
expr = jl_expand_macros(expr, inmodule, macroctx, onelevel);
expr = jl_expand_macros(expr, inmodule, macroctx, onelevel, world);
JL_GC_POP();
return expr;
}
Expand All @@ -1033,7 +1032,7 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
JL_TYPECHK(hygienic-scope, module, (jl_value_t*)newctx.m);
newctx.parent = macroctx;
jl_value_t *a = jl_exprarg(e, 0);
jl_value_t *a2 = jl_expand_macros(a, inmodule, &newctx, onelevel);
jl_value_t *a2 = jl_expand_macros(a, inmodule, &newctx, onelevel, world);
if (a != a2)
jl_array_ptr_set(e->args, 0, a2);
return expr;
Expand All @@ -1042,7 +1041,7 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
struct macroctx_stack newctx;
newctx.m = macroctx ? macroctx->m : inmodule;
newctx.parent = macroctx;
jl_value_t *result = jl_invoke_julia_macro(e->args, inmodule, &newctx.m);
jl_value_t *result = jl_invoke_julia_macro(e->args, inmodule, &newctx.m, world);
jl_value_t *wrap = NULL;
JL_GC_PUSH3(&result, &wrap, &newctx.m);
// copy and wrap the result in `(hygienic-scope ,result ,newctx)
Expand All @@ -1052,7 +1051,7 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
wrap = (jl_value_t*)jl_exprn(hygienicscope_sym, 2);
result = jl_copy_ast(result);
if (!onelevel)
result = jl_expand_macros(result, inmodule, wrap ? &newctx : macroctx, onelevel);
result = jl_expand_macros(result, inmodule, wrap ? &newctx : macroctx, onelevel, world);
if (wrap) {
jl_exprargset(wrap, 0, result);
jl_exprargset(wrap, 1, newctx.m);
Expand All @@ -1074,7 +1073,7 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
for (j = 2; j < nm; j++) {
jl_exprargset(mc2, j+1, jl_exprarg(mc, j));
}
jl_value_t *ret = jl_expand_macros((jl_value_t*)mc2, inmodule, macroctx, onelevel);
jl_value_t *ret = jl_expand_macros((jl_value_t*)mc2, inmodule, macroctx, onelevel, world);
JL_GC_POP();
return ret;
}
Expand All @@ -1085,7 +1084,7 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
size_t i;
for (i = 0; i < jl_array_len(e->args); i++) {
jl_value_t *a = jl_array_ptr_ref(e->args, i);
jl_value_t *a2 = jl_expand_macros(a, inmodule, macroctx, onelevel);
jl_value_t *a2 = jl_expand_macros(a, inmodule, macroctx, onelevel, world);
if (a != a2)
jl_array_ptr_set(e->args, i, a2);
}
Expand All @@ -1097,7 +1096,7 @@ JL_DLLEXPORT jl_value_t *jl_macroexpand(jl_value_t *expr, jl_module_t *inmodule)
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
expr = jl_expand_macros(expr, inmodule, NULL, 0, jl_world_counter);
expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
JL_GC_POP();
return expr;
Expand All @@ -1108,7 +1107,7 @@ JL_DLLEXPORT jl_value_t *jl_macroexpand1(jl_value_t *expr, jl_module_t *inmodule
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 1);
expr = jl_expand_macros(expr, inmodule, NULL, 1, jl_world_counter);
expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
JL_GC_POP();
return expr;
Expand All @@ -1123,11 +1122,18 @@ JL_DLLEXPORT jl_value_t *jl_expand(jl_value_t *expr, jl_module_t *inmodule)
// Lowering, with starting program location specified
JL_DLLEXPORT jl_value_t *jl_expand_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line)
{
return jl_expand_in_world(expr, inmodule, file, line, ~(size_t)0);
}

// Lowering, with starting program location and worldage specified
JL_DLLEXPORT jl_value_t *jl_expand_in_world(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line, size_t world)
{
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
expr = jl_expand_macros(expr, inmodule, NULL, 0, world);
expr = jl_call_scm_on_ast_and_loc("jl-expand-to-thunk", expr, inmodule, file, line);
JL_GC_POP();
return expr;
Expand All @@ -1140,7 +1146,7 @@ JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0);
jl_ast_context_t *ctx = jl_ast_ctx_enter();
fl_context_t *fl_ctx = &ctx->fl;
JL_AST_PRESERVE_PUSH(ctx, old_roots, inmodule);
Expand All @@ -1161,7 +1167,7 @@ JL_DLLEXPORT jl_value_t *jl_expand_stmt_with_loc(jl_value_t *expr, jl_module_t *
JL_TIMING(LOWERING);
JL_GC_PUSH1(&expr);
expr = jl_copy_ast(expr);
expr = jl_expand_macros(expr, inmodule, NULL, 0);
expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0);
expr = jl_call_scm_on_ast_and_loc("jl-expand-to-thunk-stmt", expr, inmodule, file, line);
JL_GC_POP();
return expr;
Expand Down
2 changes: 2 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,8 @@ JL_DLLEXPORT jl_value_t *jl_expand_with_loc(jl_value_t *expr, jl_module_t *inmod
const char *file, int line);
JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line);
JL_DLLEXPORT jl_value_t *jl_expand_in_world(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line, size_t world);
JL_DLLEXPORT jl_value_t *jl_expand_stmt(jl_value_t *expr, jl_module_t *inmodule);
JL_DLLEXPORT jl_value_t *jl_expand_stmt_with_loc(jl_value_t *expr, jl_module_t *inmodule,
const char *file, int line);
Expand Down
10 changes: 10 additions & 0 deletions test/meta.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,13 @@ end

@test Meta.parseatom("@foo", 1, filename=:bar)[1].args[2].file == :bar
@test Meta.parseall("@foo", filename=:bar).args[1].file == :bar

_lower(m::Module, ex, world::UInt) = ccall(:jl_expand_in_world, Any, (Any, Ref{Module}, Cstring, Cint, Csize_t), ex, m, "none", 0, world)

module TestExpandInWorldModule
macro m() 1 end
wa = Base.get_world_counter()
macro m() 2 end
end

@test _lower(TestExpandInWorldModule, :(@m), TestExpandInWorldModule.wa) == 1