SEXP jr_cast(jl_value_t *tt){ SEXP ans = R_NilValue; JL_GC_PUSH1(&tt); if (jl_is_nothing(tt) || jl_is_null(tt)) return ans; if (jl_is_array(tt)) { ans = jr_array(tt); } else if(jl_isa(tt, "Range")) { ans = jr_range(tt); } else if(jl_isa(tt, "DataArray")) { ans = jr_data_array(tt); } else if(jl_isa(tt, "DataFrame")) { ans = jr_data_frame(tt); } else if (jl_is_tuple(tt)) { PROTECT(ans = Rf_allocVector(VECSXP, jl_tuple_len(tt))); for (int i = 0; i < jl_tuple_len(tt); i++) SET_VECTOR_ELT(ans, i, jr_cast(jl_tupleref(tt, i))); UNPROTECT(1); } else if(jl_isa(tt, "Dict")) { ans = jr_dict(tt); } else if(jl_is_function(tt)) { ans = jr_func(tt); } else { ans = jr_scalar(tt); } JL_GC_POP(); if (ans == R_NilValue) { jl_error("invaild object"); } return ans; }
JL_DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uint32_t na) { jl_ptls_t ptls = jl_get_ptls_states(); if (type->instance != NULL) return type->instance; size_t nf = jl_datatype_nfields(type); jl_value_t *jv = jl_gc_alloc(ptls, jl_datatype_size(type), type); JL_GC_PUSH1(&jv); for (size_t i = 0; i < na; i++) { jl_value_t *ft = jl_field_type(type, i); if (!jl_isa(args[i], ft)) jl_type_error("new", ft, args[i]); jl_set_nth_field(jv, i, args[i]); } for(size_t i=na; i < nf; i++) { if (jl_field_isptr(type, i)) { *(jl_value_t**)((char*)jl_data_ptr(jv)+jl_field_offset(type,i)) = NULL; } else { jl_value_t *ft = jl_field_type(type, i); if (jl_is_uniontype(ft)) { uint8_t *psel = &((uint8_t *)jv)[jl_field_offset(type, i) + jl_field_size(type, i) - 1]; *psel = 0; } } } JL_GC_POP(); return jv; }
static int jl_typemap_intersection_array_visitor(struct jl_ordereddict_t *a, jl_value_t *ty, int tparam, int offs, struct typemap_intersection_env *closure) { size_t i, l = jl_array_len(a->values); union jl_typemap_t *data = (union jl_typemap_t*)jl_array_data(a->values); for (i = 0; i < l; i++) { union jl_typemap_t ml = data[i]; if (ml.unknown == jl_nothing) continue; jl_value_t *t; if (jl_typeof(ml.unknown) == (jl_value_t*)jl_typemap_level_type) { t = ml.node->key; } else { t = jl_field_type(jl_unwrap_unionall((jl_value_t*)ml.leaf->sig), offs); if (tparam) t = jl_tparam0(t); } // `t` is a leaftype, so intersection test becomes subtype if (ty == (jl_value_t*)jl_any_type || // easy case: Any always matches (tparam ? (jl_typeof(t) == ty || jl_isa(t, ty)) // (Type{t} <: ty), where is_leaf_type(t) => isa(t, ty) : (t == ty || jl_subtype(t, ty)))) { if (!jl_typemap_intersection_visitor(ml, offs + 1, closure)) return 0; } } return 1; }
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!! size_t i; if (va) lensig -= 1; for (i = 0; i < lensig; i++) { jl_value_t *decl = sig[i]; jl_value_t *a = args[i]; if (decl == (jl_value_t*)jl_any_type || ((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. */ continue; } jl_value_t *unw = jl_is_unionall(decl) ? ((jl_unionall_t*)decl)->body : decl; if (jl_is_type_type(unw) && jl_is_type(a)) { jl_value_t *tp0 = jl_tparam0(unw); if (jl_is_typevar(tp0)) { // in the case of Type{_}, the types don't have to match exactly. // this is cached as `Type{T} where T`. if (((jl_tvar_t*)tp0)->ub != (jl_value_t*)jl_any_type && !jl_subtype(a, ((jl_tvar_t*)tp0)->ub)) return 0; } else { if (a != tp0) { if (jl_typeof(a) != jl_typeof(tp0)) return 0; jl_datatype_t *da = (jl_datatype_t*)a; jl_datatype_t *dt = (jl_datatype_t*)tp0; while (jl_is_unionall(da)) da = (jl_datatype_t*)((jl_unionall_t*)da)->body; while (jl_is_unionall(dt)) dt = (jl_datatype_t*)((jl_unionall_t*)dt)->body; if (jl_is_datatype(da) && jl_is_datatype(dt) && da->name != dt->name) return 0; if (!jl_types_equal(a, tp0)) return 0; } } } else { return 0; } } if (va) { jl_value_t *decl = sig[i]; if (jl_vararg_kind(decl) == JL_VARARG_INT) { if (n-i != jl_unbox_long(jl_tparam1(decl))) return 0; } jl_value_t *t = jl_unwrap_vararg(decl); for(; i < n; i++) { if (!jl_isa(args[i], t)) return 0; } return 1; } return 1; }
// Check whether v is a scalar for purposes of inlining fused-broadcast // arguments when lowering; should agree with broadcast.jl on what is a // scalar. When in doubt, return false, since this is only an optimization. value_t fl_julia_scalar(fl_context_t *fl_ctx, value_t *args, uint32_t nargs) { argcount(fl_ctx, "julia-scalar?", nargs, 1); if (fl_isnumber(fl_ctx, args[0]) || fl_isstring(fl_ctx, args[0])) return fl_ctx->T; else if (iscvalue(args[0]) && fl_ctx->jl_sym == cv_type((cvalue_t*)ptr(args[0]))) { jl_value_t *v = *(jl_value_t**)cptr(args[0]); if (jl_isa(v,(jl_value_t*)jl_number_type) || jl_is_string(v)) return fl_ctx->T; } return fl_ctx->F; }
JL_DLLEXPORT void jl_typeassert(jl_value_t *x, jl_value_t *t) { if (!jl_isa(x,t)) jl_type_error("typeassert", t, x); }
static jl_value_t *eval(jl_value_t *e, interpreter_state *s) { jl_ptls_t ptls = jl_get_ptls_states(); jl_code_info_t *src = s->src; if (jl_is_ssavalue(e)) { ssize_t id = ((jl_ssavalue_t*)e)->id; if (src == NULL || id >= jl_source_nssavalues(src) || id < 0 || s->locals == NULL) jl_error("access to invalid SSAValue"); else return s->locals[jl_source_nslots(src) + id]; } if (jl_is_slot(e)) { ssize_t n = jl_slot_number(e); if (src == NULL || n > jl_source_nslots(src) || n < 1 || s->locals == NULL) jl_error("access to invalid slot number"); jl_value_t *v = s->locals[n - 1]; if (v == NULL) jl_undefined_var_error((jl_sym_t*)jl_array_ptr_ref(src->slotnames, n - 1)); return v; } if (jl_is_globalref(e)) { return jl_eval_global_var(jl_globalref_mod(e), jl_globalref_name(e)); } if (jl_is_quotenode(e)) return jl_fieldref(e,0); jl_module_t *modu = s->module; if (jl_is_symbol(e)) { // bare symbols appear in toplevel exprs not wrapped in `thunk` return jl_eval_global_var(modu, (jl_sym_t*)e); } if (!jl_is_expr(e)) return e; jl_expr_t *ex = (jl_expr_t*)e; jl_value_t **args = (jl_value_t**)jl_array_data(ex->args); size_t nargs = jl_array_len(ex->args); if (ex->head == isdefined_sym) { jl_value_t *sym = args[0]; int defined = 0; if (jl_is_slot(sym)) { ssize_t n = jl_slot_number(sym); if (src == NULL || n > jl_source_nslots(src) || n < 1 || s->locals == NULL) jl_error("access to invalid slot number"); defined = s->locals[n - 1] != NULL; } else if (jl_is_globalref(sym)) { defined = jl_boundp(jl_globalref_mod(sym), jl_globalref_name(sym)); } else if (jl_is_symbol(sym)) { defined = jl_boundp(modu, (jl_sym_t*)sym); } else if (jl_is_expr(sym) && ((jl_expr_t*)sym)->head == static_parameter_sym) { ssize_t n = jl_unbox_long(args[0]); assert(n > 0); if (s->sparam_vals && n <= jl_svec_len(s->sparam_vals)) { jl_value_t *sp = jl_svecref(s->sparam_vals, n - 1); defined = !jl_is_typevar(sp); } else { // static parameter val unknown needs to be an error for ccall jl_error("could not determine static parameter value"); } } else { assert(0 && "malformed isdefined expression"); } return defined ? jl_true : jl_false; } else if (ex->head == call_sym) { return do_call(args, nargs, s); } else if (ex->head == invoke_sym) { return do_invoke(args, nargs, s); } else if (ex->head == new_sym) { jl_value_t *thetype = eval(args[0], s); jl_value_t *v=NULL; JL_GC_PUSH2(&thetype, &v); assert(jl_is_structtype(thetype)); v = jl_new_struct_uninit((jl_datatype_t*)thetype); for (size_t i = 1; i < nargs; i++) { jl_value_t *ft = jl_field_type(thetype, i - 1); jl_value_t *fldv = eval(args[i], s); if (!jl_isa(fldv, ft)) jl_type_error("new", ft, fldv); jl_set_nth_field(v, i - 1, fldv); } JL_GC_POP(); return v; } else if (ex->head == static_parameter_sym) { ssize_t n = jl_unbox_long(args[0]); assert(n > 0); if (s->sparam_vals && n <= jl_svec_len(s->sparam_vals)) { jl_value_t *sp = jl_svecref(s->sparam_vals, n - 1); if (jl_is_typevar(sp) && !s->preevaluation) jl_undefined_var_error(((jl_tvar_t*)sp)->name); return sp; } // static parameter val unknown needs to be an error for ccall jl_error("could not determine static parameter value"); } else if (ex->head == inert_sym) { return args[0]; } else if (ex->head == copyast_sym) { return jl_copy_ast(eval(args[0], s)); } else if (ex->head == exc_sym) { return ptls->exception_in_transit; } else if (ex->head == method_sym) { jl_sym_t *fname = (jl_sym_t*)args[0]; if (jl_is_globalref(fname)) { modu = jl_globalref_mod(fname); fname = jl_globalref_name(fname); } assert(jl_expr_nargs(ex) != 1 || jl_is_symbol(fname)); if (jl_is_symbol(fname)) { jl_value_t *bp_owner = (jl_value_t*)modu; jl_binding_t *b = jl_get_binding_for_method_def(modu, fname); jl_value_t **bp = &b->value; jl_value_t *gf = jl_generic_function_def(b->name, b->owner, bp, bp_owner, b); if (jl_expr_nargs(ex) == 1) return gf; } jl_value_t *atypes = NULL, *meth = NULL; JL_GC_PUSH2(&atypes, &meth); atypes = eval(args[1], s); meth = eval(args[2], s); jl_method_def((jl_svec_t*)atypes, (jl_code_info_t*)meth, s->module, args[3]); JL_GC_POP(); return jl_nothing; } else if (ex->head == const_sym) { jl_sym_t *sym = (jl_sym_t*)args[0]; if (jl_is_globalref(sym)) { modu = jl_globalref_mod(sym); sym = jl_globalref_name(sym); } assert(jl_is_symbol(sym)); jl_binding_t *b = jl_get_binding_wr(modu, sym, 1); jl_declare_constant(b); return (jl_value_t*)jl_nothing; } else if (ex->head == abstracttype_sym) { if (inside_typedef) jl_error("cannot eval a new abstract type definition while defining another type"); jl_value_t *name = args[0]; jl_value_t *para = eval(args[1], s); jl_value_t *super = NULL; jl_value_t *temp = NULL; jl_datatype_t *dt = NULL; jl_value_t *w = NULL; JL_GC_PUSH4(¶, &super, &temp, &w); assert(jl_is_svec(para)); if (jl_is_globalref(name)) { modu = jl_globalref_mod(name); name = (jl_value_t*)jl_globalref_name(name); } assert(jl_is_symbol(name)); dt = jl_new_abstracttype(name, modu, NULL, (jl_svec_t*)para); w = dt->name->wrapper; jl_binding_t *b = jl_get_binding_wr(modu, (jl_sym_t*)name, 1); temp = b->value; check_can_assign_type(b, w); b->value = w; jl_gc_wb_binding(b, w); JL_TRY { inside_typedef = 1; super = eval(args[2], s); jl_set_datatype_super(dt, super); jl_reinstantiate_inner_types(dt); } JL_CATCH { jl_reset_instantiate_inner_types(dt); b->value = temp; jl_rethrow(); } b->value = temp; if (temp == NULL || !equiv_type(dt, (jl_datatype_t*)jl_unwrap_unionall(temp))) { jl_checked_assignment(b, w); } JL_GC_POP(); return (jl_value_t*)jl_nothing; } else if (ex->head == primtype_sym) {