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.

StackMapTest.java 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. package javassist.bytecode;
  2. import java.util.Iterator;
  3. import java.util.List;
  4. import java.util.regex.Pattern;
  5. import java.util.regex.Matcher;
  6. import java.io.ByteArrayOutputStream;
  7. import java.io.IOException;
  8. import java.io.PrintStream;
  9. import java.lang.reflect.Method;
  10. import javassist.ClassPool;
  11. import javassist.CodeConverter;
  12. import javassist.CtClass;
  13. import javassist.CtMethod;
  14. import javassist.CtNewConstructor;
  15. import javassist.CtNewMethod;
  16. import javassist.JvstTest;
  17. import javassist.Loader;
  18. import javassist.bytecode.stackmap.MapMaker;
  19. import javassist.bytecode.stackmap.TypeData;
  20. import junit.framework.TestCase;
  21. public class StackMapTest extends TestCase {
  22. public static final String PATH = JvstTest.PATH;
  23. private ClassPool loader, dloader;
  24. private Loader cloader;
  25. public StackMapTest(String name) { super(name); }
  26. protected void setUp() throws Exception {
  27. loader = ClassPool.getDefault();
  28. dloader = new ClassPool(null);
  29. dloader.appendSystemPath();
  30. dloader.insertClassPath(".");
  31. cloader = new Loader(dloader);
  32. }
  33. protected Object make(String name) throws Exception {
  34. return cloader.loadClass(name).newInstance();
  35. }
  36. protected int invoke(Object target, String method) throws Exception {
  37. Method m = target.getClass().getMethod(method, new Class[0]);
  38. Object res = m.invoke(target, new Object[0]);
  39. return ((Integer)res).intValue();
  40. }
  41. protected static void rebuildStackMaps(CtClass cc) throws BadBytecode, IOException {
  42. ClassPool cp = cc.getClassPool();
  43. Iterator it = cc.getClassFile().getMethods().iterator();
  44. while (it.hasNext()) {
  45. MethodInfo minfo = (MethodInfo)it.next();
  46. rebuildStackMap(cc, cp, minfo);
  47. }
  48. }
  49. protected static void rebuildStackMap(CtClass cc, ClassPool cp, MethodInfo minfo) throws BadBytecode, IOException {
  50. CodeAttribute ca = minfo.getCodeAttribute();
  51. if (ca != null) {
  52. StackMapTable smt = (StackMapTable)ca.getAttribute(StackMapTable.tag);
  53. if (smt != null) {
  54. String data = readSmt(smt);
  55. StackMapTable smt2 = MapMaker.make(cp, minfo);
  56. String data2 = readSmt(smt2);
  57. try {
  58. assertEquals(cc.getName() + ":" + minfo.getName() + ":" + minfo.getDescriptor(),
  59. data, data2);
  60. }
  61. catch (junit.framework.ComparisonFailure e) {
  62. System.out.println("*** " + cc.getName() + ":" + minfo.getName() + ":" + minfo.getDescriptor());
  63. smt.println(System.out);
  64. System.out.println("---");
  65. smt2.println(System.out);
  66. }
  67. }
  68. }
  69. }
  70. protected static void rebuildStackMaps2(CtClass cc) throws BadBytecode {
  71. ClassPool cp = cc.getClassPool();
  72. Iterator it = cc.getClassFile().getMethods().iterator();
  73. while (it.hasNext()) {
  74. MethodInfo minfo = (MethodInfo)it.next();
  75. minfo.rebuildStackMap(cp);
  76. }
  77. }
  78. protected static String readSmt(StackMapTable smt) throws BadBytecode, IOException {
  79. if (smt == null)
  80. return "";
  81. ByteArrayOutputStream out = new ByteArrayOutputStream();
  82. PrintStream pout = new PrintStream(out);
  83. smt.println(pout);
  84. pout.close();
  85. return out.toString();
  86. }
  87. public static void main(String[] args) throws Exception {
  88. if (args.length == 2 && args[0].equals("-c")) {
  89. CtClass cc = ClassPool.getDefault().get(args[0].replace('/', '.'));
  90. rebuildStackMaps(cc);
  91. }
  92. else {
  93. for (int i = 0; i < args.length; i++) {
  94. CtClass cc = ClassPool.getDefault().get(getClassName(args[i]));
  95. System.out.println(cc.getName());
  96. rebuildStackMaps2(cc);
  97. cc.writeFile("rebuild");
  98. }
  99. }
  100. }
  101. public static String getClassName(String fileName) {
  102. Matcher m = Pattern.compile("(.*)\\.class").matcher(fileName);
  103. if (m.matches())
  104. return m.group(1).replace('/', '.');
  105. else
  106. return fileName;
  107. }
  108. public void testCommonSuper() throws Exception {
  109. CtClass type = loader.get("javassist.CtClassType[]");
  110. CtClass base = loader.get("javassist.CtClass[]");
  111. CtClass array = loader.get("javassist.CtArray[]");
  112. CtClass array2 = loader.get("javassist.CtArray[][]");
  113. CtClass str = loader.get("java.lang.String[]");
  114. CtClass strObj = loader.get("java.lang.String");
  115. CtClass obj = loader.get("java.lang.Object[]");
  116. CtClass objObj = loader.get("java.lang.Object");
  117. assertEquals(base, TypeData.commonSuperClassEx(type, base));
  118. assertEquals(base, TypeData.commonSuperClassEx(base, type));
  119. assertEquals(base, TypeData.commonSuperClassEx(array, type));
  120. assertEquals(obj, TypeData.commonSuperClassEx(base, str));
  121. assertEquals(objObj, TypeData.commonSuperClassEx(strObj, str));
  122. assertEquals(obj, TypeData.commonSuperClassEx(array, array2));
  123. assertEquals(obj, TypeData.commonSuperClassEx(base, array2));
  124. }
  125. public void testRebuild() throws Exception {
  126. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T1");
  127. rebuildStackMaps2(cc);
  128. //Class c = cc.toClass();
  129. //Object t1 = c.newInstance();
  130. cc.writeFile();
  131. Object t1 = make(cc.getName());
  132. assertEquals(3, invoke(t1, "test"));
  133. }
  134. public static interface Intf {
  135. int foo();
  136. }
  137. public static class C1 implements Intf {
  138. public int foo() { return 0; }
  139. }
  140. public static class C2 implements Intf {
  141. public int foo() { return 3; }
  142. }
  143. public static class T1 {
  144. public int test() {
  145. return foo(-1);
  146. }
  147. public int foo(int i) {
  148. Intf obj;
  149. if (i > 0)
  150. obj = new C1();
  151. else
  152. obj = new C2();
  153. return obj.foo();
  154. }
  155. }
  156. public void testRebuild2() throws Exception {
  157. CtClass cc = loader.get("javassist.bytecode.StackMapTest$C3");
  158. rebuildStackMaps2(cc);
  159. cc.writeFile();
  160. Object t1 = make(cc.getName());
  161. assertEquals(7, invoke(t1, "test"));
  162. }
  163. public static class C3 {
  164. int value;
  165. public C3(int i) {
  166. value = i;
  167. }
  168. public C3(boolean b) {
  169. this(b ? 7 : 10);
  170. }
  171. public C3() { this(true); }
  172. public int test() { return value; }
  173. }
  174. public void testRebuild3() throws Exception {
  175. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T3");
  176. rebuildStackMaps2(cc);
  177. cc.writeFile();
  178. Object t1 = make(cc.getName());
  179. assertEquals(1100, invoke(t1, "test"));
  180. }
  181. public static interface Intf2 {
  182. int bar();
  183. }
  184. public static class D1 extends C1 implements Intf2 {
  185. public int bar() { return 10; }
  186. }
  187. public static class D2 extends C1 implements Intf2 {
  188. public int bar() { return 100; }
  189. }
  190. public static class T3 {
  191. public int bar(Intf2 i) { return 1000; }
  192. public int test() {
  193. return foo(-1);
  194. }
  195. public int foo(int i) {
  196. Intf2 obj;
  197. if (i > 0)
  198. obj = new D1();
  199. else
  200. obj = new D2();
  201. System.out.println(obj.toString());
  202. return obj.bar() + bar(obj);
  203. }
  204. }
  205. public void testRebuildArray() throws Exception {
  206. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T4");
  207. rebuildStackMaps2(cc);
  208. cc.writeFile();
  209. Object t1 = make(cc.getName());
  210. assertEquals(30, invoke(t1, "test"));
  211. }
  212. public static class T4 {
  213. public int test() {
  214. return foo(3) + foo2(3) + foo3(3) + foo4(3);
  215. }
  216. public int foo(int i) {
  217. C1[] a;
  218. if (i > 0)
  219. a = new D1[1];
  220. else
  221. a = new D2[1];
  222. if (i > 0)
  223. a[0] = new D1();
  224. else
  225. a[0] = new D2();
  226. return a[0].foo();
  227. }
  228. public int foo2(int i) {
  229. Intf2[] a;
  230. if (i > 0)
  231. a = new D1[1];
  232. else
  233. a = new D2[1];
  234. if (i > 0)
  235. a[0] = new D1();
  236. else
  237. a[0] = new D2();
  238. return a[0].bar();
  239. }
  240. public int foo3(int i) {
  241. Intf2[] a = null;
  242. if (i > 0)
  243. a = new D1[1];
  244. a[0] = new D1();
  245. return a[0].bar();
  246. }
  247. public int foo4(int i) {
  248. Intf2[] a = new Intf2[1];
  249. if (i > 0)
  250. a[0] = new D1();
  251. return a[0].bar();
  252. }
  253. }
  254. public void testRebuildConstructor() throws Exception {
  255. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T5");
  256. rebuildStackMaps2(cc);
  257. cc.writeFile();
  258. Object t1 = make(cc.getName());
  259. assertEquals(123, invoke(t1, "test"));
  260. }
  261. public static class T5 {
  262. int count;
  263. public T5() { count = 0; }
  264. public T5(int k) {
  265. if (k > 0) count = 10;
  266. else count = 100;
  267. count++;
  268. }
  269. public T5(double d) {
  270. this(d > 0.0 ? 1 : -1);
  271. if (d > 1.0) count += 10;
  272. else count += 100;
  273. count++;
  274. }
  275. public int test() {
  276. return new T5(3).count + new T5(1.0).count;
  277. }
  278. }
  279. public void testRebuildConstructor2() throws Exception {
  280. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T6");
  281. rebuildStackMaps2(cc);
  282. cc.writeFile();
  283. Object t1 = make(cc.getName());
  284. assertEquals(101, invoke(t1, "test2"));
  285. }
  286. public static class T6 {
  287. public int test2() {
  288. T5 t0 = new T5();
  289. T5 t = new T5(t0.count > 0 ? (new T5(t0.count > 0 ? 1 : -1).count) : -1);
  290. if (t0.count > 0)
  291. t.count += 1000;
  292. return t.count;
  293. }
  294. }
  295. public void testSwitchCase() throws Exception {
  296. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T7");
  297. // CodeConverter conv = new CodeConverter();
  298. // conv.replaceNew(cc, cc, "make2");
  299. // cc.instrument(conv);
  300. StringBuffer sbuf = new StringBuffer("String s;");
  301. for (int i = 0; i < 130; i++)
  302. sbuf.append("s =\"" + i + "\";");
  303. cc.getDeclaredMethod("foo").insertBefore(sbuf.toString());
  304. cc.getDeclaredMethod("test2").setBody(loader.get("javassist.bytecode.StackMapTest$T8").getDeclaredMethod("test2"), null);
  305. //rebuildStackMaps2(cc);
  306. cc.writeFile();
  307. Object t1 = make(cc.getName());
  308. assertEquals(110, invoke(t1, "test"));
  309. }
  310. public static class T7 {
  311. int value = 1;
  312. T7 t7;
  313. public static T7 make2() { return null; }
  314. public int foo() { return 1; }
  315. public int test() { return test2(10); }
  316. public int test2(int k) { return k; }
  317. }
  318. public static class T8 {
  319. public int test2(int k) {
  320. String s = "abc";
  321. T7 t = k > 0 ? new T7() : new T7();
  322. switch (k) {
  323. case 0:
  324. t = new T7();
  325. k += t.value;
  326. break;
  327. case 10:
  328. k += 100;
  329. break;
  330. }
  331. return k;
  332. }
  333. }
  334. public void testSwitchCase2() throws Exception {
  335. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T7b");
  336. StringBuffer sbuf = new StringBuffer("String s;");
  337. for (int i = 0; i < 130; i++)
  338. sbuf.append("s =\"" + i + "\";");
  339. cc.getDeclaredMethod("foo").insertBefore(sbuf.toString());
  340. cc.getDeclaredMethod("test2").setBody(loader.get("javassist.bytecode.StackMapTest$T8b").getDeclaredMethod("test2"), null);
  341. rebuildStackMaps2(cc);
  342. cc.writeFile();
  343. Object t1 = make(cc.getName());
  344. assertEquals(110, invoke(t1, "test"));
  345. }
  346. public static class T7b {
  347. int value = 1;
  348. T7b t7;
  349. public static T7b make2() { return null; }
  350. public int foo() { return 1; }
  351. public int test() { return test2(10); }
  352. public int test2(int k) { return k; }
  353. }
  354. public static class T8b {
  355. public int test2(int k) {
  356. String s = "abc";
  357. T7b t = k > 0 ? new T7b() : new T7b();
  358. switch (k) {
  359. case 0:
  360. t = new T7b();
  361. k += t.value;
  362. break;
  363. case 10:
  364. k += 100;
  365. break;
  366. }
  367. return k;
  368. }
  369. }
  370. public void testSwitchCase3() throws Exception {
  371. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T7c");
  372. StringBuffer sbuf = new StringBuffer("String s;");
  373. for (int i = 0; i < 130; i++)
  374. sbuf.append("s =\"" + i + "\";");
  375. cc.getDeclaredMethod("foo").insertBefore(sbuf.toString());
  376. cc.getDeclaredMethod("test2").setBody(loader.get("javassist.bytecode.StackMapTest$T8c").getDeclaredMethod("test2"), null);
  377. cc.writeFile();
  378. Object t1 = make(cc.getName());
  379. assertEquals(100, invoke(t1, "test"));
  380. }
  381. public static class T7c {
  382. int value = 1;
  383. T7b t7;
  384. public static T7b make2() { return null; }
  385. public static void print(String s) {}
  386. public int foo() { return 1; }
  387. public int test() { return test2(10); }
  388. public int test2(int k) { return 0; }
  389. }
  390. public static class T8c {
  391. public int test2(int k) {
  392. int jj = 50;
  393. if (k > 0)
  394. k += "fooo".length();
  395. int j = 50;
  396. loop: for (int i = 0; i < 10; i++) {
  397. int jjj = 1;
  398. switch (i) {
  399. case 0:
  400. k++;
  401. { int poi = 0; }
  402. break;
  403. case 9:
  404. break loop;
  405. case 7:
  406. k += jjj;
  407. break;
  408. }
  409. }
  410. return j + jj;
  411. }
  412. }
  413. public void testSwitchCase4() throws Exception {
  414. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T8e");
  415. StringBuffer sbuf = new StringBuffer("String s;");
  416. for (int i = 0; i < 130; i++)
  417. sbuf.append("s =\"" + i + "\";");
  418. cc.getDeclaredMethod("foo").insertBefore(sbuf.toString());
  419. CtClass orig = loader.get("javassist.bytecode.StackMapTest$T8d");
  420. CtMethod origM = orig.getDeclaredMethod("test2");
  421. writeLdcw(origM);
  422. cc.getDeclaredMethod("test2").setBody(origM, null);
  423. orig.writeFile();
  424. cc.writeFile();
  425. Object t1 = make(cc.getName());
  426. assertEquals(100, invoke(t1, "test"));
  427. }
  428. private void writeLdcw(CtMethod method) {
  429. CodeAttribute ca = method.getMethodInfo().getCodeAttribute();
  430. int index = ca.getConstPool().addStringInfo("ldcw");
  431. CodeIterator ci = ca.iterator();
  432. ci.writeByte(Opcode.LDC_W, 14);
  433. ci.write16bit(index, 15);
  434. ci.writeByte(Opcode.LDC_W, 43);
  435. ci.write16bit(index, 44);
  436. }
  437. public static class T8e {
  438. static T8dd helper() { return new T8dd(); }
  439. int integer() { return 9; }
  440. boolean integer2(String s) { return true; }
  441. static void print(String s) {}
  442. private void print2(String s) {}
  443. private Object func(String s) { return null; }
  444. I8d func2(String s) { return null; }
  445. static String ldcw() { return "k"; }
  446. static boolean debug = false;
  447. void log(String p1,String p2,String p3,Long p4, Object p5, Object p6) {}
  448. public int foo() { return 1; }
  449. public int test() {
  450. try {
  451. return test2("", 10) ? 1 : 0;
  452. } catch (Exception e) {}
  453. return 100;
  454. }
  455. public boolean test2(String s, int k) throws Exception { return false; }
  456. }
  457. public static interface I8d {
  458. String foo(String s, int i);
  459. }
  460. public static class T8dd {
  461. java.util.List foo(String s) { return new java.util.ArrayList(); }
  462. }
  463. public static class T8d {
  464. static T8dd helper() { return new T8dd(); }
  465. int integer() { return 9; }
  466. boolean integer2(String s) { return true; }
  467. static void print(String s) {}
  468. private void print2(String s) {}
  469. private Object func(String s) { return null; }
  470. I8d func2(String s) { return null; }
  471. static String ldcw() { return "k"; }
  472. static boolean debug = false;
  473. void log(String p1,String p2,String p3,Long p4, Object p5, Object p6) {}
  474. public boolean test2(String s, int i) throws Exception {
  475. String k = null;
  476. Object k2 = null;
  477. boolean v5 = true;
  478. if (!debug)
  479. print(ldcw());
  480. Object k3 = this.func(s);
  481. if (k3 == null)
  482. throw new Exception(new StringBuilder().append(ldcw()).append(s).append(",").toString());
  483. String v7 = k3.toString();
  484. k2 = this.func2(v7);
  485. if (k2 != null) { // 82:
  486. if (k2 instanceof I8d) {
  487. I8d k5 = (I8d)k2;
  488. k = k5.foo(s, i);
  489. }
  490. }
  491. java.util.List list = helper().foo(v7); // local 8
  492. for (int v9 = 0; v9 < list.size(); v9++) {
  493. boolean v10 = true;
  494. T8d v11 = (T8d)list.get(v9);
  495. switch (v11.integer()) {
  496. case 1:
  497. break;
  498. case 2:
  499. v10 = this.integer2(s);
  500. v5 &= v10;
  501. break;
  502. default :
  503. throw new Exception(new StringBuilder().append("ldc 189").append(v11.integer()).append("ldc 169").toString());
  504. }
  505. }
  506. if (v5) // 246:
  507. this.print2(s);
  508. if (v5)
  509. this.log(ldcw(), v7, s, Long.valueOf(new Integer(i).longValue()), k, null);
  510. else // 290:
  511. this.log(ldcw(), v7, s, Long.valueOf(new Integer(i).longValue()), k, null);
  512. return v5;
  513. }
  514. }
  515. public void testInnerClass() throws Exception {
  516. CtClass cc = loader.get("javassist.bytecode.StackMapTest$T9");
  517. CtClass par = loader.get("javassist.bytecode.StackMapTest$T9$Parent");
  518. CtClass in = loader.get("javassist.bytecode.StackMapTest$T9$In");
  519. rebuildStackMaps2(cc);
  520. rebuildStackMaps2(par);
  521. rebuildStackMaps2(in);
  522. cc.writeFile();
  523. in.writeFile();
  524. par.writeFile();
  525. Object t1 = make(cc.getName());
  526. assertEquals(19, invoke(t1, "test"));
  527. }
  528. public static class T9 {
  529. class Parent {
  530. int f;
  531. Parent(int i) { f = i; }
  532. }
  533. class In extends Parent {
  534. int value;
  535. public In(int i) {
  536. super(i > 0 ? 10 : 20);
  537. value = i;
  538. }
  539. }
  540. public int test() {
  541. In in = new In(9);
  542. return in.value + in.f;
  543. }
  544. }
  545. public void testConstructor3() throws Exception {
  546. CtClass cc = loader.get("javassist.bytecode.StackMapTest$C4");
  547. MethodInfo mi = cc.getDeclaredMethod("foo").getMethodInfo();
  548. mi.rebuildStackMapForME(loader);
  549. CodeIterator ci = mi.getCodeAttribute().iterator();
  550. ci.insertGap(0, 7);
  551. cc.writeFile();
  552. Object t1 = make(cc.getName());
  553. assertEquals(6, invoke(t1, "test"));
  554. }
  555. public static class C4 {
  556. public int test() { return foo(3); }
  557. public int foo(int i) {
  558. String s = new String(i > 0 ? "pos" : "negative");
  559. System.out.println("2nd stage");
  560. int len = 0;
  561. if (i > 0) {
  562. String t = new String(i > 0 ? "pos" : "negative");
  563. len = t.length();
  564. }
  565. return s.length() + len;
  566. }
  567. }
  568. public void testJIRA175() throws Exception {
  569. CtClass cc = loader.get("javassist.bytecode.StackMapTest$C5");
  570. cc.getDeclaredMethod("setter").instrument(new javassist.expr.ExprEditor() {
  571. @Override
  572. public void edit(javassist.expr.FieldAccess f) throws javassist.CannotCompileException {
  573. if (!f.where().getMethodInfo().isMethod())
  574. return;
  575. f.replace("{ $_ = $proceed($$); if (false) return $_;}");
  576. }
  577. });
  578. cc.writeFile();
  579. Object t1 = make(cc.getName());
  580. assertEquals(3, invoke(t1, "test"));
  581. }
  582. public static class C5 {
  583. String value;
  584. int ivalue;
  585. public int test() {
  586. setter("foo");
  587. return value.length();
  588. }
  589. public void setter(String s) {
  590. value = s;
  591. ivalue = s.length();
  592. }
  593. }
  594. public void testJIRA175b() throws Exception {
  595. CtClass cc = loader.get("javassist.bytecode.StackMapTest$C6");
  596. cc.getDeclaredMethod("setter").instrument(new javassist.expr.ExprEditor() {
  597. public void edit(javassist.expr.FieldAccess f) throws javassist.CannotCompileException {
  598. if (!f.where().getMethodInfo().isMethod())
  599. return;
  600. // this will make a 1-byte dead code.
  601. f.replace("{ $_ = $proceed($$); return $_;}");
  602. }
  603. });
  604. cc.writeFile();
  605. }
  606. public static class C6 {
  607. String value;
  608. int ivalue;
  609. public int test() {
  610. setter("foo");
  611. return value.length();
  612. }
  613. public void setter(String s) {
  614. value = s;
  615. ivalue = s.length();
  616. }
  617. }
  618. public void testForHibernate() throws Exception {
  619. ClassFile cf = loader.makeClass("javassist.bytecode.StackMapTestHibTest").getClassFile();
  620. ConstPool cp = cf.getConstPool();
  621. MethodInfo mi = new MethodInfo(cp, "foo", "()V");
  622. Bytecode code = new Bytecode(cp, 0, 0);
  623. code.add(Opcode.RETURN);
  624. CodeAttribute ca = code.toCodeAttribute();
  625. mi.addAttribute(ca);
  626. cf.addMethod(mi);
  627. int pc = 111;
  628. int throwableType_index = cp.addClassInfo(Throwable.class.getName());
  629. StackMapTable.Writer writer = new StackMapTable.Writer(32);
  630. int[] localTags = { StackMapTable.OBJECT, StackMapTable.OBJECT, StackMapTable.OBJECT, StackMapTable.INTEGER };
  631. int[] localData = { cp.getThisClassInfo(), cp.addClassInfo("java/lang/Object"),
  632. cp.addClassInfo("[Ljava/lang/Object;"), 0};
  633. int[] stackTags = { StackMapTable.OBJECT };
  634. int[] stackData = { throwableType_index };
  635. writer.fullFrame(pc, localTags, localData, stackTags, stackData);
  636. ca.setAttribute(writer.toStackMapTable(cp));
  637. cf.write(new java.io.DataOutputStream(new java.io.FileOutputStream("./test-hibernate.class")));
  638. }
  639. public void testCommonSuperclass() throws Exception {
  640. CtClass obj = loader.get("java.lang.Object");
  641. CtClass objarray = loader.get("java.lang.Object[]");
  642. CtClass one = loader.get("byte[]");
  643. CtClass two = loader.get("byte[][]");
  644. assertEquals("java.lang.Object", TypeData.commonSuperClassEx(one, two).getName());
  645. assertTrue(one.subtypeOf(obj));
  646. assertTrue(two.subtypeOf(obj));
  647. assertFalse(one.subtypeOf(objarray));
  648. assertTrue(two.subtypeOf(objarray));
  649. one = loader.get("int[][]");
  650. two = loader.get("java.lang.Object[]");
  651. assertEquals("java.lang.Object[]", TypeData.commonSuperClassEx(one, two).getName());
  652. assertTrue(one.subtypeOf(objarray));
  653. assertTrue(two.subtypeOf(objarray));
  654. one = loader.get("int[]");
  655. two = loader.get("java.lang.String");
  656. assertEquals("java.lang.Object", TypeData.commonSuperClassEx(one, two).getName());
  657. assertTrue(one.subtypeOf(obj));
  658. assertTrue(two.subtypeOf(obj));
  659. assertFalse(one.subtypeOf(objarray));
  660. assertFalse(two.subtypeOf(objarray));
  661. one = loader.get("int[]");
  662. two = loader.get("int[]");
  663. assertEquals("int[]", TypeData.commonSuperClassEx(one, two).getName());
  664. assertTrue(one.subtypeOf(obj));
  665. assertFalse(one.subtypeOf(objarray));
  666. one = loader.get("int[]");
  667. two = loader.get("java.lang.String[]");
  668. assertEquals("java.lang.Object", TypeData.commonSuperClassEx(one, two).getName());
  669. assertTrue(one.subtypeOf(obj));
  670. assertTrue(two.subtypeOf(obj));
  671. assertFalse(one.subtypeOf(objarray));
  672. assertTrue(two.subtypeOf(objarray));
  673. one = loader.get("java.lang.String[]");
  674. two = loader.get("java.lang.Class[]");
  675. assertEquals("java.lang.Object[]", TypeData.commonSuperClassEx(one, two).getName());
  676. assertTrue(one.subtypeOf(objarray));
  677. assertTrue(two.subtypeOf(objarray));
  678. }
  679. public void testJsr() throws Exception {
  680. CtClass cc = loader.makeClass("javassist.bytecode.StackMapTestJsrTest");
  681. ClassFile cf = cc.getClassFile();
  682. cf.setMajorVersion(ClassFile.JAVA_5);
  683. ConstPool cp = cf.getConstPool();
  684. MethodInfo mi = new MethodInfo(cp, "test", "()I");
  685. mi.setAccessFlags(AccessFlag.PUBLIC);
  686. Bytecode code = new Bytecode(cp, 1, 3);
  687. code.addIconst(3);
  688. code.addIstore(1);
  689. code.addIload(1);
  690. code.add(Opcode.IFEQ);
  691. code.addIndex(6);
  692. code.add(Opcode.JSR);
  693. code.addIndex(5);
  694. code.addIload(1);
  695. code.add(Opcode.IRETURN);
  696. code.addAstore(2);
  697. code.addRet(2);
  698. CodeAttribute ca = code.toCodeAttribute();
  699. mi.addAttribute(ca);
  700. mi.rebuildStackMap(loader);
  701. cf.addMethod(mi);
  702. cc.addConstructor(CtNewConstructor.make("public StackMapTestJsrTest() {}", cc));
  703. cc.addMethod(CtMethod.make("public static void main(String[] args) {"
  704. + "new javassist.bytecode.StackMapTestJsrTest().test();"
  705. + "}",
  706. cc));
  707. cc.writeFile();
  708. Object t1 = make(cc.getName());
  709. assertEquals(3, invoke(t1, "test"));
  710. }
  711. public void tstCtClassType() throws Exception {
  712. ClassPool cp = ClassPool.getDefault();
  713. CtClass cc = cp.get("javassist.CtClassType");
  714. MethodInfo minfo = getMethodInfo(cc.getClassFile(), "getFields", "(Ljava/util/ArrayList;Ljavassist/CtClass;)V");
  715. rebuildStackMap(cc, cp, minfo);
  716. }
  717. MethodInfo getMethodInfo(ClassFile cf, String name, String desc) {
  718. List list = cf.getMethods();
  719. Iterator it = list.iterator();
  720. while (it.hasNext()) {
  721. MethodInfo mi = (MethodInfo)it.next();
  722. if (mi.getName().equals(name) && mi.getDescriptor().equals(desc))
  723. return mi;
  724. }
  725. return null;
  726. }
  727. }