asm issueshttps://gitlab.ow2.org/asm/asm/-/issues2017-12-26T10:40:25Zhttps://gitlab.ow2.org/asm/asm/-/issues/315630Visiting a method's local vars before rather than after visiting code2017-12-26T10:40:25ZadinnVisiting a method's local vars before rather than after visiting code```
During a method visit the local variable table is not processed until after the
method code has been visited. This makes it easy to identify the scope of local
variables because the start and end labels offsets are determinate when
v...```
During a method visit the local variable table is not processed until after the
method code has been visited. This makes it easy to identify the scope of local
variables because the start and end labels offsets are determinate when
visitLocalvar is called. Conversely, it makes it hard for transformers which
are trying to track and, possibly, tweak accesses to local variables to
identify whether a specific visitLocalVar instruction refers to a local var or
param with a given name.
The problem is that by the time the transformer gets to see the details of the
variable (name, desc, signature, start position, end position and stack slot)
the code which reads or writes the variable has already been visited. It is
possible to record the local var scopes on a first pass visit and then patch
the code on a second pass. However, this is still not easy because changes
injected during the second pass relocate the start and end positions identified
during the first pass. In any case using a two pass approach forces the second
pass code to employ bytecode offsets instead of labels which feels very un-ASM.
If the local variables were visited before the bytecode the transformer would
be able to override visitLocalVariable to index the local var details by start
label and end label. It could then override visitLabel and detect the situation
where a local var came into scope or went out of scope. This is enough to
enable the transforming code to be aware of which named locals/params are
active and hence to know when a visitVarInsn is referring to a specific named
local variable or param.
One way to support this which would retain backwards compatibility would be to
provide a configuration option which allowed ClassReader and MethodNode
instance to be configured so that they visit local vars before the method
bytecode. This might be tricky if the transforming code also wants to add new
local variables. However, additional local vars should always get appended
further up the stack from any existing local vars and they would not normally
have symbol table info and so would not normally be visited.
Another option would be to retain the current order for the code and lcoal var
table visit but make ClassReader and MethodNode provide extra notifications if
they are expected by the next MethodVisitor in line. For example, Classreader
could read and record the local var info before visiting the code. If it
indexed the local var details by start and end label then when it visits a
label during the code visit it could use these indexes to identify locations
where a local var went in or out of scope. If the MethodVisitor implemented the
following interface then the Classreader could feed it the relevant notifications:
public interface LocalScopeMethodVisitor extends MethodVisitor
{
public void visitLocalScopeStart(String name, String desc, String sig, int
stackSlot);
public void visitLocalScopeEnd(String name, String desc, String sig, int
stackSlot);
}
The current visitLocalVar code could still be called after the code visit was
complete, although it might be appropriate to avoid that if these methods had
already been called.
```https://gitlab.ow2.org/asm/asm/-/issues/315553Allow use of COMPUTE_FRAMES when writing classes whose methods employ JSR/RET2017-12-26T10:40:40ZadinnAllow use of COMPUTE_FRAMES when writing classes whose methods employ JSR/RET```
If you set the COMPUTE_FRAMES flag when creating a ClassWriter then the writer
barfs when it encounters a JSR or a RET. This is a PITA and it would be very
useful if this just worked (TM). My bytecode transformer is suffering because...```
If you set the COMPUTE_FRAMES flag when creating a ClassWriter then the writer
barfs when it encounters a JSR or a RET. This is a PITA and it would be very
useful if this just worked (TM). My bytecode transformer is suffering because
it is injecting code into methods which do not use JSR/RET but the classwriter
is failing to rewrite the class because some of the untransformed methods do
use JSR/RET.
I am not sure quite why this is such a hard thing to do but I guess it must be
to do with handling the code in the target bytecode sequence which the JSR
jumps to rather than handling the JSR instruction itself. At the point where
the JSR occurs the effect is merely to pop a return address off the stack.
If the first JSR into a target bytecode sequence is always a forward reference
then it should be possible to associate the current stack details with the JSR
target at the point where the JSR is encountered and then, when the target
label is visited install the saved stack details as the current stack state.
That should allow the stack layout for the target bytecode to be computed and
frames to be generated as per any other bytecode sequence.
I will be happy to try to write a patch for this and contribute it under a
suitable open source license. Before I do that is there something I should know
about why this was not yet attempted?
regards,
Andrew Dinn
JBoss Principal Software Engineer
Byteman and Transactions Team
```https://gitlab.ow2.org/asm/asm/-/issues/315417LocalVariablesSorter.remap() incorrectly process long/double types2017-12-26T10:40:53Za_glasmanLocalVariablesSorter.remap() incorrectly process long/double types```
LocalVariablesSorter.remap(final int var, final Type type) method contains the following condition:
if (var < firstLocal) {
return var;
}
to check whether the remapping is required.
It works as expected wh...```
LocalVariablesSorter.remap(final int var, final Type type) method contains the following condition:
if (var < firstLocal) {
return var;
}
to check whether the remapping is required.
It works as expected when type size is 1. At the same time when (var == firstLocal - 1) and (type ==
Type.LONG_TYPE) the remapping should be performed. However above condition leads to missing
remapping. As a result maxLocals can be calculated incorrectly.
The following fix is suggested to take into account the long/double types:
if (var + type.getSize() <= firstLocal) {
return var;
}
```https://gitlab.ow2.org/asm/asm/-/issues/315414AnalyzerAdapter.visitFrameTypes incorrectly adds Opcodes.TOP after long types2017-12-26T10:41:09Za_glasmanAnalyzerAdapter.visitFrameTypes incorrectly adds Opcodes.TOP after long types```
Locals passed to visitFrameTypes can already contain Opcodes.TOP after the long
type. At the same time this method adds Opcodes.TOP in any case - it doesn't
check the next item after the long value.
In this case long local values are...```
Locals passed to visitFrameTypes can already contain Opcodes.TOP after the long
type. At the same time this method adds Opcodes.TOP in any case - it doesn't
check the next item after the long value.
In this case long local values are processed incorrectly: we can have the
following: .... Opcodes.LONG, Opcodes.TOP, Opcodes.TOP, ...
As a result we can have incorrect mapping with existing locals and get
incorrect stack map info.
The following fix is suggested to resolve this issue:
if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
if ((i == n - 1) || ((i < n - 1) && (types[i + 1] != Opcodes.TOP))) {
result.add(Opcodes.TOP);
}
}
```https://gitlab.ow2.org/asm/asm/-/issues/315399AnalyzerAdapter.execute() method doesn't process null array correctly for AAL...2017-12-26T10:41:26Za_glasmanAnalyzerAdapter.execute() method doesn't process null array correctly for AALOAD instruction```
AnalyzerAdapter (visitInsn(Opcodes.AALOAD)) fails on the following valid Java
construction with ClassCastException:
Object[] arr = null;
try {
Object obj = arr[0];
} catch(NullPointerException e) {
// .....```
AnalyzerAdapter (visitInsn(Opcodes.AALOAD)) fails on the following valid Java
construction with ClassCastException:
Object[] arr = null;
try {
Object obj = arr[0];
} catch(NullPointerException e) {
// ...
}
The reason is that AnalyzerAdapter.execute() method consider second stack value
as String for AALOAD instruction:
case Opcodes.AALOAD:
pop(1);
t1 = pop();
pushDesc(((String) t1).substring(1));
break;
However in this case the second value on the stack (array type) will be
Opcodes.NULL which causes ClassCastException.
I'd suggest the following fix for this issue:
case Opcodes.AALOAD:
pop(1);
t1 = pop();
if (t1 instanceof String) {
pushDesc(((String) t1).substring(1));
} else {
push("java/lang/Object");
}
break;
```https://gitlab.ow2.org/asm/asm/-/issues/315395Can you add OSGI support to the build?2017-12-26T10:41:35Zpeter_lawreyCan you add OSGI support to the build?```
http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
``````
http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
```https://gitlab.ow2.org/asm/asm/-/issues/315248Bug in CheckClassAdapter? Fails for untransformed class2018-09-03T18:19:09ZjoneianBug in CheckClassAdapter? Fails for untransformed class```
Hi,
I'm using ASM for a project, and am very impressed - really nice to use. I'm a
bit of a novice using ASM so not sure if I have found a bug, or doing something
wrong, but I found behaviour that I found odd.
I was trying to te...```
Hi,
I'm using ASM for a project, and am very impressed - really nice to use. I'm a
bit of a novice using ASM so not sure if I have found a bug, or doing something
wrong, but I found behaviour that I found odd.
I was trying to test my instrumentation by letting it transform every class
loaded by the JVM and came across a class untouched by my instrumentation, but
failed in the CheckClassAdapter. Upon further investigation I found it was
repeatable.
Below is my test case and output. I'm using ASM 3.3, and Sun JDK 1.6.0_05.
Cheers,
Ian
@Test
public void testCheckAdapter() throws Exception {
InputStream classStream =
this.getClass().getClassLoader().getResourceAsStream(SunRsaSign.class.getName()
.replace('.', '/') + ".class");
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(out, true);
CheckClassAdapter.verify(new ClassReader(classStream), false,
pw);
if(out.size() > 0) {
Assert.fail("Should not fail as as haven't done any
transformation from original class. Error is: " + out.toString());
}
}
Which gives the output:
java.lang.AssertionError: Should not fail as as haven't done any transformation
from original class. Error is:
org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 18:
Method owner: expected Ljava/util/Map;, but found Ljava/lang/Object;
at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:291)
at
org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:224)
at
org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:250)
at com.iandjones.canal.ASMTest.testCheckAdapter(ASMTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
va:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.jav
a:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java
:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
41)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:2
0)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:7
3)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:4
6)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestRefere
nce.java:46)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.jav
a:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.ja
va:197)
Caused by: org.objectweb.asm.tree.analysis.AnalyzerException: Method owner:
expected Ljava/util/Map;, but found Ljava/lang/Object;
at
org.objectweb.asm.tree.analysis.BasicVerifier.naryOperation(BasicVerifier.java:
395)
at org.objectweb.asm.tree.analysis.Frame.execute(Frame.java:593)
at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:192)
... 27 more
<init>()V
00000 SunRsaSign . . : : ALOAD 0
00001 SunRsaSign . . : SunRsaSign : LDC "SunRsaSign"
00002 SunRsaSign . . : SunRsaSign String : LDC 1.5
00003 SunRsaSign . . : SunRsaSign String D : LDC "Sun RSA signature
provider"
00004 SunRsaSign . . : SunRsaSign String D String : INVOKESPECIAL
java/security/Provider.<init> (Ljava/lang/String;DLjava/lang/String;)V
00005 SunRsaSign . . : : INVOKESTATIC java/lang/System.getSecurityManager
()Ljava/lang/SecurityManager;
00006 SunRsaSign . . : SecurityManager : IFNONNULL L0
00007 SunRsaSign . . : : ALOAD 0
00008 SunRsaSign . . : SunRsaSign : GOTO L1
00009 SunRsaSign . . : : L0
00010 SunRsaSign . . : : NEW java/util/HashMap
00011 SunRsaSign . . : HashMap : DUP
00012 SunRsaSign . . : HashMap HashMap : INVOKESPECIAL
java/util/HashMap.<init> ()V
00013 SunRsaSign . . : Object : L1
00014 SunRsaSign . . : Object : ASTORE 1
00015 SunRsaSign Object . : : ALOAD 1
00016 SunRsaSign Object . : Object : LDC "KeyFactory.RSA"
00017 SunRsaSign Object . : Object String : LDC
"sun.security.rsa.RSAKeyFactory"
00018 SunRsaSign Object . : Object String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00019 SunRsaSign HashMap . : Object : POP
00020 SunRsaSign HashMap . : : ALOAD 1
00021 SunRsaSign HashMap . : HashMap : LDC "KeyPairGenerator.RSA"
00022 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSAKeyPairGenerator"
00023 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00024 SunRsaSign HashMap . : Object : POP
00025 SunRsaSign HashMap . : : ALOAD 1
00026 SunRsaSign HashMap . : HashMap : LDC "Signature.MD2withRSA"
00027 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$MD2withRSA"
00028 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00029 SunRsaSign HashMap . : Object : POP
00030 SunRsaSign HashMap . : : ALOAD 1
00031 SunRsaSign HashMap . : HashMap : LDC "Signature.MD5withRSA"
00032 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$MD5withRSA"
00033 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00034 SunRsaSign HashMap . : Object : POP
00035 SunRsaSign HashMap . : : ALOAD 1
00036 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA1withRSA"
00037 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA1withRSA"
00038 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00039 SunRsaSign HashMap . : Object : POP
00040 SunRsaSign HashMap . : : ALOAD 1
00041 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA256withRSA"
00042 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA256withRSA"
00043 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00044 SunRsaSign HashMap . : Object : POP
00045 SunRsaSign HashMap . : : ALOAD 1
00046 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA384withRSA"
00047 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA384withRSA"
00048 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00049 SunRsaSign HashMap . : Object : POP
00050 SunRsaSign HashMap . : : ALOAD 1
00051 SunRsaSign HashMap . : HashMap : LDC "Signature.SHA512withRSA"
00052 SunRsaSign HashMap . : HashMap String : LDC
"sun.security.rsa.RSASignature$SHA512withRSA"
00053 SunRsaSign HashMap . : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00054 SunRsaSign HashMap . : Object : POP
00055 SunRsaSign HashMap . : : LDC
"java.security.interfaces.RSAPublicKey|java.security.interfaces.RSAPrivateKey"
00056 SunRsaSign HashMap . : String : ASTORE 2
00057 SunRsaSign HashMap String : : ALOAD 1
00058 SunRsaSign HashMap String : HashMap : LDC "Signature.MD2withRSA
SupportedKeyClasses"
00059 SunRsaSign HashMap String : HashMap String : ALOAD 2
00060 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00061 SunRsaSign HashMap String : Object : POP
00062 SunRsaSign HashMap String : : ALOAD 1
00063 SunRsaSign HashMap String : HashMap : LDC "Signature.MD5withRSA
SupportedKeyClasses"
00064 SunRsaSign HashMap String : HashMap String : ALOAD 2
00065 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00066 SunRsaSign HashMap String : Object : POP
00067 SunRsaSign HashMap String : : ALOAD 1
00068 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA1withRSA
SupportedKeyClasses"
00069 SunRsaSign HashMap String : HashMap String : ALOAD 2
00070 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00071 SunRsaSign HashMap String : Object : POP
00072 SunRsaSign HashMap String : : ALOAD 1
00073 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA256withRSA
SupportedKeyClasses"
00074 SunRsaSign HashMap String : HashMap String : ALOAD 2
00075 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00076 SunRsaSign HashMap String : Object : POP
00077 SunRsaSign HashMap String : : ALOAD 1
00078 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA384withRSA
SupportedKeyClasses"
00079 SunRsaSign HashMap String : HashMap String : ALOAD 2
00080 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00081 SunRsaSign HashMap String : Object : POP
00082 SunRsaSign HashMap String : : ALOAD 1
00083 SunRsaSign HashMap String : HashMap : LDC "Signature.SHA512withRSA
SupportedKeyClasses"
00084 SunRsaSign HashMap String : HashMap String : ALOAD 2
00085 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00086 SunRsaSign HashMap String : Object : POP
00087 SunRsaSign HashMap String : : ALOAD 1
00088 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyFactory.1.2.840.113549.1.1"
00089 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00090 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00091 SunRsaSign HashMap String : Object : POP
00092 SunRsaSign HashMap String : : ALOAD 1
00093 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1"
00094 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00095 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00096 SunRsaSign HashMap String : Object : POP
00097 SunRsaSign HashMap String : : ALOAD 1
00098 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1"
00099 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00100 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00101 SunRsaSign HashMap String : Object : POP
00102 SunRsaSign HashMap String : : ALOAD 1
00103 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1"
00104 SunRsaSign HashMap String : HashMap String : LDC "RSA"
00105 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00106 SunRsaSign HashMap String : Object : POP
00107 SunRsaSign HashMap String : : ALOAD 1
00108 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.2"
00109 SunRsaSign HashMap String : HashMap String : LDC "MD2withRSA"
00110 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00111 SunRsaSign HashMap String : Object : POP
00112 SunRsaSign HashMap String : : ALOAD 1
00113 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.2"
00114 SunRsaSign HashMap String : HashMap String : LDC "MD2withRSA"
00115 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00116 SunRsaSign HashMap String : Object : POP
00117 SunRsaSign HashMap String : : ALOAD 1
00118 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.4"
00119 SunRsaSign HashMap String : HashMap String : LDC "MD5withRSA"
00120 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00121 SunRsaSign HashMap String : Object : POP
00122 SunRsaSign HashMap String : : ALOAD 1
00123 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.4"
00124 SunRsaSign HashMap String : HashMap String : LDC "MD5withRSA"
00125 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00126 SunRsaSign HashMap String : Object : POP
00127 SunRsaSign HashMap String : : ALOAD 1
00128 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.5"
00129 SunRsaSign HashMap String : HashMap String : LDC "SHA1withRSA"
00130 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00131 SunRsaSign HashMap String : Object : POP
00132 SunRsaSign HashMap String : : ALOAD 1
00133 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.5"
00134 SunRsaSign HashMap String : HashMap String : LDC "SHA1withRSA"
00135 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00136 SunRsaSign HashMap String : Object : POP
00137 SunRsaSign HashMap String : : ALOAD 1
00138 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.3.14.3.2.29"
00139 SunRsaSign HashMap String : HashMap String : LDC "SHA1withRSA"
00140 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00141 SunRsaSign HashMap String : Object : POP
00142 SunRsaSign HashMap String : : ALOAD 1
00143 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.11"
00144 SunRsaSign HashMap String : HashMap String : LDC "SHA256withRSA"
00145 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00146 SunRsaSign HashMap String : Object : POP
00147 SunRsaSign HashMap String : : ALOAD 1
00148 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.11"
00149 SunRsaSign HashMap String : HashMap String : LDC "SHA256withRSA"
00150 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00151 SunRsaSign HashMap String : Object : POP
00152 SunRsaSign HashMap String : : ALOAD 1
00153 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.12"
00154 SunRsaSign HashMap String : HashMap String : LDC "SHA384withRSA"
00155 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00156 SunRsaSign HashMap String : Object : POP
00157 SunRsaSign HashMap String : : ALOAD 1
00158 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.12"
00159 SunRsaSign HashMap String : HashMap String : LDC "SHA384withRSA"
00160 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00161 SunRsaSign HashMap String : Object : POP
00162 SunRsaSign HashMap String : : ALOAD 1
00163 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.1.2.840.113549.1.1.13"
00164 SunRsaSign HashMap String : HashMap String : LDC "SHA512withRSA"
00165 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00166 SunRsaSign HashMap String : Object : POP
00167 SunRsaSign HashMap String : : ALOAD 1
00168 SunRsaSign HashMap String : HashMap : LDC
"Alg.Alias.Signature.OID.1.2.840.113549.1.1.13"
00169 SunRsaSign HashMap String : HashMap String : LDC "SHA512withRSA"
00170 SunRsaSign HashMap String : HashMap String String : INVOKEINTERFACE
java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
00171 SunRsaSign HashMap String : Object : POP
00172 SunRsaSign HashMap String : : ALOAD 1
00173 SunRsaSign HashMap String : HashMap : ALOAD 0
00174 SunRsaSign HashMap String : HashMap SunRsaSign : IF_ACMPEQ L2
00175 SunRsaSign HashMap String : : NEW sun/security/action/PutAllAction
00176 SunRsaSign HashMap String : PutAllAction : DUP
00177 SunRsaSign HashMap String : PutAllAction PutAllAction : ALOAD 0
00178 SunRsaSign HashMap String : PutAllAction PutAllAction SunRsaSign :
ALOAD 1
00179 SunRsaSign HashMap String : PutAllAction PutAllAction SunRsaSign HashMap
: INVOKESPECIAL sun/security/action/PutAllAction.<init>
(Ljava/security/Provider;Ljava/util/Map;)V
00180 SunRsaSign HashMap String : PutAllAction : INVOKESTATIC
java/security/AccessController.doPrivileged
(Ljava/security/PrivilegedAction;)Ljava/lang/Object;
00181 SunRsaSign HashMap String : Object : POP
00182 SunRsaSign HashMap String : : L2
00183 SunRsaSign HashMap String : : RETURN
at org.junit.Assert.fail(Assert.java:91)
at com.iandjones.canal.ASMTest.testCheckAdapter(ASMTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
va:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.jav
a:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java
:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
41)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:2
0)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:7
3)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:4
6)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestRefere
nce.java:46)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunne
r.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.jav
a:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.ja
va:197)
```https://gitlab.ow2.org/asm/asm/-/issues/315135COMPUTE_FRAMES with CheckClassAdapter gives IndexOutOfBoundsException2018-01-21T09:34:20ZapmckinlayCOMPUTE_FRAMES with CheckClassAdapter gives IndexOutOfBoundsException```
This code:
public Object call(Object self, Object... args) {
return null;
}
run through Bytecode Outline, and then edited slightly to get:
import org.objectweb.asm.*;
import org.objectweb.asm.util.CheckClassAdapter;
public cl...```
This code:
public Object call(Object self, Object... args) {
return null;
}
run through Bytecode Outline, and then edited slightly to get:
import org.objectweb.asm.*;
import org.objectweb.asm.util.CheckClassAdapter;
public class TestAsm implements Opcodes {
public static void main(String[] args) throws Exception {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor cv = new CheckClassAdapter(cw);
MethodVisitor mv;
cv.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "suneido/language/SampleFunction",
null, "suneido/language/SuFunction", null);
mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "call",
"(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
Label l3 = new Label();
mv.visitLabel(l3);
mv.visitLocalVariable("this", "Lsuneido/language/SampleFunction;", null, l0, l3, 0);
mv.visitLocalVariable("self", "Ljava/lang/Object;", null, l0, l3, 1);
mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l0, l3, 2);
mv.visitMaxs(0, 0);
mv.visitEnd();
cv.visitEnd();
}
}
gives:
java.lang.IndexOutOfBoundsException: Trying to access an inexistant local variable 0
at org.objectweb.asm.tree.analysis.Frame.setLocal(Unknown Source)
at org.objectweb.asm.tree.analysis.Analyzer.analyze(Unknown Source)
at org.objectweb.asm.util.CheckMethodAdapter$1.visitEnd(Unknown Source)
at org.objectweb.asm.util.CheckMethodAdapter.visitEnd(Unknown Source)
at suneido.language.TestAsm.main(TestAsm.java:29)
Exception in thread "main" java.lang.RuntimeException: Trying to access an inexistant local variable 0
call(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
00000 ? : L0
00001 ? : ACONST_NULL
00002 ? : ARETURN
00003 ? : L1
at org.objectweb.asm.util.CheckMethodAdapter$1.visitEnd(Unknown Source)
at org.objectweb.asm.util.CheckMethodAdapter.visitEnd(Unknown Source)
at suneido.language.TestAsm.main(TestAsm.java:29)
If I turn off data flow checking it works.
With visitMaxs(1, 3) or visitMaxs(99, 99) it works (with or without COMPUTE_FRAMES)
Is it possible to use CheckClassAdapter with COMPUTE_FRAMES?
My apologies in advance if I'm doing something stupid. I've searched but couldn't find an answer.
```https://gitlab.ow2.org/asm/asm/-/issues/315096ASM transforms LDC_W instructions to LDC2017-12-26T10:43:06ZcowwocASM transforms LDC_W instructions to LDC```
Repro steps:
1) Compile this testcase:
public class Testcase
{
public static void main(String[] args)
{
Class<?> c = Testcase.class;
}
}
2) javap -c -p Testcase.class gives:
public class Testcase extends java.lang.Objec...```
Repro steps:
1) Compile this testcase:
public class Testcase
{
public static void main(String[] args)
{
Class<?> c = Testcase.class;
}
}
2) javap -c -p Testcase.class gives:
public class Testcase extends java.lang.Object {
public Testcase();
Code:
0: aload_0
1: invokespecial #9 // Method java/lang/Object."<init>":
()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc_w #2 // class Testcase
2: astore_1
3: return
}
3) Process the class using ASM 3.3 as follows:
BufferedInputStream in = new BufferedInputStream(new FileInputStream(inputFile));
ClassReader classReader = new ClassReader(in);
BufferedOutputStream out = new BufferedOutputStream(new
FileOutputStream(outputFile));
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classReader.accept(classWriter, 0);
out.write(classWriter.toByteArray());
out.close();
4) javap -c -p Testcase.class now gives:
public class Testcase extends java.lang.Object {
public Testcase();
Code:
0: aload_0
1: invokespecial #9 // Method java/lang/Object."<init>":
()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // class Testcase
2: astore_1
3: return
}
5) Notice that the LDC_W instruction in the main() method was transformed into
a LDC.
```https://gitlab.ow2.org/asm/asm/-/issues/314982Method annotations are not remapped2017-12-26T10:43:20ZbriankMethod annotations are not remapped```
Annotations on methods are not remapped when using the RemappingClassAdapter.
There is a bug in the RemappingMethodAdapter that doesn't remap the annotations.
``````
Annotations on methods are not remapped when using the RemappingClassAdapter.
There is a bug in the RemappingMethodAdapter that doesn't remap the annotations.
```https://gitlab.ow2.org/asm/asm/-/issues/314969Counterintuitive interaction of arguments to ClassWriter(cr, flags)2017-12-26T10:44:37ZseweCounterintuitive interaction of arguments to ClassWriter(cr, flags)```
Currently, no stack map tables are inserted if a method can simply be copied
from ClassReader to ClassWriter. At least to me this is counterintuitive, though.
IMHO, the correct thing to do would be to never copy methods if either
CO...```
Currently, no stack map tables are inserted if a method can simply be copied
from ClassReader to ClassWriter. At least to me this is counterintuitive, though.
IMHO, the correct thing to do would be to never copy methods if either
COMPUTE_FRAMES or COMPUTE_MAXS is set. But at the very least the JavaDoc of
ClassWriter(cf, flags) should make this interaction very clear.
```https://gitlab.ow2.org/asm/asm/-/issues/314964AnalyzerAdapter does not treat <init> calls correctly2017-12-26T10:44:47ZseweAnalyzerAdapter does not treat <init> calls correctly```
This issue has been discussed on the mailing list already:
<http://mail.ow2.org/wws/arc/asm/2010-03/msg00013.html>. At least to Eugene my
understanding of the issue is correct
<http://mail.ow2.org/wws/arc/asm/2010-03/msg00014.html>; ...```
This issue has been discussed on the mailing list already:
<http://mail.ow2.org/wws/arc/asm/2010-03/msg00013.html>. At least to Eugene my
understanding of the issue is correct
<http://mail.ow2.org/wws/arc/asm/2010-03/msg00014.html>; after a constructor
call of the form SuperClass.<init>() the AnalyzerAdapter should label the top
of stack with *SubClass*, not SuperClass. But the code says otherwise:
[...]
if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') {
Object u;
if (t == Opcodes.UNINITIALIZED_THIS) {
u = owner; // argument of visitMethodInsn, not this.owner!
}
[...]
```https://gitlab.ow2.org/asm/asm/-/issues/314944visitLocalVariable skips index for long parameter2017-12-26T10:45:00ZmindlessvisitLocalVariable skips index for long parameter```
Consider a class with a method like:
public void test(long x, String y) { ... }
When using ClassReader.accept() to traverse the methods, the "index" value for
the visitLocalVariable calls of "x" and "y" will not be consecutive. Fo...```
Consider a class with a method like:
public void test(long x, String y) { ... }
When using ClassReader.accept() to traverse the methods, the "index" value for
the visitLocalVariable calls of "x" and "y" will not be consecutive. For some
reason after a parameter of type "long" the next index will be skipped.
I have seen this in asm 2.2.3 and 3.2. Is this considered a bug? In
collecting parameter info I was expecting sequential index values.
```https://gitlab.ow2.org/asm/asm/-/issues/314934ASM Handling of method Synthetic attribute causes exception during retransfor...2017-12-26T10:45:22ZmchrASM Handling of method Synthetic attribute causes exception during retransformation```
I have written a Java Agent (using the java.lang.instrument interface) that
uses ASM to transform classes. My Agent supports retransformation to allow
classes to be restored to their original bytes at runtime.
This process fails whe...```
I have written a Java Agent (using the java.lang.instrument interface) that
uses ASM to transform classes. My Agent supports retransformation to allow
classes to be restored to their original bytes at runtime.
This process fails when I work with a class which includes a method with the
"Synthetic" attribute. When I attempt to retransform the class back to its
source bytes I get the following exception.
java.lang.UnsupportedOperationException: class redefinition failed: attempted
to change method modifiers
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at
sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:124)
...
Section 4.8.7 of
http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf
states that a method can be marked as "Synthetic" using either an access bit or
an Attribute.
I have determined that the exception above is caused by ASM transforming the
source method (which has the Synthetic attribute) into a method without the
Synthetic attribute but with the synthetic access bit set. These are
semantically the same but the JVM evidently does not support switching between
these approaches at runtime.
This bug can be fixed by commenting out lines 740-741 of
org\objectweb\asm\ClassReader.java:
else if ("Synthetic".equals(attrName)) {
access |= Opcodes.ACC_SYNTHETIC;
}
With these lines commented out the synthetic attribute is not translated into a
synthetic bit.
There are similar blocks of code on the following lines.
535-536: Class level synethetic handling
645-646: Field level synethetic handling
These have not directly caused me problems but I suspect they will suffer from
the same problem.
```https://gitlab.ow2.org/asm/asm/-/issues/314746Abstract Syntax Tree (package tree.ast)2017-12-26T10:46:11ZidshiftAbstract Syntax Tree (package tree.ast)```
A contextually aware extension for the tree package.
The majority of instructions (NOP excluded) play with the stack and thus have a
relationship with previous instructions. For the purpose of extensibility, tree
should offer some ...```
A contextually aware extension for the tree package.
The majority of instructions (NOP excluded) play with the stack and thus have a
relationship with previous instructions. For the purpose of extensibility, tree
should offer some form of the Node complex which is aware of the instructions
that directly affect its functionality.
For example, presented with the given code fragment
ALOAD_1
GETFIELD a.b I
ICONST_M1
ICONST_M1
IXOR
IF_ICMPEQ
And when visiting IF_ICMPEQ, having an abstract means of doing something like
"IF_ICMPEQ.getComparisonRight()" which would return a "Statement", a chunk of
instructions, equivelant to
ICONST_M1
ICONST_M1
IXOR
Where ".getComparisonLeft()" would return
ALOAD_1
GETFIELD a.b I
And so on. Other functionality could included MethodInsnStatement, which has
awareness such as "getArgument(int index)", and "getInstance()". A "remove"
function which drops the Node and its context from the InsnList... The
Statement class is a possible abstract super class, with a special "InsnList"
that instead of containing Nodes contains a series of linked Statements.
Frame's could be calculated on a Statement basis.
The functionality such a package would provide is boundless.
Very Respectfully,
Jay
```https://gitlab.ow2.org/asm/asm/-/issues/314719method length is sometimes calculated incorrectly2018-01-20T10:15:51Zdgulottamethod length is sometimes calculated incorrectly```
asm sometimes writes an incorrect method length to a class file. Attached is a
malformed class file produced by asm.
``````
asm sometimes writes an incorrect method length to a class file. Attached is a
malformed class file produced by asm.
```https://gitlab.ow2.org/asm/asm/-/issues/314701Improper signature when parsing an enum2017-12-26T10:47:24Zmdhirsch30345Improper signature when parsing an enum```
ASM 3.2 is giving me contradictory information about the constructor of an
enum. The description (i.e. the type erased signature) seems right and the
signature seems wrong.
I have a simple enum:
public enum MyEnum {
MINE;
}
I'...```
ASM 3.2 is giving me contradictory information about the constructor of an
enum. The description (i.e. the type erased signature) seems right and the
signature seems wrong.
I have a simple enum:
public enum MyEnum {
MINE;
}
I've implemented a simple ClassVisitor named ClassPrinter which I run like so:
public static void main(String[] args) {
try {
ClassPrinter cp = new ClassPrinter();
final InputStream stream =
ClassLoader.getSystemResourceAsStream("MyEnum.class");
ClassReader cr = new ClassReader(stream);
cr.accept(cp, 0);
} catch (IOException e) {
e.printStackTrace();
}
}
The ClassPrinter just prints the information each visit method gets. When the
constructor of the MyEnum is called, this is the critical information:
method: <init>
desc: (Ljava/lang/String;I)V
sig: ()V
access: private
So the description says that the constructor takes a string and an int and
returns void, while the signature says the constructor takes no arguments and
returns void. If I print out the class with javap, it show the same
information as the description.
Particularly confusing to me is that for every other example I've worked
through, if the description is complete, i.e. there are no generics in the
method, then the signature is always null. Why in this case is the signature
non-null and wrong?
I'm using JDK 1.6.0_16 to compile and run this example.
```https://gitlab.ow2.org/asm/asm/-/issues/314690lists should use generics2017-12-26T10:47:51Zdgulottalists should use generics```
It would be nice if, for example, MethodNode.tryCatchBlocks was a
List<TryCatchBlockNode> instead of just a List.
``````
It would be nice if, for example, MethodNode.tryCatchBlocks was a
List<TryCatchBlockNode> instead of just a List.
```https://gitlab.ow2.org/asm/asm/-/issues/314592Incorrect stack frame handling in AnalyzerAdapter2017-12-26T10:48:11ZtrkropIncorrect stack frame handling in AnalyzerAdapter```
Hi all,
I use the AnalyzerAdapter for tracking the stack frames as suggested
in the documentation. At certain points I copy the state (locals and
stack) for later recovery.
When I replay the state using visitFrame(...), it is not r...```
Hi all,
I use the AnalyzerAdapter for tracking the stack frames as suggested
in the documentation. At certain points I copy the state (locals and
stack) for later recovery.
When I replay the state using visitFrame(...), it is not recovered
as expected. The problem is that the following function introduces
an additional TOP for each LONG and DOUBLE:
private static void visitFrameTypes(
final int n,
final Object[] types,
final List result)
{
for (int i = 0; i < n; ++i) {
Object type = types[i];
result.add(type);
if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
result.add(Opcodes.TOP);
}
}
}
May be I misused the AnalyzerAdapter, when I introduced it behind
the transforming class. Actually I might change this, but I think
the problem is more general and would result in incorrect informa-
tion whenever there are LONGs and DOUBLEs on the stack before the
AnalyzerAdapter gets called. If the Language Specs expect TOPs on
the stack, than the function should assume them to exist, itself.
Thus, the function should either check for TOPs after LONG or
DOUBLE as below or ignore such concerns completely, as shown
below:
private static void visitFrameTypes(
final int n,
final Object[] types,
final List result)
{
for (int i = 0; i < n; ++i) {
Object type = types[i];
result.add(type);
if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
if ((index++ > size) || (types[index] != Opcodes.TOP)) {
throw new IllegalArgumentException("error: stack/locals");
}
result.add(Opcodes.TOP);
}
}
}
private static void visitFrameTypes(
final int n,
final Object[] types,
final List result)
{
for (int i = 0; i < n; ++i) {
result.add(types[i]);
}
}
Both behaviors would be acceptable.
```https://gitlab.ow2.org/asm/asm/-/issues/314563exception from asm.commons.LocalVariablesSorterremap2017-12-26T10:48:24Zsander24exception from asm.commons.LocalVariablesSorterremap```
hi,
got a strange exception from mentioned class.. i'm actually using jarjar which
in turn is using asm-commons, but i'm 90% sure the exception is yours.. namely,
when i write:
public void someMethod() {
String line;
...```
hi,
got a strange exception from mentioned class.. i'm actually using jarjar which
in turn is using asm-commons, but i'm 90% sure the exception is yours.. namely,
when i write:
public void someMethod() {
String line;
// and use it later..
i get:
java.lang.IllegalStateException: Unknown local variable 1
at com.tonicsystems.jarjar.asm.commons.LocalVariablesSorter.remap(Unknown Source)
at com.tonicsystems.jarjar.asm.commons.LocalVariablesSorter.visitFrame(Unknown
Source)
at
com.tonicsystems.jarjar.asm.commons.RemappingMethodAdapter.visitFrame(Unknown
Source)
at com.tonicsystems.jarjar.asm.ClassReader.accept(Unknown Source)
at com.tonicsystems.jarjar.asm.ClassReader.accept(Unknown Source)
at com.tonicsystems.jarjar.ext_util.JarTransformer.process(JarTransformer.java:35)
at
com.tonicsystems.jarjar.ext_util.JarProcessorChain.process(JarProcessorChain.java:31)
....
(never mind about the package names being renamed.. that's what jarjar is about)
Why i'm sure this is a bug is that this exception disappears when i instead write:
public void someMethod() {
String line = null;
// and use it later..
sry, no time to dig for the reason myself.. np, i just work around this myself
but maybe it's a bug you'd like to fix ;)
```