You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConstPool.java 68KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later,
  9. * or the Apache License Version 2.0.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. */
  16. package javassist.bytecode;
  17. import java.io.ByteArrayOutputStream;
  18. import java.io.DataInputStream;
  19. import java.io.DataOutputStream;
  20. import java.io.IOException;
  21. import java.io.PrintWriter;
  22. import java.util.HashMap;
  23. import java.util.HashSet;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import javassist.CtClass;
  27. /**
  28. * Constant pool table.
  29. */
  30. public final class ConstPool
  31. {
  32. LongVector items;
  33. int numOfItems;
  34. int thisClassInfo;
  35. Map<ConstInfo,ConstInfo> itemsCache;
  36. /**
  37. * <code>CONSTANT_Class</code>
  38. */
  39. public static final int CONST_Class = ClassInfo.tag;
  40. /**
  41. * <code>CONSTANT_Fieldref</code>
  42. */
  43. public static final int CONST_Fieldref = FieldrefInfo.tag;
  44. /**
  45. * <code>CONSTANT_Methodref</code>
  46. */
  47. public static final int CONST_Methodref = MethodrefInfo.tag;
  48. /**
  49. * <code>CONSTANT_InterfaceMethodref</code>
  50. */
  51. public static final int CONST_InterfaceMethodref
  52. = InterfaceMethodrefInfo.tag;
  53. /**
  54. * <code>CONSTANT_String</code>
  55. */
  56. public static final int CONST_String = StringInfo.tag;
  57. /**
  58. * <code>CONSTANT_Integer</code>
  59. */
  60. public static final int CONST_Integer = IntegerInfo.tag;
  61. /**
  62. * <code>CONSTANT_Float</code>
  63. */
  64. public static final int CONST_Float = FloatInfo.tag;
  65. /**
  66. * <code>CONSTANT_Long</code>
  67. */
  68. public static final int CONST_Long = LongInfo.tag;
  69. /**
  70. * <code>CONSTANT_Double</code>
  71. */
  72. public static final int CONST_Double = DoubleInfo.tag;
  73. /**
  74. * <code>CONSTANT_NameAndType</code>
  75. */
  76. public static final int CONST_NameAndType = NameAndTypeInfo.tag;
  77. /**
  78. * <code>CONSTANT_Utf8</code>
  79. */
  80. public static final int CONST_Utf8 = Utf8Info.tag;
  81. /**
  82. * <code>CONSTANT_MethodHandle</code>
  83. */
  84. public static final int CONST_MethodHandle = MethodHandleInfo.tag;
  85. /**
  86. * <code>CONSTANT_MethodHandle</code>
  87. */
  88. public static final int CONST_MethodType = MethodTypeInfo.tag;
  89. /**
  90. * <code>CONSTANT_MethodHandle</code>
  91. */
  92. public static final int CONST_InvokeDynamic = InvokeDynamicInfo.tag;
  93. /**
  94. * <code>CONSTANT_Module</code>
  95. */
  96. public static final int CONST_Module = ModuleInfo.tag;
  97. /**
  98. * <code>CONSTANT_Package</code>
  99. */
  100. public static final int CONST_Package = PackageInfo.tag;
  101. /**
  102. * Represents the class using this constant pool table.
  103. */
  104. public static final CtClass THIS = null;
  105. /**
  106. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  107. */
  108. public static final int REF_getField = 1;
  109. /**
  110. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  111. */
  112. public static final int REF_getStatic = 2;
  113. /**
  114. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  115. */
  116. public static final int REF_putField = 3;
  117. /**
  118. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  119. */
  120. public static final int REF_putStatic = 4;
  121. /**
  122. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  123. */
  124. public static final int REF_invokeVirtual = 5;
  125. /**
  126. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  127. */
  128. public static final int REF_invokeStatic = 6;
  129. /**
  130. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  131. */
  132. public static final int REF_invokeSpecial = 7;
  133. /**
  134. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  135. */
  136. public static final int REF_newInvokeSpecial = 8;
  137. /**
  138. * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>.
  139. */
  140. public static final int REF_invokeInterface = 9;
  141. /**
  142. * Constructs a constant pool table.
  143. *
  144. * @param thisclass the name of the class using this constant
  145. * pool table
  146. */
  147. public ConstPool(String thisclass)
  148. {
  149. items = new LongVector();
  150. itemsCache = null;
  151. numOfItems = 0;
  152. addItem0(null); // index 0 is reserved by the JVM.
  153. thisClassInfo = addClassInfo(thisclass);
  154. }
  155. /**
  156. * Constructs a constant pool table from the given byte stream.
  157. *
  158. * @param in byte stream.
  159. */
  160. public ConstPool(DataInputStream in) throws IOException
  161. {
  162. itemsCache = null;
  163. thisClassInfo = 0;
  164. /* read() initializes items and numOfItems, and do addItem(null).
  165. */
  166. read(in);
  167. }
  168. void prune()
  169. {
  170. itemsCache = null;
  171. }
  172. /**
  173. * Returns the number of entries in this table.
  174. */
  175. public int getSize()
  176. {
  177. return numOfItems;
  178. }
  179. /**
  180. * Returns the name of the class using this constant pool table.
  181. */
  182. public String getClassName()
  183. {
  184. return getClassInfo(thisClassInfo);
  185. }
  186. /**
  187. * Returns the index of <code>CONSTANT_Class_info</code> structure
  188. * specifying the class using this constant pool table.
  189. */
  190. public int getThisClassInfo()
  191. {
  192. return thisClassInfo;
  193. }
  194. void setThisClassInfo(int i)
  195. {
  196. thisClassInfo = i;
  197. }
  198. ConstInfo getItem(int n)
  199. {
  200. return items.elementAt(n);
  201. }
  202. /**
  203. * Returns the <code>tag</code> field of the constant pool table
  204. * entry at the given index.
  205. *
  206. * @return either <code>CONST_Class</code>, <code>CONST_Fieldref</code>,
  207. * <code>CONST_Methodref</code>, or ...
  208. */
  209. public int getTag(int index)
  210. {
  211. return getItem(index).getTag();
  212. }
  213. /**
  214. * Reads <code>CONSTANT_Class_info</code> structure
  215. * at the given index.
  216. *
  217. * @return a fully-qualified class or interface name specified
  218. * by <code>name_index</code>. If the type is an array
  219. * type, this method returns an encoded name like
  220. * <code>[Ljava.lang.Object;</code> (note that the separators
  221. * are not slashes but dots).
  222. * @see javassist.ClassPool#getCtClass(String)
  223. */
  224. public String getClassInfo(int index)
  225. {
  226. ClassInfo c = (ClassInfo)getItem(index);
  227. if (c == null)
  228. return null;
  229. return Descriptor.toJavaName(getUtf8Info(c.name));
  230. }
  231. /**
  232. * Reads <code>CONSTANT_Class_info</code> structure
  233. * at the given index.
  234. *
  235. * @return the descriptor of the type specified
  236. * by <code>name_index</code>.
  237. * @see javassist.ClassPool#getCtClass(String)
  238. * @since 3.15
  239. */
  240. public String getClassInfoByDescriptor(int index)
  241. {
  242. ClassInfo c = (ClassInfo)getItem(index);
  243. if (c == null)
  244. return null;
  245. String className = getUtf8Info(c.name);
  246. if (className.charAt(0) == '[')
  247. return className;
  248. return Descriptor.of(className);
  249. }
  250. /**
  251. * Reads the <code>name_index</code> field of the
  252. * <code>CONSTANT_NameAndType_info</code> structure
  253. * at the given index.
  254. */
  255. public int getNameAndTypeName(int index)
  256. {
  257. NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
  258. return ntinfo.memberName;
  259. }
  260. /**
  261. * Reads the <code>descriptor_index</code> field of the
  262. * <code>CONSTANT_NameAndType_info</code> structure
  263. * at the given index.
  264. */
  265. public int getNameAndTypeDescriptor(int index)
  266. {
  267. NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
  268. return ntinfo.typeDescriptor;
  269. }
  270. /**
  271. * Reads the <code>class_index</code> field of the
  272. * <code>CONSTANT_Fieldref_info</code>,
  273. * <code>CONSTANT_Methodref_info</code>,
  274. * or <code>CONSTANT_Interfaceref_info</code>,
  275. * structure at the given index.
  276. *
  277. * @since 3.6
  278. */
  279. public int getMemberClass(int index)
  280. {
  281. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  282. return minfo.classIndex;
  283. }
  284. /**
  285. * Reads the <code>name_and_type_index</code> field of the
  286. * <code>CONSTANT_Fieldref_info</code>,
  287. * <code>CONSTANT_Methodref_info</code>,
  288. * or <code>CONSTANT_Interfaceref_info</code>,
  289. * structure at the given index.
  290. *
  291. * @since 3.6
  292. */
  293. public int getMemberNameAndType(int index)
  294. {
  295. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  296. return minfo.nameAndTypeIndex;
  297. }
  298. /**
  299. * Reads the <code>class_index</code> field of the
  300. * <code>CONSTANT_Fieldref_info</code> structure
  301. * at the given index.
  302. */
  303. public int getFieldrefClass(int index)
  304. {
  305. FieldrefInfo finfo = (FieldrefInfo)getItem(index);
  306. return finfo.classIndex;
  307. }
  308. /**
  309. * Reads the <code>class_index</code> field of the
  310. * <code>CONSTANT_Fieldref_info</code> structure
  311. * at the given index.
  312. *
  313. * @return the name of the class at that <code>class_index</code>.
  314. */
  315. public String getFieldrefClassName(int index)
  316. {
  317. FieldrefInfo f = (FieldrefInfo)getItem(index);
  318. if (f == null)
  319. return null;
  320. return getClassInfo(f.classIndex);
  321. }
  322. /**
  323. * Reads the <code>name_and_type_index</code> field of the
  324. * <code>CONSTANT_Fieldref_info</code> structure
  325. * at the given index.
  326. */
  327. public int getFieldrefNameAndType(int index)
  328. {
  329. FieldrefInfo finfo = (FieldrefInfo)getItem(index);
  330. return finfo.nameAndTypeIndex;
  331. }
  332. /**
  333. * Reads the <code>name_index</code> field of the
  334. * <code>CONSTANT_NameAndType_info</code> structure
  335. * indirectly specified by the given index.
  336. *
  337. * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
  338. * @return the name of the field.
  339. */
  340. public String getFieldrefName(int index)
  341. {
  342. FieldrefInfo f = (FieldrefInfo)getItem(index);
  343. if (f == null)
  344. return null;
  345. NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex);
  346. if(n == null)
  347. return null;
  348. return getUtf8Info(n.memberName);
  349. }
  350. /**
  351. * Reads the <code>descriptor_index</code> field of the
  352. * <code>CONSTANT_NameAndType_info</code> structure
  353. * indirectly specified by the given index.
  354. *
  355. * @param index an index to a <code>CONSTANT_Fieldref_info</code>.
  356. * @return the type descriptor of the field.
  357. */
  358. public String getFieldrefType(int index)
  359. {
  360. FieldrefInfo f = (FieldrefInfo)getItem(index);
  361. if (f == null)
  362. return null;
  363. NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex);
  364. if(n == null)
  365. return null;
  366. return getUtf8Info(n.typeDescriptor);
  367. }
  368. /**
  369. * Reads the <code>class_index</code> field of the
  370. * <code>CONSTANT_Methodref_info</code> structure
  371. * at the given index.
  372. */
  373. public int getMethodrefClass(int index)
  374. {
  375. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  376. return minfo.classIndex;
  377. }
  378. /**
  379. * Reads the <code>class_index</code> field of the
  380. * <code>CONSTANT_Methodref_info</code> structure
  381. * at the given index.
  382. *
  383. * @return the name of the class at that <code>class_index</code>.
  384. */
  385. public String getMethodrefClassName(int index)
  386. {
  387. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  388. if (minfo == null)
  389. return null;
  390. return getClassInfo(minfo.classIndex);
  391. }
  392. /**
  393. * Reads the <code>name_and_type_index</code> field of the
  394. * <code>CONSTANT_Methodref_info</code> structure
  395. * at the given index.
  396. */
  397. public int getMethodrefNameAndType(int index)
  398. {
  399. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  400. return minfo.nameAndTypeIndex;
  401. }
  402. /**
  403. * Reads the <code>name_index</code> field of the
  404. * <code>CONSTANT_NameAndType_info</code> structure
  405. * indirectly specified by the given index.
  406. *
  407. * @param index an index to a <code>CONSTANT_Methodref_info</code>.
  408. * @return the name of the method.
  409. */
  410. public String getMethodrefName(int index)
  411. {
  412. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  413. if (minfo == null)
  414. return null;
  415. NameAndTypeInfo n
  416. = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
  417. if(n == null)
  418. return null;
  419. return getUtf8Info(n.memberName);
  420. }
  421. /**
  422. * Reads the <code>descriptor_index</code> field of the
  423. * <code>CONSTANT_NameAndType_info</code> structure
  424. * indirectly specified by the given index.
  425. *
  426. * @param index an index to a <code>CONSTANT_Methodref_info</code>.
  427. * @return the descriptor of the method.
  428. */
  429. public String getMethodrefType(int index)
  430. {
  431. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  432. if (minfo == null)
  433. return null;
  434. NameAndTypeInfo n
  435. = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
  436. if(n == null)
  437. return null;
  438. return getUtf8Info(n.typeDescriptor);
  439. }
  440. /**
  441. * Reads the <code>class_index</code> field of the
  442. * <code>CONSTANT_InterfaceMethodref_info</code> structure
  443. * at the given index.
  444. */
  445. public int getInterfaceMethodrefClass(int index)
  446. {
  447. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  448. return minfo.classIndex;
  449. }
  450. /**
  451. * Reads the <code>class_index</code> field of the
  452. * <code>CONSTANT_InterfaceMethodref_info</code> structure
  453. * at the given index.
  454. *
  455. * @return the name of the class at that <code>class_index</code>.
  456. */
  457. public String getInterfaceMethodrefClassName(int index)
  458. {
  459. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  460. return getClassInfo(minfo.classIndex);
  461. }
  462. /**
  463. * Reads the <code>name_and_type_index</code> field of the
  464. * <code>CONSTANT_InterfaceMethodref_info</code> structure
  465. * at the given index.
  466. */
  467. public int getInterfaceMethodrefNameAndType(int index)
  468. {
  469. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  470. return minfo.nameAndTypeIndex;
  471. }
  472. /**
  473. * Reads the <code>name_index</code> field of the
  474. * <code>CONSTANT_NameAndType_info</code> structure
  475. * indirectly specified by the given index.
  476. *
  477. * @param index an index to
  478. * a <code>CONSTANT_InterfaceMethodref_info</code>.
  479. * @return the name of the method.
  480. */
  481. public String getInterfaceMethodrefName(int index)
  482. {
  483. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  484. if (minfo == null)
  485. return null;
  486. NameAndTypeInfo n
  487. = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
  488. if(n == null)
  489. return null;
  490. return getUtf8Info(n.memberName);
  491. }
  492. /**
  493. * Reads the <code>descriptor_index</code> field of the
  494. * <code>CONSTANT_NameAndType_info</code> structure
  495. * indirectly specified by the given index.
  496. *
  497. * @param index an index to
  498. * a <code>CONSTANT_InterfaceMethodref_info</code>.
  499. * @return the descriptor of the method.
  500. */
  501. public String getInterfaceMethodrefType(int index)
  502. {
  503. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  504. if (minfo == null)
  505. return null;
  506. NameAndTypeInfo n
  507. = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
  508. if(n == null)
  509. return null;
  510. return getUtf8Info(n.typeDescriptor);
  511. }
  512. /**
  513. * Reads <code>CONSTANT_Integer_info</code>, <code>_Float_info</code>,
  514. * <code>_Long_info</code>, <code>_Double_info</code>, or
  515. * <code>_String_info</code> structure.
  516. * These are used with the LDC instruction.
  517. *
  518. * @return a <code>String</code> value or a wrapped primitive-type
  519. * value.
  520. */
  521. public Object getLdcValue(int index)
  522. {
  523. ConstInfo constInfo = this.getItem(index);
  524. Object value = null;
  525. if (constInfo instanceof StringInfo)
  526. value = this.getStringInfo(index);
  527. else if (constInfo instanceof FloatInfo)
  528. value = Float.valueOf(getFloatInfo(index));
  529. else if (constInfo instanceof IntegerInfo)
  530. value = Integer.valueOf(getIntegerInfo(index));
  531. else if (constInfo instanceof LongInfo)
  532. value = Long.valueOf(getLongInfo(index));
  533. else if (constInfo instanceof DoubleInfo)
  534. value = Double.valueOf(getDoubleInfo(index));
  535. return value;
  536. }
  537. /**
  538. * Reads <code>CONSTANT_Integer_info</code> structure
  539. * at the given index.
  540. *
  541. * @return the value specified by this entry.
  542. */
  543. public int getIntegerInfo(int index)
  544. {
  545. IntegerInfo i = (IntegerInfo)getItem(index);
  546. return i.value;
  547. }
  548. /**
  549. * Reads <code>CONSTANT_Float_info</code> structure
  550. * at the given index.
  551. *
  552. * @return the value specified by this entry.
  553. */
  554. public float getFloatInfo(int index)
  555. {
  556. FloatInfo i = (FloatInfo)getItem(index);
  557. return i.value;
  558. }
  559. /**
  560. * Reads <code>CONSTANT_Long_info</code> structure
  561. * at the given index.
  562. *
  563. * @return the value specified by this entry.
  564. */
  565. public long getLongInfo(int index)
  566. {
  567. LongInfo i = (LongInfo)getItem(index);
  568. return i.value;
  569. }
  570. /**
  571. * Reads <code>CONSTANT_Double_info</code> structure
  572. * at the given index.
  573. *
  574. * @return the value specified by this entry.
  575. */
  576. public double getDoubleInfo(int index)
  577. {
  578. DoubleInfo i = (DoubleInfo)getItem(index);
  579. return i.value;
  580. }
  581. /**
  582. * Reads <code>CONSTANT_String_info</code> structure
  583. * at the given index.
  584. *
  585. * @return the string specified by <code>string_index</code>.
  586. */
  587. public String getStringInfo(int index)
  588. {
  589. StringInfo si = (StringInfo)getItem(index);
  590. return getUtf8Info(si.string);
  591. }
  592. /**
  593. * Reads <code>CONSTANT_utf8_info</code> structure
  594. * at the given index.
  595. *
  596. * @return the string specified by this entry.
  597. */
  598. public String getUtf8Info(int index)
  599. {
  600. Utf8Info utf = (Utf8Info)getItem(index);
  601. return utf.string;
  602. }
  603. /**
  604. * Reads the <code>reference_kind</code> field of the
  605. * <code>CONSTANT_MethodHandle_info</code> structure
  606. * at the given index.
  607. *
  608. * @see #REF_getField
  609. * @see #REF_getStatic
  610. * @see #REF_invokeInterface
  611. * @see #REF_invokeSpecial
  612. * @see #REF_invokeStatic
  613. * @see #REF_invokeVirtual
  614. * @see #REF_newInvokeSpecial
  615. * @see #REF_putField
  616. * @see #REF_putStatic
  617. * @since 3.17
  618. */
  619. public int getMethodHandleKind(int index)
  620. {
  621. MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index);
  622. return mhinfo.refKind;
  623. }
  624. /**
  625. * Reads the <code>reference_index</code> field of the
  626. * <code>CONSTANT_MethodHandle_info</code> structure
  627. * at the given index.
  628. *
  629. * @since 3.17
  630. */
  631. public int getMethodHandleIndex(int index)
  632. {
  633. MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index);
  634. return mhinfo.refIndex;
  635. }
  636. /**
  637. * Reads the <code>descriptor_index</code> field of the
  638. * <code>CONSTANT_MethodType_info</code> structure
  639. * at the given index.
  640. *
  641. * @since 3.17
  642. */
  643. public int getMethodTypeInfo(int index)
  644. {
  645. MethodTypeInfo mtinfo = (MethodTypeInfo)getItem(index);
  646. return mtinfo.descriptor;
  647. }
  648. /**
  649. * Reads the <code>bootstrap_method_attr_index</code> field of the
  650. * <code>CONSTANT_InvokeDynamic_info</code> structure
  651. * at the given index.
  652. *
  653. * @since 3.17
  654. */
  655. public int getInvokeDynamicBootstrap(int index)
  656. {
  657. InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
  658. return iv.bootstrap;
  659. }
  660. /**
  661. * Reads the <code>name_and_type_index</code> field of the
  662. * <code>CONSTANT_InvokeDynamic_info</code> structure
  663. * at the given index.
  664. *
  665. * @since 3.17
  666. */
  667. public int getInvokeDynamicNameAndType(int index)
  668. {
  669. InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
  670. return iv.nameAndType;
  671. }
  672. /**
  673. * Reads the <code>descriptor_index</code> field of the
  674. * <code>CONSTANT_NameAndType_info</code> structure
  675. * indirectly specified by the given index.
  676. *
  677. * @param index an index to a <code>CONSTANT_InvokeDynamic_info</code>.
  678. * @return the descriptor of the method.
  679. * @since 3.17
  680. */
  681. public String getInvokeDynamicType(int index)
  682. {
  683. InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index);
  684. if (iv == null)
  685. return null;
  686. NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType);
  687. if(n == null)
  688. return null;
  689. return getUtf8Info(n.typeDescriptor);
  690. }
  691. /**
  692. * Reads the <code>bootstrap_method_attr_index</code> field of the
  693. * <code>CONSTANT_Dynamic_info</code> structure
  694. * at the given index.
  695. *
  696. * @since 3.17
  697. */
  698. public int getDynamicBootstrap(int index)
  699. {
  700. DynamicInfo iv = (DynamicInfo)getItem(index);
  701. return iv.bootstrap;
  702. }
  703. /**
  704. * Reads the <code>name_and_type_index</code> field of the
  705. * <code>CONSTANT_Dynamic_info</code> structure
  706. * at the given index.
  707. *
  708. * @since 3.17
  709. */
  710. public int getDynamicNameAndType(int index)
  711. {
  712. DynamicInfo iv = (DynamicInfo)getItem(index);
  713. return iv.nameAndType;
  714. }
  715. /**
  716. * Reads the <code>descriptor_index</code> field of the
  717. * <code>CONSTANT_NameAndType_info</code> structure
  718. * indirectly specified by the given index.
  719. *
  720. * @param index an index to a <code>CONSTANT_Dynamic_info</code>.
  721. * @return the descriptor of the method.
  722. * @since 3.17
  723. */
  724. public String getDynamicType(int index)
  725. {
  726. DynamicInfo iv = (DynamicInfo)getItem(index);
  727. if (iv == null)
  728. return null;
  729. NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType);
  730. if(n == null)
  731. return null;
  732. return getUtf8Info(n.typeDescriptor);
  733. }
  734. /**
  735. * Reads the <code>name_index</code> field of the
  736. * <code>CONSTANT_Module_info</code> structure at the given index.
  737. *
  738. * @return the module name at <code>name_index</code>.
  739. * @since 3.22
  740. */
  741. public String getModuleInfo(int index)
  742. {
  743. ModuleInfo mi = (ModuleInfo)getItem(index);
  744. return getUtf8Info(mi.name);
  745. }
  746. /**
  747. * Reads the <code>name_index</code> field of the
  748. * <code>CONSTANT_Package_info</code> structure at the given index.
  749. *
  750. * @return the package name at <code>name_index</code>. It is a slash-
  751. * separated name such as com/oracle/net.
  752. * @since 3.22
  753. */
  754. public String getPackageInfo(int index)
  755. {
  756. PackageInfo mi = (PackageInfo)getItem(index);
  757. return getUtf8Info(mi.name);
  758. }
  759. /**
  760. * Determines whether <code>CONSTANT_Methodref_info</code>
  761. * structure at the given index represents the constructor
  762. * of the given class.
  763. *
  764. * @return the <code>descriptor_index</code> specifying
  765. * the type descriptor of the that constructor.
  766. * If it is not that constructor,
  767. * <code>isConstructor()</code> returns 0.
  768. */
  769. public int isConstructor(String classname, int index)
  770. {
  771. return isMember(classname, MethodInfo.nameInit, index);
  772. }
  773. /**
  774. * Determines whether <code>CONSTANT_Methodref_info</code>,
  775. * <code>CONSTANT_Fieldref_info</code>, or
  776. * <code>CONSTANT_InterfaceMethodref_info</code> structure
  777. * at the given index represents the member with the specified
  778. * name and declaring class.
  779. *
  780. * @param classname the class declaring the member
  781. * @param membername the member name
  782. * @param index the index into the constant pool table
  783. *
  784. * @return the <code>descriptor_index</code> specifying
  785. * the type descriptor of that member.
  786. * If it is not that member,
  787. * <code>isMember()</code> returns 0.
  788. */
  789. public int isMember(String classname, String membername, int index)
  790. {
  791. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  792. if (getClassInfo(minfo.classIndex).equals(classname)) {
  793. NameAndTypeInfo ntinfo
  794. = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
  795. if (getUtf8Info(ntinfo.memberName).equals(membername))
  796. return ntinfo.typeDescriptor;
  797. }
  798. return 0; // false
  799. }
  800. /**
  801. * Determines whether <code>CONSTANT_Methodref_info</code>,
  802. * <code>CONSTANT_Fieldref_info</code>, or
  803. * <code>CONSTANT_InterfaceMethodref_info</code> structure
  804. * at the given index has the name and the descriptor
  805. * given as the arguments.
  806. *
  807. * @param membername the member name
  808. * @param desc the descriptor of the member.
  809. * @param index the index into the constant pool table
  810. *
  811. * @return the name of the target class specified by
  812. * the <code>..._info</code> structure
  813. * at <code>index</code>.
  814. * Otherwise, null if that structure does not
  815. * match the given member name and descriptor.
  816. */
  817. public String eqMember(String membername, String desc, int index)
  818. {
  819. MemberrefInfo minfo = (MemberrefInfo)getItem(index);
  820. NameAndTypeInfo ntinfo
  821. = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex);
  822. if (getUtf8Info(ntinfo.memberName).equals(membername)
  823. && getUtf8Info(ntinfo.typeDescriptor).equals(desc))
  824. return getClassInfo(minfo.classIndex);
  825. return null; // false
  826. }
  827. private int addItem0(ConstInfo info)
  828. {
  829. items.addElement(info);
  830. return numOfItems++;
  831. }
  832. private int addItem(ConstInfo info)
  833. {
  834. if (itemsCache == null)
  835. itemsCache = makeItemsCache(items);
  836. ConstInfo found = itemsCache.get(info);
  837. if (found != null)
  838. return found.index;
  839. items.addElement(info);
  840. itemsCache.put(info, info);
  841. return numOfItems++;
  842. }
  843. /**
  844. * Copies the n-th item in this ConstPool object into the destination
  845. * ConstPool object.
  846. * The class names that the item refers to are renamed according
  847. * to the given map.
  848. *
  849. * @param n the <i>n</i>-th item
  850. * @param dest destination constant pool table
  851. * @param classnames the map or null.
  852. * @return the index of the copied item into the destination ClassPool.
  853. */
  854. public int copy(int n, ConstPool dest, Map<String,String> classnames)
  855. {
  856. if (n == 0)
  857. return 0;
  858. ConstInfo info = getItem(n);
  859. return info.copy(this, dest, classnames);
  860. }
  861. int addConstInfoPadding() {
  862. return addItem0(new ConstInfoPadding(numOfItems));
  863. }
  864. /**
  865. * Adds a new <code>CONSTANT_Class_info</code> structure.
  866. *
  867. * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure
  868. * for storing the class name.
  869. *
  870. * @return the index of the added entry.
  871. */
  872. public int addClassInfo(CtClass c)
  873. {
  874. if (c == THIS)
  875. return thisClassInfo;
  876. else if (!c.isArray())
  877. return addClassInfo(c.getName());
  878. else {
  879. // an array type is recorded in the hashtable with
  880. // the key "[L<classname>;" instead of "<classname>".
  881. //
  882. // note: toJvmName(toJvmName(c)) is equal to toJvmName(c).
  883. return addClassInfo(Descriptor.toJvmName(c));
  884. }
  885. }
  886. /**
  887. * Adds a new <code>CONSTANT_Class_info</code> structure.
  888. *
  889. * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure
  890. * for storing the class name.
  891. *
  892. * @param qname a fully-qualified class name
  893. * (or the JVM-internal representation of that name).
  894. * @return the index of the added entry.
  895. */
  896. public int addClassInfo(String qname)
  897. {
  898. int utf8 = addUtf8Info(Descriptor.toJvmName(qname));
  899. return addItem(new ClassInfo(utf8, numOfItems));
  900. }
  901. /**
  902. * Adds a new <code>CONSTANT_NameAndType_info</code> structure.
  903. *
  904. * <p>This also adds <code>CONSTANT_Utf8_info</code> structures.
  905. *
  906. * @param name <code>name_index</code>
  907. * @param type <code>descriptor_index</code>
  908. * @return the index of the added entry.
  909. */
  910. public int addNameAndTypeInfo(String name, String type)
  911. {
  912. return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type));
  913. }
  914. /**
  915. * Adds a new <code>CONSTANT_NameAndType_info</code> structure.
  916. *
  917. * @param name <code>name_index</code>
  918. * @param type <code>descriptor_index</code>
  919. * @return the index of the added entry.
  920. */
  921. public int addNameAndTypeInfo(int name, int type)
  922. {
  923. return addItem(new NameAndTypeInfo(name, type, numOfItems));
  924. }
  925. /**
  926. * Adds a new <code>CONSTANT_Fieldref_info</code> structure.
  927. *
  928. * <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
  929. * structure.
  930. *
  931. * @param classInfo <code>class_index</code>
  932. * @param name <code>name_index</code>
  933. * of <code>CONSTANT_NameAndType_info</code>.
  934. * @param type <code>descriptor_index</code>
  935. * of <code>CONSTANT_NameAndType_info</code>.
  936. * @return the index of the added entry.
  937. */
  938. public int addFieldrefInfo(int classInfo, String name, String type)
  939. {
  940. int nt = addNameAndTypeInfo(name, type);
  941. return addFieldrefInfo(classInfo, nt);
  942. }
  943. /**
  944. * Adds a new <code>CONSTANT_Fieldref_info</code> structure.
  945. *
  946. * @param classInfo <code>class_index</code>
  947. * @param nameAndTypeInfo <code>name_and_type_index</code>.
  948. * @return the index of the added entry.
  949. */
  950. public int addFieldrefInfo(int classInfo, int nameAndTypeInfo)
  951. {
  952. return addItem(new FieldrefInfo(classInfo, nameAndTypeInfo,
  953. numOfItems));
  954. }
  955. /**
  956. * Adds a new <code>CONSTANT_Methodref_info</code> structure.
  957. *
  958. * <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
  959. * structure.
  960. *
  961. * @param classInfo <code>class_index</code>
  962. * @param name <code>name_index</code>
  963. * of <code>CONSTANT_NameAndType_info</code>.
  964. * @param type <code>descriptor_index</code>
  965. * of <code>CONSTANT_NameAndType_info</code>.
  966. * @return the index of the added entry.
  967. */
  968. public int addMethodrefInfo(int classInfo, String name, String type)
  969. {
  970. int nt = addNameAndTypeInfo(name, type);
  971. return addMethodrefInfo(classInfo, nt);
  972. }
  973. /**
  974. * Adds a new <code>CONSTANT_Methodref_info</code> structure.
  975. *
  976. * @param classInfo <code>class_index</code>
  977. * @param nameAndTypeInfo <code>name_and_type_index</code>.
  978. * @return the index of the added entry.
  979. */
  980. public int addMethodrefInfo(int classInfo, int nameAndTypeInfo)
  981. {
  982. return addItem(new MethodrefInfo(classInfo,
  983. nameAndTypeInfo, numOfItems));
  984. }
  985. /**
  986. * Adds a new <code>CONSTANT_InterfaceMethodref_info</code>
  987. * structure.
  988. *
  989. * <p>This also adds a new <code>CONSTANT_NameAndType_info</code>
  990. * structure.
  991. *
  992. * @param classInfo <code>class_index</code>
  993. * @param name <code>name_index</code>
  994. * of <code>CONSTANT_NameAndType_info</code>.
  995. * @param type <code>descriptor_index</code>
  996. * of <code>CONSTANT_NameAndType_info</code>.
  997. * @return the index of the added entry.
  998. */
  999. public int addInterfaceMethodrefInfo(int classInfo,
  1000. String name,
  1001. String type)
  1002. {
  1003. int nt = addNameAndTypeInfo(name, type);
  1004. return addInterfaceMethodrefInfo(classInfo, nt);
  1005. }
  1006. /**
  1007. * Adds a new <code>CONSTANT_InterfaceMethodref_info</code>
  1008. * structure.
  1009. *
  1010. * @param classInfo <code>class_index</code>
  1011. * @param nameAndTypeInfo <code>name_and_type_index</code>.
  1012. * @return the index of the added entry.
  1013. */
  1014. public int addInterfaceMethodrefInfo(int classInfo,
  1015. int nameAndTypeInfo)
  1016. {
  1017. return addItem(new InterfaceMethodrefInfo(classInfo,
  1018. nameAndTypeInfo,
  1019. numOfItems));
  1020. }
  1021. /**
  1022. * Adds a new <code>CONSTANT_String_info</code>
  1023. * structure.
  1024. *
  1025. * <p>This also adds a new <code>CONSTANT_Utf8_info</code>
  1026. * structure.
  1027. *
  1028. * @return the index of the added entry.
  1029. */
  1030. public int addStringInfo(String str)
  1031. {
  1032. int utf = addUtf8Info(str);
  1033. return addItem(new StringInfo(utf, numOfItems));
  1034. }
  1035. /**
  1036. * Adds a new <code>CONSTANT_Integer_info</code>
  1037. * structure.
  1038. *
  1039. * @return the index of the added entry.
  1040. */
  1041. public int addIntegerInfo(int i)
  1042. {
  1043. return addItem(new IntegerInfo(i, numOfItems));
  1044. }
  1045. /**
  1046. * Adds a new <code>CONSTANT_Float_info</code>
  1047. * structure.
  1048. *
  1049. * @return the index of the added entry.
  1050. */
  1051. public int addFloatInfo(float f)
  1052. {
  1053. return addItem(new FloatInfo(f, numOfItems));
  1054. }
  1055. /**
  1056. * Adds a new <code>CONSTANT_Long_info</code>
  1057. * structure.
  1058. *
  1059. * @return the index of the added entry.
  1060. */
  1061. public int addLongInfo(long l)
  1062. {
  1063. int i = addItem(new LongInfo(l, numOfItems));
  1064. if (i == numOfItems - 1) // if not existing
  1065. addConstInfoPadding();
  1066. return i;
  1067. }
  1068. /**
  1069. * Adds a new <code>CONSTANT_Double_info</code>
  1070. * structure.
  1071. *
  1072. * @return the index of the added entry.
  1073. */
  1074. public int addDoubleInfo(double d)
  1075. {
  1076. int i = addItem(new DoubleInfo(d, numOfItems));
  1077. if (i == numOfItems - 1) // if not existing
  1078. addConstInfoPadding();
  1079. return i;
  1080. }
  1081. /**
  1082. * Adds a new <code>CONSTANT_Utf8_info</code>
  1083. * structure.
  1084. *
  1085. * @return the index of the added entry.
  1086. */
  1087. public int addUtf8Info(String utf8)
  1088. {
  1089. return addItem(new Utf8Info(utf8, numOfItems));
  1090. }
  1091. /**
  1092. * Adds a new <code>CONSTANT_MethodHandle_info</code>
  1093. * structure.
  1094. *
  1095. * @param kind <code>reference_kind</code>
  1096. * such as {@link #REF_invokeStatic <code>REF_invokeStatic</code>}.
  1097. * @param index <code>reference_index</code>.
  1098. * @return the index of the added entry.
  1099. *
  1100. * @since 3.17
  1101. */
  1102. public int addMethodHandleInfo(int kind, int index)
  1103. {
  1104. return addItem(new MethodHandleInfo(kind, index, numOfItems));
  1105. }
  1106. /**
  1107. * Adds a new <code>CONSTANT_MethodType_info</code>
  1108. * structure.
  1109. *
  1110. * @param desc <code>descriptor_index</code>.
  1111. * @return the index of the added entry.
  1112. *
  1113. * @since 3.17
  1114. */
  1115. public int addMethodTypeInfo(int desc)
  1116. {
  1117. return addItem(new MethodTypeInfo(desc, numOfItems));
  1118. }
  1119. /**
  1120. * Adds a new <code>CONSTANT_InvokeDynamic_info</code>
  1121. * structure.
  1122. *
  1123. * @param bootstrap <code>bootstrap_method_attr_index</code>.
  1124. * @param nameAndType <code>name_and_type_index</code>.
  1125. * @return the index of the added entry.
  1126. *
  1127. * @since 3.17
  1128. */
  1129. public int addInvokeDynamicInfo(int bootstrap, int nameAndType)
  1130. {
  1131. return addItem(new InvokeDynamicInfo(bootstrap, nameAndType, numOfItems));
  1132. }
  1133. /**
  1134. * Adds a new <code>CONSTANT_Dynamic_info</code> structure.
  1135. *
  1136. * @param bootstrap <code>bootstrap_method_attr_index</code>.
  1137. * @param nameAndType <code>name_and_type_index</code>.
  1138. * @return the index of the added entry.
  1139. * @since 3.17
  1140. */
  1141. public int addDynamicInfo(int bootstrap, int nameAndType) {
  1142. return addItem(new DynamicInfo(bootstrap, nameAndType, numOfItems));
  1143. }
  1144. /**
  1145. * Adds a new <code>CONSTANT_Module_info</code>
  1146. * @param nameIndex the index of the Utf8 entry.
  1147. * @return the index of the added entry.
  1148. * @since 3.22
  1149. */
  1150. public int addModuleInfo(int nameIndex)
  1151. {
  1152. return addItem(new ModuleInfo(nameIndex, numOfItems));
  1153. }
  1154. /**
  1155. * Adds a new <code>CONSTANT_Package_info</code>
  1156. * @param nameIndex the index of the Utf8 entry.
  1157. * @return the index of the added entry.
  1158. * @since 3.22
  1159. */
  1160. public int addPackageInfo(int nameIndex)
  1161. {
  1162. return addItem(new PackageInfo(nameIndex, numOfItems));
  1163. }
  1164. /**
  1165. * Get all the class names.
  1166. *
  1167. * @return a set of class names (<code>String</code> objects).
  1168. */
  1169. public Set<String> getClassNames()
  1170. {
  1171. Set<String> result = new HashSet<String>();
  1172. LongVector v = items;
  1173. int size = numOfItems;
  1174. for (int i = 1; i < size; ++i) {
  1175. String className = v.elementAt(i).getClassName(this);
  1176. if (className != null)
  1177. result.add(className);
  1178. }
  1179. return result;
  1180. }
  1181. /**
  1182. * Replaces all occurrences of a class name.
  1183. *
  1184. * @param oldName the replaced name (JVM-internal representation).
  1185. * @param newName the substituted name (JVM-internal representation).
  1186. */
  1187. public void renameClass(String oldName, String newName)
  1188. {
  1189. LongVector v = items;
  1190. int size = numOfItems;
  1191. for (int i = 1; i < size; ++i) {
  1192. ConstInfo ci = v.elementAt(i);
  1193. ci.renameClass(this, oldName, newName, itemsCache);
  1194. }
  1195. }
  1196. /**
  1197. * Replaces all occurrences of class names.
  1198. *
  1199. * @param classnames specifies pairs of replaced and substituted
  1200. * name.
  1201. */
  1202. public void renameClass(Map<String,String> classnames)
  1203. {
  1204. LongVector v = items;
  1205. int size = numOfItems;
  1206. for (int i = 1; i < size; ++i) {
  1207. ConstInfo ci = v.elementAt(i);
  1208. ci.renameClass(this, classnames, itemsCache);
  1209. }
  1210. }
  1211. private void read(DataInputStream in) throws IOException
  1212. {
  1213. int n = in.readUnsignedShort();
  1214. items = new LongVector(n);
  1215. numOfItems = 0;
  1216. addItem0(null); // index 0 is reserved by the JVM.
  1217. while (--n > 0) { // index 0 is reserved by JVM
  1218. int tag = readOne(in);
  1219. if ((tag == LongInfo.tag) || (tag == DoubleInfo.tag)) {
  1220. addConstInfoPadding();
  1221. --n;
  1222. }
  1223. }
  1224. }
  1225. private static Map<ConstInfo,ConstInfo> makeItemsCache(LongVector items)
  1226. {
  1227. Map<ConstInfo,ConstInfo> cache = new HashMap<ConstInfo,ConstInfo>();
  1228. int i = 1;
  1229. while (true) {
  1230. ConstInfo info = items.elementAt(i++);
  1231. if (info == null)
  1232. break;
  1233. cache.put(info, info);
  1234. }
  1235. return cache;
  1236. }
  1237. private int readOne(DataInputStream in) throws IOException
  1238. {
  1239. ConstInfo info;
  1240. int tag = in.readUnsignedByte();
  1241. switch (tag) {
  1242. case Utf8Info.tag : // 1
  1243. info = new Utf8Info(in, numOfItems);
  1244. break;
  1245. case IntegerInfo.tag : // 3
  1246. info = new IntegerInfo(in, numOfItems);
  1247. break;
  1248. case FloatInfo.tag : // 4
  1249. info = new FloatInfo(in, numOfItems);
  1250. break;
  1251. case LongInfo.tag : // 5
  1252. info = new LongInfo(in, numOfItems);
  1253. break;
  1254. case DoubleInfo.tag : // 6
  1255. info = new DoubleInfo(in, numOfItems);
  1256. break;
  1257. case ClassInfo.tag : // 7
  1258. info = new ClassInfo(in, numOfItems);
  1259. break;
  1260. case StringInfo.tag : // 8
  1261. info = new StringInfo(in, numOfItems);
  1262. break;
  1263. case FieldrefInfo.tag : // 9
  1264. info = new FieldrefInfo(in, numOfItems);
  1265. break;
  1266. case MethodrefInfo.tag : // 10
  1267. info = new MethodrefInfo(in, numOfItems);
  1268. break;
  1269. case InterfaceMethodrefInfo.tag : // 11
  1270. info = new InterfaceMethodrefInfo(in, numOfItems);
  1271. break;
  1272. case NameAndTypeInfo.tag : // 12
  1273. info = new NameAndTypeInfo(in, numOfItems);
  1274. break;
  1275. case MethodHandleInfo.tag : // 15
  1276. info = new MethodHandleInfo(in, numOfItems);
  1277. break;
  1278. case MethodTypeInfo.tag : // 16
  1279. info = new MethodTypeInfo(in, numOfItems);
  1280. break;
  1281. case DynamicInfo.tag : // 17
  1282. info = new DynamicInfo(in, numOfItems);
  1283. break;
  1284. case InvokeDynamicInfo.tag : // 18
  1285. info = new InvokeDynamicInfo(in, numOfItems);
  1286. break;
  1287. case ModuleInfo.tag : // 19
  1288. info = new ModuleInfo(in, numOfItems);
  1289. break;
  1290. case PackageInfo.tag : // 20
  1291. info = new PackageInfo(in, numOfItems);
  1292. break;
  1293. default :
  1294. throw new IOException("invalid constant type: "
  1295. + tag + " at " + numOfItems);
  1296. }
  1297. addItem0(info);
  1298. return tag;
  1299. }
  1300. /**
  1301. * Writes the contents of the constant pool table.
  1302. */
  1303. public void write(DataOutputStream out) throws IOException
  1304. {
  1305. out.writeShort(numOfItems);
  1306. LongVector v = items;
  1307. int size = numOfItems;
  1308. for (int i = 1; i < size; ++i)
  1309. v.elementAt(i).write(out);
  1310. }
  1311. /**
  1312. * Prints the contents of the constant pool table.
  1313. */
  1314. public void print()
  1315. {
  1316. print(new PrintWriter(System.out, true));
  1317. }
  1318. /**
  1319. * Prints the contents of the constant pool table.
  1320. */
  1321. public void print(PrintWriter out)
  1322. {
  1323. int size = numOfItems;
  1324. for (int i = 1; i < size; ++i) {
  1325. out.print(i);
  1326. out.print(" ");
  1327. items.elementAt(i).print(out);
  1328. }
  1329. }
  1330. }
  1331. abstract class ConstInfo
  1332. {
  1333. int index;
  1334. public ConstInfo(int i) { index = i; }
  1335. public abstract int getTag();
  1336. public String getClassName(ConstPool cp) { return null; }
  1337. public void renameClass(ConstPool cp, String oldName, String newName,
  1338. Map<ConstInfo,ConstInfo> cache) {}
  1339. public void renameClass(ConstPool cp, Map<String,String> classnames,
  1340. Map<ConstInfo,ConstInfo> cache) {}
  1341. public abstract int copy(ConstPool src, ConstPool dest,
  1342. Map<String, String> classnames);
  1343. // ** classnames is a mapping between JVM names.
  1344. public abstract void write(DataOutputStream out) throws IOException;
  1345. public abstract void print(PrintWriter out);
  1346. @Override
  1347. public String toString() {
  1348. ByteArrayOutputStream bout = new ByteArrayOutputStream();
  1349. PrintWriter out = new PrintWriter(bout);
  1350. print(out);
  1351. return bout.toString();
  1352. }
  1353. }
  1354. /* padding following DoubleInfo or LongInfo.
  1355. */
  1356. class ConstInfoPadding extends ConstInfo
  1357. {
  1358. public ConstInfoPadding(int i) { super(i); }
  1359. @Override
  1360. public int getTag() { return 0; }
  1361. @Override
  1362. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1363. {
  1364. return dest.addConstInfoPadding();
  1365. }
  1366. @Override
  1367. public void write(DataOutputStream out) throws IOException {}
  1368. @Override
  1369. public void print(PrintWriter out)
  1370. {
  1371. out.println("padding");
  1372. }
  1373. }
  1374. class ClassInfo extends ConstInfo
  1375. {
  1376. static final int tag = 7;
  1377. int name;
  1378. public ClassInfo(int className, int index)
  1379. {
  1380. super(index);
  1381. name = className;
  1382. }
  1383. public ClassInfo(DataInputStream in, int index) throws IOException
  1384. {
  1385. super(index);
  1386. name = in.readUnsignedShort();
  1387. }
  1388. @Override
  1389. public int hashCode() { return name; }
  1390. @Override
  1391. public boolean equals(Object obj)
  1392. {
  1393. return obj instanceof ClassInfo && ((ClassInfo)obj).name == name;
  1394. }
  1395. @Override
  1396. public int getTag() { return tag; }
  1397. @Override
  1398. public String getClassName(ConstPool cp)
  1399. {
  1400. return cp.getUtf8Info(name);
  1401. }
  1402. @Override
  1403. public void renameClass(ConstPool cp, String oldName, String newName,
  1404. Map<ConstInfo,ConstInfo> cache)
  1405. {
  1406. String nameStr = cp.getUtf8Info(name);
  1407. String newNameStr = null;
  1408. if (nameStr.equals(oldName))
  1409. newNameStr = newName;
  1410. else if (nameStr.charAt(0) == '[') {
  1411. String s = Descriptor.rename(nameStr, oldName, newName);
  1412. if (nameStr != s)
  1413. newNameStr = s;
  1414. }
  1415. if (newNameStr != null)
  1416. if (cache == null)
  1417. name = cp.addUtf8Info(newNameStr);
  1418. else {
  1419. cache.remove(this);
  1420. name = cp.addUtf8Info(newNameStr);
  1421. cache.put(this, this);
  1422. }
  1423. }
  1424. @Override
  1425. public void renameClass(ConstPool cp, Map<String,String> map,
  1426. Map<ConstInfo,ConstInfo> cache)
  1427. {
  1428. String oldName = cp.getUtf8Info(name);
  1429. String newName = null;
  1430. if (oldName.charAt(0) == '[') {
  1431. String s = Descriptor.rename(oldName, map);
  1432. if (oldName != s)
  1433. newName = s;
  1434. }
  1435. else {
  1436. String s = map.get(oldName);
  1437. if (s != null && !s.equals(oldName))
  1438. newName = s;
  1439. }
  1440. if (newName != null) {
  1441. if (cache == null)
  1442. name = cp.addUtf8Info(newName);
  1443. else {
  1444. cache.remove(this);
  1445. name = cp.addUtf8Info(newName);
  1446. cache.put(this, this);
  1447. }
  1448. }
  1449. }
  1450. @Override
  1451. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1452. {
  1453. String classname = src.getUtf8Info(name);
  1454. if (map != null) {
  1455. String newname = map.get(classname);
  1456. if (newname != null)
  1457. classname = newname;
  1458. }
  1459. return dest.addClassInfo(classname);
  1460. }
  1461. @Override
  1462. public void write(DataOutputStream out) throws IOException
  1463. {
  1464. out.writeByte(tag);
  1465. out.writeShort(name);
  1466. }
  1467. @Override
  1468. public void print(PrintWriter out)
  1469. {
  1470. out.print("Class #");
  1471. out.println(name);
  1472. }
  1473. }
  1474. class NameAndTypeInfo extends ConstInfo
  1475. {
  1476. static final int tag = 12;
  1477. int memberName;
  1478. int typeDescriptor;
  1479. public NameAndTypeInfo(int name, int type, int index)
  1480. {
  1481. super(index);
  1482. memberName = name;
  1483. typeDescriptor = type;
  1484. }
  1485. public NameAndTypeInfo(DataInputStream in, int index) throws IOException
  1486. {
  1487. super(index);
  1488. memberName = in.readUnsignedShort();
  1489. typeDescriptor = in.readUnsignedShort();
  1490. }
  1491. @Override
  1492. public int hashCode() { return (memberName << 16) ^ typeDescriptor; }
  1493. @Override
  1494. public boolean equals(Object obj)
  1495. {
  1496. if (obj instanceof NameAndTypeInfo) {
  1497. NameAndTypeInfo nti = (NameAndTypeInfo)obj;
  1498. return nti.memberName == memberName
  1499. && nti.typeDescriptor == typeDescriptor;
  1500. }
  1501. return false;
  1502. }
  1503. @Override
  1504. public int getTag() { return tag; }
  1505. @Override
  1506. public void renameClass(ConstPool cp, String oldName, String newName,
  1507. Map<ConstInfo,ConstInfo> cache)
  1508. {
  1509. String type = cp.getUtf8Info(typeDescriptor);
  1510. String type2 = Descriptor.rename(type, oldName, newName);
  1511. if (type != type2)
  1512. if (cache == null)
  1513. typeDescriptor = cp.addUtf8Info(type2);
  1514. else {
  1515. cache.remove(this);
  1516. typeDescriptor = cp.addUtf8Info(type2);
  1517. cache.put(this, this);
  1518. }
  1519. }
  1520. @Override
  1521. public void renameClass(ConstPool cp, Map<String,String> map,
  1522. Map<ConstInfo,ConstInfo> cache)
  1523. {
  1524. String type = cp.getUtf8Info(typeDescriptor);
  1525. String type2 = Descriptor.rename(type, map);
  1526. if (type != type2)
  1527. if (cache == null)
  1528. typeDescriptor = cp.addUtf8Info(type2);
  1529. else {
  1530. cache.remove(this);
  1531. typeDescriptor = cp.addUtf8Info(type2);
  1532. cache.put(this, this);
  1533. }
  1534. }
  1535. @Override
  1536. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1537. {
  1538. String mname = src.getUtf8Info(memberName);
  1539. String tdesc = src.getUtf8Info(typeDescriptor);
  1540. tdesc = Descriptor.rename(tdesc, map);
  1541. return dest.addNameAndTypeInfo(dest.addUtf8Info(mname),
  1542. dest.addUtf8Info(tdesc));
  1543. }
  1544. @Override
  1545. public void write(DataOutputStream out) throws IOException {
  1546. out.writeByte(tag);
  1547. out.writeShort(memberName);
  1548. out.writeShort(typeDescriptor);
  1549. }
  1550. @Override
  1551. public void print(PrintWriter out) {
  1552. out.print("NameAndType #");
  1553. out.print(memberName);
  1554. out.print(", type #");
  1555. out.println(typeDescriptor);
  1556. }
  1557. }
  1558. abstract class MemberrefInfo extends ConstInfo
  1559. {
  1560. int classIndex;
  1561. int nameAndTypeIndex;
  1562. public MemberrefInfo(int cindex, int ntindex, int thisIndex)
  1563. {
  1564. super(thisIndex);
  1565. classIndex = cindex;
  1566. nameAndTypeIndex = ntindex;
  1567. }
  1568. public MemberrefInfo(DataInputStream in, int thisIndex)
  1569. throws IOException
  1570. {
  1571. super(thisIndex);
  1572. classIndex = in.readUnsignedShort();
  1573. nameAndTypeIndex = in.readUnsignedShort();
  1574. }
  1575. @Override
  1576. public int hashCode() { return (classIndex << 16) ^ nameAndTypeIndex; }
  1577. @Override
  1578. public boolean equals(Object obj) {
  1579. if (obj instanceof MemberrefInfo) {
  1580. MemberrefInfo mri = (MemberrefInfo)obj;
  1581. return mri.classIndex == classIndex
  1582. && mri.nameAndTypeIndex == nameAndTypeIndex
  1583. && mri.getClass() == this.getClass();
  1584. }
  1585. return false;
  1586. }
  1587. @Override
  1588. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1589. {
  1590. int classIndex2 = src.getItem(classIndex).copy(src, dest, map);
  1591. int ntIndex2 = src.getItem(nameAndTypeIndex).copy(src, dest, map);
  1592. return copy2(dest, classIndex2, ntIndex2);
  1593. }
  1594. abstract protected int copy2(ConstPool dest, int cindex, int ntindex);
  1595. @Override
  1596. public void write(DataOutputStream out) throws IOException
  1597. {
  1598. out.writeByte(getTag());
  1599. out.writeShort(classIndex);
  1600. out.writeShort(nameAndTypeIndex);
  1601. }
  1602. @Override
  1603. public void print(PrintWriter out)
  1604. {
  1605. out.print(getTagName() + " #");
  1606. out.print(classIndex);
  1607. out.print(", name&type #");
  1608. out.println(nameAndTypeIndex);
  1609. }
  1610. public abstract String getTagName();
  1611. }
  1612. class FieldrefInfo extends MemberrefInfo
  1613. {
  1614. static final int tag = 9;
  1615. public FieldrefInfo(int cindex, int ntindex, int thisIndex)
  1616. {
  1617. super(cindex, ntindex, thisIndex);
  1618. }
  1619. public FieldrefInfo(DataInputStream in, int thisIndex)
  1620. throws IOException
  1621. {
  1622. super(in, thisIndex);
  1623. }
  1624. @Override
  1625. public int getTag() { return tag; }
  1626. @Override
  1627. public String getTagName() { return "Field"; }
  1628. @Override
  1629. protected int copy2(ConstPool dest, int cindex, int ntindex)
  1630. {
  1631. return dest.addFieldrefInfo(cindex, ntindex);
  1632. }
  1633. }
  1634. class MethodrefInfo extends MemberrefInfo
  1635. {
  1636. static final int tag = 10;
  1637. public MethodrefInfo(int cindex, int ntindex, int thisIndex)
  1638. {
  1639. super(cindex, ntindex, thisIndex);
  1640. }
  1641. public MethodrefInfo(DataInputStream in, int thisIndex)
  1642. throws IOException
  1643. {
  1644. super(in, thisIndex);
  1645. }
  1646. @Override
  1647. public int getTag() { return tag; }
  1648. @Override
  1649. public String getTagName() { return "Method"; }
  1650. @Override
  1651. protected int copy2(ConstPool dest, int cindex, int ntindex)
  1652. {
  1653. return dest.addMethodrefInfo(cindex, ntindex);
  1654. }
  1655. }
  1656. class InterfaceMethodrefInfo extends MemberrefInfo
  1657. {
  1658. static final int tag = 11;
  1659. public InterfaceMethodrefInfo(int cindex, int ntindex, int thisIndex)
  1660. {
  1661. super(cindex, ntindex, thisIndex);
  1662. }
  1663. public InterfaceMethodrefInfo(DataInputStream in, int thisIndex)
  1664. throws IOException
  1665. {
  1666. super(in, thisIndex);
  1667. }
  1668. @Override
  1669. public int getTag() { return tag; }
  1670. @Override
  1671. public String getTagName() { return "Interface"; }
  1672. @Override
  1673. protected int copy2(ConstPool dest, int cindex, int ntindex)
  1674. {
  1675. return dest.addInterfaceMethodrefInfo(cindex, ntindex);
  1676. }
  1677. }
  1678. class StringInfo extends ConstInfo
  1679. {
  1680. static final int tag = 8;
  1681. int string;
  1682. public StringInfo(int str, int index)
  1683. {
  1684. super(index);
  1685. string = str;
  1686. }
  1687. public StringInfo(DataInputStream in, int index) throws IOException
  1688. {
  1689. super(index);
  1690. string = in.readUnsignedShort();
  1691. }
  1692. @Override
  1693. public int hashCode() { return string; }
  1694. @Override
  1695. public boolean equals(Object obj)
  1696. {
  1697. return obj instanceof StringInfo && ((StringInfo)obj).string == string;
  1698. }
  1699. @Override
  1700. public int getTag() { return tag; }
  1701. @Override
  1702. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1703. {
  1704. return dest.addStringInfo(src.getUtf8Info(string));
  1705. }
  1706. @Override
  1707. public void write(DataOutputStream out) throws IOException
  1708. {
  1709. out.writeByte(tag);
  1710. out.writeShort(string);
  1711. }
  1712. @Override
  1713. public void print(PrintWriter out)
  1714. {
  1715. out.print("String #");
  1716. out.println(string);
  1717. }
  1718. }
  1719. class IntegerInfo extends ConstInfo
  1720. {
  1721. static final int tag = 3;
  1722. int value;
  1723. public IntegerInfo(int v, int index)
  1724. {
  1725. super(index);
  1726. value = v;
  1727. }
  1728. public IntegerInfo(DataInputStream in, int index) throws IOException
  1729. {
  1730. super(index);
  1731. value = in.readInt();
  1732. }
  1733. @Override
  1734. public int hashCode() { return value; }
  1735. @Override
  1736. public boolean equals(Object obj)
  1737. {
  1738. return obj instanceof IntegerInfo && ((IntegerInfo)obj).value == value;
  1739. }
  1740. @Override
  1741. public int getTag() { return tag; }
  1742. @Override
  1743. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1744. {
  1745. return dest.addIntegerInfo(value);
  1746. }
  1747. @Override
  1748. public void write(DataOutputStream out) throws IOException
  1749. {
  1750. out.writeByte(tag);
  1751. out.writeInt(value);
  1752. }
  1753. @Override
  1754. public void print(PrintWriter out)
  1755. {
  1756. out.print("Integer ");
  1757. out.println(value);
  1758. }
  1759. }
  1760. class FloatInfo extends ConstInfo
  1761. {
  1762. static final int tag = 4;
  1763. float value;
  1764. public FloatInfo(float f, int index)
  1765. {
  1766. super(index);
  1767. value = f;
  1768. }
  1769. public FloatInfo(DataInputStream in, int index) throws IOException
  1770. {
  1771. super(index);
  1772. value = in.readFloat();
  1773. }
  1774. @Override
  1775. public int hashCode() { return Float.floatToIntBits(value); }
  1776. @Override
  1777. public boolean equals(Object obj)
  1778. {
  1779. return obj instanceof FloatInfo && ((FloatInfo)obj).value == value;
  1780. }
  1781. @Override
  1782. public int getTag() { return tag; }
  1783. @Override
  1784. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1785. {
  1786. return dest.addFloatInfo(value);
  1787. }
  1788. @Override
  1789. public void write(DataOutputStream out) throws IOException
  1790. {
  1791. out.writeByte(tag);
  1792. out.writeFloat(value);
  1793. }
  1794. @Override
  1795. public void print(PrintWriter out)
  1796. {
  1797. out.print("Float ");
  1798. out.println(value);
  1799. }
  1800. }
  1801. class LongInfo extends ConstInfo
  1802. {
  1803. static final int tag = 5;
  1804. long value;
  1805. public LongInfo(long l, int index)
  1806. {
  1807. super(index);
  1808. value = l;
  1809. }
  1810. public LongInfo(DataInputStream in, int index) throws IOException
  1811. {
  1812. super(index);
  1813. value = in.readLong();
  1814. }
  1815. @Override
  1816. public int hashCode() { return (int)(value ^ (value >>> 32)); }
  1817. @Override
  1818. public boolean equals(Object obj) {
  1819. return obj instanceof LongInfo && ((LongInfo)obj).value == value;
  1820. }
  1821. @Override
  1822. public int getTag() { return tag; }
  1823. @Override
  1824. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1825. {
  1826. return dest.addLongInfo(value);
  1827. }
  1828. @Override
  1829. public void write(DataOutputStream out) throws IOException
  1830. {
  1831. out.writeByte(tag);
  1832. out.writeLong(value);
  1833. }
  1834. @Override
  1835. public void print(PrintWriter out)
  1836. {
  1837. out.print("Long ");
  1838. out.println(value);
  1839. }
  1840. }
  1841. class DoubleInfo extends ConstInfo
  1842. {
  1843. static final int tag = 6;
  1844. double value;
  1845. public DoubleInfo(double d, int index)
  1846. {
  1847. super(index);
  1848. value = d;
  1849. }
  1850. public DoubleInfo(DataInputStream in, int index) throws IOException
  1851. {
  1852. super(index);
  1853. value = in.readDouble();
  1854. }
  1855. @Override
  1856. public int hashCode() {
  1857. long v = Double.doubleToLongBits(value);
  1858. return (int)(v ^ (v >>> 32));
  1859. }
  1860. @Override
  1861. public boolean equals(Object obj)
  1862. {
  1863. return obj instanceof DoubleInfo
  1864. && ((DoubleInfo)obj).value == value;
  1865. }
  1866. @Override
  1867. public int getTag() { return tag; }
  1868. @Override
  1869. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  1870. {
  1871. return dest.addDoubleInfo(value);
  1872. }
  1873. @Override
  1874. public void write(DataOutputStream out) throws IOException
  1875. {
  1876. out.writeByte(tag);
  1877. out.writeDouble(value);
  1878. }
  1879. @Override
  1880. public void print(PrintWriter out)
  1881. {
  1882. out.print("Double ");
  1883. out.println(value);
  1884. }
  1885. }
  1886. class Utf8Info extends ConstInfo
  1887. {
  1888. static final int tag = 1;
  1889. String string;
  1890. public Utf8Info(String utf8, int index)
  1891. {
  1892. super(index);
  1893. string = utf8;
  1894. }
  1895. public Utf8Info(DataInputStream in, int index)
  1896. throws IOException
  1897. {
  1898. super(index);
  1899. string = in.readUTF();
  1900. }
  1901. @Override
  1902. public int hashCode() {
  1903. return string.hashCode();
  1904. }
  1905. @Override
  1906. public boolean equals(Object obj) {
  1907. return obj instanceof Utf8Info
  1908. && ((Utf8Info)obj).string.equals(string);
  1909. }
  1910. @Override
  1911. public int getTag() { return tag; }
  1912. @Override
  1913. public int copy(ConstPool src, ConstPool dest,
  1914. Map<String,String> map)
  1915. {
  1916. return dest.addUtf8Info(string);
  1917. }
  1918. @Override
  1919. public void write(DataOutputStream out)
  1920. throws IOException
  1921. {
  1922. out.writeByte(tag);
  1923. out.writeUTF(string);
  1924. }
  1925. @Override
  1926. public void print(PrintWriter out) {
  1927. out.print("UTF8 \"");
  1928. out.print(string);
  1929. out.println("\"");
  1930. }
  1931. }
  1932. class MethodHandleInfo extends ConstInfo {
  1933. static final int tag = 15;
  1934. int refKind, refIndex;
  1935. public MethodHandleInfo(int kind, int referenceIndex, int index) {
  1936. super(index);
  1937. refKind = kind;
  1938. refIndex = referenceIndex;
  1939. }
  1940. public MethodHandleInfo(DataInputStream in, int index)
  1941. throws IOException
  1942. {
  1943. super(index);
  1944. refKind = in.readUnsignedByte();
  1945. refIndex = in.readUnsignedShort();
  1946. }
  1947. @Override
  1948. public int hashCode() { return (refKind << 16) ^ refIndex; }
  1949. @Override
  1950. public boolean equals(Object obj)
  1951. {
  1952. if (obj instanceof MethodHandleInfo) {
  1953. MethodHandleInfo mh = (MethodHandleInfo)obj;
  1954. return mh.refKind == refKind && mh.refIndex == refIndex;
  1955. }
  1956. return false;
  1957. }
  1958. @Override
  1959. public int getTag() { return tag; }
  1960. @Override
  1961. public int copy(ConstPool src, ConstPool dest,
  1962. Map<String,String> map)
  1963. {
  1964. return dest.addMethodHandleInfo(refKind,
  1965. src.getItem(refIndex).copy(src, dest, map));
  1966. }
  1967. @Override
  1968. public void write(DataOutputStream out) throws IOException
  1969. {
  1970. out.writeByte(tag);
  1971. out.writeByte(refKind);
  1972. out.writeShort(refIndex);
  1973. }
  1974. @Override
  1975. public void print(PrintWriter out) {
  1976. out.print("MethodHandle #");
  1977. out.print(refKind);
  1978. out.print(", index #");
  1979. out.println(refIndex);
  1980. }
  1981. }
  1982. class MethodTypeInfo extends ConstInfo
  1983. {
  1984. static final int tag = 16;
  1985. int descriptor;
  1986. public MethodTypeInfo(int desc, int index)
  1987. {
  1988. super(index);
  1989. descriptor = desc;
  1990. }
  1991. public MethodTypeInfo(DataInputStream in, int index)
  1992. throws IOException
  1993. {
  1994. super(index);
  1995. descriptor = in.readUnsignedShort();
  1996. }
  1997. @Override
  1998. public int hashCode() { return descriptor; }
  1999. @Override
  2000. public boolean equals(Object obj)
  2001. {
  2002. if (obj instanceof MethodTypeInfo)
  2003. return ((MethodTypeInfo)obj).descriptor == descriptor;
  2004. return false;
  2005. }
  2006. @Override
  2007. public int getTag() { return tag; }
  2008. @Override
  2009. public void renameClass(ConstPool cp, String oldName, String newName,
  2010. Map<ConstInfo,ConstInfo> cache)
  2011. {
  2012. String desc = cp.getUtf8Info(descriptor);
  2013. String desc2 = Descriptor.rename(desc, oldName, newName);
  2014. if (desc != desc2)
  2015. if (cache == null)
  2016. descriptor = cp.addUtf8Info(desc2);
  2017. else {
  2018. cache.remove(this);
  2019. descriptor = cp.addUtf8Info(desc2);
  2020. cache.put(this, this);
  2021. }
  2022. }
  2023. @Override
  2024. public void renameClass(ConstPool cp, Map<String,String> map,
  2025. Map<ConstInfo,ConstInfo> cache)
  2026. {
  2027. String desc = cp.getUtf8Info(descriptor);
  2028. String desc2 = Descriptor.rename(desc, map);
  2029. if (desc != desc2)
  2030. if (cache == null)
  2031. descriptor = cp.addUtf8Info(desc2);
  2032. else {
  2033. cache.remove(this);
  2034. descriptor = cp.addUtf8Info(desc2);
  2035. cache.put(this, this);
  2036. }
  2037. }
  2038. @Override
  2039. public int copy(ConstPool src, ConstPool dest, Map<String,String> map)
  2040. {
  2041. String desc = src.getUtf8Info(descriptor);
  2042. desc = Descriptor.rename(desc, map);
  2043. return dest.addMethodTypeInfo(dest.addUtf8Info(desc));
  2044. }
  2045. @Override
  2046. public void write(DataOutputStream out) throws IOException
  2047. {
  2048. out.writeByte(tag);
  2049. out.writeShort(descriptor);
  2050. }
  2051. @Override
  2052. public void print(PrintWriter out) {
  2053. out.print("MethodType #");
  2054. out.println(descriptor);
  2055. }
  2056. }
  2057. class InvokeDynamicInfo extends ConstInfo
  2058. {
  2059. static final int tag = 18;
  2060. int bootstrap, nameAndType;
  2061. public InvokeDynamicInfo(int bootstrapMethod,
  2062. int ntIndex, int index)
  2063. {
  2064. super(index);
  2065. bootstrap = bootstrapMethod;
  2066. nameAndType = ntIndex;
  2067. }
  2068. public InvokeDynamicInfo(DataInputStream in, int index)
  2069. throws IOException
  2070. {
  2071. super(index);
  2072. bootstrap = in.readUnsignedShort();
  2073. nameAndType = in.readUnsignedShort();
  2074. }
  2075. @Override
  2076. public int hashCode() { return (bootstrap << 16) ^ nameAndType; }
  2077. @Override
  2078. public boolean equals(Object obj)
  2079. {
  2080. if (obj instanceof InvokeDynamicInfo) {
  2081. InvokeDynamicInfo iv = (InvokeDynamicInfo)obj;
  2082. return iv.bootstrap == bootstrap
  2083. && iv.nameAndType == nameAndType;
  2084. }
  2085. return false;
  2086. }
  2087. @Override
  2088. public int getTag() { return tag; }
  2089. @Override
  2090. public int copy(ConstPool src, ConstPool dest,
  2091. Map<String,String> map)
  2092. {
  2093. return dest.addInvokeDynamicInfo(bootstrap,
  2094. src.getItem(nameAndType).copy(src, dest, map));
  2095. }
  2096. @Override
  2097. public void write(DataOutputStream out) throws IOException
  2098. {
  2099. out.writeByte(tag);
  2100. out.writeShort(bootstrap);
  2101. out.writeShort(nameAndType);
  2102. }
  2103. @Override
  2104. public void print(PrintWriter out) {
  2105. out.print("InvokeDynamic #");
  2106. out.print(bootstrap);
  2107. out.print(", name&type #");
  2108. out.println(nameAndType);
  2109. }
  2110. }
  2111. class DynamicInfo extends ConstInfo {
  2112. static final int tag = 17;
  2113. int bootstrap, nameAndType;
  2114. public DynamicInfo(int bootstrapMethod,
  2115. int ntIndex, int index) {
  2116. super(index);
  2117. bootstrap = bootstrapMethod;
  2118. nameAndType = ntIndex;
  2119. }
  2120. public DynamicInfo(DataInputStream in, int index)
  2121. throws IOException {
  2122. super(index);
  2123. bootstrap = in.readUnsignedShort();
  2124. nameAndType = in.readUnsignedShort();
  2125. }
  2126. @Override
  2127. public int hashCode() {
  2128. return (bootstrap << 16) ^ nameAndType;
  2129. }
  2130. @Override
  2131. public boolean equals(Object obj) {
  2132. if (obj instanceof DynamicInfo) {
  2133. DynamicInfo iv = (DynamicInfo) obj;
  2134. return iv.bootstrap == bootstrap
  2135. && iv.nameAndType == nameAndType;
  2136. }
  2137. return false;
  2138. }
  2139. @Override
  2140. public int getTag() {
  2141. return tag;
  2142. }
  2143. @Override
  2144. public int copy(ConstPool src, ConstPool dest,
  2145. Map<String, String> map) {
  2146. return dest.addDynamicInfo(bootstrap,
  2147. src.getItem(nameAndType).copy(src, dest, map));
  2148. }
  2149. @Override
  2150. public void write(DataOutputStream out) throws IOException {
  2151. out.writeByte(tag);
  2152. out.writeShort(bootstrap);
  2153. out.writeShort(nameAndType);
  2154. }
  2155. @Override
  2156. public void print(PrintWriter out) {
  2157. out.print("Dynamic #");
  2158. out.print(bootstrap);
  2159. out.print(", name&type #");
  2160. out.println(nameAndType);
  2161. }
  2162. }
  2163. class ModuleInfo extends ConstInfo
  2164. {
  2165. static final int tag = 19;
  2166. int name;
  2167. public ModuleInfo(int moduleName, int index)
  2168. {
  2169. super(index);
  2170. name = moduleName;
  2171. }
  2172. public ModuleInfo(DataInputStream in, int index)
  2173. throws IOException
  2174. {
  2175. super(index);
  2176. name = in.readUnsignedShort();
  2177. }
  2178. @Override
  2179. public int hashCode() { return name; }
  2180. @Override
  2181. public boolean equals(Object obj)
  2182. {
  2183. return obj instanceof ModuleInfo
  2184. && ((ModuleInfo)obj).name == name;
  2185. }
  2186. @Override
  2187. public int getTag() { return tag; }
  2188. public String getModuleName(ConstPool cp)
  2189. {
  2190. return cp.getUtf8Info(name);
  2191. }
  2192. @Override
  2193. public int copy(ConstPool src, ConstPool dest,
  2194. Map<String,String> map)
  2195. {
  2196. String moduleName = src.getUtf8Info(name);
  2197. int newName = dest.addUtf8Info(moduleName);
  2198. return dest.addModuleInfo(newName);
  2199. }
  2200. @Override
  2201. public void write(DataOutputStream out) throws IOException
  2202. {
  2203. out.writeByte(tag);
  2204. out.writeShort(name);
  2205. }
  2206. @Override
  2207. public void print(PrintWriter out) {
  2208. out.print("Module #");
  2209. out.println(name);
  2210. }
  2211. }
  2212. class PackageInfo extends ConstInfo
  2213. {
  2214. static final int tag = 20;
  2215. int name;
  2216. public PackageInfo(int moduleName, int index)
  2217. {
  2218. super(index);
  2219. name = moduleName;
  2220. }
  2221. public PackageInfo(DataInputStream in, int index)
  2222. throws IOException
  2223. {
  2224. super(index);
  2225. name = in.readUnsignedShort();
  2226. }
  2227. @Override
  2228. public int hashCode() { return name; }
  2229. @Override
  2230. public boolean equals(Object obj) {
  2231. return obj instanceof PackageInfo
  2232. && ((PackageInfo)obj).name == name;
  2233. }
  2234. @Override
  2235. public int getTag() { return tag; }
  2236. public String getPackageName(ConstPool cp)
  2237. {
  2238. return cp.getUtf8Info(name);
  2239. }
  2240. @Override
  2241. public int copy(ConstPool src, ConstPool dest,
  2242. Map<String,String> map)
  2243. {
  2244. String packageName = src.getUtf8Info(name);
  2245. int newName = dest.addUtf8Info(packageName);
  2246. return dest.addModuleInfo(newName);
  2247. }
  2248. @Override
  2249. public void write(DataOutputStream out) throws IOException
  2250. {
  2251. out.writeByte(tag);
  2252. out.writeShort(name);
  2253. }
  2254. @Override
  2255. public void print(PrintWriter out)
  2256. {
  2257. out.print("Package #");
  2258. out.println(name);
  2259. }
  2260. }