Skip to content
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 base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ AssertionError() = AssertionError("")

abstract type WrappedException <: Exception end

# Usage of LoadError is deprecated in the runtime. It's left here for compatibility.
struct LoadError <: WrappedException
file::AbstractString
line::Int
Expand Down
3 changes: 3 additions & 0 deletions base/docs/basedocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1914,6 +1914,9 @@ AssertionError

An error occurred while [`include`](@ref Base.include)ing, [`require`](@ref Base.require)ing, or [`using`](@ref) a file. The error specifics
should be available in the `.error` field.

!!! compat "Julia 1.3"
LoadError is deprecated because it is no longer emitted by the runtime as of Julia 1.3.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Message needs changing if this was to go into 1.2

"""
LoadError

Expand Down
2 changes: 1 addition & 1 deletion base/error.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ rethrow() = ccall(:jl_rethrow, Bottom, ())
rethrow(e) = ccall(:jl_rethrow_other, Bottom, (Any,), e)

struct InterpreterIP
code::Union{CodeInfo,Core.MethodInstance,Nothing}
code::Union{CodeInfo,Core.MethodInstance,Symbol,Nothing}
stmt::Csize_t
end

Expand Down
3 changes: 3 additions & 0 deletions base/stacktraces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ function lookup(ip::Base.InterpreterIP)
elseif ip.code === nothing
# interpreted top-level expression with no CodeInfo
return [StackFrame(top_level_scope_sym, empty_sym, 0, nothing, false, false, 0)]
elseif ip.code isa Symbol
# top-level expression during macro expansion pass
return [StackFrame(top_level_scope_sym, ip.code, ip.stmt, nothing, false, false, 0)]
else
@assert ip.code isa Core.CodeInfo
codeinfo = ip.code
Expand Down
110 changes: 60 additions & 50 deletions src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ 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, interpreter_state *istate,
struct macroctx_stack *macroctx, int onelevel);

value_t fl_current_module_counter(fl_context_t *fl_ctx, value_t *args, uint32_t nargs)
{
Expand Down Expand Up @@ -800,11 +801,21 @@ JL_DLLEXPORT jl_value_t *jl_parse_string(const char *str, size_t len,
return result;
}

// parse and eval a whole file, possibly reading from a string (`content`)
jl_value_t *jl_parse_eval_all(const char *fname,
const char *content, size_t contentlen,
jl_module_t *inmodule)
typedef struct {
const char *fname;
const char *content;
size_t contentlen;
jl_module_t *inmodule;
} jl_parse_eval_all_args;

INTERP_CALLBACK_ABI void *jl_parse_eval_all_callback(interpreter_state *istate, void* vargs)
{
jl_parse_eval_all_args *args = (jl_parse_eval_all_args*)vargs;
const char *fname = args->fname;
const char *content = args->content;
size_t contentlen = args->contentlen;
jl_module_t *inmodule = args->inmodule;

jl_ptls_t ptls = jl_get_ptls_states();
if (ptls->in_pure_callback)
jl_error("cannot use include inside a generated function");
Expand Down Expand Up @@ -839,6 +850,8 @@ jl_value_t *jl_parse_eval_all(const char *fname,
size_t last_age = jl_get_ptls_states()->world_age;
jl_lineno = 0;
jl_filename = fname;
istate->src = jl_symbol(fname);
istate->ip = jl_lineno;
jl_module_t *old_module = ctx->module;
ctx->module = inmodule;
jl_value_t *form = NULL;
Expand All @@ -854,7 +867,7 @@ jl_value_t *jl_parse_eval_all(const char *fname,
JL_TIMING(LOWERING);
if (fl_ctx->T == fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "contains-macrocall")), expression)) {
form = scm_to_julia(fl_ctx, expression, inmodule);
form = jl_expand_macros(form, inmodule, NULL, 0);
form = jl_expand_macros(form, inmodule, istate, NULL, 0);
expression = julia_to_scm(fl_ctx, form);
}
// expand non-final expressions in statement position (value unused)
Expand All @@ -867,10 +880,13 @@ jl_value_t *jl_parse_eval_all(const char *fname,
form = scm_to_julia(fl_ctx, expression, inmodule);
JL_SIGATOMIC_END();
jl_get_ptls_states()->world_age = jl_world_counter;
if (jl_is_linenode(form))
if (jl_is_linenode(form)) {
jl_lineno = jl_linenode_line(form);
else
istate->ip = jl_lineno;
}
else {
result = jl_toplevel_eval_flex(inmodule, form, 1, 1);
}
JL_SIGATOMIC_BEGIN();
ast = cdr_(ast);
}
Expand All @@ -889,16 +905,23 @@ jl_value_t *jl_parse_eval_all(const char *fname,
ctx->module = old_module;
jl_ast_ctx_leave(ctx);
if (err) {
if (jl_loaderror_type == NULL)
jl_rethrow();
else
jl_rethrow_other(jl_new_struct(jl_loaderror_type, form, result,
jl_current_exception()));
jl_rethrow();
}
JL_GC_POP();
return result;
}

// parse and eval a whole file, possibly reading from a string (`content`)
jl_value_t *jl_parse_eval_all(const char *fname,
const char *content, size_t contentlen,
jl_module_t *inmodule)
{
jl_parse_eval_all_args vargs = {
fname, content, contentlen, inmodule
};
return (jl_value_t*)enter_interpreter_frame(jl_parse_eval_all_callback, (void*)&vargs);
}

JL_DLLEXPORT jl_value_t *jl_load_file_string(const char *text, size_t len,
char *filename, jl_module_t *inmodule)
{
Expand Down Expand Up @@ -1004,7 +1027,8 @@ int jl_has_meta(jl_array_t *body, jl_sym_t *sym)
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,
interpreter_state* istate)
{
jl_ptls_t ptls = jl_get_ptls_states();
JL_TIMING(MACRO_INVOCATION);
Expand All @@ -1020,6 +1044,10 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
if (!jl_typeis(lno, jl_linenumbernode_type)) {
margs[1] = jl_new_struct(jl_linenumbernode_type, jl_box_long(0), jl_nothing);
}
if (istate) { // FIXME??
istate->ip = jl_unbox_long(jl_fieldref(margs[1], 0));
istate->src = jl_fieldref(margs[1], 1); // FIXME!
}
margs[2] = (jl_value_t*)inmodule;
for (i = 3; i < nargs; i++)
margs[i] = jl_array_ptr_ref(args, i - 1);
Expand All @@ -1028,38 +1056,20 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
size_t world = jl_world_counter;
ptls->world_age = world;
jl_value_t *result;
JL_TRY {
margs[0] = jl_toplevel_eval(*ctx, margs[0]);
jl_method_instance_t *mfunc = jl_method_lookup(jl_gf_mtable(margs[0]), margs, nargs, 1, world);
if (mfunc == NULL) {
jl_method_error((jl_function_t*)margs[0], margs, nargs, world);
// unreachable
}
*ctx = mfunc->def.method->module;
result = jl_invoke(mfunc, margs, nargs);
}
JL_CATCH {
if (jl_loaderror_type == NULL) {
jl_rethrow();
}
else {
jl_value_t *lno = margs[1];
jl_value_t *file = jl_fieldref(lno, 1);
if (jl_is_symbol(file))
margs[0] = jl_cstr_to_string(jl_symbol_name((jl_sym_t*)file));
else
margs[0] = jl_cstr_to_string("<macrocall>");
margs[1] = jl_fieldref(lno, 0); // extract and allocate line number
jl_rethrow_other(jl_new_struct(jl_loaderror_type, margs[0], margs[1],
jl_current_exception()));
}
margs[0] = jl_toplevel_eval(*ctx, margs[0]);
jl_method_instance_t *mfunc = jl_method_lookup(jl_gf_mtable(margs[0]), margs, nargs, 1, world);
if (mfunc == NULL) {
jl_method_error((jl_function_t*)margs[0], margs, nargs, world);
// unreachable
}
*ctx = mfunc->def.method->module;
result = jl_invoke(mfunc, margs, nargs);
ptls->world_age = last_age;
JL_GC_POP();
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, interpreter_state* istate, struct macroctx_stack *macroctx, int onelevel)
{
if (!expr || !jl_is_expr(expr))
return expr;
Expand All @@ -1079,7 +1089,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, istate, macroctx, onelevel);
JL_GC_POP();
return expr;
}
Expand All @@ -1089,7 +1099,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, istate, &newctx, onelevel);
if (a != a2)
jl_array_ptr_set(e->args, 0, a2);
return expr;
Expand All @@ -1098,7 +1108,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, istate);
jl_value_t *wrap = NULL;
JL_GC_PUSH3(&result, &wrap, &newctx.m);
// copy and wrap the result in `(hygienic-scope ,result ,newctx)
Expand All @@ -1108,7 +1118,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, istate, wrap ? &newctx : macroctx, onelevel);
if (wrap) {
jl_exprargset(wrap, 0, result);
jl_exprargset(wrap, 1, newctx.m);
Expand All @@ -1130,7 +1140,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, istate, macroctx, onelevel);
JL_GC_POP();
return ret;
}
Expand All @@ -1141,7 +1151,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, istate, macroctx, onelevel);
if (a != a2)
jl_array_ptr_set(e->args, i, a2);
}
Expand All @@ -1153,7 +1163,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, NULL, 0);
expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
JL_GC_POP();
return expr;
Expand All @@ -1164,7 +1174,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, NULL, 1);
expr = jl_call_scm_on_ast("jl-expand-macroscope", expr, inmodule);
JL_GC_POP();
return expr;
Expand All @@ -1176,7 +1186,7 @@ JL_DLLEXPORT jl_value_t *jl_expand_with_loc(jl_value_t *expr, jl_module_t *inmod
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, NULL, 0);
expr = jl_call_scm_on_ast_and_loc("jl-expand-to-thunk", expr, inmodule, file, line);
JL_GC_POP();
return expr;
Expand All @@ -1194,7 +1204,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, NULL, 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
1 change: 0 additions & 1 deletion src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,6 @@ void jl_get_builtin_hooks(void)
#endif
jl_argumenterror_type = (jl_datatype_t*)core("ArgumentError");
jl_methoderror_type = (jl_datatype_t*)core("MethodError");
jl_loaderror_type = (jl_datatype_t*)core("LoadError");
jl_initerror_type = (jl_datatype_t*)core("InitError");

jl_weakref_type = (jl_datatype_t*)core("WeakRef");
Expand Down
11 changes: 0 additions & 11 deletions src/interpreter-stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ asm(
ASM_END
);

#define CALLBACK_ABI

#elif defined(_CPU_X86_)

#define MAX_INTERP_STATE_SIZE 36
Expand Down Expand Up @@ -206,7 +204,6 @@ asm(
ASM_END
);

#define CALLBACK_ABI __attribute__((fastcall))
static_assert(sizeof(interpreter_state) <= MAX_INTERP_STATE_SIZE, "Update assembly code above");

#elif defined(_CPU_AARCH64_)
Expand Down Expand Up @@ -253,8 +250,6 @@ asm(
ASM_END
);

#define CALLBACK_ABI

#elif defined(_CPU_ARM_)

#define MAX_INTERP_STATE_SIZE 48
Expand Down Expand Up @@ -296,8 +291,6 @@ asm(
ASM_END
);

#define CALLBACK_ABI

#elif defined(_CPU_PPC64_)
/**
* Implementation notes:
Expand Down Expand Up @@ -367,8 +360,6 @@ asm(
ASM_END
);

#define CALLBACK_ABI

#else
#warning "Interpreter backtraces not implemented for this platform"
#define NO_INTERP_BT
Expand Down Expand Up @@ -406,7 +397,6 @@ JL_DLLEXPORT size_t jl_capture_interp_frame(uintptr_t *data, uintptr_t sp, uintp
return 2;
}

extern void * CALLBACK_ABI enter_interpreter_frame(void * CALLBACK_ABI (*callback)(interpreter_state *, void *), void *arg);
#else
JL_DLLEXPORT int jl_is_interpreter_frame(uintptr_t ip)
{
Expand All @@ -422,7 +412,6 @@ JL_DLLEXPORT size_t jl_capture_interp_frame(uintptr_t *data, uintptr_t sp, uintp
{
return 0;
}
#define CALLBACK_ABI
void *NOINLINE enter_interpreter_frame(void *(*callback)(interpreter_state *, void *), void *arg) {
interpreter_state state = {};
return callback(&state, arg);
Expand Down
Loading