2
0

SymbolFile.java 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  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. thisPack.ResetImports();
  377. }
  378. //
  379. // Symbol file reading
  380. //
  381. private static void InsertType(int tNum,TypeDesc ty) {
  382. if (tNum >= typeList.length) {
  383. int newLen = 2 * typeList.length;
  384. while (tNum >= newLen) { newLen += typeList.length; }
  385. TypeDesc[] tmp = new TypeDesc[newLen];
  386. System.arraycopy(typeList, 0, tmp, 0, typeList.length);
  387. typeList = tmp;
  388. }
  389. typeList[tNum] = ty;
  390. }
  391. private static int readOrd() throws IOException {
  392. int b1 = in.readUnsignedByte();
  393. if (b1 <= 0x7f) { return b1; }
  394. else { int b2 = in.readByte();
  395. return b1 - 128 + b2 * 128; }
  396. }
  397. private static void GetSym() throws IOException {
  398. sSym = in.readByte();
  399. switch (sSym) {
  400. case namSy : acc = in.readByte(); // fall through
  401. case strSy : name = in.readUTF(); break;
  402. case arrSy :
  403. case ptrSy :
  404. case retSy :
  405. case fromS :
  406. case tDefS :
  407. case basSy : tOrd = readOrd(); break;
  408. case bytSy : iVal = in.readByte(); break;
  409. case keySy :
  410. case setSy : iVal = in.readInt(); break;
  411. case numSy : lVal = in.readLong(); break;
  412. case fltSy : dVal = in.readDouble(); break;
  413. case chrSy : cVal = in.readChar(); break;
  414. case modSy :
  415. case impSy :
  416. case conSy :
  417. case varSy :
  418. case typSy :
  419. case prcSy :
  420. case mthSy :
  421. case parSy :
  422. case start :
  423. case close :
  424. case falSy :
  425. case truSy :
  426. case frmSy :
  427. case endFm :
  428. case recSy :
  429. case endRc :
  430. case endAr :
  431. case eTpSy :
  432. case iFcSy :
  433. case evtSy :
  434. case pTpSy : break;
  435. default: char ch = (char) sSym;
  436. System.out.println("Bad symbol file format." +ch+" "+sSym);
  437. System.exit(1);
  438. }
  439. }
  440. private static void Expect(int expSym) throws IOException {
  441. if (expSym != sSym) {
  442. System.out.println("Error in symbol file: expecting " +
  443. String.valueOf((char) expSym) + " got " +
  444. String.valueOf((char) sSym));
  445. System.exit(1);
  446. }
  447. GetSym();
  448. }
  449. private static void Check(int expSym) {
  450. if (expSym != sSym) {
  451. System.out.println("Error in symbol file: checking " +
  452. String.valueOf((char) expSym) + " got " +
  453. String.valueOf((char) sSym));
  454. System.exit(1);
  455. }
  456. }
  457. private static void SkipToEndRec(DataInputStream in) throws IOException {
  458. while (sSym != endRc) {
  459. switch (sSym) {
  460. case mthSy:
  461. GetSym(); // name
  462. in.readByte();
  463. in.readByte();
  464. readOrd();
  465. break;
  466. case varSy:
  467. GetSym(); // name
  468. readOrd();
  469. break;
  470. case conSy:
  471. GetSym(); // name
  472. GetSym(); // Literal
  473. break;
  474. case prcSy:
  475. GetSym(); // name
  476. break;
  477. case parSy:
  478. in.readByte();
  479. readOrd();
  480. break;
  481. case namSy:
  482. readOrd();
  483. break;
  484. default:
  485. break;
  486. }
  487. GetSym();
  488. }
  489. }
  490. private static int GetAccess() {
  491. switch (acc) {
  492. case prvMode:
  493. return ConstantPool.ACC_PRIVATE;
  494. case pubMode:
  495. return ConstantPool.ACC_PUBLIC;
  496. case protect:
  497. return ConstantPool.ACC_PROTECTED;
  498. default:
  499. break;
  500. }
  501. return 0;
  502. }
  503. private static ClassDesc GetClassDesc(PackageDesc thisPack,String className) {
  504. ClassDesc aClass = ClassDesc.GetClassDesc(thisPack.name + Util.FWDSLSH +
  505. className,thisPack);
  506. if (aClass.fieldList == null){ aClass.fieldList = new ArrayList<>(); }
  507. if (aClass.methodList == null){ aClass.methodList = new ArrayList<>(); }
  508. return aClass;
  509. }
  510. private static void GetConstant(ClassDesc cClass) throws IOException {
  511. // Constant = conSy Name Literal.
  512. // Literal = Number | String | Set | Char | Real | falSy | truSy.
  513. TypeDesc typ = null;
  514. Object val = null;
  515. Expect(conSy);
  516. String constName = name;
  517. int fAcc = GetAccess();
  518. fAcc = fAcc + ConstantPool.ACC_STATIC + ConstantPool.ACC_FINAL;
  519. Expect(namSy);
  520. switch (sSym) {
  521. case numSy : typ = TypeDesc.GetBasicType(TypeDesc.longT);
  522. val = lVal; break;
  523. case strSy : typ = TypeDesc.GetBasicType(TypeDesc.strT);
  524. val = name; break;
  525. case setSy : typ = TypeDesc.GetBasicType(TypeDesc.setT);
  526. val = iVal; break;
  527. case chrSy : typ = TypeDesc.GetBasicType(TypeDesc.charT);
  528. val = cVal; break;
  529. case fltSy : typ = TypeDesc.GetBasicType(TypeDesc.dbleT);
  530. val = dVal; break;
  531. case falSy : typ = TypeDesc.GetBasicType(TypeDesc.boolT);
  532. val = false; break;
  533. case truSy : typ = TypeDesc.GetBasicType(TypeDesc.boolT);
  534. val = true; break;
  535. }
  536. boolean ok = cClass.fieldList.add(new FieldInfo(cClass,fAcc,constName,typ,val));
  537. GetSym();
  538. }
  539. private static void GetVar(ClassDesc vClass) throws IOException {
  540. // Variable = varSy Name TypeOrd.
  541. Expect(varSy);
  542. String varName = name;
  543. int fAcc = GetAccess();
  544. Check(namSy);
  545. FieldInfo f = new FieldInfo(vClass,fAcc,varName,null,null);
  546. f.typeFixUp = readOrd();
  547. vClass.fieldList.add(f);
  548. GetSym();
  549. }
  550. private static void GetType(PackageDesc thisPack) throws IOException {
  551. // Type = typSy Name TypeOrd.
  552. Expect(typSy);
  553. ClassDesc thisClass = GetClassDesc(thisPack,name);
  554. thisClass.access = GetAccess();
  555. Check(namSy);
  556. int tNum = readOrd();
  557. thisClass.inTypeNum = tNum;
  558. InsertType(tNum,thisClass);
  559. GetSym();
  560. }
  561. private static void GetFormalType(ClassDesc thisClass,MethodInfo thisMethod)
  562. throws IOException {
  563. // FormalType = [retSy TypeOrd] frmSy {parSy Byte TypeOrd} endFm.
  564. int [] pars = new int[20];
  565. int numPars = 0;
  566. TypeDesc retType = TypeDesc.GetBasicType(TypeDesc.noTyp);
  567. if (sSym == retSy) { thisMethod.retTypeFixUp = tOrd; GetSym();}
  568. Expect(frmSy);
  569. while (sSym != endFm) {
  570. Check(parSy);
  571. in.readByte(); /* ignore par mode */
  572. pars[numPars++] = readOrd();
  573. GetSym();
  574. }
  575. Expect(endFm);
  576. thisMethod.parFixUps = new int[numPars];
  577. System.arraycopy(pars, 0, thisMethod.parFixUps, 0, numPars);
  578. }
  579. private static void GetMethod(ClassDesc thisClass) throws IOException {
  580. // Method = mthSy Name Byte Byte TypeOrd [String] FormalType.
  581. String jName = null;
  582. Expect(mthSy);
  583. Check(namSy);
  584. String nam = name;
  585. int pAcc = GetAccess();
  586. int attr = in.readByte();
  587. int recMode = in.readByte();
  588. int cNum = readOrd();
  589. if (cNum != thisClass.inTypeNum) {
  590. System.err.println("Method not part of THIS class!");
  591. System.exit(1);
  592. }
  593. GetSym();
  594. if (sSym == strSy) { jName = name; GetSym(); }
  595. MethodInfo m = new MethodInfo(thisClass,nam,jName,pAcc);
  596. switch (attr) {
  597. case 1 : if (!m.isInitProc) {
  598. m.accessFlags += ConstantPool.ACC_FINAL;
  599. }
  600. break;
  601. case 2 : m.overridding = true;
  602. m.accessFlags += (ConstantPool.ACC_ABSTRACT +
  603. ConstantPool.ACC_FINAL);
  604. break;
  605. case 3 : m.accessFlags += (ConstantPool.ACC_ABSTRACT +
  606. ConstantPool.ACC_FINAL);
  607. break;
  608. case 6 : m.overridding = true;
  609. break;
  610. case 7 : break;
  611. }
  612. GetFormalType(thisClass,m);
  613. thisClass.methodList.add(m);
  614. thisClass.scope.put(m.name,m);
  615. }
  616. private static void GetProc(ClassDesc pClass) throws IOException {
  617. // Proc = prcSy Name [String] [truSy] FormalType.
  618. String jName = null;
  619. Expect(prcSy);
  620. String procName = name;
  621. int pAcc = GetAccess();
  622. pAcc = pAcc + ConstantPool.ACC_STATIC;
  623. Expect(namSy);
  624. if (sSym == strSy) { jName = name; GetSym(); }
  625. MethodInfo m = new MethodInfo(pClass,procName,jName,pAcc);
  626. if (sSym == truSy) {
  627. m.isInitProc = true; GetSym();
  628. }
  629. GetFormalType(pClass,m);
  630. pClass.methodList.add(m);
  631. }
  632. private static void ClearTypeList() {
  633. for (int i=0; i < typeList.length; i++) {
  634. if (typeList[i] != null) {
  635. if (typeList[i].typeOrd >= TypeDesc.specT) {
  636. typeList[i].inTypeNum = 0;
  637. typeList[i].outTypeNum = 0;
  638. }
  639. if (typeList[i] instanceof ClassDesc) {
  640. ((ClassDesc)typeList[i]).inBaseTypeNum = 0;
  641. ((ClassDesc)typeList[i]).outBaseTypeNum = 0;
  642. ((ClassDesc)typeList[i]).writeDetails = false;
  643. } else if (typeList[i] instanceof ArrayDesc) {
  644. ((ArrayDesc)typeList[i]).elemTypeFixUp = 0;
  645. }
  646. }
  647. typeList[i] = null;
  648. }
  649. tListIx = 0;
  650. nextType = TypeDesc.ordT;
  651. }
  652. private static void FixArrayElemType(ArrayDesc arr) {
  653. if (arr.elemTypeFixUp == 0) { return; }
  654. TypeDesc elem = GetFixUpType(arr.elemTypeFixUp);
  655. if (elem instanceof ArrayDesc) {
  656. FixArrayElemType((ArrayDesc)elem);
  657. arr.dim = ((ArrayDesc)elem).dim + 1;
  658. arr.ultimateElemType = ((ArrayDesc)elem).ultimateElemType;
  659. } else {
  660. arr.ultimateElemType = elem;
  661. }
  662. arr.elemType = elem;
  663. }
  664. private static TypeDesc GetFixUpType (int num) {
  665. if (num < TypeDesc.specT) { return TypeDesc.GetBasicType(num); }
  666. if (typeList[num] instanceof PtrDesc) {
  667. return ((PtrDesc)typeList[num]).boundType;
  668. }
  669. return typeList[num];
  670. }
  671. public static void ReadSymbolFile(File symFile, PackageDesc thisPack)
  672. throws FileNotFoundException, IOException {
  673. if (ClassDesc.verbose) {
  674. System.out.println("INFO: Reading symbol file " + symFile.getName());
  675. }
  676. ClearTypeList();
  677. ClassDesc aClass, impClass;
  678. int maxInNum = 0;
  679. //
  680. // Read the symbol file and create descriptors
  681. //
  682. try (FileInputStream fIn = new FileInputStream(symFile)) {
  683. in = new DataInputStream(fIn);
  684. if (in.readInt() != magic) {
  685. System.out.println(symFile.getName() + " is not a valid symbol file.");
  686. System.exit(1);
  687. }
  688. GetSym();
  689. Expect(modSy);
  690. if (!thisPack.cpName.equals(name)) {
  691. System.out.println("ERROR: Symbol file " + symFile.getName()
  692. + " does not contain MODULE " + thisPack.cpName + ", it contains MODULE "
  693. + name);
  694. System.exit(1);
  695. }
  696. Expect(namSy);
  697. if (sSym == strSy) {
  698. if (!name.equals(thisPack.javaName)) {
  699. System.out.println("Wrong name in symbol file.");
  700. System.exit(1);
  701. }
  702. GetSym();
  703. if (sSym == truSy) {
  704. System.out.println("ERROR: Java Package cannot be an interface.");
  705. System.exit(1);
  706. }
  707. GetSym();
  708. } else {
  709. System.err.println("<" + symFile.getName()
  710. + "> NOT A SYMBOL FILE FOR A JAVA PACKAGE!");
  711. System.exit(1);
  712. }
  713. while (sSym != start) {
  714. switch (sSym) {
  715. case impSy:
  716. GetSym(); // name
  717. String iName = name;
  718. GetSym();
  719. if (sSym == strSy) {
  720. PackageDesc pack = PackageDesc.getPackage(name);
  721. thisPack.pkgImports.add(pack);
  722. GetSym();
  723. }
  724. Expect(keySy);
  725. break;
  726. case conSy:
  727. case varSy:
  728. case prcSy:
  729. System.out.println("Symbol File is not from a java class");
  730. System.exit(1);
  731. break;
  732. case typSy:
  733. GetType(thisPack);
  734. break;
  735. }
  736. }
  737. Expect(start);
  738. while (sSym != close) {
  739. PackageDesc impPack;
  740. impClass = null;
  741. String impModName = null;
  742. int impAcc = 0,
  743. impModAcc = 0;
  744. Check(tDefS);
  745. int tNum = tOrd;
  746. GetSym();
  747. if (tNum > maxInNum) {
  748. maxInNum = tNum;
  749. }
  750. if (sSym == fromS) {
  751. int impNum = tOrd - 1;
  752. GetSym();
  753. Check(namSy);
  754. String impName = name;
  755. impAcc = acc;
  756. if (impNum < 0) {
  757. impPack = thisPack;
  758. } else {
  759. impPack = (PackageDesc) thisPack.pkgImports.get(impNum);
  760. }
  761. impClass = GetClassDesc(impPack, impName);
  762. GetSym();
  763. }
  764. switch (sSym) {
  765. case arrSy:
  766. ArrayDesc newArr;
  767. int elemOrd = tOrd;
  768. GetSym();
  769. Expect(endAr);
  770. TypeDesc eTy = null;
  771. if (elemOrd < typeList.length) {
  772. if (elemOrd < TypeDesc.specT) {
  773. eTy = TypeDesc.GetBasicType(elemOrd);
  774. } else {
  775. eTy = typeList[elemOrd];
  776. }
  777. if ((eTy != null) && (eTy instanceof PtrDesc)
  778. && (((PtrDesc) eTy).boundType != null)
  779. && (((PtrDesc) eTy).boundType instanceof ClassDesc)) {
  780. eTy = ((PtrDesc) eTy).boundType;
  781. }
  782. }
  783. if (eTy != null) {
  784. newArr = ArrayDesc.FindOrCreateArrayType(1, eTy, true);
  785. } else {
  786. newArr = new ArrayDesc(elemOrd);
  787. }
  788. if ((tNum < typeList.length) && (typeList[tNum] != null)) {
  789. PtrDesc desc = (PtrDesc) typeList[tNum];
  790. if (desc.inBaseTypeNum != tNum) {
  791. System.out.println("WRONG BASE TYPE FOR POINTER!");
  792. System.exit(1);
  793. }
  794. desc.Init(newArr);
  795. newArr.SetPtrType(desc);
  796. }
  797. InsertType(tNum, newArr);
  798. break;
  799. case ptrSy:
  800. TypeDesc ty;
  801. if (impClass != null) {
  802. InsertType(tNum, impClass);
  803. ty = impClass;
  804. ty.inTypeNum = tNum;
  805. ty.inBaseTypeNum = tOrd;
  806. InsertType(tOrd, ty);
  807. } else if ((tNum < typeList.length)
  808. && (typeList[tNum] != null)
  809. && (typeList[tNum] instanceof ClassDesc)) {
  810. ty = typeList[tNum];
  811. ty.inTypeNum = tNum;
  812. ty.inBaseTypeNum = tOrd;
  813. InsertType(tOrd, ty);
  814. } else {
  815. ty = new PtrDesc(tNum, tOrd);
  816. InsertType(tNum, ty);
  817. if ((tOrd < typeList.length)
  818. && (typeList[tOrd] != null)) {
  819. ((PtrDesc) ty).Init(typeList[tOrd]);
  820. }
  821. }
  822. GetSym();
  823. break;
  824. case recSy:
  825. if ((tNum >= typeList.length)
  826. || (typeList[tNum] == null)
  827. || (!(typeList[tNum] instanceof ClassDesc))) {
  828. /* cannot have record type that is not a base type
  829. of a pointer in a java file */
  830. System.err.println(
  831. "RECORD TYPE " + tNum + " IS NOT POINTER BASE TYPE!");
  832. System.exit(1);
  833. }
  834. aClass = (ClassDesc) typeList[tNum];
  835. acc = in.readByte();
  836. aClass.setRecAtt(acc);
  837. if (aClass.read) {
  838. GetSym();
  839. SkipToEndRec(in);
  840. GetSym();
  841. } else {
  842. GetSym();
  843. if (sSym == truSy) {
  844. aClass.isInterface = true;
  845. GetSym();
  846. } else if (sSym == falSy) {
  847. GetSym();
  848. }
  849. if (sSym == basSy) {
  850. aClass.superNum = tOrd;
  851. GetSym();
  852. }
  853. if (sSym == iFcSy) {
  854. GetSym();
  855. aClass.intNums = new int[10];
  856. aClass.numInts = 0;
  857. while (sSym == basSy) {
  858. if (aClass.numInts >= aClass.intNums.length) {
  859. int tmp[] = new int[aClass.intNums.length * 2];
  860. System.arraycopy(aClass.intNums, 0, tmp, 0, aClass.intNums.length);
  861. aClass.intNums = tmp;
  862. }
  863. aClass.intNums[aClass.numInts] = tOrd;
  864. aClass.numInts++;
  865. GetSym();
  866. }
  867. }
  868. while (sSym == namSy) {
  869. FieldInfo f = new FieldInfo(aClass, GetAccess(), name,
  870. null, null);
  871. f.typeFixUp = readOrd();
  872. GetSym();
  873. boolean ok = aClass.fieldList.add(f);
  874. aClass.scope.put(f.name, f);
  875. }
  876. while ((sSym == mthSy) || (sSym == prcSy)
  877. || (sSym == varSy) || (sSym == conSy)) {
  878. switch (sSym) {
  879. case mthSy:
  880. GetMethod(aClass);
  881. break;
  882. case prcSy:
  883. GetProc(aClass);
  884. break;
  885. case varSy:
  886. GetVar(aClass);
  887. break;
  888. case conSy:
  889. GetConstant(aClass);
  890. break;
  891. }
  892. }
  893. Expect(endRc);
  894. }
  895. break;
  896. case pTpSy:
  897. System.out.println("CANNOT HAVE PROC TYPE IN JAVA FILE!");
  898. break;
  899. case evtSy:
  900. System.out.println("CANNOT HAVE EVENT TYPE IN JAVA FILE!");
  901. break;
  902. case eTpSy:
  903. System.out.println("CANNOT HAVE ENUM TYPE IN JAVA FILE!");
  904. break;
  905. case tDefS:
  906. case close:
  907. InsertType(tNum, impClass);
  908. break;
  909. default:
  910. char ch = (char) sSym;
  911. System.out.println("UNRECOGNISED TYPE!" + sSym + " " + ch);
  912. System.exit(1);
  913. }
  914. }
  915. Expect(close);
  916. Check(keySy);
  917. }
  918. //
  919. // Now do the type fixups
  920. //
  921. for (int i = TypeDesc.specT; i <= maxInNum; i++) {
  922. if ((typeList[i] != null) && (typeList[i] instanceof ClassDesc)) {
  923. if (!((ClassDesc) typeList[i]).read) {
  924. aClass = (ClassDesc) typeList[i];
  925. if (aClass.superNum != 0) {
  926. aClass.superClass = (ClassDesc) typeList[aClass.superNum];
  927. }
  928. aClass.interfaces = new ClassDesc[aClass.numInts];
  929. for (int j = 0; j < aClass.numInts; j++) {
  930. aClass.interfaces[j] = (ClassDesc) GetFixUpType(aClass.intNums[j]);
  931. }
  932. int size;
  933. if (aClass.fieldList == null) {
  934. size = 0;
  935. } else {
  936. size = aClass.fieldList.size();
  937. }
  938. //aClass.fields = new FieldInfo[size];
  939. for (int j = 0; j < size; j++) {
  940. FieldInfo fieldJ = (FieldInfo) aClass.fieldList.get(j);
  941. //aClass.fields[j] = fieldJ;
  942. fieldJ.type = GetFixUpType(fieldJ.typeFixUp);
  943. if (fieldJ.type instanceof ClassDesc) { // FIXME And is public?
  944. aClass.AddImportToClass((ClassDesc) fieldJ.type);
  945. }
  946. }
  947. aClass.fieldList = null;
  948. if (aClass.methodList == null) {
  949. size = 0;
  950. } else {
  951. size = aClass.methodList.size();
  952. }
  953. //aClass.methods = new MethodInfo[size];
  954. for (int k = 0; k < size; k++) {
  955. MethodInfo methodK = (MethodInfo) aClass.methodList.get(k);
  956. //aClass.methods[k] = methodK;
  957. methodK.retType = GetFixUpType(methodK.retTypeFixUp);
  958. if (methodK.retType instanceof ClassDesc) {
  959. aClass.AddImportToClass((ClassDesc) methodK.retType);
  960. }
  961. methodK.parTypes = new TypeDesc[methodK.parFixUps.length];
  962. for (int j = 0; j < methodK.parFixUps.length; j++) {
  963. methodK.parTypes[j] = GetFixUpType(methodK.parFixUps[j]);
  964. if (methodK.parTypes[j] instanceof ClassDesc) {
  965. aClass.AddImportToClass((ClassDesc) methodK.parTypes[j]);
  966. }
  967. }
  968. }
  969. aClass.methodList = null;
  970. aClass.read = true;
  971. aClass.done = true;
  972. }
  973. } else if ((typeList[i] != null) && (typeList[i] instanceof ArrayDesc)) {
  974. FixArrayElemType((ArrayDesc) typeList[i]);
  975. } else if ((typeList[i] != null) && (typeList[i] instanceof PtrDesc)) {
  976. PtrDesc ptr = (PtrDesc) typeList[i];
  977. if (ptr.typeOrd == TypeDesc.arrPtr) {
  978. ptr.Init(typeList[ptr.inBaseTypeNum]);
  979. }
  980. } else if (typeList[i] != null) {
  981. System.out.println("Type " + i + " " + typeList[i].name
  982. + " is NOT array or class");
  983. System.exit(0);
  984. }
  985. }
  986. }
  987. }