jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i) { jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v); if (i >= jl_tuple_len(st->names)) jl_throw(jl_bounds_exception); size_t offs = jl_field_offset(st,i) + sizeof(void*); if (st->fields[i].isptr) { jl_value_t *fval = *(jl_value_t**)((char*)v + offs); if (fval == NULL) jl_throw(jl_undefref_exception); return fval; } return jl_new_bits(jl_tupleref(st->types,i), (char*)v + offs); }
void jl_arrayset(jl_array_t *a, jl_value_t *rhs, size_t i) { jl_value_t *el_type = jl_tparam0(jl_typeof(a)); if (el_type != (jl_value_t*)jl_any_type) { if (!jl_subtype(rhs, el_type, 1)) jl_type_error("arrayset", el_type, rhs); } if (!a->ptrarray) { jl_assign_bits(&((char*)a->data)[i*a->elsize], rhs); } else { ((jl_value_t**)a->data)[i] = rhs; } }
JL_DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i) { jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v); if (i >= jl_datatype_nfields(st)) jl_bounds_error_int(v, i+1); size_t offs = jl_field_offset(st,i); if (jl_field_isptr(st,i)) { jl_value_t *fval = *(jl_value_t**)((char*)v + offs); if (fval == NULL) jl_throw(jl_undefref_exception); return fval; } return jl_new_bits(jl_field_type(st,i), (char*)v + offs); }
JL_DLLEXPORT jl_value_t *jl_powi_llvm(jl_value_t *a, jl_value_t *b) { jl_value_t *ty = jl_typeof(a); if (!jl_is_bitstype(ty)) jl_error("powi_llvm: a is not a bitstype"); if (!jl_is_bitstype(jl_typeof(b)) || jl_datatype_size(jl_typeof(b)) != 4) jl_error("powi_llvm: b is not a 32-bit bitstype"); jl_value_t *newv = newstruct((jl_datatype_t*)ty); void *pa = jl_data_ptr(a), *pr = jl_data_ptr(newv); int sz = jl_datatype_size(ty); switch (sz) { /* choose the right size c-type operation */ case 4: *(float*)pr = powf(*(float*)pa, (float)jl_unbox_int32(b)); break; case 8: *(double*)pr = pow(*(double*)pa, (double)jl_unbox_int32(b)); break; default: jl_error("powi_llvm: runtime floating point intrinsics are not implemented for bit sizes other than 32 and 64"); } return newv; }
static inline jl_value_t *jl_fintrinsic_1(jl_value_t *ty, jl_value_t *a, const char *name, fintrinsic_op1 *floatop, fintrinsic_op1 *doubleop) { if (!jl_is_bitstype(jl_typeof(a))) jl_errorf("%s: value is not a bitstype", name); if (!jl_is_bitstype(ty)) jl_errorf("%s: type is not a bitstype", name); jl_value_t *newv = newstruct((jl_datatype_t*)ty); void *pa = jl_data_ptr(a), *pr = jl_data_ptr(newv); unsigned sz = jl_datatype_size(jl_typeof(a)); unsigned sz2 = jl_datatype_size(ty); switch (sz) { /* choose the right size c-type operation based on the input */ case 4: floatop(sz2 * host_char_bit, pa, pr); break; case 8: doubleop(sz2 * host_char_bit, pa, pr); break; default: jl_errorf("%s: runtime floating point intrinsics are not implemented for bit sizes other than 32 and 64", name); } return newv; }
static inline jl_value_t *jl_iintrinsic_2(jl_value_t *a, jl_value_t *b, const char *name, char (*getsign)(void*, unsigned), jl_value_t *(*lambda2)(jl_value_t*, void*, void*, unsigned, unsigned, const void*), const void *list, int cvtb) { jl_value_t *ty = jl_typeof(a); jl_value_t *tyb = jl_typeof(b); if (tyb != ty) { if (!cvtb) jl_errorf("%s: types of a and b must match", name); if (!jl_is_bitstype(tyb)) jl_errorf("%s: b is not a bitstypes", name); } if (!jl_is_bitstype(ty)) jl_errorf("%s: a is not a bitstypes", name); void *pa = jl_data_ptr(a), *pb = jl_data_ptr(b); unsigned sz = jl_datatype_size(ty); unsigned sz2 = next_power_of_two(sz); unsigned szb = jl_datatype_size(tyb); if (sz2 > sz) { /* round type up to the appropriate c-type and set/clear the unused bits */ void *pa2 = alloca(sz2); memcpy(pa2, pa, sz); memset((char*)pa2 + sz, getsign(pa, sz), sz2 - sz); pa = pa2; } if (sz2 > szb) { /* round type up to the appropriate c-type and set/clear/truncate the unused bits */ void *pb2 = alloca(sz2); memcpy(pb2, pb, szb); memset((char*)pb2 + szb, getsign(pb, sz), sz2 - szb); pb = pb2; } jl_value_t *newv = lambda2(ty, pa, pb, sz, sz2, list); return newv; }
DLLEXPORT void jl_show_any(jl_value_t *str, jl_value_t *v) { ios_t *s = (ios_t*)jl_iostr_data(str); // fallback for printing some other builtin types if (jl_is_tuple(v)) { jl_show_tuple(str, (jl_tuple_t*)v, '(', ')', 1); } else if (jl_is_type(v)) { show_type(str, v); } else if (jl_is_func(v)) { show_function(s, v); } else if (jl_typeis(v,jl_intrinsic_type)) { JL_PRINTF(s, "#<intrinsic-function %d>", *(uint32_t*)jl_bits_data(v)); } else { jl_value_t *t = (jl_value_t*)jl_typeof(v); assert(jl_is_struct_type(t) || jl_is_bits_type(t)); jl_tag_type_t *tt = (jl_tag_type_t*)t; JL_PUTS(tt->name->name->name, s); if (tt->parameters != jl_null) { jl_show_tuple(str, tt->parameters, '{', '}', 0); } JL_PUTC('(', s); if (jl_is_struct_type(tt)) { jl_struct_type_t *st = (jl_struct_type_t*)tt; size_t i; size_t n = jl_tuple_len(st->names); for(i=0; i < n; i++) { jl_value_t *fval = jl_get_nth_field(v, i); if (fval == NULL) JL_PUTS("#undef", s); else jl_show(str, fval); if (i < n-1) JL_PUTC(',', s); } } else { size_t nb = jl_bitstype_nbits(tt)/8; char *data = (char*)jl_bits_data(v); JL_PUTS("0x", s); for(int i=nb-1; i >= 0; --i) ios_printf(s, "%02hhx", data[i]); } JL_PUTC(')', s); } }
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; } if (ta == (jl_value_t*)jl_union_kind) return jl_egal(jl_fieldref(a,0), jl_fieldref(b,0)); return 0; }
JL_DLLEXPORT jl_value_t *jl_arrayref(jl_array_t *a, size_t i) { if (a->flags.ptrarray) return jl_ptrarrayref(a, i); assert(i < jl_array_len(a)); jl_value_t *eltype = (jl_value_t*)jl_tparam0(jl_typeof(a)); if (jl_is_uniontype(eltype)) { // isbits union selector bytes are always stored directly after the last array element uint8_t sel = jl_array_typetagdata(a)[i]; eltype = jl_nth_union_component(eltype, sel); if (jl_is_datatype_singleton((jl_datatype_t*)eltype)) return ((jl_datatype_t*)eltype)->instance; } return jl_new_bits(eltype, &((char*)a->data)[i * a->elsize]); }
JL_DLLEXPORT int jl_egal(jl_value_t *a, jl_value_t *b) { // warning: a,b may NOT have been gc-rooted by the caller 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_svec(a)) return compare_svec((jl_svec_t*)a, (jl_svec_t*)b); 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 && compare_svec(dta->parameters, dtb->parameters); } if (dt->mutabl) return 0; size_t sz = jl_datatype_size(dt); if (sz == 0) return 1; size_t nf = jl_datatype_nfields(dt); if (nf == 0) return bits_equal(jl_data_ptr(a), jl_data_ptr(b), sz); return compare_fields(a, b, dt); }
static inline jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *dims) { jl_value_t *eltype = jl_tparam0(atype); size_t elsz = 0, al = 0; if (!jl_is_kind(jl_typeof(eltype))) jl_type_error_rt("Array", "element type", (jl_value_t*)jl_type_type, eltype); int isunboxed = jl_islayout_inline(eltype, &elsz, &al); int isunion = jl_is_uniontype(eltype); if (!isunboxed) { elsz = sizeof(void*); al = elsz; } return _new_array_(atype, ndims, dims, isunboxed, isunion, elsz); }
JL_DLLEXPORT jl_value_t *jl_fptosi_auto(jl_value_t *a) { jl_datatype_t *ty; switch (jl_datatype_size(jl_typeof(a))) { case 4: ty = jl_int32_type; break; case 8: ty = jl_int64_type; break; default: jl_error("fptoui: runtime floating point intrinsics are not implemented for bit sizes other than 32 and 64"); } return jl_fptosi((jl_value_t*)ty, a); }
static void jl_uv_call_close_callback(jl_value_t *val) { jl_value_t *cb; if (!jl_old_base_module) { if (close_cb == NULL) close_cb = jl_get_global(jl_base_module, jl_symbol("_uv_hook_close")); cb = close_cb; } else { cb = jl_get_global(jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), jl_symbol("_uv_hook_close")); } assert(cb); jl_value_t *args[2] = {cb,val}; jl_apply(args, 2); }
void jl_assign_bits(void *dest, jl_value_t *bits) { // bits must be a heap box. size_t nb = jl_datatype_size(jl_typeof(bits)); if (nb == 0) return; switch (nb) { case 1: *(uint8_t*)dest = *(uint8_t*)bits; break; case 2: jl_store_unaligned_i16(dest, *(uint16_t*)bits); break; case 4: jl_store_unaligned_i32(dest, *(uint32_t*)bits); break; case 8: jl_store_unaligned_i64(dest, *(uint64_t*)bits); break; case 16: memcpy(dest, jl_assume_aligned(bits, 16), 16); break; default: memcpy(dest, bits, nb); } }
JL_DLLEXPORT void jl_arrayset(jl_array_t *a, jl_value_t *rhs, size_t i) { assert(i < jl_array_len(a)); jl_value_t *el_type = jl_tparam0(jl_typeof(a)); if (el_type != (jl_value_t*)jl_any_type) { if (!jl_subtype(rhs, el_type, 1)) jl_type_error("arrayset", el_type, rhs); } if (!a->flags.ptrarray) { jl_assign_bits(&((char*)a->data)[i*a->elsize], rhs); } else { ((jl_value_t**)a->data)[i] = rhs; jl_gc_wb(jl_array_owner(a), rhs); } }
static inline int sig_match_leaf(jl_value_t **args, jl_value_t **sig, size_t n) { // NOTE: This function is a huge performance hot spot!! for(size_t i=0; i < n; i++) { jl_value_t *decl = sig[i]; jl_value_t *a = args[i]; if ((jl_value_t*)jl_typeof(a) != decl) { /* we are only matching concrete types here, and those types are hash-consed, so pointer comparison should work. */ return 0; } } return 1; }
void jl_show(jl_value_t *stream, jl_value_t *v) { if (jl_base_module) { if (jl_show_gf == NULL) { jl_show_gf = (jl_function_t*)jl_get_global(jl_base_module, jl_symbol("show")); } if (jl_show_gf==NULL || stream==NULL) { JL_PRINTF(JL_STDERR, " could not show value of type %s", jl_is_tuple(v) ? "Tuple" : ((jl_datatype_t*)jl_typeof(v))->name->name->name); return; } jl_value_t *args[2] = {stream,v}; jl_apply(jl_show_gf, args, 2); } }
JL_DLLEXPORT jl_value_t *jl_arrayref(jl_array_t *a, size_t i) { assert(i < jl_array_len(a)); jl_value_t *elt; if (!a->flags.ptrarray) { jl_value_t *el_type = (jl_value_t*)jl_tparam0(jl_typeof(a)); elt = jl_new_bits(el_type, &((char*)a->data)[i*a->elsize]); } else { elt = ((jl_value_t**)a->data)[i]; if (elt == NULL) { jl_throw(jl_undefref_exception); } } return elt; }
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; }
static inline int sig_match_simple(jl_value_t **args, size_t n, jl_value_t **sig, int va, size_t lensig) { // NOTE: This function is a performance hot spot!! for(size_t i=0; i < n; i++) { jl_value_t *decl = sig[i]; if (i == lensig-1) { if (va) { jl_value_t *t = jl_tparam0(decl); for(; i < n; i++) { if (!jl_subtype(args[i], t, 1)) return 0; } return 1; } } jl_value_t *a = args[i]; if (decl == (jl_value_t*)jl_any_type) { } else if ((jl_value_t*)jl_typeof(a) == decl) { /* we are only matching concrete types here, and those types are hash-consed, so pointer comparison should work. */ } else if (jl_is_type_type(decl) && jl_is_type(a)) { jl_value_t *tp0 = jl_tparam0(decl); if (tp0 == (jl_value_t*)jl_typetype_tvar) { // in the case of Type{T}, the types don't have // to match exactly either. this is cached as Type{T}. // analogous to the situation with tuples. } else if (jl_is_typevar(tp0)) { if (!jl_subtype(a, ((jl_tvar_t*)tp0)->ub, 0)) return 0; } else { if (a!=tp0 && !jl_types_equal(a,tp0)) return 0; } } else { return 0; } } return 1; }
// this is the general entry point for looking up a type in the cache // (as a subtype, or with typeseq) jl_typemap_entry_t *jl_typemap_assoc_by_type(union jl_typemap_t ml_or_cache, jl_tupletype_t *types, jl_svec_t **penv, int8_t subtype_inexact__sigseq_useenv, int8_t subtype, int8_t offs) { if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_level_type) { jl_typemap_level_t *cache = ml_or_cache.node; // called object is the primary key for constructors, otherwise first argument jl_value_t *ty = NULL; if (jl_datatype_nfields(types) > offs) { ty = jl_tparam(types, offs); if (cache->targ != (void*)jl_nothing && jl_is_type_type(ty)) { jl_value_t *a0 = jl_tparam0(ty); if (jl_is_datatype(a0)) { union jl_typemap_t ml = mtcache_hash_lookup(cache->targ, a0, 1, offs); if (ml.unknown != jl_nothing) { jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, types, penv, subtype_inexact__sigseq_useenv, subtype, offs+1); if (li) return li; } } } if (cache->arg1 != (void*)jl_nothing && jl_is_datatype(ty)) { union jl_typemap_t ml = mtcache_hash_lookup(cache->arg1, ty, 0, offs); if (ml.unknown != jl_nothing) { jl_typemap_entry_t *li = jl_typemap_assoc_by_type(ml, types, penv, subtype_inexact__sigseq_useenv, subtype, offs+1); if (li) return li; } } } if (subtype) { jl_typemap_entry_t *li = jl_typemap_assoc_by_type_(cache->linear, types, subtype_inexact__sigseq_useenv, penv); if (li) return li; return jl_typemap_assoc_by_type(cache->any, types, penv, subtype_inexact__sigseq_useenv, subtype, offs+1); } else { if (ty && jl_is_any(ty)) return jl_typemap_assoc_by_type(cache->any, types, penv, subtype_inexact__sigseq_useenv, subtype, offs+1); else return jl_typemap_lookup_by_type_(cache->linear, types, subtype_inexact__sigseq_useenv); } } else { return subtype ? jl_typemap_assoc_by_type_(ml_or_cache.leaf, types, subtype_inexact__sigseq_useenv, penv) : jl_typemap_lookup_by_type_(ml_or_cache.leaf, types, subtype_inexact__sigseq_useenv); } }
JL_DLLEXPORT jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i) { jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v); assert(i < jl_datatype_nfields(st)); size_t offs = jl_field_offset(st, i); if (jl_field_isptr(st, i)) { return *(jl_value_t**)((char*)v + offs); } jl_value_t *ty = jl_field_type(st, i); if (jl_is_uniontype(ty)) { uint8_t sel = ((uint8_t*)v)[offs + jl_field_size(st, i) - 1]; ty = jl_nth_union_component(ty, sel); if (jl_is_datatype_singleton((jl_datatype_t*)ty)) return ((jl_datatype_t*)ty)->instance; } return jl_new_bits(ty, (char*)v + offs); }
// run time version of pointerref intrinsic (warning: i is not rooted) JL_DLLEXPORT jl_value_t *jl_pointerref(jl_value_t *p, jl_value_t *i) { JL_TYPECHK(pointerref, pointer, p); JL_TYPECHK(pointerref, long, i); jl_value_t *ety = jl_tparam0(jl_typeof(p)); if (ety == (jl_value_t*)jl_any_type) { jl_value_t **pp = (jl_value_t**)(jl_unbox_long(p) + (jl_unbox_long(i)-1)*sizeof(void*)); return *pp; } else { if (!jl_is_datatype(ety)) jl_error("pointerref: invalid pointer"); size_t nb = LLT_ALIGN(jl_datatype_size(ety), ((jl_datatype_t*)ety)->layout->alignment); char *pp = (char*)jl_unbox_long(p) + (jl_unbox_long(i)-1)*nb; return jl_new_bits(ety, pp); } }
int jl_typemap_visitor(union jl_typemap_t cache, jl_typemap_visitor_fptr fptr, void *closure) { if (jl_typeof(cache.unknown) == (jl_value_t*)jl_typemap_level_type) { if (cache.node->targ.values != (void*)jl_nothing) if (!jl_typemap_array_visitor(&cache.node->targ, fptr, closure)) return 0; if (cache.node->arg1.values != (void*)jl_nothing) if (!jl_typemap_array_visitor(&cache.node->arg1, fptr, closure)) return 0; if (!jl_typemap_node_visitor(cache.node->linear, fptr, closure)) return 0; return jl_typemap_visitor(cache.node->any, fptr, closure); } else { return jl_typemap_node_visitor(cache.leaf, fptr, closure); } }
DLLEXPORT void jl_show_any(jl_value_t *str, jl_value_t *v) { uv_stream_t *s = ((uv_stream_t**)str)[1]; // fallback for printing some other builtin types if (jl_is_tuple(v)) { jl_show_tuple(str, (jl_tuple_t*)v, '(', ')', 1); } else if (jl_is_type(v)) { show_type(str, v); } else if (jl_is_func(v)) { show_function(s, v); } else if (jl_typeis(v,jl_intrinsic_type)) { JL_PRINTF(s, "# intrinsic function %d", *(uint32_t*)jl_data_ptr(v)); } else { jl_value_t *t = (jl_value_t*)jl_typeof(v); assert(jl_is_datatype(t)); jl_datatype_t *dt = (jl_datatype_t*)t; show_type(str, t); JL_PUTC('(', s); if (jl_tuple_len(dt->names)>0 || dt->size==0) { size_t i; size_t n = jl_tuple_len(dt->names); for(i=0; i < n; i++) { jl_value_t *fval = jl_get_nth_field(v, i); if (fval == NULL) JL_PUTS("#undef", s); else jl_show(str, fval); if (i < n-1) JL_PUTC(',', s); } } else { size_t nb = jl_datatype_size(dt); char *data = (char*)jl_data_ptr(v); JL_PUTS("0x", s); for(int i=nb-1; i >= 0; --i) jl_printf(s, "%02hhx", data[i]); } JL_PUTC(')', s); } }
jl_typemap_entry_t *jl_typemap_assoc_exact(union jl_typemap_t ml_or_cache, jl_value_t **args, size_t n, int8_t offs) { // NOTE: This function is a huge performance hot spot!! if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_level_type) { jl_typemap_level_t *cache = ml_or_cache.node; if (n > offs) { jl_value_t *a1 = args[offs]; jl_value_t *ty = (jl_value_t*)jl_typeof(a1); assert(jl_is_datatype(ty)); if (ty == (jl_value_t*)jl_datatype_type && cache->targ != (void*)jl_nothing) { ml_or_cache = mtcache_hash_lookup(cache->targ, a1, 1, offs); jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, args, n, offs+1); if (ml) return ml; } if (cache->arg1 != (void*)jl_nothing) { ml_or_cache = mtcache_hash_lookup(cache->arg1, ty, 0, offs); if (jl_typeof(ml_or_cache.unknown) == (jl_value_t*)jl_typemap_entry_type && ml_or_cache.leaf->simplesig == (void*)jl_nothing && offs < 2 && n > 1) { jl_value_t *a0 = args[1-offs]; jl_value_t *t0 = (jl_value_t*)jl_typeof(a0); if (ml_or_cache.leaf->next==(void*)jl_nothing && n==2 && jl_datatype_nfields(ml_or_cache.leaf->sig)==2 && jl_tparam(ml_or_cache.leaf->sig, 1 - offs) == t0) return ml_or_cache.leaf; if (n==3) { // some manually-unrolled common special cases jl_value_t *a2 = args[2]; if (!jl_is_tuple(a2)) { // issue #6426 jl_typemap_entry_t *mn = ml_or_cache.leaf; if (jl_datatype_nfields(mn->sig)==3 && jl_tparam(mn->sig,1-offs)==t0 && jl_tparam(mn->sig,2)==(jl_value_t*)jl_typeof(a2)) return mn; mn = mn->next; if (mn!=(void*)jl_nothing && jl_datatype_nfields(mn->sig)==3 && jl_tparam(mn->sig,1-offs)==t0 && jl_tparam(mn->sig,2)==(jl_value_t*)jl_typeof(a2)) return mn; } } } jl_typemap_entry_t *ml = jl_typemap_assoc_exact(ml_or_cache, args, n, offs+1); if (ml) return ml; } } jl_typemap_entry_t *ml = jl_typemap_node_assoc_exact(cache->linear, args, n); if (ml) return ml; return jl_typemap_assoc_exact(cache->any, args, n, offs+1); } else { return jl_typemap_node_assoc_exact(ml_or_cache.leaf, args, n); } }
DLLEXPORT uptrint_t jl_object_id(jl_value_t *v) { if (jl_is_symbol(v)) return ((jl_sym_t*)v)->hash; jl_value_t *tv = (jl_value_t*)jl_typeof(v); if (tv == (jl_value_t*)jl_tuple_type) { uptrint_t h = 0; size_t l = jl_tuple_len(v); for(size_t i = 0; i < l; i++) { uptrint_t u = jl_object_id(jl_tupleref(v,i)); h = bitmix(h, u); } return h; } jl_datatype_t *dt = (jl_datatype_t*)tv; if (dt == jl_datatype_type) { jl_datatype_t *dtv = (jl_datatype_t*)v; uptrint_t h = inthash((uptrint_t)tv); return bitmix(bitmix(h, jl_object_id((jl_value_t*)dtv->name)), jl_object_id((jl_value_t*)dtv->parameters)); } if (dt->mutabl) return inthash((uptrint_t)v); size_t sz = jl_datatype_size(tv); uptrint_t h = inthash((uptrint_t)tv); if (sz == 0) return ~h; size_t nf = jl_tuple_len(dt->names); if (nf == 0) { return bits_hash(jl_data_ptr(v), sz) ^ h; } for (size_t f=0; f < nf; f++) { size_t offs = dt->fields[f].offset; char *vo = (char*)jl_data_ptr(v) + offs; uptrint_t u; if (dt->fields[f].isptr) { jl_value_t *f = *(jl_value_t**)vo; u = f==NULL ? 0 : jl_object_id(f); } else { u = bits_hash(vo, dt->fields[f].size); } h = bitmix(h, u); } return h; }
jl_value_t *jl_toplevel_eval_flex(jl_value_t *ex, int fast) { //jl_show(ex); //ios_printf(ios_stdout, "\n"); jl_lambda_info_t *thk; int ewc = 0; if (jl_typeof(ex) != (jl_type_t*)jl_lambda_info_type) { if (jl_is_expr(ex) && eval_with_compiler_p((jl_expr_t*)ex, fast)) { thk = jl_wrap_expr(ex); ewc = 1; } else { return jl_interpret_toplevel_expr(ex); } } else { thk = (jl_lambda_info_t*)ex; ewc = eval_with_compiler_p(jl_lam_body((jl_expr_t*)thk->ast), fast); if (!ewc) { jl_array_t *vinfos = jl_lam_vinfo((jl_expr_t*)thk->ast); int i; for(i=0; i < vinfos->length; i++) { if (jl_vinfo_capt((jl_array_t*)jl_cellref(vinfos,i))) { // interpreter doesn't handle closure environment ewc = 1; break; } } } } jl_value_t *thunk=NULL; jl_function_t *gf=NULL; jl_value_t *result; JL_GC_PUSH(&thunk, &gf, &thk); if (ewc) { thunk = jl_new_closure_internal(thk, (jl_value_t*)jl_null); result = jl_apply((jl_function_t*)thunk, NULL, 0); } else { result = jl_interpret_toplevel_thunk(thk); } JL_GC_POP(); return result; }
static void jl_typemap_insert_generic(union jl_typemap_t *pml, jl_value_t *parent, jl_typemap_entry_t *newrec, jl_value_t *key, int8_t offs, const struct jl_typemap_info *tparams) { if (jl_typeof(pml->unknown) == (jl_value_t*)jl_typemap_level_type) { jl_typemap_level_insert_(pml->node, newrec, offs, tparams); return; } unsigned count = jl_typemap_list_count(pml->leaf); if (count > MAX_METHLIST_COUNT) { pml->node = jl_method_convert_list_to_cache(pml->leaf, key, offs); jl_gc_wb(parent, pml->node); jl_typemap_level_insert_(pml->node, newrec, offs, tparams); return; } jl_typemap_list_insert_(&pml->leaf, parent, newrec, tparams); }
static size_t jl_static_show_x(JL_STREAM *out, jl_value_t *v, struct recur_list *depth) { // show values without calling a julia method or allocating through the GC if (v == NULL) { return jl_printf(out, "#<null>"); } else if ((uintptr_t)v < 4096U) { return jl_printf(out, "#<%d>", (int)(uintptr_t)v); } unsigned int dist = 1; struct recur_list this_item = {depth, v}, *p = depth; while (p) { if (p->v == v) return jl_printf(out, "<circular reference @-%u>", dist); dist++; p = p->prev; } return jl_static_show_x_(out, v, (jl_datatype_t*)jl_typeof(v), &this_item); }