1 (* ==================================================================== *)
2 (* *)
3 (* SymFileRW: Symbol-file reading and writing for GPCP. *)
4 (* Copyright (c) John Gough 1999, 2000. *)
5 (* *)
6 (* ==================================================================== *)
10 IMPORT
11 GPCPcopyright,
12 RTS,
13 Error,
14 Console,
19 LitValue,
20 Visitor,
21 ExprDesc,
27 FileNames;
29 (* ========================================================================= *
30 // Collected syntax ---
31 //
32 // SymFile = Header [String (falSy | truSy | <other attribute>)]
33 // [ VersionName ]
34 // {Import | Constant | Variable | Type | Procedure}
35 // TypeList Key.
36 // -- optional String is external name.
37 // -- falSy ==> Java class
38 // -- truSy ==> Java interface
39 // -- others ...
40 // Header = magic modSy Name.
41 // VersionName= numSy longint numSy longint numSy longint.
42 // -- mj# mn# bld rv# 8xbyte extract
43 // Import = impSy Name [String] Key.
44 // -- optional string is explicit external name of class
45 // Constant = conSy Name Literal.
46 // Variable = varSy Name TypeOrd.
47 // Type = typSy Name TypeOrd.
48 // Procedure = prcSy Name [String] FormalType.
49 // -- optional string is explicit external name of procedure
50 // Method = mthSy Name byte byte TypeOrd [String] [Name] FormalType.
51 // -- optional string is explicit external name of method
52 // FormalType = [retSy TypeOrd] frmSy {parSy byte TypeOrd [String]} endFm.
53 // -- optional phrase is return type for proper procedures
54 // TypeOrd = ordinal.
55 // TypeHeader = tDefS Ord [fromS Ord Name].
56 // -- optional phrase occurs if:
57 // -- type not from this module, i.e. indirect export
58 // TypeList = start { Array | Record | Pointer | ProcType |
59 // Enum | Vector | NamedType } close.
60 // Array = TypeHeader arrSy TypeOrd (Byte | Number | <empty>) endAr.
61 // -- nullable phrase is array length for fixed length arrays
62 // Vector = TypeHeader vecSy TypeOrd endAr.
63 // Pointer = TypeHeader ptrSy TypeOrd.
64 // Event = TypeHeader evtSy FormalType.
65 // ProcType = TypeHeader pTpSy FormalType.
66 // Record = TypeHeader recSy recAtt [truSy | falSy]
67 // [basSy TypeOrd] [iFcSy {basSy TypeOrd}]
68 // {Name TypeOrd} {Method} {Statics} endRc.
69 // -- truSy ==> is an extension of external interface
70 // -- falSy ==> is an extension of external class
71 // -- basSy option defines base type, if not ANY / j.l.Object
72 // Statics = ( Constant | Variable | Procedure ).
73 // Enum = TypeHeader eTpSy { Constant } endRc.
74 // NamedType = TypeHeader.
75 // Name = namSy byte UTFstring.
76 // Literal = Number | String | Set | Char | Real | falSy | truSy.
77 // Byte = bytSy byte.
78 // String = strSy UTFstring.
79 // Number = numSy longint.
80 // Real = fltSy ieee-double.
81 // Set = setSy integer.
82 // Key = keySy integer..
83 // Char = chrSy unicode character.
84 //
85 // Notes on the syntax:
86 // All record types must have a Name field, even though this is often
87 // redundant. The issue is that every record type (including those that
88 // are anonymous in CP) corresponds to a IR class, and the definer
89 // and the user of the class _must_ agree on the IR name of the class.
90 // The same reasoning applies to procedure types, which must have equal
91 // interface names in all modules.
92 // ======================================================================== *)
94 CONST
108 CONST
113 (* ============================================================ *)
115 TYPE
125 TYPE
141 (* ============================================================ *)
146 (* ============================================================ *)
151 (* ============================================================ *)
152 (* ======== Import Stack Implementation ======= *)
153 (* ============================================================ *)
159 BEGIN
164 BEGIN
171 BEGIN
175 (* ============================================================ *)
178 BEGIN
182 (* ============================================================ *)
183 (* ======== Various writing utility procedures ======= *)
184 (* ============================================================ *)
188 BEGIN
190 (*
191 * Initialization: cSum starts at zero. Since impOrd of
192 * the module is zero, impOrd of the imports starts at 1.
193 *)
202 (* ======================================= *)
207 (* need to turn off overflow checking here *)
214 (* ======================================= *)
221 BEGIN
243 (* ======================================= *)
250 BEGIN
273 (* ======================================= *)
276 BEGIN
281 (* ======================================= *)
284 BEGIN
290 (* ======================================= *)
295 BEGIN
304 (* ======================================= *)
309 BEGIN
320 (* ======================================= *)
323 BEGIN
328 (* ======================================= *)
331 BEGIN
336 (* ======================================= *)
340 BEGIN
346 (* ======================================= *)
349 BEGIN
355 ELSE
360 (* ======================================= *)
363 (*
364 * This proceedure facilitates the naming rules
365 * for records and (runtime) classes: -
366 *
367 * (1) Classes derived from named record types have
368 * names synthesized from the record typename.
369 * (2) If a named pointer is bound to an anon record
370 * the class takes its name from the pointer name.
371 * (3) If both the pointer and the record types have
372 * names, the class is named from the record.
373 *)
375 (* ------------------------------------ *)
377 BEGIN
385 (* ------------------------------------ *)
386 BEGIN
389 (*
390 * We wish to ensure that anonymous records are
391 * never emitted before their binding pointer
392 * types. This ensures that we do not need to
393 * merge types when reading the files.
394 *)
401 (*
402 * If a pointer to record is being emitted, and
403 * the pointer is NOT anonymous, then the class
404 * is known by the name of the record. Thus the
405 * record name must be emitted, at least opaquely.
406 * Furthermore, we must indicate the binding
407 * relationship between the pointer and record.
408 * (It is possible that DCode need record size.)
409 *)
427 (* ============================================================ *)
428 (* ======== Various writing procedures ======= *)
429 (* ============================================================ *)
432 (*
433 ** FormalType = [retSy TypeOrd] frmSy {parSy Byte TypeOrd [String]} endFm.
434 *)
437 BEGIN
441 (*
442 * The structure of this type must be
443 * emitted, unless it is an imported type.
444 *)
453 (*
454 * Emit Optional Parameter name
455 *)
459 (*
460 * The structure of this type must be
461 * emitted, unless it is an imported type.
462 *)
468 (* ======================================= *)
474 (*
475 ** Constant = conSy Name Literal.
476 ** Literal = Number | String | Set | Char | Real | falSy | truSy.
477 *)
478 BEGIN
497 (* ======================================= *)
500 (*
501 ** Type = TypeSy Name TypeOrd.
502 *)
503 BEGIN
507 (*
508 * The structure of this type must be
509 * emitted, even if it is an imported type.
510 *)
514 (* ======================================= *)
517 (*
518 ** Variable = varSy Name TypeOrd.
519 *)
520 BEGIN
524 (*
525 * The structure of this type must be
526 * emitted, unless it is an imported type.
527 *)
531 (* ======================================= *)
534 (*
535 ** Import = impSy Name.
536 *)
537 BEGIN
548 (* ======================================= *)
551 (*
552 ** Procedure = prcSy Name FormalType.
553 *)
554 BEGIN
562 (* ======================================= *)
565 (*
566 ** Method = mthSy Name Byte Byte TypeOrd [strSy ] FormalType.
567 *)
568 BEGIN
580 (* ======================================= *)
584 BEGIN
589 ELSE
595 (* ======================================= *)
598 (*
599 ** TypeHeader = typSy Ord [fromS Ord Name].
600 *)
603 (* =================================== *)
605 BEGIN
613 (* =================================== *)
614 BEGIN
621 ELSE
624 ELSE
630 (*
631 * Convert native types back to RTS.nativeXXX, if necessary.
632 * That is ... if the native module is not explicitly imported.
633 *)
642 (* ======================================= *)
645 BEGIN
661 (* ======================================= *)
667 (*
668 ** Record = TypeHeader recSy recAtt [truSy | falSy | <others>]
669 ** [basSy TypeOrd] [iFcSy {basSy TypeOrd}]
670 ** {Name TypeOrd} {Method} {Statics} endRc.
671 *)
672 BEGIN
680 (* ########## *)
686 (* ########## *)
691 (* ########## *)
699 (* ########## *)
714 (*
715 * IF G.special THEN (* we might need to emit static stuff *)
716 *
719 *)
732 (*
733 * END;
734 *)
740 (* ======================================= *)
745 (*
746 ** Enum = TypeHeader eTpSy { constant } endRc.
747 *)
748 BEGIN
756 (* D.AppendType(f.modS.expRecs, t); *)
759 (* ======================================= *)
762 BEGIN
766 (* ======================================= *)
769 BEGIN
778 (* ======================================= *)
781 BEGIN
788 (* ======================================= *)
793 BEGIN
794 (*
795 * We cannot use a FOR loop here, as the tide changes
796 * during evaluation, as a result of reaching new types.
797 *)
813 (* ======================================= *)
820 (*
821 * fileName : FileNames.NameString;
822 *)
824 (* ----------------------------------- *)
827 BEGIN
831 ELSE
836 (* ----------------------------------- *)
837 (*
838 ** SymFile = Header [String (falSy | truSy | <others>)]
839 ** [ VersionName]
840 ** {Import | Constant | Variable
841 ** | Type | Procedure | Method} TypeList.
842 ** Header = magic modSy Name.
843 ** VersionName= numSy longint numSy longint numSy longint.
844 ** -- mj# mn# bld rv# 8xbyte extract
845 *)
846 BEGIN
847 (*
848 * Create the SymFile structure, and open the output file.
849 *)
851 (* Start of alternative gpcp1.2 code *)
855 ELSE
864 ELSE
865 (*
866 * Emit the symbol file header
867 *)
869 (* End of alternative gpcp1.2 code *)
872 ELSE
882 (*
883 * Emit the optional TypeName, if required.
884 *
885 * VersionName= numSy longint numSy longint numSy longint.
886 * -- mj# mn# bld rv# 8xbyte extract
887 *)
893 (*
894 * Create the symbol table visitor, an extension of
895 * Symbols.SymForAll type. Emit symbols from the scope.
896 *)
900 (*
901 * Now emit the types on the worklist.
902 *)
906 (*
907 * Now emit the accumulated checksum key symbol.
908 *)
916 (* ============================================================ *)
917 (* ======== Various reading utility procedures ======= *)
918 (* ============================================================ *)
921 BEGIN
925 (* ======================================= *)
928 CONST
934 BEGIN
946 ELSE
957 ELSE
960 ELSE
963 ELSE
970 (* ======================================= *)
973 BEGIN
977 (* ======================================= *)
981 (* overflow checking off here *)
985 (* ======================================= *)
991 (* overflow checking off here *)
999 (* ======================================= *)
1003 BEGIN
1008 (* ======================================= *)
1012 BEGIN
1015 ELSE
1021 (* ============================================================ *)
1022 (* ======== Symbol File Reader ======= *)
1023 (* ============================================================ *)
1027 BEGIN
1036 (* ======================================= *)
1039 (* ======================================= *)
1042 BEGIN
1047 (* ======================================= *)
1051 BEGIN
1055 | namSy :
1057 | strSy :
1061 | bytSy :
1065 | numSy :
1067 | fltSy :
1069 | chrSy :
1075 (* ======================================= *)
1078 BEGIN
1083 (* ======================================= *)
1090 BEGIN
1097 (* #### *)
1107 (* #### *)
1110 ELSE
1114 (* normal case, nothing to do *)
1117 ELSE
1130 (* ============================================ *)
1137 BEGIN
1143 BEGIN
1146 ELSE
1153 (* ============================================ *)
1160 BEGIN
1165 BEGIN
1172 (* ============================================ *)
1175 (* insert, taking into account possible overloaded methods. *)
1176 VAR
1182 BEGIN
1184 (*
1185 * D.getName.Of(s, sS);
1186 * S.SemError.RepSt2(172, iS, sS, S.line, S.col);
1187 *)
1191 BEGIN
1194 (*
1195 IF ~ok THEN Report(id,rec.idnt); END;
1196 *)
1200 (* ============================================ *)
1204 BEGIN
1218 (* ============================================ *)
1223 BEGIN
1228 ELSE
1230 REPEAT
1239 (* ============================================ *)
1243 BEGIN
1249 (* ============================================ *)
1253 (*
1254 ** FormalType = [retSy TypeOrd] frmSy {parSy Byte TypeOrd [String]} endFm.
1255 // -- optional phrase is return type for proper procedures
1256 *)
1259 BEGIN
1271 (* Skip over optional parameter name string *)
1282 (* ============================================ *)
1285 (* Assert: the current symbol ptrSy *)
1286 (* Pointer = TypeHeader ptrSy TypeOrd. *)
1291 BEGIN
1296 (*
1297 * Check if there is space in the tArray for this
1298 * element, otherwise expand using typeOf().
1299 *)
1304 ELSE
1313 (* ============================================ *)
1316 (* Assert: the current symbol is pTpSy. *)
1317 (* ProcType = TypeHeader pTpSy FormalType. *)
1318 BEGIN
1323 (* ============================================ *)
1326 (* Assert: the current symbol is evtSy. *)
1327 (* EventType = TypeHeader evtSy FormalType. *)
1328 BEGIN
1333 (* ============================================ *)
1336 (* Assert: at entry the current symbol is arrSy. *)
1337 (* Array = TypeHeader arrSy TypeOrd (Byte | Number | ) endAr. *)
1338 (* -- nullable phrase is array length for fixed length arrays *)
1341 BEGIN
1351 (* ELSE length := 0 *)
1357 (* ============================================ *)
1360 (* Assert: at entry the current symbol is vecSy. *)
1361 (* Vector = TypeHeader vecSy TypeOrd endAr. *)
1364 BEGIN
1372 (* ============================================ *)
1377 (* ============================================ *)
1380 (* Assert: at entry the current symbol is recSy. *)
1381 (* Record = TypeHeader recSy recAtt [truSy | falSy | <others>] *)
1382 (* [basSy TypeOrd] [iFcSy {basSy TypeOrd}] *)
1383 (* {Name TypeOrd} {Method} {Statics} endRc. *)
1384 CONST
1396 BEGIN
1400 (*
1401 * The recAtt field has two other bits piggy-backed onto it.
1402 * The noNew Field of xAttr is just added on in the writing
1403 * and is stripped off here. The valRc field is used to lock
1404 * in foreign value classes, even though they have basTp # NIL.
1405 *)
1406 (*
1407 * IF mskd # Ty.noAtt THEN INCL(rslt.xAttr, D.clsTp) END;
1408 * IF attr >= noNw THEN DEC(attr, noNw); INCL(rslt.xAttr, D.noNew) END;
1409 *)
1477 ELSE
1481 (* #### *)
1487 (* #### *)
1492 (* ============================================ *)
1495 (* Assert: at entry the current symbol is eTpSy. *)
1496 (* Enum = TypeHeader eTpSy { Constant} endRc. *)
1499 BEGIN
1512 (* ============================================ *)
1515 (* Type = typSy Name TypeOrd. *)
1519 BEGIN
1520 (*
1521 * Post: every previously unknown typId id
1522 * has the property: id.type.idnt = id.
1523 * If oldI # newT, then the new typId has
1524 * newT.type.idnt = oldI.
1525 *)
1540 (* ============================================ *)
1543 (* Import = impSy Name [String] Key. *)
1544 (* -- optional string is external name *)
1545 (* first symbol should be namSy here. *)
1549 BEGIN
1558 (* Shouldn't this be an error? *)
1561 (* probably don't need to do anything here ... *)
1578 (* should not be necessary anymore *)
1581 (*
1582 * This recursively reads the symbol files for
1583 * any imports of this file which are on the
1584 * list to be imported later anyhow.
1585 *)
1588 ELSE
1596 (* ============================================ *)
1599 (* Constant = conSy Name Literal. *)
1600 (* Assert: f.sSym = namSy. *)
1603 BEGIN
1614 (* ============================================ *)
1617 (* Variable = varSy Name TypeOrd. *)
1620 BEGIN
1629 (* ============================================ *)
1632 (* Procedure = prcSy Name[String]FormalType. *)
1633 (* This is a static proc, mths come with Recs *)
1636 BEGIN
1645 (* and leave scopeNm = NIL *)
1653 (* IF this is a java module, do some semantic checks *)
1654 (* ... *)
1658 (* ============================================ *)
1661 (* Method = mthSy Name byte byte TypeOrd [String][Name] FormalType. *)
1666 BEGIN
1674 (* byte1 is the method attributes *)
1676 (* byte2 is param form of receiver *)
1678 (* next 1 or 2 bytes are rcv-type *)
1684 (* and leave scopeNm = NIL *)
1687 (* Skip over optional receiver name string *)
1691 (* End skip over optional receiver name *)
1695 (* IF this is a java module, do some semantic checks *)
1699 (* ============================================ *)
1702 (* TypeList = start { Array | Record | Pointer *)
1703 (* | ProcType | Vector} close. *)
1704 (* TypeHeader = tDefS Ord [fromS Ord Name]. *)
1717 BEGIN
1721 (* Do type header *)
1727 (*
1728 * The [fromS modOrd typNam] appears if the type is imported.
1729 * There are two cases:
1730 * this is the first time that "mod.typNam" has been
1731 * seen during this compilation
1732 * ==> insert a new typId descriptor in mod.symTb
1733 * this name is already in the mod.symTb table
1734 * ==> fetch the previous descriptor
1735 *)
1748 (* Get type info. *)
1764 ELSE
1768 (*
1769 * A name has been declared for this type, tpIdnt is
1770 * the (possibly previously known) id descriptor, and
1771 * tpDesc is the newly parsed descriptor of the type.
1772 *)
1774 (*
1775 * Case #1: no previous type.
1776 * This is the first time the compiler has seen this type
1777 *)
1781 (*
1782 * Case #2: previous type exists, new type is opaque.
1783 * Throw away the newly parsed opaque type desc, and
1784 * use the previously known type *even* if it is opaque!
1785 *)
1788 (*
1789 * Case #3: previous type is opaque, new type is non-opaque.
1790 * This type had been seen opaquely, but now has a
1791 * non-opaque definition
1792 *)
1796 ELSE
1797 (*
1798 * Case #4: previous type is non-opaque, new type is non-opaque.
1799 * This type already has a non-opaque descriptor.
1800 * We shall keep the original copy.
1801 *)
1804 (*
1805 * Normally, imported types cannot be anonymous.
1806 * However, there is one special case here. Anon
1807 * records can be record base types, but are always
1808 * preceeded by the binding pointer type. A typical
1809 * format of output from SymDec might be ---
1810 *
1811 * T18 = SomeMod.BasePtr
1812 * POINTER TO T19;
1813 * T19 = EXTENSIBLE RECORD (T11) ... END;
1814 *
1815 * in this case T19 is an anon record from SomeMod,
1816 * not the current module.
1817 *
1818 * Thus we pre-override the future record declaration
1819 * by the bound type of the pointer. This ensures
1820 * uniqueness of the record descriptor, even if it is
1821 * imported indirectly multiple times.
1822 *)
1828 ELSE
1829 (*
1830 * tpIdnt is NIL ==> type is from this import,
1831 * except for the special case above. In the usual
1832 * case we replace the tmpTp by tpDesc. In the special
1833 * case the tmpTp has been already been overridden by
1834 * the previously imported bound type.
1835 *)
1847 (*
1848 * First we fix up all symbolic references in the
1849 * the type array. Postcondition is : no element
1850 * of the type array directly or indirectly refers
1851 * to a temporary type.
1852 *)
1856 (*
1857 * We now fix up all references in the symbol table
1858 * that still refer to temporary symbol-file types.
1859 *)
1864 (*
1865 * Now check that all overloaded ids are necessary
1866 *)
1873 (* ============================================ *)
1876 (*
1877 // SymFile = Header [String (falSy | truSy | <others>)]
1878 // {Import | Constant | Variable | Type | Procedure}
1879 // TypeList Key.
1880 // Header = magic modSy Name.
1881 //
1882 // magic has already been recognized.
1883 *)
1885 BEGIN
1932 LOOP
1945 (* Now read the typelist *)
1957 (* ============================================================ *)
1958 (* ======== SymFileSFA visitor method ======= *)
1959 (* ============================================================ *)
1962 BEGIN
1969 (* new *)
1971 (*
1972 * old ... we used to emit the constructor as a static method.
1973 * Now it appears as a static in the bound record decl.
1974 *
1975 * | Id.ctorP,
1976 * Id.conPrc : t.sym.EmitProcedureId(id(Id.PrcId));
1977 *)
1983 (* ============================================================ *)
1984 (* ======== TypeLinker visitor method ======= *)
1985 (* ============================================================ *)
1988 BEGIN
1992 ELSE
1999 (* ============================================================ *)
2000 (* ======== Symbol file parser method ======= *)
2001 (* ============================================================ *)
2006 BEGIN
2012 PopStack;
2015 (* ============================================ *)
2021 BEGIN
2022 (*
2023 * The list of scopes has been constructed by
2024 * the parser, while reading the import list.
2025 * In the case of already known scopes the list
2026 * references the original descriptor.
2027 *)
2028 InitStack;
2040 (* ============================================================ *)
2041 BEGIN
2045 (* ============================================================ *)