static void continue_prepare(struct compile_and_run_frame *frame) { value closure; struct global_state *gcopy; if (mprepare_load_next_start(&frame->ps)) return; mprepare_vars(&frame->ps); gcopy = copy_global_state(frame->ps.ccontext->gstate); GCPRO1(gcopy); closure = compile_code(frame->ps.ccontext->gstate, frame->f->body); GCPOP(1); if (closure) { GCPRO1(closure); if (debug_lvl > 1) output_value(muderr, prt_examine, closure); frame->state = running; if (frame->dontrun) { /* Just leave the closure itself as the result */ stack_reserve(sizeof(value)); stack_push(closure); } else push_closure(closure, 0); GCPOP(1); return; } global_set(frame->ps.ccontext->gstate, gcopy); runtime_error(error_compile_error); }
void *push_frame(framekind action, uvalue size) { u8 *oldfp = fp; struct generic_frame *frame; stack_reserve(size); sp -= size; fp = sp; frame = (struct generic_frame *)fp; frame->action = action; frame->oldfp = oldfp; return frame; }
struct closure *unsafe_alloc_and_push_closure(u8 nb_variables) { /* This could (should?) be optimised to avoid the need for GCPRO1/stack_reserve/GCPOP */ struct closure *newp = (struct closure *)unsafe_allocate_record(type_function, nb_variables + 1); SET_READONLY(newp); GCPRO1(newp); stack_reserve(sizeof(value)); GCPOP(1); stack_push(newp); return newp; }