Commit 01a551c4 authored by Eric Bruneton's avatar Eric Bruneton

Move the code to replace the ASM specific instructions to a separate method.

parent 71a78ab5
......@@ -644,35 +644,48 @@ public class ClassWriter extends ClassVisitor {
firstAttribute.putAttributes(symbolTable, result);
}
// Third step: do a ClassReader->ClassWriter round trip if the generated class contains ASM
// specific instructions due to large forward jumps.
// Third step: replace the ASM specific instructions, if any.
if (hasAsmInstructions) {
Attribute[] attributes = getAttributePrototypes();
firstField = null;
lastField = null;
firstMethod = null;
lastMethod = null;
lastRuntimeVisibleAnnotation = null;
lastRuntimeInvisibleAnnotation = null;
lastRuntimeVisibleTypeAnnotation = null;
lastRuntimeInvisibleTypeAnnotation = null;
moduleWriter = null;
nestHostClassIndex = 0;
numberOfNestMemberClasses = 0;
nestMemberClasses = null;
firstAttribute = null;
compute = hasFrames ? MethodWriter.COMPUTE_INSERTED_FRAMES : MethodWriter.COMPUTE_NOTHING;
new ClassReader(result.data, 0, /* checkClassVersion = */ false)
.accept(
this,
attributes,
(hasFrames ? ClassReader.EXPAND_FRAMES : 0) | ClassReader.EXPAND_ASM_INSNS);
return toByteArray();
return replaceAsmInstructions(result.data, hasFrames);
} else {
return result.data;
}
}
/**
* Returns the equivalent of the given class file, with the ASM specific instructions replaced
* with standard ones. This is done with a ClassReader -> ClassWriter round trip.
*
* @param classFile a class file containing ASM specific instructions, generated by this
* ClassWriter.
* @param hasFrames whether there is at least one stack map frames in 'classFile'.
* @return an equivalent of 'classFile', with the ASM specific instructions replaced with standard
* ones.
*/
private byte[] replaceAsmInstructions(final byte[] classFile, final boolean hasFrames) {
Attribute[] attributes = getAttributePrototypes();
firstField = null;
lastField = null;
firstMethod = null;
lastMethod = null;
lastRuntimeVisibleAnnotation = null;
lastRuntimeInvisibleAnnotation = null;
lastRuntimeVisibleTypeAnnotation = null;
lastRuntimeInvisibleTypeAnnotation = null;
moduleWriter = null;
nestHostClassIndex = 0;
numberOfNestMemberClasses = 0;
nestMemberClasses = null;
firstAttribute = null;
compute = hasFrames ? MethodWriter.COMPUTE_INSERTED_FRAMES : MethodWriter.COMPUTE_NOTHING;
new ClassReader(classFile, 0, /* checkClassVersion = */ false)
.accept(
this,
attributes,
(hasFrames ? ClassReader.EXPAND_FRAMES : 0) | ClassReader.EXPAND_ASM_INSNS);
return toByteArray();
}
/**
* Returns the prototypes of the attributes used by this class, its fields and its methods.
*
......
......@@ -55,8 +55,8 @@ public class ClassWriterTest extends AsmTest {
/**
* Tests that the non-static fields of ClassWriter are the expected ones. This test is designed to
* fail each time new fields are added to ClassWriter, and serves as a reminder to update the
* field reset logic in {@link ClassWriter#toByteArray()}, if needed, each time a new field is
* added.
* field reset logic in {@link ClassWriter#replaceAsmInstructions()}, if needed, each time a new
* field is added.
*/
@Test
public void testInstanceFields() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment