• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.classfile.editor;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.attribute.*;
25 import proguard.classfile.attribute.annotation.*;
26 import proguard.classfile.attribute.annotation.visitor.*;
27 import proguard.classfile.attribute.preverification.*;
28 import proguard.classfile.attribute.preverification.visitor.*;
29 import proguard.classfile.attribute.visitor.*;
30 import proguard.classfile.constant.*;
31 import proguard.classfile.constant.visitor.ConstantVisitor;
32 import proguard.classfile.instruction.*;
33 import proguard.classfile.instruction.visitor.InstructionVisitor;
34 import proguard.classfile.util.SimplifiedVisitor;
35 import proguard.classfile.visitor.*;
36 
37 /**
38  * This ClassVisitor remaps all possible references to constant pool entries
39  * of the classes that it visits, based on a given index map. It is assumed that
40  * the constant pool entries themselves have already been remapped.
41  *
42  * @author Eric Lafortune
43  */
44 public class ConstantPoolRemapper
45 extends      SimplifiedVisitor
46 implements   ClassVisitor,
47              ConstantVisitor,
48              MemberVisitor,
49              AttributeVisitor,
50              BootstrapMethodInfoVisitor,
51              InnerClassesInfoVisitor,
52              ExceptionInfoVisitor,
53              InstructionVisitor,
54              StackMapFrameVisitor,
55              VerificationTypeVisitor,
56              ParameterInfoVisitor,
57              LocalVariableInfoVisitor,
58              LocalVariableTypeInfoVisitor,
59              AnnotationVisitor,
60              ElementValueVisitor
61 {
62     private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false, true);
63 
64     private int[] constantIndexMap;
65 
66 
67     /**
68      * Sets the given mapping of old constant pool entry indexes to their new
69      * indexes.
70      */
setConstantIndexMap(int[] constantIndexMap)71     public void setConstantIndexMap(int[] constantIndexMap)
72     {
73         this.constantIndexMap = constantIndexMap;
74     }
75 
76 
77     // Implementations for ClassVisitor.
78 
visitProgramClass(ProgramClass programClass)79     public void visitProgramClass(ProgramClass programClass)
80     {
81         // Remap the local constant pool references.
82         programClass.u2thisClass  = remapConstantIndex(programClass.u2thisClass);
83         programClass.u2superClass = remapConstantIndex(programClass.u2superClass);
84 
85         remapConstantIndexArray(programClass.u2interfaces,
86                                 programClass.u2interfacesCount);
87 
88         // Remap the references of the contant pool entries themselves.
89         programClass.constantPoolEntriesAccept(this);
90 
91         // Remap the references in all fields, methods, and attributes.
92         programClass.fieldsAccept(this);
93         programClass.methodsAccept(this);
94         programClass.attributesAccept(this);
95     }
96 
97 
visitLibraryClass(LibraryClass libraryClass)98     public void visitLibraryClass(LibraryClass libraryClass)
99     {
100     }
101 
102 
103     // Implementations for ConstantVisitor.
104 
visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)105     public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
106     {
107         // Nothing to do.
108     }
109 
110 
visitLongConstant(Clazz clazz, LongConstant longConstant)111     public void visitLongConstant(Clazz clazz, LongConstant longConstant)
112     {
113         // Nothing to do.
114     }
115 
116 
visitFloatConstant(Clazz clazz, FloatConstant floatConstant)117     public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
118     {
119         // Nothing to do.
120     }
121 
122 
visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)123     public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
124     {
125         // Nothing to do.
126     }
127 
128 
visitStringConstant(Clazz clazz, StringConstant stringConstant)129     public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
130     {
131         stringConstant.u2stringIndex =
132             remapConstantIndex(stringConstant.u2stringIndex);
133     }
134 
135 
visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)136     public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
137     {
138         // Nothing to do.
139     }
140 
141 
visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)142     public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
143     {
144         invokeDynamicConstant.u2nameAndTypeIndex =
145             remapConstantIndex(invokeDynamicConstant.u2nameAndTypeIndex);
146     }
147 
148 
visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)149     public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
150     {
151         methodHandleConstant.u2referenceIndex =
152             remapConstantIndex(methodHandleConstant.u2referenceIndex);
153     }
154 
155 
visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)156     public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
157     {
158         fieldrefConstant.u2classIndex =
159             remapConstantIndex(fieldrefConstant.u2classIndex);
160         fieldrefConstant.u2nameAndTypeIndex =
161             remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex);
162     }
163 
164 
visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)165     public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
166     {
167         interfaceMethodrefConstant.u2classIndex =
168             remapConstantIndex(interfaceMethodrefConstant.u2classIndex);
169         interfaceMethodrefConstant.u2nameAndTypeIndex =
170             remapConstantIndex(interfaceMethodrefConstant.u2nameAndTypeIndex);
171     }
172 
173 
visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)174     public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
175     {
176         methodrefConstant.u2classIndex =
177             remapConstantIndex(methodrefConstant.u2classIndex);
178         methodrefConstant.u2nameAndTypeIndex =
179             remapConstantIndex(methodrefConstant.u2nameAndTypeIndex);
180     }
181 
182 
visitClassConstant(Clazz clazz, ClassConstant classConstant)183     public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
184     {
185         classConstant.u2nameIndex =
186             remapConstantIndex(classConstant.u2nameIndex);
187     }
188 
189 
visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)190     public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
191     {
192         methodTypeConstant.u2descriptorIndex =
193             remapConstantIndex(methodTypeConstant.u2descriptorIndex);
194     }
195 
196 
visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)197     public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
198     {
199         nameAndTypeConstant.u2nameIndex =
200             remapConstantIndex(nameAndTypeConstant.u2nameIndex);
201         nameAndTypeConstant.u2descriptorIndex =
202             remapConstantIndex(nameAndTypeConstant.u2descriptorIndex);
203     }
204 
205 
206     // Implementations for MemberVisitor.
207 
visitProgramField(ProgramClass programClass, ProgramField programField)208     public void visitProgramField(ProgramClass programClass, ProgramField programField)
209     {
210         visitMember(programClass, programField);
211     }
212 
213 
visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)214     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
215     {
216         visitMember(programClass, programMethod);
217     }
218 
219 
visitMember(ProgramClass programClass, ProgramMember programMember)220     private void visitMember(ProgramClass programClass, ProgramMember programMember)
221     {
222         // Remap the local constant pool references.
223         programMember.u2nameIndex =
224             remapConstantIndex(programMember.u2nameIndex);
225         programMember.u2descriptorIndex =
226             remapConstantIndex(programMember.u2descriptorIndex);
227 
228         // Remap the constant pool references of the remaining attributes.
229         programMember.attributesAccept(programClass, this);
230     }
231 
232 
visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)233     public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
234     {
235         // Library classes are left unchanged.
236     }
237 
238 
visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)239     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
240     {
241         // Library classes are left unchanged.
242     }
243 
244 
245     // Implementations for AttributeVisitor.
246 
visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)247     public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
248     {
249         unknownAttribute.u2attributeNameIndex =
250             remapConstantIndex(unknownAttribute.u2attributeNameIndex);
251 
252         // There's not much else we can do with unknown attributes.
253     }
254 
255 
visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)256     public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
257     {
258         bootstrapMethodsAttribute.u2attributeNameIndex =
259             remapConstantIndex(bootstrapMethodsAttribute.u2attributeNameIndex);
260 
261         // Remap the constant pool references of the bootstrap method entries.
262         bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
263     }
264 
265 
visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)266     public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
267     {
268         sourceFileAttribute.u2attributeNameIndex =
269             remapConstantIndex(sourceFileAttribute.u2attributeNameIndex);
270         sourceFileAttribute.u2sourceFileIndex =
271             remapConstantIndex(sourceFileAttribute.u2sourceFileIndex);
272     }
273 
274 
visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)275     public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
276     {
277         sourceDirAttribute.u2attributeNameIndex =
278             remapConstantIndex(sourceDirAttribute.u2attributeNameIndex);
279         sourceDirAttribute.u2sourceDirIndex       =
280             remapConstantIndex(sourceDirAttribute.u2sourceDirIndex);
281     }
282 
283 
visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)284     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
285     {
286         innerClassesAttribute.u2attributeNameIndex =
287             remapConstantIndex(innerClassesAttribute.u2attributeNameIndex);
288 
289         // Remap the constant pool references of the inner classes.
290         innerClassesAttribute.innerClassEntriesAccept(clazz, this);
291     }
292 
293 
visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)294     public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
295     {
296         enclosingMethodAttribute.u2attributeNameIndex =
297             remapConstantIndex(enclosingMethodAttribute.u2attributeNameIndex);
298         enclosingMethodAttribute.u2classIndex =
299             remapConstantIndex(enclosingMethodAttribute.u2classIndex);
300         enclosingMethodAttribute.u2nameAndTypeIndex =
301             remapConstantIndex(enclosingMethodAttribute.u2nameAndTypeIndex);
302     }
303 
304 
visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)305     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
306     {
307         deprecatedAttribute.u2attributeNameIndex =
308             remapConstantIndex(deprecatedAttribute.u2attributeNameIndex);
309     }
310 
311 
visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)312     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
313     {
314         syntheticAttribute.u2attributeNameIndex =
315             remapConstantIndex(syntheticAttribute.u2attributeNameIndex);
316     }
317 
318 
visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)319     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
320     {
321         signatureAttribute.u2attributeNameIndex =
322             remapConstantIndex(signatureAttribute.u2attributeNameIndex);
323         signatureAttribute.u2signatureIndex       =
324             remapConstantIndex(signatureAttribute.u2signatureIndex);
325     }
326 
327 
visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)328     public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
329     {
330         constantValueAttribute.u2attributeNameIndex =
331             remapConstantIndex(constantValueAttribute.u2attributeNameIndex);
332         constantValueAttribute.u2constantValueIndex =
333             remapConstantIndex(constantValueAttribute.u2constantValueIndex);
334     }
335 
336 
visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute)337     public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute methodParametersAttribute)
338     {
339         methodParametersAttribute.u2attributeNameIndex =
340             remapConstantIndex(methodParametersAttribute.u2attributeNameIndex);
341 
342         // Remap the constant pool references of the parameter information.
343         methodParametersAttribute.parametersAccept(clazz, method, this);
344     }
345 
346 
visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)347     public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
348     {
349         exceptionsAttribute.u2attributeNameIndex =
350             remapConstantIndex(exceptionsAttribute.u2attributeNameIndex);
351 
352         // Remap the constant pool references of the exceptions.
353         remapConstantIndexArray(exceptionsAttribute.u2exceptionIndexTable,
354                                 exceptionsAttribute.u2exceptionIndexTableLength);
355     }
356 
357 
visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)358     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
359     {
360         codeAttribute.u2attributeNameIndex =
361             remapConstantIndex(codeAttribute.u2attributeNameIndex);
362 
363         // Initially, the code attribute editor doesn't contain any changes.
364         codeAttributeEditor.reset(codeAttribute.u4codeLength);
365 
366         // Remap the constant pool references of the instructions.
367         codeAttribute.instructionsAccept(clazz, method, this);
368 
369         // Apply the code atribute editor. It will only contain any changes if
370         // the code length is changing at any point.
371         codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
372 
373         // Remap the constant pool references of the exceptions and attributes.
374         codeAttribute.exceptionsAccept(clazz, method, this);
375         codeAttribute.attributesAccept(clazz, method, this);
376     }
377 
378 
visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)379     public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
380     {
381         stackMapAttribute.u2attributeNameIndex =
382             remapConstantIndex(stackMapAttribute.u2attributeNameIndex);
383 
384         // Remap the constant pool references of the stack map frames.
385         stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
386     }
387 
388 
visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)389     public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
390     {
391         stackMapTableAttribute.u2attributeNameIndex =
392             remapConstantIndex(stackMapTableAttribute.u2attributeNameIndex);
393 
394         // Remap the constant pool references of the stack map frames.
395         stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
396     }
397 
398 
visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)399     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
400     {
401         lineNumberTableAttribute.u2attributeNameIndex =
402             remapConstantIndex(lineNumberTableAttribute.u2attributeNameIndex);
403     }
404 
405 
visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)406     public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
407     {
408         localVariableTableAttribute.u2attributeNameIndex =
409             remapConstantIndex(localVariableTableAttribute.u2attributeNameIndex);
410 
411         // Remap the constant pool references of the local variables.
412         localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
413     }
414 
415 
visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)416     public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
417     {
418         localVariableTypeTableAttribute.u2attributeNameIndex =
419             remapConstantIndex(localVariableTypeTableAttribute.u2attributeNameIndex);
420 
421         // Remap the constant pool references of the local variables.
422         localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
423     }
424 
425 
visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)426     public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
427     {
428         annotationsAttribute.u2attributeNameIndex =
429             remapConstantIndex(annotationsAttribute.u2attributeNameIndex);
430 
431         // Remap the constant pool references of the annotations.
432         annotationsAttribute.annotationsAccept(clazz, this);
433     }
434 
435 
visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)436     public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
437     {
438         parameterAnnotationsAttribute.u2attributeNameIndex =
439             remapConstantIndex(parameterAnnotationsAttribute.u2attributeNameIndex);
440 
441         // Remap the constant pool references of the annotations.
442         parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
443     }
444 
445 
visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)446     public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
447     {
448         annotationDefaultAttribute.u2attributeNameIndex =
449             remapConstantIndex(annotationDefaultAttribute.u2attributeNameIndex);
450 
451         // Remap the constant pool references of the annotations.
452         annotationDefaultAttribute.defaultValueAccept(clazz, this);
453     }
454 
455 
456     // Implementations for BootstrapMethodInfoVisitor.
457 
visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)458     public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
459     {
460         bootstrapMethodInfo.u2methodHandleIndex =
461             remapConstantIndex(bootstrapMethodInfo.u2methodHandleIndex);
462 
463         // Remap the constant pool references of the bootstrap methods..
464         remapConstantIndexArray(bootstrapMethodInfo.u2methodArguments,
465                                 bootstrapMethodInfo.u2methodArgumentCount);
466     }
467 
468 
469     // Implementations for InnerClassesInfoVisitor.
470 
visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)471     public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
472     {
473         if (innerClassesInfo.u2innerClassIndex != 0)
474         {
475             innerClassesInfo.u2innerClassIndex =
476                 remapConstantIndex(innerClassesInfo.u2innerClassIndex);
477         }
478 
479         if (innerClassesInfo.u2outerClassIndex != 0)
480         {
481             innerClassesInfo.u2outerClassIndex =
482                 remapConstantIndex(innerClassesInfo.u2outerClassIndex);
483         }
484 
485         if (innerClassesInfo.u2innerNameIndex != 0)
486         {
487             innerClassesInfo.u2innerNameIndex =
488                 remapConstantIndex(innerClassesInfo.u2innerNameIndex);
489         }
490     }
491 
492 
493     // Implementations for ExceptionInfoVisitor.
494 
visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)495     public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
496     {
497         if (exceptionInfo.u2catchType != 0)
498         {
499             exceptionInfo.u2catchType =
500                 remapConstantIndex(exceptionInfo.u2catchType);
501         }
502     }
503 
504 
505     // Implementations for InstructionVisitor.
506 
visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)507     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
508 
509 
visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)510     public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
511     {
512         // Is the new constant pool index different from the original one?
513         int newConstantIndex = remapConstantIndex(constantInstruction.constantIndex);
514         if (newConstantIndex != constantInstruction.constantIndex)
515         {
516             // Replace the instruction.
517             Instruction replacementInstruction =
518                 new ConstantInstruction(constantInstruction.opcode,
519                                         newConstantIndex,
520                                         constantInstruction.constant);
521 
522             codeAttributeEditor.replaceInstruction(offset, replacementInstruction);
523         }
524     }
525 
526 
527     // Implementations for StackMapFrameVisitor.
528 
visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame)529     public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {}
530 
531 
visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)532     public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
533     {
534         // Remap the constant pool references of the verification types.
535         sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
536     }
537 
538 
visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)539     public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
540     {
541         // Remap the constant pool references of the verification types.
542         moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
543     }
544 
545 
visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)546     public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
547     {
548         // Remap the constant pool references of the verification types.
549         fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
550         fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
551     }
552 
553 
554     // Implementations for VerificationTypeVisitor.
555 
visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType)556     public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {}
557 
558 
visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)559     public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
560     {
561         objectType.u2classIndex =
562             remapConstantIndex(objectType.u2classIndex);
563     }
564 
565 
566     // Implementations for ParameterInfoVisitor.
567 
visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo)568     public void visitParameterInfo(Clazz clazz, Method method, int parameterIndex, ParameterInfo parameterInfo)
569     {
570         parameterInfo.u2nameIndex =
571             remapConstantIndex(parameterInfo.u2nameIndex);
572     }
573 
574 
575     // Implementations for LocalVariableInfoVisitor.
576 
visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)577     public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
578     {
579         localVariableInfo.u2nameIndex =
580             remapConstantIndex(localVariableInfo.u2nameIndex);
581         localVariableInfo.u2descriptorIndex =
582             remapConstantIndex(localVariableInfo.u2descriptorIndex);
583     }
584 
585 
586     // Implementations for LocalVariableTypeInfoVisitor.
587 
visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)588     public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
589     {
590         localVariableTypeInfo.u2nameIndex =
591             remapConstantIndex(localVariableTypeInfo.u2nameIndex);
592         localVariableTypeInfo.u2signatureIndex =
593             remapConstantIndex(localVariableTypeInfo.u2signatureIndex);
594     }
595 
596 
597     // Implementations for AnnotationVisitor.
598 
visitAnnotation(Clazz clazz, Annotation annotation)599     public void visitAnnotation(Clazz clazz, Annotation annotation)
600     {
601         annotation.u2typeIndex =
602             remapConstantIndex(annotation.u2typeIndex);
603 
604         // Remap the constant pool references of the element values.
605         annotation.elementValuesAccept(clazz, this);
606     }
607 
608 
609     // Implementations for ElementValueVisitor.
610 
visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)611     public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
612     {
613         constantElementValue.u2elementNameIndex =
614             remapConstantIndex(constantElementValue.u2elementNameIndex);
615         constantElementValue.u2constantValueIndex =
616             remapConstantIndex(constantElementValue.u2constantValueIndex);
617     }
618 
619 
visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)620     public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
621     {
622         enumConstantElementValue.u2elementNameIndex =
623             remapConstantIndex(enumConstantElementValue.u2elementNameIndex);
624         enumConstantElementValue.u2typeNameIndex =
625             remapConstantIndex(enumConstantElementValue.u2typeNameIndex);
626         enumConstantElementValue.u2constantNameIndex =
627             remapConstantIndex(enumConstantElementValue.u2constantNameIndex);
628     }
629 
630 
visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)631     public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
632     {
633         classElementValue.u2elementNameIndex =
634             remapConstantIndex(classElementValue.u2elementNameIndex);
635         classElementValue.u2classInfoIndex       =
636             remapConstantIndex(classElementValue.u2classInfoIndex);
637     }
638 
639 
visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)640     public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
641     {
642         annotationElementValue.u2elementNameIndex =
643             remapConstantIndex(annotationElementValue.u2elementNameIndex);
644 
645         // Remap the constant pool references of the annotation.
646         annotationElementValue.annotationAccept(clazz, this);
647     }
648 
649 
visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)650     public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
651     {
652         arrayElementValue.u2elementNameIndex =
653             remapConstantIndex(arrayElementValue.u2elementNameIndex);
654 
655         // Remap the constant pool references of the element values.
656         arrayElementValue.elementValuesAccept(clazz, annotation, this);
657     }
658 
659 
660     /**
661      * Remaps all constant pool indices in the given array.
662      */
remapConstantIndexArray(int[] array, int length)663     private void remapConstantIndexArray(int[] array, int length)
664     {
665         for (int index = 0; index < length; index++)
666         {
667             array[index] = remapConstantIndex(array[index]);
668         }
669     }
670 
671     // Small utility methods.
672 
673 
674     /**
675      * Returns the new constant pool index of the entry at the
676      * given index.
677      */
remapConstantIndex(int constantIndex)678     private int remapConstantIndex(int constantIndex)
679     {
680         int remappedConstantIndex = constantIndexMap[constantIndex];
681         if (remappedConstantIndex < 0)
682         {
683             throw new IllegalArgumentException("Can't remap constant index ["+constantIndex+"]");
684         }
685 
686         return remappedConstantIndex;
687     }
688 }
689