Пример #1
0
JL_DLLEXPORT jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m,
                                                       jl_value_t *e,
                                                       jl_svec_t *local_syms,
                                                       jl_svec_t *local_vals)
{
    jl_value_t *v=NULL;
    jl_module_t *last_m = jl_current_module;
    jl_module_t *task_last_m = jl_current_task->current_module;
    size_t i, nl = jl_svec_len(local_syms);
    jl_value_t **locals = (jl_value_t**)alloca(sizeof(jl_value_t*) * 2 * nl);
    for (i = 0; i < nl; i++) {
        locals[2 * i] = jl_svecref(local_syms, i);
        locals[2 * i + 1] = jl_svec_len(local_vals) > 0 ? jl_svecref(local_vals, i) : NULL;
    }
    JL_TRY {
        jl_current_task->current_module = jl_current_module = m;
        v = eval(e, locals, nl, 0);
    }
    JL_CATCH {
        jl_current_module = last_m;
        jl_current_task->current_module = task_last_m;
        jl_rethrow();
    }
    jl_current_module = last_m;
    jl_current_task->current_module = task_last_m;
    assert(v);
    return v;
}
Пример #2
0
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)
{
    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;
    interpreter_state s;
    s.src = src;
    s.module = m;
    s.locals = NULL;
    s.sparam_vals = sparam_vals;

    JL_TRY {
        ptls->current_task->current_module = ptls->current_module = m;
        v = eval(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 v;
}
Пример #3
0
// given a new lambda_info with static parameter values, make a copy
// of the tree with declared types evaluated and static parameters passed
// on to all enclosed functions.
// this tree can then be further mutated by optimization passes.
DLLEXPORT
jl_value_t *jl_prepare_ast(jl_lambda_info_t *li, jl_tuple_t *sparams)
{
    jl_tuple_t *spenv = NULL;
    jl_value_t *ast = li->ast;
    if (ast == NULL) return NULL;
    JL_GC_PUSH(&spenv, &ast);
    spenv = jl_tuple_tvars_to_symbols(sparams);
    if (!jl_is_expr(ast)) {
        ast = jl_uncompress_ast(li, ast);
        ast = dont_copy_ast(ast, sparams, 1);
    }
    else {
        ast = copy_ast(ast, sparams, 1);
    }
    jl_module_t *last_m = jl_current_module;
    JL_TRY {
        jl_current_module = li->module;
        eval_decl_types(jl_lam_vinfo((jl_expr_t*)ast), spenv);
        eval_decl_types(jl_lam_capt((jl_expr_t*)ast), spenv);
    }
    JL_CATCH {
        jl_current_module = last_m;
        jl_rethrow();
    }
    jl_current_module = last_m;
    JL_GC_POP();
    return ast;
}
Пример #4
0
static void JL_NORETURN jl_throw_in_ctx(jl_value_t *e, void *sigctx)
{
    if (!jl_safe_restore)
        jl_bt_size = rec_backtrace_ctx(jl_bt_data, JL_MAX_BT_SIZE,
                                       jl_to_bt_context(sigctx));
    jl_exception_in_transit = e;
    // TODO throw the error by modifying sigctx for supported platforms
    // This will avoid running the atexit handler on the signal stack
    // if no excepiton handler is registered.
    jl_rethrow();
}
Пример #5
0
static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule, jl_module_t **ctx)
{
    jl_ptls_t ptls = jl_get_ptls_states();
    JL_TIMING(MACRO_INVOCATION);
    size_t nargs = jl_array_len(args) + 1;
    JL_NARGSV("macrocall", 3); // macro name, location, and module
    jl_value_t **margs;
    JL_GC_PUSHARGS(margs, nargs);
    int i;
    margs[0] = jl_array_ptr_ref(args, 0);
    // __source__ argument
    jl_value_t *lno = jl_array_ptr_ref(args, 1);
    margs[1] = lno;
    if (!jl_typeis(lno, jl_linenumbernode_type)) {
        margs[1] = jl_new_struct(jl_linenumbernode_type, jl_box_long(0), jl_nothing);
    }
    margs[2] = (jl_value_t*)inmodule;
    for (i = 3; i < nargs; i++)
        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;
    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 = mfunc->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],
                                           ptls->exception_in_transit));
        }
    }
    ptls->world_age = last_age;
    JL_GC_POP();
    return result;
}
Пример #6
0
// repeatedly call jl_parse_next and eval everything
jl_value_t *jl_parse_eval_all(const char *fname, size_t len)
{
    //jl_printf(JL_STDERR, "***** loading %s\n", fname);
    int last_lineno = jl_lineno;
    const char *last_filename = jl_filename;
    jl_lineno = 0;
    jl_filename = fname;
    jl_value_t *fn=NULL, *ln=NULL, *form=NULL, *result=jl_nothing;
    JL_GC_PUSH4(&fn, &ln, &form, &result);
    JL_TRY {
        // handle syntax error
        while (1) {
            form = jl_parse_next();
            if (form == NULL)
                break;
            if (jl_is_expr(form)) {
                if (((jl_expr_t*)form)->head == jl_incomplete_sym) {
                    jl_errorf("syntax: %s", jl_string_data(jl_exprarg(form,0)));
                }
                if (((jl_expr_t*)form)->head == error_sym) {
                    jl_interpret_toplevel_expr(form);
                }
            }
            result = jl_toplevel_eval_flex(form, 1);
        }
    }
    JL_CATCH {
        jl_stop_parsing();
        fn = jl_pchar_to_string(fname, len);
        ln = jl_box_long(jl_lineno);
        jl_lineno = last_lineno;
        jl_filename = last_filename;
        if (jl_loaderror_type == NULL) {
            jl_rethrow();
        }
        else {
            jl_rethrow_other(jl_new_struct(jl_loaderror_type, fn, ln,
                                           jl_exception_in_transit));
        }
    }
    jl_stop_parsing();
    jl_lineno = last_lineno;
    jl_filename = last_filename;
    JL_GC_POP();
    return result;
}
Пример #7
0
jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e,
                                          jl_value_t **locals, size_t nl)
{
    jl_value_t *v=NULL;
    jl_module_t *last_m = jl_current_module;
    JL_TRY {
        jl_current_module = m;
        v = eval(e, locals, nl);
    }
    JL_CATCH {
        jl_current_module = last_m;
        jl_rethrow();
    }
    jl_current_module = last_m;
    assert(v);
    return v;
}
Пример #8
0
JL_DLLEXPORT void jl_module_run_initializer(jl_module_t *m)
{
    jl_function_t *f = jl_module_get_initializer(m);
    if (f == NULL)
        return;
    JL_TRY {
        jl_apply(f, NULL, 0);
    }
    JL_CATCH {
        if (jl_initerror_type == NULL) {
            jl_rethrow();
        }
        else {
            jl_rethrow_other(jl_new_struct(jl_initerror_type, m->name,
                                           jl_exception_in_transit));
        }
    }
}
Пример #9
0
void jl_module_run_initializer(jl_module_t *m)
{
    jl_ptls_t ptls = jl_get_ptls_states();
    jl_function_t *f = jl_module_get_initializer(m);
    if (f == NULL)
        return;
    JL_TRY {
        jl_apply(&f, 1);
    }
    JL_CATCH {
        if (jl_initerror_type == NULL) {
            jl_rethrow();
        }
        else {
            jl_rethrow_other(jl_new_struct(jl_initerror_type, m->name,
                                           ptls->exception_in_transit));
        }
    }
}
Пример #10
0
void jl_module_run_initializer(jl_module_t *m)
{
    jl_function_t *f = jl_module_get_initializer(m);
    if (f == NULL)
        return;
    size_t last_age = jl_get_ptls_states()->world_age;
    JL_TRY {
        jl_get_ptls_states()->world_age = jl_world_counter;
        jl_apply(&f, 1);
        jl_get_ptls_states()->world_age = last_age;
    }
    JL_CATCH {
        if (jl_initerror_type == NULL) {
            jl_rethrow();
        }
        else {
            jl_rethrow_other(jl_new_struct(jl_initerror_type, m->name,
                                           jl_exception_in_transit));
        }
    }
}
Пример #11
0
jl_value_t *jl_eval_module_expr(jl_expr_t *ex)
{
    assert(ex->head == module_sym);
    jl_module_t *last_module = jl_current_module;
    int std_imports = (jl_exprarg(ex,0)==jl_true);
    jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1);
    if (!jl_is_symbol(name)) {
        jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name);
    }
    jl_module_t *parent_module = jl_current_module;
    jl_binding_t *b = jl_get_binding_wr(parent_module, name);
    jl_declare_constant(b);
    if (b->value != NULL) {
        JL_PRINTF(JL_STDERR, "Warning: replacing module %s\n", name->name);
    }
    jl_module_t *newm = jl_new_module(name);
    newm->parent = parent_module;
    b->value = (jl_value_t*)newm;
    if (parent_module == jl_main_module && name == jl_symbol("Base")) {
        jl_old_base_module = jl_base_module;
        // pick up Base module during bootstrap
        jl_base_module = newm;
    }
    // export all modules from Main
    if (parent_module == jl_main_module)
        jl_module_export(jl_main_module, name);

    // add standard imports unless baremodule
    if (std_imports) {
        if (jl_base_module != NULL)
            jl_module_using(newm, jl_base_module); // using Base
    }

    JL_GC_PUSH(&last_module);
    jl_current_module = newm;

    jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args;
    JL_TRY {
        for(int i=0; i < exprs->length; i++) {
            // process toplevel form
            jl_value_t *form = jl_cellref(exprs, i);
            (void)jl_toplevel_eval_flex(form, 1);
        }
    }
    JL_CATCH {
        jl_current_module = last_module;
        jl_rethrow();
    }
    JL_GC_POP();
    jl_current_module = last_module;

    size_t i;
    void **table = newm->bindings.table;
    for(i=1; i < newm->bindings.size; i+=2) {
        if (table[i] != HT_NOTFOUND) {
            jl_binding_t *b = (jl_binding_t*)table[i];
            // remove non-exported macros
            if (b->name->name[0]=='@' && !b->exportp)
                b->value = NULL;
            // error for unassigned exports
            /*
            if (b->exportp && b->owner==newm && b->value==NULL)
                jl_errorf("identifier %s exported from %s is not initialized",
                          b->name->name, newm->name->name);
            */
        }
    }
    return jl_nothing;
}
Пример #12
0
static jl_value_t *eval(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;
        if (src == NULL || id >= jl_source_nssavalues(src) || id < 0 || s->locals == NULL)
            jl_error("access to invalid SSAValue");
        else
            return s->locals[jl_source_nslots(src) + id];
    }
    if (jl_is_slot(e)) {
        ssize_t n = jl_slot_number(e);
        if (src == NULL || n > jl_source_nslots(src) || n < 1 || s->locals == NULL)
            jl_error("access to invalid slot number");
        jl_value_t *v = s->locals[n - 1];
        if (v == NULL)
            jl_undefined_var_error((jl_sym_t*)jl_array_ptr_ref(src->slotnames, n - 1));
        return v;
    }
    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);
    }
    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_value_t *sym = args[0];
        int defined = 0;
        if (jl_is_slot(sym)) {
            ssize_t n = jl_slot_number(sym);
            if (src == NULL || n > jl_source_nslots(src) || n < 1 || s->locals == NULL)
                jl_error("access to invalid slot number");
            defined = s->locals[n - 1] != NULL;
        }
        else if (jl_is_globalref(sym)) {
            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);
        }
        else if (jl_is_expr(sym) && ((jl_expr_t*)sym)->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)) {
                jl_value_t *sp = jl_svecref(s->sparam_vals, n - 1);
                defined = !jl_is_typevar(sp);
            }
            else {
                // static parameter val unknown needs to be an error for ccall
                jl_error("could not determine static parameter value");
            }
        }
        else {
            assert(0 && "malformed isdefined expression");
        }
        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);
        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);
            if (!jl_isa(fldv, ft))
                jl_type_error("new", ft, fldv);
            jl_set_nth_field(v, i - 1, fldv);
        }
        JL_GC_POP();
        return v;
    }
    else if (ex->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)) {
            jl_value_t *sp = jl_svecref(s->sparam_vals, n - 1);
            if (jl_is_typevar(sp) && !s->preevaluation)
                jl_undefined_var_error(((jl_tvar_t*)sp)->name);
            return sp;
        }
        // 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 (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, args[3]);
        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(&para, &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) {
Пример #13
0
static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
{
    jl_ptls_t ptls = jl_get_ptls_states();
    jl_code_info_t *src = s==NULL ? NULL : s->src;
    if (jl_is_ssavalue(e)) {
        ssize_t id = ((jl_ssavalue_t*)e)->id;
        if (id >= jl_source_nssavalues(src) || id < 0 || s->locals == NULL)
            jl_error("access to invalid SSAValue");
        else
            return s->locals[jl_source_nslots(src) + id];
    }
    if (jl_is_slot(e)) {
        ssize_t n = jl_slot_number(e);
        if (n > jl_source_nslots(src) || n < 1 || s->locals == NULL)
            jl_error("access to invalid slot number");
        jl_value_t *v = s->locals[n-1];
        if (v == NULL)
            jl_undefined_var_error((jl_sym_t*)jl_array_ptr_ref(src->slotnames, n - 1));
        return v;
    }
    if (jl_is_globalref(e)) {
        jl_sym_t *s = jl_globalref_name(e);
        jl_value_t *v = jl_get_global(jl_globalref_mod(e), s);
        if (v == NULL)
            jl_undefined_var_error(s);
        return v;
    }
    if (jl_is_quotenode(e))
        return jl_fieldref(e,0);
    jl_module_t *modu = (s == NULL ? ptls->current_module : s->module);
    if (jl_is_symbol(e)) {  // bare symbols appear in toplevel exprs not wrapped in `thunk`
        jl_value_t *v = jl_get_global(modu, (jl_sym_t*)e);
        if (v == NULL)
            jl_undefined_var_error((jl_sym_t*)e);
        return v;
    }
    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 == 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);
        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_set_nth_field(v, i-1, eval(args[i], s));
        }
        JL_GC_POP();
        return v;
    }
    else if (ex->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)) {
            jl_value_t *sp = jl_svecref(s->sparam_vals, n - 1);
            if (!jl_is_typevar(sp))
                return sp;
        }
        // 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 (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=NULL;
            jl_value_t *bp_owner=NULL;
            jl_binding_t *b=NULL;
            if (bp == NULL) {
                b = jl_get_binding_for_method_def(modu, fname);
                bp = &b->value;
                bp_owner = (jl_value_t*)modu;
            }
            jl_value_t *gf = jl_generic_function_def(fname, 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, args[3]);
        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);
        jl_declare_constant(b);
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == global_sym) {
        // create uninitialized mutable binding for "global x" decl
        // TODO: handle type decls
        size_t i, l = jl_array_len(ex->args);
        for (i = 0; i < l; i++) {
            jl_sym_t *gsym = (jl_sym_t*)args[i];
            jl_module_t *gmodu = modu;
            if (jl_is_globalref(gsym)) {
                gmodu = jl_globalref_mod(gsym);
                gsym = jl_globalref_name(gsym);
            }
            assert(jl_is_symbol(gsym));
            jl_get_binding_wr(gmodu, gsym);
        }
        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_GC_PUSH4(&para, &super, &temp, &dt);
        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, NULL, (jl_svec_t*)para);
        jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name);
        temp = b->value;
        check_can_assign_type(b);
        b->value = (jl_value_t*)dt;
        jl_gc_wb_binding(b, dt);
        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*)temp)) {
            jl_checked_assignment(b, (jl_value_t*)dt);
        }
        JL_GC_POP();
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == bitstype_sym) {
Пример #14
0
jl_value_t *jl_resolve_globals(jl_value_t *expr, jl_module_t *module, jl_svec_t *sparam_vals)
{
    if (jl_is_symbol(expr)) {
        if (module == NULL)
            return expr;
        return jl_module_globalref(module, (jl_sym_t*)expr);
    }
    else if (jl_is_expr(expr)) {
        jl_expr_t *e = (jl_expr_t*)expr;
        if (e->head == global_sym) {
            // execute the side-effects of "global x" decl immediately:
            // creates uninitialized mutable binding in module for each global
            jl_toplevel_eval_flex(module, expr, 0, 1);
            expr = jl_nothing;
        }
        if (jl_is_toplevel_only_expr(expr) || e->head == const_sym || e->head == copyast_sym ||
            e->head == quote_sym || e->head == inert_sym ||
            e->head == meta_sym || e->head == inbounds_sym ||
            e->head == boundscheck_sym || e->head == simdloop_sym) {
            // ignore these
        }
        else {
            if (e->head == call_sym && jl_expr_nargs(e) == 3 &&
                    jl_is_quotenode(jl_exprarg(e, 2)) && module != NULL) {
                // replace getfield(module_expr, :sym) with GlobalRef
                jl_value_t *s = jl_fieldref(jl_exprarg(e, 2), 0);
                jl_value_t *fe = jl_exprarg(e, 0);
                if (jl_is_symbol(s) && jl_is_globalref(fe)) {
                    jl_binding_t *b = jl_get_binding(jl_globalref_mod(fe), jl_globalref_name(fe));
                    jl_value_t *f = NULL;
                    if (b && b->constp) {
                        f = b->value;
                    }
                    if (f == jl_builtin_getfield) {
                        jl_value_t *me = jl_exprarg(e, 1);
                        jl_module_t *me_mod = NULL;
                        jl_sym_t *me_sym = NULL;
                        if (jl_is_globalref(me)) {
                            me_mod = jl_globalref_mod(me);
                            me_sym = jl_globalref_name(me);
                        }
                        else if (jl_is_symbol(me) && jl_binding_resolved_p(module, (jl_sym_t*)me)) {
                            me_mod = module;
                            me_sym = (jl_sym_t*)me;
                        }
                        if (me_mod && me_sym) {
                            jl_binding_t *b = jl_get_binding(me_mod, me_sym);
                            if (b && b->constp) {
                                jl_value_t *m = b->value;
                                if (m && jl_is_module(m)) {
                                    return jl_module_globalref((jl_module_t*)m, (jl_sym_t*)s);
                                }
                            }
                        }
                    }
                }
            }
            size_t i = 0, nargs = jl_array_len(e->args);
            if (e->head == foreigncall_sym) {
                JL_NARGSV(ccall method definition, 5); // (fptr, rt, at, cc, narg)
                jl_value_t *rt = jl_exprarg(e, 1);
                jl_value_t *at = jl_exprarg(e, 2);
                if (!jl_is_type(rt)) {
                    JL_TRY {
                        rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals);
                    }
                    JL_CATCH {
                        if (jl_typeis(jl_exception_in_transit, jl_errorexception_type))
                            jl_error("could not evaluate ccall return type (it might depend on a local variable)");
                        else
                            jl_rethrow();
                    }
                    jl_exprargset(e, 1, rt);
                }
                if (!jl_is_svec(at)) {
                    JL_TRY {
                        at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals);
                    }
                    JL_CATCH {
                        if (jl_typeis(jl_exception_in_transit, jl_errorexception_type))
                            jl_error("could not evaluate ccall argument type (it might depend on a local variable)");
                        else
                            jl_rethrow();
                    }
                    jl_exprargset(e, 2, at);
                }
                if (jl_is_svec(rt))
                    jl_error("ccall: missing return type");
                JL_TYPECHK(ccall method definition, type, rt);
                JL_TYPECHK(ccall method definition, simplevector, at);
                JL_TYPECHK(ccall method definition, quotenode, jl_exprarg(e, 3));
                JL_TYPECHK(ccall method definition, symbol, *(jl_value_t**)jl_exprarg(e, 3));
                JL_TYPECHK(ccall method definition, long, jl_exprarg(e, 4));
            }
Пример #15
0
// 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_ptls_t ptls = jl_get_ptls_states();
    if (ptls->in_pure_callback)
        jl_error("cannot use include inside a generated function");
    jl_ast_context_t *ctx = jl_ast_ctx_enter();
    fl_context_t *fl_ctx = &ctx->fl;
    value_t f, ast, expression;
    size_t len = strlen(fname);
    f = cvalue_static_cstrn(fl_ctx, fname, len);
    fl_gc_handle(fl_ctx, &f);
    if (content != NULL) {
        JL_TIMING(PARSING);
        value_t t = cvalue_static_cstrn(fl_ctx, content, contentlen);
        fl_gc_handle(fl_ctx, &t);
        ast = fl_applyn(fl_ctx, 2, symbol_value(symbol(fl_ctx, "jl-parse-string-stream")), t, f);
        fl_free_gc_handles(fl_ctx, 1);
    }
    else {
        JL_TIMING(PARSING);
        assert(memchr(fname, 0, len) == NULL); // was checked already in jl_load
        ast = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-parse-file")), f);
    }
    fl_free_gc_handles(fl_ctx, 1);
    if (ast == fl_ctx->F) {
        jl_ast_ctx_leave(ctx);
        jl_errorf("could not open file %s", fname);
    }
    fl_gc_handle(fl_ctx, &ast);
    fl_gc_handle(fl_ctx, &expression);

    int last_lineno = jl_lineno;
    const char *last_filename = jl_filename;
    size_t last_age = jl_get_ptls_states()->world_age;
    jl_lineno = 0;
    jl_filename = fname;
    jl_module_t *old_module = ctx->module;
    ctx->module = inmodule;
    jl_value_t *form = NULL;
    jl_value_t *result = jl_nothing;
    int err = 0;
    JL_GC_PUSH2(&form, &result);
    JL_TRY {
        assert(iscons(ast) && car_(ast) == symbol(fl_ctx, "toplevel"));
        ast = cdr_(ast);
        while (iscons(ast)) {
            expression = car_(ast);
            {
                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);
                    expression = julia_to_scm(fl_ctx, form);
                }
                // expand non-final expressions in statement position (value unused)
                expression =
                    fl_applyn(fl_ctx, 1,
                              symbol_value(symbol(fl_ctx, iscons(cdr_(ast)) ? "jl-expand-to-thunk-stmt" : "jl-expand-to-thunk")),
                              expression);
            }
            jl_get_ptls_states()->world_age = jl_world_counter;
            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))
                jl_lineno = jl_linenode_line(form);
            else
                result = jl_toplevel_eval_flex(inmodule, form, 1, 1);
            JL_SIGATOMIC_BEGIN();
            ast = cdr_(ast);
        }
    }
    JL_CATCH {
        form = jl_pchar_to_string(fname, len);
        result = jl_box_long(jl_lineno);
        err = 1;
    }
    jl_get_ptls_states()->world_age = last_age;
    jl_lineno = last_lineno;
    jl_filename = last_filename;
    fl_free_gc_handles(fl_ctx, 2);
    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,
                                           ptls->exception_in_transit));
    }
    JL_GC_POP();
    return result;
}
Пример #16
0
static jl_lambda_info_t *jl_instantiate_staged(jl_method_t *generator, jl_tupletype_t *tt, jl_svec_t *env)
{
    size_t i, l;
    jl_expr_t *ex = NULL;
    jl_value_t *linenum = NULL;
    jl_svec_t *sparam_vals = env;
    jl_lambda_info_t *func = generator->lambda_template;
    JL_GC_PUSH4(&ex, &linenum, &sparam_vals, &func);
    int last_in = in_pure_callback;
    assert(jl_svec_len(func->sparam_syms) == jl_svec_len(sparam_vals));
    JL_TRY {
        in_pure_callback = 1;
        ex = jl_exprn(lambda_sym, 2);

        int nargs = func->nargs;
        jl_array_t *argnames = jl_alloc_vec_any(nargs);
        jl_array_ptr_set(ex->args, 0, argnames);
        for (i = 0; i < nargs; i++)
            jl_array_ptr_set(argnames, i, jl_array_ptr_ref(func->slotnames, i));

        jl_expr_t *scopeblock = jl_exprn(jl_symbol("scope-block"), 1);
        jl_array_ptr_set(ex->args, 1, scopeblock);
        jl_expr_t *body = jl_exprn(jl_symbol("block"), 2);
        jl_array_ptr_set(((jl_expr_t*)jl_exprarg(ex,1))->args, 0, body);
        linenum = jl_box_long(generator->line);
        jl_value_t *linenode = jl_new_struct(jl_linenumbernode_type, linenum);
        jl_array_ptr_set(body->args, 0, linenode);

        // invoke code generator
        assert(jl_nparams(tt) == jl_array_len(argnames) ||
               (func->isva && (jl_nparams(tt) >= jl_array_len(argnames) - 1)));
        jl_array_ptr_set(body->args, 1,
                jl_call_staged(sparam_vals, func, jl_svec_data(tt->parameters), jl_nparams(tt)));

        if (func->sparam_syms != jl_emptysvec) {
            // mark this function as having the same static parameters as the generator
            size_t i, nsp = jl_svec_len(func->sparam_syms);
            jl_expr_t *newast = jl_exprn(jl_symbol("with-static-parameters"), nsp + 1);
            jl_exprarg(newast, 0) = (jl_value_t*)ex;
            // (with-static-parameters func_expr sp_1 sp_2 ...)
            for (i = 0; i < nsp; i++)
                jl_exprarg(newast, i+1) = jl_svecref(func->sparam_syms, i);
            ex = newast;
        }

        // need to eval macros in the right module, but not give a warning for the `eval` call unless that results in a call to `eval`
        func = (jl_lambda_info_t*)jl_toplevel_eval_in_warn(generator->module, (jl_value_t*)ex, 1);

        // finish marking this as a specialization of the generator
        func->isva = generator->lambda_template->isva;
        func->def = generator;
        jl_gc_wb(func, generator);
        func->sparam_vals = env;
        jl_gc_wb(func, env);
        func->specTypes = tt;
        jl_gc_wb(func, tt);

        jl_array_t *stmts = (jl_array_t*)func->code;
        for(i = 0, l = jl_array_len(stmts); i < l; i++) {
            jl_array_ptr_set(stmts, i, jl_resolve_globals(jl_array_ptr_ref(stmts, i), func));
        }
        in_pure_callback = last_in;
    }
    JL_CATCH {
        in_pure_callback = last_in;
        jl_rethrow();
    }
    JL_GC_POP();
    return func;
}
Пример #17
0
jl_value_t *jl_eval_module_expr(jl_expr_t *ex)
{
    jl_ptls_t ptls = jl_get_ptls_states();
    static arraylist_t module_stack;
    static int initialized=0;
    static jl_module_t *outermost = NULL;
    if (!initialized) {
        arraylist_new(&module_stack, 0);
        initialized = 1;
    }
    assert(ex->head == module_sym);
    jl_module_t *last_module = ptls->current_module;
    if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex,2))) {
        jl_error("syntax: malformed module expression");
    }
    int std_imports = (jl_exprarg(ex,0)==jl_true);
    jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1);
    if (!jl_is_symbol(name)) {
        jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name);
    }
    jl_module_t *parent_module = ptls->current_module;
    jl_binding_t *b = jl_get_binding_wr(parent_module, name);
    jl_declare_constant(b);
    if (b->value != NULL) {
        if (!jl_is_module(b->value)) {
            jl_errorf("invalid redefinition of constant %s",
                      jl_symbol_name(name));
        }
        if (jl_generating_output()) {
            jl_errorf("cannot replace module %s during compilation",
                      jl_symbol_name(name));
        }
        jl_printf(JL_STDERR, "WARNING: replacing module %s\n",
                  jl_symbol_name(name));
    }
    jl_module_t *newm = jl_new_module(name);
    newm->parent = parent_module;
    b->value = (jl_value_t*)newm;
    jl_gc_wb_binding(b, newm);

    if (parent_module == jl_main_module && name == jl_symbol("Base")) {
        // pick up Base module during bootstrap
        jl_base_module = newm;
    }
    // export all modules from Main
    if (parent_module == jl_main_module)
        jl_module_export(jl_main_module, name);

    // add standard imports unless baremodule
    if (std_imports) {
        if (jl_base_module != NULL) {
            jl_add_standard_imports(newm);
        }
    }

    jl_value_t *defaultdefs = NULL, *form = NULL;
    JL_GC_PUSH3(&last_module, &defaultdefs, &form);
    jl_module_t *task_last_m = ptls->current_task->current_module;
    ptls->current_task->current_module = ptls->current_module = newm;
    jl_module_t *prev_outermost = outermost;
    size_t stackidx = module_stack.len;
    if (outermost == NULL)
        outermost = newm;

    if (std_imports) {
        // add `eval` function
        defaultdefs = jl_call_scm_on_ast("module-default-defs", (jl_value_t*)ex);
        jl_toplevel_eval_flex(defaultdefs, 0, 1);
        defaultdefs = NULL;
    }

    jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args;
    JL_TRY {
        for(int i=0; i < jl_array_len(exprs); i++) {
            // process toplevel form
            form = jl_expand(jl_array_ptr_ref(exprs, i));
            (void)jl_toplevel_eval_flex(form, 1, 1);
        }
    }
    JL_CATCH {
        ptls->current_module = last_module;
        ptls->current_task->current_module = task_last_m;
        outermost = prev_outermost;
        module_stack.len = stackidx;
        jl_rethrow();
    }
    JL_GC_POP();
    ptls->current_module = last_module;
    ptls->current_task->current_module = task_last_m;
    outermost = prev_outermost;

