void mexecute(u16 n, const char *name, int count, fncode fn) /* Effects: Generates code to call function in variable n, with count arguments */ { struct string *mod; int status = module_vstatus(fnglobals(fn), n, &mod); if (!in_glist(n, definable) && !in_glist(n, readable) && !in_glist(n, writable)) { if (status == var_module) { /* Implicitly import protected modules */ if (module_status(fnglobals(fn), mod->str) != module_protected && !all_readable && imported(mod->str) == module_unloaded) log_error("read of global %s (module %s)", name, mod->str); } else if (!all_readable) log_error("read of global %s", name); } if (count == 1) ins2(op_execute_global1, n, fn); else if (count == 2) ins2(op_execute_global2, n, fn); else { /* Could have an op_execute_global */ ins2(op_recall + global_var, n, fn); ins1(op_execute, count, fn); } }
void mrecall(u16 n, const char *name, fncode fn) /* Effects: Generate code to recall variable n */ { struct string *mod; struct global_state *gstate = fnglobals(fn); int status = module_vstatus(gstate, n, &mod); if (!in_glist(n, definable) && !in_glist(n, readable) && !in_glist(n, writable)) { if (status == var_module) { /* Implicitly import protected modules */ if (module_status(gstate, mod->str) == module_protected) { if (immutablep(GVAR(gstate, n))) /* Use value */ { ins_constant(GVAR(gstate, n), fn); return; } } else if (!all_readable && imported(mod->str) == module_unloaded) log_error("read of global %s (module %s)", name, mod->str); } else if (!all_readable) log_error("read of global %s", name); } ins2(op_recall + global_var, n, fn); }
CC compile_and_run(block_t region, struct global_state *gstate, const char *nicename, u8 *noreload, bool dontrun) { struct compile_and_run_frame *frame; struct compile_context *ccontext; GCPRO1(gstate); frame = push_frame(compile_and_run_action, sizeof(struct compile_and_run_frame)); ccontext = (struct compile_context *)allocate_record(type_vector, 2); frame->dontrun = dontrun; frame->ps.ccontext = ccontext; ccontext->gstate = gstate; /* no evaluation_state yet */ GCPOP(1); frame->state = init; if (!region) region = new_block(); frame->parser_block = region; /* Set filename */ lexloc.filename = bstrdup(region, nicename); normal_lexing(); if ((frame->f = parse(frame->parser_block))) { if (noreload) { if (frame->f->name && module_status(frame->ps.ccontext->gstate, frame->f->name) != module_unloaded) { free_block(frame->parser_block); *noreload = TRUE; FA_POP(&fp, &sp); return; } *noreload = FALSE; } if (mprepare(&frame->ps, frame->parser_block, frame->f)) { frame->state = preparing; continue_prepare(frame); return; } } runtime_error(error_compile_error); }
void mprepare_load_next_done(struct mprepare_state *s) { vlist mod = s->modules; int mstatus = module_status(s->ccontext->gstate, mod->var); stack_pop(); if (mstatus < module_loaded) { if (mstatus == module_loading) log_error("loop in requires of %s", mod->var); else warning("failed to load %s", mod->var); s->all_loaded = FALSE; } s->lmodules = new_mlist(s->heap, mod->var, mstatus, s->lmodules); s->modules = mod->next; }