From e0e0f8fa3dfb5d921d94855ab367320707272a2d Mon Sep 17 00:00:00 2001 From: claudiol Date: Tue, 6 Dec 2016 18:21:53 -0500 Subject: [PATCH] Modified how error handlers are called. Added RESUME command. --- mainwindow.cpp | 5 +++ mainwindow.h | 2 ++ mainwindow.ui | 12 ++++++++ newrpl/errors.c | 26 ++++++---------- newrpl/lib-eight-docol.c | 66 +++++++++------------------------------- newrpl/lib-nine-docol2.c | 31 ++++++++++++++++--- newrpl/libraries.h | 1 - newrpl/newrpl.h | 1 + newrpl/runstream.c | 9 ++++-- newrpl/sysvars.c | 2 +- newrpl/sysvars.h | 2 +- 11 files changed, 78 insertions(+), 79 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index da60edd..e96cc71 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -661,3 +661,8 @@ void MainWindow::on_actionPower_ON_triggered() screentmr->start(50); } + +void MainWindow::on_actionSimulate_Alarm_triggered() +{ + +} diff --git a/mainwindow.h b/mainwindow.h index 3e1f8a4..c352ff8 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -56,6 +56,8 @@ private slots: void on_actionPower_ON_triggered(); + void on_actionSimulate_Alarm_triggered(); + public slots: void domaintimer(); private: diff --git a/mainwindow.ui b/mainwindow.ui index 07139e8..a114762 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -54,8 +54,15 @@ + + + Hardware + + + + @@ -106,6 +113,11 @@ Power ON + + + Simulate Alarm + + diff --git a/newrpl/errors.c b/newrpl/errors.c index 0172d0f..d352541 100644 --- a/newrpl/errors.c +++ b/newrpl/errors.c @@ -70,29 +70,14 @@ void rplCatchException() Exceptions=0; // RESET THE EXCEPTIONS TO ALLOW HANDLER TO RUN - if(ISPROLOG(*ErrorHandler) && (LIBNUM(*ErrorHandler)==DOCOL)) { - // SPECIAL LOW-LEVEL TRANSPARENT ERROR HANDLER - // DO NOT CLEANUP ANYTHING OR REMOVE THE HANDLER + // DO NOT CLEANUP ANYTHING OR REMOVE THE HANDLER rplProtectData(); // PROTECT THE USER DATA STACK WITHIN THE ERROR 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(rplPeekRet(4)); // PUSH RETURN ADDRESS AS IF GOING INTO THE SECO - rplPushRet((WORDPTR)error_exit_seco); // INJECT CLEANUP UPON NORMAL RETURN - IPtr=rplPeekRet(2); /*=ErrorHandler (original)*/; // SKIP THE PROLOG OF THE SECO, SO THAT SEMI RETURNS DIRECTLY TO exiterror_seco + IPtr=rplPeekRet(4)-1; /*=ErrorHandler (original)*/; CurOpcode=0; - } else { - // 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; - rplRemoveExceptionHandler(); - - - } - - } // RAISE AN RPL EXCEPTION @@ -102,6 +87,13 @@ void rplException(WORD exception) ExceptionPointer=IPtr; } +// RAISE A HARDWARE RPL EXCEPTION +void rplHardException(WORD exception) +{ + HWExceptions|=exception; +} + + // RAISE A LIBRARY ERROR EXCEPTION // AND SET THE ERROR CODE TO THE GIVEN OPCODE void rplError(WORD errorcode) diff --git a/newrpl/lib-eight-docol.c b/newrpl/lib-eight-docol.c index 9b2fe41..5482583 100644 --- a/newrpl/lib-eight-docol.c +++ b/newrpl/lib-eight-docol.c @@ -33,13 +33,14 @@ 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)), \ ECMD(ERROR_REENTER,"",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)), \ - CMD(ERR0,MKTOKENINFO(4,TITYPE_NOTALLOWED,1,2)) + CMD(ERR0,MKTOKENINFO(4,TITYPE_NOTALLOWED,1,2)), \ + CMD(HALT,MKTOKENINFO(4,TITYPE_NOTALLOWED,1,2)) + @@ -66,10 +67,6 @@ ROMOBJECT errormsg_ident[]={ TEXT2WORD('r','M','s','g') }; -ROMOBJECT error_exit_seco[]={ - CMD_XEQSECO, - CMD_ERROR_EXIT -}; ROMOBJECT error_reenter_seco[]={ @@ -82,7 +79,6 @@ ROMOBJECT error_reenter_seco[]={ // UP TO 64 OBJECTS ALLOWED, NO MORE const WORDPTR const ROMPTR_TABLE[]={ (WORDPTR)errormsg_ident, - (WORDPTR)error_exit_seco, (WORDPTR)error_reenter_seco, 0 }; @@ -104,6 +100,10 @@ void LIB_HANDLER() rplException(EX_EXITRPL); return; case BKPOINT: + // TODO: IMPLEMENT CONDITIONAL BREAKPOINTS + // FOR NOW BEHAVE SAME AS HALT + // DELIBERATE FALL-THROUGH + case HALT: rplException(EX_HALT); return; case XEQSECO: @@ -135,37 +135,6 @@ 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: RETURN ADDRESS TO CONTINUE ERROR HANDLER - // 2: ... SAVED ERROR HANDLER ... - // 6: IPtr TO RESUME - // 7: ... 8: DATA STACK PROTECTION - // 9: ... SAVED USER ERROR HANDLER - { - if(rplDepthRet()<12) { - // 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; - } - 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(); // REMOVE THE REENTRANT EXCEPTION HANDLER - rplPopRet(); // REMOVE RESUME ADDRESS - rplUnprotectData(); // REMOVE STACK PROTECTION - rplRemoveExceptionHandler(); // REMOVE ORIGINAL USER ERROR HANDLER - return; // AND CONTINUE EXECUTION AS IF SEMI WAS EXECUTED - } - case ERROR_REENTER: // THIS IS CALLED ONLY WHEN A SPECIAL ERROR THROWS AN ERROR, TO CLEANUP AND EXIT // JUST LIKE A NORMAL ERROR HANDLER WOULD @@ -181,6 +150,8 @@ void LIB_HANDLER() return; } + rplRemoveExceptionHandler(); // REMOVE SECOND RE-ENTER HANDLER + rplRemoveExceptionHandler(); // REMOVE ORIGINAL RE-ENTER ERROR HANDLER rplPopRet(); // REMOVE RESUME ADDRESS DSTop=rplUnprotectData(); // CLEANUP STACK FROM ANYTHING THE FAILING ERROR HANDLER DID rplRemoveExceptionHandler(); // REMOVE ORIGINAL USER ERROR HANDLER @@ -196,25 +167,20 @@ void LIB_HANDLER() // 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: exit_error_seco - // 2: RETURN ADDRESS TO CONTINUE ERROR HANDLER - // 3: ... SAVED ERROR HANDLER ... - // 7: IPtr TO RESUME - // 8: ... 9: DATA STACK PROTECTION - // 10: ... SAVED USER ERROR HANDLER + // 1: ... SAVED ERROR HANDLER ... + // 5: IPtr TO RESUME + // 6: ... 7: DATA STACK PROTECTION + // 8: ... SAVED USER ERROR HANDLER { - if(rplDepthRet()<13) { + if(rplDepthRet()<11) { // THIS OPCODE WAS NOT CALLED FROM WITHIN AN ERROR HANDLER, JUST DO NOP return; } - if((rplPeekRet(1)!=(WORDPTR)error_exit_seco) || (ErrorHandler!=(WORDPTR)error_reenter_seco)) { + if(ErrorHandler!=(WORDPTR)error_reenter_seco) { // NOT WITHIN AN ERROR HANDLER, DO NOTHING return; } - rplPopRet(); // DON'T NEED exit_error_seco - rplPopRet(); // DROP THE CALLER ADDRESS TO EXIT THE ERROR HANDLER - rplRemoveExceptionHandler(); // REMOVE THE REENTRANT EXCEPTION HANDLER IPtr=rplPopRet(); // RESUME AT THIS ADDRESS CurOpcode=*IPtr; // MAKE SURE THE OFFENDING OBJECT IS SKIPPED @@ -365,8 +331,6 @@ void LIB_HANDLER() return; } - - // ADD MORE OPCODES HERE case OVR_EVAL: case OVR_EVAL1: diff --git a/newrpl/lib-nine-docol2.c b/newrpl/lib-nine-docol2.c index 78a5732..0a0a429 100644 --- a/newrpl/lib-nine-docol2.c +++ b/newrpl/lib-nine-docol2.c @@ -553,9 +553,20 @@ void LIB_HANDLER() } return; case ELSEERR: - // THIS WOULD ONLY BE EXECUTED AT THE END OF AN ERROR TRAP. SKIP TO THE ENDERR MARKER { - int count=0; + if(ErrorHandler!=(WORDPTR)error_reenter_seco) { + // NOT WITHIN AN ERROR HANDLER, DO NOTHING + return; + } + + // AT THE END OF THE ERROR HANDLER, DO SOME CLEANUP + rplRemoveExceptionHandler(); + rplPopRet(); + rplUnprotectData(); + rplRemoveExceptionHandler(); + + // SKIP TO THE ENDERR MARKER + int count=0; while(count || (*IPtr!=MKOPCODE(LIBRARY_NUMBER,ENDERR)) ) { if(*IPtr==MKOPCODE(LIBRARY_NUMBER,IFERR)) ++count; if(*IPtr==MKOPCODE(LIBRARY_NUMBER,ENDERR)) --count; @@ -567,10 +578,20 @@ void LIB_HANDLER() return; case ENDERR: - // THIS IS ONLY EXECUTED WHEN EXITING AN ERROR HANDLER - // THERE'S NOTHING ELSE TO DO - return; + { + if(ErrorHandler!=(WORDPTR)error_reenter_seco) { + // NOT WITHIN AN ERROR HANDLER, OR AFTER AN ELSEERR STATEMENT, DO NOTHING + return; + } + // AT THE END OF THE ERROR HANDLER, DO SOME CLEANUP + rplRemoveExceptionHandler(); + rplPopRet(); + rplUnprotectData(); + rplRemoveExceptionHandler(); + + return; + } // STANDARIZED OPCODES: diff --git a/newrpl/libraries.h b/newrpl/libraries.h index de7652d..6165e4e 100644 --- a/newrpl/libraries.h +++ b/newrpl/libraries.h @@ -418,7 +418,6 @@ extern const WORD empty_string[]; extern const WORD empty_list[]; extern const WORD angle_180[]; extern const WORD savedcmdline_ident[]; -extern const WORD error_exit_seco[]; extern const WORD error_reenter_seco[]; diff --git a/newrpl/newrpl.h b/newrpl/newrpl.h index 67c15ce..c2f1a69 100644 --- a/newrpl/newrpl.h +++ b/newrpl/newrpl.h @@ -738,6 +738,7 @@ void rplSkipNextAlarm(); #define EX_ERRORCODE 8 #define EX_POWEROFF 16 #define EX_DIRTYFS 32 +#define EX_AUTORESUME 64 // ADD OTHER EXCEPTIONS HERE diff --git a/newrpl/runstream.c b/newrpl/runstream.c index 46d39c1..0e70383 100644 --- a/newrpl/runstream.c +++ b/newrpl/runstream.c @@ -257,7 +257,10 @@ BINT rplRun(void) // INVALID OPCODE = END OF EXECUTION (CANNOT BE TRAPPED BY HANDLER) return NEEDS_CLEANUP; } + Exceptions|=HWExceptions; // COPY HARDWARE EXCEPTIONS INTO EXCEPTIONS AT THIS POINT TO AVOID + // STOPPING IN THE MIDDLE OF A COMMAND if(Exceptions) { + if(HWExceptions) HWExceptions=0; // CLEAR ANY HARDWARE EXCEPTIONS // HARD EXCEPTIONS FIRST, DO NOT ALLOW ERROR HANDLERS TO CATCH THESE ONES if(Exceptions&EX_EXITRPL) { @@ -383,7 +386,7 @@ void rplInit(void) DStkSize=0; // TOTAL SIZE OF DATA STACK RStkSize=0; // TOTAL SIZE OF RETURN STACK LAMSize=0; - Exceptions=0; // NO EXCEPTIONS RAISED + HWExceptions=Exceptions=0; // NO EXCEPTIONS RAISED ExceptionPointer=0; rplClearLibraries(); @@ -473,7 +476,7 @@ void rplWarmInit(void) IPtr=0; // INSTRUCTION POINTER SHOULD BE SET LATER TO A VALID RUNSTREAM CurOpcode=0; // CURRENT OPCODE (WORD) - Exceptions=0; // NO EXCEPTIONS RAISED + HWExceptions=Exceptions=0; // NO EXCEPTIONS RAISED ExceptionPointer=0; RSTop=RStk; // CLEAR RETURN STACK @@ -562,7 +565,7 @@ void rplHotInit() IPtr=0; // INSTRUCTION POINTER SHOULD BE SET LATER TO A VALID RUNSTREAM CurOpcode=0; // CURRENT OPCODE (WORD) - Exceptions=0; // NO EXCEPTIONS RAISED + HWExceptions=Exceptions=0; // NO EXCEPTIONS RAISED ExceptionPointer=0; RSTop=RStk; // CLEAR RETURN STACK diff --git a/newrpl/sysvars.c b/newrpl/sysvars.c index 4406afe..2db35a7 100644 --- a/newrpl/sysvars.c +++ b/newrpl/sysvars.c @@ -79,7 +79,7 @@ BINT NumHiLibs; // OTHER RPL CORE VARIABLES THAT ARE NOT AFFECTED BY GC WORD CurOpcode; // CURRENT OPCODE (WORD) -WORD Exceptions, TrappedExceptions; // FLAGS FOR CURRENT EXCEPTIONS +WORD HWExceptions, Exceptions, TrappedExceptions; // FLAGS FOR CURRENT EXCEPTIONS WORD ErrorCode, TrappedErrorCode; WORDPTR *ValidateTop; // TEMPORARY DATA AFTER THE RETURN STACK USED DURING COMPILATION WORDPTR *ValidateBottom; // TEMPORARY DATA AFTER THE RETURN STACK USED DURING COMPILATION diff --git a/newrpl/sysvars.h b/newrpl/sysvars.h index 0a55691..944cde5 100644 --- a/newrpl/sysvars.h +++ b/newrpl/sysvars.h @@ -67,7 +67,7 @@ WORDPTR *LAMs; // BASE OF LOCAL VARIABLES STORAGE // OTHER VARIABLES THAT ARE NOT AFFECTED BY GC WORD CurOpcode; // CURRENT OPCODE (WORD) -WORD Exceptions, TrappedExceptions; // FLAGS FOR CURRENT EXCEPTIONS +WORD HWExceptions, Exceptions, TrappedExceptions; // FLAGS FOR CURRENT EXCEPTIONS WORD ErrorCode, TrappedErrorCode; WORDPTR *RSTop; // TOP OF THE RETURN STACK WORDPTR *DSTop; // TOP OF THE DATA STACK