mirror of
https://git.code.sf.net/p/newrpl/sources
synced 2024-11-16 19:51:25 +01:00
Work in progress - new RPL exception handlers
This commit is contained in:
parent
d0c5373d5e
commit
32daa580f4
6 changed files with 140 additions and 26 deletions
|
@ -429,7 +429,7 @@ rplSetEntryPoint(obj);
|
|||
rplRun();
|
||||
|
||||
// DISCARD ANY ERRORS DURING EXECUTION, IDEALLY IT HIT THE BREAKPOINT
|
||||
if(Exceptions!=EX_BKPOINT) {
|
||||
if(Exceptions!=EX_HALT) {
|
||||
// THERE WAS SOME OTHER ERROR DURING EXECUTION, DISCARD ALL OUTPUT FROM THE FAILED PROGRAM
|
||||
rplClearData();
|
||||
}
|
||||
|
@ -4081,22 +4081,23 @@ void halOuterLoop()
|
|||
}
|
||||
|
||||
|
||||
// DO OTHER IDLE PROCESSING HERE
|
||||
|
||||
|
||||
isidle=1;
|
||||
|
||||
halSetBusyHandler();
|
||||
|
||||
if (halCheckSystemAlarm()) {
|
||||
jobdone=isidle=0;
|
||||
halTriggerAlarm();
|
||||
}
|
||||
|
||||
} else {
|
||||
jobdone=isidle=0;
|
||||
halSetBusyHandler();
|
||||
}
|
||||
// DO OTHER IDLE PROCESSING HERE
|
||||
|
||||
|
||||
isidle=1;
|
||||
|
||||
} else { jobdone=isidle=0; }
|
||||
|
||||
|
||||
halSetBusyHandler();
|
||||
|
||||
|
||||
|
||||
|
||||
} while(!halProcessKey(keymsg));
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ LIBS += -L/usr/local/lib
|
|||
DISTFILES +=
|
||||
|
||||
|
||||
QMAKE_CFLAGS += -Wno-duplicate-decl-specifier
|
||||
#QMAKE_CFLAGS += -Wno-duplicate-decl-specifier
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -69,16 +69,26 @@ void rplCatchException()
|
|||
|
||||
Exceptions=0; // RESET THE EXCEPTIONS TO ALLOW HANDLER TO RUN
|
||||
|
||||
// SET INSTRUCTION POINTER AND CONTINUE EXECUTION AT THE ERROR HANDLER
|
||||
IPtr=ErrorHandler-1; // MAKE SURE THE FIRST OBJECT AT THE ERROR HANDLER IS NOT SKIPPED
|
||||
CurOpcode=0;
|
||||
|
||||
if(ISPROLOG(*ErrorHandler) && (LIBNUM(*ErrorHandler)==DOCOL)) {
|
||||
// SPECIAL LOW-LEVEL ERROR HANDLER
|
||||
// SPECIAL LOW-LEVEL TRANSPARENT ERROR HANDLER
|
||||
// DO NOT CLEANUP ANYTHING OR REMOVE THE HANDLER
|
||||
rplPushRet(IPtr); // PUSH THE OFFENDING OPCODE TO RESUME AFTER THE ERROR HANDLER FINISHED
|
||||
rplSetExceptionHandler((WORDPTR)error_reenter_seco);
|
||||
// TRANSPARENT ERROR HANDLERS MUST ENSURE ALL STACK, RSTACK AND LOCALS ARE LEFT INTACT
|
||||
rplPushRet((WORDPTR)exiterror_seco); // UPON NORMAL RETURN
|
||||
|
||||
IPtr=ErrorHandler; // SKIP THE PROLOG OF THE SECO, SO THAT SEMI RETURNS DIRECTLY TO exiterror_seco
|
||||
CurOpcode=0;
|
||||
|
||||
} else {
|
||||
rplRemoveExceptionHandler();
|
||||
// SET INSTRUCTION POINTER AND CONTINUE EXECUTION AT THE ERROR HANDLER
|
||||
IPtr=ErrorHandler-1; // MAKE SURE THE FIRST OBJECT AT THE ERROR HANDLER IS NOT SKIPPED
|
||||
CurOpcode=0;
|
||||
|
||||
}
|
||||
|
||||
} else rplRemoveExceptionHandler();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
CMD(XEQSECO,MKTOKENINFO(7,TITYPE_NOTALLOWED,1,2)), \
|
||||
ECMD(SEMI,";",MKTOKENINFO(1,TITYPE_NOTALLOWED,1,2)), \
|
||||
CMD(EVAL1NEXT,MKTOKENINFO(9,TITYPE_NOTALLOWED,1,2)), \
|
||||
ECMD(ERROR_EXIT,"",MKTOKENINFO(0,TITYPE_NOTALLOWED,1,2)), \
|
||||
CMD(RESUME,MKTOKENINFO(6,TITYPE_NOTALLOWED,1,2)), \
|
||||
CMD(DOERR,MKTOKENINFO(5,TITYPE_NOTALLOWED,1,2)), \
|
||||
CMD(ERRN,MKTOKENINFO(4,TITYPE_NOTALLOWED,1,2)), \
|
||||
CMD(ERRM,MKTOKENINFO(4,TITYPE_NOTALLOWED,1,2)), \
|
||||
|
@ -63,6 +65,11 @@ ROMOBJECT errormsg_ident[]={
|
|||
TEXT2WORD('r','M','s','g')
|
||||
};
|
||||
|
||||
ROMOBJECT exiterror_seco[]={
|
||||
CMD_ERROR_EXIT
|
||||
};
|
||||
|
||||
|
||||
// EXTERNAL EXPORTED OBJECT TABLE
|
||||
// UP TO 64 OBJECTS ALLOWED, NO MORE
|
||||
const WORDPTR const ROMPTR_TABLE[]={
|
||||
|
@ -86,7 +93,7 @@ void LIB_HANDLER()
|
|||
rplException(EX_EXITRPL);
|
||||
return;
|
||||
case BKPOINT:
|
||||
rplException(EX_BKPOINT);
|
||||
rplException(EX_HALT);
|
||||
return;
|
||||
case XEQSECO:
|
||||
// IF THE NEXT OBJECT IN THE SECONDARY
|
||||
|
@ -119,6 +126,98 @@ void LIB_HANDLER()
|
|||
// SINCE IPtr POINTS TO THE NEXT OBJECT, IT WILL BE SKIPPED
|
||||
return;
|
||||
|
||||
case ERROR_EXIT:
|
||||
// THIS IS CALLED ONLY WHEN INSIDE AN ERROR HANDLER TO CLEANUP AND EXIT
|
||||
// JUST LIKE A NORMAL ERROR HANDLER WOULD
|
||||
// THE RETURN STACK CAN NEVER BE EMPTY (CHECK THAT) AND IT SHOULD HAVE:
|
||||
// ON NORMAL RETURN FROM AN ERROR HANDLER:
|
||||
// 1: ... SPECIAL ERROR HANDLER ... 4: IPtr TO RESUME 5: ... OLD ERROR HANDLER
|
||||
{
|
||||
if(rplDepthRet()<5) {
|
||||
// THIS OPCODE WAS NOT CALLED FROM WITHIN AN ERROR HANDLER, JUST DO EXITRPL
|
||||
rplException(EX_EXITRPL);
|
||||
return;
|
||||
}
|
||||
if(ErrorHandler!=(WORDPTR)error_reenter_seco) {
|
||||
// NOT WITHIN AN ERROR HANDLER
|
||||
rplException(EX_EXITRPL);
|
||||
return;
|
||||
}
|
||||
rplRemoveExceptionHandler(); // REMOVE THE REENTRANT EXCEPTION HANDLER
|
||||
|
||||
IPtr=rplPopRet(); // GET THE CALLER ADDRESS
|
||||
if(IPtr) CurOpcode=*IPtr; // SET THE WORD SO MAIN LOOP SKIPS THIS OBJECT, AND THE NEXT ONE IS EXECUTED
|
||||
|
||||
rplRemoveExceptionHandler();
|
||||
return; // AND CONTINUE EXECUTION AS IF SEMI WAS EXECUTED
|
||||
|
||||
}
|
||||
if((rplDepthRet()<11)||(rplPeekRet(5)!=(WORDPTR)errorexit_seco)) {
|
||||
// THIS OPCODE WAS NOT CALLED AS AN ERROR WITHIN AN ERROR HANDLER, JUST DO EXITRPL
|
||||
rplException(EX_EXITRPL);
|
||||
return;
|
||||
}
|
||||
|
||||
// ERROR IN THE ERROR HANDLER?
|
||||
rplRemoveExceptionHandler(); // REMOVE THE ERROR HANDLER WITHIN THE ERROR HANDLER
|
||||
rplPopRet(); // REMOVE THE errorexit HANDLER
|
||||
rplPopRet(); // REMOVE THE RESUME ADDRESS
|
||||
rplRemoveExceptionHandler(); // REMOVE THE OLD EXCEPTION HANDLER
|
||||
|
||||
// AND DO SEMI, WHICH WILL PUT IPtr TO EXECUTE THE ENDERR WORD
|
||||
IPtr=rplPopRet(); // GET THE CALLER ADDRESS
|
||||
if(IPtr) CurOpcode=*IPtr; // SET THE WORD SO MAIN LOOP SKIPS THIS OBJECT, AND THE NEXT ONE IS EXECUTED
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case RESUME:
|
||||
// THIS IS CALLED ONLY WHEN INSIDE AN ERROR HANDLER TO "RESUME" THE ORIGINAL CODE
|
||||
// JUST AFTER THE OPCODE THAT CAUSED THE EXCEPTION
|
||||
// THE RETURN STACK CAN NEVER BE EMPTY (CHECK THAT) AND IT SHOULD HAVE:
|
||||
// ON NORMAL RETURN FROM AN ERROR HANDLER:
|
||||
// 1: errorexit_seco, 2: IPtr, 3: ... OLD ERROR HANDLER ...
|
||||
|
||||
|
||||
{
|
||||
if(rplDepthRet()<7) {
|
||||
// THIS OPCODE WAS NOT CALLED FROM WITHIN AN ERORR HANDLER, JUST DO EXITRPL
|
||||
rplException(EX_EXITRPL);
|
||||
return;
|
||||
}
|
||||
if(rplPeekRet(1)==(WORDPTR)errorexit_seco) {
|
||||
// THIS OPCODE WAS CALLED AS A NORMAL RETURN FROM AN ERROR HANDLER
|
||||
rplPopRet(); // REMOVE THE errorexit HANDLER
|
||||
rplPopRet(); // REMOVE THE RESUME ADDRESS
|
||||
rplRemoveExceptionHandler(); // REMOVE THE OLD EXCEPTION HANDLER
|
||||
|
||||
IPtr=rplPopRet(); // GET THE CALLER ADDRESS
|
||||
if(IPtr) CurOpcode=*IPtr; // SET THE WORD SO MAIN LOOP SKIPS THIS OBJECT, AND THE NEXT ONE IS EXECUTED
|
||||
return; // AND CONTINUE EXECUTION AS IF SEMI WAS EXECUTED
|
||||
|
||||
}
|
||||
if((rplDepthRet()<11)||(rplPeekRet(5)!=(WORDPTR)errorexit_seco)) {
|
||||
// THIS OPCODE WAS NOT CALLED AS AN ERROR WITHIN AN ERROR HANDLER, JUST DO EXITRPL
|
||||
rplException(EX_EXITRPL);
|
||||
return;
|
||||
}
|
||||
|
||||
// ERROR IN THE ERROR HANDLER?
|
||||
rplRemoveExceptionHandler(); // REMOVE THE ERROR HANDLER WITHIN THE ERROR HANDLER
|
||||
rplPopRet(); // REMOVE THE errorexit HANDLER
|
||||
rplPopRet(); // REMOVE THE RESUME ADDRESS
|
||||
rplRemoveExceptionHandler(); // REMOVE THE OLD EXCEPTION HANDLER
|
||||
|
||||
// AND DO SEMI, WHICH WILL PUT IPtr TO EXECUTE THE ENDERR WORD
|
||||
IPtr=rplPopRet(); // GET THE CALLER ADDRESS
|
||||
if(IPtr) CurOpcode=*IPtr; // SET THE WORD SO MAIN LOOP SKIPS THIS OBJECT, AND THE NEXT ONE IS EXECUTED
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
case DOERR:
|
||||
// THROW AN ERROR BY EITHER A STRING OR ERROR CODE
|
||||
{
|
||||
|
|
|
@ -178,8 +178,9 @@ void rplClearErrors();
|
|||
void rplBlameUserCommand();
|
||||
void rplBlameError(WORDPTR command);
|
||||
|
||||
|
||||
#define CLEAN_RUN 0
|
||||
#define NEEDS_CLEANUP 1
|
||||
#define CODE_HALTED 2
|
||||
|
||||
// ENVIRONMENT FUNCTIONS IN RUNSTREAM.C
|
||||
void rplInit();
|
||||
|
@ -708,7 +709,7 @@ void rplSkipNextAlarm();
|
|||
// DEFINED EXCEPTIONS
|
||||
|
||||
#define EX_EXITRPL 1
|
||||
#define EX_BKPOINT 2
|
||||
#define EX_HALT 2
|
||||
#define EX_OUTOFMEM 4
|
||||
#define EX_ERRORCODE 8
|
||||
#define EX_POWEROFF 16
|
||||
|
|
|
@ -255,25 +255,28 @@ BINT rplRun(void)
|
|||
else {
|
||||
rplError(ERR_MISSINGLIBRARY);
|
||||
// INVALID OPCODE = END OF EXECUTION (CANNOT BE TRAPPED BY HANDLER)
|
||||
return 1;
|
||||
return NEEDS_CLEANUP;
|
||||
}
|
||||
if(Exceptions) {
|
||||
|
||||
// HARD EXCEPTIONS FIRST, DO NOT ALLOW ERROR HANDLERS TO CATCH THESE ONES
|
||||
if(Exceptions&EX_EXITRPL) {
|
||||
Exceptions=0;
|
||||
rplClearRStk(); // CLEAR THE RETURN STACK
|
||||
rplClearLAMs(); // CLEAR ALL LOCAL VARIABLES
|
||||
ErrorHandler=0;
|
||||
return 0; // DON'T ALLOW HANDLER TO TRAP THIS EXCEPTION
|
||||
return CLEAN_RUN; // DON'T ALLOW HANDLER TO TRAP THIS EXCEPTION
|
||||
}
|
||||
if(Exceptions&EX_HALT) { rplSkipNext(); return CODE_HALTED; } // PREPARE TO RESUME ON NEXT CALL
|
||||
if(Exceptions&EX_POWEROFF) { rplSkipNext(); return CODE_HALTED; } // PREPARE AUTORESUME
|
||||
|
||||
if(ErrorHandler) {
|
||||
// ERROR WAS TRAPPED BY A HANDLER
|
||||
rplCatchException();
|
||||
}
|
||||
else {
|
||||
// THERE IS NO ERROR HANDLER --> UNTRAPPED ERROR
|
||||
if(Exceptions&EX_BKPOINT) rplSkipNext(); // PREPARE TO RESUME ON NEXT CALL
|
||||
if(Exceptions&EX_POWEROFF) { rplSkipNext(); return 2; }
|
||||
return 1; // END EXECUTION IMMEDIATELY IF AN UNHANDLED EXCEPTION IS THROWN
|
||||
return NEEDS_CLEANUP; // END EXECUTION IMMEDIATELY IF AN UNHANDLED EXCEPTION IS THROWN
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue