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.

TransformNew.java 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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.convert;
  17. import javassist.CannotCompileException;
  18. import javassist.CtClass;
  19. import javassist.bytecode.CodeAttribute;
  20. import javassist.bytecode.CodeIterator;
  21. import javassist.bytecode.ConstPool;
  22. import javassist.bytecode.Descriptor;
  23. import javassist.bytecode.StackMap;
  24. import javassist.bytecode.StackMapTable;
  25. final public class TransformNew extends Transformer {
  26. private int nested;
  27. private String classname, trapClass, trapMethod;
  28. public TransformNew(Transformer next,
  29. String classname, String trapClass, String trapMethod) {
  30. super(next);
  31. this.classname = classname;
  32. this.trapClass = trapClass;
  33. this.trapMethod = trapMethod;
  34. }
  35. @Override
  36. public void initialize(ConstPool cp, CodeAttribute attr) {
  37. nested = 0;
  38. }
  39. /**
  40. * Replace a sequence of
  41. * NEW classname
  42. * DUP
  43. * ...
  44. * INVOKESPECIAL
  45. * with
  46. * NOP
  47. * NOP
  48. * ...
  49. * INVOKESTATIC trapMethod in trapClass
  50. */
  51. @Override
  52. public int transform(CtClass clazz, int pos, CodeIterator iterator,
  53. ConstPool cp) throws CannotCompileException
  54. {
  55. int index;
  56. int c = iterator.byteAt(pos);
  57. if (c == NEW) {
  58. index = iterator.u16bitAt(pos + 1);
  59. if (cp.getClassInfo(index).equals(classname)) {
  60. if (iterator.byteAt(pos + 3) != DUP)
  61. throw new CannotCompileException(
  62. "NEW followed by no DUP was found");
  63. iterator.writeByte(NOP, pos);
  64. iterator.writeByte(NOP, pos + 1);
  65. iterator.writeByte(NOP, pos + 2);
  66. iterator.writeByte(NOP, pos + 3);
  67. ++nested;
  68. StackMapTable smt
  69. = (StackMapTable)iterator.get().getAttribute(StackMapTable.tag);
  70. if (smt != null)
  71. smt.removeNew(pos);
  72. StackMap sm
  73. = (StackMap)iterator.get().getAttribute(StackMap.tag);
  74. if (sm != null)
  75. sm.removeNew(pos);
  76. }
  77. }
  78. else if (c == INVOKESPECIAL) {
  79. index = iterator.u16bitAt(pos + 1);
  80. int typedesc = cp.isConstructor(classname, index);
  81. if (typedesc != 0 && nested > 0) {
  82. int methodref = computeMethodref(typedesc, cp);
  83. iterator.writeByte(INVOKESTATIC, pos);
  84. iterator.write16bit(methodref, pos + 1);
  85. --nested;
  86. }
  87. }
  88. return pos;
  89. }
  90. private int computeMethodref(int typedesc, ConstPool cp) {
  91. int classIndex = cp.addClassInfo(trapClass);
  92. int mnameIndex = cp.addUtf8Info(trapMethod);
  93. typedesc = cp.addUtf8Info(
  94. Descriptor.changeReturnType(classname,
  95. cp.getUtf8Info(typedesc)));
  96. return cp.addMethodrefInfo(classIndex,
  97. cp.addNameAndTypeInfo(mnameIndex, typedesc));
  98. }
  99. }