// return a new lambda-info that has some extra static parameters merged in JL_DLLEXPORT jl_lambda_info_t *jl_get_specialized(jl_method_t *m, jl_tupletype_t *types, jl_svec_t *sp) { jl_lambda_info_t *linfo = m->lambda_template; jl_lambda_info_t *new_linfo; assert(jl_svec_len(linfo->sparam_syms) == jl_svec_len(sp) || sp == jl_emptysvec); if (!m->isstaged) { new_linfo = jl_copy_lambda(linfo); new_linfo->specTypes = types; new_linfo->def = m; new_linfo->sparam_vals = sp; if (jl_options.compile_enabled == JL_OPTIONS_COMPILE_OFF || jl_options.compile_enabled == JL_OPTIONS_COMPILE_MIN) { // copy fptr from the template method definition new_linfo->fptr = linfo->fptr; new_linfo->jlcall_api = linfo->jlcall_api; if (jl_options.compile_enabled == JL_OPTIONS_COMPILE_OFF && new_linfo->fptr == NULL) { jl_printf(JL_STDERR,"code missing for "); jl_static_show(JL_STDERR, (jl_value_t*)new_linfo); jl_printf(JL_STDERR, " sysimg may not have been built with --compile=all\n"); } } } else { new_linfo = jl_instantiate_staged(m, types, sp); } return new_linfo; }
// return a new lambda-info that has some extra static parameters merged in JL_DLLEXPORT jl_lambda_info_t *jl_get_specialized(jl_method_t *m, jl_tupletype_t *types, jl_svec_t *sp, int allow_exec) { jl_lambda_info_t *linfo = m->lambda_template; jl_lambda_info_t *new_linfo; assert(jl_svec_len(linfo->sparam_syms) == jl_svec_len(sp) || sp == jl_emptysvec); if (!m->isstaged) { new_linfo = jl_copy_lambda(linfo); new_linfo->specTypes = types; new_linfo->def = m; new_linfo->sparam_vals = sp; } else if (!allow_exec) { new_linfo = jl_copy_lambda(linfo); new_linfo->specTypes = types; new_linfo->def = m; new_linfo->sparam_vals = sp; jl_set_lambda_code_null(new_linfo); } else { new_linfo = jl_instantiate_staged(m, types, sp); } return new_linfo; }
jl_method_t *jl_new_method(jl_lambda_info_t *definition, jl_sym_t *name, jl_tupletype_t *sig, jl_svec_t *tvars, int isstaged) { assert(definition->code); jl_method_t *m = jl_new_method_uninit(); m->isstaged = isstaged; m->name = name; m->sig = sig; if (jl_svec_len(tvars) == 1) tvars = (jl_svec_t*)jl_svecref(tvars, 0); m->tvars = tvars; m->ambig = jl_nothing; JL_GC_PUSH1(&m); // the front end may add this lambda to multiple methods; make a copy if so jl_method_t *oldm = definition->def; int reused = oldm != NULL; if (reused) definition = jl_copy_lambda(definition); definition->specTypes = isstaged ? jl_anytuple_type : sig; m->lambda_template = definition; jl_gc_wb(m, definition); definition->def = m; jl_gc_wb(definition, m); if (reused) { m->file = oldm->file; m->line = oldm->line; m->called = oldm->called; } else { jl_array_t *stmts = (jl_array_t*)definition->code; int i, l; for(i = 0, l = jl_array_len(stmts); i < l; i++) { jl_array_ptr_set(stmts, i, jl_resolve_globals(jl_array_ptr_ref(stmts, i), definition)); } jl_method_init_properties(m); } JL_GC_POP(); return m; }