aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/bytecode/BootstrapMethodsAttribute.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/bytecode/BootstrapMethodsAttribute.java')
-rw-r--r--src/main/javassist/bytecode/BootstrapMethodsAttribute.java103
1 files changed, 81 insertions, 22 deletions
diff --git a/src/main/javassist/bytecode/BootstrapMethodsAttribute.java b/src/main/javassist/bytecode/BootstrapMethodsAttribute.java
index 94a0481f..0fd04cf8 100644
--- a/src/main/javassist/bytecode/BootstrapMethodsAttribute.java
+++ b/src/main/javassist/bytecode/BootstrapMethodsAttribute.java
@@ -2,6 +2,7 @@ package javassist.bytecode;
import java.io.DataInputStream;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Map;
public class BootstrapMethodsAttribute extends AttributeInfo {
@@ -35,6 +36,26 @@ public class BootstrapMethodsAttribute extends AttributeInfo {
* <code>bootstrap_arguments</code>.
*/
public int[] arguments;
+
+ /**
+ * Makes a copy. Class names are replaced according to the
+ * * given <code>Map</code> object.
+ *
+ * @param srcCp the constant pool table from the source
+ * @param destCp the constant pool table used bt new copy
+ * @param classnames pairs of replaced and substituted class names.
+ *
+ * @return new BootstrapMethod
+ */
+ protected BootstrapMethod copy(ConstPool srcCp, ConstPool destCp, Map<String,String> classnames) {
+ int newMethodRef = srcCp.copy(methodRef, destCp, classnames);
+ int[] newArguments = new int[arguments.length];
+
+ for (int i = 0; i < arguments.length; i++)
+ newArguments[i] = srcCp.copy(arguments[i], destCp, classnames);
+
+ return new BootstrapMethod(newMethodRef, newArguments);
+ }
}
BootstrapMethodsAttribute(ConstPool cp, int n, DataInputStream in)
@@ -51,25 +72,8 @@ public class BootstrapMethodsAttribute extends AttributeInfo {
*/
public BootstrapMethodsAttribute(ConstPool cp, BootstrapMethod[] methods) {
super(cp, tag);
- int size = 2;
- for (int i = 0; i < methods.length; i++)
- size += 4 + methods[i].arguments.length * 2;
-
- byte[] data = new byte[size];
- ByteArray.write16bit(methods.length, data, 0); // num_bootstrap_methods
- int pos = 2;
- for (int i = 0; i < methods.length; i++) {
- ByteArray.write16bit(methods[i].methodRef, data, pos);
- ByteArray.write16bit(methods[i].arguments.length, data, pos + 2);
- int[] args = methods[i].arguments;
- pos += 4;
- for (int k = 0; k < args.length; k++) {
- ByteArray.write16bit(args[k], data, pos);
- pos += 2;
- }
- }
- set(data);
+ set(convertMethodsToBytes(methods));
}
/**
@@ -113,12 +117,67 @@ public class BootstrapMethodsAttribute extends AttributeInfo {
BootstrapMethod[] methods = getMethods();
ConstPool thisCp = getConstPool();
for (int i = 0; i < methods.length; i++) {
- BootstrapMethod m = methods[i];
- m.methodRef = thisCp.copy(m.methodRef, newCp, classnames);
- for (int k = 0; k < m.arguments.length; k++)
- m.arguments[k] = thisCp.copy(m.arguments[k], newCp, classnames);
+ methods[i] = methods[i].copy(thisCp, newCp, classnames);
}
return new BootstrapMethodsAttribute(newCp, methods);
}
+
+ /**
+ * add bootstrap method from given <code>ConstPool</code> and <code>BootstrapMethod</code>,
+ * and add it to the specified index. Class names are replaced according to the
+ * given <code>Map</code> object.
+ *
+ * <p>
+ * if the index less than 0 or large than the origin method length, then throw <code>RuntimeException</code>;<br>
+ * if the index large or equals to 0 and less or equals to the origin method length,
+ * then replace the origin method with the new <code>BootstrapMethod srcBm</code> ;<br>
+ * if the index equals to the origin method length, then append the new <code>BootstrapMethod srcBm</code> at
+ * the origin methods tail.
+ * </p>
+ *
+ * @param srcCp the constant pool table of source.
+ * @param srcBm the bootstrap method of source
+ * @param index the new method index on bootstrap methods
+ * @param classnames pairs of replaced and substituted
+ * class names.
+ */
+ public void addMethod(ConstPool srcCp, BootstrapMethod srcBm, int index, Map<String,String> classnames) {
+ BootstrapMethod[] methods = getMethods();
+
+ if (index < 0 || index > methods.length) {
+ throw new RuntimeException("index out of range");
+ }
+
+ if (index == methods.length) {
+ BootstrapMethod[] newBmArray = new BootstrapMethod[methods.length + 1];
+ System.arraycopy(methods, 0, newBmArray, 0, methods.length);
+ methods = newBmArray;
+ }
+
+ methods[index] = srcBm.copy(srcCp, getConstPool(), classnames);
+ set(convertMethodsToBytes(methods));
+ }
+
+ private static byte[] convertMethodsToBytes(BootstrapMethod[] methods) {
+ int size = 2;
+ for (int i = 0; i < methods.length; i++)
+ size += 4 + methods[i].arguments.length * 2;
+
+ byte[] data = new byte[size];
+ ByteArray.write16bit(methods.length, data, 0); // num_bootstrap_methods
+ int pos = 2;
+ for (int i = 0; i < methods.length; i++) {
+ ByteArray.write16bit(methods[i].methodRef, data, pos);
+ ByteArray.write16bit(methods[i].arguments.length, data, pos + 2);
+ int[] args = methods[i].arguments;
+ pos += 4;
+ for (int k = 0; k < args.length; k++) {
+ ByteArray.write16bit(args[k], data, pos);
+ pos += 2;
+ }
+ }
+
+ return data;
+ }
}