int jl_egal(jl_value_t *a, jl_value_t *b) { if (a == b) return 1; jl_value_t *ta = (jl_value_t*)jl_typeof(a); if (ta != (jl_value_t*)jl_typeof(b)) return 0; if (jl_is_bits_type(ta)) { size_t nb = jl_bitstype_nbits(ta)/8; switch (nb) { case 1: return *(int8_t*)jl_bits_data(a) == *(int8_t*)jl_bits_data(b); case 2: return *(int16_t*)jl_bits_data(a) == *(int16_t*)jl_bits_data(b); case 4: return *(int32_t*)jl_bits_data(a) == *(int32_t*)jl_bits_data(b); case 8: return *(int64_t*)jl_bits_data(a) == *(int64_t*)jl_bits_data(b); default: return memcmp(jl_bits_data(a), jl_bits_data(b), nb)==0; } } if (jl_is_tuple(a)) { size_t l = jl_tuple_len(a); if (l != jl_tuple_len(b)) return 0; for(size_t i=0; i < l; i++) { if (!jl_egal(jl_tupleref(a,i),jl_tupleref(b,i))) return 0; } return 1; } return 0; }
jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_binding_t *bnd, jl_tuple_t *argtypes, jl_function_t *f, jl_tuple_t *t) { jl_value_t *gf; if (bnd) { //jl_declare_constant(bnd); if (bnd->value != NULL && !bnd->constp) { jl_errorf("cannot define function %s; it already has a value", bnd->name->name); } bnd->constp = 1; } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name); *bp = gf; } else { gf = *bp; if (!jl_is_gf(gf)) { if (jl_is_datatype(gf) && ((jl_function_t*)gf)->fptr == jl_f_ctor_trampoline) { jl_add_constructors((jl_datatype_t*)gf); } if (!jl_is_gf(gf)) { jl_error("invalid method definition: not a generic function"); } } } JL_GC_PUSH1(&gf); assert(jl_is_function(f)); assert(jl_is_tuple(argtypes)); assert(jl_is_tuple(t)); for(size_t i=0; i < jl_tuple_len(argtypes); i++) { jl_value_t *elt = jl_tupleref(argtypes,i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) { jl_lambda_info_t *li = f->linfo; jl_errorf("invalid type for argument %s in method definition for %s at %s:%d", jl_is_expr(li->ast) ? ((jl_sym_t*)jl_arrayref(jl_lam_args((jl_expr_t*)li->ast),i))->name : "?", name->name, li->file->name, li->line); } } for(size_t i=0; i < jl_tuple_len(t); i++) { if (!jl_is_typevar(jl_tupleref(t,i))) jl_type_error_rt(name->name, "method definition", (jl_value_t*)jl_tvar_type, jl_tupleref(t,i)); } jl_add_method((jl_function_t*)gf, argtypes, f, t); 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); } JL_GC_POP(); return gf; }
static jl_value_t *expr_type(jl_value_t *e, jl_codectx_t *ctx) { if (jl_is_expr(e)) return ((jl_expr_t*)e)->etype; if (jl_is_symbolnode(e)) return jl_symbolnode_type(e); if (jl_is_quotenode(e)) return (jl_value_t*)jl_typeof(jl_fieldref(e,0)); if (jl_is_lambda_info(e)) return (jl_value_t*)jl_function_type; if (jl_is_getfieldnode(e)) { jl_value_t *v = static_eval(e, ctx); if (v == NULL) return jl_getfieldnode_type(e); e = v; goto type_of_constant; } if (jl_is_topnode(e)) { e = jl_fieldref(e,0); jl_binding_t *b = jl_get_binding(topmod(ctx), (jl_sym_t*)e); if (!b || !b->value) return jl_top_type; if (b->constp) { e = b->value; goto type_of_constant; } else { return (jl_value_t*)jl_any_type; } } if (jl_is_symbol(e)) { if (jl_is_symbol(e)) { if (is_global((jl_sym_t*)e, ctx)) { // look for static parameter for(size_t i=0; i < jl_tuple_len(ctx->sp); i+=2) { assert(jl_is_symbol(jl_tupleref(ctx->sp, i))); if (e == jl_tupleref(ctx->sp, i)) { e = jl_tupleref(ctx->sp, i+1); goto type_of_constant; } } } else { return (jl_value_t*)jl_any_type; } } jl_binding_t *b = jl_get_binding(ctx->module, (jl_sym_t*)e); if (!b || !b->value) return jl_top_type; if (b->constp) e = b->value; else return (jl_value_t*)jl_any_type; } type_of_constant: if (jl_is_some_tag_type(e)) return (jl_value_t*)jl_wrap_Type(e); return (jl_value_t*)jl_typeof(e); }
DLLEXPORT jl_value_t *jl_closure_env(jl_function_t *f) { if (jl_is_tuple(f->env) && ((jl_tuple_t*)f->env)->length==2 && jl_tupleref(f->env,0) == (jl_value_t*)f) return jl_tupleref(f->env,1); return f->env; }
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 jl_function_t *jl_mt_assoc_by_type(jl_methtable_t *mt, jl_tuple_t *tt, int cache) { jl_methlist_t *m = mt->defs; size_t nargs = tt->length; size_t i; jl_value_t *env = jl_false; while (m != NULL) { if (m->tvars!=jl_null) { env = jl_type_match((jl_value_t*)tt, (jl_value_t*)m->sig); if (env != (jl_value_t*)jl_false) break; } else if (jl_tuple_subtype(&jl_tupleref(tt,0), nargs, &jl_tupleref(m->sig,0), ((jl_tuple_t*)m->sig)->length, 0, 0)) { break; } m = m->next; } if (env == (jl_value_t*)jl_false) { if (m != NULL) { if (!cache) { return m->func; } return cache_method(mt, tt, m->func, (jl_tuple_t*)m->sig, jl_null); } return NULL; } jl_tuple_t *newsig=NULL; JL_GC_PUSH(&env, &newsig); assert(jl_is_tuple(env)); jl_tuple_t *tpenv = (jl_tuple_t*)env; // don't bother computing this if no arguments are tuples for(i=0; i < tt->length; i++) { if (jl_is_tuple(jl_tupleref(tt,i))) break; } if (i < tt->length) { newsig = (jl_tuple_t*)jl_instantiate_type_with((jl_type_t*)m->sig, &jl_tupleref(tpenv,0), tpenv->length/2); } else { newsig = (jl_tuple_t*)m->sig; } assert(jl_is_tuple(newsig)); jl_function_t *nf; if (!cache) nf = m->func; else nf = cache_method(mt, tt, m->func, newsig, tpenv); JL_GC_POP(); return nf; }
jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data, jl_tuple_t *dims) { size_t i; jl_array_t *a; size_t ndims = jl_tuple_len(dims); int ndimwords = jl_array_ndimwords(ndims); a = allocobj((sizeof(jl_array_t) + sizeof(void*) + ndimwords*sizeof(size_t) + 15)&-16); a->type = atype; a->ndims = ndims; a->offset = 0; a->data = NULL; a->isaligned = data->isaligned; jl_value_t *el_type = jl_tparam0(atype); if (store_unboxed(el_type)) { a->elsize = jl_datatype_size(el_type); a->ptrarray = 0; } else { a->elsize = sizeof(void*); a->ptrarray = 1; } JL_GC_PUSH1(&a); jl_array_data_owner(a) = (jl_value_t*)data; a->how = 3; a->data = data->data; a->isshared = 1; data->isshared = 1; if (ndims == 1) { size_t l = jl_unbox_long(jl_tupleref(dims,0)); #ifdef STORE_ARRAY_LEN a->length = l; #endif a->nrows = l; a->maxsize = l; } else { size_t *adims = &a->nrows; size_t l=1; wideint_t prod; for(i=0; i < ndims; i++) { adims[i] = jl_unbox_long(jl_tupleref(dims, i)); prod = (wideint_t)l * (wideint_t)adims[i]; if (prod > (wideint_t) MAXINTVAL) jl_error("invalid Array dimensions"); l = prod; } #ifdef STORE_ARRAY_LEN a->length = l; #endif } JL_GC_POP(); return a; }
jl_array_t *jl_ptr_to_array(jl_type_t *atype, void *data, jl_tuple_t *dims, int julia_mallocated) { size_t i, elsz, nel=1; jl_array_t *a; size_t ndims = jl_tuple_len(dims); for(i=0; i < ndims; i++) { nel *= jl_unbox_long(jl_tupleref(dims, i)); } jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype); int isunboxed = jl_is_bits_type(el_type); if (isunboxed) elsz = jl_bitstype_nbits(el_type)/8; else elsz = sizeof(void*); int ndimwords = (ndims > 2 ? (ndims-2) : 0); #ifndef __LP64__ // on 32-bit, ndimwords must be odd to preserve 8-byte alignment ndimwords += (~ndimwords)&1; #endif a = allocobj(sizeof(jl_array_t) + ndimwords*sizeof(size_t)); a->type = atype; a->data = data; a->length = nel; a->elsize = elsz; a->ptrarray = !isunboxed; a->ndims = ndims; if (julia_mallocated) { a->reshaped = 0; jl_gc_acquire_buffer(data); } else { // this marks the array as not owning its buffer a->reshaped = 1; *((jl_array_t**)(&a->_space[0] + ndimwords*sizeof(size_t))) = a; } if (ndims == 1) { a->nrows = a->length; a->maxsize = a->length; a->offset = 0; } else { size_t *adims = &a->nrows; for(i=0; i < ndims; i++) { adims[i] = jl_unbox_long(jl_tupleref(dims, i)); } } return a; }
jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data, jl_tuple_t *dims, int own_buffer) { size_t i, elsz, nel=1; jl_array_t *a; size_t ndims = jl_tuple_len(dims); wideint_t prod; for(i=0; i < ndims; i++) { prod = (wideint_t)nel * (wideint_t)jl_unbox_long(jl_tupleref(dims, i)); if (prod > (wideint_t) MAXINTVAL) jl_error("invalid Array dimensions"); nel = prod; } jl_value_t *el_type = jl_tparam0(atype); int isunboxed = store_unboxed(el_type); if (isunboxed) elsz = jl_datatype_size(el_type); else elsz = sizeof(void*); int ndimwords = jl_array_ndimwords(ndims); a = allocobj((sizeof(jl_array_t) + ndimwords*sizeof(size_t)+15)&-16); a->type = atype; a->data = data; #ifdef STORE_ARRAY_LEN a->length = nel; #endif a->elsize = elsz; a->ptrarray = !isunboxed; a->ndims = ndims; a->offset = 0; a->isshared = 1; a->isaligned = 0; if (own_buffer) { a->how = 2; jl_gc_track_malloced_array(a); } else { a->how = 0; } if (ndims == 1) { a->nrows = nel; a->maxsize = nel; } else { size_t *adims = &a->nrows; for(i=0; i < ndims; i++) { adims[i] = jl_unbox_long(jl_tupleref(dims, i)); } } return a; }
static jl_function_t *jl_method_table_assoc_exact(jl_methtable_t *mt, jl_value_t **args, size_t n) { jl_methlist_t *ml = NULL; if (n > 0) { jl_value_t *a0 = args[0]; jl_value_t *ty = (jl_value_t*)jl_typeof(a0); uptrint_t uid; if ((ty == (jl_value_t*)jl_struct_kind && (uid = ((jl_struct_type_t*)a0)->uid)) || (ty == (jl_value_t*)jl_bits_kind && (uid = ((jl_bits_type_t*)a0)->uid))) { if (mt->cache_targ && uid < jl_array_len(mt->cache_targ)) { ml = (jl_methlist_t*)jl_cellref(mt->cache_targ, uid); if (ml) goto mt_assoc_lkup; } } if ((jl_is_struct_type(ty) && (uid = ((jl_struct_type_t*)ty)->uid)) || (jl_is_bits_type(ty) && (uid = ((jl_bits_type_t*)ty)->uid))) { if (mt->cache_arg1 && uid < jl_array_len(mt->cache_arg1)) { ml = (jl_methlist_t*)jl_cellref(mt->cache_arg1, uid); if (ml) { if (ml->next==NULL && n==1 && ml->sig->length==1) return ml->func; if (n==2) { // some manually-unrolled common special cases jl_value_t *a1 = args[1]; jl_methlist_t *mn = ml; if (mn->sig->length==2 && jl_tupleref(mn->sig,1)==(jl_value_t*)jl_typeof(a1)) return mn->func; mn = mn->next; if (mn && mn->sig->length==2 && jl_tupleref(mn->sig,1)==(jl_value_t*)jl_typeof(a1)) return mn->func; } } } } } if (ml == NULL) ml = mt->cache; mt_assoc_lkup: while (ml != NULL) { if (((jl_tuple_t*)ml->sig)->length == n || ml->va==jl_true) { if (cache_match(args, n, (jl_tuple_t*)ml->sig, ml->va==jl_true)) { return ml->func; } } ml = ml->next; } return NULL; }
jl_tuple_t *jl_tuple_tvars_to_symbols(jl_tuple_t *t) { jl_tuple_t *s = jl_alloc_tuple_uninit(jl_tuple_len(t)); size_t i; for(i=0; i < jl_tuple_len(s); i+=2) { assert(jl_is_typevar(jl_tupleref(t,i))); jl_tupleset(s, i, (jl_value_t*)((jl_tvar_t*)jl_tupleref(t,i))->name); jl_tupleset(s, i+1, jl_tupleref(t,i+1)); } return s; }
void jl_add_constructors(jl_datatype_t *t) { if (t->name == jl_array_typename) { t->fptr = jl_f_no_function; return; } jl_initialize_generic_function((jl_function_t*)t, t->name->name); if (t->name->ctor_factory == (jl_value_t*)jl_nothing || t->name->ctor_factory == (jl_value_t*)jl_null) { } else { assert(jl_tuple_len(t->parameters) > 0); if (t == (jl_datatype_t*)t->name->primary) return; jl_function_t *cfactory = NULL; jl_tuple_t *env = NULL; JL_GC_PUSH2(&cfactory, &env); if (jl_compileropts.compile_enabled) { // instantiating assert(jl_is_function(t->name->ctor_factory)); // add type's static parameters to the ctor factory size_t np = jl_tuple_len(t->parameters); env = jl_alloc_tuple_uninit(np*2); for(size_t i=0; i < np; i++) { jl_tupleset(env, i*2+0, jl_tupleref(((jl_datatype_t*)t->name->primary)->parameters, i)); jl_tupleset(env, i*2+1, jl_tupleref(t->parameters, i)); } cfactory = jl_instantiate_method((jl_function_t*)t->name->ctor_factory, env); cfactory->linfo->ast = jl_prepare_ast(cfactory->linfo, cfactory->linfo->sparams); } else { cfactory = ((jl_datatype_t*)t)->name->static_ctor_factory; if (cfactory == NULL) { JL_PRINTF(JL_STDERR,"code missing for type %s\n", t->name->name); exit(1); } // in generically-compiled case, pass static parameters via closure // environment. env = jl_tuple_append((jl_tuple_t*)cfactory->env, t->parameters); cfactory = jl_new_closure(cfactory->fptr, (jl_value_t*)env, cfactory->linfo); } // call user-defined constructor factory on (type,) jl_value_t *cfargs[1] = { (jl_value_t*)t }; jl_apply(cfactory, cfargs, 1); JL_GC_POP(); } }
jl_tuple_t *jl_tuple_append(jl_tuple_t *a, jl_tuple_t *b) { jl_tuple_t *c = jl_alloc_tuple_uninit(a->length + b->length); size_t i=0, j; for(j=0; j < a->length; j++) { jl_tupleset(c, i, jl_tupleref(a,j)); i++; } for(j=0; j < b->length; j++) { jl_tupleset(c, i, jl_tupleref(b,j)); i++; } return c; }
jl_array_t *jl_ptr_to_array(jl_type_t *atype, void *data, jl_tuple_t *dims, int own_buffer) { size_t i, elsz, nel=1; jl_array_t *a; size_t ndims = jl_tuple_len(dims); for(i=0; i < ndims; i++) { nel *= jl_unbox_long(jl_tupleref(dims, i)); } jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype); int isunboxed = jl_is_bits_type(el_type); if (isunboxed) elsz = jl_bitstype_nbits(el_type)/8; else elsz = sizeof(void*); int ndimwords = jl_array_ndimwords(ndims); a = allocobj((sizeof(jl_array_t) + ndimwords*sizeof(size_t)+15)&-16); a->type = atype; a->data = data; a->length = nel; a->elsize = elsz; a->ptrarray = !isunboxed; a->ndims = ndims; if (own_buffer) { a->ismalloc = 1; jl_array_data_owner(a) = (jl_value_t*)jl_gc_acquire_buffer(data,nel*elsz); } else { a->ismalloc = 0; jl_array_data_owner(a) = (jl_value_t*)a; } if (ndims == 1) { a->nrows = a->length; a->maxsize = a->length; a->offset = 0; } else { size_t *adims = &a->nrows; for(i=0; i < ndims; i++) { adims[i] = jl_unbox_long(jl_tupleref(dims, i)); } } return a; }
jl_tuple_t *jl_tuple_append(jl_tuple_t *a, jl_tuple_t *b) { jl_tuple_t *c = jl_alloc_tuple_uninit(jl_tuple_len(a) + jl_tuple_len(b)); size_t i=0, j; for(j=0; j < jl_tuple_len(a); j++) { jl_tupleset(c, i, jl_tupleref(a,j)); i++; } for(j=0; j < jl_tuple_len(b); j++) { jl_tupleset(c, i, jl_tupleref(b,j)); i++; } return c; }
static jl_value_t *nth_slot_type(jl_tuple_t *sig, size_t i) { size_t len = sig->length; if (len == 0) return NULL; if (i < len-1) return jl_tupleref(sig, i); if (jl_is_seq_type(jl_tupleref(sig,len-1))) { return jl_tparam0(jl_tupleref(sig,len-1)); } if (i == len-1) return jl_tupleref(sig, i); return NULL; }
int jl_egal(jl_value_t *a, jl_value_t *b) { if (a == b) return 1; jl_value_t *ta = (jl_value_t*)jl_typeof(a); if (ta != (jl_value_t*)jl_typeof(b)) return 0; if (jl_is_tuple(a)) { size_t l = jl_tuple_len(a); if (l != jl_tuple_len(b)) return 0; for(size_t i=0; i < l; i++) { if (!jl_egal(jl_tupleref(a,i),jl_tupleref(b,i))) return 0; } return 1; } jl_datatype_t *dt = (jl_datatype_t*)ta; if (dt == jl_datatype_type) { jl_datatype_t *dta = (jl_datatype_t*)a; jl_datatype_t *dtb = (jl_datatype_t*)b; return dta->name == dtb->name && jl_egal((jl_value_t*)dta->parameters, (jl_value_t*)dtb->parameters); } if (dt->mutabl) return 0; size_t sz = dt->size; if (sz == 0) return 1; size_t nf = jl_tuple_len(dt->names); if (nf == 0) { return bits_equal(jl_data_ptr(a), jl_data_ptr(b), sz); } for (size_t f=0; f < nf; f++) { size_t offs = dt->fields[f].offset; char *ao = (char*)jl_data_ptr(a) + offs; char *bo = (char*)jl_data_ptr(b) + offs; int eq; if (dt->fields[f].isptr) { jl_value_t *af = *(jl_value_t**)ao; jl_value_t *bf = *(jl_value_t**)bo; if (af == bf) eq = 1; else if (af==NULL || bf==NULL) eq = 0; else eq = jl_egal(af, bf); } else { eq = bits_equal(ao, bo, dt->fields[f].size); } if (!eq) return 0; } return 1; }
void jl_check_static_parameter_conflicts(jl_lambda_info_t *li, jl_tuple_t *t, jl_sym_t *fname) { jl_array_t *vinfo; size_t nvars; if (li->ast && jl_is_expr(li->ast)) { vinfo = jl_lam_vinfo((jl_expr_t*)li->ast); nvars = jl_array_len(vinfo); for(size_t i=0; i < jl_tuple_len(t); i++) { for(size_t j=0; j < nvars; j++) { jl_value_t *tv = jl_tupleref(t,i); if (jl_is_typevar(tv)) { if ((jl_sym_t*)jl_arrayref((jl_array_t*)jl_arrayref(vinfo,j),0) == ((jl_tvar_t*)tv)->name) { JL_PRINTF(JL_STDERR, "Warning: local variable %s conflicts with a static parameter in %s", ((jl_tvar_t*)tv)->name->name, fname->name); print_func_loc(JL_STDERR, li); JL_PRINTF(JL_STDERR, ".\n"); } } } } } }
void jl_compute_struct_offsets(jl_struct_type_t *st) { size_t sz = 0, alignm = 0; for(size_t i=0; i < st->types->length; i++) { jl_value_t *ty = jl_tupleref(st->types, i); size_t fsz, al; if (jl_is_bits_type(ty)) { fsz = jl_bitstype_nbits(ty)/8; al = fsz; // alignment == size for bits types st->fields[i].isptr = 0; } else { fsz = sizeof(void*); al = fsz; st->fields[i].isptr = 1; } sz = LLT_ALIGN(sz, al); if (al > alignm) alignm = al; st->fields[i].offset = sz; st->fields[i].size = fsz; sz += fsz; } st->alignment = alignm; st->size = LLT_ALIGN(sz, alignm); }
void jl_type_infer(jl_lambda_info_t *li, jl_tuple_t *argtypes, jl_lambda_info_t *def) { int last_ii = jl_in_inference; jl_in_inference = 1; if (jl_typeinf_func != NULL) { // TODO: this should be done right before code gen, so if it is // interrupted we can try again the next time the function is // called assert(li->inInference == 0); li->inInference = 1; jl_value_t *fargs[4]; fargs[0] = (jl_value_t*)li; fargs[1] = (jl_value_t*)argtypes; fargs[2] = (jl_value_t*)jl_null; fargs[3] = (jl_value_t*)def; #ifdef TRACE_INFERENCE ios_printf(ios_stderr,"inference on %s(", li->name->name); print_sig(argtypes); ios_printf(ios_stderr, ")\n"); #endif #ifdef ENABLE_INFERENCE jl_value_t *newast = jl_apply(jl_typeinf_func, fargs, 4); li->ast = jl_tupleref(newast, 0); li->inferred = jl_true; #endif li->inInference = 0; } jl_in_inference = last_ii; }
static Type *julia_struct_to_llvm(jl_value_t *jt) { if (jl_is_structtype(jt) && !jl_is_array_type(jt)) { if (!jl_is_leaf_type(jt)) return NULL; jl_datatype_t *jst = (jl_datatype_t*)jt; if (jst->struct_decl == NULL) { size_t ntypes = jl_tuple_len(jst->types); if (ntypes == 0) return NULL; std::vector<Type *> latypes(0); size_t i; for(i = 0; i < ntypes; i++) { jl_value_t *ty = jl_tupleref(jst->types, i); Type *lty = ty==(jl_value_t*)jl_bool_type ? T_int8 : julia_type_to_llvm(ty); if (jst->fields[i].isptr) lty = jl_pvalue_llvmt; latypes.push_back(lty); } jst->struct_decl = (void*)StructType::create(latypes, jst->name->name->name); } return (Type*)jst->struct_decl; } return julia_type_to_llvm(jt); }
jl_array_t *jl_reshape_array(jl_type_t *atype, jl_array_t *data, jl_tuple_t *dims) { size_t i; jl_array_t *a; size_t ndims = dims->length; int ndimwords = (ndims > 2 ? (ndims-2) : 0); #ifndef __LP64__ // on 32-bit, ndimwords must be odd to preserve 8-byte alignment ndimwords += (~ndimwords)&1; #endif a = allocobj(sizeof(jl_array_t) + ndimwords*sizeof(size_t)); a->type = atype; *((jl_array_t**)(&a->_space[0] + ndimwords*sizeof(size_t))) = data; a->data = data->data; a->length = data->length; a->elsize = data->elsize; a->ndims = ndims; a->reshaped = 1; if (ndims == 1) { a->nrows = a->length; a->maxsize = a->length; a->offset = 0; } else { size_t *adims = &a->nrows; for(i=0; i < ndims; i++) { adims[i] = jl_unbox_long(jl_tupleref(dims, i)); } } return a; }
void jl_compute_field_offsets(jl_datatype_t *st) { size_t sz = 0, alignm = 0; int ptrfree = 1; for(size_t i=0; i < jl_tuple_len(st->types); i++) { jl_value_t *ty = jl_tupleref(st->types, i); size_t fsz, al; if (jl_isbits(ty) && (al=((jl_datatype_t*)ty)->alignment)!=0) { fsz = jl_datatype_size(ty); st->fields[i].isptr = 0; } else { fsz = sizeof(void*); al = fsz; st->fields[i].isptr = 1; ptrfree = 0; } sz = LLT_ALIGN(sz, al); if (al > alignm) alignm = al; st->fields[i].offset = sz; st->fields[i].size = fsz; sz += fsz; } st->alignment = alignm; st->size = LLT_ALIGN(sz, alignm); st->pointerfree = ptrfree && !st->abstract; }
DLLEXPORT jl_value_t *jl_new_structt(jl_struct_type_t *type, jl_tuple_t *t) { assert(jl_tuple_len(type->names) == jl_tuple_len(t)); jl_value_t *jv = jl_new_struct_uninit(type); for(size_t i=0; i < jl_tuple_len(t); i++) { ((jl_value_t**)jv)[i+1] = jl_tupleref(t, i); } return jv; }
static int all_typevars(jl_tuple_t *p) { size_t i; for(i=0; i < p->length; i++) { if (!jl_is_typevar(jl_tupleref(p,i))) return 0; } return 1; }
jl_array_t *jl_new_array(jl_type_t *atype, jl_tuple_t *dims) { size_t ndims = jl_tuple_len(dims); size_t *adims = alloca(ndims*sizeof(size_t)); size_t i; for(i=0; i < ndims; i++) adims[i] = jl_unbox_long(jl_tupleref(dims,i)); return _new_array(atype, ndims, adims); }
DLLEXPORT jl_value_t *jl_new_structt(jl_struct_type_t *type, jl_tuple_t *t) { assert(jl_tuple_len(type->names) == jl_tuple_len(t)); jl_value_t *jv = jl_new_struct_uninit(type); for(size_t i=0; i < jl_tuple_len(t); i++) { jl_set_nth_field(jv, i, jl_tupleref(t, i)); } return jv; }
static int tuple_all_Any(jl_tuple_t *t) { int i; for(i=0; i < t->length; i++) { if (jl_tupleref(t,i) != (jl_value_t*)jl_any_type) return 0; } return 1; }
jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i) { jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v); size_t offs = jl_field_offset(st,i) + sizeof(void*); if (st->fields[i].isptr) { return *(jl_value_t**)((char*)v + offs); } return jl_new_bits(jl_tupleref(st->types,i), (char*)v + offs); }
void jl_check_type_tuple(jl_tuple_t *t, jl_sym_t *name, const char *ctx) { for(size_t i=0; i < jl_tuple_len(t); i++) { jl_value_t *elt = jl_tupleref(t,i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) { jl_type_error_rt(name->name, ctx, (jl_value_t*)jl_type_type, elt); } } }