Skip to content

Commit

Permalink
kernel: simplify IntrBegin/IntrEnd and their callers
Browse files Browse the repository at this point in the history
- don't save context in the interpreter; instead, require the caller to
  do this. That way, the interpreter is fully isolated from the context;
  and this also enables further refactoring.
- do away with the TRY_IF_NO_ERROR/CATCH_ERROR around IntrEnd cals
- remove intrReturning temporary variable, use intr->returning directly
  (it used to be necessary to copy & reset its value, back when this was
  stored in a global variable; but now we create this fresh on the stack
  so there's no need for any of this)
  • Loading branch information
fingolfin committed Jun 4, 2020
1 parent 7e9133a commit 816a3f5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 53 deletions.
32 changes: 8 additions & 24 deletions src/intrprtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,7 @@ static void FinishAndCallFakeFuncExpr(IntrState * intr, Obj stackNams)
*F IntrBegin() . . . . . . . . . . . . . . . . . . . . start an interpreter
*F IntrEnd(<error>,<result>) . . . . . . . . . . . . . stop an interpreter
**
** 'IntrBegin' starts a new interpreter in context <frame>. If in doubt,
** pass STATE(BottomLVars) as <frame>
** 'IntrBegin' starts a new interpreter.
**
** 'IntrEnd' stops the current interpreter.
**
Expand All @@ -235,7 +234,7 @@ static void FinishAndCallFakeFuncExpr(IntrState * intr, Obj stackNams)
** return-void-statement was interpreted. If 'IntrEnd' returns 'STATUS_QUIT',
** then a quit-statement was interpreted.
*/
void IntrBegin(IntrState * intr, Obj frame)
void IntrBegin(IntrState * intr)
{
/* allocate a new values stack */
intr->StackObj = NEW_PLIST(T_PLIST, 64);
Expand All @@ -246,27 +245,13 @@ void IntrBegin(IntrState * intr, Obj frame)

/* no return-statement was yet interpreted */
intr->returning = 0;

// remember the old execution state
intr->oldLVars = STATE(CurrLVars);

// start an execution environment
SWITCH_TO_OLD_LVARS(frame);
}

ExecStatus IntrEnd(IntrState * intr, UInt error, Obj * result)
ExecStatus IntrEnd(IntrState * intr, BOOL error, Obj * result)
{
UInt intrReturning; /* interpreted return-statement? */

// restore the execution environment
SWITCH_TO_OLD_LVARS(intr->oldLVars);

/* if everything went fine */
if ( ! error ) {

/* remember whether the interpreter interpreted a return-statement */
intrReturning = intr->returning;

/* must be back in immediate (non-ignoring, non-coding) mode */
GAP_ASSERT(intr->ignoring == 0);
GAP_ASSERT(intr->coding == 0);
Expand All @@ -275,6 +260,8 @@ ExecStatus IntrEnd(IntrState * intr, UInt error, Obj * result)
GAP_ASSERT(LEN_PLIST(intr->StackObj) == 1);
if (result)
*result = PopVoidObj(intr);

return intr->returning;
}

/* otherwise clean up the mess */
Expand All @@ -285,16 +272,13 @@ ExecStatus IntrEnd(IntrState * intr, UInt error, Obj * result)
CodeEnd(1);
}

/* remember that we had an error */
intrReturning = STATUS_ERROR;

/* dummy result value (probably ignored) */
if (result)
*result = 0;
}

/* indicate whether a return-statement was interpreted */
return intrReturning;
// indicate that we had an error
return STATUS_ERROR;
}
}


Expand Down
12 changes: 3 additions & 9 deletions src/intrprtr.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ struct IntrState {

// 'StackObj' is the stack of values.
Obj StackObj;

// 'IntrBegin' stores in 'oldLVars' the previous value of
// 'STATE(CurrLVars)', and 'IntrEnd' restores it from there by calling
// 'SWITCH_TO_OLD_LVARS'.
Bag oldLVars;
};

