Previous: Chainer
Up: Chainer and MarkJump
Previous Page: Chainer
Next Page: Use of DlgGlbls

MarkJump

MarkJump is a unit that implements so-called ``long jumps'' (i.e. jumps across Intel memory segment boundaries) to previously marked locations in the code. It provides routines to do the marking, return a data structure containing the mark, and to jump to the location given by that structure. Since the mark records the full CPU process state at the time of marking, this also cuts back the stack and eliminates all outstanding procedure calls, by brute force.

This version of MarkJump is based on a previous form kindly supplied by Tim Hudson .

BEWARE! This unit is highly dependent on DOS and on Turbo Pascal syntax extensions.

The exported declarations are as follows:

UNIT MarkJump;

INTERFACE

TYPE jumploc = RECORD validenv : BOOLEAN; returnval : WORD; _bp, _sp, _ss, _ds, _ip, _cs, _obp : WORD; (**)OpenFHandles: set of 0 .. 255; end;

VAR dgNextModName: string[80]; { Name of next module to be run, for menu's information. Usually supplied by Ports. Empty string can be taken as requesting menu itself. } dgParamSaveBuffer: string; dgTargetMark: ARRAY[1..20] OF JumpLoc; { Long jump targets available for general use. }

{ returns 0 on original call and the retvalue of the long jump from routines that jump to it } function setjmp(var env:jumploc):word; { jump to set up location - retval should not be 0 (not checked) }

procedure longjmp(var env:jumploc; retval:word);

PROCEDURE MarkFilesOpen(VAR Env: JumpLoc);

PROCEDURE ExitToTarget(VAR Env: JumpLoc; RetVal: WORD);

implementation

FUNCTION SetJmp( VAR Env: JumpLoc): WORD;

SetJmp returns in the Env the process environment from which it was called. It may now be used by LongJmp, below, to jump from any location in the code back to the position at which SetJmp was called. Since this means that SetJmp will appear to its calling code to be returning either when it itself is called, or when LongJmp is called, its return indicates which one is the case for a given return: 0 indicates returning from SetJmp itself; anything else indicates arrival by long jump.

PROCEDURE ExitToTarget(VAR Env: JumpLoc; RetVal: WORD);

ExitToTarget effects an unconditional jump to the location in the executing code recorded in Env, which must have been initialised by SetJmp before the call to ExitToTarget. This completely cuts off the execution at the location from which ExitToTarget was called, resuming it at the return from the SetJmp call that initialised Env. RetVal supplies the function value that SetJmp will (appear to) return.

Before performing the jump, ExitToTarget closes all open DOS file handles that Env indicates were not open when it was initialised. See MarkFilesOpen, below.

ExitToTarget does not risk attempting to cut heap usage back to where it was when Env was taken. Any combination of usages, including system usages, could still be outstanding, and the unit would risk corrupting the system if it attempted to restore the heap.

This is a very dangerous way to transfer control. Its only purpose in the dialogue library is to provide Ports with a substitute for the EXIT routine to which Turbo Pascal provides no equivalent, and without which Ports cannot perform the necessary termination of the module from within Extra Services.

procedure longjmp(var env:jumploc; retval:word);

longjmp is used by ExitToTarget to perform the actual jump to Env's location. It does not perform the file-handle closing. ExitToTarget is the preferred routine to use.

PROCEDURE MarkFilesOpen(VAR Env: JumpLoc);

MarkFilesOpen adds to the Env a record of the DOS file handles that are open at the time of the call to it. Any that are found to have been opened since then, when Env is passed to ExitToTarget, are then closed. This is primarily to avoid losing available DOS file handles, since little or no information can be available to the unit about how those files were being used. It also makes the risky assumption that the association of a given file handle that was open at the time of marking has not since changed to a different file.

Fortunately, MarkJump's services are required in only one place: Ports' exit from within the individual module, back to the attract mode.



Previous: Chainer
Up: Chainer and MarkJump
Previous Page: Chainer
Next Page: Use of DlgGlbls

Educational Technology Center
Dept. of Info. and Comp.Sci.
Univ. of California, Irvine
92717, CA, USA