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