SymbolFile.java 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  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);
  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. if (ty.outTypeNum > 0) { return; }
  196. ty.outTypeNum = nextType++;
  197. if (tListIx >= typeList.length) {
  198. TypeDesc[] tmp = new TypeDesc[typeList.length + initTypeListSize];
  199. System.arraycopy(typeList, 0, tmp, 0, typeList.length);
  200. typeList = tmp;
  201. }
  202. // Temporary diagnostic code
  203. if (ClassDesc.VERBOSE && (ty.name != null)) {
  204. System.out.printf("Inserting %s at ix %d\n", ty.name, tListIx);
  205. if (ty instanceof ClassDesc
  206. && target != ((ClassDesc)ty).parentPkg
  207. && !imps.contains(((ClassDesc)ty).parentPkg)) {
  208. System.err.println(ty.name + " not on import list");
  209. }
  210. }
  211. typeList[tListIx++] = ty;
  212. }
  213. public static void AddTypeToTypeList(TypeDesc ty) {
  214. InsertTypeInTypeList(ty);
  215. if (!ty.writeDetails) {
  216. return;
  217. }
  218. if (ty instanceof ClassDesc) {
  219. ClassDesc aClass = (ClassDesc)ty;
  220. if (aClass.outBaseTypeNum > 0) {
  221. return;
  222. }
  223. aClass.outBaseTypeNum = nextType++;
  224. if (aClass.superClass != null) {
  225. aClass.superClass.writeDetails = true;
  226. AddTypeToTypeList(aClass.superClass);
  227. }
  228. if (aClass.isInterface) {
  229. for (ClassDesc intf : aClass.interfaces) {
  230. intf.writeDetails = true;
  231. AddTypeToTypeList(intf); // Recurse
  232. }
  233. }
  234. } else if (ty instanceof PtrDesc) {
  235. ty = ((PtrDesc)ty).boundType;
  236. if (ty.outTypeNum == 0) {
  237. AddTypeToTypeList(ty);
  238. }
  239. } else if (ty instanceof ArrayDesc) {
  240. ty = ((ArrayDesc)ty).elemType;
  241. while (ty instanceof ArrayDesc) {
  242. ArrayDesc aTy = (ArrayDesc)ty;
  243. if (aTy.ptrType.outTypeNum == 0) {
  244. InsertTypeInTypeList(aTy.ptrType);
  245. }
  246. if (aTy.outTypeNum == 0) {
  247. InsertTypeInTypeList(aTy);
  248. }
  249. ty = aTy.elemType;
  250. }
  251. if (ty.outTypeNum == 0) {
  252. InsertTypeInTypeList(ty);
  253. }
  254. }
  255. }
  256. /**
  257. * Writes out the ordinal number of the type denoted by this
  258. * <code>TypeDesc</code> object. If a descriptor does not have
  259. * a ordinal already allocated this implies that the type has
  260. * not yet been added to the type-list. In this case the type
  261. * is added to the list and an ordinal allocated.
  262. * <p>
  263. * Builtin types have pre-allocated type ordinal, less than
  264. * <code>TypeDesc.ordT</code>.
  265. * @param out The data stream to which the symbol file is being written.
  266. * @param ty The <code>TypeDesc</code> whose type ordinal is required.
  267. * @throws IOException
  268. */
  269. static void writeTypeOrd(DataOutputStream out,TypeDesc ty)throws IOException {
  270. if (ty.typeOrd < TypeDesc.ordT) {
  271. // ==> ty is a builtin type.
  272. out.writeByte(ty.typeOrd);
  273. } else {
  274. if (ty.outTypeNum == 0) {
  275. // ==> ty is a class type.
  276. AddTypeToTypeList(ty); // blame ty
  277. }
  278. if (ty.outTypeNum == 0) {
  279. System.out.println("ERROR: type has number 0 for type " + ty.name);
  280. System.exit(1);
  281. }
  282. writeOrd(out,ty.outTypeNum);
  283. }
  284. }
  285. public static void WriteFormalType(MethodInfo m,DataOutputStream out)
  286. throws IOException {
  287. if ((m.retType != null) && (m.retType.typeOrd != 0)) {
  288. out.writeByte(retSy);
  289. writeTypeOrd(out,m.retType);
  290. }
  291. out.writeByte(frmSy);
  292. for (TypeDesc parType : m.parTypes) {
  293. out.writeByte(parSy);
  294. if (parType instanceof ArrayDesc) {
  295. out.writeByte(1); // array params are IN
  296. } else {
  297. out.writeByte(0); // all other java parameters are value
  298. }
  299. writeTypeOrd(out, parType);
  300. }
  301. out.writeByte(endFm);
  302. }
  303. public static void WriteSymbolFile(PackageDesc thisPack) throws IOException{
  304. ClearTypeList();
  305. DataOutputStream out = j2cpsfiles.CreateSymFile(thisPack.cpName);
  306. out.writeInt(magic);
  307. out.writeByte(modSy);
  308. writeName(out,0,thisPack.cpName);
  309. writeString(out,thisPack.javaName);
  310. out.writeByte(falSy); /* package is not an interface */
  311. // #############################
  312. imps = thisPack.pkgImports;
  313. target = thisPack;
  314. // #############################
  315. //
  316. // Emit package import list
  317. // Import = impSy Name [String] Key.
  318. // Imports are given an index as they are listed.
  319. //
  320. for (int i=0; i < thisPack.pkgImports.size(); i++) {
  321. out.writeByte(impSy);
  322. PackageDesc imp = (PackageDesc)thisPack.pkgImports.get(i);
  323. // -------------------
  324. if (ClassDesc.VERBOSE)
  325. System.out.printf("import %d %s %d\n",
  326. i,
  327. (imp.javaName == null ? "null" : imp.javaName),
  328. i+1);
  329. // -------------------
  330. imp.impNum = i+1;
  331. writeName(out,0,imp.cpName);
  332. writeString(out,imp.javaName);
  333. out.writeByte(keySy);
  334. out.writeInt(0);
  335. }
  336. for (ClassDesc thisClass : thisPack.myClasses) {
  337. if ((thisClass != null) && ConstantPool.isPublic(thisClass.access)) {
  338. // -------------------
  339. if (ClassDesc.verbose)
  340. System.out.printf("Member class %s\n", thisClass.javaName);
  341. // -------------------
  342. // This class is a class of the package being
  343. // emitted to this symbol file. Details are required.
  344. // -------------------
  345. thisClass.writeDetails = true;
  346. out.writeByte(typSy);
  347. writeName(out,thisClass.access,thisClass.objName);
  348. writeTypeOrd(out,thisClass);
  349. }
  350. }
  351. //
  352. // Write out typelist
  353. //
  354. out.writeByte(start);
  355. for (int i=0; i < tListIx; i++) {
  356. TypeDesc desc = typeList[i];
  357. // -------------------
  358. if (ClassDesc.VERBOSE)
  359. System.out.printf("typeList element %d (of %d) %s %d\n",
  360. i, tListIx,
  361. (desc.name == null ? "null" : desc.name),
  362. desc.outTypeNum);
  363. // -------------------
  364. out.writeByte(tDefS);
  365. writeOrd(out,desc.outTypeNum);
  366. desc.writeType(out, thisPack);
  367. }
  368. out.writeByte(close);
  369. out.writeByte(keySy);
  370. out.writeInt(0);
  371. thisPack.ResetImports();
  372. }
  373. //
  374. // Symbol file reading
  375. //
  376. private static void InsertType(int tNum,TypeDesc ty) {
  377. if (tNum >= typeList.length) {
  378. int newLen = 2 * typeList.length;
  379. while (tNum >= newLen) { newLen += typeList.length; }
  380. TypeDesc[] tmp = new TypeDesc[newLen];
  381. System.arraycopy(typeList, 0, tmp, 0, typeList.length);
  382. typeList = tmp;
  383. }
  384. typeList[tNum] = ty;
  385. }
  386. private static int readOrd() throws IOException {
  387. int b1 = in.readUnsignedByte();
  388. if (b1 <= 0x7f) { return b1; }
  389. else { int b2 = in.readByte();
  390. return b1 - 128 + b2 * 128; }
  391. }
  392. private static void GetSym() throws IOException {
  393. sSym = in.readByte();
  394. switch (sSym) {
  395. case namSy : acc = in.readByte(); // fall through
  396. case strSy : name = in.readUTF(); break;
  397. case arrSy :
  398. case ptrSy :
  399. case retSy :
  400. case fromS :
  401. case tDefS :
  402. case basSy : tOrd = readOrd(); break;
  403. case bytSy : iVal = in.readByte(); break;
  404. case keySy :
  405. case setSy : iVal = in.readInt(); break;
  406. case numSy : lVal = in.readLong(); break;
  407. case fltSy : dVal = in.readDouble(); break;
  408. case chrSy : cVal = in.readChar(); break;
  409. case modSy :
  410. case impSy :
  411. case conSy :
  412. case varSy :
  413. case typSy :
  414. case prcSy :
  415. case mthSy :
  416. case parSy :
  417. case start :
  418. case close :
  419. case falSy :
  420. case truSy :
  421. case frmSy :
  422. case endFm :
  423. case recSy :
  424. case endRc :
  425. case endAr :
  426. case eTpSy :
  427. case iFcSy :
  428. case evtSy :
  429. case pTpSy : break;
  430. default: char ch = (char) sSym;
  431. System.out.println("Bad symbol file format." +ch+" "+sSym);
  432. System.exit(1);
  433. }
  434. }
  435. private static void Expect(int expSym) throws IOException {
  436. if (expSym != sSym) {
  437. System.out.println("Error in symbol file: expecting " +
  438. String.valueOf((char) expSym) + " got " +
  439. String.valueOf((char) sSym));
  440. System.exit(1);
  441. }
  442. GetSym();
  443. }
  444. private static void Check(int expSym) {
  445. if (expSym != sSym) {
  446. System.out.println("Error in symbol file: checking " +
  447. String.valueOf((char) expSym) + " got " +
  448. String.valueOf((char) sSym));
  449. System.exit(1);
  450. }
  451. }
  452. private static void SkipToEndRec(DataInputStream in) throws IOException {
  453. while (sSym != endRc) {
  454. switch (sSym) {
  455. case mthSy:
  456. GetSym(); // name
  457. in.readByte();
  458. in.readByte();
  459. readOrd();
  460. break;
  461. case varSy:
  462. GetSym(); // name
  463. readOrd();
  464. break;
  465. case conSy:
  466. GetSym(); // name
  467. GetSym(); // Literal
  468. break;
  469. case prcSy:
  470. GetSym(); // name
  471. break;
  472. case parSy:
  473. in.readByte();
  474. readOrd();
  475. break;
  476. case namSy:
  477. readOrd();
  478. break;
  479. default:
  480. break;
  481. }
  482. GetSym();
  483. }
  484. }
  485. private static int GetAccess() {
  486. switch (acc) {
  487. case prvMode:
  488. return ConstantPool.ACC_PRIVATE;
  489. case pubMode:
  490. return ConstantPool.ACC_PUBLIC;
  491. case protect:
  492. return ConstantPool.ACC_PROTECTED;
  493. default:
  494. break;
  495. }
  496. return 0;
  497. }
  498. private static ClassDesc GetClassDesc(PackageDesc thisPack,String className) {
  499. ClassDesc aClass = ClassDesc.GetClassDesc(thisPack.name + Util.FWDSLSH +
  500. className,thisPack);
  501. if (aClass.fieldList == null){ aClass.fieldList = new ArrayList<>(); }
  502. if (aClass.methodList == null){ aClass.methodList = new ArrayList<>(); }
  503. return aClass;
  504. }
  505. private static void GetConstant(ClassDesc cClass) throws IOException {
  506. // Constant = conSy Name Literal.
  507. // Literal = Number | String | Set | Char | Real | falSy | truSy.
  508. TypeDesc typ = null;
  509. Object val = null;
  510. Expect(conSy);
  511. String constName = name;
  512. int fAcc = GetAccess();
  513. fAcc = fAcc + ConstantPool.ACC_STATIC + ConstantPool.ACC_FINAL;
  514. Expect(namSy);
  515. switch (sSym) {
  516. case numSy : typ = TypeDesc.GetBasicType(TypeDesc.longT);
  517. val = lVal; break;
  518. case strSy : typ = TypeDesc.GetBasicType(TypeDesc.strT);
  519. val = name; break;
  520. case setSy : typ = TypeDesc.GetBasicType(TypeDesc.setT);
  521. val = iVal; break;
  522. case chrSy : typ = TypeDesc.GetBasicType(TypeDesc.charT);
  523. val = cVal; break;
  524. case fltSy : typ = TypeDesc.GetBasicType(TypeDesc.dbleT);
  525. val = dVal; break;
  526. case falSy : typ = TypeDesc.GetBasicType(TypeDesc.boolT);
  527. val = false; break;
  528. case truSy : typ = TypeDesc.GetBasicType(TypeDesc.boolT);
  529. val = true; break;
  530. }
  531. boolean ok = cClass.fieldList.add(new FieldInfo(cClass,fAcc,constName,typ,val));
  532. GetSym();
  533. }
  534. private static void GetVar(ClassDesc vClass) throws IOException {
  535. // Variable = varSy Name TypeOrd.
  536. Expect(varSy);
  537. String varName = name;
  538. int fAcc = GetAccess();
  539. Check(namSy);
  540. FieldInfo f = new FieldInfo(vClass,fAcc,varName,null,null);
  541. f.typeFixUp = readOrd();
  542. vClass.fieldList.add(f);
  543. GetSym();
  544. }
  545. private static void GetType(PackageDesc thisPack) throws IOException {
  546. // Type = typSy Name TypeOrd.
  547. Expect(typSy);
  548. ClassDesc thisClass = GetClassDesc(thisPack,name);
  549. thisClass.access = GetAccess();
  550. Check(namSy);
  551. int tNum = readOrd();
  552. thisClass.inTypeNum = tNum;
  553. InsertType(tNum,thisClass);
  554. GetSym();
  555. }
  556. private static void GetFormalType(ClassDesc thisClass,MethodInfo thisMethod)
  557. throws IOException {
  558. // FormalType = [retSy TypeOrd] frmSy {parSy Byte TypeOrd} endFm.
  559. int [] pars = new int[20];
  560. int numPars = 0;
  561. TypeDesc retType = TypeDesc.GetBasicType(TypeDesc.noTyp);
  562. if (sSym == retSy) { thisMethod.retTypeFixUp = tOrd; GetSym();}
  563. Expect(frmSy);
  564. while (sSym != endFm) {
  565. Check(parSy);
  566. in.readByte(); /* ignore par mode */
  567. pars[numPars++] = readOrd();
  568. GetSym();
  569. }
  570. Expect(endFm);
  571. thisMethod.parFixUps = new int[numPars];
  572. System.arraycopy(pars, 0, thisMethod.parFixUps, 0, numPars);
  573. }
  574. private static void GetMethod(ClassDesc thisClass) throws IOException {
  575. // Method = mthSy Name Byte Byte TypeOrd [String] FormalType.
  576. String jName = null;
  577. Expect(mthSy);
  578. Check(namSy);
  579. String nam = name;
  580. int pAcc = GetAccess();
  581. int attr = in.readByte();
  582. int recMode = in.readByte();
  583. int cNum = readOrd();
  584. if (cNum != thisClass.inTypeNum) {
  585. System.err.println("Method not part of THIS class!");
  586. System.exit(1);
  587. }
  588. GetSym();
  589. if (sSym == strSy) { jName = name; GetSym(); }
  590. MethodInfo m = new MethodInfo(thisClass,nam,jName,pAcc);
  591. switch (attr) {
  592. case 1 : if (!m.isInitProc) {
  593. m.accessFlags += ConstantPool.ACC_FINAL;
  594. }
  595. break;
  596. case 2 : m.overridding = true;
  597. m.accessFlags += (ConstantPool.ACC_ABSTRACT +
  598. ConstantPool.ACC_FINAL);
  599. break;
  600. case 3 : m.accessFlags += (ConstantPool.ACC_ABSTRACT +
  601. ConstantPool.ACC_FINAL);
  602. break;
  603. case 6 : m.overridding = true;
  604. break;
  605. case 7 : break;
  606. }
  607. GetFormalType(thisClass,m);
  608. thisClass.methodList.add(m);
  609. thisClass.scope.put(m.name,m);
  610. }
  611. private static void GetProc(ClassDesc pClass) throws IOException {
  612. // Proc = prcSy Name [String] [truSy] FormalType.
  613. String jName = null;
  614. Expect(prcSy);
  615. String procName = name;
  616. int pAcc = GetAccess();
  617. pAcc = pAcc + ConstantPool.ACC_STATIC;
  618. Expect(namSy);
  619. if (sSym == strSy) { jName = name; GetSym(); }
  620. MethodInfo m = new MethodInfo(pClass,procName,jName,pAcc);
  621. if (sSym == truSy) {
  622. m.isInitProc = true; GetSym();
  623. }
  624. GetFormalType(pClass,m);
  625. pClass.methodList.add(m);
  626. }
  627. private static void ClearTypeList() {
  628. for (int i=0; i < typeList.length; i++) {
  629. if (typeList[i] != null) {
  630. if (typeList[i].typeOrd >= TypeDesc.specT) {
  631. typeList[i].inTypeNum = 0;
  632. typeList[i].outTypeNum = 0;
  633. }
  634. if (typeList[i] instanceof ClassDesc) {
  635. ((ClassDesc)typeList[i]).inBaseTypeNum = 0;
  636. ((ClassDesc)typeList[i]).outBaseTypeNum = 0;
  637. ((ClassDesc)typeList[i]).writeDetails = false;
  638. } else if (typeList[i] instanceof ArrayDesc) {
  639. ((ArrayDesc)typeList[i]).elemTypeFixUp = 0;
  640. }
  641. }
  642. typeList[i] = null;
  643. }
  644. tListIx = 0;
  645. nextType = TypeDesc.ordT;
  646. }
  647. private static void FixArrayElemType(ArrayDesc arr) {
  648. if (arr.elemTypeFixUp == 0) { return; }
  649. TypeDesc elem = GetFixUpType(arr.elemTypeFixUp);
  650. if (elem instanceof ArrayDesc) {
  651. FixArrayElemType((ArrayDesc)elem);
  652. arr.dim = ((ArrayDesc)elem).dim + 1;
  653. arr.ultimateElemType = ((ArrayDesc)elem).ultimateElemType;
  654. } else {
  655. arr.ultimateElemType = elem;
  656. }
  657. arr.elemType = elem;
  658. }
  659. private static TypeDesc GetFixUpType (int num) {
  660. if (num < TypeDesc.specT) { return TypeDesc.GetBasicType(num); }
  661. if (typeList[num] instanceof PtrDesc) {
  662. return ((PtrDesc)typeList[num]).boundType;
  663. }
  664. return typeList[num];
  665. }
  666. public static void ReadSymbolFile(File symFile, PackageDesc thisPack)
  667. throws FileNotFoundException, IOException {
  668. if (ClassDesc.verbose) {
  669. System.out.println("INFO: Reading symbol file " + symFile.getName());
  670. }
  671. ClearTypeList();
  672. ClassDesc aClass, impClass;
  673. int maxInNum = 0;
  674. //
  675. // Read the symbol file and create descriptors
  676. //
  677. try (FileInputStream fIn = new FileInputStream(symFile)) {
  678. in = new DataInputStream(fIn);
  679. if (in.readInt() != magic) {
  680. System.out.println(symFile.getName() + " is not a valid symbol file.");
  681. System.exit(1);
  682. }
  683. GetSym();
  684. Expect(modSy);
  685. if (!thisPack.cpName.equals(name)) {
  686. System.out.println("ERROR: Symbol file " + symFile.getName()
  687. + " does not contain MODULE " + thisPack.cpName + ", it contains MODULE "
  688. + name);
  689. System.exit(1);
  690. }
  691. Expect(namSy);
  692. if (sSym == strSy) {
  693. if (!name.equals(thisPack.javaName)) {
  694. System.out.println("Wrong name in symbol file.");
  695. System.exit(1);
  696. }
  697. GetSym();
  698. if (sSym == truSy) {
  699. System.out.println("ERROR: Java Package cannot be an interface.");
  700. System.exit(1);
  701. }
  702. GetSym();
  703. } else {
  704. System.err.println("<" + symFile.getName()
  705. + "> NOT A SYMBOL FILE FOR A JAVA PACKAGE!");
  706. System.exit(1);
  707. }
  708. while (sSym != start) {
  709. switch (sSym) {
  710. case impSy:
  711. GetSym(); // name
  712. String iName = name;
  713. GetSym();
  714. if (sSym == strSy) {
  715. PackageDesc pack = PackageDesc.getPackage(name);
  716. thisPack.pkgImports.add(pack);
  717. GetSym();
  718. }
  719. Expect(keySy);
  720. break;
  721. case conSy:
  722. case varSy:
  723. case prcSy:
  724. System.out.println("Symbol File is not from a java class");
  725. System.exit(1);
  726. break;
  727. case typSy:
  728. GetType(thisPack);
  729. break;
  730. }
  731. }
  732. Expect(start);
  733. while (sSym != close) {
  734. PackageDesc impPack;
  735. impClass = null;
  736. String impModName = null;
  737. int impAcc = 0,
  738. impModAcc = 0;
  739. Check(tDefS);
  740. int tNum = tOrd;
  741. GetSym();
  742. if (tNum > maxInNum) {
  743. maxInNum = tNum;
  744. }
  745. if (sSym == fromS) {
  746. int impNum = tOrd - 1;
  747. GetSym();
  748. Check(namSy);
  749. String impName = name;
  750. impAcc = acc;
  751. if (impNum < 0) {
  752. impPack = thisPack;
  753. } else {
  754. impPack = (PackageDesc) thisPack.pkgImports.get(impNum);
  755. }
  756. impClass = GetClassDesc(impPack, impName);
  757. GetSym();
  758. }
  759. switch (sSym) {
  760. case arrSy:
  761. ArrayDesc newArr;
  762. int elemOrd = tOrd;
  763. GetSym();
  764. Expect(endAr);
  765. TypeDesc eTy = null;
  766. if (elemOrd < typeList.length) {
  767. if (elemOrd < TypeDesc.specT) {
  768. eTy = TypeDesc.GetBasicType(elemOrd);
  769. } else {
  770. eTy = typeList[elemOrd];
  771. }
  772. if ((eTy != null) && (eTy instanceof PtrDesc)
  773. && (((PtrDesc) eTy).boundType != null)
  774. && (((PtrDesc) eTy).boundType instanceof ClassDesc)) {
  775. eTy = ((PtrDesc) eTy).boundType;
  776. }
  777. }
  778. if (eTy != null) {
  779. newArr = ArrayDesc.FindOrCreateArrayType(1, eTy, true);
  780. } else {
  781. newArr = new ArrayDesc(elemOrd);
  782. }
  783. if ((tNum < typeList.length) && (typeList[tNum] != null)) {
  784. PtrDesc desc = (PtrDesc) typeList[tNum];
  785. if (desc.inBaseTypeNum != tNum) {
  786. System.out.println("WRONG BASE TYPE FOR POINTER!");
  787. System.exit(1);
  788. }
  789. desc.Init(newArr);
  790. newArr.SetPtrType(desc);
  791. }
  792. InsertType(tNum, newArr);
  793. break;
  794. case ptrSy:
  795. TypeDesc ty;
  796. if (impClass != null) {
  797. InsertType(tNum, impClass);
  798. ty = impClass;
  799. ty.inTypeNum = tNum;
  800. ty.inBaseTypeNum = tOrd;
  801. InsertType(tOrd, ty);
  802. } else if ((tNum < typeList.length)
  803. && (typeList[tNum] != null)
  804. && (typeList[tNum] instanceof ClassDesc)) {
  805. ty = typeList[tNum];
  806. ty.inTypeNum = tNum;
  807. ty.inBaseTypeNum = tOrd;
  808. InsertType(tOrd, ty);
  809. } else {
  810. ty = new PtrDesc(tNum, tOrd);
  811. InsertType(tNum, ty);
  812. if ((tOrd < typeList.length)
  813. && (typeList[tOrd] != null)) {
  814. ((PtrDesc) ty).Init(typeList[tOrd]);
  815. }
  816. }
  817. GetSym();
  818. break;
  819. case recSy:
  820. if ((tNum >= typeList.length)
  821. || (typeList[tNum] == null)
  822. || (!(typeList[tNum] instanceof ClassDesc))) {
  823. /* cannot have record type that is not a base type
  824. of a pointer in a java file */
  825. System.err.println(
  826. "RECORD TYPE " + tNum + " IS NOT POINTER BASE TYPE!");
  827. System.exit(1);
  828. }
  829. aClass = (ClassDesc) typeList[tNum];
  830. acc = in.readByte();
  831. aClass.setRecAtt(acc);
  832. if (aClass.read) {
  833. GetSym();
  834. SkipToEndRec(in);
  835. GetSym();
  836. } else {
  837. GetSym();
  838. if (sSym == truSy) {
  839. aClass.isInterface = true;
  840. GetSym();
  841. } else if (sSym == falSy) {
  842. GetSym();
  843. }
  844. if (sSym == basSy) {
  845. aClass.superNum = tOrd;
  846. GetSym();
  847. }
  848. if (sSym == iFcSy) {
  849. GetSym();
  850. aClass.intNums = new int[10];
  851. aClass.numInts = 0;
  852. while (sSym == basSy) {
  853. if (aClass.numInts >= aClass.intNums.length) {
  854. int tmp[] = new int[aClass.intNums.length * 2];
  855. System.arraycopy(aClass.intNums, 0, tmp, 0, aClass.intNums.length);
  856. aClass.intNums = tmp;
  857. }
  858. aClass.intNums[aClass.numInts] = tOrd;
  859. aClass.numInts++;
  860. GetSym();
  861. }
  862. }
  863. while (sSym == namSy) {
  864. FieldInfo f = new FieldInfo(aClass, GetAccess(), name,
  865. null, null);
  866. f.typeFixUp = readOrd();
  867. GetSym();
  868. boolean ok = aClass.fieldList.add(f);
  869. aClass.scope.put(f.name, f);
  870. }
  871. while ((sSym == mthSy) || (sSym == prcSy)
  872. || (sSym == varSy) || (sSym == conSy)) {
  873. switch (sSym) {
  874. case mthSy:
  875. GetMethod(aClass);
  876. break;
  877. case prcSy:
  878. GetProc(aClass);
  879. break;
  880. case varSy:
  881. GetVar(aClass);
  882. break;
  883. case conSy:
  884. GetConstant(aClass);
  885. break;
  886. }
  887. }
  888. Expect(endRc);
  889. }
  890. break;
  891. case pTpSy:
  892. System.out.println("CANNOT HAVE PROC TYPE IN JAVA FILE!");
  893. break;
  894. case evtSy:
  895. System.out.println("CANNOT HAVE EVENT TYPE IN JAVA FILE!");
  896. break;
  897. case eTpSy:
  898. System.out.println("CANNOT HAVE ENUM TYPE IN JAVA FILE!");
  899. break;
  900. case tDefS:
  901. case close:
  902. InsertType(tNum, impClass);
  903. break;
  904. default:
  905. char ch = (char) sSym;
  906. System.out.println("UNRECOGNISED TYPE!" + sSym + " " + ch);
  907. System.exit(1);
  908. }
  909. }
  910. Expect(close);
  911. Check(keySy);
  912. }
  913. //
  914. // Now do the type fixups
  915. //
  916. for (int i = TypeDesc.specT; i <= maxInNum; i++) {
  917. if ((typeList[i] != null) && (typeList[i] instanceof ClassDesc)) {
  918. if (!((ClassDesc) typeList[i]).read) {
  919. aClass = (ClassDesc) typeList[i];
  920. if (aClass.superNum != 0) {
  921. aClass.superClass = (ClassDesc) typeList[aClass.superNum];
  922. }
  923. aClass.interfaces = new ClassDesc[aClass.numInts];
  924. for (int j = 0; j < aClass.numInts; j++) {
  925. aClass.interfaces[j] = (ClassDesc) GetFixUpType(aClass.intNums[j]);
  926. }
  927. int size;
  928. if (aClass.fieldList == null) {
  929. size = 0;
  930. } else {
  931. size = aClass.fieldList.size();
  932. }
  933. //aClass.fields = new FieldInfo[size];
  934. for (int j = 0; j < size; j++) {
  935. FieldInfo fieldJ = (FieldInfo) aClass.fieldList.get(j);
  936. //aClass.fields[j] = fieldJ;
  937. fieldJ.type = GetFixUpType(fieldJ.typeFixUp);
  938. if (fieldJ.type instanceof ClassDesc) { // FIXME And is public?
  939. aClass.AddImportToClass((ClassDesc) fieldJ.type);
  940. }
  941. }
  942. aClass.fieldList = null;
  943. if (aClass.methodList == null) {
  944. size = 0;
  945. } else {
  946. size = aClass.methodList.size();
  947. }
  948. //aClass.methods = new MethodInfo[size];
  949. for (int k = 0; k < size; k++) {
  950. MethodInfo methodK = (MethodInfo) aClass.methodList.get(k);
  951. //aClass.methods[k] = methodK;
  952. methodK.retType = GetFixUpType(methodK.retTypeFixUp);
  953. if (methodK.retType instanceof ClassDesc) {
  954. aClass.AddImportToClass((ClassDesc) methodK.retType);
  955. }
  956. methodK.parTypes = new TypeDesc[methodK.parFixUps.length];
  957. for (int j = 0; j < methodK.parFixUps.length; j++) {
  958. methodK.parTypes[j] = GetFixUpType(methodK.parFixUps[j]);
  959. if (methodK.parTypes[j] instanceof ClassDesc) {
  960. aClass.AddImportToClass((ClassDesc) methodK.parTypes[j]);
  961. }
  962. }
  963. }
  964. aClass.methodList = null;
  965. aClass.read = true;
  966. aClass.done = true;
  967. }
  968. } else if ((typeList[i] != null) && (typeList[i] instanceof ArrayDesc)) {
  969. FixArrayElemType((ArrayDesc) typeList[i]);
  970. } else if ((typeList[i] != null) && (typeList[i] instanceof PtrDesc)) {
  971. PtrDesc ptr = (PtrDesc) typeList[i];
  972. if (ptr.typeOrd == TypeDesc.arrPtr) {
  973. ptr.Init(typeList[ptr.inBaseTypeNum]);
  974. }
  975. } else if (typeList[i] != null) {
  976. System.out.println("Type " + i + " " + typeList[i].name
  977. + " is NOT array or class");
  978. System.exit(0);
  979. }
  980. }
  981. }
  982. }