asm issueshttps://gitlab.ow2.org/asm/asm/-/issues2017-11-30T14:43:14Zhttps://gitlab.ow2.org/asm/asm/-/issues/316516Add "FrameTrackingAdapter" for incremental stackmap frame updates2017-11-30T14:43:14ZmarchofAdd "FrameTrackingAdapter" for incremental stackmap frame updates```
With the latest Java versions correct stackmap frames become more and more
important. Re-calculating frames is an expensive task and comes with the pain
to figure out type hierarchies ("getCommonSuperClass()").
For most instrumentat...```
With the latest Java versions correct stackmap frames become more and more
important. Re-calculating frames is an expensive task and comes with the pain
to figure out type hierarchies ("getCommonSuperClass()").
For most instrumentation tasks it is possible to incremetally update frames.
For this you need to know the current frame types, to insert additional frames
as needed by your instrumentation code. For the JaCoCo project I developed a
"FrameTracker":
https://github.com/jacoco/jacoco/blob/master/org.jacoco.core/src/org/jacoco/core/internal/instr/FrameTracker.java
It is a MethodVisitor that keeps track of the current types of the local
variables and the operand stack. This class can be used to instrument class
files with stackmap frame information without re-calculating the overall type
information. If the additional code requires an additional frame due to the
control structure it adds this frame can be inserted with a call to insertFrame().
As it seems to be a generic and useful piece of code it might make sense to
provide such functionality directly within ASM. I adjusted the code and its
tests for ASM:
https://github.com/marchof/asm/commit/bffcf692983c9dda2a4e38afcaab8da0fe4e28c2
```https://gitlab.ow2.org/asm/asm/-/issues/316375Add version 52.0 in ASM to support JDK 8 classfiles2017-11-30T14:43:14ZaruldAdd version 52.0 in ASM to support JDK 8 classfiles```
Accept classfiles with major version 52 for JDK 8
http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2012-October/004536.html
Is it possible to add this new version support? IntelliJ IDEA is dependent on
ASM 4, but since the...```
Accept classfiles with major version 52 for JDK 8
http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2012-October/004536.html
Is it possible to add this new version support? IntelliJ IDEA is dependent on
ASM 4, but since the new class file version was merged into lambda repository,
it makes it difficult to use newer lambda builds with Intellij due to this bug
(http://youtrack.jetbrains.com/issue/IDEA-95473).
Attaching a patch that adds support for version 52 in ASM. I haven't tested it,
hope someone can look into this.
```https://gitlab.ow2.org/asm/asm/-/issues/316318Allow generated SVUID field to be marked synthetic2017-11-30T14:43:15ZdjencksAllow generated SVUID field to be marked synthetic```
Apache Aries proxies need to be able to mark generated svuid fields as
synthetic. I think this might generally be a useful feature and is easier to
add to the SerialVersionUIDAdder than to add on with delegation/subclassing.
If you...```
Apache Aries proxies need to be able to mark generated svuid fields as
synthetic. I think this might generally be a useful feature and is easier to
add to the SerialVersionUIDAdder than to add on with delegation/subclassing.
If you don't like this idea can you at least add a getter for the hasSVUID
field (it was protected in asm 3, thus accessible to subclasses).
The attached patch adds the optional capability to mark added SerialVersionUID
fields synthetic and enhances the test to check whether the SerialVersionUID
field is actually added when expected and if the added field is synthetic as
configured.
```https://gitlab.ow2.org/asm/asm/-/issues/313804Improve analysis results2017-11-30T14:43:15ZgpothierImprove analysis results```
Using the BasicVerifier to verify methods, the information about errors is
currently not as useful as it could be, particularly because the instruction
numbers given do not reflect actual bytecode addresses or indexes (because it
is ...```
Using the BasicVerifier to verify methods, the information about errors is
currently not as useful as it could be, particularly because the instruction
numbers given do not reflect actual bytecode addresses or indexes (because it
is the rank of the faulty instruction in the method node's instruction list,
which includes labels, line number info, and so on).
I propose to include a reference to the faulty instruction in the
AnalyzerException class so that a more useful message can be generated by the
client code. The attached patch does precisely this. Then a code snippet like
this one can be used to retrieve the actual bytecode rank of an instruction,
which is very useful when using a tool that numbers the bytecodes, like eg.
jclasslib):
private int getBytecodeRank(MethodNode aNode, AbstractInsnNode aInstruction)
{
if (aInstruction == null) return -1;
int theRank = 1;
ListIterator<AbstractInsnNode> theIterator = aNode.instructions.iterator();
while(theIterator.hasNext())
{
AbstractInsnNode theNode = theIterator.next();
if (theNode == aInstruction) return theRank;
int theOpcode = theNode.getOpcode();
if (theOpcode >= 0) theRank++;
}
return -1;
}
```https://gitlab.ow2.org/asm/asm/-/issues/314119Provide read access to uninitializedTypes in AnalyzerAdapter2017-11-30T14:43:15ZorlovmProvide read access to uninitializedTypes in AnalyzerAdapter```
Beyond locals and stack, uninitialized types are also useful for code analysis
using AnalyzerAdapter (i.e., being able to actually look at the type to be
constructed).
I use the following method:
public Map<Label, String> getUn...```
Beyond locals and stack, uninitialized types are also useful for code analysis
using AnalyzerAdapter (i.e., being able to actually look at the type to be
constructed).
I use the following method:
public Map<Label, String> getUninitializedTypes() {
return Collections.unmodifiableMap(uninitializedTypes);
}
but it's possible to just make the field public, or provide a wrapper around
Map.get() (but then the user might want to do something more complex than a get).
```https://gitlab.ow2.org/asm/asm/-/issues/308745BasicInterpreter.newOperation lacks a throws AnalyzerException clause2017-11-30T14:43:15ZmaisonobeBasicInterpreter.newOperation lacks a throws AnalyzerException clause```
The implementation of newOperation in BasicInterpreter does not declare the
AnalyzerException. This prevents extending the class with a new implementation
that would throw this exception, despite the exception is declared in the
inte...```
The implementation of newOperation in BasicInterpreter does not declare the
AnalyzerException. This prevents extending the class with a new implementation
that would throw this exception, despite the exception is declared in the
interface. This is also inconsistent with the BasicInterpreter.copyOperation
mathod which don't throw any exception but does declare one, which is fine for
extension.
Could a "throws AnalyzerException" clause be added to this base implementation ?
Thanks,
Luc
```https://gitlab.ow2.org/asm/asm/-/issues/317628New jdk9 v53 class file format version were introduced2017-11-30T14:43:15ZskydreamerrNew jdk9 v53 class file format version were introduced```
ClassReader should support v53 class file version
http://hg.openjdk.java.net/jdk9/dev/langtools/rev/b42e6d7b1b99
``````
ClassReader should support v53 class file version
http://hg.openjdk.java.net/jdk9/dev/langtools/rev/b42e6d7b1b99
```https://gitlab.ow2.org/asm/asm/-/issues/308554Method.getMethod(java.lang.reflect.Method)2017-11-30T14:43:15ZyozhMethod.getMethod(java.lang.reflect.Method)```
Please, add static
===
static Method getMethod(java.lang.reflect.Method) {
return new Method(method.getName(), Type.getMethodDescriptor(method));
}
===
and also
===
static Method getMethod(java.lang.reflect.Constructor) {
...```
Please, add static
===
static Method getMethod(java.lang.reflect.Method) {
return new Method(method.getName(), Type.getMethodDescriptor(method));
}
===
and also
===
static Method getMethod(java.lang.reflect.Constructor) {
return new Method("<init>, Type.getConstructorDescriptor(method));
}
===
I use such methods frequently in my program.
```https://gitlab.ow2.org/asm/asm/-/issues/316005Constant pool access2017-11-30T14:43:15ZpfichtnerConstant pool access```
Is there a prefered way to read the entries in the constant pool? I could not
find one.
In the class ClassReader all necessary data is available but it's not accesible
(items are available via #getItem but #getItemCount is missing, ...```
Is there a prefered way to read the entries in the constant pool? I could not
find one.
In the class ClassReader all necessary data is available but it's not accesible
(items are available via #getItem but #getItemCount is missing, field
#maxStringLength is private). To be able to read the data I would need at least
access via getter to this two attributes:
public int getItemCount() {
return items.length;
}
public int getMaxStringLength() {
return maxStringLength;
}
Since both methods do not allow to change attributes' values there is no risk
for adding this methods. On the other side the internal byte[] b is public
mutatable so there would be no increased risk to change items and
maxStringLength to public, too.
Regards Peter
```https://gitlab.ow2.org/asm/asm/-/issues/307378GeneratorAdapter.push(Type) doesnt properly handle primitive types2017-11-30T14:43:16ZivaynbergGeneratorAdapter.push(Type) doesnt properly handle primitive types```
im new to asm and bytecode manipulation in general, so this might not be a bug.
when i was writing some bytecode generation code i noticed that ga.push(type)
doesnt properly handle primitives, so here is the patch.
``````
im new to asm and bytecode manipulation in general, so this might not be a bug.
when i was writing some bytecode generation code i noticed that ga.push(type)
doesnt properly handle primitives, so here is the patch.
```https://gitlab.ow2.org/asm/asm/-/issues/306499Add clone() method to InsnList2017-11-30T14:43:16ZekuleshovAdd clone() method to InsnList```
Add clone() method to InsnList
``````
Add clone() method to InsnList
```https://gitlab.ow2.org/asm/asm/-/issues/306236Provide access to class name, super and interfaces without going trough Class...2017-11-30T14:43:16ZekuleshovProvide access to class name, super and interfaces without going trough ClassReader.accept()```
We can add the following code into the ClassReader's constructor:
...
this.access = readUnsignedShort(index);
this.thisClassName = readClass(index + 2, c);
int v = items[readUnsignedShort(index + 4)];
this.superClassName = ...```
We can add the following code into the ClassReader's constructor:
...
this.access = readUnsignedShort(index);
this.thisClassName = readClass(index + 2, c);
int v = items[readUnsignedShort(index + 4)];
this.superClassName = v == 0 ? null : readUTF8(v, c);
int interfacesCount = readUnsignedShort(index + 6);
this.implementedItfs = new String[interfacesCount];
index += 8;
for (int i = 0; i < interfacesCount; ++i) {
this.implementedItfs[i] = readClass(index, c);
index += 2;
}
but this would require to add new fields in this class...
So, need to check if this impacts performances for CR and CR+CW roundtrip (with
test/perfs tests).
```https://gitlab.ow2.org/asm/asm/-/issues/316212org.objectweb.asm.optimizer.ClassOptimizer does not work with classes in defa...2017-12-12T06:25:41Zpicpromusicorg.objectweb.asm.optimizer.ClassOptimizer does not work with classes in default package```
The line
pkgName = name.substring(0, name.lastIndexOf('/'));
in ClassOptimizer.visit(...) causes an StringArrayOutOfBoundsException when a
class of the default package is passed to the org.objectweb.asm.optimizer.Shrinker.
...```
The line
pkgName = name.substring(0, name.lastIndexOf('/'));
in ClassOptimizer.visit(...) causes an StringArrayOutOfBoundsException when a
class of the default package is passed to the org.objectweb.asm.optimizer.Shrinker.
```https://gitlab.ow2.org/asm/asm/-/issues/316204Analyzer produces incorrect lvt types for jsr return targets when jsr frame c...2017-12-26T09:12:31ZkhoffmanAnalyzer produces incorrect lvt types for jsr return targets when jsr frame changes twice during analysis```
I'm using ASM to perform some analyses that are very sensitive to type
information in the local variable table. Tracking down a problem with the
results of one of the analyses led me to find a rare bug in ASM.
The bug happens when r...```
I'm using ASM to perform some analyses that are very sensitive to type
information in the local variable table. Tracking down a problem with the
results of one of the analyses led me to find a rare bug in ASM.
The bug happens when running BasicInterpreter (and thus Analyzer) on the class
org.eclipse.core.runtime.internal.adaptor.BundleStopper. The problem happens
when you have a JSR instruction that can be reached from two different control
flow paths, one path with more active LVT variables than the other path.
Consider the following (a simplification of the problematic code from
BundleStopper.basicStopBundles()):
for (...) {
try {
Object o1 = new Object();
} catch (Exception e) {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
} finally {
System.out.println("hi");
}
}
This gets compiled such that the end of the try block and the end of the catch
block both JUMP to a label and then immediately executes a JSR to the finally
block (the compiler also could have put a separate JSR at the end of each
block, which would have avoided the bug, but for whatever reason, it chose to
JUMP at the end of each block and then do the JSR).
Now consider what happens if Analyzer happens to process the catch block in the
queue before the try block. The catch block uses more LVT slots, and so when it
JUMPs to the label right before the JSR, initially that label will be populated
with type information for all of those LVT slots.
Then let's say that the JSR subroutine happens to be processed next in the
queue. At the end of the JSR when it reaches the RET instruction, it will merge
its current frame at the end of the JSR (except for variables accessed in the
JSR) with the frame of the calling instruction and merge that with the return
target (the instruction following the JSR instruction). At this point the
calling JSR instruction still have a state with the extra LVT variables, and so
it propagates this to the next instruction (the return target, happens to be a
label).
Eventually the queue contains the if block and at the end of the if block we
merge our LVT state with the JUMP target, which reduces the number of valid LVT
slots at the JSR instruction. The JSR instruction gets processed again, but
there are no changes to be merged (the subroutine by this point already had the
LVT slots that were fewer), and so the analysis terminates.
However, this leaves the return target of the JSR instruction (the instruction
after the JSR instruction) with an LVT that has too be many variables in it.
The key insight to fixing this is to realize that anytime the LVT of a JSR
instruction changes, we must add to the queue the RET instructions of the
relevant subroutine.
I have implemented this in the attached patch, and verified that it works
correctly. The patch uses a map to track the RET instruction(s) that jump to
any JSR return target that have already been processed. When a JSR is processed
in the queue, it always adds these RET instructions into the queue as well
(even if no changes were caused by the JSR instruction itself, if we are
processing the JSR instruction something caused the JSR instruction's state
itself to change, so we just propagate this one step further).
I will be attaching the printout of the LVT/STACK of the actual
BundleStopper.basicStopBundles method anaylsis before the fix and after the
fix, as well as the patch against SVN /tags/ASM_3_3_2 release. I'm also
attaching the .jar file with the .class file that will reproduce the problem.
I also fixed another problem along the way with this patch -- if there are
multiple callers for the same subroutine then the code to add another caller to
the subroutine doesn't update all of the copies of the subroutine in the
subroutines array (because findSubroutine makes a deep copy of the subroutine
for each entry). The fix is to update all of the subroutines entries when a
second caller is added to a subroutine object.
```https://gitlab.ow2.org/asm/asm/-/issues/316188ASM fails to load a class file with ClassCircularityError2017-12-26T09:14:58ZjamesssssASM fails to load a class file with ClassCircularityError```
If you have a class that implements an interface and has a method that assign
itself to a variable of type the interface, ASM fails to load the class with a
ClassCircularityError
Occurs with ASM 3.3.1 and JDK 1.6
``````
If you have a class that implements an interface and has a method that assign
itself to a variable of type the interface, ASM fails to load the class with a
ClassCircularityError
Occurs with ASM 3.3.1 and JDK 1.6
```https://gitlab.ow2.org/asm/asm/-/issues/315984asm-xml.dtd fails to mention FREM element2017-12-26T09:15:34Zseweasm-xml.dtd fails to mention FREM element```
This bug is related to #315942. The DTD and the code are out-of-sync.
``````
This bug is related to #315942. The DTD and the code are out-of-sync.
```https://gitlab.ow2.org/asm/asm/-/issues/3178036.0 not in maven repository2017-12-26T09:25:39Zpdeva6.0 not in maven repositoryneither maven central nor repository.ow2.org seem to contain v6.0.
Only 6.0-beta is available in bothneither maven central nor repository.ow2.org seem to contain v6.0.
Only 6.0-beta is available in bothhttps://gitlab.ow2.org/asm/asm/-/issues/317800Resizing jump instruction adds invalid stack frame to a class without frames2017-12-26T09:26:31ZlauritResizing jump instruction adds invalid stack frame to a class without framesProbably caused by https://gitlab.ow2.org/asm/asm/commit/8648c008d91355420653a072a5146746c293b507
With class version 49 fails with array index out of bounds when reading class, with 50 there is an extra frame that isn't supposed to be th...Probably caused by https://gitlab.ow2.org/asm/asm/commit/8648c008d91355420653a072a5146746c293b507
With class version 49 fails with array index out of bounds when reading class, with 50 there is an extra frame that isn't supposed to be there. Also that extra frame can't be decoded by javap
```java
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class Main implements Opcodes {
public static void main(String... args) {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
cw.visit(49, ACC_PUBLIC + ACC_SUPER, "Test", null, "java/lang/Object", null);
// cw.visit(50, ACC_PUBLIC + ACC_SUPER, "Test", null, "java/lang/Object", null);
{
fv = cw.visitField(0, "b", "Z", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(0, "a", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "Test", "b", "Z");
Label l1 = new Label();
mv.visitJumpInsn(IFEQ, l1);
for (int i = 0; i < 40000; i++) {
mv.visitInsn(NOP);
}
mv.visitLabel(l1);
mv.visitInsn(RETURN);
Label l3 = new Label();
mv.visitLabel(l3);
mv.visitLocalVariable("this", "LTest;", null, l0, l3, 0);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
cw.visitEnd();
byte[] bytes = cw.toByteArray();
ClassReader cr = new ClassReader(bytes);
ClassVisitor cv = new ClassVisitor(ASM5) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodVisitor(ASM5) {
@Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
throw new IllegalStateException("no frames expected");
}
};
}
};
cr.accept(cv, 0);
}
}
```https://gitlab.ow2.org/asm/asm/-/issues/317799class file format was damaged after transform some jkd 1.4 class2017-12-26T09:27:06Zrobert lighteeclass file format was damaged after transform some jkd 1.4 classi am using asm3.3 and jdk1.6 in weblogic & spring envirionment to transform class file which was compiled by JDK1.4,after transfrom,UnsupportedClassVersionError appear. i saved the transformed bytearray to filesystem,and i found that so...i am using asm3.3 and jdk1.6 in weblogic & spring envirionment to transform class file which was compiled by JDK1.4,after transfrom,UnsupportedClassVersionError appear. i saved the transformed bytearray to filesystem,and i found that some class file was damaged,
and i tested in a simple main program which without using weblogic & spring,eveything goes well,can anyone help me ?https://gitlab.ow2.org/asm/asm/-/issues/317797Unexpected behaviour for ClassReader#readUTF82017-12-26T09:27:22ZSam SunUnexpected behaviour for ClassReader#readUTF8Given the index to a `CONSTANT_Utf8_info` struct within the constant pool, and a `ClassReader` instance, I'm unable to read the `CONSTANT_Utf8_info` struct without using reflection to call `ClassReader#readUTF`. This is because the `read...Given the index to a `CONSTANT_Utf8_info` struct within the constant pool, and a `ClassReader` instance, I'm unable to read the `CONSTANT_Utf8_info` struct without using reflection to call `ClassReader#readUTF`. This is because the `readUTF8` actually reads a `CONSTANT_String_info` struct. Is it possible to expose a method which allows reading a `CONSTANT_Utf8_info` struct, or make `readUTF` public?