#if 0
    // some optional post-processing steps
    size_t i;
    void **table = newm->bindings.table;
    for(i=1; i < newm->bindings.size; i+=2) {
        if (table[i] != HT_NOTFOUND) {
            jl_binding_t *b = (jl_binding_t*)table[i];
            // remove non-exported macros
            if (jl_symbol_name(b->name)[0]=='@' &&
                !b->exportp && b->owner == newm)
                b->value = NULL;
            // error for unassigned exports
            /*
            if (b->exportp && b->owner==newm && b->value==NULL)
                jl_errorf("identifier %s exported from %s is not initialized",
                          jl_symbol_name(b->name), jl_symbol_name(newm->name));
            */
        }
    }
#endif

    arraylist_push(&module_stack, newm);

    if (outermost == NULL || ptls->current_module == jl_main_module) {
        JL_TRY {
            size_t i, l=module_stack.len;
            for(i = stackidx; i < l; i++) {
                jl_module_load_time_initialize((jl_module_t*)module_stack.items[i]);
            }
            assert(module_stack.len == l);
            module_stack.len = stackidx;
        }
        JL_CATCH {
            module_stack.len = stackidx;
            jl_rethrow();
        }
    }
Пример #18
0
static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl, size_t ngensym)
{
    if (jl_is_symbol(e)) {
        jl_value_t *v;
        size_t i;
        for(i=0; i < nl; i++) {
            if (locals[i*2] == e) {
                v = locals[i*2+1];
                break;
            }
        }
        if (i >= nl) {
            v = jl_get_global(jl_current_module, (jl_sym_t*)e);
        }
        if (v == NULL) {
            jl_undefined_var_error((jl_sym_t*)e);
        }
        return v;
    }
    if (jl_is_symbolnode(e)) {
        return eval((jl_value_t*)jl_symbolnode_sym(e), locals, nl, ngensym);
    }
    if (jl_is_gensym(e)) {
        ssize_t genid = ((jl_gensym_t*)e)->id;
        if (genid >= ngensym || genid < 0)
            jl_error("access to invalid GenSym location");
        else
            return locals[nl*2 + genid];
    }
    if (jl_is_quotenode(e)) {
        return jl_fieldref(e,0);
    }
    if (jl_is_topnode(e)) {
        jl_sym_t *s = (jl_sym_t*)jl_fieldref(e,0);
        jl_value_t *v = jl_get_global(jl_base_relative_to(jl_current_module),s);
        if (v == NULL)
            jl_undefined_var_error(s);
        return v;
    }
    if (!jl_is_expr(e)) {
        if (jl_is_globalref(e)) {
            jl_value_t *gfargs[2] = {(jl_value_t*)jl_globalref_mod(e), (jl_value_t*)jl_globalref_name(e)};
            return jl_f_get_field(NULL, gfargs, 2);
        }
        if (jl_is_lambda_info(e)) {
            jl_lambda_info_t *li = (jl_lambda_info_t*)e;
            if (jl_boot_file_loaded && li->ast && jl_is_expr(li->ast)) {
                li->ast = jl_compress_ast(li, li->ast);
                jl_gc_wb(li, li->ast);
            }
            return (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_emptysvec, li);
        }
        if (jl_is_linenode(e)) {
            jl_lineno = jl_linenode_line(e);
        }
        if (jl_is_newvarnode(e)) {
            jl_value_t *var = jl_fieldref(e,0);
            assert(!jl_is_gensym(var));
            assert(jl_is_symbol(var));
            for(size_t i=0; i < nl; i++) {
                if (locals[i*2] == var) {
                    locals[i*2+1] = NULL;
                    break;
                }
            }
            return (jl_value_t*)jl_nothing;
        }
        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 == call_sym) {
        if (jl_is_lambda_info(args[0])) {
            // directly calling an inner function ("let")
            jl_lambda_info_t *li = (jl_lambda_info_t*)args[0];
            if (jl_is_expr(li->ast) && !jl_lam_vars_captured((jl_expr_t*)li->ast) &&
                !jl_has_intrinsics((jl_expr_t*)li->ast, (jl_expr_t*)li->ast, jl_current_module)) {
                size_t na = nargs-1;
                if (na == 0)
                    return jl_interpret_toplevel_thunk(li);
                jl_array_t *formals = jl_lam_args((jl_expr_t*)li->ast);
                size_t nreq = jl_array_len(formals);
                if (nreq==0 || !jl_is_rest_arg(jl_cellref(formals,nreq-1))) {
                    jl_value_t **ar;
                    JL_GC_PUSHARGS(ar, na*2);
                    for(int i=0; i < na; i++) {
                        ar[i*2+1] = eval(args[i+1], locals, nl, ngensym);
                        jl_gc_wb(ex->args, ar[i*2+1]);
                    }
                    if (na != nreq) {
                        jl_error("wrong number of arguments");
                    }
                    for(int i=0; i < na; i++) {
                        jl_value_t *v = jl_cellref(formals, i);
                        ar[i*2] = (jl_is_gensym(v)) ? v : (jl_value_t*)jl_decl_var(v);
                    }
                    jl_value_t *ret = jl_interpret_toplevel_thunk_with(li, ar, na);
                    JL_GC_POP();
                    return ret;
                }
            }
        }
        jl_function_t *f = (jl_function_t*)eval(args[0], locals, nl, ngensym);
        if (jl_is_func(f))
            return do_call(f, &args[1], nargs-1, NULL, locals, nl, ngensym);
        else
            return do_call(jl_module_call_func(jl_current_module), args, nargs, (jl_value_t*)f, locals, nl, ngensym);
    }
    else if (ex->head == assign_sym) {
        jl_value_t *sym = args[0];
        jl_value_t *rhs = eval(args[1], locals, nl, ngensym);
        if (jl_is_gensym(sym)) {
            ssize_t genid = ((jl_gensym_t*)sym)->id;
            if (genid >= ngensym || genid < 0)
                jl_error("assignment to invalid GenSym location");
            locals[nl*2 + genid] = rhs;
            return rhs;
        }
        if (jl_is_symbol(sym)) {
            size_t i;
            for (i=0; i < nl; i++) {
                if (locals[i*2] == sym) {
                    locals[i*2+1] = rhs;
                    return rhs;
                }
            }
        }
        jl_module_t *m = jl_current_module;
        if (jl_is_globalref(sym)) {
            m = jl_globalref_mod(sym);
            sym = (jl_value_t*)jl_globalref_name(sym);
        }
        assert(jl_is_symbol(sym));
        JL_GC_PUSH1(&rhs);
        jl_binding_t *b = jl_get_binding_wr(m, (jl_sym_t*)sym);
        jl_checked_assignment(b, rhs);
        JL_GC_POP();
        return rhs;
    }
    else if (ex->head == new_sym) {
        jl_value_t *thetype = eval(args[0], locals, nl, ngensym);
        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_set_nth_field(v, i-1, eval(args[i], locals, nl, ngensym));
        }
        JL_GC_POP();
        return v;
    }
    else if (ex->head == null_sym) {
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == body_sym) {
        return eval_body(ex->args, locals, nl, ngensym, 0, 0);
    }
    else if (ex->head == exc_sym) {
        return jl_exception_in_transit;
    }
    else if (ex->head == static_typeof_sym) {
        return (jl_value_t*)jl_any_type;
    }
    else if (ex->head == method_sym) {
        jl_sym_t *fname = (jl_sym_t*)args[0];
        jl_value_t **bp=NULL;
        jl_value_t *bp_owner=NULL;
        jl_binding_t *b=NULL;
        jl_value_t *gf=NULL;
        int kw=0;
        if (jl_is_expr(fname) || jl_is_globalref(fname)) {
            if (jl_is_expr(fname) && ((jl_expr_t*)fname)->head == kw_sym) {
                kw = 1;
                fname = (jl_sym_t*)jl_exprarg(fname, 0);
            }
            gf = eval((jl_value_t*)fname, locals, nl, ngensym);
            if (jl_is_expr(fname))
                fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0);
            bp = &gf;
            assert(jl_is_symbol(fname));
        }
        else {
            for (size_t i=0; i < nl; i++) {
                if (locals[i*2] == (jl_value_t*)fname) {
                    bp = &locals[i*2+1];
                    break;
                }
            }
            if (bp == NULL) {
                b = jl_get_binding_for_method_def(jl_current_module, fname);
                bp = &b->value;
                bp_owner = (jl_value_t*)jl_current_module;
            }
        }
        if (jl_expr_nargs(ex) == 1)
            return jl_generic_function_def(fname, bp, bp_owner, b);
        jl_value_t *atypes=NULL, *meth=NULL;
        JL_GC_PUSH2(&atypes, &meth);
        atypes = eval(args[1], locals, nl, ngensym);
        if (jl_is_lambda_info(args[2])) {
            jl_check_static_parameter_conflicts((jl_lambda_info_t*)args[2], (jl_svec_t*)jl_svecref(atypes,1), fname);
        }
        meth = eval(args[2], locals, nl, ngensym);
        jl_method_def(fname, bp, bp_owner, b, (jl_svec_t*)atypes, (jl_function_t*)meth, args[3], NULL, kw);
        JL_GC_POP();
        return *bp;
    }
    else if (ex->head == copyast_sym) {
        return jl_copy_ast(eval(args[0], locals, nl, ngensym));
    }
    else if (ex->head == const_sym) {
        jl_value_t *sym = args[0];
        assert(jl_is_symbol(sym));
        for (size_t i=0; i < nl; i++) {
            if (locals[i*2] == sym) {
                return (jl_value_t*)jl_nothing;
            }
        }
        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym);
        jl_declare_constant(b);
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == global_sym) {
        // create uninitialized mutable binding for "global x" decl
        // TODO: handle type decls
        for (size_t i=0; i < jl_array_len(ex->args); i++) {
            assert(jl_is_symbol(args[i]));
            jl_get_binding_wr(jl_current_module, (jl_sym_t*)args[i]);
        }
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == abstracttype_sym) {
        jl_value_t *name = args[0];
        jl_value_t *para = eval(args[1], locals, nl, ngensym);
        jl_value_t *super = NULL;
        jl_value_t *temp = NULL;
        jl_datatype_t *dt = NULL;
        JL_GC_PUSH4(&para, &super, &temp, &dt);
        assert(jl_is_svec(para));
        assert(jl_is_symbol(name));
        dt = jl_new_abstracttype(name, jl_any_type, (jl_svec_t*)para);
        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name);
        temp = b->value;
        check_can_assign_type(b);
        b->value = (jl_value_t*)dt;
        jl_gc_wb_binding(b, dt);
        super = eval(args[2], locals, nl, ngensym);
        jl_set_datatype_super(dt, super);
        b->value = temp;
        if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
            jl_checked_assignment(b, (jl_value_t*)dt);
        }
        JL_GC_POP();
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == bitstype_sym) {
        jl_value_t *name = args[0];
        jl_value_t *super = NULL, *para = NULL, *vnb = NULL, *temp = NULL;
        jl_datatype_t *dt = NULL;
        JL_GC_PUSH4(&para, &super, &temp, &dt);
        assert(jl_is_symbol(name));
        para = eval(args[1], locals, nl, ngensym);
        assert(jl_is_svec(para));
        vnb  = eval(args[2], locals, nl, ngensym);
        if (!jl_is_long(vnb))
            jl_errorf("invalid declaration of bits type %s", ((jl_sym_t*)name)->name);
        ssize_t nb = jl_unbox_long(vnb);
        if (nb < 1 || nb>=(1<<23) || (nb&7) != 0)
            jl_errorf("invalid number of bits in type %s",
                      ((jl_sym_t*)name)->name);
        dt = jl_new_bitstype(name, jl_any_type, (jl_svec_t*)para, nb);
        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name);
        temp = b->value;
        check_can_assign_type(b);
        b->value = (jl_value_t*)dt;
        jl_gc_wb_binding(b, dt);
        super = eval(args[3], locals, nl, ngensym);
        jl_set_datatype_super(dt, super);
        b->value = temp;
        if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
            jl_checked_assignment(b, (jl_value_t*)dt);
        }
        JL_GC_POP();
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == compositetype_sym) {
        jl_value_t *name = args[0];
        assert(jl_is_symbol(name));
        jl_value_t *para = eval(args[1], locals, nl, ngensym);
        assert(jl_is_svec(para));
        jl_value_t *temp = NULL;
        jl_value_t *super = NULL;
        jl_datatype_t *dt = NULL;
        JL_GC_PUSH4(&para, &super, &temp, &dt);
        temp = eval(args[2], locals, nl, ngensym);  // field names
        dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_svec_t*)para,
                             (jl_svec_t*)temp, NULL,
                             0, args[5]==jl_true ? 1 : 0, jl_unbox_long(args[6]));

        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name);
        temp = b->value;  // save old value
        // temporarily assign so binding is available for field types
        check_can_assign_type(b);
        b->value = (jl_value_t*)dt;
        jl_gc_wb_binding(b,dt);

        JL_TRY {
            // operations that can fail
            inside_typedef = 1;
            dt->types = (jl_svec_t*)eval(args[4], locals, nl, ngensym);
            jl_gc_wb(dt, dt->types);
            inside_typedef = 0;
            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_type_error_rt(dt->name->name->name, "type definition", (jl_value_t*)jl_type_type, elt);
            }
            super = eval(args[3], locals, nl, ngensym);
            jl_set_datatype_super(dt, super);
        }
        JL_CATCH {
            b->value = temp;
            jl_rethrow();
        }
        for(size_t i=0; i < jl_svec_len(para); i++) {
            ((jl_tvar_t*)jl_svecref(para,i))->bound = 0;
        }
        jl_compute_field_offsets(dt);
        if (para == (jl_value_t*)jl_emptysvec && jl_is_datatype_singleton(dt)) {
            dt->instance = newstruct(dt);
            jl_gc_wb(dt, dt->instance);
        }

        b->value = temp;
        if (temp==NULL || !equiv_type(dt, (jl_datatype_t*)temp)) {
            jl_checked_assignment(b, (jl_value_t*)dt);
        }
        else {
            // TODO: remove all old ctors and set temp->name->ctor_factory = dt->name->ctor_factory
        }

        JL_GC_POP();
        return (jl_value_t*)jl_nothing;
    }
