static Value *emit_arraylen_prim(Value *t, jl_value_t *ty) { #ifdef STORE_ARRAY_LEN (void)ty; Value *lenbits = emit_nthptr(t, 2); return builder.CreatePtrToInt(lenbits, T_size); #else jl_value_t *p1 = jl_tparam1(ty); if (jl_is_long(p1)) { size_t nd = jl_unbox_long(p1); Value *l = ConstantInt::get(T_size, 1); for(size_t i=0; i < nd; i++) { l = builder.CreateMul(l, emit_arraysize(t, (int)(i+1))); } return l; } else { std::vector<Type *> fargt(0); fargt.push_back(jl_pvalue_llvmt); FunctionType *ft = FunctionType::get(T_size, fargt, false); Value *alen = jl_Module->getOrInsertFunction("jl_array_len_", ft); return builder.CreateCall(alen, t); } #endif }
int jl_array_isdefined(jl_value_t **args0, int nargs) { assert(jl_is_array(args0[0])); jl_array_t *a = (jl_array_t*)args0[0]; jl_value_t **args = &args0[1]; size_t nidxs = nargs-1; size_t i=0; size_t k, stride=1; size_t nd = jl_array_ndims(a); for(k=0; k < nidxs; k++) { if (!jl_is_long(args[k])) jl_type_error("isdefined", (jl_value_t*)jl_long_type, args[k]); size_t ii = jl_unbox_long(args[k])-1; i += ii * stride; size_t d = k>=nd ? 1 : jl_array_dim(a, k); if (k < nidxs-1 && ii >= d) return 0; stride *= d; } for(; k < nd; k++) stride *= jl_array_dim(a, k); if (i >= stride) return 0; if (a->ptrarray) return ((jl_value_t**)jl_array_data(a))[i] != NULL; return 1; }
static jl_value_t *copy_ast(jl_value_t *expr, jl_tuple_t *sp, int do_sp) { if (jl_is_symbol(expr)) { if (!do_sp) return expr; // pre-evaluate certain static parameters to help type inference for(int i=0; i < jl_tuple_len(sp); i+=2) { assert(jl_is_typevar(jl_tupleref(sp,i))); if ((jl_sym_t*)expr == ((jl_tvar_t*)jl_tupleref(sp,i))->name) { jl_value_t *spval = jl_tupleref(sp,i+1); if (jl_is_long(spval)) return spval; } } } else if (jl_is_lambda_info(expr)) { jl_lambda_info_t *li = (jl_lambda_info_t*)expr; /* if (sp == jl_null && li->ast && jl_lam_capt((jl_expr_t*)li->ast)->length == 0) return expr; */ // TODO: avoid if above condition is true and decls have already // been evaluated. JL_GC_PUSH(&li); li = jl_add_static_parameters(li, sp); li->ast = jl_prepare_ast(li, li->sparams); JL_GC_POP(); return (jl_value_t*)li; } else if (jl_typeis(expr,jl_array_any_type)) { jl_array_t *a = (jl_array_t*)expr; jl_array_t *na = jl_alloc_cell_1d(jl_array_len(a)); JL_GC_PUSH(&na); size_t i; for(i=0; i < jl_array_len(a); i++) jl_cellset(na, i, copy_ast(jl_cellref(a,i), sp, do_sp)); JL_GC_POP(); return (jl_value_t*)na; } else if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; jl_expr_t *ne = jl_exprn(e->head, jl_array_len(e->args)); JL_GC_PUSH(&ne); size_t i; if (e->head == lambda_sym) { jl_exprarg(ne, 0) = copy_ast(jl_exprarg(e,0), sp, 0); jl_exprarg(ne, 1) = copy_ast(jl_exprarg(e,1), sp, 0); jl_exprarg(ne, 2) = copy_ast(jl_exprarg(e,2), sp, 1); } else { for(i=0; i < jl_array_len(e->args); i++) jl_exprarg(ne, i) = copy_ast(jl_exprarg(e,i), sp, 1); } JL_GC_POP(); return (jl_value_t*)ne; } return expr; }
static value_t julia_to_scm(jl_value_t *v) { if (jl_is_symbol(v)) { return symbol(((jl_sym_t*)v)->name); } if (v == jl_true) { return FL_T; } if (v == jl_false) { return FL_F; } if (jl_is_expr(v)) { jl_expr_t *ex = (jl_expr_t*)v; value_t args = array_to_list(ex->args); fl_gc_handle(&args); value_t hd = julia_to_scm((jl_value_t*)ex->head); value_t scmv = fl_cons(hd, args); fl_free_gc_handles(1); return scmv; } if (jl_typeis(v, jl_linenumbernode_type)) { return fl_cons(julia_to_scm((jl_value_t*)line_sym), fl_cons(julia_to_scm(jl_fieldref(v,0)), FL_NIL)); } if (jl_typeis(v, jl_labelnode_type)) { return fl_cons(julia_to_scm((jl_value_t*)label_sym), fl_cons(julia_to_scm(jl_fieldref(v,0)), FL_NIL)); } if (jl_typeis(v, jl_gotonode_type)) { return fl_cons(julia_to_scm((jl_value_t*)goto_sym), fl_cons(julia_to_scm(jl_fieldref(v,0)), FL_NIL)); } if (jl_typeis(v, jl_quotenode_type)) { return fl_cons(julia_to_scm((jl_value_t*)quote_sym), fl_cons(julia_to_scm(jl_fieldref(v,0)), FL_NIL)); } if (jl_typeis(v, jl_topnode_type)) { return fl_cons(julia_to_scm((jl_value_t*)top_sym), fl_cons(julia_to_scm(jl_fieldref(v,0)), FL_NIL)); } if (jl_is_long(v) && fits_fixnum(jl_unbox_long(v))) { return fixnum(jl_unbox_long(v)); } if (jl_typeis(v,jl_array_any_type)) { return array_to_list((jl_array_t*)v); } value_t opaque = cvalue(jvtype, sizeof(void*)); *(jl_value_t**)cv_data((cvalue_t*)ptr(opaque)) = v; return opaque; }
// copy a :lambda Expr into its LambdaInfo representation static void jl_lambda_info_set_ast(jl_lambda_info_t *li, jl_expr_t *ast) { assert(jl_is_expr(ast)); jl_expr_t *bodyex = (jl_expr_t*)jl_exprarg(ast, 2); assert(jl_is_expr(bodyex)); jl_array_t *body = bodyex->args; li->code = (jl_value_t*)body; jl_gc_wb(li, li->code); if (has_meta(body, pure_sym)) li->pure = 1; jl_array_t *vinfo = (jl_array_t*)jl_exprarg(ast, 1); jl_array_t *vis = (jl_array_t*)jl_array_ptr_ref(vinfo, 0); size_t nslots = jl_array_len(vis); jl_value_t *ssavalue_types = jl_array_ptr_ref(vinfo, 2); assert(jl_is_long(ssavalue_types)); size_t nssavalue = jl_unbox_long(ssavalue_types); li->slotnames = jl_alloc_vec_any(nslots); jl_gc_wb(li, li->slotnames); li->slottypes = jl_nothing; li->slotflags = jl_alloc_array_1d(jl_array_uint8_type, nslots); jl_gc_wb(li, li->slotflags); li->ssavaluetypes = jl_box_long(nssavalue); jl_gc_wb(li, li->ssavaluetypes); int i; for(i=0; i < nslots; i++) { jl_value_t *vi = jl_array_ptr_ref(vis, i); jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(vi, 0); assert(jl_is_symbol(name)); char *str = jl_symbol_name(name); if (i > 0 && name != unused_sym) { if (str[0] == '#') { // convention for renamed variables: #...#original_name char *nxt = strchr(str + 1, '#'); if (nxt) name = jl_symbol(nxt+1); else if (str[1] == 's') // compiler-generated temporaries, #sXXX name = compiler_temp_sym; } } jl_array_ptr_set(li->slotnames, i, name); jl_array_uint8_set(li->slotflags, i, jl_unbox_long(jl_array_ptr_ref(vi, 2))); } jl_array_t *sparams = (jl_array_t*)jl_array_ptr_ref(vinfo, 3); assert(jl_is_array(sparams)); li->sparam_syms = jl_alloc_svec_uninit(jl_array_len(sparams)); jl_gc_wb(li, li->sparam_syms); for(i=0; i < jl_array_len(sparams); i++) { jl_svecset(li->sparam_syms, i, jl_array_ptr_ref(sparams, i)); } jl_array_t *args = (jl_array_t*)jl_exprarg(ast, 0); size_t narg = jl_array_len(args); li->nargs = narg; li->isva = narg > 0 && jl_is_rest_arg(jl_array_ptr_ref(args, narg - 1)); }
static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v) { if (jl_is_symbol(v)) return symbol(fl_ctx, jl_symbol_name((jl_sym_t*)v)); if (v == jl_true) return jl_ast_ctx(fl_ctx)->true_sym; if (v == jl_false) return jl_ast_ctx(fl_ctx)->false_sym; if (v == jl_nothing) return fl_cons(fl_ctx, jl_ast_ctx(fl_ctx)->null_sym, fl_ctx->NIL); if (jl_is_expr(v)) { jl_expr_t *ex = (jl_expr_t*)v; value_t args = fl_ctx->NIL; fl_gc_handle(fl_ctx, &args); array_to_list(fl_ctx, ex->args, &args); value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)ex->head); if (ex->head == lambda_sym && jl_expr_nargs(ex)>0 && jl_is_array(jl_exprarg(ex,0))) { value_t llist = fl_ctx->NIL; fl_gc_handle(fl_ctx, &llist); array_to_list(fl_ctx, (jl_array_t*)jl_exprarg(ex,0), &llist); car_(args) = llist; fl_free_gc_handles(fl_ctx, 1); } value_t scmv = fl_cons(fl_ctx, hd, args); fl_free_gc_handles(fl_ctx, 1); return scmv; } // GC Note: jl_fieldref(v, 0) allocate for LabelNode, GotoNode // but we don't need a GC root here because julia_to_list2 // shouldn't allocate in this case. if (jl_typeis(v, jl_labelnode_type)) return julia_to_list2(fl_ctx, (jl_value_t*)label_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_linenumbernode_type)) return julia_to_list2(fl_ctx, (jl_value_t*)line_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_gotonode_type)) return julia_to_list2(fl_ctx, (jl_value_t*)goto_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_quotenode_type)) return julia_to_list2(fl_ctx, (jl_value_t*)inert_sym, jl_fieldref(v,0)); if (jl_typeis(v, jl_newvarnode_type)) return julia_to_list2(fl_ctx, (jl_value_t*)newvar_sym, jl_fieldref(v,0)); if (jl_is_long(v) && fits_fixnum(jl_unbox_long(v))) return fixnum(jl_unbox_long(v)); if (jl_is_ssavalue(v)) jl_error("SSAValue objects should not occur in an AST"); if (jl_is_slot(v)) jl_error("Slot objects should not occur in an AST"); value_t opaque = cvalue(fl_ctx, jl_ast_ctx(fl_ctx)->jvtype, sizeof(void*)); *(jl_value_t**)cv_data((cvalue_t*)ptr(opaque)) = v; return opaque; }
// Note that this function updates len static jl_value_t *jl_new_bits_internal(jl_value_t *dt, void *data, size_t *len) { if (jl_is_ntuple_type(dt)) { jl_value_t *lenvar = jl_tparam0(dt); jl_value_t *elty = jl_tparam1(dt); assert(jl_is_datatype(elty)); size_t alignment = ((jl_datatype_t*)elty)->alignment; *len = LLT_ALIGN((*len), alignment); assert(jl_is_long(lenvar)); size_t l = jl_unbox_long(lenvar); size_t nb = l*LLT_ALIGN(jl_datatype_size(elty), alignment); jl_value_t *v = (jl_value_t*)newobj(dt, NWORDS(nb)); memcpy(jl_data_ptr(v), data, nb); return v; } assert(jl_is_datatype(dt)); jl_datatype_t *bt = (jl_datatype_t*)dt; size_t nb = jl_datatype_size(bt); if (nb == 0) return jl_new_struct_uninit(bt); *len = LLT_ALIGN(*len, bt->alignment); data = (char*)data + (*len); *len += nb; if (bt == jl_uint8_type) return jl_box_uint8(*(uint8_t*)data); if (bt == jl_int64_type) return jl_box_int64(*(int64_t*)data); if (bt == jl_bool_type) return (*(int8_t*)data) ? jl_true:jl_false; if (bt == jl_int32_type) return jl_box_int32(*(int32_t*)data); if (bt == jl_float64_type) return jl_box_float64(*(double*)data); jl_value_t *v = (jl_value_t*)newobj((jl_value_t*)bt, NWORDS(nb)); switch (nb) { case 1: *(int8_t*) jl_data_ptr(v) = *(int8_t*)data; break; case 2: *(int16_t*) jl_data_ptr(v) = *(int16_t*)data; break; case 4: *(int32_t*) jl_data_ptr(v) = *(int32_t*)data; break; case 8: *(int64_t*) jl_data_ptr(v) = *(int64_t*)data; break; case 16: *(bits128_t*)jl_data_ptr(v) = *(bits128_t*)data; break; default: memcpy(jl_data_ptr(v), data, nb); } return v; }
static size_t array_nd_index(jl_array_t *a, jl_value_t **args, size_t nidxs, const char *fname) { size_t i=0; size_t k, stride=1; size_t nd = jl_array_ndims(a); for(k=0; k < nidxs; k++) { if (!jl_is_long(args[k])) jl_type_error(fname, (jl_value_t*)jl_long_type, args[k]); size_t ii = jl_unbox_long(args[k])-1; i += ii * stride; size_t d = k>=nd ? 1 : jl_array_dim(a, k); if (k < nidxs-1 && ii >= d) jl_bounds_error_v((jl_value_t*)a, args, nidxs); stride *= d; } for(; k < nd; k++) stride *= jl_array_dim(a, k); if (i >= stride) jl_bounds_error_v((jl_value_t*)a, args, nidxs); return i; }
int jl_array_isdefined(jl_value_t **args0, int nargs) { assert(jl_is_array(args0[0])); jl_value_t **depwarn_args; JL_GC_PUSHARGS(depwarn_args, 3); depwarn_args[0] = jl_get_global(jl_base_module, jl_symbol("depwarn")); depwarn_args[1] = jl_cstr_to_string("isdefined(a::Array, i::Int) is deprecated, use isassigned(a, i) instead"); depwarn_args[2] = (jl_value_t*) jl_symbol("isdefined"); jl_apply(depwarn_args, 3); JL_GC_POP(); jl_array_t *a = (jl_array_t*)args0[0]; jl_value_t **args = &args0[1]; size_t nidxs = nargs-1; size_t i=0; size_t k, stride=1; size_t nd = jl_array_ndims(a); for(k=0; k < nidxs; k++) { if (!jl_is_long(args[k])) jl_type_error("isdefined", (jl_value_t*)jl_long_type, args[k]); size_t ii = jl_unbox_long(args[k])-1; i += ii * stride; size_t d = k>=nd ? 1 : jl_array_dim(a, k); if (k < nidxs-1 && ii >= d) return 0; stride *= d; } for(; k < nd; k++) stride *= jl_array_dim(a, k); if (i >= stride) return 0; if (a->flags.ptrarray) return ((jl_value_t**)jl_array_data(a))[i] != NULL; return 1; }
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(¶, &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(¶, &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(¶, &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; }
static jl_value_t *copy_ast(jl_value_t *expr, jl_tuple_t *sp, int do_sp) { if (jl_is_symbol(expr)) { if (!do_sp) return expr; // pre-evaluate certain static parameters to help type inference for(int i=0; i < jl_tuple_len(sp); i+=2) { assert(jl_is_typevar(jl_tupleref(sp,i))); if ((jl_sym_t*)expr == ((jl_tvar_t*)jl_tupleref(sp,i))->name) { jl_value_t *spval = jl_tupleref(sp,i+1); if (jl_is_long(spval)) return spval; } } } else if (jl_is_lambda_info(expr)) { jl_lambda_info_t *li = (jl_lambda_info_t*)expr; /* if (sp == jl_null && li->ast && jl_array_len(jl_lam_capt((jl_expr_t*)li->ast)) == 0) return expr; */ // TODO: avoid if above condition is true and decls have already // been evaluated. JL_GC_PUSH1(&li); li = jl_add_static_parameters(li, sp); // inner lambda does not need the "def" link. it leads to excess object // retention, for example pointing to the original uncompressed AST // of a top-level thunk that gets type inferred. li->def = li; li->ast = jl_prepare_ast(li, li->sparams); JL_GC_POP(); return (jl_value_t*)li; } else if (jl_typeis(expr,jl_array_any_type)) { jl_array_t *a = (jl_array_t*)expr; jl_array_t *na = jl_alloc_cell_1d(jl_array_len(a)); JL_GC_PUSH1(&na); size_t i; for(i=0; i < jl_array_len(a); i++) jl_cellset(na, i, copy_ast(jl_cellref(a,i), sp, do_sp)); JL_GC_POP(); return (jl_value_t*)na; } else if (jl_is_expr(expr)) { jl_expr_t *e = (jl_expr_t*)expr; jl_expr_t *ne = jl_exprn(e->head, jl_array_len(e->args)); JL_GC_PUSH1(&ne); if (e->head == lambda_sym) { jl_exprarg(ne, 0) = copy_ast(jl_exprarg(e,0), sp, 0); jl_exprarg(ne, 1) = copy_ast(jl_exprarg(e,1), sp, 0); jl_exprarg(ne, 2) = copy_ast(jl_exprarg(e,2), sp, 1); } else { for(size_t i=0; i < jl_array_len(e->args); i++) jl_exprarg(ne, i) = copy_ast(jl_exprarg(e,i), sp, 1); } JL_GC_POP(); return (jl_value_t*)ne; } return expr; }
static int jl_source_nssavalues(jl_code_info_t *src) { return jl_is_long(src->ssavaluetypes) ? jl_unbox_long(src->ssavaluetypes) : jl_array_len(src->ssavaluetypes); }
// copy a :lambda Expr into its LambdaInfo representation static void jl_lambda_info_set_ast(jl_lambda_info_t *li, jl_expr_t *ast) { assert(jl_is_expr(ast)); jl_expr_t *bodyex = (jl_expr_t*)jl_exprarg(ast, 2); assert(jl_is_expr(bodyex)); jl_array_t *body = bodyex->args; li->code = (jl_value_t*)body; jl_gc_wb(li, li->code); size_t j, n = jl_array_len(body); jl_value_t **bd = (jl_value_t**)jl_array_data((jl_array_t*)li->code); for(j=0; j < n; j++) { jl_value_t *st = bd[j]; if (jl_is_expr(st) && ((jl_expr_t*)st)->head == meta_sym) { size_t k, ins = 0, na = jl_expr_nargs(st); jl_array_t *meta = ((jl_expr_t*)st)->args; for(k=0; k < na; k++) { jl_value_t *ma = jl_array_ptr_ref(meta, k); if (ma == (jl_value_t*)pure_sym) li->pure = 1; else if (ma == (jl_value_t*)inline_sym) li->inlineable = 1; else jl_array_ptr_set(meta, ins++, ma); } if (ins == 0) bd[j] = jl_nothing; else jl_array_del_end(meta, na-ins); } } jl_array_t *vinfo = (jl_array_t*)jl_exprarg(ast, 1); jl_array_t *vis = (jl_array_t*)jl_array_ptr_ref(vinfo, 0); size_t nslots = jl_array_len(vis); jl_value_t *ssavalue_types = jl_array_ptr_ref(vinfo, 2); assert(jl_is_long(ssavalue_types)); size_t nssavalue = jl_unbox_long(ssavalue_types); li->slotnames = jl_alloc_vec_any(nslots); jl_gc_wb(li, li->slotnames); li->slottypes = jl_nothing; li->slotflags = jl_alloc_array_1d(jl_array_uint8_type, nslots); jl_gc_wb(li, li->slotflags); li->ssavaluetypes = jl_box_long(nssavalue); jl_gc_wb(li, li->ssavaluetypes); int i; for(i=0; i < nslots; i++) { jl_value_t *vi = jl_array_ptr_ref(vis, i); jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(vi, 0); assert(jl_is_symbol(name)); char *str = jl_symbol_name(name); if (i > 0 && name != unused_sym) { if (str[0] == '#') { // convention for renamed variables: #...#original_name char *nxt = strchr(str + 1, '#'); if (nxt) name = jl_symbol(nxt+1); else if (str[1] == 's') // compiler-generated temporaries, #sXXX name = compiler_temp_sym; } } jl_array_ptr_set(li->slotnames, i, name); jl_array_uint8_set(li->slotflags, i, jl_unbox_long(jl_array_ptr_ref(vi, 2))); } jl_array_t *sparams = (jl_array_t*)jl_array_ptr_ref(vinfo, 3); assert(jl_is_array(sparams)); li->sparam_syms = jl_alloc_svec_uninit(jl_array_len(sparams)); jl_gc_wb(li, li->sparam_syms); for(i=0; i < jl_array_len(sparams); i++) { jl_svecset(li->sparam_syms, i, jl_array_ptr_ref(sparams, i)); } jl_array_t *args = (jl_array_t*)jl_exprarg(ast, 0); size_t narg = jl_array_len(args); li->nargs = narg; li->isva = narg > 0 && jl_is_rest_arg(jl_array_ptr_ref(args, narg - 1)); }
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_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_errorf("%s not defined", s->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); size_t nargs = jl_array_len(ex->args); 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], nargs-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_value_t *v=NULL; JL_GC_PUSH(&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)); } 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; jl_value_t *gf=NULL; int kw=0; if (jl_is_expr(fname)) { if (((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); assert(jl_is_function(gf)); assert(jl_is_gf(gf)); if (!kw) { fname = (jl_sym_t*)jl_fieldref(jl_exprarg(fname, 2), 0); bp = &gf; } else { bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter; } 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; } } 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 *bp; } 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 < 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); jl_value_t *super = NULL; JL_GC_PUSH(¶, &super); jl_datatype_t *dt = jl_new_abstracttype(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*)dt); super = eval(args[2], locals, nl); jl_set_datatype_super(dt, 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(¶, &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_datatype_t *dt = jl_new_bitstype(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*)dt); super = eval(args[3], locals, nl); jl_set_datatype_super(dt, super); JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == compositetype_sym) { void jl_add_constructors(jl_datatype_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_datatype_t *dt = NULL; JL_GC_PUSH(¶, &super, &fnames, &dt); fnames = eval(args[2], locals, nl); dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para, (jl_tuple_t*)fnames, NULL, 0, args[6]==jl_true ? 1 : 0); dt->fptr = jl_f_ctor_trampoline; dt->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*)dt); inside_typedef = 1; dt->types = (jl_tuple_t*)eval(args[5], locals, nl); inside_typedef = 0; jl_check_type_tuple(dt->types, dt->name->name, "type definition"); super = eval(args[4], locals, nl); jl_set_datatype_super(dt, super); jl_compute_field_offsets(dt); jl_add_constructors(dt); 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: %s", jl_string_data(args[0])); jl_throw(args[0]); } jl_errorf("unsupported or misplaced expression %s", ex->head->name); return (jl_value_t*)jl_nothing; }
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); } 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(jl_current_module, fname); if (b == NULL) { // if no existing binding for this, make a new one b = jl_get_binding_wr(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(¶, &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(¶, &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(¶, &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_expander(jl_current_module, nm, f); return (jl_value_t*)jl_nothing; } 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]); } else if (ex->head == line_sym) { return (jl_value_t*)jl_nothing; } else if (ex->head == multivalue_sym) { return (jl_value_t*)jl_nothing; } jl_errorf("unsupported or misplaced expression %s", ex->head->name); return (jl_value_t*)jl_nothing; }