(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: M3Linker.i3 *) (* Last Modified On Wed Sep 2 10:27:40 PDT 1992 By rustan *) (* Modified On Fri Feb 28 07:44:33 PST 1992 By kalsow *) INTERFACE M3Linker; IMPORT Rd, Wr; (*------------------------------------------------------------------------*) PROCEDURE ReadUnits (input : Rd.T; filename : TEXT; imported : BOOLEAN; errors : Wr.T): UnitList; (* read and parse the link-info in 'input' and return the resulting UnitList. Each unit will be marked as coming from 'filename'. If there are errors, messages will be written to 'errors' and NIL is returned. If 'errors' is NIL, the error messages are silently dropped. *) PROCEDURE MergeUnit (unit : Unit; base : LinkSet; errors : Wr.T): LinkSet; (* check that the version stamps in 'unit' and the version stamps of the units in 'base' are consistent. If they are, 'base' is updated to include 'unit' and it is returned, otherwise 'base' is left unmodified and NIL is returned. If there are inconsistencies, error messages are written on 'errors'. If 'errors' is NIL, the error messages are silently dropped. It is an unchecked runtime error to modify any of the units or their referents once they've been merged with 'base'. *) PROCEDURE CheckSet (base: LinkSet; m: CheckMode; errors:Wr.T):BOOLEAN; (* check whether 'base' defines a complete set (ie. all version stamps are defined and consistent, all imported interfaces are defined, 'Main' is exported, all types are defined, ...). The particular checks depend on the mode selected. If the units of 'base' form a complete set, 'base' is updated and TRUE is returned, otherwise 'base' is left unmodified and FALSE is returned. If there are inconsistencies, error messages are written on 'errors'. If 'errors' is NIL, the error messages are silently dropped. It is an unchecked runtime error to modify any of the units of 'base'. *) EXCEPTION LinkError (TEXT); PROCEDURE GenerateMain (base: LinkSet; magic: TEXT; output: Wr.T; verbose: BOOLEAN) RAISES {LinkError}; (* write the C main program for the units in 'base' on 'output'. It is a checked runtime error if 'base' has not been run through CheckSet. If non-NIL, 'magic' is encoded in the generated program. KRML: The procedure raises LinkError if a link error occurred. The string associated with the exception is an error message (without a newline) to be displayed. *) PROCEDURE WriteUnits (base: LinkSet; magic: TEXT; output: Wr.T); (* write the linker info for the units in 'base' on 'output'. This is the inverse of 'ReadUnits' *) PROCEDURE Contents (base: LinkSet): UnitList; (* returns the list of units contained in 'base'. It is an unchecked runtime error to modify this list or any of its referents. *) (*------------------------------------------------------------------------*) (* The data structures processed by the linker are defined below: *) CONST LinkerMagic = "M3 v2.1 Mosaic"; CONST BuiltinUnitName = "M3_BUILTIN"; TYPE LinkSet <: REFANY; TYPE Mode = { Units, Program, BaseProgram, Overlay, Library }; CheckMode = [ Mode.Program .. Mode.Library ]; TYPE NameList = REF RECORD name: Name; next: NameList END; UnitList = REF RECORD unit: Unit; next: UnitList END; (* new KRML *) OverrideList = REF RECORD supertype: Name; offset : CARDINAL; Cname : Name; next : OverrideList := NIL END; SigCodeList = REF RECORD offset : CARDINAL; encoding : TEXT; next : SigCodeList := NIL END; (* end KRML *) TYPE Name = RECORD text: TEXT := NIL; hash: INTEGER; END; TYPE File = REF RECORD name : TEXT := NIL; magic : TEXT := NIL; imported : BOOLEAN := FALSE; END; TYPE Unit = REF RECORD name : Name; file : File; interface : BOOLEAN := FALSE; imported_generics: NameList := NIL; imported_units : NameList := NIL; exported_units : NameList := NIL; imported_symbols : VersionStamp := NIL; exported_symbols : VersionStamp := NIL; undefined_types : UndefinedType := NIL; defined_types : Type := NIL; revelations : Revelation := NIL; END; TYPE VersionStamp = REF RECORD symbol : Name; stamp : StampData; next : VersionStamp; export : BOOLEAN; END; StampData = ARRAY [0..1] OF INTEGER; TYPE Revelation = REF RECORD unit : Name; lhs : Name; rhs : Name; next : Revelation; partial : BOOLEAN; export : BOOLEAN; END; TYPE TypeClass = { None, Array, Enum, Object, Opaque, OpenArray, Packed, Procedure, Record, Ref, Set, Subrange }; TYPE UndefinedType = REF RECORD uid : Name; class : TypeClass; name : TEXT := NIL; next : UndefinedType := NIL; END; TYPE Type = REF RECORD uid : Name; class : TypeClass; name : TEXT := NIL; next : Type := NIL; unit : Unit := NIL; depends : NameList := NIL; preDecl : TEXT := NIL; decl : TEXT := NIL; methodDecl : TEXT := NIL; super : Name; (* new KRML *) isTraced : [0..2] := 2; (* 0/1 means FALSE/TRUE; 2 means undefined *) dataSize : INTEGER := 0; dataAlignment : INTEGER := 0; brand : Name; nMethods : CARDINAL := 0; overrides : OverrideList := NIL; sigEncodings : SigCodeList := NIL; inapprNetType : TEXT := NIL; (* non-NIL means inappropriate to be a network object type; the field then is the name of the module which deems it inappropriate *) nDimensions : CARDINAL := 0; elementSize : CARDINAL := 0; initProc : Name; mapProc : Name; tracedOffs : Name; (* end KRML *) END; (*------------------------------------------------------------------------*) (* A 'link-info' file is a sequence of possibly blank filled lines with the following contents: Zn --- the current file's magic is 'n' In --- start unit: interface 'n' Mn --- start unit: module 'n' Am --- current unit exports interface m Bm --- current unit imports interface m gm --- current unit imports generic unit m in x --- import symbol 'n' with version stamp 'x' en x --- export symbol 'n' with version stamp 'x' Km n x --- import symbol 'n' with verison stamp 'x', node # = m Vm n x --- export symbol 'n' with verison stamp 'x', node # = m Gm --- import copy of symbol with node # = m Wm --- export copy of symbol with node # = m Rx y --- export REVEAL 'x' = 'y' from current unit rm x y --- import REVEAL 'x' = 'y' from interface 'm' Xx y --- export REVEAL 'x' <: 'y' from current unit xm x y --- import REVEAL 'x' <: 'y' from interface 'm' Hm x c --- set current type = 'x', node # = m, class = c Qm --- set current type to a copy of type w/node # m Jm x c --- set current type = 'x', leave it undefined, node# = m, class=c Um --- set current type to a copy of undefined type w/node # m tx c --- set current type = 'x', class = c ux c --- set current type = 'x', leave the type 'undefined', class = c Nn --- user-sensible name for current type is 'n' dx --- current type depends on type 'x' C --- C post-declaration for current type follows D --- C pre-declaration for current type follows O --- C declaration for current type's methods follows Sx --- super type of current type is 'x' * --- end of multi-line entry KRML: kb s a m d e --- 'b' indicates whether or not current type is traced 's' is the dataSize 'a' is the alignment 'm' is the number of new methods (0 for REF types) 'd' is the number of open dimensions (0 for OBJECT types) 'e' is the element size of each open array element (0 for OBJECT types) lb --- 'b' is the brand of the current type os f y --- specifies the differences in the current type's method suite as compared to that of the parent type's of of the current type In particular, the type's method suite will look exactly like that of its parent's, where new methods are NIL, *except* for those methods for which an "os f y" triple is included. The information specified by this triple takes precedence over the said default rule. The triple is interpreted as: 's' is the uid of some supertype of the current type (in particular, 's' may be the current type) the method referred to is the one with offset 'f' into 's's new methods 'y' is the C name of the actual procedure np --- 'p' is the init proc of the current type mp --- 'p' is the map proc of the current type bs --- 's' is a string containing the sequence of traced offsets of the current type so e --- 'e' is the signature encoding of the current type's 'o'th new method ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz USED: **** ***** *** *** **** * * ** * * *** **** * *) END M3Linker.