Пример #19
0
void darwin_accerr_handler(unw_context_t *uc)
{
    bt_size = rec_backtrace_ctx(bt_data, MAX_BT_SIZE, uc);
    jl_exception_in_transit = jl_readonlymemory_exception;
    jl_rethrow();
}
Пример #20
0
void darwin_stack_overflow_handler(unw_context_t *uc)
{
    bt_size = rec_backtrace_ctx(bt_data, MAX_BT_SIZE, uc);
    jl_exception_in_transit = jl_stackovf_exception;
    jl_rethrow();
}
Пример #21
0
jl_value_t *jl_eval_module_expr(jl_expr_t *ex)
{
    static arraylist_t module_stack;
    static int initialized=0;
    if (!initialized) {
        arraylist_new(&module_stack, 0);
        initialized = 1;
    }
    assert(ex->head == module_sym);
    jl_module_t *last_module = jl_current_module;
    if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex,2))) {
        jl_error("syntax: malformed module expression");
    }
    int std_imports = (jl_exprarg(ex,0)==jl_true);
    jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1);
    if (!jl_is_symbol(name)) {
        jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name);
    }
    jl_module_t *parent_module = jl_current_module;
    jl_binding_t *b = jl_get_binding_wr(parent_module, name);
    jl_declare_constant(b);
    if (b->value != NULL) {
        JL_PRINTF(JL_STDERR, "Warning: replacing module %s\n", name->name);
    }
    jl_module_t *newm = jl_new_module(name);
    newm->parent = parent_module;
    b->value = (jl_value_t*)newm;
    if (parent_module == jl_main_module && name == jl_symbol("Base")) {
        // pick up Base module during bootstrap
        jl_old_base_module = jl_base_module;
        jl_base_module = newm;
        // reinitialize global variables
        // to pick up new types from Base
        jl_errorexception_type = NULL;
        jl_typeerror_type = NULL;
        jl_methoderror_type = NULL;
        jl_loaderror_type = NULL;
        jl_weakref_type = NULL;
        jl_current_task->tls = jl_nothing;
    }
    // export all modules from Main
    if (parent_module == jl_main_module)
        jl_module_export(jl_main_module, name);

    // add standard imports unless baremodule
    if (std_imports) {
        if (jl_base_module != NULL) {
            jl_add_standard_imports(newm);
        }
    }

    JL_GC_PUSH1(&last_module);
    jl_module_t *task_last_m = jl_current_task->current_module;
    jl_current_task->current_module = jl_current_module = newm;

    jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args;
    JL_TRY {
        for(int i=0; i < jl_array_len(exprs); i++) {
            // process toplevel form
            jl_value_t *form = jl_cellref(exprs, i);
            (void)jl_toplevel_eval_flex(form, 1);
        }
    }
    JL_CATCH {
        jl_current_module = last_module;
        jl_current_task->current_module = task_last_m;
        jl_rethrow();
    }
    JL_GC_POP();
    jl_current_module = last_module;
    jl_current_task->current_module = task_last_m;

