2
0

SymbolFile.java 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /**********************************************************************/
  2. /* Symbol File class for j2cps */
  3. /* */
  4. /* (c) copyright QUT, John Gough 2000-2012, John Gough, 2012-2017 */
  5. /**********************************************************************/
  6. package j2cps;
  7. import java.io.*;
  8. import java.util.ArrayList;
  9. import j2cpsfiles.j2cpsfiles;
  10. class SymbolFile {
  11. /************************************************************************/
  12. /* Symbol file reading/writing */
  13. /************************************************************************/
  14. // Collected syntax ---
  15. //
  16. // SymFile = Header [String (falSy | truSy)]
  17. // {Import | Constant | Variable | Type | Procedure}
  18. // TypeList Key.
  19. // Header = magic modSy Name.
  20. // Import = impSy Name [String] Key.
  21. // Constant = conSy Name Literal.
  22. // Variable = varSy Name TypeOrd.
  23. // -------- Note --------
  24. // The Type syntax is used to declare the type ordinals
  25. // that are used for all references to this module's types.
  26. // ----------------------
  27. // Type = typSy Name TypeOrd.
  28. // Procedure = prcSy Name [String] [truSy] FormalType.
  29. // Method = mthSy Name Byte Byte TypeOrd [String] FormalType.
  30. // FormalType = [retSy TypeOrd] frmSy {parSy Byte TypeOrd} endFm.
  31. // TypeOrd = ordinal.
  32. // -------- Note --------
  33. // TypeHeaders are used in the symbol file format to
  34. // denote a type that is defined here or is imported.
  35. // For types defined here, the ordinal is that declard
  36. // in the definition section of this symbol file.
  37. // For imported types the first ordinal is the ordinal
  38. // declared in the definition section, the second ordinal
  39. // is the index into the package import list.
  40. // ----------------------
  41. // TypeHeader = tDefS Ord [fromS Ord Name].
  42. // TypeList = start {Array | Record | Pointer | ProcType |
  43. // NamedType | Enum} close.
  44. // Array = TypeHeader arrSy TypeOrd (Byte | Number | ) endAr.
  45. // Pointer = TypeHeader ptrSy TypeOrd.
  46. // ProcType = TypeHeader pTpSy FormalType.
  47. // EventType = TypeHeader evtSy FormalType.
  48. // Record = TypeHeader recSy recAtt [truSy | falSy] [basSy TypeOrd]
  49. // [iFcSy basSy TypeOrd {basSy TypeOrd}]
  50. // {Name TypeOrd} {Method} {Statics} endRc.
  51. // Statics = ( Constant | Variable | Procedure ).
  52. // Enum = TypeHeader eTpSy { Constant } endRc.
  53. // NamedType = TypeHeader.
  54. // Name = namSy byte UTFstring.
  55. // Literal = Number | String | Set | Char | Real | falSy | truSy.
  56. // Byte = bytSy byte.
  57. // String = strSy UTFstring.
  58. // Number = numSy java.lang.long.
  59. // Real = fltSy java.lang.double.
  60. // Set = setSy java.lang.int.
  61. // Key = keySy java.lang.int.
  62. // Char = chrSy java.lang.char.
  63. //
  64. // Notes on the syntax:
  65. // All record types must have a Name field, even though this is often
  66. // redundant. The issue is that every record type (including those that
  67. // are anonymous in CP) corresponds to a Java class, and the definer
  68. // and the user of the class _must_ agree on the JVM name of the class.
  69. // The same reasoning applies to procedure types, which must have equal
  70. // interface names in all modules.
  71. //
  72. static final String[] mthAtt = {"", ",NEW", ",ABSTRACT", ",NEW,ABSTRACT",
  73. ",EMPTY", ",NEW,EMPTY",
  74. ",EXTENSIBLE", ",NEW,EXTENSIBLE"};
  75. static final String[] recAtt = {"RECORD ", "ABSTRACT RECORD ",
  76. "LIMITED RECORD ", "EXTENSIBLE RECORD "};
  77. static final String[] mark = {"", "*", "-", "!"};
  78. static final String[] varMark = {"", "IN", "OUT", "VAR"};
  79. //private static final String spaces = " ";
  80. //private static final String recEndSpace = " ";
  81. static final int modSy = (int) 'H';
  82. static final int namSy = (int) '$';
  83. static final int bytSy = (int) '\\';
  84. static final int numSy = (int) '#';
  85. static final int chrSy = (int) 'c';
  86. static final int strSy = (int) 's';
  87. static final int fltSy = (int) 'r';
  88. static final int falSy = (int) '0';
  89. static final int truSy = (int) '1';
  90. static final int impSy = (int) 'I';
  91. static final int setSy = (int) 'S';
  92. static final int keySy = (int) 'K';
  93. static final int conSy = (int) 'C';
  94. static final int typSy = (int) 'T';
  95. static final int tDefS = (int) 't';
  96. static final int prcSy = (int) 'P';
  97. static final int retSy = (int) 'R';
  98. static final int mthSy = (int) 'M';
  99. static final int varSy = (int) 'V';
  100. static final int parSy = (int) 'p';
  101. static final int iFcSy = (int) '~';
  102. static final int start = (int) '&';
  103. static final int close = (int) '!';
  104. static final int recSy = (int) '{';
  105. static final int endRc = (int) '}';
  106. static final int frmSy = (int) '(';
  107. static final int fromS = (int) '@';
  108. static final int endFm = (int) ')';
  109. static final int arrSy = (int) '[';
  110. static final int endAr = (int) ']';
  111. static final int pTpSy = (int) '%';
  112. static final int evtSy = (int) 'v';
  113. static final int ptrSy = (int) '^';
  114. static final int basSy = (int) '+';
  115. static final int eTpSy = (int) 'e';
  116. static final int magic = 0xdeadd0d0;
  117. static final int prvMode = 0;
  118. static final int pubMode = 1;
  119. static final int rdoMode = 2;
  120. static final int protect = 3;
  121. private static final int initTypeListSize = 128;
  122. public static TypeDesc[] typeList = new TypeDesc[initTypeListSize];
  123. private static int nextType = TypeDesc.ordT;
  124. private static int tListIx = 0;
  125. private static int sSym = 0;
  126. private static int acc = 0;
  127. private static String name;
  128. private static int iVal;
  129. private static long lVal;
  130. private static int tOrd;
  131. private static char cVal;
  132. private static double dVal;
  133. private static DataInputStream in;
  134. private static int count = 0;
  135. private static PackageDesc target = null;
  136. private static ArrayList<PackageDesc> imps = null;
  137. // Symbol file writing
  138. static void writeName(DataOutputStream out,int access, String name)
  139. throws IOException{
  140. out.writeByte(namSy);
  141. if (ConstantPool.isPublic(access)) {
  142. out.writeByte(pubMode);
  143. }
  144. else if (ConstantPool.isProtected(access)) {
  145. out.writeByte(protect);
  146. }
  147. else /* if (ConstantPool.isPrivate(access)) */ {
  148. out.writeByte(prvMode); // Why are we emitting this if it is private?
  149. }
  150. if (name == null) {
  151. name = "DUMMY" + count++;
  152. System.err.println( name );
  153. }
  154. out.writeUTF(name);
  155. }
  156. static void writeString(DataOutputStream out,String str) throws IOException {
  157. out.writeByte(strSy);
  158. out.writeUTF(str);
  159. }
  160. static void writeLiteral(DataOutputStream out,Object val) throws IOException {
  161. if (val instanceof String) {
  162. writeString(out,(String) val);
  163. } else if (val instanceof Integer) {
  164. out.writeByte(numSy);
  165. out.writeLong(((Integer)val).longValue());
  166. } else if (val instanceof Long) {
  167. out.writeByte(numSy);
  168. out.writeLong(((Long)val));
  169. } else if (val instanceof Float) {
  170. out.writeByte(fltSy);
  171. out.writeDouble(((Float)val).doubleValue());
  172. } else if (val instanceof Double) {
  173. out.writeByte(fltSy);
  174. out.writeDouble(((Double)val));
  175. } else {
  176. System.out.println("Unknown constant type");
  177. System.exit(1);
  178. }
  179. }
  180. public static void writeOrd(DataOutputStream out,int i) throws IOException {
  181. // DIAGNOSTIC
  182. if (i < 0)
  183. throw new IOException();
  184. // DIAGNOSTIC
  185. if (i <= 0x7f) {
  186. out.writeByte(i);
  187. } else if (i <= 0x7fff) {
  188. out.writeByte(128 + i % 128);
  189. out.writeByte(i / 128);
  190. } else {
  191. throw new IOException();
  192. }
  193. }
  194. private static void InsertTypeInTypeList(TypeDesc ty) {
  195. // Make a longer list.
  196. if (ty.outTypeNum > 0) { return; }
  197. ty.outTypeNum = nextType++;
  198. if (tListIx >= typeList.length) {
  199. TypeDesc[] tmp = new TypeDesc[typeList.length + initTypeListSize];
  200. System.arraycopy(typeList, 0, tmp, 0, typeList.length);
  201. typeList = tmp;
  202. }
  203. // Temporary diagnostic code
  204. if (ClassDesc.VERBOSE && (ty.name != null)) {
  205. System.out.printf("Inserting %s at ix %d\n", ty.name, tListIx);
  206. if (ty instanceof ClassDesc
  207. && target != ((ClassDesc)ty).parentPkg
  208. && !imps.contains(((ClassDesc)ty).parentPkg)) {
  209. System.err.println(ty.name + " not on import list");
  210. }
  211. }
  212. typeList[tListIx++] = ty;
  213. }
  214. public static void AddTypeToTypeList(TypeDesc ty) {
  215. InsertTypeInTypeList(ty);
  216. if (!ty.writeDetails) {
  217. return;
  218. }
  219. if (ty instanceof ClassDesc) {
  220. ClassDesc aClass = (ClassDesc)ty;
  221. if (aClass.outBaseTypeNum > 0) {
  222. return;
  223. }
  224. aClass.outBaseTypeNum = nextType++;
  225. if (aClass.superClass != null) {
  226. aClass.superClass.writeDetails = true;
  227. AddTypeToTypeList(aClass.superClass);
  228. }
  229. if (aClass.isInterface) {
  230. for (ClassDesc intf : aClass.interfaces) {
  231. intf.writeDetails = true;
  232. AddTypeToTypeList(intf); // Recurse
  233. }
  234. }
  235. } else if (ty instanceof PtrDesc) {
  236. ty = ((PtrDesc)ty).boundType;
  237. if (ty.outTypeNum == 0) {
  238. AddTypeToTypeList(ty);
  239. }
  240. } else if (ty instanceof ArrayDesc) {
  241. ty = ((ArrayDesc)ty).elemType;
  242. while (ty instanceof ArrayDesc) {
  243. ArrayDesc aTy = (ArrayDesc)ty;
  244. if (aTy.ptrType.outTypeNum == 0) {
  245. InsertTypeInTypeList(aTy.ptrType);
  246. }
  247. if (aTy.outTypeNum == 0) {
  248. InsertTypeInTypeList(aTy);
  249. }
  250. ty = aTy.elemType;
  251. }
  252. if (ty.outTypeNum == 0) {
  253. InsertTypeInTypeList(ty);
  254. }
  255. }
  256. }
  257. /**
  258. * Writes out the ordinal number of the type denoted by this
  259. * <code>TypeDesc</code> object. If a descriptor does not have
  260. * a ordinal already allocated this implies that the type has
  261. * not yet been added to the type-list. In this case the type
  262. * is added to the list and an ordinal allocated.
  263. * <p>
  264. * Builtin types have pre-allocated type ordinal, less than
  265. * <code>TypeDesc.ordT</code>.
  266. * @param out The data stream to which the symbol file is being written.
  267. * @param ty The <code>TypeDesc</code> whose type ordinal is required.
  268. * @throws IOException
  269. */
  270. static void writeTypeOrd(DataOutputStream out,TypeDesc ty)throws IOException {
  271. if (ty.typeOrd < TypeDesc.ordT) {
  272. // ==> ty is a builtin type.
  273. out.writeByte(ty.typeOrd);
  274. } else {
  275. if (ty.outTypeNum == 0) {
  276. // ==> ty is a class type.
  277. AddTypeToTypeList(ty); // blame ty
  278. }
  279. if (ty.outTypeNum == 0) {
  280. System.out.println("ERROR: type has number 0 for type " + ty.name);
  281. System.exit(1);
  282. }
  283. writeOrd(out,ty.outTypeNum);
  284. }
  285. }
  286. public static void WriteFormalType(MethodInfo m,DataOutputStream out)
  287. throws IOException {
  288. if ((m.retType != null) && (m.retType.typeOrd != 0)) {
  289. out.writeByte(retSy);
  290. writeTypeOrd(out,m.retType);
  291. }
  292. out.writeByte(frmSy);
  293. for (TypeDesc parType : m.parTypes) {
  294. out.writeByte(parSy);
  295. if (parType instanceof ArrayDesc) {
  296. out.writeByte(1); // array params are IN
  297. } else {
  298. out.writeByte(0); // all other java parameters are value
  299. }
  300. writeTypeOrd(out, parType);
  301. }
  302. out.writeByte(endFm);
  303. }
  304. public static void WriteSymbolFile(PackageDesc thisPack) throws IOException{
  305. ClearTypeList();
  306. DataOutputStream out = j2cpsfiles.CreateSymFile(thisPack.cpName);
  307. out.writeInt(magic);
  308. out.writeByte(modSy);
  309. writeName(out,0,thisPack.cpName);
  310. writeString(out,thisPack.javaName);
  311. out.writeByte(falSy); /* package is not an interface */
  312. // #############################
  313. imps = thisPack.pkgImports;
  314. target = thisPack;
  315. // #############################
  316. //
  317. // Emit package import list
  318. // Import = impSy Name [String] Key.
  319. // Imports are given an index as they are listed.
  320. //
  321. for (int i=0; i < thisPack.pkgImports.size(); i++) {
  322. out.writeByte(impSy);
  323. PackageDesc imp = (PackageDesc)thisPack.pkgImports.get(i);
  324. // -------------------
  325. if (ClassDesc.VERBOSE)
  326. System.out.printf("import %d %s %d\n",
  327. i,
  328. (imp.javaName == null ? "null" : imp.javaName),
  329. i+1);
  330. // -------------------
  331. imp.impNum = i+1;
  332. writeName(out,0,imp.cpName);
  333. writeString(out,imp.javaName);
  334. out.writeByte(keySy);
  335. out.writeInt(0);
  336. }
  337. for (ClassDesc thisClass : thisPack.myClasses) {
  338. if ((thisClass != null) && ConstantPool.isPublic(thisClass.access)) {
  339. // -------------------
  340. if (ClassDesc.verbose)
  341. System.out.printf("Member class %s\n", thisClass.javaName);
  342. // -------------------
  343. // This class is a class of the package being
  344. // emitted to this symbol file. Details are required.
  345. // -------------------
  346. thisClass.writeDetails = true;
  347. out.writeByte(typSy);
  348. writeName(out,thisClass.access,thisClass.objName);
  349. writeTypeOrd(out,thisClass);
  350. // Sanity check.
  351. assert (thisClass.access & 0x200) == 0 ||
  352. (thisClass.access & 1) == 1 :
  353. "Interface not public : " + thisClass.qualName;
  354. }
  355. }
  356. //
  357. // Write out typelist
  358. //
  359. out.writeByte(start);
  360. for (int i=0; i < tListIx; i++) {
  361. TypeDesc desc = typeList[i];
  362. // -------------------
  363. if (ClassDesc.VERBOSE)
  364. System.out.printf("typeList element %d (of %d) %s %d\n",
  365. i, tListIx,
  366. (desc.name == null ? "null" : desc.name),
  367. desc.outTypeNum);
  368. // -------------------
  369. out.writeByte(tDefS);
  370. writeOrd(out,desc.outTypeNum);
  371. desc.writeType(out, thisPack);
  372. }
  373. out.writeByte(close);
  374. out.writeByte(keySy);
  375. out.writeInt(0);
  376. // We need to emit the optional comments to
  377. // trigger special behaviour from Browse.
  378. writeString(out, "Creator PeToCps " + j2cps.versionStr);
  379. writeString(out, "Compiled from " + j2cps.pkgOrJar);
  380. thisPack.ResetImports();
  381. }
  382. //
  383. // Symbol file reading
  384. //
  385. private static void InsertType(int tNum,TypeDesc ty) {
  386. if (tNum >= typeList.length) {
  387. int newLen = 2 * typeList.length;
  388. while (tNum >= newLen) { newLen += typeList.length; }
  389. TypeDesc[] tmp = new TypeDesc[newLen];
  390. System.arraycopy(typeList, 0, tmp, 0, typeList.length);
  391. typeList = tmp;
  392. }
  393. typeList[tNum] = ty;
  394. }
  395. private static int readOrd() throws IOException {
  396. int b1 = in.readUnsignedByte();
  397. if (b1 <= 0x7f) { return b1; }
  398. else { int b2 = in.readByte();
  399. return b1 - 128 + b2 * 128; }
  400. }
  401. private static void GetSym() throws IOException {
  402. sSym = in.readByte();
  403. switch (sSym) {
  404. case namSy : acc = in.readByte(); // fall through
  405. case strSy : name = in.readUTF(); break;
  406. case arrSy :
  407. case ptrSy :
  408. case retSy :
  409. case fromS :
  410. case tDefS :
  411. case basSy : tOrd = readOrd(); break;
  412. case bytSy : iVal = in.readByte(); break;
  413. case keySy :
  414. case setSy : iVal = in.readInt(); break;
  415. case numSy : lVal = in.readLong(); break;
  416. case fltSy : dVal = in.readDouble(); break;
  417. case chrSy : cVal = in.readChar(); break;
  418. case modSy :
  419. case impSy :
  420. case conSy :
  421. case varSy :
  422. case typSy :
  423. case prcSy :
  424. case mthSy :
  425. case parSy :
  426. case start :
  427. case close :
  428. case falSy :
  429. case truSy :
  430. case frmSy :
  431. case endFm :
  432. case recSy :
  433. case endRc :
  434. case endAr :
  435. case eTpSy :
  436. case iFcSy :
  437. case evtSy :
  438. case pTpSy : break;
  439. default: char ch = (char) sSym;
  440. System.out.println("Bad symbol file format." +ch+" "+sSym);
  441. System.exit(1);
  442. }
  443. }
  444. private static void Expect(int expSym) throws IOException {
  445. if (expSym != sSym) {
  446. System.out.println("Error in symbol file: expecting " +
  447. String.valueOf((char) expSym) + " got " +
  448. String.valueOf((char) sSym));
  449. System.exit(1);
  450. }
  451. GetSym();
  452. }
  453. private static void Check(int expSym) {
  454. if (expSym != sSym) {
  455. System.out.println("Error in symbol file: checking " +
  456. String.valueOf((char) expSym) + " got " +
  457. String.valueOf((char) sSym));
  458. System.exit(1);
  459. }
  460. }
  461. private static void SkipToEndRec(DataInputStream in) throws IOException {
  462. while (sSym != endRc) {
  463. switch (sSym) {
  464. case mthSy:
  465. GetSym(); // name
  466. in.readByte();
  467. in.readByte();
  468. readOrd();
  469. break;
  470. case varSy:
  471. GetSym(); // name
  472. readOrd();
  473. break;
  474. case conSy:
  475. GetSym(); // name
  476. GetSym(); // Literal
  477. break;
  478. case prcSy:
  479. GetSym(); // name
  480. break;
  481. case parSy:
  482. in.readByte();
  483. readOrd();
  484. break;
  485. case namSy:
  486. readOrd();
  487. break;
  488. default:
  489. break;
  490. }
  491. GetSym();
  492. }
  493. }
  494. private static int GetAccess() {
  495. switch (acc) {
  496. case prvMode:
  497. return ConstantPool.ACC_PRIVATE;
  498. case pubMode:
  499. return ConstantPool.ACC_PUBLIC;
  500. case protect:
  501. return ConstantPool.ACC_PROTECTED;
  502. default:
  503. break;
  504. }
  505. return 0;
  506. }
  507. private static ClassDesc GetClassDesc(PackageDesc thisPack,String className) {
  508. ClassDesc aClass = ClassDesc.GetClassDesc(thisPack.name + Util.FWDSLSH +
  509. className,thisPack);
  510. if (aClass.fieldList == null){ aClass.fieldList = new ArrayList<>(); }
  511. if (aClass.methodList == null){ aClass.methodList = new ArrayList<>(); }
  512. return aClass;
  513. }
  514. private static void GetConstant(ClassDesc cClass) throws IOException {
  515. // Constant = conSy Name Literal.
  516. // Literal = Number | String | Set | Char | Real | falSy | truSy.
  517. TypeDesc typ = null;
  518. Object val = null;
  519. Expect(conSy);
  520. String constName = name;
  521. int fAcc = GetAccess();
  522. fAcc = fAcc + ConstantPool.ACC_STATIC + ConstantPool.ACC_FINAL;
  523. Expect(namSy);
  524. switch (sSym) {
  525. case numSy : typ = TypeDesc.GetBasicType(TypeDesc.longT);
  526. val = lVal; break;
  527. case strSy : typ = TypeDesc.GetBasicType(TypeDesc.strT);
  528. val = name; break;
  529. case setSy : typ = TypeDesc.GetBasicType(TypeDesc.setT);
  530. val = iVal; break;
  531. case chrSy : typ = TypeDesc.GetBasicType(TypeDesc.charT);
  532. val = cVal; break;
  533. case fltSy : typ = TypeDesc.GetBasicType(TypeDesc.dbleT);
  534. val = dVal; break;
  535. case falSy : typ = TypeDesc.GetBasicType(TypeDesc.boolT);
  536. val = false; break;
  537. case truSy : typ = TypeDesc.GetBasicType(TypeDesc.boolT);
  538. val = true; break;
  539. }
  540. boolean ok = cClass.fieldList.add(new FieldInfo(cClass,fAcc,constName,typ,val));
  541. GetSym();
  542. }
  543. private static void GetVar(ClassDesc vClass) throws IOException {
  544. // Variable = varSy Name TypeOrd.
  545. Expect(varSy);
  546. String varName = name;
  547. int fAcc = GetAccess();
  548. Check(namSy);
  549. FieldInfo f = new FieldInfo(vClass,fAcc,varName,null,null);
  550. f.typeFixUp = readOrd();
  551. vClass.fieldList.add(f);
  552. GetSym();
  553. }
  554. private static void GetType(PackageDesc thisPack) throws IOException {
  555. // Type = typSy Name TypeOrd.
  556. Expect(typSy);
  557. ClassDesc thisClass = GetClassDesc(thisPack,name);
  558. thisClass.access = GetAccess();
  559. Check(namSy);
  560. int tNum = readOrd();
  561. thisClass.inTypeNum = tNum;
  562. InsertType(tNum,thisClass);
  563. GetSym();
  564. }
  565. private static void GetFormalType(ClassDesc thisClass,MethodInfo thisMethod)
  566. throws IOException {
  567. // FormalType = [retSy TypeOrd] frmSy {parSy Byte TypeOrd} endFm.
  568. int [] pars = new int[20];
  569. int numPars = 0;
  570. TypeDesc retType = TypeDesc.GetBasicType(TypeDesc.noTyp);
  571. if (sSym == retSy) { thisMethod.retTypeFixUp = tOrd; GetSym();}
  572. Expect(frmSy);
  573. while (sSym != endFm) {
  574. Check(parSy);
  575. in.readByte(); /* ignore par mode */
  576. pars[numPars++] = readOrd();
  577. GetSym();
  578. }
  579. Expect(endFm);
  580. thisMethod.parFixUps = new int[numPars];
  581. System.arraycopy(pars, 0, thisMethod.parFixUps, 0, numPars);
  582. }
  583. private static void GetMethod(ClassDesc thisClass) throws IOException {
  584. // Method = mthSy Name Byte Byte TypeOrd [String] FormalType.
  585. String jName = null;
  586. Expect(mthSy);
  587. Check(namSy);
  588. String nam = name;
  589. int pAcc = GetAccess();
  590. int attr = in.readByte();
  591. int recMode = in.readByte();
  592. int cNum = readOrd();
  593. if (cNum != thisClass.inTypeNum) {
  594. System.err.println("Method not part of THIS class!");
  595. System.exit(1);
  596. }
  597. GetSym();
  598. if (sSym == strSy) { jName = name; GetSym(); }
  599. MethodInfo m = new MethodInfo(thisClass,nam,jName,pAcc);
  600. switch (attr) {
  601. case 1 : if (!m.isInitProc) {
  602. m.accessFlags += ConstantPool.ACC_FINAL;
  603. }
  604. break;
  605. case 2 : m.overridding = true;
  606. m.accessFlags += (ConstantPool.ACC_ABSTRACT +
  607. ConstantPool.ACC_FINAL);
  608. break;
  609. case 3 : m.accessFlags += (ConstantPool.ACC_ABSTRACT +
  610. ConstantPool.ACC_FINAL);
  611. break;
  612. case 6 : m.overridding = true;
  613. break;
  614. case 7 : break;
  615. }
  616. GetFormalType(thisClass,m);
  617. thisClass.methodList.add(m);
  618. thisClass.scope.put(m.name,m);
  619. }
  620. private static void GetProc(ClassDesc pClass) throws IOException {
  621. // Proc = prcSy Name [String] [truSy] FormalType.
  622. String jName = null;
  623. Expect(prcSy);
  624. String procName = name;
  625. int pAcc = GetAccess();
  626. pAcc = pAcc + ConstantPool.ACC_STATIC;
  627. Expect(namSy);
  628. if (sSym == strSy) { jName = name; GetSym(); }
  629. MethodInfo m = new MethodInfo(pClass,procName,jName,pAcc);
  630. if (sSym == truSy) {
  631. m.isInitProc = true; GetSym();
  632. }
  633. GetFormalType(pClass,m);
  634. pClass.methodList.add(m);
  635. }
  636. private static void ClearTypeList() {
  637. for (int i=0; i < typeList.length; i++) {
  638. if (typeList[i] != null) {
  639. if (typeList[i].typeOrd >= TypeDesc.specT) {
  640. typeList[i].inTypeNum = 0;
  641. typeList[i].outTypeNum = 0;
  642. }
  643. if (typeList[i] instanceof ClassDesc) {
  644. ((ClassDesc)typeList[i]).inBaseTypeNum = 0;
  645. ((ClassDesc)typeList[i]).outBaseTypeNum = 0;
  646. ((ClassDesc)typeList[i]).writeDetails = false;
  647. } else if (typeList[i] instanceof ArrayDesc) {
  648. ((ArrayDesc)typeList[i]).elemTypeFixUp = 0;
  649. }
  650. }
  651. typeList[i] = null;
  652. }
  653. tListIx = 0;
  654. nextType = TypeDesc.ordT;
  655. }
  656. private static void FixArrayElemType(ArrayDesc arr) {
  657. if (arr.elemTypeFixUp == 0) { return; }
  658. TypeDesc elem = GetFixUpType(arr.elemTypeFixUp);
  659. if (elem instanceof ArrayDesc) {
  660. FixArrayElemType((ArrayDesc)elem);
  661. arr.dim = ((ArrayDesc)elem).dim + 1;
  662. arr.ultimateElemType = ((ArrayDesc)elem).ultimateElemType;
  663. } else {
  664. arr.ultimateElemType = elem;
  665. }
  666. arr.elemType = elem;
  667. }
  668. private static TypeDesc GetFixUpType (int num) {
  669. if (num < TypeDesc.specT) { return TypeDesc.GetBasicType(num); }
  670. if (typeList[num] instanceof PtrDesc) {
  671. return ((PtrDesc)typeList[num]).boundType;
  672. }
  673. return typeList[num];
  674. }
  675. public static void ReadSymbolFile(File symFile, PackageDesc thisPack)
  676. throws FileNotFoundException, IOException {
  677. if (ClassDesc.verbose) {
  678. System.out.println("INFO: Reading symbol file " + symFile.getName());
  679. }
  680. ClearTypeList();
  681. ClassDesc aClass, impClass;
  682. int maxInNum = 0;
  683. //
  684. // Read the symbol file and create descriptors
  685. //
  686. try (FileInputStream fIn = new FileInputStream(symFile)) {
  687. in = new DataInputStream(fIn);
  688. if (in.readInt() != magic) {
  689. System.out.println(symFile.getName() + " is not a valid symbol file.");
  690. System.exit(1);
  691. }
  692. GetSym();
  693. Expect(modSy);
  694. if (!thisPack.cpName.equals(name)) {
  695. System.out.println("ERROR: Symbol file " + symFile.getName()
  696. + " does not contain MODULE " + thisPack.cpName + ", it contains MODULE "
  697. + name);
  698. System.exit(1);
  699. }
  700. Expect(namSy);
  701. if (sSym == strSy) {
  702. if (!name.equals(thisPack.javaName)) {
  703. System.out.println("Wrong name in symbol file.");
  704. System.exit(1);
  705. }
  706. GetSym();
  707. if (sSym == truSy) {
  708. System.out.println("ERROR: Java Package cannot be an interface.");
  709. System.exit(1);
  710. }
  711. GetSym();
  712. } else {
  713. System.err.println("<" + symFile.getName()
  714. + "> NOT A SYMBOL FILE FOR A JAVA PACKAGE!");
  715. System.exit(1);
  716. }
  717. while (sSym != start) {
  718. switch (sSym) {
  719. case impSy:
  720. GetSym(); // name
  721. String iName = name;
  722. GetSym();
  723. if (sSym == strSy) {
  724. PackageDesc pack = PackageDesc.getPackage(name);
  725. thisPack.pkgImports.add(pack);
  726. GetSym();
  727. }
  728. Expect(keySy);
  729. break;
  730. case conSy:
  731. case varSy:
  732. case prcSy:
  733. System.out.println("Symbol File is not from a java class");
  734. System.exit(1);
  735. break;
  736. case typSy:
  737. GetType(thisPack);
  738. break;
  739. }
  740. }
  741. Expect(start);
  742. while (sSym != close) {
  743. PackageDesc impPack;
  744. impClass = null;
  745. String impModName = null;
  746. int impAcc = 0,
  747. impModAcc = 0;
  748. Check(tDefS);
  749. int tNum = tOrd;
  750. GetSym();
  751. if (tNum > maxInNum) {
  752. maxInNum = tNum;
  753. }
  754. if (sSym == fromS) {
  755. int impNum = tOrd - 1;
  756. GetSym();
  757. Check(namSy);
  758. String impName = name;
  759. impAcc = acc;
  760. if (impNum < 0) {
  761. impPack = thisPack;
  762. } else {
  763. impPack = (PackageDesc) thisPack.pkgImports.get(impNum);
  764. }
  765. impClass = GetClassDesc(impPack, impName);
  766. GetSym();
  767. }
  768. switch (sSym) {
  769. case arrSy:
  770. ArrayDesc newArr;
  771. int elemOrd = tOrd;
  772. GetSym();
  773. Expect(endAr);
  774. TypeDesc eTy = null;
  775. if (elemOrd < typeList.length) {
  776. if (elemOrd < TypeDesc.specT) {
  777. eTy = TypeDesc.GetBasicType(elemOrd);
  778. } else {
  779. eTy = typeList[elemOrd];
  780. }
  781. if ((eTy != null) && (eTy instanceof PtrDesc)
  782. && (((PtrDesc) eTy).boundType != null)
  783. && (((PtrDesc) eTy).boundType instanceof ClassDesc)) {
  784. eTy = ((PtrDesc) eTy).boundType;
  785. }
  786. }
  787. if (eTy != null) {
  788. newArr = ArrayDesc.FindOrCreateArrayType(1, eTy, true);
  789. } else {
  790. newArr = new ArrayDesc(elemOrd);
  791. }
  792. if ((tNum < typeList.length) && (typeList[tNum] != null)) {
  793. PtrDesc desc = (PtrDesc) typeList[tNum];
  794. if (desc.inBaseTypeNum != tNum) {
  795. System.out.println("WRONG BASE TYPE FOR POINTER!");
  796. System.exit(1);
  797. }
  798. desc.Init(newArr);
  799. newArr.SetPtrType(desc);
  800. }
  801. InsertType(tNum, newArr);
  802. break;
  803. case ptrSy:
  804. TypeDesc ty;
  805. if (impClass != null) {
  806. InsertType(tNum, impClass);
  807. ty = impClass;
  808. ty.inTypeNum = tNum;
  809. ty.inBaseTypeNum = tOrd;
  810. InsertType(tOrd, ty);
  811. } else if ((tNum < typeList.length)
  812. && (typeList[tNum] != null)
  813. && (typeList[tNum] instanceof ClassDesc)) {
  814. ty = typeList[tNum];
  815. ty.inTypeNum = tNum;
  816. ty.inBaseTypeNum = tOrd;
  817. InsertType(tOrd, ty);
  818. } else {
  819. ty = new PtrDesc(tNum, tOrd);
  820. InsertType(tNum, ty);
  821. if ((tOrd < typeList.length)
  822. && (typeList[tOrd] != null)) {
  823. ((PtrDesc) ty).Init(typeList[tOrd]);
  824. }
  825. }
  826. GetSym();
  827. break;
  828. case recSy:
  829. if ((tNum >= typeList.length)
  830. || (typeList[tNum] == null)
  831. || (!(typeList[tNum] instanceof ClassDesc))) {
  832. /* cannot have record type that is not a base type
  833. of a pointer in a java file */
  834. System.err.println(
  835. "RECORD TYPE " + tNum + " IS NOT POINTER BASE TYPE!");
  836. System.exit(1);
  837. }
  838. aClass = (ClassDesc) typeList[tNum];
  839. acc = in.readByte();
  840. aClass.setRecAtt(acc);
  841. if (aClass.read) {
  842. GetSym();
  843. SkipToEndRec(in);
  844. GetSym();
  845. } else {
  846. GetSym();
  847. if (sSym == truSy) {
  848. aClass.isInterface = true;
  849. GetSym();
  850. } else if (sSym == falSy) {
  851. GetSym();
  852. }
  853. if (sSym == basSy) {
  854. aClass.superNum = tOrd;
  855. GetSym();
  856. }
  857. if (sSym == iFcSy) {
  858. GetSym();
  859. aClass.intNums = new int[10];
  860. aClass.numInts = 0;
  861. while (sSym == basSy) {
  862. if (aClass.numInts >= aClass.intNums.length) {
  863. int tmp[] = new int[aClass.intNums.length * 2];
  864. System.arraycopy(aClass.intNums, 0, tmp, 0, aClass.intNums.length);
  865. aClass.intNums = tmp;
  866. }
  867. aClass.intNums[aClass.numInts] = tOrd;
  868. aClass.numInts++;
  869. GetSym();
  870. }
  871. }
  872. while (sSym == namSy) {
  873. FieldInfo f = new FieldInfo(aClass, GetAccess(), name,
  874. null, null);
  875. f.typeFixUp = readOrd();
  876. GetSym();
  877. boolean ok = aClass.fieldList.add(f);
  878. aClass.scope.put(f.name, f);
  879. }
  880. while ((sSym == mthSy) || (sSym == prcSy)
  881. || (sSym == varSy) || (sSym == conSy)) {
  882. switch (sSym) {
  883. case mthSy:
  884. GetMethod(aClass);
  885. break;
  886. case prcSy:
  887. GetProc(aClass);
  888. break;
  889. case varSy:
  890. GetVar(aClass);
  891. break;
  892. case conSy:
  893. GetConstant(aClass);
  894. break;
  895. }
  896. }
  897. Expect(endRc);
  898. }
  899. break;
  900. case pTpSy:
  901. System.out.println("CANNOT HAVE PROC TYPE IN JAVA FILE!");
  902. break;
  903. case evtSy:
  904. System.out.println("CANNOT HAVE EVENT TYPE IN JAVA FILE!");
  905. break;
  906. case eTpSy:
  907. System.out.println("CANNOT HAVE ENUM TYPE IN JAVA FILE!");
  908. break;
  909. case tDefS:
  910. case close:
  911. InsertType(tNum, impClass);
  912. break;
  913. default:
  914. char ch = (char) sSym;
  915. System.out.println("UNRECOGNISED TYPE!" + sSym + " " + ch);
  916. System.exit(1);
  917. }
  918. }
  919. Expect(close);
  920. Check(keySy);
  921. }
  922. //
  923. // Now do the type fixups
  924. //
  925. for (int i = TypeDesc.specT; i <= maxInNum; i++) {
  926. if ((typeList[i] != null) && (typeList[i] instanceof ClassDesc)) {
  927. if (!((ClassDesc) typeList[i]).read) {
  928. aClass = (ClassDesc) typeList[i];
  929. if (aClass.superNum != 0) {
  930. aClass.superClass = (ClassDesc) typeList[aClass.superNum];
  931. }
  932. aClass.interfaces = new ClassDesc[aClass.numInts];
  933. for (int j = 0; j < aClass.numInts; j++) {
  934. aClass.interfaces[j] = (ClassDesc) GetFixUpType(aClass.intNums[j]);
  935. }
  936. int size;
  937. if (aClass.fieldList == null) {
  938. size = 0;
  939. } else {
  940. size = aClass.fieldList.size();
  941. }
  942. //aClass.fields = new FieldInfo[size];
  943. for (int j = 0; j < size; j++) {
  944. FieldInfo fieldJ = (FieldInfo) aClass.fieldList.get(j);
  945. //aClass.fields[j] = fieldJ;
  946. fieldJ.type = GetFixUpType(fieldJ.typeFixUp);
  947. if (fieldJ.type instanceof ClassDesc) { // FIXME And is public?
  948. aClass.AddImportToClass((ClassDesc) fieldJ.type);
  949. }
  950. }
  951. aClass.fieldList = null;
  952. if (aClass.methodList == null) {
  953. size = 0;
  954. } else {
  955. size = aClass.methodList.size();
  956. }
  957. //aClass.methods = new MethodInfo[size];
  958. for (int k = 0; k < size; k++) {
  959. MethodInfo methodK = (MethodInfo) aClass.methodList.get(k);
  960. //aClass.methods[k] = methodK;
  961. methodK.retType = GetFixUpType(methodK.retTypeFixUp);
  962. if (methodK.retType instanceof ClassDesc) {
  963. aClass.AddImportToClass((ClassDesc) methodK.retType);
  964. }
  965. methodK.parTypes = new TypeDesc[methodK.parFixUps.length];
  966. for (int j = 0; j < methodK.parFixUps.length; j++) {
  967. methodK.parTypes[j] = GetFixUpType(methodK.parFixUps[j]);
  968. if (methodK.parTypes[j] instanceof ClassDesc) {
  969. aClass.AddImportToClass((ClassDesc) methodK.parTypes[j]);
  970. }
  971. }
  972. }
  973. aClass.methodList = null;
  974. aClass.read = true;
  975. aClass.done = true;
  976. }
  977. } else if ((typeList[i] != null) && (typeList[i] instanceof ArrayDesc)) {
  978. FixArrayElemType((ArrayDesc) typeList[i]);
  979. } else if ((typeList[i] != null) && (typeList[i] instanceof PtrDesc)) {
  980. PtrDesc ptr = (PtrDesc) typeList[i];
  981. if (ptr.typeOrd == TypeDesc.arrPtr) {
  982. ptr.Init(typeList[ptr.inBaseTypeNum]);
  983. }
  984. } else if (typeList[i] != null) {
  985. System.out.println("Type " + i + " " + typeList[i].name
  986. + " is NOT array or class");
  987. System.exit(0);
  988. }
  989. }
  990. }
  991. }