Пример #1
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 *l_ast = li->ast;
    if (l_ast == NULL) return NULL;
    jl_value_t *ast = l_ast;
    JL_GC_PUSH(&spenv, &ast);
    if (jl_is_tuple(ast))
        ast = jl_uncompress_ast((jl_tuple_t*)ast);
    spenv = jl_tuple_tvars_to_symbols(sparams);
    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_raise(jl_exception_in_transit);
    }
    jl_current_module = last_m;
    JL_GC_POP();
    return ast;
}
Пример #2
0
// load toplevel expressions, from (file ...)
void jl_load_file_expr(char *fname, jl_value_t *ast)
{
    jl_array_t *b = ((jl_expr_t*)ast)->args;
    size_t i;
    volatile size_t lineno=0;
    if (((jl_expr_t*)ast)->head == jl_continue_sym) {
        jl_errorf("syntax error: %s", jl_string_data(jl_exprarg(ast,0)));
    }
    JL_TRY {
        jl_register_toplevel_eh();
        // handle syntax error
        if (((jl_expr_t*)ast)->head == error_sym) {
            jl_interpret_toplevel_expr(ast);
        }
        for(i=0; i < b->length; i++) {
            // process toplevel form
            jl_value_t *form = jl_cellref(b, i);
            if (jl_is_linenode(form)) {
                lineno = jl_linenode_line(form);
            }
            else {
                (void)jl_toplevel_eval_flex(form, 0, &lineno);
            }
        }
    }
    JL_CATCH {
        jl_value_t *fn=NULL, *ln=NULL;
        JL_GC_PUSH(&fn, &ln);
        fn = jl_pchar_to_string(fname, strlen(fname));
        ln = jl_box_long(lineno);
        jl_raise(jl_new_struct(jl_loaderror_type, fn, ln,
                               jl_exception_in_transit));
    }
}
Пример #3
0
jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
{
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(jl_typeof(a));
    jl_value_t *elt;
    if (jl_is_bits_type(el_type)) {
        if (el_type == (jl_type_t*)jl_bool_type) {
            if (((int8_t*)a->data)[i] != 0)
                return jl_true;
            return jl_false;
        }
        elt = new_scalar((jl_bits_type_t*)el_type);
        size_t nb = a->elsize;
        switch (nb) {
        case 1:
            *(int8_t*)jl_bits_data(elt)  = ((int8_t*)a->data)[i];  break;
        case 2:
            *(int16_t*)jl_bits_data(elt) = ((int16_t*)a->data)[i]; break;
        case 4:
            *(int32_t*)jl_bits_data(elt) = ((int32_t*)a->data)[i]; break;
        case 8:
            *(int64_t*)jl_bits_data(elt) = ((int64_t*)a->data)[i]; break;
        case 16:
            *(bits128_t*)jl_bits_data(elt) = ((bits128_t*)a->data)[i]; break;
        default:
            memcpy(jl_bits_data(elt), &((char*)a->data)[i*nb], nb);
        }
    }
    else {
        elt = ((jl_value_t**)a->data)[i];
        if (elt == NULL) {
            jl_raise(jl_undefref_exception);
        }
    }
    return elt;
}
Пример #4
0
static jl_value_t *nth_field(jl_value_t *v, size_t i)
{
    jl_value_t *fld = ((jl_value_t**)v)[1+i];
    if (fld == NULL)
        jl_raise(jl_undefref_exception);
    return fld;
}
Пример #5
0
// repeatedly call jl_parse_next and eval everything
void jl_parse_eval_all(char *fname)
{
    //ios_printf(ios_stderr, "***** loading %s\n", fname);
    int lineno=0;
    jl_value_t *fn=NULL, *ln=NULL, *form=NULL;
    JL_GC_PUSH(&fn, &ln, &form);
    JL_TRY {
        jl_register_toplevel_eh();
        // handle syntax error
        while (1) {
            form = jl_parse_next(&lineno);
            if (form == NULL)
                break;
            if (jl_is_expr(form)) {
                if (((jl_expr_t*)form)->head == jl_continue_sym) {
                    jl_errorf("syntax error: %s", jl_string_data(jl_exprarg(form,0)));
                }
                if (((jl_expr_t*)form)->head == error_sym) {
                    jl_interpret_toplevel_expr(form);
                }
            }
            (void)jl_toplevel_eval_flex(form, 1, &lineno);
        }
    }
    JL_CATCH {
        jl_stop_parsing();
        fn = jl_pchar_to_string(fname, strlen(fname));
        ln = jl_box_long(lineno);
        jl_raise(jl_new_struct(jl_loaderror_type, fn, ln,
                               jl_exception_in_transit));
    }
    jl_stop_parsing();
    JL_GC_POP();
}
Пример #6
0
void jl_error(const char *str)
{
    if (jl_errorexception_type == NULL) {
        JL_PRINTF(JL_STDERR, "%s", str);
        jl_exit(1);
    }
    jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str));
    JL_GC_PUSH(&msg);
    jl_raise(jl_new_struct(jl_errorexception_type, msg));
}
Пример #7
0
void fpe_handler(int arg)
{
    (void)arg;
    sigset_t sset;
    sigemptyset(&sset);
    sigaddset(&sset, SIGFPE);
    sigprocmask(SIG_UNBLOCK, &sset, NULL);

    jl_raise(jl_divbyzero_exception);
}
Пример #8
0
void jl_type_error_rt(const char *fname, const char *context,
                      jl_value_t *ty, jl_value_t *got)
{
    jl_value_t *ctxt=NULL;
    JL_GC_PUSH(&ctxt, &got);
    ctxt = jl_pchar_to_string((char*)context, strlen(context));
    jl_value_t *ex = jl_new_struct(jl_typeerror_type, jl_symbol(fname),
                                   ctxt, ty, got);
    jl_raise(ex);
}
Пример #9
0
static void *alloc_big(size_t sz)
{
    if (allocd_bytes > collect_interval) {
        jl_gc_collect();
    }
    sz = (sz+3) & -4;
    size_t offs = BVOFFS*sizeof(void*);
    if (sz + offs < offs)  // overflow in adding offs, size was "negative"
        jl_raise(jl_memory_exception);
    bigval_t *v = (bigval_t*)malloc(sz + offs);
    allocd_bytes += (sz+offs);
    if (v == NULL)
        jl_raise(jl_memory_exception);
    v->sz = sz;
    v->flags = 0;
    v->next = big_objects;
    big_objects = v;
    return &v->_data[0];
}
Пример #10
0
void jl_errorf(const char *fmt, ...)
{
    char buf[1024];
    va_list args;
    va_start(args, fmt);
    int nc = vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);
    jl_value_t *msg = jl_pchar_to_string(buf, nc);
    JL_GC_PUSH(&msg);
    jl_raise(jl_new_struct(jl_errorexception_type, msg));
}
Пример #11
0
jl_mallocptr_t *jl_gc_managed_malloc(size_t sz)
{
    if (allocd_bytes > collect_interval) {
        jl_gc_collect();
    }
    sz = (sz+3) & -4;
    void *b = malloc(sz);
    if (b == NULL)
        jl_raise(jl_memory_exception);
    allocd_bytes += sz;
    return jl_gc_acquire_buffer(b, sz);
}
Пример #12
0
void segv_handler(int sig, siginfo_t *info, void *context)
{
    sigset_t sset;
    sigemptyset(&sset);
    sigaddset(&sset, SIGSEGV);
    sigprocmask(SIG_UNBLOCK, &sset, NULL);

#ifdef COPY_STACKS
    if ((char*)info->si_addr > (char*)jl_stack_lo-3000000 &&
        (char*)info->si_addr < (char*)jl_stack_hi) {
#else
    if ((char*)info->si_addr > (char*)jl_current_task->stack-8192 &&
        (char*)info->si_addr <
        (char*)jl_current_task->stack+jl_current_task->ssize) {
#endif
        jl_raise(jl_stackovf_exception);
    }
    else {
        signal(SIGSEGV, SIG_DFL);
    }
}

volatile sig_atomic_t jl_signal_pending = 0;
volatile sig_atomic_t jl_defer_signal = 0;

void sigint_handler(int sig, siginfo_t *info, void *context)
{
    sigset_t sset;
    sigemptyset(&sset);
    sigaddset(&sset, SIGINT);
    sigprocmask(SIG_UNBLOCK, &sset, NULL);

    if (jl_defer_signal) {
        jl_signal_pending = sig;
    }
    else {
        jl_signal_pending = 0;
        jl_raise(jl_interrupt_exception);
    }
}
Пример #13
0
static void *alloc_big(size_t sz, int isobj)
{
    if (allocd_bytes > collect_interval) {
        jl_gc_collect();
    }
    sz = (sz+3) & -4;
    allocd_bytes += sz;
    size_t offs = BVOFFS*sizeof(void*);
    if (sz + offs < offs)  // overflow in adding offs, size was "negative"
        jl_raise(jl_memory_exception);
    bigval_t *v = (bigval_t*)malloc(sz + offs);
    if (v == NULL)
        jl_raise(jl_memory_exception);
#if defined(MEMDEBUG) || defined(MEMPROFILE)
    v->sz = sz;
#endif
    v->next = big_objects;
    v->flags = 0;
    v->isobj = isobj;
    big_objects = v;
    return &v->_data[0];
}
Пример #14
0
jl_value_t *jl_eval_module_expr(jl_expr_t *ex, int *plineno)
{
    assert(ex->head == module_sym);
    jl_module_t *last_module = jl_current_module;
    jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 0);
    if (!jl_is_symbol(name)) {
        jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name);
    }
    if (name == jl_current_module->name) {
        jl_errorf("module name %s conflicts with enclosing module", name->name);
    }
    jl_binding_t *b = jl_get_binding_wr(jl_current_module, name);
    jl_declare_constant(b);
    if (b->value != NULL) {
        JL_PRINTF(JL_STDERR, "Warning: redefinition of module %s ignored\n",
                   name->name);
        return jl_nothing;
    }
    jl_module_t *newm = jl_new_module(name);
    b->value = (jl_value_t*)newm;
    if (jl_current_module == jl_core_module && name == jl_symbol("Base")) {
        // pick up Base module during bootstrap, and stay within it
        // after loading.
        jl_base_module = last_module = newm;
    }
    JL_GC_PUSH(&last_module);
    jl_current_module = newm;

    jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 1))->args;
    JL_TRY {
        for(int i=0; i < exprs->length; i++) {
            // process toplevel form
            jl_value_t *form = jl_cellref(exprs, i);
            if (jl_is_linenode(form)) {
                if (plineno)
                    *plineno = jl_linenode_line(form);
            }
            else {
                (void)jl_toplevel_eval_flex(form, 0, plineno);
            }
        }
    }
    JL_CATCH {
        JL_GC_POP();
        jl_current_module = last_module;
        jl_raise(jl_exception_in_transit);
    }
    JL_GC_POP();
    jl_current_module = last_module;
    return jl_nothing;
}
Пример #15
0
void sigint_handler(int sig, siginfo_t *info, void *context)
{
    sigset_t sset;
    sigemptyset(&sset);
    sigaddset(&sset, SIGINT);
    sigprocmask(SIG_UNBLOCK, &sset, NULL);

    if (jl_defer_signal) {
        jl_signal_pending = sig;
    }
    else {
        jl_signal_pending = 0;
        jl_raise(jl_interrupt_exception);
    }
}
Пример #16
0
jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
{
    jl_type_t *el_type = (jl_type_t*)jl_tparam0(jl_typeof(a));
    jl_value_t *elt;
    if (jl_is_bits_type(el_type)) {
        elt = jl_new_bits((jl_bits_type_t*)el_type,
                          &((char*)a->data)[i*a->elsize]);
    }
    else {
        elt = ((jl_value_t**)a->data)[i];
        if (elt == NULL) {
            jl_raise(jl_undefref_exception);
        }
    }
    return elt;
}
Пример #17
0
// load toplevel expressions, from (file ...)
void jl_load_file_expr(char *fname, jl_value_t *ast)
{
    jl_array_t *b = ((jl_expr_t*)ast)->args;
    size_t i;
    volatile size_t lineno=0;
    if (((jl_expr_t*)ast)->head == jl_continue_sym) {
        jl_errorf("syntax error: %s", jl_string_data(jl_exprarg(ast,0)));
    }
    char oldcwd[512];
    char newcwd[512];
    get_cwd(oldcwd, sizeof(oldcwd));
    char *sep = strrchr(fname, PATHSEP);
    if (sep) {
        size_t n = (sep - fname)+1;
        if (n > sizeof(newcwd)-1) n = sizeof(newcwd)-1;
        strncpy(newcwd, fname, n);
        newcwd[n] = '\0';
        set_cwd(newcwd);
    }
    JL_TRY {
        jl_register_toplevel_eh();
        // handle syntax error
        if (((jl_expr_t*)ast)->head == error_sym) {
            jl_interpret_toplevel_expr(ast);
        }
        for(i=0; i < b->length; i++) {
            // process toplevel form
            jl_value_t *form = jl_cellref(b, i);
            if (jl_is_linenode(form)) {
                lineno = jl_linenode_line(form);
            }
            else {
                (void)jl_toplevel_eval_flex(form, 0, &lineno);
            }
        }
    }
    JL_CATCH {
        if (sep) set_cwd(oldcwd);
        jl_value_t *fn=NULL, *ln=NULL;
        JL_GC_PUSH(&fn, &ln);
        fn = jl_pchar_to_string(fname, strlen(fname));
        ln = jl_box_long(lineno);
        jl_raise(jl_new_struct(jl_loaderror_type, fn, ln,
                               jl_exception_in_transit));
    }
    if (sep) set_cwd(oldcwd);
}
Пример #18
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_raise(jl_exception_in_transit);
    }
    jl_current_module = last_m;
    assert(v);
    return v;
}
Пример #19
0
static void add_page(pool_t *p)
{
    gcpage_t *pg = malloc(sizeof(gcpage_t));
    if (pg == NULL)
        jl_raise(jl_memory_exception);
    gcval_t *v = (gcval_t*)&pg->data[0];
    char *lim = (char*)pg + GC_PAGE_SZ - p->osize;
    gcval_t *fl;
    gcval_t **pfl = &fl;
    while ((char*)v <= lim) {
        *pfl = v;
        pfl = &v->next;
        v = (gcval_t*)((char*)v + p->osize);
    }
    // these statements are ordered so that interrupting after any of them
    // leaves the system in a valid state
    *pfl = p->freelist;
    pg->next = p->pages;
    p->pages = pg;
    p->freelist = fl;
}
Пример #20
0
Файл: gf.c Проект: cshen/julia
/*
  warn about ambiguous method priorities
  
  the relative priority of A and B is ambiguous if
  !subtype(A,B) && !subtype(B,A) && no corresponding tuple
  elements are disjoint.
  
  for example, (AbstractArray, AbstractMatrix) and (AbstractMatrix, AbstractArray) are ambiguous.
  however, (AbstractArray, AbstractMatrix, Foo) and (AbstractMatrix, AbstractArray, Bar) are fine
  since Foo and Bar are disjoint, so there would be no confusion over
  which one to call.
  
  There is also this kind of ambiguity: foo{T,S}(T, S) vs. foo(Any,Any)
  In this case jl_types_equal() is true, but one is jl_type_morespecific
  or jl_type_match_morespecific than the other.
  To check this, jl_types_equal_generic needs to be more sophisticated
  so (T,T) is not equivalent to (Any,Any). (TODO)
*/
static void check_ambiguous(jl_methlist_t *ml, jl_tuple_t *type,
                            jl_tuple_t *sig, jl_sym_t *fname)
{
    // we know !jl_args_morespecific(type, sig)
    if ((type->length==sig->length ||
         (type->length==sig->length+1 && is_va_tuple(type)) ||
         (type->length+1==sig->length && is_va_tuple(sig))) &&
        !jl_args_morespecific((jl_value_t*)sig, (jl_value_t*)type)) {
        jl_value_t *isect = jl_type_intersection((jl_value_t*)type,
                                                 (jl_value_t*)sig);
        if (isect == (jl_value_t*)jl_bottom_type)
            return;
        JL_GC_PUSH(&isect);
        jl_methlist_t *l = ml;
        while (l != NULL) {
            if (sigs_eq(isect, (jl_value_t*)l->sig))
                goto done_chk_amb;  // ok, intersection is covered
            l = l->next;
        }
        char *n = fname->name;
        jl_value_t *errstream = jl_get_global(jl_system_module,
                                              jl_symbol("stderr_stream"));
        JL_TRY {
            if (errstream)
                jl_set_current_output_stream_obj(errstream);
            ios_t *s = jl_current_output_stream();
            ios_printf(s, "Warning: New definition %s", n);
            jl_show((jl_value_t*)type);
            ios_printf(s, " is ambiguous with %s", n);
            jl_show((jl_value_t*)sig);
            ios_printf(s, ".\n         Make sure %s", n);
            jl_show(isect);
            ios_printf(s, " is defined first.\n");
        }
        JL_CATCH {
            jl_raise(jl_exception_in_transit);
        }
    done_chk_amb:
        JL_GC_POP();
    }
Пример #21
0
void segv_handler(int sig, siginfo_t *info, void *context)
{
    sigset_t sset;
    sigemptyset(&sset);
    sigaddset(&sset, SIGSEGV);
    sigprocmask(SIG_UNBLOCK, &sset, NULL);

    if (
#ifdef COPY_STACKS
        (char*)info->si_addr > (char*)jl_stack_lo-3000000 &&
        (char*)info->si_addr < (char*)jl_stack_hi
#else
        (char*)info->si_addr > (char*)jl_current_task->stack-8192 &&
        (char*)info->si_addr <
        (char*)jl_current_task->stack+jl_current_task->ssize
#endif
        ) {
        jl_raise(jl_stackovf_exception);
    }
    else {
        signal(SIGSEGV, SIG_DFL);
    }
}
Пример #22
0
jl_value_t *jl_eval_module_expr(jl_expr_t *ex, int *plineno)
{
    assert(ex->head == module_sym);
    jl_module_t *last_module = jl_current_module;
    jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 0);
    if (!jl_is_symbol(name)) {
        jl_type_error("module", (jl_value_t*)jl_sym_type, (jl_value_t*)name);
    }
    jl_module_t *parent_module;
    if (jl_current_module == jl_core_module ||
        jl_current_module == jl_main_module) {
        parent_module = jl_root_module;
    }
    else {
        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 = (jl_value_t*)parent_module;
    b->value = (jl_value_t*)newm;
    if (parent_module == jl_root_module && name == jl_symbol("Base") &&
        jl_base_module == NULL) {
        // pick up Base module during bootstrap
        jl_base_module = newm;
    }
    JL_GC_PUSH(&last_module);
    jl_current_module = newm;

    jl_array_t *exprs = ((jl_expr_t*)jl_exprarg(ex, 1))->args;
    JL_TRY {
        for(int i=0; i < exprs->length; i++) {
            // process toplevel form
            jl_value_t *form = jl_cellref(exprs, i);
            if (jl_is_linenode(form)) {
                if (plineno)
                    *plineno = jl_linenode_line(form);
            }
            else {
                (void)jl_toplevel_eval_flex(form, 1, plineno);
            }
        }
    }
    JL_CATCH {
        JL_GC_POP();
        jl_current_module = last_module;
        jl_raise(jl_exception_in_transit);
    }
    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;
}
Пример #23
0
void jl_divide_by_zero_error(void)
{
    jl_raise(jl_divbyzero_exception);
}
Пример #24
0
void jl_undef_ref_error(void)
{
    jl_raise(jl_undefref_exception);
}
Пример #25
0
static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl)
{
    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_errorf("%s not defined", ((jl_sym_t*)e)->name);
        }
        return v;
    }
    if (jl_is_symbolnode(e)) {
        return eval((jl_value_t*)jl_symbolnode_sym(e), locals, nl);
    }
    if (jl_is_quotenode(e)) {
        return jl_fieldref(e,0);
    }
    if (jl_is_topnode(e)) {
        jl_value_t *v = jl_get_global(jl_current_module,
                                      (jl_sym_t*)jl_fieldref(e,0));
        if (v == NULL)
            jl_errorf("%s not defined", ((jl_sym_t*)jl_fieldref(e,0))->name);
        return v;
    }
    if (!jl_is_expr(e)) {
        if (jl_is_getfieldnode(e)) {
            jl_value_t *v = eval(jl_getfieldnode_val(e), locals, nl);
            jl_value_t *gfargs[2] = {v, (jl_value_t*)jl_getfieldnode_name(e)};
            return jl_f_get_field(NULL, gfargs, 2);
        }
        if (jl_is_lambda_info(e)) {
            return (jl_value_t*)jl_new_closure(NULL, (jl_value_t*)jl_null,
                                               (jl_lambda_info_t*)e);
        }
        if (jl_is_linenode(e)) {
            jl_lineno = jl_linenode_line(e);
        }
        return e;
    }
    jl_expr_t *ex = (jl_expr_t*)e;
    jl_value_t **args = &jl_cellref(ex->args,0);
    if (ex->head == call_sym ||  ex->head == call1_sym) {
        jl_function_t *f = (jl_function_t*)eval(args[0], locals, nl);
        if (!jl_is_func(f))
            jl_type_error("apply", (jl_value_t*)jl_function_type,
                          (jl_value_t*)f);
        return do_call(f, &args[1], ex->args->length-1, locals, nl);
    }
    else if (ex->head == assign_sym) {
        jl_value_t *sym = args[0];
        size_t i;
        for (i=0; i < nl; i++) {
            if (locals[i*2] == sym) {
                return (locals[i*2+1] = eval(args[1], locals, nl));
            }
        }
        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)sym);
        jl_value_t *rhs = eval(args[1], locals, nl);
        jl_checked_assignment(b, rhs);
        return rhs;
    }
    else if (ex->head == new_sym) {
        jl_value_t *thetype = eval(args[0], locals, nl);
        JL_GC_PUSH(&thetype);
        assert(jl_is_struct_type(thetype));
        jl_value_t *v = jl_new_struct_uninit((jl_struct_type_t*)thetype);
        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, 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_binding_t *b=NULL;
        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;
        }
        jl_value_t *atypes=NULL, *meth=NULL, *tvars=NULL;
        JL_GC_PUSH(&atypes, &meth, &tvars);
        atypes = eval(args[1], locals, nl);
        meth = eval(args[2], locals, nl);
        tvars = eval(args[3], locals, nl);
        jl_method_def(fname, bp, b, (jl_tuple_t*)atypes,
                      (jl_function_t*)meth, (jl_tuple_t*)tvars);
        JL_GC_POP();
        return jl_nothing;
    }
    else if (ex->head == const_sym) {
        jl_value_t *sym = args[0];
        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 < ex->args->length; 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);
        jl_value_t *super = NULL;
        JL_GC_PUSH(&para, &super);
        jl_tag_type_t *tt=jl_new_tagtype(name, jl_any_type, (jl_tuple_t*)para);
        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name);
        jl_checked_assignment(b, (jl_value_t*)tt);
        super = eval(args[2], locals, nl);
        jl_set_tag_type_super(tt, super);
        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;
        JL_GC_PUSH(&para, &super, &vnb);
        para = eval(args[1], locals, nl);
        vnb  = eval(args[2], locals, nl);
        if (!jl_is_long(vnb))
            jl_errorf("invalid declaration of bits type %s", ((jl_sym_t*)name)->name);
        int32_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);
        jl_bits_type_t *bt = jl_new_bits_type(name, jl_any_type, (jl_tuple_t*)para, nb);
        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name);
        jl_checked_assignment(b, (jl_value_t*)bt);
        super = eval(args[3], locals, nl);
        jl_set_tag_type_super((jl_tag_type_t*)bt, super);
        JL_GC_POP();
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == compositetype_sym) {
        void jl_add_constructors(jl_struct_type_t *t);
        jl_value_t *name = args[0];
        jl_value_t *para = eval(args[1], locals, nl);
        jl_value_t *fnames = NULL;
        jl_value_t *super = NULL;
        jl_struct_type_t *st = NULL;
        JL_GC_PUSH(&para, &super, &fnames, &st);
        fnames = eval(args[2], locals, nl);
        st = jl_new_struct_type((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para,
                                (jl_tuple_t*)fnames, NULL);
        st->ctor_factory = eval(args[3], locals, nl);
        jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name);
        jl_checked_assignment(b, (jl_value_t*)st);
        st->types = (jl_tuple_t*)eval(args[5], locals, nl);
        jl_check_type_tuple(st->types, st->name->name, "type definition");
        super = eval(args[4], locals, nl);
        jl_set_tag_type_super((jl_tag_type_t*)st, super);
        jl_compute_struct_offsets(st);
        jl_add_constructors(st);
        JL_GC_POP();
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == macro_sym) {
        jl_sym_t *nm = (jl_sym_t*)args[0];
        assert(jl_is_symbol(nm));
        jl_function_t *f = (jl_function_t*)eval(args[1], locals, nl);
        assert(jl_is_function(f));
        if (jl_boot_file_loaded &&
            f->linfo && f->linfo->ast && jl_is_expr(f->linfo->ast)) {
            jl_lambda_info_t *li = f->linfo;
            li->ast = jl_compress_ast(li, li->ast);
            li->name = nm;
        }
        jl_set_global(jl_current_module, nm, (jl_value_t*)f);
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == line_sym) {
        jl_lineno = jl_unbox_long(jl_exprarg(ex,0));
        return (jl_value_t*)jl_nothing;
    }
    else if (ex->head == module_sym) {
        return jl_eval_module_expr(ex);
    }
    else if (ex->head == error_sym || ex->head == jl_continue_sym) {
        if (jl_is_byte_string(args[0]))
            jl_errorf("syntax error: %s", jl_string_data(args[0]));
        jl_raise(args[0]);
    }
    jl_errorf("unsupported or misplaced expression %s", ex->head->name);
    return (jl_value_t*)jl_nothing;
}
Пример #26
0
void jl_error(const char *str)
{
    jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str));
    JL_GC_PUSH(&msg);
    jl_raise(jl_new_struct(jl_errorexception_type, msg));
}