2
0

SymbolFile.java 32 KB

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