#if 0
    // some optional post-processing steps
    size_t i;
    void **table = newm->bindings.table;
    for(i=1; i < newm->bindings.size; i+=2) {
        if (table[i] != HT_NOTFOUND) {
            jl_binding_t *b = (jl_binding_t*)table[i];
            // remove non-exported macros
            if (b->name->name[0]=='@' && !b->exportp && b->owner==newm)
                b->value = NULL;
            // error for unassigned exports
            /*
            if (b->exportp && b->owner==newm && b->value==NULL)
                jl_errorf("identifier %s exported from %s is not initialized",
                          b->name->name, newm->name->name);
            */
        }
    }
#endif

    arraylist_push(&module_stack, newm);

    if (jl_current_module == jl_main_module) {
        while (module_stack.len > 0) {
            jl_module_load_time_initialize((jl_module_t *) arraylist_pop(&module_stack));
        }
    }

    return jl_nothing;
}
Пример #22
0
jl_value_t *jl_eval_module_expr(jl_expr_t *ex)
{
    static arraylist_t module_stack;
    static int initialized=0;
    static jl_module_t *outermost = NULL;
    if (!initialized) {
        arraylist_new(&module_stack, 0);
        initialized = 1;
    }
    assert(ex->head == module_sym);
    jl_module_t *last_module = jl_current_module;
    if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex,2))) {
        jl_error("syntax: malformed module expression");
    }
    int std_imports = (jl_exprarg(ex,0)==jl_true);
    jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1);
    if (!jl_is_symbol(name)) {
        jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name);
    }
    jl_module_t *parent_module = jl_current_module;
    jl_binding_t *b = jl_get_binding_wr(parent_module, name);
    jl_declare_constant(b);
    if (b->value != NULL) {
        if (!jl_is_module(b->value)) {
            jl_errorf("invalid redefinition of constant %s", name->name);
        }
        if (jl_generating_output() && jl_options.incremental) {
            jl_errorf("cannot replace module %s during incremental compile", name->name);
        }
        if (!jl_generating_output()) {
            // suppress warning "replacing module Core.Inference" during bootstrapping
            jl_printf(JL_STDERR, "WARNING: replacing module %s\n", name->name);
        }
    }
    jl_module_t *newm = jl_new_module(name);
    newm->parent = parent_module;
    b->value = (jl_value_t*)newm;
    jl_gc_wb_binding(b, newm);

    if (parent_module == jl_main_module && name == jl_symbol("Base")) {
        // pick up Base module during bootstrap
        jl_old_base_module = jl_base_module;
        jl_base_module = newm;
        // reinitialize global variables
        // to pick up new types from Base
        jl_errorexception_type = NULL;
        jl_argumenterror_type = NULL;
        jl_methoderror_type = NULL;
        jl_loaderror_type = NULL;
        jl_current_task->tls = jl_nothing; // may contain an entry for :SOURCE_FILE that is not valid in the new base
    }
    // export all modules from Main
    if (parent_module == jl_main_module)
        jl_module_export(jl_main_module, name);

    // add standard imports unless baremodule
    if (std_imports) {
        if (jl_base_module != NULL) {
            jl_add_standard_imports(newm);
        }
    }

    JL_GC_PUSH1(&last_module);
    jl_module_t *task_last_m = jl_current_task->current_module;
    jl_current_task->current_module = jl_current_module = newm;
    jl_module_t *prev_outermost = outermost;
    size_t stackidx = module_stack.len;
    if (outermost == NULL)
        outermost = newm;

    jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 2))->args;
    JL_TRY {
        for(int i=0; i < jl_array_len(exprs); i++) {
            // process toplevel form
            jl_value_t *form = jl_cellref(exprs, i);
            (void)jl_toplevel_eval_flex(form, 1);
        }
    }
    JL_CATCH {
        jl_current_module = last_module;
        jl_current_task->current_module = task_last_m;
        outermost = prev_outermost;
        module_stack.len = stackidx;
        jl_rethrow();
    }
    JL_GC_POP();
    jl_current_module = last_module;
    jl_current_task->current_module = task_last_m;
    outermost = prev_outermost;