typedef struct IntrState IntrState;
Expand All @@ -66,8 +61,7 @@ typedef struct IntrState IntrState;
*F IntrBegin() . . . . . . . . . . . . . . . . . . . . start an interpreter
*F IntrEnd(<error>,<result>) . . . . . . . . . . . . . stop an interpreter
**
** 'IntrBegin' starts a new interpreter in context <frame>. If in doubt,
** pass STATE(BottomLVars) as <frame>
** 'IntrBegin' starts a new interpreter.
**
** 'IntrEnd' stops the current interpreter.
**
Expand All @@ -82,9 +76,9 @@ typedef struct IntrState IntrState;
** return-void-statement was interpreted. If 'IntrEnd' returns 'STATUS_QUIT',
** then a quit-statement was interpreted.
*/
void IntrBegin(IntrState * intr, Obj frame);
void IntrBegin(IntrState * intr);

ExecStatus IntrEnd(IntrState * intr, UInt error, Obj * result);
ExecStatus IntrEnd(IntrState * intr, BOOL error, Obj * result);


/****************************************************************************
Expand Down
50 changes: 30 additions & 20 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -2606,7 +2606,13 @@ ExecStatus ReadEvalCommand(Obj context, Obj *evalResult, UInt *dualSemicolon)

AssGVar(GVarName("READEVALCOMMAND_LINENUMBER"), INTOBJ_INT(GetInputLineNumber()));

IntrBegin(&rs->intr, context );
// remember the old execution state
Bag oldLVars = STATE(CurrLVars);

// start an execution environment
SWITCH_TO_OLD_LVARS(context);

IntrBegin(&rs->intr);

switch (rs->s.Symbol) {
/* read an expression or an assignment or a procedure call */
Expand All @@ -2632,23 +2638,23 @@ ExecStatus ReadEvalCommand(Obj context, Obj *evalResult, UInt *dualSemicolon)
SyntaxError(&rs->s, "; expected");
}

/* end the interpreter */
TRY_IF_NO_ERROR {
type = IntrEnd(&rs->intr, 0, evalResult);
// check for dual semicolon
if (dualSemicolon)
*dualSemicolon = (rs->s.Symbol == S_DUALSEMICOLON);

// end the interpreter
type = IntrEnd(&rs->intr, rs->s.NrError > 0, evalResult);

// restore the execution environment
SWITCH_TO_OLD_LVARS(oldLVars);

/* check for dual semicolon */
if (dualSemicolon)
*dualSemicolon = (rs->s.Symbol == S_DUALSEMICOLON);
}
CATCH_ERROR {
IntrEnd(&rs->intr, 1, evalResult);
type = STATUS_ERROR;
#ifdef HPCGAP
if (rs->s.NrError > 0) {
PopRegionLocks(lockSP);
if (TLS(CurrentHashLock))
HashUnlock(TLS(CurrentHashLock));
#endif
}
#endif

GAP_ASSERT(rs->LoopNesting == 0);

Expand Down Expand Up @@ -2711,7 +2717,14 @@ UInt ReadEvalFile(Obj * evalResult)
rs->ReadTilde = 0;
STATE(Tilde) = 0;
rs->CurrLHSGVar = 0;
IntrBegin(&rs->intr, STATE(BottomLVars));

// remember the old execution state
Bag oldLVars = STATE(CurrLVars);

// start an execution environment
SWITCH_TO_OLD_LVARS(STATE(BottomLVars));

IntrBegin(&rs->intr);

/* check for local variables */
nams = NEW_PLIST(T_PLIST, 0);
Expand Down Expand Up @@ -2744,13 +2757,10 @@ UInt ReadEvalFile(Obj * evalResult)
}

/* end the interpreter */
TRY_IF_NO_ERROR {
type = IntrEnd(&rs->intr, 0, evalResult);
}
CATCH_ERROR {
IntrEnd(&rs->intr, 1, evalResult);
type = STATUS_ERROR;
}
type = IntrEnd(&rs->intr, rs->s.NrError > 0, evalResult);

// restore the execution environment
SWITCH_TO_OLD_LVARS(oldLVars);

/* switch back to the old reader context */
memcpy( STATE(ReadJmpError), readJmpError, sizeof(jmp_buf) );
Expand Down

0 comments on commit 816a3f5

Please sign in to comment.