+VM_DEFINE_INSTRUCTION (83, prompt, "prompt", 4, 2, 0)
+{
+ scm_t_int32 offset;
+ scm_t_uint8 escape_only_p;
+ SCM k, prompt;
+
+ escape_only_p = FETCH ();
+ FETCH_OFFSET (offset);
+ POP (k);
+
+ SYNC_REGISTER ();
+ /* Push the prompt onto the dynamic stack. */
+ prompt = scm_c_make_prompt (k, fp, sp, ip + offset, escape_only_p, vm_cookie,
+ scm_i_dynwinds ());
+ scm_i_set_dynwinds (scm_cons (prompt, SCM_PROMPT_DYNWINDS (prompt)));
+ if (SCM_PROMPT_SETJMP (prompt))
+ {
+ /* The prompt exited nonlocally. Cache the regs back from the vp, and go
+ to the handler.
+
+ Note, at this point, we must assume that any variable local to
+ vm_engine that can be assigned *has* been assigned. So we need to pull
+ all our state back from the ip/fp/sp.
+ */
+ CACHE_REGISTER ();
+ program = SCM_FRAME_PROGRAM (fp);
+ CACHE_PROGRAM ();
+ NEXT;
+ }
+
+ /* Otherwise setjmp returned for the first time, so we go to execute the
+ prompt's body. */
+ NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (85, wind, "wind", 0, 2, 0)
+{
+ SCM wind, unwind;
+ POP (unwind);
+ POP (wind);
+ SYNC_REGISTER ();
+ /* Push wind and unwind procedures onto the dynamic stack. Note that neither
+ are actually called; the compiler should emit calls to wind and unwind for
+ the normal dynamic-wind control flow. */
+ if (SCM_UNLIKELY (scm_is_false (scm_thunk_p (wind))))
+ {
+ finish_args = wind;
+ goto vm_error_not_a_thunk;
+ }
+ if (SCM_UNLIKELY (scm_is_false (scm_thunk_p (unwind))))
+ {
+ finish_args = unwind;
+ goto vm_error_not_a_thunk;
+ }
+ scm_i_set_dynwinds (scm_cons (scm_cons (wind, unwind), scm_i_dynwinds ()));
+ NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (86, abort, "abort", 1, -1, -1)
+{
+ unsigned n = FETCH ();
+ SYNC_REGISTER ();
+ if (sp - n - 2 <= SCM_FRAME_UPPER_ADDRESS (fp))
+ goto vm_error_stack_underflow;
+ vm_abort (vm, n, vm_cookie);
+ /* vm_abort should not return */
+ abort ();
+}
+
+VM_DEFINE_INSTRUCTION (87, unwind, "unwind", 0, 0, 0)
+{
+ /* A normal exit from the dynamic extent of an expression. Pop the top entry
+ off of the dynamic stack. */
+ scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
+ NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (90, wind_fluids, "wind-fluids", 1, -1, 0)
+{
+ unsigned n = FETCH ();
+ SCM wf;
+
+ if (sp - 2*n < SCM_FRAME_UPPER_ADDRESS (fp))
+ goto vm_error_stack_underflow;
+
+ SYNC_REGISTER ();
+ wf = scm_i_make_with_fluids (n, sp + 1 - 2*n, sp + 1 - n);
+ scm_i_swap_with_fluids (wf, dynstate);
+ scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
+ NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (91, unwind_fluids, "unwind-fluids", 0, 0, 0)
+{
+ SCM wf;
+ wf = scm_car (scm_i_dynwinds ());
+ scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
+ scm_i_swap_with_fluids (wf, dynstate);
+ NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (92, fluid_ref, "fluid-ref", 0, 1, 1)
+{
+ size_t num;
+ SCM fluids;
+
+ CHECK_UNDERFLOW ();
+ fluids = SCM_I_DYNAMIC_STATE_FLUIDS (dynstate);
+ if (SCM_UNLIKELY (!SCM_I_FLUID_P (*sp))
+ || ((num = SCM_I_FLUID_NUM (*sp)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids)))
+ {
+ /* Punt dynstate expansion and error handling to the C proc. */
+ SYNC_REGISTER ();
+ *sp = scm_fluid_ref (*sp);
+ }
+ else
+ *sp = SCM_SIMPLE_VECTOR_REF (fluids, num);
+
+ NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (93, fluid_set, "fluid-set", 0, 2, 0)
+{
+ size_t num;
+ SCM val, fluid, fluids;
+
+ POP (val);
+ POP (fluid);
+ fluids = SCM_I_DYNAMIC_STATE_FLUIDS (dynstate);
+ if (SCM_UNLIKELY (!SCM_I_FLUID_P (fluid))
+ || ((num = SCM_I_FLUID_NUM (fluid)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids)))
+ {
+ /* Punt dynstate expansion and error handling to the C proc. */
+ SYNC_REGISTER ();
+ scm_fluid_set_x (fluid, val);
+ }
+ else
+ SCM_SIMPLE_VECTOR_SET (fluids, num, val);
+
+ NEXT;
+}
+
+VM_DEFINE_INSTRUCTION (95, assert_nargs_ee_locals, "assert-nargs-ee/locals", 1, 0, 0)
+{
+ scm_t_ptrdiff n;
+ SCM *old_sp;
+
+ /* nargs = n & 0x7, nlocs = nargs + (n >> 3) */
+ n = FETCH ();
+
+ if (SCM_UNLIKELY (sp - (fp - 1) != (n & 0x7)))
+ goto vm_error_wrong_num_args;
+
+ old_sp = sp;
+ sp += (n >> 3);
+ CHECK_OVERFLOW ();
+ while (old_sp < sp)
+ *++old_sp = SCM_UNDEFINED;
+
+ NEXT;
+}
+