#if 0
    // some optional post-processing steps
    size_t i;
    void **table = newm->bindings.table;
    for(i=1; i < newm->bindings.size; i+=2) {
        if (table[i] != HT_NOTFOUND) {
            jl_binding_t *b = (jl_binding_t*)table[i];
            // remove non-exported macros
            if (b->name->name[0]=='@' && !b->exportp && b->owner==newm)
                b->value = NULL;
            // error for unassigned exports
            /*
            if (b->exportp && b->owner==newm && b->value==NULL)
                jl_errorf("identifier %s exported from %s is not initialized",
                          b->name->name, newm->name->name);
            */
        }
    }
#endif

    arraylist_push(&module_stack, newm);

    if (outermost == NULL || jl_current_module == jl_main_module) {
        size_t i, l=module_stack.len;
        for(i = stackidx; i < l; i++) {
            jl_module_load_time_initialize((jl_module_t*)module_stack.items[i]);
        }
        assert(module_stack.len == l);
        module_stack.len = stackidx;
    }

    return (jl_value_t*)newm;
}
Пример #23
0
// 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)
{
    if (in_pure_callback)
        jl_error("cannot use include inside a generated function");
    jl_ast_context_t *ctx = jl_ast_ctx_enter();
    fl_context_t *fl_ctx = &ctx->fl;
    value_t f, ast;
    size_t len = strlen(fname);
    f = cvalue_static_cstrn(fl_ctx, fname, len);
    fl_gc_handle(fl_ctx, &f);
    if (content != NULL) {
        value_t t = cvalue_static_cstrn(fl_ctx, content, contentlen);
        fl_gc_handle(fl_ctx, &t);
        ast = fl_applyn(fl_ctx, 2, symbol_value(symbol(fl_ctx, "jl-parse-string-stream")), t, f);
        fl_free_gc_handles(fl_ctx, 1);
    }
    else {
        assert(memchr(fname, 0, len) == NULL); // was checked already in jl_load
        ast = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-parse-file")), f);
    }
    fl_free_gc_handles(fl_ctx, 1);
    if (ast == fl_ctx->F) {
        jl_ast_ctx_leave(ctx);
        jl_errorf("could not open file %s", fname);
    }
    fl_gc_handle(fl_ctx, &ast);

    int last_lineno = jl_lineno;
    const char *last_filename = jl_filename;
    jl_lineno = 0;
    jl_filename = fname;
    jl_array_t *roots = NULL;
    jl_array_t **old_roots = ctx->roots;
    ctx->roots = &roots;
    jl_value_t *form=NULL, *result=jl_nothing;
    int err = 0;
    JL_GC_PUSH3(&roots, &form, &result);
    JL_TRY {
        assert(iscons(ast) && car_(ast) == symbol(fl_ctx,"toplevel"));
        ast = cdr_(ast);
        while (iscons(ast)) {
            value_t expansion = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk")), car_(ast));
            form = scm_to_julia(fl_ctx, expansion, 0);
            jl_sym_t *head = NULL;
            if (jl_is_expr(form)) head = ((jl_expr_t*)form)->head;
            JL_SIGATOMIC_END();
            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(form);
            else if (head == line_sym)
                jl_lineno = jl_unbox_long(jl_exprarg(form,0));
            else if (jl_is_linenode(form))
                jl_lineno = jl_linenode_line(form);
            else
                result = jl_toplevel_eval_flex(form, 1, 1);
            JL_SIGATOMIC_BEGIN();
            ast = cdr_(ast);
        }
    }
    JL_CATCH {
        form = jl_pchar_to_string(fname, len);
        result = jl_box_long(jl_lineno);
        err = 1;
    }
    jl_lineno = last_lineno;
    jl_filename = last_filename;
    fl_free_gc_handles(fl_ctx, 1);
    ctx->roots = old_roots;
    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_exception_in_transit));
    }
    JL_GC_POP();
    return result;
}