| File Variables |
| Argument passing - Subroutines and Functions - Mike Pope |
| RevTech Replies - Mike Pope (RevTech UK Ltd) |
| Symbol Table Structure |
| SecureUser |
| VERBatim - V25 |
| @ATTACK - @Files.System |
| Advanced Revelation Initialisation Sequence (Overview) by Mike Pope |
| REVMEDIA Revisted |
| Reader's Clinic - Functions and Subroutines |
| Reader's Letters - Jim Owen |
| Playing with Scan Codes |
| Argument passing - Subroutines and Functions - Mike Pope |
| Creating Your Own Background Processes |
| @ATTACK - @Last.Select.Process |
| Reader's Forum |
| QTIPS - Menu Item Pre-Processing |
| QTIPS - DOSTime |
| VERBatim - V11 |
| @ATTACK - @Backgrnd.Time |
| @ATTACK - @Index.Time |
| QTIPS - Time-outs in Windows |
| Gas Bar |
| @ATTACK - @Rn.Counter |
| QTIPS - Replacing GAS.BAR routine during PERFORM "SELECT" |
| QTIPS - Inconsistent @Variable Behaviour |
| Playing with Scan Codes |
| QTIPS - Compiling Protection Code |
| QTIPS - Invalid Code and Command |
| QTIPS - Code/Command Help |
| Compiling 64K on a Shoestring by Blaise Wrenn (LexStat Systems Ltd) |
| QTIPS - Using @Upper.Case and @Lower.Case with Foreign Languages |
| @ATTACK - @Lower.Case |
| @ATTACK - @Upper.Case |
| Sorting out Collation Sequences by Mike Pope |
| Reader's Clinic - Different Id Same Record |
| RTP Series - RTP25 |
| QTIPS - String Space |
| Reader's Letters - Jim Owen |
| QTIPS - Finding/Replacing Spaces With The Editor |
| RTP Series - RTP18 |
| RTP Series - RTP18.english |
| VERBatim - V39 |
| Advanced Revelation Initialisation Sequence (Overview) by Mike Pope |
| REVMEDIA Revisited |
RevMedia FKB
| Document | V4I2A10 |
| Title | The End of the Line - Mike Pope and Hal Wyman |
| Keywords | LINEMARK RTP25 BREAK KEY TRACE DEBUGGER $INSERT STOPLINECOUNT STARTLINECOUNT |
| Text | What R/BASIC STATEMENT do you use most often? PRINT? REM? Angle brackets? No easily the most common STATEMENT is an obscure even invisible one: LINEMARK Even if you've never typed it in you have used it: the compiler puts this STATEMENT at the end of every physical line of the program wherever there is an @FM (but not ';') (Note: the discussion here pertains to Advanced Revelation 2 1; minor differences obtain in earlier versions ) If it's so common what does the LINEMARK STATEMENT do? Basically it has the indirect role of being the place in an executing program where the debugger can grab hold Consider that the debugger can appear for many reasons (besides the occasional fatal error) One is that [Ctrl Break] has been pressed; another is if you have set the execution counter; yet another is that you have a trace on a variable or program Each of these involves flags set by the system For EXAMPLE when you press the break key not much really happens About the only activity is that the keyboard handler within AREV EXE not the BIOS or life would be simpler sets a flag stating "break key pressed" Actually doing something about the break key is the function of a higher level process and in Advanced Revelation that's the LINEMARK opcode Each time this STATEMENT is executed that is at every line it checks the "break key has been hit" flag If the flag is set and the "break key enabled" flag is ALSO set (i e you haven't executed BREAK OFF) LINEMARK springs into action by CALLING RTP25 Advanced Revelation's own debugger Note that the linemark opcode itself doesn't actually do too much Its sole function is to check the flags If it sees one it CALLS the debugger to sort out why the flag was set and what to do about it If you ever wondered why a program WITH a trace executes so slowly now you know: it's not only checking the trace flag for each line but CALLING the debugger to determine if it's time to call a halt or just carry on to the next line The most visible evidence of linemarks is the line counter that appears when you drop into the debugger Again though this is an indirect function Having decided to call the debugger the engine first paws through the object code for the currently executing program and analyzes each opcode counting linemarks producing at the end a "line count" In this case the linemark really is nothing more than the passive place marker it is often assumed to be Using LINEMARK There is some overhead involved in having a LINEMARK An empty LOOP with LINEMARK runs in 15 16 seconds; without LINEMARK in 13 97 Obviously the linemark opcode adds roughly 9% onto the execution speed of a line Just as interesting is the space taken up by all those bonus linemarks For example look at the size of the OBJECT code for RTP18 (TCL) a program of about 750 lines (29K) compiled WITH and without linemarks: WITH 6 312 bytes without 5 300 bytes The space you save would vary WITH the number of comments the statements you'd used etc But you can see that excluding linemarks can MAKE quite a difference To remove linemarks COMPILE at TCL (not within the editor) USING the (L) option Do this and you'll ALSO soon experience the downside No linemark no checking of flags no debugger no stopping the program Run a long index search then press [Ctrl Break]: nothing happens at least not immediately Most system programs are compiled yes for speed reasons without linemarks Therefore there is nothing to detect the "break key pressed flag" until of course you do actually encounter a linemark even if the next linemark to happen along is in say INPUT CHAR In some system programs you'll STOP if you press [Ctrl Break] but you'll get an absurd line number: "WINDOW Line 2 " It hasn't really stopped on line 2; that's just how many linemarks the engine detected up the point of execution before CALLING the debugger This illustrates a compromise you can make when USING linemarks It's efficient to suppress linemarks but it's drastic: there will be no ex machina way into the program However you can add the odd LINEMARK here and there to provide a backdoor for the debugger In fact it's a sound piece of advice to always put a LINEMARK statement inside a LOOP so: LOOP LINEMARK UNTIL PIGS_FLY REPEAT None of the above applies to DICTIONARY items First the COMPILER forces an (L) option for dict items and second even explicit LINEMARKs are ignored in SYMBOLIC fields $INSERT statements pose another problem These cause code to be included into the source; by the time the code gets to the 'real' compiler it's all one program Normally of course there would be a linemark at the end of each line and any line counting would be completely out of whack But the system seems to ignore the lines within the $INSERT as far as counting lines is concerned This trick is accomplished USING the little known STOPLINECOUNT and STARTLINECOUNT statements that act as switches telling the compiler to do what their NAMES suggest They are embedded by the compiler's preprocessor around any $INSERT statements These give you a means within a program of doing what the (L) option does in the compiler namely to cause linemarks not to be added WITH the added advantage of being able to turn linemark suppression off and on for only specific portions of a program You can therefore PROTECT critical areas of your program FROM user interference (and make them EXECUTE that slight bit faster) while retaining the flexibility to break into a program at any point As WITH the (L) compiler option these statements have no effect on any hard coded LINEMARK statements which remain in place (and executable) no matter what though the line numbers they REPORT will not be accurate any more You now know everything you need to about LINEMARK As WITH many humble things there is more to it than meets the eye And now at least you can feel that you are on intimate terms WITH the R/BASIC STATEMENT that you use consciously or otherwise more than any other in the system (Volume 4 Issue 2 Pages 14 15) |
Page last modified: 31/01/03