DragonRuntimeSupport: CEDAR DEFINITIONS = BEGIN Version: CARDINAL = 0; ProcAny: TYPE = PROC ANY RETURNS ANY; ProcPtr: TYPE = LONG POINTER TO ProcAny; Comparison: TYPE = MACHINE DEPENDENT {less(0), equal(1), greater(2)}; PTR: TYPE = LONG POINTER TO Word; Word: TYPE = PACKED ARRAY [0..bitsPerWord) OF BIT; bitsPerWord: NAT = 32; RefPtr: TYPE = LONG POINTER TO REF; Type: TYPE = MACHINE DEPENDENT { nullType (0), lastType (177777B) }; RegArrayPtr: TYPE = LONG POINTER TO RegArray; RegArray: TYPE = ARRAY [0..15] OF Word; ExceptAny: TYPE = SIGNAL ANY RETURNS ANY; LockPtr: TYPE = LONG POINTER TO LockRep; LockRep: TYPE; -- for MONITORLOCK CondPtr: TYPE = LONG POINTER TO CondRep; CondRep: TYPE; -- for CONDITION SecureProcess: TYPE[3]; -- 96 bits of identification of a PROCESS MixedMul: PROC [x: CARD, y: INT] RETURNS [INT]; IntMul: PROC [x, y: INT] RETURNS [INT]; IntDiv: PROC [x, y: INT] RETURNS [INT]; IntMod: PROC [x,y: INT] RETURNS [INT]; CardMul: PROC [x, y: CARD] RETURNS [CARD]; CardDiv: PROC [x, y: CARD] RETURNS [CARD]; CardMod: PROC [x, y: CARD] RETURNS [CARD]; RealCompare: PROC [x, y: REAL] RETURNS [Comparison]; RealAdd: PROC [x, y: REAL] RETURNS [REAL]; RealSub: PROC [x, y: REAL] RETURNS [REAL]; RealMul: PROC [x, y: REAL] RETURNS [REAL]; RealDiv: PROC [x, y: REAL] RETURNS [REAL]; RealMod: PROC [x, y: REAL] RETURNS [REAL]; RealScale: PROC [r: REAL, scale: INTEGER] RETURNS [REAL]; Float: PROC [int: INT] RETURNS [REAL]; Fix: PROC [r: REAL, mode: RoundingMode _ rn] RETURNS [INT]; RoundingMode: TYPE = MACHINE DEPENDENT {rn, rz, rm, rp}; ArithmeticOverflow: ERROR; ZeroDivisor: ERROR; BoundsFault: ERROR; MoveWords: PROC [src: PTR, dst: PTR, nWords: INT]; MoveWordsDisjoint: PROC [src: PTR, dst: PTR, nWords: INT]; FillWords: PROC [src: Word, dst: PTR, nWords: INT]; FillMultiWords: PROC [src: PTR, srcSize: INT, dst: PTR, nTimes: INT]; EqualWords: PROC [x: PTR, y: PTR, nWords: INT] RETURNS [BOOL]; ExtractField: PROC [base: PTR, offset: INT, bits: [0..bitsPerWord]] RETURNS [Word]; DepositField: PROC [base: PTR, offset: INT, bits: [0..bitsPerWord], word: Word]; MoveFields: PROC [ src: PTR, srcOffset: INT, dst: PTR, dstOffset: PTR, bits: [0..bitsPerWord], times: INT]; FillFields: PROC [dst: PTR, dstOffset: PTR, bits: [0..bitsPerWord], times: INT, value: Word]; Fork: PROC [proc: ProcAny, argPtr: PTR, nArgs: INT, nRets: INT] RETURNS [SecureProcess]; Join: PROC [process: SecureProcess, retPtr: PTR]; Wait: PROC [cond: CondPtr, lock: LockPtr]; Notify: PROC [cond: CondPtr]; Broadcast: PROC [cond: CondPtr]; MonitorEntry: PROC [lock: LockPtr]; MonitorExit: PROC [lock: LockPtr]; ExtensionAlloc: PROC [nWords: INT] RETURNS [PTR]; ExtensionFree: PROC [ptr: PTR] RETURNS [PTR _ NIL]; CopyModule: PROC; StartModule: PROC [module: PTR, args: PTR]; RestartModule: PROC [module: PTR, args: PTR]; StopModule: PROC; HandlerAction: TYPE = {reject, resume, exit}; BytePC: TYPE = WORD; HandlerType: TYPE = PROC [regsPtr: RegArrayPtr, except: ExceptAny, rtnPtr: PTR, argPtr: PTR] RETURNS[action: HandlerAction, pc: BytePC, levels: NAT]; RaiseSignal: PROC [which: ExceptAny, rtns: PTR, args: PTR]; RaiseError: PROC [which: ExceptAny, args: PTR]; ExceptionBody: PROC; AbortedError: ERROR; UnwindError: ERROR; UnnamedError: ERROR; UnnamedSignal: SIGNAL; UncaughtError: ERROR; AssignRef: PROC [dstPtr: RefPtr, src: REF]; AssignNil: PROC [dstPtr: RefPtr]; AssignRefComposite: PROC [dst: PTR, src: PTR, type: Type]; AssignRefCompositeFault: ERROR; IncRC: PROC [ref: REF]; DecRC: PROC [ref: REF]; GetReferentType: PROC [ref: REF] RETURNS [Type]; Narrow: PROC [ref: REF, type: Type] RETURNS [REF]; NarrowFault: ERROR [ref: REF, type: Type]; AssignProc: PROC [dstPtr: ProcPtr, src: ProcAny]; CheckProc: PROC [proc: ProcAny]; NestedProcError: ERROR [proc: ProcAny]; NewObject: PROC [nWords: INT, type: Type] RETURNS [REF]; END. ,ΎDragonRuntimeSupport.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) January 27, 1987 7:30:51 pm PST Carl Hauser, May 8, 1987 6:42:16 pm PDT These definitions describe the architected, but private, interface between the Cedar compiler and the runtime support routines for compiled code. There is a Dragon flavor right now, but we will slowly get this stuff to be machine independent. If you are not writing the compiler, loader, makeboot, or the runtime initialization you have no business putting this interface in the DIRECTORY clause of anything. Version The version of DragonRuntimeSupport Types Basic definitions For safe storage This definition is likely to be changed somewhat. For signalling These definitions are partial. For more details, see DragonStack.mesa and SignalsImpl.mesa. Denotes any SIGNAL or ERROR For locks & processes These definitions are partial. For details, see Process.mesa. The compiler DOES NOT know the details of CONDITION, MONITORLOCK, except for their size and initial values. Arithmetic Signed numbers (INT) returns x * y raises ArithmeticOverflow if the result is not expressible as an INT note especially efficient when x is small how about optional efficient special cases for various machines? returns x * y raises ArithmeticOverflow if the result is not expressible as an INT returns x / y raises ZeroDivisor if y = 0 ArithmeticOverflow if the result is not expressible as an INT returns x MOD y (always IN [0..ABS[y]) ) raises ZeroDivisor if y = 0 ArithmeticOverflow if the result is not expressible as an INT (i.e. FIRST[INT]/-1) Signed division note: let q = IntDiv[x, y], r = IntMod[x, y], with no exceptions then x = IntMul[q, y] + r, and 0 < r < ABS[y] Unsigned numbers (CARD) returns x * y note no overflow checking returns x / y raises ZeroDivisor if y = 0 note no overflow checking returns x MOD y raises ZeroDivisor if y = 0 note no overflow checking Unigned division note: let q = CardDiv[x, y], r = CardMod[x, y], with no exceptions then x = CardMul[q, y] + r, and 0 < r < y Real numbers (32-bit IEEE) compares x and y raises RealException as specified by the IEEE standard returns x + y raises RealException as specified by the IEEE standard returns x - y raises RealException as specified by the IEEE standard returns x * y raises RealException as specified by the IEEE standard returns x / y raises RealException as specified by the IEEE standard returns x MOD y == x - Trunc[x/y]*y raises RealException as specified by the IEEE standard returns r*(2**scale) raises RealException as specified by the IEEE standard returns the real number most closely corresponding to int raises RealException as specified by the IEEE standard returns the integer closest to r determined by the mode raises RealException as specified by the IEEE standard rn: Round to nearest (unbiased). rz: Round to zero (truncate). rp: Round to plus infinity (round up). rm: Round to minus infinity (round down). Arithmetic Exceptions raised on arithmetic overflow; the compiler may raise this explictly when an arithmetic overflow is detected via a comparison rather than an arithmetic instruction. raised when dividing by 0; the compiler may raise this explictly when a division by zero is detected via a comparison rather than a call to divide. raised when a bounds check instruction fails; the compiler may raise this explictly when a bounds fault is detected via a comparison rather than via a bounds check instruction. RealException: ERROR ...; -- is defined in the Real interface. (The compiler does not know the details, and does not use this error explictly). Vectors Moving Multi-word variables are transferred via these built-in routines. Moves words from the source to the destination. No words are moved if nWords < 0. Increasing addresses are used. If the variables overlap, words are transferred singly, otherwise MoveWords is the same as MoveWordsDisjoint. Moves words from the source to the destination. No words are moved if nWords < 0. Increasing addresses are used. For efficiency, no check is made for overlapping variables, but the caller assures disjointness. Filling The ALL construct allows for filling of arrays. Assignment of some kinds of constant multi-word variables can be handled similarly. For sub-word arrays, the compiler promotes the filling to word or field assignment. Initializes words in the destination to the src word. No words are moved if nWords < 0. Increasing dst addresses are used. Useful for ALL[foo]. Initializes words in the destination to the src words (starting at src for srcSize words). No words are moved if nTimes < 0. Increasing addresses are used. Useful for ALL[foo]. Equality Multi-word variables need multi-word equality testing. Tests the two multi-word variables for equality. Fields When the compiler encounters really difficult cases it emits calls to these routines. Extracts the field from any base pointer at any reasonable bit offset. The word returned is the field right-justified with zero bits on the left. Deposits the field to any base pointer at any reasonable bit offset. The word given has the bits right-justified. Moves fields that are bits wide from the src address (plus srcOffset bits) to the dst address (plus dstOffset bits) for times number of fields. Increasing addresses will be used. If the source and destination overlap then single-field transfers will be used. Fills fields that are bits wide in the dst address (plus dstOffset bits) for times number of fields. Increasing addresses will be used. The fill value will be right-justified in value. Monitors & Processes Takes a procedure and pointer to the arguments and forks a new process to execute the procedure. nArgs and nRets are required because the shape of the runtime environment for the procedure depends on them. Takes a process, waits for it to finish, and returns a pointer to the return record. Waits for a condition variable to be notified (the condition variable is protected by the given monitor lock). Notifies the "best" process waiting for the given condition variable (the condition variable is protected by the given monitor lock). If lock # NIL, Notify places the process on the monitor lock's queue, otherwise just allows that process to run. Notifies all processes waiting on the given condition variable (the condition variable is protected by the given monitor lock). If lock # NIL, Broadcast places those processes on the monitor lock's queue, otherwise just allows those processes to run. Attempts to enter the monitor protected by the given monitor lock. The executing process will wait until it has possession of the lock. Releases the monitor lock, allowing the "best" process waiting for the monitor lock to proceed. Frame Extensions Although frames are normally in registers, there are various cases where frame extensions must be placed in actual storage. The compiler uses these routines to allocate and free the parts of local frames that must be in memory. Allocates a frame extension large enough to hold nWords worth of data. Frees a frame extension obtained by ExtensionAlloc. Ignores ptr = NIL. Always returns NIL for convenience of assigning back to the link. Global Frame Modules can be started, stopped, restarted, and copied through the current language. Although there is some question as to how much of this support should be continued, here are the hooks to support the current semantics. Used to implement NEW prog. Starts a module (with given arguments). Used to implement START prog. Starts a module (with given arguments). Used to implement RESTART prog. Used to implement STOP of the current module. Signaller The signaller finds the appropriate handler by looking in tables passed from the compiler to the runtime system via the loader. These tables provide a PC to handler map, where the handler is given as a PC. For signals and errors, argument and return records are always passed by reference, rather than sometimes by value (as in current PrincOps). We think that the added uniformity is worth the slight additional runtime cost. This is the type of the handler procedure. The regsPtr passed in gives the saved registers for the frame containing the handler. The signal denotes which exception is being raised, and the args give the argument record for the signal. The return values generated by RESUME are assigned to rtns^. pc and levels are significant only if action=exit, corresponding to the source constructs GO TO, RETRY, and CONTINUE from within catch phrases. pc denotes the program counter to be used by the frame containing the target of the GOTO out of the catch phrase, and levels deenotes the number of levels of nested catch phrases to be unwound. In the simplest possible situation p[args ! err => CONTINUE] levels should be 1. Raises the named signal with the given argument record. Used for result _ SIGNAL which[args]. rtns^ is assigned the return record supplied by RESUME. Raises the named error with the given argument record. Used for ERROR which[args]. Used for foo: ERROR = CODE or foo: SIGNAL = CODE. Should never be called. Corresponds to ABORTED. Corresponds to UNWIND. Corresponds to unnamed ERROR. Corresponds to unnamed SIGNAL. Corresponds to RuntimeError.UNCAUGHT, which may be built-in some day. SafeStorage Safe Storage support for Cedar extensions to Mesa performs reference-counting to determine when to automtically reclaim storage. Atomically assigns a reference to a reference-containing cell. Atomically assigns NIL to a reference-containing cell. Performs dst^ _ src^, treating the copied variable as being of the specified type. Reference-counted fields are treated properly. This operation is definitely not atomic. AssignRefCompositeFault will be raised if an an improper assignment is attempted (i.e. assignment to a variant record). Here for completeness. Not actually used by the compiler. Increments the RC of a given reference. Useful when initializing a newly allocated object. Decrements the RC of a given reference. Useful?? Gets the referent type of an object from a reference to that object. Returns nullType for ref = NIL. Useful for WITH ref SELECT FROM ... Checks to determine that the type of the object is equal to the given type, then returns the original reference. When ref = NIL, NIL is returned and no checking is performed. Raises NarrowFault if the types are different. Useful for NARROW. This error is raised by Narrow when the type of the reference is not equal to the expected type. Assigns the procedure to the given cell, checking for scope violations (only NIL or outer-level procedures can be assigned). Performs reference-counting if src or dstPtr^ is a valid REF. Raises NestedProcError if assigning a nested procedure. Checks the procedure for being assignable. Raises NestedProcError if the proc is nested. Raised if the procedure described by proc is a nested procedure. Allocates a new object of the given type from the default zone, using at least nWords of storage, and initializing the type appropriately. Carl Hauser, May 8, 1987 4:51:47 pm PDT Changed process primitives to operate on SecureProcesses. Fork and Join should now match their implementations at least in number and primitive type of parameters and results. Changed Notify and Broadcast to not take lock parameters. Κ ˜codešœ™Kšœ Οmœ7™BK™3K™'—K˜Iblock™σLšΟbˆΠbs ž™₯IheadšœΟkœ  œ ˜/™™#KšΟnœ œ˜——™™Kš œ  œ œ œ œ œ˜%Kš œ  œ œ œ œ ˜(Kšœ  œ œ  œ!˜EKš  œ œ œ œ œ˜!š œ œ œ œ œ œ˜2Kšœ  œ˜——™Kš œ œ œ œ œ œ˜#šœ œ œ  œ˜ Kšœ1™1Kšœ ˜ Kšœ˜Kšœ˜——™Kšœ\™\K™Kš œ  œ œ œ œ ˜-Jšœ  œ œ  œ˜'š œ  œ œ œ œ œ˜)Kšœ  œ ™——™Kšœj  œ  œ+™«K™š œ  œ œ œ œ ˜(Kšœ  œΟcΠck ˜"K˜—š œ  œ œ œ œ ˜(Kšœ  œ’£ ˜ K˜—Kšœ œ’£&˜B——™ šœ œ™š ‘œ œ œ œ œ œ˜/Kšœ ™ šœ™Kšœ=™=—™K™$K™@K™——š ‘œ œ œ œ œ˜'Kšœ ™ šœ™Kšœ=™=K™——š ‘œ œ œ œ œ˜'Kšœ ™ šœ™Kšœ™Kšœ=™=—K™—š ‘œ œ œ œ œ˜&Kšœ  œ  œ œ™(šœ™Kšœ™šœ=™=Kšœ œ œ™K™——™Kšœ:™:Kšœ!œ œ™-———šœ œ™š ‘œ œ œ œ œ˜*Kšœ ™ ™K™K™——š ‘œ œ œ œ œ˜*Kšœ ™ šœ™Kšœ™—™K™K™——š ‘œ œ œ œ œ˜*Kšœ™šœ™Kšœ™—™K™—K™™Kšœ<™Kšœ’Dœ ’™P———™™KšœA™AK™š ‘ œ œ œ œ  œ˜2KšœNœ’™αK™—š ‘œ œ œ œ  œ˜:KšœNœ…™Τ——™KšœΩ™ΩK™š‘ œ œ œ  œ˜3KšœTœ=™’K˜—š ‘œ œ œ  œ œ  œ˜EKšœyœ9™³——™Kšœ6™6K™š‘ œ œ œ œ  œ œ œ˜>Kšœ0™0———™KšœU™UK™š ‘ œ œ œ  œ œ˜SKšœ’™’K™—š‘ œ œ œ  œ&˜PKšœr™rK™—š‘ œ œ œ  œ œ  œ! œ˜kKš œΟzœ€œ€ œ€œ€ œ €œ‡™„K™—š ‘ œ œ œ  œ! œ˜]Kš œ€œ €œ€ œ €œb€œ™Ί——™š ‘œ œ œ  œ  œ œ˜XKšœΝ™ΝK˜—š‘œ œ" œ˜1KšœT™TK˜—š‘œ œ ˜*Kšœn™nK˜—š‘œ œ˜Kšœ‘ œc™χK˜—š‘ œ œ˜ Kšœ‹ œm™ϋK˜—š‘ œ œ˜#Kšœˆ™ˆK˜—š‘ œ œ˜"Kšœ_™_——™Kšœδ™δK™š ‘œ œ  œ œ œ˜1KšœF™FK˜—š ‘ œ œ œ œ œ œ˜3KšœC œ œ/™Š——™ Kšœή™ήK™š‘ œ œ˜Kšœ œ™K™—š‘ œ œ  œ œ˜+Kšœ; œ™FK˜—š‘ œ œ  œ œ˜-Kšœ; œ™HK˜—š‘ œ œ˜Kšœ œ™-——™ KšœΞ™ΞK™K™έK™Kšœ œ˜-Kšœ œ œ˜K˜šž œ œ œ3 œ  œ œ, œ˜•Kšœ0€œP€œ2€œ+™ξKšœ œ€œ™>š€œ€œ€œ. œ œ œ œ€œt€œi™υKšœ™—Kšœ™K™—š‘ œ œ œ œ˜;KšœK œ? œ™—K™—š‘ œ œ œ˜/KšœA œ ™SK™—š‘ œ œ˜Kš œ œ œ  œ œ™JK™—š‘ œ œ˜Kšœ œ™K˜—š‘ œ œ˜Kšœ œ™K˜—š‘ œ œ˜Kšœ œ™K˜—š‘ œ œ˜Kšœ œ™K˜—š‘ œ œ˜Kšœ œ!™E——šœ ™ šœ€™€K™—š‘ œ œ œ˜+Kšœ>™>K˜—š‘ œ œ˜!Kšœ œ ™6K˜—š‘œ œ œ œ˜:Kšœ₯™₯K˜—š‘œ œ˜K™:K˜—š‘œ œ œ˜Kšœ œJ™[K˜—š‘œ œ œ˜Kšœ œ ™1—K˜š‘œ œ œ œ˜0Kš œa œ œ œ œ™Š—K˜š ‘œ œ œ œ œ˜2Kšœ} œ œg œ™σK™—š‘ œ œ œ˜*Kšœ`™`K™—š‘ œ œ!˜1KšœM œg œ:™τK™—š‘ œ œ˜ KšœY™YK™—š‘œ œ˜'Kšœ@™@K™—š ‘ œ œ  œ œ œ˜8KšœŠ™ŠK™—K˜—Jš œ˜™'Kšœ)Οr œ₯œ₯œi™°Kšœ₯œ₯ œ™9—K™—…—I[