From c47aaaaf94780d02e42e49e790e4fd96af4ef0f8 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 9 Nov 2017 12:06:52 -0500 Subject: [PATCH] reorganize and clean up interpreter code removes some cruft and makes the code better match the structure of valid IR --- base/inference.jl | 5 +- src/ast.c | 9 +- src/datatype.c | 2 - src/init.c | 2 - src/interpreter.c | 686 +++++++++++++++++++++++----------------------- src/julia.h | 1 + src/method.c | 2 - src/staticdata.c | 2 - src/toplevel.c | 20 +- 9 files changed, 366 insertions(+), 363 deletions(-) diff --git a/base/inference.jl b/base/inference.jl index b70485c24339f..50e1218edaed3 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -2590,8 +2590,6 @@ function abstract_eval(@nospecialize(e), vtypes::VarTable, sv::InferenceState) t = (length(e.args) == 1) ? Any : Void elseif e.head === :copyast t = abstract_eval(e.args[1], vtypes, sv) - elseif e.head === :inert - return abstract_eval_constant(e.args[1]) elseif e.head === :invoke error("type inference data-flow error: tried to double infer a function") elseif e.head === :boundscheck @@ -2776,8 +2774,7 @@ issubstate(a::VarState, b::VarState) = (a.typ ⊑ b.typ && a.undef <= b.undef) # Meta expression head, these generally can't be deleted even when they are # in a dead branch but can be ignored when analyzing uses/liveness. is_meta_expr_head(head::Symbol) = - (head === :inbounds || head === :boundscheck || head === :meta || - head === :line || head === :simdloop) + (head === :inbounds || head === :boundscheck || head === :meta || head === :simdloop) is_meta_expr(ex::Expr) = is_meta_expr_head(ex.head) function tmerge(@nospecialize(typea), @nospecialize(typeb)) diff --git a/src/ast.c b/src/ast.c index 9a288826d856e..d54e5581fab89 100644 --- a/src/ast.c +++ b/src/ast.c @@ -785,16 +785,9 @@ jl_value_t *jl_parse_eval_all(const char *fname, } jl_get_ptls_states()->world_age = jl_world_counter; form = scm_to_julia(fl_ctx, expression, inmodule); - jl_sym_t *head = NULL; - if (jl_is_expr(form)) - head = ((jl_expr_t*)form)->head; JL_SIGATOMIC_END(); jl_get_ptls_states()->world_age = jl_world_counter; - if (head == jl_incomplete_sym) - jl_errorf("syntax: %s", jl_string_data(jl_exprarg(form, 0))); - else if (head == error_sym) - jl_interpret_toplevel_expr_in(inmodule, form, NULL, NULL); - else if (jl_is_linenode(form)) + if (jl_is_linenode(form)) jl_lineno = jl_linenode_line(form); else result = jl_toplevel_eval_flex(inmodule, form, 1, 1); diff --git a/src/datatype.c b/src/datatype.c index 3f1f27603651a..33181b90ad873 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -393,8 +393,6 @@ void jl_compute_field_offsets(jl_datatype_t *st) jl_errorf("type %s has field offset %d that exceeds the page size", jl_symbol_name(st->name->name), descsz); } -extern int jl_boot_file_loaded; - JL_DLLEXPORT jl_datatype_t *jl_new_datatype( jl_sym_t *name, jl_module_t *module, diff --git a/src/init.c b/src/init.c index ddbd9e45678a9..2e50a228f2a16 100644 --- a/src/init.c +++ b/src/init.c @@ -55,7 +55,6 @@ JL_DLLEXPORT const char* __asan_default_options() { } #endif -int jl_boot_file_loaded = 0; size_t jl_page_size; void jl_init_stack_limits(int ismaster) @@ -696,7 +695,6 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_load(jl_core_module, "boot.jl"); jl_get_builtin_hooks(); - jl_boot_file_loaded = 1; jl_init_box_caches(); } diff --git a/src/interpreter.c b/src/interpreter.c index 5582c064036c8..968a715e58341 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -27,95 +27,13 @@ typedef struct { #include "interpreter-stacktrace.c" -static jl_value_t *eval(jl_value_t *e, interpreter_state *s); +static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s); static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s, int start, int toplevel); -jl_value_t *jl_eval_module_expr(jl_module_t *m, jl_expr_t *ex); int jl_is_toplevel_only_expr(jl_value_t *e); -// deprecated: do not use this method in new code -// it uses special scoping / evaluation / error rules -// which should instead be handled in lowering -struct interpret_toplevel_expr_in_args { - jl_module_t *m; - jl_value_t *e; - jl_code_info_t *src; - jl_svec_t *sparam_vals; -}; - -SECT_INTERP CALLBACK_ABI void *jl_interpret_toplevel_expr_in_callback(interpreter_state *s, void *vargs) -{ - struct interpret_toplevel_expr_in_args *args = - (struct interpret_toplevel_expr_in_args*)vargs; - jl_ptls_t ptls = jl_get_ptls_states(); - jl_value_t *v=NULL; - jl_module_t *last_m = ptls->current_module; - jl_module_t *task_last_m = ptls->current_task->current_module; - s->src = args->src; - s->module = args->m; - s->sparam_vals = args->sparam_vals; - s->preevaluation = (s->sparam_vals != NULL); - s->continue_at = 0; - s->mi = NULL; - - JL_TRY { - ptls->current_task->current_module = ptls->current_module = args->m; - v = eval(args->e, s); - } - JL_CATCH { - ptls->current_module = last_m; - ptls->current_task->current_module = task_last_m; - jl_rethrow(); - } - ptls->current_module = last_m; - ptls->current_task->current_module = task_last_m; - assert(v); - return (void*)v; -} - -SECT_INTERP jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e, jl_code_info_t *src, jl_svec_t *sparam_vals) -{ - struct interpret_toplevel_expr_in_args args = { - m, e, src, sparam_vals - }; - return (jl_value_t *)enter_interpreter_frame(jl_interpret_toplevel_expr_in_callback, (void*)&args); -} - -SECT_INTERP static jl_value_t *do_call(jl_value_t **args, size_t nargs, interpreter_state *s) -{ - jl_value_t **argv; - JL_GC_PUSHARGS(argv, nargs); - size_t i; - for(i=0; i < nargs; i++) - argv[i] = eval(args[i], s); - jl_value_t *result = jl_apply_generic(argv, nargs); - JL_GC_POP(); - return result; -} - -SECT_INTERP static jl_value_t *do_invoke(jl_value_t **args, size_t nargs, interpreter_state *s) -{ - jl_value_t **argv; - JL_GC_PUSHARGS(argv, nargs - 1); - size_t i; - for (i = 1; i < nargs; i++) - argv[i - 1] = eval(args[i], s); - jl_method_instance_t *meth = (jl_method_instance_t*)args[0]; - assert(jl_is_method_instance(meth)); - jl_value_t *result = jl_call_method_internal(meth, argv, nargs - 1); - JL_GC_POP(); - return result; -} +// type definition forms -SECT_INTERP jl_value_t *jl_eval_global_var(jl_module_t *m, jl_sym_t *e) -{ - jl_value_t *v = jl_get_global(m, e); - if (v == NULL) - jl_undefined_var_error(e); - return v; -} - -extern int jl_boot_file_loaded; extern int inside_typedef; // this is a heuristic for allowing "redefining" a type to something identical @@ -203,6 +121,232 @@ SECT_INTERP void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super) jl_gc_wb(tt, tt->super); } +static void eval_abstracttype(jl_expr_t *ex, interpreter_state *s) +{ + jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + if (inside_typedef) + jl_error("cannot eval a new abstract type definition while defining another type"); + jl_value_t *name = args[0]; + jl_value_t *para = eval_value(args[1], s); + jl_value_t *super = NULL; + jl_value_t *temp = NULL; + jl_datatype_t *dt = NULL; + jl_value_t *w = NULL; + jl_module_t *modu = s->module; + JL_GC_PUSH4(¶, &super, &temp, &w); + assert(jl_is_svec(para)); + if (jl_is_globalref(name)) { + modu = jl_globalref_mod(name); + name = (jl_value_t*)jl_globalref_name(name); + } + assert(jl_is_symbol(name)); + dt = jl_new_abstracttype(name, modu, NULL, (jl_svec_t*)para); + w = dt->name->wrapper; + jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); + temp = b->value; + check_can_assign_type(b, w); + b->value = w; + jl_gc_wb_binding(b, w); + JL_TRY { + inside_typedef = 1; + super = eval_value(args[2], s); + jl_set_datatype_super(dt, super); + jl_reinstantiate_inner_types(dt); + } + JL_CATCH { + jl_reset_instantiate_inner_types(dt); + b->value = temp; + jl_rethrow(); + } + b->value = temp; + if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)jl_unwrap_unionall(temp))) { + jl_checked_assignment(b, w); + } + JL_GC_POP(); +} + +static void eval_primitivetype(jl_expr_t *ex, interpreter_state *s) +{ + jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + if (inside_typedef) + jl_error("cannot eval a new primitive type definition while defining another type"); + jl_value_t *name = args[0]; + jl_value_t *super = NULL, *para = NULL, *vnb = NULL, *temp = NULL; + jl_datatype_t *dt = NULL; + jl_value_t *w = NULL; + jl_module_t *modu = s->module; + JL_GC_PUSH4(¶, &super, &temp, &w); + if (jl_is_globalref(name)) { + modu = jl_globalref_mod(name); + name = (jl_value_t*)jl_globalref_name(name); + } + assert(jl_is_symbol(name)); + para = eval_value(args[1], s); + assert(jl_is_svec(para)); + vnb = eval_value(args[2], s); + if (!jl_is_long(vnb)) + jl_errorf("invalid declaration of primitive type %s", + jl_symbol_name((jl_sym_t*)name)); + ssize_t nb = jl_unbox_long(vnb); + if (nb < 1 || nb >= (1 << 23) || (nb & 7) != 0) + jl_errorf("invalid number of bits in primitive type %s", + jl_symbol_name((jl_sym_t*)name)); + dt = jl_new_primitivetype(name, modu, NULL, (jl_svec_t*)para, nb); + w = dt->name->wrapper; + jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); + temp = b->value; + check_can_assign_type(b, w); + b->value = w; + jl_gc_wb_binding(b, w); + JL_TRY { + inside_typedef = 1; + super = eval_value(args[3], s); + jl_set_datatype_super(dt, super); + jl_reinstantiate_inner_types(dt); + } + JL_CATCH { + jl_reset_instantiate_inner_types(dt); + b->value = temp; + jl_rethrow(); + } + b->value = temp; + if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)jl_unwrap_unionall(temp))) { + jl_checked_assignment(b, w); + } + JL_GC_POP(); +} + +static void eval_structtype(jl_expr_t *ex, interpreter_state *s) +{ + jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + if (inside_typedef) + jl_error("cannot eval a new struct type definition while defining another type"); + jl_value_t *name = args[0]; + jl_value_t *para = eval_value(args[1], s); + jl_value_t *temp = NULL; + jl_value_t *super = NULL; + jl_datatype_t *dt = NULL; + jl_value_t *w = NULL; + jl_module_t *modu = s->module; + JL_GC_PUSH4(¶, &super, &temp, &w); + if (jl_is_globalref(name)) { + modu = jl_globalref_mod(name); + name = (jl_value_t*)jl_globalref_name(name); + } + assert(jl_is_symbol(name)); + assert(jl_is_svec(para)); + temp = eval_value(args[2], s); // field names + dt = jl_new_datatype((jl_sym_t*)name, modu, NULL, (jl_svec_t*)para, + (jl_svec_t*)temp, NULL, + 0, args[5]==jl_true ? 1 : 0, jl_unbox_long(args[6])); + w = dt->name->wrapper; + + jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); + temp = b->value; // save old value + // temporarily assign so binding is available for field types + check_can_assign_type(b, w); + b->value = w; + jl_gc_wb_binding(b, w); + + JL_TRY { + inside_typedef = 1; + // operations that can fail + super = eval_value(args[3], s); + jl_set_datatype_super(dt, super); + dt->types = (jl_svec_t*)eval_value(args[4], s); + jl_gc_wb(dt, dt->types); + for (size_t i = 0; i < jl_svec_len(dt->types); i++) { + jl_value_t *elt = jl_svecref(dt->types, i); + if ((!jl_is_type(elt) && !jl_is_typevar(elt)) || jl_is_vararg_type(elt)) { + jl_type_error_rt(jl_symbol_name(dt->name->name), + "type definition", + (jl_value_t*)jl_type_type, elt); + } + } + jl_reinstantiate_inner_types(dt); + } + JL_CATCH { + jl_reset_instantiate_inner_types(dt); + b->value = temp; + jl_rethrow(); + } + jl_compute_field_offsets(dt); + + b->value = temp; + if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)jl_unwrap_unionall(temp))) { + jl_checked_assignment(b, w); + } + + JL_GC_POP(); +} + +// method definition form + +static jl_value_t *eval_methoddef(jl_expr_t *ex, interpreter_state *s) +{ + jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); + jl_sym_t *fname = (jl_sym_t*)args[0]; + jl_module_t *modu = s->module; + if (jl_is_globalref(fname)) { + modu = jl_globalref_mod(fname); + fname = jl_globalref_name(fname); + } + assert(jl_expr_nargs(ex) != 1 || jl_is_symbol(fname)); + + if (jl_is_symbol(fname)) { + jl_value_t *bp_owner = (jl_value_t*)modu; + jl_binding_t *b = jl_get_binding_for_method_def(modu, fname); + jl_value_t **bp = &b->value; + jl_value_t *gf = jl_generic_function_def(b->name, b->owner, bp, bp_owner, b); + if (jl_expr_nargs(ex) == 1) + return gf; + } + + jl_value_t *atypes = NULL, *meth = NULL; + JL_GC_PUSH2(&atypes, &meth); + atypes = eval_value(args[1], s); + meth = eval_value(args[2], s); + jl_method_def((jl_svec_t*)atypes, (jl_code_info_t*)meth, s->module); + JL_GC_POP(); + return jl_nothing; +} + +// expression evaluator + +SECT_INTERP static jl_value_t *do_call(jl_value_t **args, size_t nargs, interpreter_state *s) +{ + jl_value_t **argv; + JL_GC_PUSHARGS(argv, nargs); + size_t i; + for(i=0; i < nargs; i++) + argv[i] = eval_value(args[i], s); + jl_value_t *result = jl_apply_generic(argv, nargs); + JL_GC_POP(); + return result; +} + +SECT_INTERP static jl_value_t *do_invoke(jl_value_t **args, size_t nargs, interpreter_state *s) +{ + jl_value_t **argv; + JL_GC_PUSHARGS(argv, nargs - 1); + size_t i; + for (i = 1; i < nargs; i++) + argv[i - 1] = eval_value(args[i], s); + jl_method_instance_t *meth = (jl_method_instance_t*)args[0]; + assert(jl_is_method_instance(meth)); + jl_value_t *result = jl_call_method_internal(meth, argv, nargs - 1); + JL_GC_POP(); + return result; +} + +SECT_INTERP jl_value_t *jl_eval_global_var(jl_module_t *m, jl_sym_t *e) +{ + jl_value_t *v = jl_get_global(m, e); + if (v == NULL) + jl_undefined_var_error(e); + return v; +} + SECT_INTERP static int jl_source_nslots(jl_code_info_t *src) { return jl_array_len(src->slotflags); @@ -213,9 +357,8 @@ SECT_INTERP static int jl_source_nssavalues(jl_code_info_t *src) return jl_is_long(src->ssavaluetypes) ? jl_unbox_long(src->ssavaluetypes) : jl_array_len(src->ssavaluetypes); } -SECT_INTERP static jl_value_t *eval(jl_value_t *e, interpreter_state *s) +SECT_INTERP static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s) { - jl_ptls_t ptls = jl_get_ptls_states(); jl_code_info_t *src = s->src; if (jl_is_ssavalue(e)) { ssize_t id = ((jl_ssavalue_t*)e)->id; @@ -233,21 +376,28 @@ SECT_INTERP static jl_value_t *eval(jl_value_t *e, interpreter_state *s) jl_undefined_var_error((jl_sym_t*)jl_array_ptr_ref(src->slotnames, n - 1)); return v; } + if (jl_is_quotenode(e)) { + return jl_quotenode_value(e); + } if (jl_is_globalref(e)) { return jl_eval_global_var(jl_globalref_mod(e), jl_globalref_name(e)); } - if (jl_is_quotenode(e)) - return jl_fieldref(e,0); - jl_module_t *modu = s->module; if (jl_is_symbol(e)) { // bare symbols appear in toplevel exprs not wrapped in `thunk` - return jl_eval_global_var(modu, (jl_sym_t*)e); + return jl_eval_global_var(s->module, (jl_sym_t*)e); } if (!jl_is_expr(e)) return e; jl_expr_t *ex = (jl_expr_t*)e; jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); size_t nargs = jl_array_len(ex->args); - if (ex->head == isdefined_sym) { + jl_sym_t *head = ex->head; + if (head == call_sym) { + return do_call(args, nargs, s); + } + else if (head == invoke_sym) { + return do_invoke(args, nargs, s); + } + else if (head == isdefined_sym) { jl_value_t *sym = args[0]; int defined = 0; if (jl_is_slot(sym)) { @@ -260,7 +410,7 @@ SECT_INTERP static jl_value_t *eval(jl_value_t *e, interpreter_state *s) defined = jl_boundp(jl_globalref_mod(sym), jl_globalref_name(sym)); } else if (jl_is_symbol(sym)) { - defined = jl_boundp(modu, (jl_sym_t*)sym); + defined = jl_boundp(s->module, (jl_sym_t*)sym); } else if (jl_is_expr(sym) && ((jl_expr_t*)sym)->head == static_parameter_sym) { ssize_t n = jl_unbox_long(jl_exprarg(sym, 0)); @@ -279,21 +429,15 @@ SECT_INTERP static jl_value_t *eval(jl_value_t *e, interpreter_state *s) } return defined ? jl_true : jl_false; } - else if (ex->head == call_sym) { - return do_call(args, nargs, s); - } - else if (ex->head == invoke_sym) { - return do_invoke(args, nargs, s); - } - else if (ex->head == new_sym) { - jl_value_t *thetype = eval(args[0], s); + else if (head == new_sym) { + jl_value_t *thetype = eval_value(args[0], s); jl_value_t *v=NULL; JL_GC_PUSH2(&thetype, &v); assert(jl_is_structtype(thetype)); v = jl_new_struct_uninit((jl_datatype_t*)thetype); for (size_t i = 1; i < nargs; i++) { jl_value_t *ft = jl_field_type(thetype, i - 1); - jl_value_t *fldv = eval(args[i], s); + jl_value_t *fldv = eval_value(args[i], s); if (!jl_isa(fldv, ft)) jl_type_error("new", ft, fldv); jl_set_nth_field(v, i - 1, fldv); @@ -301,7 +445,7 @@ SECT_INTERP static jl_value_t *eval(jl_value_t *e, interpreter_state *s) JL_GC_POP(); return v; } - else if (ex->head == static_parameter_sym) { + else if (head == static_parameter_sym) { ssize_t n = jl_unbox_long(args[0]); assert(n > 0); if (s->sparam_vals && n <= jl_svec_len(s->sparam_vals)) { @@ -313,227 +457,29 @@ SECT_INTERP static jl_value_t *eval(jl_value_t *e, interpreter_state *s) // static parameter val unknown needs to be an error for ccall jl_error("could not determine static parameter value"); } - else if (ex->head == inert_sym) { - return args[0]; - } - else if (ex->head == copyast_sym) { - return jl_copy_ast(eval(args[0], s)); - } - else if (ex->head == exc_sym) { - return ptls->exception_in_transit; + else if (head == copyast_sym) { + return jl_copy_ast(eval_value(args[0], s)); } - else if (ex->head == method_sym) { - jl_sym_t *fname = (jl_sym_t*)args[0]; - if (jl_is_globalref(fname)) { - modu = jl_globalref_mod(fname); - fname = jl_globalref_name(fname); - } - assert(jl_expr_nargs(ex) != 1 || jl_is_symbol(fname)); - - if (jl_is_symbol(fname)) { - jl_value_t *bp_owner = (jl_value_t*)modu; - jl_binding_t *b = jl_get_binding_for_method_def(modu, fname); - jl_value_t **bp = &b->value; - jl_value_t *gf = jl_generic_function_def(b->name, b->owner, bp, bp_owner, b); - if (jl_expr_nargs(ex) == 1) - return gf; - } - - jl_value_t *atypes = NULL, *meth = NULL; - JL_GC_PUSH2(&atypes, &meth); - atypes = eval(args[1], s); - meth = eval(args[2], s); - jl_method_def((jl_svec_t*)atypes, (jl_code_info_t*)meth, s->module); - JL_GC_POP(); - return jl_nothing; - } - else if (ex->head == const_sym) { - jl_sym_t *sym = (jl_sym_t*)args[0]; - if (jl_is_globalref(sym)) { - modu = jl_globalref_mod(sym); - sym = jl_globalref_name(sym); - } - assert(jl_is_symbol(sym)); - jl_binding_t *b = jl_get_binding_wr(modu, sym, 1); - jl_declare_constant(b); - return (jl_value_t*)jl_nothing; - } - else if (ex->head == abstracttype_sym) { - if (inside_typedef) - jl_error("cannot eval a new abstract type definition while defining another type"); - jl_value_t *name = args[0]; - jl_value_t *para = eval(args[1], s); - jl_value_t *super = NULL; - jl_value_t *temp = NULL; - jl_datatype_t *dt = NULL; - jl_value_t *w = NULL; - JL_GC_PUSH4(¶, &super, &temp, &w); - assert(jl_is_svec(para)); - if (jl_is_globalref(name)) { - modu = jl_globalref_mod(name); - name = (jl_value_t*)jl_globalref_name(name); - } - assert(jl_is_symbol(name)); - dt = jl_new_abstracttype(name, modu, NULL, (jl_svec_t*)para); - w = dt->name->wrapper; - jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); - temp = b->value; - check_can_assign_type(b, w); - b->value = w; - jl_gc_wb_binding(b, w); - JL_TRY { - inside_typedef = 1; - super = eval(args[2], s); - jl_set_datatype_super(dt, super); - jl_reinstantiate_inner_types(dt); - } - JL_CATCH { - jl_reset_instantiate_inner_types(dt); - b->value = temp; - jl_rethrow(); - } - b->value = temp; - if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)jl_unwrap_unionall(temp))) { - jl_checked_assignment(b, w); - } - JL_GC_POP(); - return (jl_value_t*)jl_nothing; - } - else if (ex->head == primtype_sym) { - if (inside_typedef) - jl_error("cannot eval a new primitive type definition while defining another type"); - jl_value_t *name = args[0]; - jl_value_t *super = NULL, *para = NULL, *vnb = NULL, *temp = NULL; - jl_datatype_t *dt = NULL; - jl_value_t *w = NULL; - JL_GC_PUSH4(¶, &super, &temp, &w); - if (jl_is_globalref(name)) { - modu = jl_globalref_mod(name); - name = (jl_value_t*)jl_globalref_name(name); - } - assert(jl_is_symbol(name)); - para = eval(args[1], s); - assert(jl_is_svec(para)); - vnb = eval(args[2], s); - if (!jl_is_long(vnb)) - jl_errorf("invalid declaration of primitive type %s", - jl_symbol_name((jl_sym_t*)name)); - ssize_t nb = jl_unbox_long(vnb); - if (nb < 1 || nb >= (1 << 23) || (nb & 7) != 0) - jl_errorf("invalid number of bits in primitive type %s", - jl_symbol_name((jl_sym_t*)name)); - dt = jl_new_primitivetype(name, modu, NULL, (jl_svec_t*)para, nb); - w = dt->name->wrapper; - jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); - temp = b->value; - check_can_assign_type(b, w); - b->value = w; - jl_gc_wb_binding(b, w); - JL_TRY { - inside_typedef = 1; - super = eval(args[3], s); - jl_set_datatype_super(dt, super); - jl_reinstantiate_inner_types(dt); - } - JL_CATCH { - jl_reset_instantiate_inner_types(dt); - b->value = temp; - jl_rethrow(); - } - b->value = temp; - if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)jl_unwrap_unionall(temp))) { - jl_checked_assignment(b, w); - } - JL_GC_POP(); - return (jl_value_t*)jl_nothing; - } - else if (ex->head == structtype_sym) { - if (inside_typedef) - jl_error("cannot eval a new struct type definition while defining another type"); - jl_value_t *name = args[0]; - jl_value_t *para = eval(args[1], s); - jl_value_t *temp = NULL; - jl_value_t *super = NULL; - jl_datatype_t *dt = NULL; - jl_value_t *w = NULL; - JL_GC_PUSH4(¶, &super, &temp, &w); - if (jl_is_globalref(name)) { - modu = jl_globalref_mod(name); - name = (jl_value_t*)jl_globalref_name(name); - } - assert(jl_is_symbol(name)); - assert(jl_is_svec(para)); - temp = eval(args[2], s); // field names - dt = jl_new_datatype((jl_sym_t*)name, modu, NULL, (jl_svec_t*)para, - (jl_svec_t*)temp, NULL, - 0, args[5]==jl_true ? 1 : 0, jl_unbox_long(args[6])); - w = dt->name->wrapper; - - jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); - temp = b->value; // save old value - // temporarily assign so binding is available for field types - check_can_assign_type(b, w); - b->value = w; - jl_gc_wb_binding(b,w); - - JL_TRY { - inside_typedef = 1; - // operations that can fail - super = eval(args[3], s); - jl_set_datatype_super(dt, super); - dt->types = (jl_svec_t*)eval(args[4], s); - jl_gc_wb(dt, dt->types); - for (size_t i = 0; i < jl_svec_len(dt->types); i++) { - jl_value_t *elt = jl_svecref(dt->types, i); - if ((!jl_is_type(elt) && !jl_is_typevar(elt)) || jl_is_vararg_type(elt)) { - jl_type_error_rt(jl_symbol_name(dt->name->name), - "type definition", - (jl_value_t*)jl_type_type, elt); - } - } - jl_reinstantiate_inner_types(dt); - } - JL_CATCH { - jl_reset_instantiate_inner_types(dt); - b->value = temp; - jl_rethrow(); - } - jl_compute_field_offsets(dt); - - b->value = temp; - if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)jl_unwrap_unionall(temp))) { - jl_checked_assignment(b, w); - } - - JL_GC_POP(); - return (jl_value_t*)jl_nothing; + else if (head == exc_sym) { + return jl_get_ptls_states()->exception_in_transit; } - else if (ex->head == module_sym) { - return jl_eval_module_expr(s->module, ex); - } - else if (ex->head == thunk_sym) { - return jl_toplevel_eval(s->module, (jl_value_t*)ex); - } - else if (ex->head == error_sym || ex->head == jl_incomplete_sym) { - if (nargs == 0) - jl_error("malformed \"error\" expression"); - if (jl_is_string(args[0])) - jl_errorf("syntax: %s", jl_string_data(args[0])); - jl_throw(args[0]); - } - else if (ex->head == boundscheck_sym) { + else if (head == boundscheck_sym) { return jl_true; } - else if (ex->head == boundscheck_sym || ex->head == inbounds_sym || ex->head == fastmath_sym || - ex->head == simdloop_sym || ex->head == meta_sym) { + else if (head == boundscheck_sym || head == inbounds_sym || head == fastmath_sym || + head == simdloop_sym || head == meta_sym) { return jl_nothing; - } else if (ex->head == gc_preserve_begin_sym || ex->head == gc_preserve_end_sym) { + } + else if (head == gc_preserve_begin_sym || head == gc_preserve_end_sym) { // The interpreter generally keeps values that were assigned in this scope // rooted. If the interpreter learns to be more agressive here, we may // want to explicitly root these values. return jl_nothing; } - jl_errorf("unsupported or misplaced expression %s", jl_symbol_name(ex->head)); + else if (head == method_sym && nargs == 1) { + return eval_methoddef(ex, s); + } + jl_errorf("unsupported or misplaced expression %s", jl_symbol_name(head)); abort(); } @@ -556,15 +502,11 @@ SECT_INTERP static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s else if (jl_is_expr(stmt)) { jl_sym_t *head = ((jl_expr_t*)stmt)->head; if (head == return_sym) { - jl_value_t *ex = jl_exprarg(stmt, 0); - if (toplevel && jl_is_toplevel_only_expr(ex)) - return jl_toplevel_eval(s->module, ex); - else - return eval(ex, s); + return eval_value(jl_exprarg(stmt, 0), s); } else if (head == assign_sym) { jl_value_t *sym = jl_exprarg(stmt, 0); - jl_value_t *rhs = eval(jl_exprarg(stmt, 1), s); + jl_value_t *rhs = eval_value(jl_exprarg(stmt, 1), s); if (jl_is_ssavalue(sym)) { ssize_t genid = ((jl_ssavalue_t*)sym)->id; if (genid >= jl_source_nssavalues(s->src) || genid < 0) @@ -590,7 +532,7 @@ SECT_INTERP static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s } } else if (head == goto_ifnot_sym) { - jl_value_t *cond = eval(jl_exprarg(stmt, 0), s); + jl_value_t *cond = eval_value(jl_exprarg(stmt, 0), s); if (cond == jl_false) { s->ip = jl_unbox_long(jl_exprarg(stmt, 1)) - 1; continue; @@ -599,11 +541,6 @@ SECT_INTERP static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s jl_type_error_rt("toplevel", "if", (jl_value_t*)jl_bool_type, cond); } } - else if (head == line_sym) { - if (toplevel) - jl_lineno = jl_unbox_long(jl_exprarg(stmt, 0)); - // TODO: interpreted function line numbers - } else if (head == enter_sym) { jl_enter_handler(&__eh); if (!jl_setjmp(__eh.eh_ctx,1)) { @@ -636,18 +573,41 @@ SECT_INTERP static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s s->continue_at = s->ip + 1; jl_longjmp(eh->eh_ctx, 1); } - else if (toplevel && jl_is_toplevel_only_expr(stmt)) { - jl_toplevel_eval(s->module, stmt); + else if (head == const_sym) { + jl_sym_t *sym = (jl_sym_t*)jl_exprarg(stmt, 0); + jl_module_t *modu = s->module; + if (jl_is_globalref(sym)) { + modu = jl_globalref_mod(sym); + sym = jl_globalref_name(sym); + } + assert(jl_is_symbol(sym)); + jl_binding_t *b = jl_get_binding_wr(modu, sym, 1); + jl_declare_constant(b); + } + else if (toplevel) { + if (head == method_sym) { + eval_methoddef((jl_expr_t*)stmt, s); + } + else if (head == abstracttype_sym) { + eval_abstracttype((jl_expr_t*)stmt, s); + } + else if (head == primtype_sym) { + eval_primitivetype((jl_expr_t*)stmt, s); + } + else if (head == structtype_sym) { + eval_structtype((jl_expr_t*)stmt, s); + } + else if (jl_is_toplevel_only_expr(stmt)) { + jl_toplevel_eval(s->module, stmt); + } + else { + eval_value(stmt, s); + } } else { - eval(stmt, s); + eval_value(stmt, s); } } - else if (jl_is_linenode(stmt)) { - if (toplevel) - jl_lineno = jl_linenode_line(stmt); - // TODO: interpreted function line numbers - } else if (jl_is_newvarnode(stmt)) { jl_value_t *var = jl_fieldref(stmt, 0); assert(jl_is_slot(var)); @@ -655,15 +615,19 @@ SECT_INTERP static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s assert(n <= jl_source_nslots(s->src) && n > 0); s->locals[n - 1] = NULL; } + else if (toplevel && jl_is_linenode(stmt)) { + jl_lineno = jl_linenode_line(stmt); + } else { - eval(stmt, s); + eval_value(stmt, s); } s->ip++; } - assert(0); - return NULL; + abort(); } +// preparing method IR for interpreter + jl_code_info_t *jl_code_for_interpreter(jl_method_instance_t *lam) { jl_code_info_t *src = (jl_code_info_t*)lam->inferred; @@ -687,6 +651,8 @@ jl_code_info_t *jl_code_for_interpreter(jl_method_instance_t *lam) return src; } +// interpreter entry points + struct jl_interpret_call_args { jl_method_instance_t *lam; jl_value_t **args; @@ -763,6 +729,54 @@ SECT_INTERP jl_value_t *jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info return (jl_value_t *)enter_interpreter_frame(jl_interpret_toplevel_thunk_callback, (void*)&args); } +// deprecated: do not use this method in new code +// it uses special scoping / evaluation / error rules +// which should instead be handled in lowering +struct interpret_toplevel_expr_in_args { + jl_module_t *m; + jl_value_t *e; + jl_code_info_t *src; + jl_svec_t *sparam_vals; +}; + +SECT_INTERP CALLBACK_ABI void *jl_interpret_toplevel_expr_in_callback(interpreter_state *s, void *vargs) +{ + struct interpret_toplevel_expr_in_args *args = + (struct interpret_toplevel_expr_in_args*)vargs; + jl_ptls_t ptls = jl_get_ptls_states(); + jl_value_t *v=NULL; + jl_module_t *last_m = ptls->current_module; + jl_module_t *task_last_m = ptls->current_task->current_module; + s->src = args->src; + s->module = args->m; + s->sparam_vals = args->sparam_vals; + s->preevaluation = (s->sparam_vals != NULL); + s->continue_at = 0; + s->mi = NULL; + + JL_TRY { + ptls->current_task->current_module = ptls->current_module = args->m; + v = eval_value(args->e, s); + } + JL_CATCH { + ptls->current_module = last_m; + ptls->current_task->current_module = task_last_m; + jl_rethrow(); + } + ptls->current_module = last_m; + ptls->current_task->current_module = task_last_m; + assert(v); + return (void*)v; +} + +SECT_INTERP jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e, jl_code_info_t *src, jl_svec_t *sparam_vals) +{ + struct interpret_toplevel_expr_in_args args = { + m, e, src, sparam_vals + }; + return (jl_value_t *)enter_interpreter_frame(jl_interpret_toplevel_expr_in_callback, (void*)&args); +} + #ifdef __cplusplus } #endif diff --git a/src/julia.h b/src/julia.h index b2a24198064a4..09dfb6356f23d 100644 --- a/src/julia.h +++ b/src/julia.h @@ -775,6 +775,7 @@ STATIC_INLINE void jl_array_uint8_set(void *a, size_t i, uint8_t x) #define jl_gotonode_label(x) (((intptr_t*)(x))[0]) #define jl_globalref_mod(s) (*(jl_module_t**)(s)) #define jl_globalref_name(s) (((jl_sym_t**)(s))[1]) +#define jl_quotenode_value(x) (((jl_value_t**)x)[0]) #define jl_nparams(t) jl_svec_len(((jl_datatype_t*)(t))->parameters) #define jl_tparam0(t) jl_svecref(((jl_datatype_t*)(t))->parameters, 0) diff --git a/src/method.c b/src/method.c index a984cb1ad9645..ba6cb3c80b046 100644 --- a/src/method.c +++ b/src/method.c @@ -525,8 +525,6 @@ static jl_method_t *jl_new_method( // method definition ---------------------------------------------------------- -extern int jl_boot_file_loaded; - void print_func_loc(JL_STREAM *s, jl_method_t *m); static void jl_check_static_parameter_conflicts(jl_method_t *m, jl_code_info_t *src, jl_svec_t *t) diff --git a/src/staticdata.c b/src/staticdata.c index b8eea09645e87..3d92adfcd660a 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1330,7 +1330,6 @@ JL_DLLEXPORT void jl_save_system_image(const char *fname) JL_SIGATOMIC_END(); } -extern int jl_boot_file_loaded; extern void jl_get_builtins(void); extern void jl_get_builtin_hooks(void); extern void jl_gc_set_permalloc_region(void *start, void *end); @@ -1487,7 +1486,6 @@ static void jl_restore_system_image_from_stream(ios_t *f) jl_get_builtins(); jl_get_builtin_hooks(); - jl_boot_file_loaded = 1; jl_init_box_caches(); jl_update_all_gvars(&s); diff --git a/src/toplevel.c b/src/toplevel.c index 1dda1441ad7bd..9920896c8d50f 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -459,7 +459,9 @@ int jl_is_toplevel_only_expr(jl_value_t *e) ((jl_expr_t*)e)->head == export_sym || ((jl_expr_t*)e)->head == thunk_sym || ((jl_expr_t*)e)->head == global_sym || - ((jl_expr_t*)e)->head == toplevel_sym); + ((jl_expr_t*)e)->head == toplevel_sym || + ((jl_expr_t*)e)->head == error_sym || + ((jl_expr_t*)e)->head == jl_incomplete_sym); } jl_value_t *jl_resolve_globals(jl_value_t *expr, jl_module_t *module, jl_svec_t *sparam_vals); @@ -542,11 +544,7 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *m, jl_value_t *e, int fast, int e } jl_expr_t *ex = (jl_expr_t*)e; - if (ex->head == error_sym || ex->head == jl_incomplete_sym) { - // expression types simple enough not to need expansion - return jl_interpret_toplevel_expr_in(m, e, NULL, NULL); - } - else if (ex->head == module_sym) { + if (ex->head == module_sym) { return jl_eval_module_expr(m, ex); } else if (ex->head == importall_sym) { @@ -640,7 +638,8 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *m, jl_value_t *e, int fast, int e JL_GC_PUSH3(&li, &thk, &ex); if (!expanded && ex->head != body_sym && ex->head != thunk_sym && ex->head != return_sym && - ex->head != method_sym && ex->head != toplevel_sym) { + ex->head != method_sym && ex->head != toplevel_sym && ex->head != error_sym && + ex->head != jl_incomplete_sym) { // not yet expanded ex = (jl_expr_t*)jl_expand(e, m); } @@ -658,6 +657,13 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *m, jl_value_t *e, int fast, int e JL_GC_POP(); return res; } + else if (head == error_sym || head == jl_incomplete_sym) { + if (jl_expr_nargs(ex) == 0) + jl_errorf("malformed \"%s\" expression", jl_symbol_name(head)); + if (jl_is_string(jl_exprarg(ex,0))) + jl_errorf("syntax: %s", jl_string_data(jl_exprarg(ex,0))); + jl_throw(jl_exprarg(ex,0)); + } if (head == thunk_sym) { thk = (jl_code_info_t*)jl_exprarg(ex,0);