summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Bruneton <ebruneton@free.fr>2023-09-17 14:11:12 +0200
committerEric Bruneton <ebruneton@free.fr>2023-09-23 19:05:53 +0200
commit5d00fe4ea47b17f3d2e981a18ee447d9b1d32de1 (patch)
tree3b23315074a8c24eefb101e247c5c336f70d0b88
parentc890eac5963700541703445d06c62c18e044d671 (diff)
downloadow2-asm-5d00fe4ea47b17f3d2e981a18ee447d9b1d32de1.tar.gz
Add a getArgumentCount() method in Type.
-rw-r--r--asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java2
-rw-r--r--asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java4
-rw-r--r--asm/src/main/java/org/objectweb/asm/MethodWriter.java4
-rw-r--r--asm/src/main/java/org/objectweb/asm/Type.java61
-rw-r--r--asm/src/test/java/org/objectweb/asm/TypeTest.java28
5 files changed, 76 insertions, 23 deletions
diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java
index 2776fb30..ac3600c7 100644
--- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java
+++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/Frame.java
@@ -672,7 +672,7 @@ public class Frame<V extends Value> {
final AbstractInsnNode insn, final String methodDescriptor, final Interpreter<V> interpreter)
throws AnalyzerException {
ArrayList<V> valueList = new ArrayList<>();
- for (int i = Type.getArgumentTypes(methodDescriptor).length; i > 0; --i) {
+ for (int i = Type.getArgumentCount(methodDescriptor); i > 0; --i) {
valueList.add(0, pop());
}
if (insn.getOpcode() != Opcodes.INVOKESTATIC && insn.getOpcode() != Opcodes.INVOKEDYNAMIC) {
diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java
index 23e3e4c5..8b529a52 100644
--- a/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java
+++ b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java
@@ -294,14 +294,14 @@ public class MethodNode extends MethodVisitor {
AnnotationNode annotation = new AnnotationNode(descriptor);
if (visible) {
if (visibleParameterAnnotations == null) {
- int params = Type.getArgumentTypes(desc).length;
+ int params = Type.getArgumentCount(desc);
visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
}
visibleParameterAnnotations[parameter] =
Util.add(visibleParameterAnnotations[parameter], annotation);
} else {
if (invisibleParameterAnnotations == null) {
- int params = Type.getArgumentTypes(desc).length;
+ int params = Type.getArgumentCount(desc);
invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
}
invisibleParameterAnnotations[parameter] =
diff --git a/asm/src/main/java/org/objectweb/asm/MethodWriter.java b/asm/src/main/java/org/objectweb/asm/MethodWriter.java
index a1e075b6..8cdeec47 100644
--- a/asm/src/main/java/org/objectweb/asm/MethodWriter.java
+++ b/asm/src/main/java/org/objectweb/asm/MethodWriter.java
@@ -694,7 +694,7 @@ final class MethodWriter extends MethodVisitor {
if (visible) {
if (lastRuntimeVisibleParameterAnnotations == null) {
lastRuntimeVisibleParameterAnnotations =
- new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+ new AnnotationWriter[Type.getArgumentCount(descriptor)];
}
return lastRuntimeVisibleParameterAnnotations[parameter] =
AnnotationWriter.create(
@@ -702,7 +702,7 @@ final class MethodWriter extends MethodVisitor {
} else {
if (lastRuntimeInvisibleParameterAnnotations == null) {
lastRuntimeInvisibleParameterAnnotations =
- new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+ new AnnotationWriter[Type.getArgumentCount(descriptor)];
}
return lastRuntimeInvisibleParameterAnnotations[parameter] =
AnnotationWriter.create(
diff --git a/asm/src/main/java/org/objectweb/asm/Type.java b/asm/src/main/java/org/objectweb/asm/Type.java
index 85aab7ea..c60a4233 100644
--- a/asm/src/main/java/org/objectweb/asm/Type.java
+++ b/asm/src/main/java/org/objectweb/asm/Type.java
@@ -295,26 +295,12 @@ public final class Type {
*/
public static Type[] getArgumentTypes(final String methodDescriptor) {
// First step: compute the number of argument types in methodDescriptor.
- int numArgumentTypes = 0;
- // Skip the first character, which is always a '('.
- int currentOffset = 1;
- // Parse the argument types, one at a each loop iteration.
- while (methodDescriptor.charAt(currentOffset) != ')') {
- while (methodDescriptor.charAt(currentOffset) == '[') {
- currentOffset++;
- }
- if (methodDescriptor.charAt(currentOffset++) == 'L') {
- // Skip the argument descriptor content.
- int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
- currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
- }
- ++numArgumentTypes;
- }
+ int numArgumentTypes = getArgumentCount(methodDescriptor);
// Second step: create a Type instance for each argument type.
Type[] argumentTypes = new Type[numArgumentTypes];
// Skip the first character, which is always a '('.
- currentOffset = 1;
+ int currentOffset = 1;
// Parse and create the argument types, one at each loop iteration.
int currentArgumentTypeIndex = 0;
while (methodDescriptor.charAt(currentOffset) != ')') {
@@ -703,13 +689,51 @@ public final class Type {
}
/**
+ * Returns the number of arguments of this method type. This method should only be used for method
+ * types.
+ *
+ * @return the number of arguments of this method type. Each argument counts for 1, even long and
+ * double ones. The implicit @literal{this} argument is not counted.
+ */
+ public int getArgumentCount() {
+ return getArgumentCount(getDescriptor());
+ }
+
+ /**
+ * Returns the number of arguments in the given method descriptor.
+ *
+ * @param methodDescriptor a method descriptor.
+ * @return the number of arguments in the given method descriptor. Each argument counts for 1,
+ * even long and double ones. The implicit @literal{this} argument is not counted.
+ */
+ public static int getArgumentCount(final String methodDescriptor) {
+ int argumentCount = 0;
+ // Skip the first character, which is always a '('.
+ int currentOffset = 1;
+ // Parse the argument types, one at a each loop iteration.
+ while (methodDescriptor.charAt(currentOffset) != ')') {
+ while (methodDescriptor.charAt(currentOffset) == '[') {
+ currentOffset++;
+ }
+ if (methodDescriptor.charAt(currentOffset++) == 'L') {
+ // Skip the argument descriptor content.
+ int semiColumnOffset = methodDescriptor.indexOf(';', currentOffset);
+ currentOffset = Math.max(currentOffset, semiColumnOffset + 1);
+ }
+ ++argumentCount;
+ }
+ return argumentCount;
+ }
+
+ /**
* Returns the size of the arguments and of the return value of methods of this type. This method
* should only be used for method types.
*
* @return the size of the arguments of the method (plus one for the implicit this argument),
* argumentsSize, and the size of its return value, returnSize, packed into a single int i =
* {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
- * i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
+ * i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}). Long and double values have size 2,
+ * the others have size 1.
*/
public int getArgumentsAndReturnSizes() {
return getArgumentsAndReturnSizes(getDescriptor());
@@ -722,7 +746,8 @@ public final class Type {
* @return the size of the arguments of the method (plus one for the implicit this argument),
* argumentsSize, and the size of its return value, returnSize, packed into a single int i =
* {@code (argumentsSize &lt;&lt; 2) | returnSize} (argumentsSize is therefore equal to {@code
- * i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}).
+ * i &gt;&gt; 2}, and returnSize to {@code i &amp; 0x03}). Long and double values have size 2,
+ * the others have size 1.
*/
public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
int argumentsSize = 1;
diff --git a/asm/src/test/java/org/objectweb/asm/TypeTest.java b/asm/src/test/java/org/objectweb/asm/TypeTest.java
index bf52bcd2..ccefc808 100644
--- a/asm/src/test/java/org/objectweb/asm/TypeTest.java
+++ b/asm/src/test/java/org/objectweb/asm/TypeTest.java
@@ -249,6 +249,34 @@ class TypeTest implements Opcodes {
}
@Test
+ void testGetArgumentCountFromType() {
+ assertEquals(
+ 14,
+ Type.getMethodType("(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V")
+ .getArgumentCount());
+ }
+
+ @Test
+ void testGetArgumentCountFromDescriptor() {
+ assertEquals(
+ 14, Type.getArgumentCount("(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V"));
+ assertEquals(0, Type.getArgumentCount("()I"));
+ }
+
+ @Test
+ void testGetArgumentsAndReturnSizeFromType() {
+ assertEquals(
+ 17 << 2,
+ Type.getMethodType("(IZBCSDFJLI;LV;Ljava/lang/Object;[I[LI;[[Ljava/lang/Object;)V")
+ .getArgumentsAndReturnSizes());
+ assertEquals(1 << 2 | 1, Type.getMethodType("()I").getArgumentsAndReturnSizes());
+ assertEquals(1 << 2 | 1, Type.getMethodType("()F").getArgumentsAndReturnSizes());
+ assertEquals(1 << 2 | 2, Type.getMethodType("()J").getArgumentsAndReturnSizes());
+ assertEquals(1 << 2 | 2, Type.getMethodType("()D").getArgumentsAndReturnSizes());
+ assertEquals(1 << 2 | 1, Type.getMethodType("()LD;").getArgumentsAndReturnSizes());
+ }
+
+ @Test
void testGetArgumentsAndReturnSizeFromDescriptor() {
assertEquals(
17 << 2,