Mostly reformatting.
authorStephen Adams <edu/mit/csail/zurich/adams>
Wed, 26 Jul 1995 21:16:17 +0000 (21:16 +0000)
committerStephen Adams <edu/mit/csail/zurich/adams>
Wed, 26 Jul 1995 21:16:17 +0000 (21:16 +0000)
Merged in changes in 7.4 since split fixnum type-codes.

v8/src/microcode/interp.c

index 559c62281f4c31b3ea04035f95b7301e46f24cc9..ed28054dadd46229feecb4b8cec0ab1537ec3773 100644 (file)
 /* -*-C-*-
 
-$Id: interp.c,v 9.84 1994/06/02 19:13:16 cph Exp $
+$Id: interp.c,v 9.85 1995/07/26 21:16:17 adams Exp $
+
+Copyright (c) 1988-1995 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+/* This file contains the heart of the SCode interpreter. */
+
+#define In_Main_Interpreter true
+#include "scheme.h"
+#include "locks.h"
+#include "trap.h"
+#include "lookup.h"
+#include "winder.h"
+#include "history.h"
+#include "cmpint.h"
+#include "zones.h"
+#include "prmcon.h"
+
+extern PTR EXFUN (obstack_chunk_alloc, (unsigned int size));
+extern void EXFUN (free, (PTR ptr));
+#define obstack_chunk_free free
+extern void EXFUN (back_out_of_primitive_internal, (void));
+extern void EXFUN (preserve_signal_mask, (void));
+\f
+/* In order to make the interpreter tail recursive (i.e.
+ * to avoid calling procedures and thus saving unnecessary
+ * state information), the main body of the interpreter
+ * is coded in a continuation passing style.
+ *
+ * Basically, this is done by dispatching on the type code
+ * for an Scode item.  At each dispatch, some processing
+ * is done which may include setting the return address
+ * register, saving the current continuation (return address
+ * and current expression) and jumping to the start of
+ * the interpreter.
+ *
+ * It may be helpful to think of this program as being what
+ * you would get if you wrote the straightforward Scheme
+ * interpreter and then converted it into continuation
+ * passing style as follows.  At every point where you would
+ * call EVAL to handle a sub-form, you put a jump back to
+ * Do_Expression.  Now, if there was code after the call to
+ * EVAL you first push a "return code" (using Save_Cont) on
+ * the stack and move the code that used to be after the
+ * call down into the part of this file after the tag
+ * Pop_Return.
+ *
+ * Notice that because of the caller saves convention used
+ * here, all of the registers which are of interest have
+ * been SAVEd on the racks by the time interpretation arrives
+ * at Do_Expression (the top of EVAL).
+ *
+ * For notes on error handling and interrupts, see the file
+ * utils.c.
+ *
+ * This file is divided into two parts. The first
+ * corresponds is called the EVAL dispatch, and is ordered
+ * alphabetically by the SCode item handled.  The second,
+ * called the return dispatch, begins at Pop_Return and is
+ * ordered alphabetically by return code name.
+ */
+\f
+#define Prepare_Pop_Return_Interrupt(Return_Code, Contents_of_Val)     \
+{                                                                      \
+  SCHEME_OBJECT temp;                                                  \
+                                                                       \
+  temp = (Contents_of_Val);                                            \
+  Store_Return(Return_Code);                                           \
+  Save_Cont();                                                         \
+  Store_Return(RC_RESTORE_VALUE);                                      \
+  Store_Expression(temp);                                              \
+  Save_Cont();                                                         \
+}
+
+#define Interrupt(Masked_Code)                                         \
+{                                                                      \
+  Export_Registers();                                                  \
+  Setup_Interrupt(Masked_Code);                                                \
+  Import_Registers();                                                  \
+  goto Perform_Application;                                            \
+}
+
+#define Immediate_GC(N)                                                        \
+{                                                                      \
+  Request_GC(N);                                                       \
+  Interrupt(PENDING_INTERRUPTS());                                     \
+}
+
+#define Eval_GC_Check(Amount)                                          \
+if (GC_Check(Amount))                                                  \
+{                                                                      \
+  Prepare_Eval_Repeat();                                               \
+  Immediate_GC(Amount);                                                        \
+}
+\f
+#define Prepare_Eval_Repeat()                                          \
+{                                                                      \
+ Will_Push(CONTINUATION_SIZE+1);                                       \
+  STACK_PUSH (Fetch_Env());                                            \
+  Store_Return(RC_EVAL_ERROR);                                         \
+  Save_Cont();                                                         \
+ Pushed();                                                             \
+}
+
+#define Eval_Error(Err)                                                        \
+{                                                                      \
+  Export_Registers();                                                  \
+  Do_Micro_Error(Err, false);                                          \
+  Import_Registers();                                                  \
+  goto Internal_Apply;                                                 \
+}
+
+#define Pop_Return_Error(Err)                                          \
+{                                                                      \
+  Export_Registers();                                                  \
+  Do_Micro_Error(Err, true);                                           \
+  Import_Registers();                                                  \
+  goto Internal_Apply;                                                 \
+}
+
+#define BACK_OUT_AFTER_PRIMITIVE()                                     \
+{                                                                      \
+  Export_Registers();                                                  \
+  back_out_of_primitive_internal ();                                   \
+  Import_Registers();                                                  \
+}
+\f
+#define Reduces_To(Expr)                                               \
+       { Store_Expression(Expr);                                       \
+          New_Reduction(Fetch_Expression(), Fetch_Env());              \
+          goto Do_Expression;                                          \
+        }
+
+#define Reduces_To_Nth(N)                                              \
+        Reduces_To(FAST_MEMORY_REF (Fetch_Expression(), (N)))
+
+#define Do_Nth_Then(Return_Code, N, Extra)                             \
+       { Store_Return(Return_Code);                                    \
+         Save_Cont();                                                  \
+         Store_Expression(FAST_MEMORY_REF (Fetch_Expression(), (N)));  \
+         New_Subproblem(Fetch_Expression(), Fetch_Env());              \
+          Extra;                                                       \
+         goto Do_Expression;                                           \
+        }
+
+#define Do_Another_Then(Return_Code, N)                                        \
+       { Store_Return(Return_Code);                                    \
+          Save_Cont();                                                 \
+         Store_Expression(FAST_MEMORY_REF (Fetch_Expression(), (N)));  \
+         Reuse_Subproblem(Fetch_Expression(), Fetch_Env());            \
+         goto Do_Expression;                                           \
+        }
+\f
+                      /***********************/
+                      /* Macros for Stepping */
+                      /***********************/
+
+#define Fetch_Trapper(field)   \
+  MEMORY_REF (Get_Fixed_Obj_Slot(Stepper_State), (field))
+
+#define Fetch_Eval_Trapper() Fetch_Trapper(HUNK_CXR0)
+#define Fetch_Apply_Trapper() Fetch_Trapper(HUNK_CXR1)
+#define Fetch_Return_Trapper() Fetch_Trapper(HUNK_CXR2)
+\f
+/* Macros for handling FUTUREs */
+
+#ifdef COMPILE_FUTURES
+
+/* ARG_TYPE_ERROR handles the error returns from primitives which type check
+   their arguments and restarts them or suspends if the argument is a future.
+ */
+
+#define ARG_TYPE_ERROR(Arg_No, Err_No)                                 \
+{                                                                      \
+  fast SCHEME_OBJECT *Arg, Orig_Arg;                                   \
+                                                                       \
+  Arg = &(STACK_REF((Arg_No - 1) + STACK_ENV_FIRST_ARG));              \
+  Orig_Arg = *Arg;                                                     \
+                                                                       \
+  if (OBJECT_TYPE (*Arg) != TC_FUTURE)                                 \
+  {                                                                    \
+    Pop_Return_Error(Err_No);                                          \
+  }                                                                    \
+                                                                       \
+  while ((OBJECT_TYPE (*Arg) == TC_FUTURE) && (Future_Has_Value(*Arg)))        \
+  {                                                                    \
+    if (Future_Is_Keep_Slot(*Arg))                                     \
+    {                                                                  \
+      Log_Touch_Of_Future(*Arg);                                       \
+    }                                                                  \
+    *Arg = Future_Value(*Arg);                                         \
+  }                                                                    \
+  if (OBJECT_TYPE (*Arg) != TC_FUTURE)                                 \
+  {                                                                    \
+    goto Apply_Non_Trapping;                                           \
+  }                                                                    \
+                                                                       \
+  TOUCH_SETUP(*Arg);                                                   \
+  *Arg = Orig_Arg;                                                     \
+  goto Apply_Non_Trapping;                                             \
+}
+\f
+/* Apply_Future_Check is called at apply time to guarantee that certain
+   objects (the procedure itself, and its LAMBDA components for user defined
+   procedures) are not futures
+*/
+
+#define Apply_Future_Check(Name, Object)                               \
+{                                                                      \
+  fast SCHEME_OBJECT *Arg, Orig_Answer;                                        \
+                                                                       \
+  Arg = &(Object);                                                     \
+  Orig_Answer = *Arg;                                                  \
+                                                                       \
+  while (OBJECT_TYPE (*Arg) == TC_FUTURE)                              \
+  {                                                                    \
+    if (Future_Has_Value(*Arg))                                                \
+    {                                                                  \
+      if (Future_Is_Keep_Slot(*Arg))                                   \
+      {                                                                        \
+       Log_Touch_Of_Future(*Arg);                                      \
+      }                                                                        \
+      *Arg = Future_Value(*Arg);                                       \
+    }                                                                  \
+    else                                                               \
+    {                                                                  \
+      Prepare_Apply_Interrupt ();                                      \
+      TOUCH_SETUP (*Arg);                                              \
+      *Arg = Orig_Answer;                                              \
+      goto Internal_Apply;                                             \
+    }                                                                  \
+  }                                                                    \
+  Name = *Arg;                                                         \
+}
+
+/* Future handling macros continue on the next page */
+\f
+/* Future handling macros, continued */
+
+/* Pop_Return_Val_Check suspends the process if the value calculated by
+   a recursive call to EVAL is an undetermined future */
+
+#define Pop_Return_Val_Check()                                         \
+{                                                                      \
+  fast SCHEME_OBJECT Orig_Val = Val;                                   \
+                                                                       \
+  while (OBJECT_TYPE (Val) == TC_FUTURE)                               \
+  {                                                                    \
+    if (Future_Has_Value(Val))                                         \
+    {                                                                  \
+      if (Future_Is_Keep_Slot(Val))                                    \
+      {                                                                        \
+       Log_Touch_Of_Future(Val);                                       \
+      }                                                                        \
+      Val = Future_Value(Val);                                         \
+    }                                                                  \
+    else                                                               \
+    {                                                                  \
+      Save_Cont();                                                     \
+     Will_Push(CONTINUATION_SIZE + (STACK_ENV_EXTRA_SLOTS + 2));       \
+      Store_Return(RC_RESTORE_VALUE);                                  \
+      Store_Expression(Orig_Val);                                      \
+      Save_Cont();                                                     \
+      STACK_PUSH (Val);                                                        \
+      STACK_PUSH (Get_Fixed_Obj_Slot(System_Scheduler));               \
+      STACK_PUSH (STACK_FRAME_HEADER + 1);                             \
+     Pushed();                                                         \
+      goto Internal_Apply;                                             \
+    }                                                                  \
+  }                                                                    \
+}
+\f
+/* This saves stuff unnecessarily in most cases.
+   For example, when Which_Way is PRIM_APPLY, Val, Env, Expr,
+   and Return_Code are undefined.
+ */
+
+#define LOG_FUTURES()                                                  \
+{                                                                      \
+  if (Must_Report_References())                                                \
+  {                                                                    \
+    Save_Cont();                                                       \
+   Will_Push(CONTINUATION_SIZE + 2);                                   \
+    STACK_PUSH (Val);                                                  \
+    Save_Env();                                                                \
+    Store_Return(RC_REPEAT_DISPATCH);                                  \
+    Store_Expression(LONG_TO_FIXNUM(CODE_MAP(Which_Way)));             \
+    Save_Cont();                                                       \
+   Pushed();                                                           \
+    Call_Future_Logging();                                             \
+ }                                                                     \
+}
+
+#else /* not COMPILE_FUTURES */
+
+#define Pop_Return_Val_Check()
+
+#define Apply_Future_Check(Name, Object)       Name = (Object)
+
+#define ARG_TYPE_ERROR(Arg_No, Err_No)                                 \
+{                                                                      \
+  Pop_Return_Error(Err_No)                                             \
+}
+
+#define LOG_FUTURES()
+
+#endif /* COMPILE_FUTURES */
+\f
+/* Notes on Repeat_Dispatch:
+
+   The codes used (values of Which_Way) are divided into two groups:
+   Those for which the primitive has already backed out, and those for
+   which the back out code has not yet been executed, and is therefore
+   executed below.
+
+   Under most circumstances the distinction is moot, but if there are
+   futures in the system, and future touches must be logged, the code
+   must be set up to "interrupt" the dispatch, and proceed it later.
+   The primitive back out code must be done before the furure is
+   logged, so all of these codes are split into two versions: one set
+   before doing the back out, and another afterwards.
+ */
+
+/* This is assumed to be larger (in absolute value) than any PRIM_<mumble>
+   and ERR_<mumble>.
+ */
+#define PRIM_BIAS_AMOUNT 1000
+
+#if (MAX_ERROR >= PRIM_BIAS_AMOUNT)
+#include "Inconsistency: errors.h and interp.c"
+#endif
+
+#define CODE_MAP(code)                                                 \
+((code < 0) ?                                                          \
+ (code - PRIM_BIAS_AMOUNT) :                                           \
+ (code + PRIM_BIAS_AMOUNT))
+
+#define CODE_UNMAP(code)                                               \
+((code < 0) ?                                                          \
+ (code + PRIM_BIAS_AMOUNT) :                                           \
+ (code - PRIM_BIAS_AMOUNT))
+
+#define CODE_MAPPED_P(code)                                            \
+((code < (- PRIM_BIAS_AMOUNT)) ||                                      \
+ (code >= PRIM_BIAS_AMOUNT))
+
+#define PROCEED_AFTER_PRIMITIVE()                                      \
+{                                                                      \
+  (Regs [REGBLOCK_PRIMITIVE]) = SHARP_F;                               \
+  LOG_FUTURES ();                                                      \
+}
+\f
+/*
+  The EVAL/APPLY ying/yang
+ */
+
+
+interpreter_state_t interpreter_state = NULL_INTERPRETER_STATE;
+
+void
+DEFUN (bind_interpreter_state, (s), interpreter_state_t s)
+{
+  (s -> previous_state) = interpreter_state;
+  (s -> nesting_level) =
+    ((interpreter_state == NULL_INTERPRETER_STATE)
+     ? 0
+     : (1 + (interpreter_state -> nesting_level)));
+  (s -> dstack_position) = dstack_position;
+  interpreter_state = s;
+}
+
+void
+DEFUN (unbind_interpreter_state, (s), interpreter_state_t s)
+{
+  interpreter_state = s;
+  {
+    long old_mask = (FETCH_INTERRUPT_MASK ());
+    SET_INTERRUPT_MASK (0);
+    dstack_set_position (s -> dstack_position);
+    SET_INTERRUPT_MASK (old_mask);
+  }
+  interpreter_state = (s -> previous_state);
+}
+
+void
+DEFUN (abort_to_interpreter, (argument), int argument)
+{
+  if (interpreter_state == NULL_INTERPRETER_STATE)
+  {
+    outf_fatal ("abort_to_interpreter: Interpreter not set up.\n");
+    termination_init_error ();
+  }
+  
+  interpreter_throw_argument = argument;
+  {
+    long old_mask = (FETCH_INTERRUPT_MASK ());
+    SET_INTERRUPT_MASK (0);
+    dstack_set_position (interpreter_catch_dstack_position);
+    SET_INTERRUPT_MASK (old_mask);
+  }
+  obstack_free ((&scratch_obstack), 0);
+  obstack_init (&scratch_obstack);
+  longjmp (interpreter_catch_env, argument);
+}
+
+int
+DEFUN_VOID (abort_to_interpreter_argument)
+{
+  return (interpreter_throw_argument);
+}
+\f
+extern void EXFUN (Interpret, (Boolean));
+
+void
+DEFUN (Interpret, (pop_return_p), Boolean pop_return_p)
+{
+  long Which_Way;
+  fast SCHEME_OBJECT * Reg_Block, * Reg_Stack_Pointer, * Reg_History;
+  struct interpreter_state_s new_state;
+  extern long enter_compiled_expression();
+  extern long apply_compiled_procedure();
+  extern long return_to_compiled_code();
+
+  Reg_Block = &Registers[0];
+
+  /* Primitives jump back here for errors, requests to evaluate an
+   * expression, apply a function, or handle an interrupt request.  On
+   * errors or interrupts they leave their arguments on the stack, the
+   * primitive itself in Expression.  The code should do a primitive
+   * backout in these cases, but not in others (apply, eval, etc.), since
+   * the primitive itself will have left the state of the interpreter ready
+   * for operation.
+   */
+
+  bind_interpreter_state (&new_state);
+  preserve_signal_mask ();
+  Which_Way = (setjmp (interpreter_catch_env));
+  Set_Time_Zone (Zone_Working);
+  Import_Registers ();
+\f
+Repeat_Dispatch:
+  switch (Which_Way)
+  {
+    case PRIM_APPLY:
+      PROCEED_AFTER_PRIMITIVE();
+    case CODE_MAP(PRIM_APPLY):
+      goto Internal_Apply;
+
+    case PRIM_NO_TRAP_APPLY:
+      PROCEED_AFTER_PRIMITIVE();
+    case CODE_MAP(PRIM_NO_TRAP_APPLY):
+      goto Apply_Non_Trapping;
+
+    case PRIM_DO_EXPRESSION:
+      Val = Fetch_Expression();
+      PROCEED_AFTER_PRIMITIVE();
+    case CODE_MAP(PRIM_DO_EXPRESSION):
+      Reduces_To(Val);
+
+    case PRIM_NO_TRAP_EVAL:
+      Val = Fetch_Expression();
+      PROCEED_AFTER_PRIMITIVE();
+    case CODE_MAP(PRIM_NO_TRAP_EVAL):
+      New_Reduction(Val, Fetch_Env());
+      goto Eval_Non_Trapping;
+
+    case 0:                    /* first time */
+      if (pop_return_p)
+       goto Pop_Return;
+      else
+       break;                  /* fall into eval */
+
+    case PRIM_POP_RETURN:
+      PROCEED_AFTER_PRIMITIVE();
+    case CODE_MAP(PRIM_POP_RETURN):
+      goto Pop_Return;
+
+    case PRIM_NO_TRAP_POP_RETURN:
+      PROCEED_AFTER_PRIMITIVE();
+    case CODE_MAP(PRIM_NO_TRAP_POP_RETURN):
+      goto Pop_Return_Non_Trapping;
+
+    case PRIM_REENTER:
+      BACK_OUT_AFTER_PRIMITIVE();
+      LOG_FUTURES();
+    case CODE_MAP(PRIM_REENTER):
+      goto Perform_Application;
+\f
+    case PRIM_TOUCH:
+    {
+      SCHEME_OBJECT temp;
+
+      temp = Val;
+      BACK_OUT_AFTER_PRIMITIVE();
+      Val = temp;
+      LOG_FUTURES();
+    }
+    /* fall through */
+    case CODE_MAP(PRIM_TOUCH):
+      TOUCH_SETUP(Val);
+      goto Internal_Apply;
+
+    case PRIM_INTERRUPT:
+      BACK_OUT_AFTER_PRIMITIVE();
+      LOG_FUTURES();
+      /* fall through */
+    case CODE_MAP(PRIM_INTERRUPT):
+      Save_Cont();
+      Interrupt(PENDING_INTERRUPTS());
+
+    case ERR_ARG_1_WRONG_TYPE:
+      BACK_OUT_AFTER_PRIMITIVE();
+      LOG_FUTURES();
+      /* fall through */
+    case CODE_MAP(ERR_ARG_1_WRONG_TYPE):
+      ARG_TYPE_ERROR(1, ERR_ARG_1_WRONG_TYPE);
+
+    case ERR_ARG_2_WRONG_TYPE:
+      BACK_OUT_AFTER_PRIMITIVE();
+      LOG_FUTURES();
+      /* fall through */
+    case CODE_MAP(ERR_ARG_2_WRONG_TYPE):
+      ARG_TYPE_ERROR(2, ERR_ARG_2_WRONG_TYPE);
+
+    case ERR_ARG_3_WRONG_TYPE:
+      BACK_OUT_AFTER_PRIMITIVE();
+      LOG_FUTURES();
+      /* fall through */
+    case CODE_MAP(ERR_ARG_3_WRONG_TYPE):
+      ARG_TYPE_ERROR(3, ERR_ARG_3_WRONG_TYPE);
+
+    default:
+    {
+      if (!CODE_MAPPED_P(Which_Way))
+      {
+       BACK_OUT_AFTER_PRIMITIVE();
+       LOG_FUTURES();
+      }
+      else
+      {
+       Which_Way = CODE_UNMAP(Which_Way);
+      }
+      Pop_Return_Error(Which_Way);
+    }
+  }
+\f
+Do_Expression:
+
+  if (0 && Eval_Debug)
+  {
+    Print_Expression ((Fetch_Expression ()), "Eval, expression");
+    outf_console ("\n");
+  }
+
+/* The expression register has an Scode item in it which
+ * should be evaluated and the result left in Val.
+ *
+ * A "break" after the code for any operation indicates that
+ * all processing for this operation has been completed, and
+ * the next step will be to pop a return code off the stack
+ * and proceed at Pop_Return.  This is sometimes called
+ * "executing the continuation" since the return code can be
+ * considered the continuation to be performed after the
+ * operation.
+ *
+ * An operation can terminate with a Reduces_To or
+ * Reduces_To_Nth macro.  This indicates that the  value of
+ * the current Scode item is the value returned when the
+ * new expression is evaluated.  Therefore no new
+ * continuation is created and processing continues at
+ * Do_Expression with the new expression in the expression
+ * register.
+ *
+ * Finally, an operation can terminate with a Do_Nth_Then
+ * macro.  This indicates that another expression must be
+ * evaluated and them some additional processing will be
+ * performed before the value of this S-Code item available.
+ * Thus a new continuation is created and placed on the
+ * stack (using Save_Cont), the new expression is placed in
+ * the Expression register, and processing continues at
+ * Do_Expression.
+ */
+
+/* Handling of Eval Trapping.
+
+   If we are handling traps and there is an Eval Trap set,
+   turn off all trapping and then go to Internal_Apply to call the
+   user supplied eval hook with the expression to be evaluated and the
+   environment. */
+
+  if (Microcode_Does_Stepping &&
+      Trapping &&
+      (! WITHIN_CRITICAL_SECTION_P()) &&
+      ((Fetch_Eval_Trapper ()) != SHARP_F))
+  {
+    Stop_Trapping ();
+   Will_Push (4);
+    STACK_PUSH (Fetch_Env ());
+    STACK_PUSH (Fetch_Expression ());
+    STACK_PUSH (Fetch_Eval_Trapper ());
+    STACK_PUSH (STACK_FRAME_HEADER + 2);
+   Pushed ();
+    goto Apply_Non_Trapping;
+  }
+\f
+Eval_Non_Trapping:
+  Eval_Ucode_Hook();
+  switch (OBJECT_TYPE (Fetch_Expression()))
+  {
+    default:
+#if FALSE
+      Eval_Error(ERR_UNDEFINED_USER_TYPE);
+#else
+      /* fall through to self evaluating. */
+#endif
+
+    case TC_BIG_FIXNUM:         /* The self evaluating items */
+    case TC_BIG_FLONUM:
+    case TC_CHARACTER_STRING:
+    case TC_CHARACTER:
+    case TC_COMPILED_CODE_BLOCK:
+    case TC_COMPLEX:
+    case TC_CONTROL_POINT:
+    case TC_DELAYED:
+    case TC_ENTITY:
+    case TC_ENVIRONMENT:
+    case TC_EXTENDED_PROCEDURE:
+    case TC_POSITIVE_FIXNUM:
+#if (TC_POSITIVE_FIXNUM != TC_NEGATIVE_FIXNUM)
+    case TC_NEGATIVE_FIXNUM:
+#endif
+    case TC_HUNK3_A:
+    case TC_HUNK3_B:
+    case TC_INTERNED_SYMBOL:
+    case TC_LIST:
+    case TC_NON_MARKED_VECTOR:
+    case TC_NULL:
+    case TC_PRIMITIVE:
+    case TC_PROCEDURE:
+    case TC_QUAD:
+    case TC_RATNUM:
+    case TC_REFERENCE_TRAP:
+    case TC_RETURN_CODE:
+    case TC_UNINTERNED_SYMBOL:
+    case TC_CONSTANT:
+    case TC_VECTOR:
+    case TC_VECTOR_16B:
+    case TC_VECTOR_1B:
+      Val = Fetch_Expression();
+      break;
+
+    case TC_ACCESS:
+     Will_Push(CONTINUATION_SIZE);
+      Do_Nth_Then(RC_EXECUTE_ACCESS_FINISH, ACCESS_ENVIRONMENT, Pushed());
+
+    case TC_ASSIGNMENT:
+     Will_Push(CONTINUATION_SIZE + 1);
+      Save_Env();
+      Do_Nth_Then(RC_EXECUTE_ASSIGNMENT_FINISH, ASSIGN_VALUE, Pushed());
+
+    case TC_BROKEN_HEART:
+      Export_Registers();
+      Microcode_Termination (TERM_BROKEN_HEART);
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case TC_COMBINATION:
+      {
+       long Array_Length;
+
+       Array_Length = (VECTOR_LENGTH (Fetch_Expression()) - 1);
+#ifdef USE_STACKLETS
+       /* Save_Env, Finger */
+        Eval_GC_Check(New_Stacklet_Size(Array_Length + 1 + 1 + CONTINUATION_SIZE));
+#endif /* USE_STACKLETS */
+       Will_Push(Array_Length + 1 + 1 + CONTINUATION_SIZE);
+       Stack_Pointer = (STACK_LOC (- Array_Length));
+        STACK_PUSH (MAKE_OBJECT (TC_MANIFEST_NM_VECTOR, Array_Length));
+       /* The finger: last argument number */
+       Pushed();
+        if (Array_Length == 0)
+       {
+         STACK_PUSH (STACK_FRAME_HEADER);   /* Frame size */
+          Do_Nth_Then(RC_COMB_APPLY_FUNCTION, COMB_FN_SLOT, {});
+       }
+       Save_Env();
+       Do_Nth_Then(RC_COMB_SAVE_VALUE, Array_Length+1, {});
+      }
+
+    case TC_COMBINATION_1:
+     Will_Eventually_Push(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG + 1);
+      Save_Env();
+      Do_Nth_Then(RC_COMB_1_PROCEDURE, COMB_1_ARG_1, {});
+
+    case TC_COMBINATION_2:
+     Will_Eventually_Push(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG + 2);
+      Save_Env();
+      Do_Nth_Then(RC_COMB_2_FIRST_OPERAND, COMB_2_ARG_2, {});
+
+    case TC_COMMENT:
+      Reduces_To_Nth(COMMENT_EXPRESSION);
+
+    case TC_CONDITIONAL:
+     Will_Push(CONTINUATION_SIZE + 1);
+      Save_Env();
+      Do_Nth_Then(RC_CONDITIONAL_DECIDE, COND_PREDICATE, Pushed());
+
+    case TC_COMPILED_ENTRY:
+      {
+       SCHEME_OBJECT compiled_expression;
+
+       compiled_expression = (Fetch_Expression ());
+       execute_compiled_setup();
+       Store_Expression (compiled_expression);
+       Export_Registers();
+       Which_Way = enter_compiled_expression();
+       goto return_from_compiled_code;
+      }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case TC_DEFINITION:
+     Will_Push(CONTINUATION_SIZE + 1);
+      Save_Env();
+      Do_Nth_Then(RC_EXECUTE_DEFINITION_FINISH, DEFINE_VALUE, Pushed());
+
+    case TC_DELAY:
+      /* Deliberately omitted: Eval_GC_Check(2); */
+      Val = MAKE_POINTER_OBJECT (TC_DELAYED, Free);
+      Free[THUNK_ENVIRONMENT] = Fetch_Env();
+      Free[THUNK_PROCEDURE] =
+        FAST_MEMORY_REF (Fetch_Expression(), DELAY_OBJECT);
+      Free += 2;
+      break;
+
+    case TC_DISJUNCTION:
+     Will_Push(CONTINUATION_SIZE + 1);
+      Save_Env();
+      Do_Nth_Then(RC_DISJUNCTION_DECIDE, OR_PREDICATE, Pushed());
+
+    case TC_EXTENDED_LAMBDA:   /* Close the procedure */
+    /* Deliberately omitted: Eval_GC_Check(2); */
+      Val = MAKE_POINTER_OBJECT (TC_EXTENDED_PROCEDURE, Free);
+      Free[PROCEDURE_LAMBDA_EXPR] = Fetch_Expression();
+      Free[PROCEDURE_ENVIRONMENT] = Fetch_Env();
+      Free += 2;
+      break;
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+#ifdef COMPILE_FUTURES
+    case TC_FUTURE:
+      if (Future_Has_Value(Fetch_Expression()))
+      {
+        SCHEME_OBJECT Future = Fetch_Expression();
+        if (Future_Is_Keep_Slot(Future)) Log_Touch_Of_Future(Future);
+        Reduces_To_Nth(FUTURE_VALUE);
+      }
+      Prepare_Eval_Repeat();
+     Will_Push(STACK_ENV_EXTRA_SLOTS+2);
+      STACK_PUSH (Fetch_Expression()); /* Arg: FUTURE object */
+      STACK_PUSH (Get_Fixed_Obj_Slot(System_Scheduler));
+      STACK_PUSH (STACK_FRAME_HEADER+1);
+     Pushed();
+      goto Internal_Apply;
+#endif
+
+    case TC_IN_PACKAGE:
+     Will_Push(CONTINUATION_SIZE);
+      Do_Nth_Then(RC_EXECUTE_IN_PACKAGE_CONTINUE,
+                  IN_PACKAGE_ENVIRONMENT, Pushed());
+
+    case TC_LAMBDA:             /* Close the procedure */
+    case TC_LEXPR:
+    /* Deliberately omitted: Eval_GC_Check(2); */
+      Val = MAKE_POINTER_OBJECT (TC_PROCEDURE, Free);
+      Free[PROCEDURE_LAMBDA_EXPR] = Fetch_Expression();
+      Free[PROCEDURE_ENVIRONMENT] = Fetch_Env();
+      Free += 2;
+      break;
+
+    case TC_MANIFEST_NM_VECTOR:
+    case TC_MANIFEST_SPECIAL_NM_VECTOR:
+      Eval_Error(ERR_EXECUTE_MANIFEST_VECTOR);
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    /*
+      The argument to Will_Eventually_Push is determined by how much
+      will be on the stack if we back out of the primitive.
+     */
+
+    case TC_PCOMB0:
+     Will_Eventually_Push(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG);
+     Finished_Eventual_Pushing(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG);
+      Store_Expression (OBJECT_NEW_TYPE (TC_PRIMITIVE, (Fetch_Expression ())));
+      goto Primitive_Internal_Apply;
+
+    case TC_PCOMB1:
+     Will_Eventually_Push(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG + 1);
+      Do_Nth_Then(RC_PCOMB1_APPLY, PCOMB1_ARG_SLOT, {});
+
+    case TC_PCOMB2:
+     Will_Eventually_Push(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG + 2);
+      Save_Env();
+      Do_Nth_Then(RC_PCOMB2_DO_1, PCOMB2_ARG_2_SLOT, {});
+
+    case TC_PCOMB3:
+     Will_Eventually_Push(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG + 3);
+      Save_Env();
+      Do_Nth_Then(RC_PCOMB3_DO_2, PCOMB3_ARG_3_SLOT, {});
+
+    case TC_SCODE_QUOTE:
+      Val = FAST_MEMORY_REF (Fetch_Expression(), SCODE_QUOTE_OBJECT);
+      break;
+
+    case TC_SEQUENCE_2:
+     Will_Push(CONTINUATION_SIZE + 1);
+      Save_Env();
+      Do_Nth_Then(RC_SEQ_2_DO_2, SEQUENCE_1, Pushed());
+
+    case TC_SEQUENCE_3:
+     Will_Push(CONTINUATION_SIZE + 1);
+      Save_Env();
+      Do_Nth_Then(RC_SEQ_3_DO_2, SEQUENCE_1, Pushed());
+
+    case TC_THE_ENVIRONMENT:
+      Val = Fetch_Env(); break;
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case TC_VARIABLE:
+    {
+      long temp;
+
+#ifndef No_In_Line_Lookup
+
+      fast SCHEME_OBJECT *cell;
+      SCHEME_OBJECT orig_temp, Var;
+
+      Var = Fetch_Expression();
+      Set_Time_Zone(Zone_Lookup);
+      cell = OBJECT_ADDRESS (Fetch_Expression());
+      lookup(cell, Fetch_Env(), cell, repeat_variable_lookup);
+
+lookup_end_restart:
+
+      Val = MEMORY_FETCH (cell[0]);
+      if (OBJECT_TYPE (Val) != TC_REFERENCE_TRAP)
+      {
+       Set_Time_Zone(Zone_Working);
+       goto Pop_Return;
+      }
+
+      get_trap_kind(temp, Val);
+      orig_temp = temp;
+      switch(temp)
+      {
+       case TRAP_DANGEROUS:
+       case TRAP_UNBOUND_DANGEROUS:
+       case TRAP_UNASSIGNED_DANGEROUS:
+       case TRAP_FLUID_DANGEROUS:
+       case TRAP_COMPILER_CACHED_DANGEROUS:
+         cell = OBJECT_ADDRESS (Fetch_Expression());
+         temp =
+           deep_lookup_end(deep_lookup(Fetch_Env(),
+                                       cell[VARIABLE_SYMBOL],
+                                       cell),
+                           cell);
+         Import_Val();
+         if (temp != PRIM_DONE)
+           break;
+         Set_Time_Zone(Zone_Working);
+         goto Pop_Return;
+
+       case TRAP_COMPILER_CACHED:
+         cell = MEMORY_LOC (FAST_MEMORY_REF (Val, TRAP_EXTRA),
+                               TRAP_EXTENSION_CELL);
+         goto lookup_end_restart;
+
+       case TRAP_FLUID:
+         cell = lookup_fluid(Val);
+         goto lookup_end_restart;
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+       case TRAP_UNBOUND:
+         temp = ERR_UNBOUND_VARIABLE;
+         break;
+
+       case TRAP_UNASSIGNED:
+         temp = ERR_UNASSIGNED_VARIABLE;
+         break;
+
+       default:
+         temp = ERR_ILLEGAL_REFERENCE_TRAP;
+         break;
+      }
+
+#else /* No_In_Line_Lookup */
+
+      Set_Time_Zone(Zone_Lookup);
+      temp = Lex_Ref(Fetch_Env(), Fetch_Expression());
+      Import_Val();
+      if (temp == PRIM_DONE)
+       goto Pop_Return;
+
+#endif /* No_In_Line_Lookup */
+
+      /* Back out of the evaluation. */
+
+      Set_Time_Zone(Zone_Working);
+
+      if (temp == PRIM_INTERRUPT)
+      {
+       Prepare_Eval_Repeat();
+       Interrupt(PENDING_INTERRUPTS());
+      }
+      Eval_Error(temp);
+    }
+
+    SITE_EXPRESSION_DISPATCH_HOOK()
+  };
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+/* Now restore the continuation saved during an earlier part
+ * of the EVAL cycle and continue as directed.
+ */
+
+Pop_Return:
+  if (Microcode_Does_Stepping &&
+      Trapping &&
+      (! WITHIN_CRITICAL_SECTION_P()) &&
+      ((Fetch_Return_Trapper ()) != SHARP_F))
+  {
+    Will_Push(3);
+      Stop_Trapping();
+      STACK_PUSH (Val);
+      STACK_PUSH (Fetch_Return_Trapper());
+      STACK_PUSH (STACK_FRAME_HEADER+1);
+    Pushed();
+    goto Apply_Non_Trapping;
+  }
+Pop_Return_Non_Trapping:
+  Pop_Return_Ucode_Hook();
+  Restore_Cont();
+  if (Consistency_Check &&
+      (OBJECT_TYPE (Fetch_Return()) != TC_RETURN_CODE))
+  {
+    STACK_PUSH (Val);                  /* For possible stack trace */
+    Save_Cont();
+    Export_Registers();
+    Microcode_Termination (TERM_BAD_STACK);
+  }
+  if (0 && Eval_Debug)
+  {
+    Print_Return ("Pop_Return, return code");
+    Print_Expression (Val, "Pop_Return, value");
+    outf_console ("\n");
+  };
+
+  /* Dispatch on the return code.  A BREAK here will cause
+   * a "goto Pop_Return" to occur, since this is the most
+   * common occurrence.
+   */
+
+  switch (OBJECT_DATUM (Fetch_Return()))
+  {
+    case RC_COMB_1_PROCEDURE:
+      Restore_Env();
+      STACK_PUSH (Val);                /* Arg. 1 */
+      STACK_PUSH (SHARP_F);                /* Operator */
+      STACK_PUSH (STACK_FRAME_HEADER + 1);
+     Finished_Eventual_Pushing(CONTINUATION_SIZE);
+      Do_Another_Then(RC_COMB_APPLY_FUNCTION, COMB_1_FN);
+
+    case RC_COMB_2_FIRST_OPERAND:
+      Restore_Env();
+      STACK_PUSH (Val);
+      Save_Env();
+      Do_Another_Then(RC_COMB_2_PROCEDURE, COMB_2_ARG_1);
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_COMB_2_PROCEDURE:
+      Restore_Env();
+      STACK_PUSH (Val);                /* Arg 1, just calculated */
+      STACK_PUSH (SHARP_F);            /* Function */
+      STACK_PUSH (STACK_FRAME_HEADER + 2);
+     Finished_Eventual_Pushing(CONTINUATION_SIZE);
+      Do_Another_Then(RC_COMB_APPLY_FUNCTION, COMB_2_FN);
+
+    case RC_COMB_APPLY_FUNCTION:
+       End_Subproblem();
+       goto Internal_Apply_Val;
+
+    case RC_COMB_SAVE_VALUE:
+      {        long Arg_Number;
+
+        Restore_Env();
+        Arg_Number = OBJECT_DATUM (STACK_REF(STACK_COMB_FINGER))-1;
+        STACK_REF(STACK_COMB_FIRST_ARG+Arg_Number) = Val;
+        STACK_REF(STACK_COMB_FINGER) =
+          MAKE_OBJECT (TC_MANIFEST_NM_VECTOR, Arg_Number);
+       /* DO NOT count on the type code being NMVector here, since
+          the stack parser may create them with #F here! */
+        if (Arg_Number > 0)
+        {
+          Save_Env();
+          Do_Another_Then(RC_COMB_SAVE_VALUE,
+                          (COMB_ARG_1_SLOT - 1) + Arg_Number);
+        }
+       STACK_PUSH (FAST_MEMORY_REF (Fetch_Expression(), 0)); /* Frame Size */
+        Do_Another_Then(RC_COMB_APPLY_FUNCTION, COMB_FN_SLOT);
+      }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+#define define_compiler_restart(return_code, entry)                    \
+    case return_code:                                                  \
+      {                                                                        \
+       extern long entry();                                            \
+       compiled_code_restart();                                        \
+       Export_Registers();                                             \
+       Which_Way = entry();                                            \
+       goto return_from_compiled_code;                                 \
+      }
+
+      define_compiler_restart (RC_COMP_INTERRUPT_RESTART,
+                              comp_interrupt_restart)
+
+      define_compiler_restart (RC_COMP_LOOKUP_APPLY_RESTART,
+                              comp_lookup_apply_restart)
+
+      define_compiler_restart (RC_COMP_REFERENCE_RESTART,
+                              comp_reference_restart)
+
+      define_compiler_restart (RC_COMP_ACCESS_RESTART,
+                              comp_access_restart)
+
+      define_compiler_restart (RC_COMP_UNASSIGNED_P_RESTART,
+                              comp_unassigned_p_restart)
+
+      define_compiler_restart (RC_COMP_UNBOUND_P_RESTART,
+                              comp_unbound_p_restart)
+\f
+      define_compiler_restart (RC_COMP_ASSIGNMENT_RESTART,
+                              comp_assignment_restart)
+
+      define_compiler_restart (RC_COMP_DEFINITION_RESTART,
+                              comp_definition_restart)
+
+      define_compiler_restart (RC_COMP_SAFE_REFERENCE_RESTART,
+                              comp_safe_reference_restart)
+
+      define_compiler_restart (RC_COMP_LOOKUP_TRAP_RESTART,
+                              comp_lookup_trap_restart)
+
+      define_compiler_restart (RC_COMP_ASSIGNMENT_TRAP_RESTART,
+                              comp_assignment_trap_restart)
+
+      define_compiler_restart (RC_COMP_OP_REF_TRAP_RESTART,
+                              comp_op_lookup_trap_restart)
+
+      define_compiler_restart (RC_COMP_CACHE_REF_APPLY_RESTART,
+                              comp_cache_lookup_apply_restart)
+
+      define_compiler_restart (RC_COMP_SAFE_REF_TRAP_RESTART,
+                              comp_safe_lookup_trap_restart)
+
+      define_compiler_restart (RC_COMP_UNASSIGNED_TRAP_RESTART,
+                              comp_unassigned_p_trap_restart)
+
+      define_compiler_restart (RC_COMP_LINK_CACHES_RESTART,
+                              comp_link_caches_restart)
+
+      define_compiler_restart (RC_COMP_LINK_CACHES_CONTINUE,
+                              comp_link_caches_continue)
+
+      define_compiler_restart (RC_COMP_ERROR_RESTART,
+                              comp_error_restart)
+\f
+    case RC_REENTER_COMPILED_CODE:
+      compiled_code_restart();
+      Export_Registers();
+      Which_Way = return_to_compiled_code();
+      goto return_from_compiled_code;
+
+    case RC_CONDITIONAL_DECIDE:
+      Pop_Return_Val_Check();
+      End_Subproblem();
+      Restore_Env();
+      Reduces_To_Nth ((Val == SHARP_F) ? COND_ALTERNATIVE : COND_CONSEQUENT);
+
+    case RC_DISJUNCTION_DECIDE:
+      /* Return predicate if it isn't #F; else do ALTERNATIVE */
+      Pop_Return_Val_Check();
+      End_Subproblem();
+      Restore_Env();
+      if (Val != SHARP_F) goto Pop_Return;
+      Reduces_To_Nth(OR_ALTERNATIVE);
+
+    case RC_END_OF_COMPUTATION:
+    {
+      /* Signals bottom of stack */
+
+      interpreter_state_t previous_state;
+
+      previous_state = interpreter_state->previous_state;
+      Export_Registers();
+      if (previous_state == NULL_INTERPRETER_STATE)
+      {
+       termination_end_of_computation ();
+       /*NOTREACHED*/
+      }
+      else
+      {
+       dstack_position = interpreter_catch_dstack_position;
+       interpreter_state = previous_state;
+       return;
+      }
+    }
+
+    case RC_EVAL_ERROR:
+      /* Should be called RC_REDO_EVALUATION. */
+      Store_Env(STACK_POP ());
+      Reduces_To(Fetch_Expression());
+\f
+    case RC_EXECUTE_ACCESS_FINISH:
+    {
+      long Result;
+      SCHEME_OBJECT value;
+
+      Pop_Return_Val_Check();
+      value = Val;
+
+      if (ENVIRONMENT_P (Val))
+      {
+        Result = Symbol_Lex_Ref(value,
+                               FAST_MEMORY_REF (Fetch_Expression(),
+                                               ACCESS_NAME));
+       Import_Val();
+       if (Result == PRIM_DONE)
+       {
+         End_Subproblem();
+         break;
+       }
+       if (Result != PRIM_INTERRUPT)
+       {
+         Val = value;
+         Pop_Return_Error(Result);
+       }
+       Prepare_Pop_Return_Interrupt(RC_EXECUTE_ACCESS_FINISH, value);
+       Interrupt(PENDING_INTERRUPTS());
+      }
+      Val = value;
+      Pop_Return_Error(ERR_BAD_FRAME);
+    }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_EXECUTE_ASSIGNMENT_FINISH:
+    {
+      long temp;
+      SCHEME_OBJECT value;
+      Lock_Handle set_serializer;
+
+#ifndef No_In_Line_Lookup
+
+      SCHEME_OBJECT bogus_unassigned;
+      fast SCHEME_OBJECT *cell;
+
+      Set_Time_Zone(Zone_Lookup);
+      Restore_Env();
+      cell = OBJECT_ADDRESS (MEMORY_REF (Fetch_Expression(), ASSIGN_NAME));
+      lookup(cell, Fetch_Env(), cell, repeat_assignment_lookup);
+
+      value = Val;
+      bogus_unassigned = Get_Fixed_Obj_Slot(Non_Object);
+      if (value == bogus_unassigned)
+       value = UNASSIGNED_OBJECT;
+
+assignment_end_before_lock:
+
+      setup_lock(set_serializer, cell);
+
+assignment_end_after_lock:
+
+      Val = *cell;
+
+      if (OBJECT_TYPE (*cell) != TC_REFERENCE_TRAP)
+      {
+normal_assignment_done:
+       *cell = value;
+       remove_lock(set_serializer);
+       Set_Time_Zone(Zone_Working);
+       End_Subproblem();
+       goto Pop_Return;
+      }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+      get_trap_kind(temp, *cell);
+      switch(temp)
+      {
+       case TRAP_DANGEROUS:
+       case TRAP_UNBOUND_DANGEROUS:
+       case TRAP_UNASSIGNED_DANGEROUS:
+       case TRAP_FLUID_DANGEROUS:
+       case TRAP_COMPILER_CACHED_DANGEROUS:
+         remove_lock(set_serializer);
+         cell = OBJECT_ADDRESS (MEMORY_REF (Fetch_Expression(), ASSIGN_NAME));
+         temp =
+           deep_assignment_end(deep_lookup(Fetch_Env(),
+                                           cell[VARIABLE_SYMBOL],
+                                           cell),
+                               cell,
+                               value,
+                               false);
+external_assignment_return:
+         Import_Val();
+         if (temp != PRIM_DONE)
+           break;
+         Set_Time_Zone(Zone_Working);
+         End_Subproblem();
+         goto Pop_Return;
+
+       case TRAP_COMPILER_CACHED:
+       {
+         SCHEME_OBJECT extension, references;
+
+         extension = FAST_MEMORY_REF (Val, TRAP_EXTRA);
+         references = FAST_MEMORY_REF (extension, TRAP_EXTENSION_REFERENCES);
+
+         if ((FAST_MEMORY_REF (references, TRAP_REFERENCES_OPERATOR))
+             != SHARP_F)
+         {
+
+           /* There are uuo links.
+              wimp out and let deep_assignment_end handle it.
+            */
+
+           remove_lock(set_serializer);
+           temp = deep_assignment_end(cell,
+                                      fake_variable_object,
+                                      value,
+                                      false);
+           goto external_assignment_return;
+         }
+         cell = MEMORY_LOC (extension, TRAP_EXTENSION_CELL);
+         update_lock(set_serializer, cell);
+         goto assignment_end_after_lock;
+       }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+       case TRAP_FLUID:
+         remove_lock(set_serializer);
+         cell = lookup_fluid(Val);
+         goto assignment_end_before_lock;
+
+       case TRAP_UNBOUND:
+         remove_lock(set_serializer);
+         temp = ERR_UNBOUND_VARIABLE;
+         break;
+
+       case TRAP_UNASSIGNED:
+         Val = bogus_unassigned;
+         goto normal_assignment_done;
+
+       default:
+         remove_lock(set_serializer);
+         temp = ERR_ILLEGAL_REFERENCE_TRAP;
+         break;
+      }
+
+      if (value == UNASSIGNED_OBJECT)
+       value = bogus_unassigned;
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+#else /* No_In_Line_Lookup */
+
+      value = Val;
+      Set_Time_Zone(Zone_Lookup);
+      Restore_Env();
+      temp = Lex_Set(Fetch_Env(),
+                    MEMORY_REF (Fetch_Expression(), ASSIGN_NAME),
+                    value);
+      Import_Val();
+      if (temp == PRIM_DONE)
+      {
+       End_Subproblem();
+       Set_Time_Zone(Zone_Working);
+       break;
+      }
+
+#endif /* No_In_Line_Lookup */
+
+      Set_Time_Zone(Zone_Working);
+      Save_Env();
+      if (temp != PRIM_INTERRUPT)
+      {
+       Val = value;
+       Pop_Return_Error(temp);
+      }
+
+      Prepare_Pop_Return_Interrupt(RC_EXECUTE_ASSIGNMENT_FINISH,
+                                  value);
+      Interrupt(PENDING_INTERRUPTS());
+    }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_EXECUTE_DEFINITION_FINISH:
+      {
+       SCHEME_OBJECT value;
+        long result;
+
+       value = Val;
+        Restore_Env();
+       Export_Registers();
+        result = Local_Set(Fetch_Env(),
+                          FAST_MEMORY_REF (Fetch_Expression(), DEFINE_NAME),
+                          Val);
+        Import_Registers();
+        if (result == PRIM_DONE)
+        {
+         End_Subproblem();
+          break;
+       }
+       Save_Env();
+       if (result == PRIM_INTERRUPT)
+       {
+         Prepare_Pop_Return_Interrupt(RC_EXECUTE_DEFINITION_FINISH,
+                                      value);
+         Interrupt(PENDING_INTERRUPTS());
+       }
+       Val = value;
+        Pop_Return_Error(result);
+      }
+
+    case RC_EXECUTE_IN_PACKAGE_CONTINUE:
+      Pop_Return_Val_Check();
+      if (ENVIRONMENT_P (Val))
+      {
+       End_Subproblem();
+        Store_Env(Val);
+        Reduces_To_Nth(IN_PACKAGE_EXPRESSION);
+      }
+      Pop_Return_Error(ERR_BAD_FRAME);
+
+#ifdef COMPILE_FUTURES
+    case RC_FINISH_GLOBAL_INT:
+      Export_Registers();
+      Val = Global_Int_Part_2(Fetch_Expression(), Val);
+      Import_Registers_Except_Val();
+      break;
+#endif
+\f
+    case RC_HALT:
+      Export_Registers();
+      Microcode_Termination (TERM_TERM_HANDLER);
+
+    case RC_HARDWARE_TRAP:
+    {
+      /* This just reinvokes the handler */
+
+      SCHEME_OBJECT info, handler;
+      info = (STACK_REF (0));
+
+      Save_Cont();
+      if ((! (Valid_Fixed_Obj_Vector())) ||
+         ((handler = (Get_Fixed_Obj_Slot(Trap_Handler))) == SHARP_F))
+      {
+       outf_fatal ("There is no trap handler for recovery!\n");
+       termination_trap ();
+       /*NOTREACHED*/
+      }
+     Will_Push(STACK_ENV_EXTRA_SLOTS + 2);
+      STACK_PUSH (info);
+      STACK_PUSH (handler);
+      STACK_PUSH (STACK_FRAME_HEADER + 1);
+     Pushed();
+      goto Internal_Apply;
+    }
+\f
+/* Internal_Apply, the core of the application mechanism.
+
+   Branch here to perform a function application.
+
+   At this point the top of the stack contains an application frame
+   which consists of the following elements (see sdata.h):
+   - A header specifying the frame length.
+   - A procedure.
+   - The actual (evaluated) arguments.
+
+   No registers (except the stack pointer) are meaning full at this point.
+   Before interrupts or errors are processed, some registers are cleared
+   to avoid holding onto garbage if a garbage collection occurs.
+*/
+
+#define Prepare_Apply_Interrupt()                                      \
+{                                                                      \
+  Store_Expression (SHARP_F);                                          \
+  Prepare_Pop_Return_Interrupt (RC_INTERNAL_APPLY_VAL,                 \
+                               (STACK_REF (STACK_ENV_FUNCTION)));      \
+}
+
+#define Apply_Error(N)                                                 \
+{                                                                      \
+  Store_Expression (SHARP_F);                                          \
+  Store_Return (RC_INTERNAL_APPLY_VAL);                                        \
+  Val = (STACK_REF (STACK_ENV_FUNCTION));                              \
+  Pop_Return_Error (N);                                                        \
+}
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_INTERNAL_APPLY_VAL:
+Internal_Apply_Val:
+
+       STACK_REF (STACK_ENV_FUNCTION) = Val;
+
+    case RC_INTERNAL_APPLY:
+Internal_Apply:
+
+      if (Microcode_Does_Stepping &&
+         Trapping &&
+         (! WITHIN_CRITICAL_SECTION_P()) &&
+         ((Fetch_Apply_Trapper ()) != SHARP_F))
+      {
+       long Count;
+
+       Count = (OBJECT_DATUM (STACK_REF (STACK_ENV_HEADER)));
+        (* (STACK_LOC (0))) = (Fetch_Apply_Trapper ());
+        STACK_PUSH (STACK_FRAME_HEADER + Count);
+        Stop_Trapping ();
+      }
+
+Apply_Non_Trapping:
+
+      if ((PENDING_INTERRUPTS()) != 0)
+      {
+       long Interrupts;
+
+       Interrupts = (PENDING_INTERRUPTS());
+       Prepare_Apply_Interrupt ();
+       Interrupt(Interrupts);
+      }
+
+Perform_Application:
+
+      Apply_Ucode_Hook();
+
+      {
+        fast SCHEME_OBJECT Function, orig_proc;
+
+       Apply_Future_Check (Function, (STACK_REF (STACK_ENV_FUNCTION)));
+       orig_proc = Function;
+
+apply_dispatch:
+        switch (OBJECT_TYPE (Function))
+        {
+         case TC_ENTITY:
+         {
+           fast long nargs, nactuals;
+           SCHEME_OBJECT data;
+
+           /* Will_Pushed ommited since frame must be contiguous.
+              combination code must ensure one more slot.
+            */
+
+           /* This code assumes that adding 1 to nactuals takes care
+              of everything, including type code, etc.
+            */
+
+           nargs = (STACK_POP ());
+           nactuals = (OBJECT_DATUM (nargs));
+           data = (MEMORY_REF (Function, ENTITY_DATA));
+           if ((VECTOR_P (data))
+               && (nactuals < (VECTOR_LENGTH (data)))
+               && ((VECTOR_REF (data, nactuals)) != SHARP_F)
+               && ((VECTOR_REF (data, 0))
+                   == (Get_Fixed_Obj_Slot (ARITY_DISPATCHER_TAG))))
+           {
+             SCHEME_OBJECT nproc = (VECTOR_REF (data, nactuals));
+
+             if ((Function == orig_proc) && (nproc != Function))
+             {
+               Function = nproc;
+               STACK_PUSH (nargs);
+               STACK_REF (STACK_ENV_FUNCTION) = nproc;
+               goto apply_dispatch;
+             }
+             else
+             {
+               Function = orig_proc;
+               STACK_REF (STACK_ENV_FUNCTION - 1) = orig_proc;
+             }
+           }
+           
+           STACK_PUSH (FAST_MEMORY_REF (Function, ENTITY_OPERATOR));
+           STACK_PUSH (nargs + 1);
+           /* This must be done to prevent an infinite push loop by
+              an entity whose handler is the entity itself or some
+              other such loop.  Of course, it will die if stack overflow
+              interrupts are disabled.
+            */
+           Stack_Check (Stack_Pointer);
+           goto Internal_Apply;
+         }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+         case TC_RECORD:
+         {
+           SCHEME_OBJECT record_type = (VECTOR_REF (Function, 0));
+           if ((RECORD_P (record_type))
+               && ((OBJECT_TYPE (FAST_MEMORY_REF (record_type, 0)))
+                   == TC_CONSTANT)
+               && ((VECTOR_LENGTH (record_type)) >= 2)
+               && ((VECTOR_REF (record_type, 1)) != SHARP_F)
+               && ((VECTOR_REF (record_type, 1)) != Function))
+             {
+               SCHEME_OBJECT nargs_object = (STACK_POP ());
+               STACK_PUSH (VECTOR_REF (record_type, 1));
+               STACK_PUSH
+                 (MAKE_OBJECT ((OBJECT_TYPE (nargs_object)),
+                               ((OBJECT_DATUM (nargs_object)) + 1)));
+               Stack_Check (Stack_Pointer);
+               goto Internal_Apply;
+             }
+           else
+             goto internal_apply_inapplicable;
+         }
+
+         case TC_PROCEDURE:
+         {
+           fast long nargs;
+
+            nargs = OBJECT_DATUM (STACK_POP ());
+           Function = FAST_MEMORY_REF (Function, PROCEDURE_LAMBDA_EXPR);
+
+           {
+             fast SCHEME_OBJECT formals;
+
+             Apply_Future_Check(formals,
+                                FAST_MEMORY_REF (Function, LAMBDA_FORMALS));
+
+             if ((nargs != VECTOR_LENGTH (formals)) &&
+                 ((OBJECT_TYPE (Function) != TC_LEXPR) ||
+                 (nargs < VECTOR_LENGTH (formals))))
+             {
+               STACK_PUSH (STACK_FRAME_HEADER + nargs - 1);
+               Apply_Error(ERR_WRONG_NUMBER_OF_ARGUMENTS);
+             }
+           }
+
+           if (0 && Eval_Debug)
+           {
+             Print_Expression(LONG_TO_UNSIGNED_FIXNUM(nargs),
+                              "APPLY: Number of arguments");
+           }
+
+            if (GC_Check(nargs + 1))
+            {
+             STACK_PUSH (STACK_FRAME_HEADER + nargs - 1);
+              Prepare_Apply_Interrupt ();
+              Immediate_GC(nargs + 1);
+            }
+
+           {
+             fast SCHEME_OBJECT *scan;
+             fast SCHEME_OBJECT temp;
+
+             scan = Free;
+             temp = (MAKE_POINTER_OBJECT (TC_ENVIRONMENT, scan));
+             *scan++ = MAKE_OBJECT (TC_MANIFEST_VECTOR, nargs);
+             while(--nargs >= 0)
+               *scan++ = (STACK_POP ());
+             Free = scan;
+             Store_Env(temp);
+             Reduces_To(FAST_MEMORY_REF (Function, LAMBDA_SCODE));
+           }
+          }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+          case TC_CONTROL_POINT:
+         {
+            if (OBJECT_DATUM (STACK_REF (STACK_ENV_HEADER)) !=
+                STACK_ENV_FIRST_ARG)
+           {
+              Apply_Error(ERR_WRONG_NUMBER_OF_ARGUMENTS);
+           }
+            Val = (STACK_REF (STACK_ENV_FIRST_ARG));
+            Our_Throw(false, Function);
+           Apply_Stacklet_Backout();
+           Our_Throw_Part_2();
+            goto Pop_Return;
+         }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+         /*
+            After checking the number of arguments, remove the
+            frame header since primitives do not expect it.
+
+            NOTE: This code must match the application code which
+            follows Primitive_Internal_Apply.
+          */
+
+          case TC_PRIMITIVE:
+          {
+           fast long nargs;
+
+           if (!IMPLEMENTED_PRIMITIVE_P(Function))
+           {
+             Apply_Error(ERR_UNIMPLEMENTED_PRIMITIVE);
+           }
+
+           /* Note that the first test below will fail for lexpr primitives. */
+
+           nargs = ((OBJECT_DATUM (STACK_REF(STACK_ENV_HEADER))) -
+                    (STACK_ENV_FIRST_ARG - 1));
+            if (nargs != PRIMITIVE_ARITY(Function))
+           {
+             if (PRIMITIVE_ARITY(Function) != LEXPR_PRIMITIVE_ARITY)
+             {
+               Apply_Error(ERR_WRONG_NUMBER_OF_ARGUMENTS);
+             }
+             Regs[REGBLOCK_LEXPR_ACTUALS] = ((SCHEME_OBJECT) nargs);
+           }
+
+            Stack_Pointer = (STACK_LOC (STACK_ENV_FIRST_ARG));
+            Store_Expression (Function);
+           EXPORT_REGS_BEFORE_PRIMITIVE ();
+           PRIMITIVE_APPLY (Val, Function);
+           IMPORT_REGS_AFTER_PRIMITIVE ();
+           POP_PRIMITIVE_FRAME (nargs);
+           if (Must_Report_References())
+           {
+             Store_Expression(Val);
+             Store_Return(RC_RESTORE_VALUE);
+             Save_Cont();
+             Call_Future_Logging();
+           }
+           goto Pop_Return;
+         }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+          case TC_EXTENDED_PROCEDURE:
+          {
+           SCHEME_OBJECT lambda, temp;
+            long nargs, nparams, formals, params, auxes,
+                 rest_flag, size;
+
+           fast long i;
+           fast SCHEME_OBJECT *scan;
+
+            nargs = OBJECT_DATUM (STACK_POP ()) - STACK_FRAME_HEADER;
+
+           if (0 && Eval_Debug)
+           {
+             Print_Expression(LONG_TO_UNSIGNED_FIXNUM(nargs+STACK_FRAME_HEADER),
+                              "APPLY: Number of arguments");
+           }
+
+            lambda = FAST_MEMORY_REF (Function, PROCEDURE_LAMBDA_EXPR);
+           Apply_Future_Check(Function,
+                              FAST_MEMORY_REF (lambda, ELAMBDA_NAMES));
+            nparams = VECTOR_LENGTH (Function) - 1;
+
+           Apply_Future_Check(Function, Get_Count_Elambda(lambda));
+            formals = Elambda_Formals_Count(Function);
+            params = Elambda_Opts_Count(Function) + formals;
+            rest_flag = Elambda_Rest_Flag(Function);
+            auxes = nparams - (params + rest_flag);
+
+            if ((nargs < formals) || (!rest_flag && (nargs > params)))
+            {
+             STACK_PUSH (STACK_FRAME_HEADER + nargs);
+              Apply_Error(ERR_WRONG_NUMBER_OF_ARGUMENTS);
+            }
+
+           /* size includes the procedure slot, but not the header. */
+            size = params + rest_flag + auxes + 1;
+            if (GC_Check(size + 1 + ((nargs > params) ?
+                                    (2 * (nargs - params)) :
+                                    0)))
+            {
+             STACK_PUSH (STACK_FRAME_HEADER + nargs);
+              Prepare_Apply_Interrupt ();
+              Immediate_GC(size + 1 + ((nargs > params) ?
+                                      (2 * (nargs - params)) :
+                                      0));
+            }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+           scan = Free;
+           temp = (MAKE_POINTER_OBJECT (TC_ENVIRONMENT, scan));
+           *scan++ = MAKE_OBJECT (TC_MANIFEST_VECTOR, size);
+
+           if (nargs <= params)
+           {
+             for (i = (nargs + 1); --i >= 0; )
+               *scan++ = (STACK_POP ());
+             for (i = (params - nargs); --i >= 0; )
+               *scan++ = UNASSIGNED_OBJECT;
+             if (rest_flag)
+               *scan++ = EMPTY_LIST;
+             for (i = auxes; --i >= 0; )
+               *scan++ = UNASSIGNED_OBJECT;
+           }
+           else
+           {
+             /* rest_flag must be true. */
+             SCHEME_OBJECT list;
+
+             list = MAKE_POINTER_OBJECT (TC_LIST, (scan + size));
+             for (i = (params + 1); --i >= 0; )
+               *scan++ = (STACK_POP ());
+             *scan++ = list;
+             for (i = auxes; --i >= 0; )
+               *scan++ = UNASSIGNED_OBJECT;
+             /* Now scan == OBJECT_ADDRESS (list) */
+             for (i = (nargs - params); --i >= 0; )
+             {
+               *scan++ = (STACK_POP ());
+               *scan = MAKE_POINTER_OBJECT (TC_LIST, (scan + 1));
+               scan += 1;
+             }
+             scan[-1] = EMPTY_LIST;
+           }
+
+           Free = scan;
+            Store_Env (temp);
+            Reduces_To(Get_Body_Elambda(lambda));
+          }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+          case TC_COMPILED_ENTRY:
+         {
+           apply_compiled_setup (STACK_ENV_EXTRA_SLOTS +
+                                 (OBJECT_DATUM (STACK_REF (STACK_ENV_HEADER))));
+           Export_Registers ();
+           Which_Way = apply_compiled_procedure();
+
+return_from_compiled_code:
+           Import_Registers ();
+            switch (Which_Way)
+            {
+              case PRIM_DONE:
+             {
+                compiled_code_done ();
+               goto Pop_Return;
+             }
+
+             case PRIM_APPLY:
+             {
+                compiler_apply_procedure
+                 (STACK_ENV_EXTRA_SLOTS +
+                  OBJECT_DATUM (STACK_REF (STACK_ENV_HEADER)));
+               goto Internal_Apply;
+             }
+
+             case PRIM_INTERRUPT:
+             {
+                compiled_error_backout ();
+               Save_Cont ();
+               Interrupt (PENDING_INTERRUPTS ());
+             }
+
+             case PRIM_APPLY_INTERRUPT:
+             {
+                apply_compiled_backout ();
+               Prepare_Apply_Interrupt ();
+               Interrupt (PENDING_INTERRUPTS ());
+             }
+\f
+             case ERR_INAPPLICABLE_OBJECT:
+             /* This error code means that apply_compiled_procedure
+                was called on an object which is not a compiled procedure,
+                or it was called in a system without compiler support.
+                
+                Fall through...
+             */
+
+             case ERR_WRONG_NUMBER_OF_ARGUMENTS:
+             {
+                apply_compiled_backout ();
+               Apply_Error (Which_Way);
+             }
+
+             case ERR_EXECUTE_MANIFEST_VECTOR:
+             { /* This error code means that enter_compiled_expression
+                  was called in a system without compiler support.
+                  This is a kludge!
+               */
+               execute_compiled_backout ();
+               Val =
+                 (OBJECT_NEW_TYPE (TC_COMPILED_ENTRY, (Fetch_Expression ())));
+               Pop_Return_Error (Which_Way);
+             }
+
+             case ERR_INAPPLICABLE_CONTINUATION:
+             { /* This error code means that return_to_compiled_code
+                  saw a non-continuation on the stack, or was called
+                  in a system without compiler support.
+               */
+               Store_Expression (SHARP_F);
+               Store_Return (RC_REENTER_COMPILED_CODE);
+               Pop_Return_Error (Which_Way);
+             }
+
+             default:
+               compiled_error_backout ();
+               Pop_Return_Error (Which_Way);
+            }
+          }
+
+          default:
+         internal_apply_inapplicable:
+            Apply_Error (ERR_INAPPLICABLE_OBJECT);
+        }       /* End of switch in RC_INTERNAL_APPLY */
+      }         /* End of RC_INTERNAL_APPLY case */
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_MOVE_TO_ADJACENT_POINT:
+    /* Expression contains the space in which we are moving */
+    {
+      long From_Count;
+      SCHEME_OBJECT Thunk, New_Location;
+
+      From_Count =
+       (UNSIGNED_FIXNUM_TO_LONG (STACK_REF (TRANSLATE_FROM_DISTANCE)));
+      if (From_Count != 0)
+      {
+        SCHEME_OBJECT Current = STACK_REF(TRANSLATE_FROM_POINT);
+       STACK_REF(TRANSLATE_FROM_DISTANCE) =
+         (LONG_TO_UNSIGNED_FIXNUM (From_Count - 1));
+       Thunk = FAST_MEMORY_REF (Current, STATE_POINT_AFTER_THUNK);
+       New_Location = FAST_MEMORY_REF (Current, STATE_POINT_NEARER_POINT);
+       STACK_REF(TRANSLATE_FROM_POINT) = New_Location;
+       if ((From_Count == 1) &&
+           (STACK_REF(TRANSLATE_TO_DISTANCE) == LONG_TO_UNSIGNED_FIXNUM(0)))
+         Stack_Pointer = (STACK_LOC (4));
+       else Save_Cont();
+      }
+      else
+      {
+       long To_Count;
+       fast SCHEME_OBJECT To_Location;
+       fast long i;
+
+       To_Count =
+         (UNSIGNED_FIXNUM_TO_LONG (STACK_REF (TRANSLATE_TO_DISTANCE)) -  1);
+       To_Location = STACK_REF(TRANSLATE_TO_POINT);
+       for (i = 0; i < To_Count; i++)
+       {
+         To_Location =
+           (FAST_MEMORY_REF (To_Location, STATE_POINT_NEARER_POINT));
+       }
+       Thunk = FAST_MEMORY_REF (To_Location, STATE_POINT_BEFORE_THUNK);
+       New_Location = To_Location;
+       STACK_REF(TRANSLATE_TO_DISTANCE) = LONG_TO_UNSIGNED_FIXNUM(To_Count);
+       if (To_Count == 0)
+       {
+         Stack_Pointer = (STACK_LOC (4));
+       }
+       else
+       {
+         Save_Cont();
+       }
+      }
+      if ((Fetch_Expression ()) != SHARP_F)
+      {
+        MEMORY_SET
+         ((Fetch_Expression ()), STATE_SPACE_NEAREST_POINT, New_Location);
+      }
+      else
+      {
+       Current_State_Point = New_Location;
+      }
+     Will_Push(2);
+      STACK_PUSH (Thunk);
+      STACK_PUSH (STACK_FRAME_HEADER);
+     Pushed();
+      goto Internal_Apply;
+    }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_INVOKE_STACK_THREAD:
+      /* Used for WITH_THREADED_STACK primitive */
+     Will_Push(3);
+      STACK_PUSH (Val);        /* Value calculated by thunk */
+      STACK_PUSH (Fetch_Expression());
+      STACK_PUSH (STACK_FRAME_HEADER+1);
+     Pushed();
+      goto Internal_Apply;
+
+    case RC_JOIN_STACKLETS:
+      Our_Throw(true, Fetch_Expression());
+      Join_Stacklet_Backout();
+      Our_Throw_Part_2();
+      break;
+
+    case RC_NORMAL_GC_DONE:
+      Val = (Fetch_Expression ());
+      if (GC_Space_Needed < 0)
+      {
+       /* Paranoia */
+
+       GC_Space_Needed = 0;
+      }
+      if (GC_Check (GC_Space_Needed))
+       termination_gc_out_of_space ();
+      GC_Space_Needed = 0;
+      EXIT_CRITICAL_SECTION ({ Save_Cont(); Export_Registers(); });
+      End_GC_Hook ();
+      break;
+\f
+    case RC_PCOMB1_APPLY:
+      End_Subproblem();
+      STACK_PUSH (Val);                /* Argument value */
+     Finished_Eventual_Pushing(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG);
+      Store_Expression(FAST_MEMORY_REF (Fetch_Expression(), PCOMB1_FN_SLOT));
+
+Primitive_Internal_Apply:
+      if (Microcode_Does_Stepping &&
+         Trapping &&
+         (! WITHIN_CRITICAL_SECTION_P()) &&
+         ((Fetch_Apply_Trapper ()) != SHARP_F))
+      {
+       /* Does this work in the stacklet case?
+          We may have a non-contiguous frame. -- Jinx
+        */
+       Will_Push(3);
+        STACK_PUSH (Fetch_Expression());
+        STACK_PUSH (Fetch_Apply_Trapper());
+        STACK_PUSH (STACK_FRAME_HEADER + 1 +
+            PRIMITIVE_N_PARAMETERS(Fetch_Expression()));
+       Pushed();
+        Stop_Trapping();
+       goto Apply_Non_Trapping;
+      }
+
+      /* NOTE: This code must match the code in the TC_PRIMITIVE
+        case of Internal_Apply.
+        This code is simpler because:
+        1) The arity was checked at syntax time.
+        2) We don't have to deal with "lexpr" primitives.
+        3) We don't need to worry about unimplemented primitives because
+           unimplemented primitives will cause an error at invocation.
+       */
+
+      {
+       fast SCHEME_OBJECT primitive = (Fetch_Expression ());
+       EXPORT_REGS_BEFORE_PRIMITIVE ();
+       PRIMITIVE_APPLY (Val, primitive);
+       IMPORT_REGS_AFTER_PRIMITIVE ();
+       POP_PRIMITIVE_FRAME (PRIMITIVE_ARITY (primitive));
+       if (Must_Report_References ())
+         {
+           Store_Expression (Val);
+           Store_Return (RC_RESTORE_VALUE);
+           Save_Cont ();
+           Call_Future_Logging ();
+         }
+       break;
+      }
+\f
+    case RC_PCOMB2_APPLY:
+      End_Subproblem();
+      STACK_PUSH (Val);                /* Value of arg. 1 */
+     Finished_Eventual_Pushing(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG);
+      Store_Expression(FAST_MEMORY_REF (Fetch_Expression(), PCOMB2_FN_SLOT));
+      goto Primitive_Internal_Apply;
+
+    case RC_PCOMB2_DO_1:
+      Restore_Env();
+      STACK_PUSH (Val);                /* Save value of arg. 2 */
+      Do_Another_Then(RC_PCOMB2_APPLY, PCOMB2_ARG_1_SLOT);
+
+    case RC_PCOMB3_APPLY:
+      End_Subproblem();
+      STACK_PUSH (Val);                /* Save value of arg. 1 */
+     Finished_Eventual_Pushing(CONTINUATION_SIZE + STACK_ENV_FIRST_ARG);
+      Store_Expression(FAST_MEMORY_REF (Fetch_Expression(), PCOMB3_FN_SLOT));
+      goto Primitive_Internal_Apply;
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_PCOMB3_DO_1:
+    {
+      SCHEME_OBJECT Temp;
+
+      Temp = (STACK_POP ());           /* Value of arg. 3 */
+      Restore_Env();
+      STACK_PUSH (Temp);               /* Save arg. 3 again */
+      STACK_PUSH (Val);                /* Save arg. 2 */
+      Do_Another_Then(RC_PCOMB3_APPLY, PCOMB3_ARG_1_SLOT);
+    }
+
+    case RC_PCOMB3_DO_2:
+      Restore_Then_Save_Env();
+      STACK_PUSH (Val);                /* Save value of arg. 3 */
+      Do_Another_Then(RC_PCOMB3_DO_1, PCOMB3_ARG_2_SLOT);
+
+    case RC_POP_RETURN_ERROR:
+    case RC_RESTORE_VALUE:
+      Val = Fetch_Expression();
+      break;
+
+    case RC_PRIMITIVE_CONTINUE:
+      Export_Registers ();
+      Val = (continue_primitive ());
+      Import_Registers ();
+      break;
+
+    case RC_REPEAT_DISPATCH:
+      Which_Way = (FIXNUM_TO_LONG (Fetch_Expression ()));
+      Restore_Env();
+      Val = (STACK_POP ());
+      Restore_Cont();
+      goto Repeat_Dispatch;
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+/* The following two return codes are both used to restore
+   a saved history object.  The difference is that the first
+   does not copy the history object while the second does.
+   In both cases, the Expression register contains the history
+   object and the next item to be popped off the stack contains
+   the offset back to the previous restore history return code.
+
+   ASSUMPTION: History objects are never created using futures.
+*/
+
+    case RC_RESTORE_DONT_COPY_HISTORY:
+    {
+      SCHEME_OBJECT Stacklet;
+
+      Prev_Restore_History_Offset = OBJECT_DATUM (STACK_POP ());
+      Stacklet = (STACK_POP ());
+      History = OBJECT_ADDRESS (Fetch_Expression());
+      if (Prev_Restore_History_Offset == 0)
+      {
+       Prev_Restore_History_Stacklet = NULL;
+      }
+      else if (Stacklet == SHARP_F)
+      {
+        Prev_Restore_History_Stacklet = NULL;
+      }
+      else
+      {
+       Prev_Restore_History_Stacklet = OBJECT_ADDRESS (Stacklet);
+      }
+      break;
+    }
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_RESTORE_HISTORY:
+    {
+      SCHEME_OBJECT Stacklet;
+
+      Export_Registers();
+      if (! Restore_History(Fetch_Expression()))
+      {
+       Import_Registers();
+        Save_Cont();
+       Will_Push(CONTINUATION_SIZE);
+        Store_Expression(Val);
+        Store_Return(RC_RESTORE_VALUE);
+        Save_Cont();
+       Pushed();
+        Immediate_GC((Free > MemTop) ? 0 : ((MemTop-Free)+1));
+      }
+      Import_Registers();
+      Prev_Restore_History_Offset = OBJECT_DATUM (STACK_POP ());
+      Stacklet = (STACK_POP ());
+      if (Prev_Restore_History_Offset == 0)
+       Prev_Restore_History_Stacklet = NULL;
+      else
+      {
+        if (Stacklet == SHARP_F)
+        {
+          Prev_Restore_History_Stacklet = NULL;
+         Get_End_Of_Stacklet()[-Prev_Restore_History_Offset] =
+            MAKE_OBJECT (TC_RETURN_CODE, RC_RESTORE_HISTORY);
+        }
+        else
+       {
+          Prev_Restore_History_Stacklet = OBJECT_ADDRESS (Stacklet);
+         Prev_Restore_History_Stacklet[-Prev_Restore_History_Offset] =
+            MAKE_OBJECT (TC_RETURN_CODE, RC_RESTORE_HISTORY);
+        }
+      }
+      break;
+    }
+
+    case RC_RESTORE_FLUIDS:
+      Fluid_Bindings = Fetch_Expression();
+      break;
+
+    case RC_RESTORE_INT_MASK:
+      SET_INTERRUPT_MASK (UNSIGNED_FIXNUM_TO_LONG (Fetch_Expression()));
+      if (GC_Check (0))
+        Request_GC (0);
+      if ((PENDING_INTERRUPTS ()) != 0)
+      {
+       Store_Return (RC_RESTORE_VALUE);
+       Store_Expression (Val);
+       Save_Cont ();
+       Interrupt (PENDING_INTERRUPTS ());
+      }
+      break;
+
+    case RC_STACK_MARKER:
+      /* Frame consists of the return code followed by two objects.
+        The first object has already been popped into the Expression
+        register, so just pop the second argument. */
+      Stack_Pointer = (STACK_LOCATIVE_OFFSET (Stack_Pointer, 1));
+      break;
+
+/* Interpret() continues on the next page */
+\f
+/* Interpret(), continued */
+
+    case RC_RESTORE_TO_STATE_POINT:
+    {
+      SCHEME_OBJECT Where_To_Go = Fetch_Expression();
+     Will_Push(CONTINUATION_SIZE);
+      /* Restore the contents of Val after moving to point */
+      Store_Expression(Val);
+      Store_Return(RC_RESTORE_VALUE);
+      Save_Cont();
+     Pushed();
+      Export_Registers();
+      Translate_To_Point(Where_To_Go);
+      break;                   /* We never get here.... */
+    }
+
+    case RC_SEQ_2_DO_2:
+      End_Subproblem();
+      Restore_Env();
+      Reduces_To_Nth(SEQUENCE_2);
+
+    case RC_SEQ_3_DO_2:
+      Restore_Then_Save_Env();
+      Do_Another_Then(RC_SEQ_3_DO_3, SEQUENCE_2);
+
+    case RC_SEQ_3_DO_3:
+      End_Subproblem();
+      Restore_Env();
+      Reduces_To_Nth(SEQUENCE_3);
+
+/* Interpret() continues on the next page */
+\f
+/* -*-C-*-
+
+$Id: interp.c,v 9.85 1995/07/26 21:16:17 adams Exp $
 
 Copyright (c) 1988-94 Massachusetts Institute of Technology