JL_DLLEXPORT jl_value_t *jl_lookup_code_address(void *ip, int skipC) { jl_ptls_t ptls = jl_get_ptls_states(); jl_frame_t *frames = NULL; int8_t gc_state = jl_gc_safe_enter(ptls); int n = jl_getFunctionInfo(&frames, (uintptr_t)ip, skipC, 0); jl_gc_safe_leave(ptls, gc_state); jl_value_t *rs = (jl_value_t*)jl_alloc_svec(n); JL_GC_PUSH1(&rs); for (int i = 0; i < n; i++) { jl_frame_t frame = frames[i]; jl_value_t *r = (jl_value_t*)jl_alloc_svec(7); jl_svecset(rs, i, r); if (frame.func_name) jl_svecset(r, 0, jl_symbol(frame.func_name)); else jl_svecset(r, 0, empty_sym); free(frame.func_name); if (frame.file_name) jl_svecset(r, 1, jl_symbol(frame.file_name)); else jl_svecset(r, 1, empty_sym); free(frame.file_name); jl_svecset(r, 2, jl_box_long(frame.line)); jl_svecset(r, 3, frame.linfo != NULL ? (jl_value_t*)frame.linfo : jl_nothing); jl_svecset(r, 4, jl_box_bool(frame.fromC)); jl_svecset(r, 5, jl_box_bool(frame.inlined)); jl_svecset(r, 6, jl_box_long((intptr_t)ip)); } free(frames); JL_GC_POP(); return rs; }
JL_DLLEXPORT jl_value_t *jl_lookup_code_address(void *ip, int skipC) { char *func_name; size_t line_num; char *file_name; size_t inlinedat_line; char *inlinedat_file; jl_lambda_info_t *outer_linfo; int fromC = frame_info_from_ip(&func_name, &file_name, &line_num, &inlinedat_file, &inlinedat_line, &outer_linfo, (size_t)ip, skipC, 0); jl_value_t *r = (jl_value_t*)jl_alloc_svec(8); JL_GC_PUSH1(&r); jl_svecset(r, 0, jl_symbol(func_name)); jl_svecset(r, 1, jl_symbol(file_name)); jl_svecset(r, 2, jl_box_long(line_num)); jl_svecset(r, 3, jl_symbol(inlinedat_file ? inlinedat_file : "")); jl_svecset(r, 4, jl_box_long(inlinedat_file ? inlinedat_line : -1)); jl_svecset(r, 5, outer_linfo != NULL ? (jl_value_t*)outer_linfo : jl_nothing); jl_svecset(r, 6, jl_box_bool(fromC)); jl_svecset(r, 7, jl_box_long((intptr_t)ip)); free(func_name); free(file_name); free(inlinedat_file); JL_GC_POP(); return r; }
JL_DLLEXPORT void JL_NORETURN jl_bounds_error_ints(jl_value_t *v, size_t *idxs, size_t nidxs) { size_t i; jl_value_t *t = NULL; JL_GC_PUSH2(&v, &t); // root arguments so the caller doesn't need to t = (jl_value_t*)jl_alloc_svec(nidxs); for (i = 0; i < nidxs; i++) { jl_svecset(t, i, jl_box_long(idxs[i])); } t = jl_f_tuple(NULL, jl_svec_data(t), nidxs); jl_throw(jl_new_struct((jl_datatype_t*)jl_boundserror_type, v, t)); }
// perform f(args...) on stack JL_DLLEXPORT jl_value_t *jl_apply_2va(jl_value_t *f, jl_value_t **args, uint32_t nargs) { nargs++; int onstack = (nargs < jl_page_size/sizeof(jl_value_t*)); jl_value_t **newargs; JL_GC_PUSHARGS(newargs, onstack ? nargs : 1); jl_svec_t *arg_heap = NULL; newargs[0] = f; // make sure f is rooted if (!onstack) { arg_heap = jl_alloc_svec(nargs); newargs[0] = (jl_value_t*)arg_heap; newargs = jl_svec_data(arg_heap); newargs[0] = f; } memcpy(&newargs[1], args, (nargs-1)*sizeof(jl_value_t*)); jl_value_t *ret = jl_apply_generic(newargs, nargs); JL_GC_POP(); return ret; }
DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_value_t *bp_owner, jl_binding_t *bnd, jl_svec_t *argdata, jl_function_t *f, jl_value_t *isstaged, jl_value_t *call_func, int iskw) { jl_module_t *module = (bnd ? bnd->owner : NULL); // argdata is svec({types...}, svec(typevars...)) jl_tupletype_t *argtypes = (jl_tupletype_t*)jl_svecref(argdata,0); jl_svec_t *tvars = (jl_svec_t*)jl_svecref(argdata,1); jl_value_t *gf = NULL; JL_GC_PUSH4(&gf, &tvars, &argtypes, &f); if (bnd && bnd->value != NULL && !bnd->constp) { jl_errorf("cannot define function %s; it already has a value", bnd->name->name); } if (*bp != NULL) { gf = *bp; if (!jl_is_gf(gf)) { if (jl_is_datatype(gf)) { // DataType: define `call`, for backwards compat with outer constructors if (call_func == NULL) call_func = (jl_value_t*)jl_module_call_func(jl_current_module); size_t na = jl_nparams(argtypes); jl_svec_t *newargtypes = jl_alloc_svec(1 + na); jl_lambda_info_t *new_linfo = NULL; JL_GC_PUSH2(&newargtypes, &new_linfo); new_linfo = jl_copy_lambda_info(f->linfo); f = jl_new_closure(f->fptr, f->env, new_linfo); size_t i=0; if (iskw) { assert(na > 0); // for kw sorter, keep container argument first jl_svecset(newargtypes, 0, jl_tparam(argtypes, 0)); i++; } jl_svecset(newargtypes, i, jl_wrap_Type(gf)); i++; for(; i < na+1; i++) { jl_svecset(newargtypes, i, jl_tparam(argtypes, i-1)); } argtypes = jl_apply_tuple_type(newargtypes); JL_GC_POP(); gf = call_func; name = call_sym; // edit args, insert type first if (!jl_is_expr(f->linfo->ast)) { f->linfo->ast = jl_uncompress_ast(f->linfo, f->linfo->ast); jl_gc_wb(f->linfo, f->linfo->ast); } else { // Do not mutate the original ast since it might // be reused somewhere else f->linfo->ast = jl_copy_ast(f->linfo->ast); jl_gc_wb(f->linfo, f->linfo->ast); } jl_array_t *al = jl_lam_args((jl_expr_t*)f->linfo->ast); if (jl_array_len(al) == 0) { al = jl_alloc_cell_1d(1); jl_exprargset(f->linfo->ast, 0, (jl_value_t*)al); } else { jl_array_grow_beg(al, 1); } if (iskw) { jl_cellset(al, 0, jl_cellref(al, 1)); jl_cellset(al, 1, (jl_value_t*)jl_gensym()); } else { jl_cellset(al, 0, (jl_value_t*)jl_gensym()); } } if (!jl_is_gf(gf)) { jl_errorf("cannot define function %s; it already has a value", name->name); } } if (iskw) { jl_methtable_t *mt = jl_gf_mtable(gf); assert(!module); module = mt->module; bp = (jl_value_t**)&mt->kwsorter; bp_owner = (jl_value_t*)mt; gf = *bp; } } // TODO size_t na = jl_nparams(argtypes); for(size_t i=0; i < na; i++) { jl_value_t *elt = jl_tparam(argtypes,i); if (!jl_is_type(elt) && !jl_is_typevar(elt)) { jl_lambda_info_t *li = f->linfo; jl_exceptionf(jl_argumenterror_type, "invalid type for argument %s in method definition for %s at %s:%d", jl_lam_argname(li,i)->name, name->name, li->file->name, li->line); } } int ishidden = !!strchr(name->name, '#'); for(size_t i=0; i < jl_svec_len(tvars); i++) { jl_value_t *tv = jl_svecref(tvars,i); if (!jl_is_typevar(tv)) jl_type_error_rt(name->name, "method definition", (jl_value_t*)jl_tvar_type, tv); if (!ishidden && !type_contains((jl_value_t*)argtypes, tv)) { jl_printf(JL_STDERR, "WARNING: static parameter %s does not occur in signature for %s", ((jl_tvar_t*)tv)->name->name, name->name); print_func_loc(JL_STDERR, f->linfo); jl_printf(JL_STDERR, ".\nThe method will not be callable.\n"); } } if (bnd) { bnd->constp = 1; } if (*bp == NULL) { gf = (jl_value_t*)jl_new_generic_function(name, module); *bp = gf; if (bp_owner) jl_gc_wb(bp_owner, gf); } assert(jl_is_function(f)); assert(jl_is_tuple_type(argtypes)); assert(jl_is_svec(tvars)); jl_add_method((jl_function_t*)gf, argtypes, f, tvars, isstaged == jl_true); 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_wb(li, li->ast); } JL_GC_POP(); return gf; }