1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 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 InstructionVisitor, 51 InnerClassesInfoVisitor, 52 ExceptionInfoVisitor, 53 StackMapFrameVisitor, 54 VerificationTypeVisitor, 55 LocalVariableInfoVisitor, 56 LocalVariableTypeInfoVisitor, 57 AnnotationVisitor, 58 ElementValueVisitor 59 { 60 private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); 61 62 private int[] constantIndexMap; 63 64 65 /** 66 * Sets the given mapping of old constant pool entry indexes to their new 67 * indexes. 68 */ setConstantIndexMap(int[] constantIndexMap)69 public void setConstantIndexMap(int[] constantIndexMap) 70 { 71 this.constantIndexMap = constantIndexMap; 72 } 73 74 75 // Implementations for ClassVisitor. 76 visitProgramClass(ProgramClass programClass)77 public void visitProgramClass(ProgramClass programClass) 78 { 79 // Remap the local constant pool references. 80 programClass.u2thisClass = remapConstantIndex(programClass.u2thisClass); 81 programClass.u2superClass = remapConstantIndex(programClass.u2superClass); 82 83 remapConstantIndexArray(programClass.u2interfaces, 84 programClass.u2interfacesCount); 85 86 // Remap the references of the contant pool entries themselves. 87 programClass.constantPoolEntriesAccept(this); 88 89 // Remap the references in all fields, methods, and attributes. 90 programClass.fieldsAccept(this); 91 programClass.methodsAccept(this); 92 programClass.attributesAccept(this); 93 } 94 95 visitLibraryClass(LibraryClass libraryClass)96 public void visitLibraryClass(LibraryClass libraryClass) 97 { 98 } 99 100 101 // Implementations for ConstantVisitor. 102 visitClassConstant(Clazz clazz, ClassConstant classConstant)103 public void visitClassConstant(Clazz clazz, ClassConstant classConstant) 104 { 105 classConstant.u2nameIndex = 106 remapConstantIndex(classConstant.u2nameIndex); 107 } 108 109 visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)110 public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) 111 { 112 // Nothing to do. 113 } 114 115 visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)116 public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) 117 { 118 fieldrefConstant.u2classIndex = 119 remapConstantIndex(fieldrefConstant.u2classIndex); 120 fieldrefConstant.u2nameAndTypeIndex = 121 remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex); 122 } 123 124 visitFloatConstant(Clazz clazz, FloatConstant floatConstant)125 public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) 126 { 127 // Nothing to do. 128 } 129 130 visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)131 public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) 132 { 133 // Nothing to do. 134 } 135 136 visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)137 public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant) 138 { 139 interfaceMethodrefConstant.u2classIndex = 140 remapConstantIndex(interfaceMethodrefConstant.u2classIndex); 141 interfaceMethodrefConstant.u2nameAndTypeIndex = 142 remapConstantIndex(interfaceMethodrefConstant.u2nameAndTypeIndex); 143 } 144 145 visitLongConstant(Clazz clazz, LongConstant longConstant)146 public void visitLongConstant(Clazz clazz, LongConstant longConstant) 147 { 148 // Nothing to do. 149 } 150 151 visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)152 public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) 153 { 154 methodrefConstant.u2classIndex = 155 remapConstantIndex(methodrefConstant.u2classIndex); 156 methodrefConstant.u2nameAndTypeIndex = 157 remapConstantIndex(methodrefConstant.u2nameAndTypeIndex); 158 } 159 160 visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)161 public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) 162 { 163 nameAndTypeConstant.u2nameIndex = 164 remapConstantIndex(nameAndTypeConstant.u2nameIndex); 165 nameAndTypeConstant.u2descriptorIndex = 166 remapConstantIndex(nameAndTypeConstant.u2descriptorIndex); 167 } 168 169 visitStringConstant(Clazz clazz, StringConstant stringConstant)170 public void visitStringConstant(Clazz clazz, StringConstant stringConstant) 171 { 172 stringConstant.u2stringIndex = 173 remapConstantIndex(stringConstant.u2stringIndex); 174 } 175 176 visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)177 public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) 178 { 179 // Nothing to do. 180 } 181 182 183 // Implementations for MemberVisitor. 184 visitProgramField(ProgramClass programClass, ProgramField programField)185 public void visitProgramField(ProgramClass programClass, ProgramField programField) 186 { 187 visitMember(programClass, programField); 188 } 189 190 visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)191 public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 192 { 193 visitMember(programClass, programMethod); 194 } 195 196 visitMember(ProgramClass programClass, ProgramMember programMember)197 private void visitMember(ProgramClass programClass, ProgramMember programMember) 198 { 199 // Remap the local constant pool references. 200 programMember.u2nameIndex = 201 remapConstantIndex(programMember.u2nameIndex); 202 programMember.u2descriptorIndex = 203 remapConstantIndex(programMember.u2descriptorIndex); 204 205 // Remap the constant pool references of the remaining attributes. 206 programMember.attributesAccept(programClass, this); 207 } 208 209 visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)210 public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField) 211 { 212 // Library classes are left unchanged. 213 } 214 215 visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)216 public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) 217 { 218 // Library classes are left unchanged. 219 } 220 221 222 // Implementations for AttributeVisitor. 223 visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)224 public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) 225 { 226 unknownAttribute.u2attributeNameIndex = 227 remapConstantIndex(unknownAttribute.u2attributeNameIndex); 228 229 // There's not much else we can do with unknown attributes. 230 } 231 232 visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)233 public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) 234 { 235 sourceFileAttribute.u2attributeNameIndex = 236 remapConstantIndex(sourceFileAttribute.u2attributeNameIndex); 237 sourceFileAttribute.u2sourceFileIndex = 238 remapConstantIndex(sourceFileAttribute.u2sourceFileIndex); 239 } 240 241 visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)242 public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) 243 { 244 sourceDirAttribute.u2attributeNameIndex = 245 remapConstantIndex(sourceDirAttribute.u2attributeNameIndex); 246 sourceDirAttribute.u2sourceDirIndex = 247 remapConstantIndex(sourceDirAttribute.u2sourceDirIndex); 248 } 249 250 visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)251 public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) 252 { 253 innerClassesAttribute.u2attributeNameIndex = 254 remapConstantIndex(innerClassesAttribute.u2attributeNameIndex); 255 256 // Remap the constant pool references of the inner classes. 257 innerClassesAttribute.innerClassEntriesAccept(clazz, this); 258 } 259 260 visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)261 public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) 262 { 263 enclosingMethodAttribute.u2attributeNameIndex = 264 remapConstantIndex(enclosingMethodAttribute.u2attributeNameIndex); 265 enclosingMethodAttribute.u2classIndex = 266 remapConstantIndex(enclosingMethodAttribute.u2classIndex); 267 enclosingMethodAttribute.u2nameAndTypeIndex = 268 remapConstantIndex(enclosingMethodAttribute.u2nameAndTypeIndex); 269 } 270 271 visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)272 public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) 273 { 274 deprecatedAttribute.u2attributeNameIndex = 275 remapConstantIndex(deprecatedAttribute.u2attributeNameIndex); 276 } 277 278 visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)279 public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) 280 { 281 syntheticAttribute.u2attributeNameIndex = 282 remapConstantIndex(syntheticAttribute.u2attributeNameIndex); 283 } 284 285 visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)286 public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) 287 { 288 signatureAttribute.u2attributeNameIndex = 289 remapConstantIndex(signatureAttribute.u2attributeNameIndex); 290 signatureAttribute.u2signatureIndex = 291 remapConstantIndex(signatureAttribute.u2signatureIndex); 292 } 293 294 visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)295 public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) 296 { 297 constantValueAttribute.u2attributeNameIndex = 298 remapConstantIndex(constantValueAttribute.u2attributeNameIndex); 299 constantValueAttribute.u2constantValueIndex = 300 remapConstantIndex(constantValueAttribute.u2constantValueIndex); 301 } 302 303 visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)304 public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) 305 { 306 exceptionsAttribute.u2attributeNameIndex = 307 remapConstantIndex(exceptionsAttribute.u2attributeNameIndex); 308 309 // Remap the constant pool references of the exceptions. 310 remapConstantIndexArray(exceptionsAttribute.u2exceptionIndexTable, 311 exceptionsAttribute.u2exceptionIndexTableLength); 312 } 313 314 visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)315 public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) 316 { 317 codeAttribute.u2attributeNameIndex = 318 remapConstantIndex(codeAttribute.u2attributeNameIndex); 319 320 // Initially, the code attribute editor doesn't contain any changes. 321 codeAttributeEditor.reset(codeAttribute.u4codeLength); 322 323 // Remap the constant pool references of the instructions. 324 codeAttribute.instructionsAccept(clazz, method, this); 325 326 // Apply the code atribute editor. It will only contain any changes if 327 // the code length is changing at any point. 328 codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); 329 330 // Remap the constant pool references of the exceptions and attributes. 331 codeAttribute.exceptionsAccept(clazz, method, this); 332 codeAttribute.attributesAccept(clazz, method, this); 333 } 334 335 visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)336 public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute) 337 { 338 stackMapAttribute.u2attributeNameIndex = 339 remapConstantIndex(stackMapAttribute.u2attributeNameIndex); 340 341 // Remap the constant pool references of the stack map frames. 342 stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); 343 } 344 345 visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)346 public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute) 347 { 348 stackMapTableAttribute.u2attributeNameIndex = 349 remapConstantIndex(stackMapTableAttribute.u2attributeNameIndex); 350 351 // Remap the constant pool references of the stack map frames. 352 stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this); 353 } 354 355 visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)356 public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute) 357 { 358 lineNumberTableAttribute.u2attributeNameIndex = 359 remapConstantIndex(lineNumberTableAttribute.u2attributeNameIndex); 360 } 361 362 visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)363 public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) 364 { 365 localVariableTableAttribute.u2attributeNameIndex = 366 remapConstantIndex(localVariableTableAttribute.u2attributeNameIndex); 367 368 // Remap the constant pool references of the local variables. 369 localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 370 } 371 372 visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)373 public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) 374 { 375 localVariableTypeTableAttribute.u2attributeNameIndex = 376 remapConstantIndex(localVariableTypeTableAttribute.u2attributeNameIndex); 377 378 // Remap the constant pool references of the local variables. 379 localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 380 } 381 382 visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)383 public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute) 384 { 385 annotationsAttribute.u2attributeNameIndex = 386 remapConstantIndex(annotationsAttribute.u2attributeNameIndex); 387 388 // Remap the constant pool references of the annotations. 389 annotationsAttribute.annotationsAccept(clazz, this); 390 } 391 392 visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)393 public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute) 394 { 395 parameterAnnotationsAttribute.u2attributeNameIndex = 396 remapConstantIndex(parameterAnnotationsAttribute.u2attributeNameIndex); 397 398 // Remap the constant pool references of the annotations. 399 parameterAnnotationsAttribute.annotationsAccept(clazz, method, this); 400 } 401 402 visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)403 public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute) 404 { 405 annotationDefaultAttribute.u2attributeNameIndex = 406 remapConstantIndex(annotationDefaultAttribute.u2attributeNameIndex); 407 408 // Remap the constant pool references of the annotations. 409 annotationDefaultAttribute.defaultValueAccept(clazz, this); 410 } 411 412 413 // Implementations for InnerClassesInfoVisitor. 414 visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)415 public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) 416 { 417 if (innerClassesInfo.u2innerClassIndex != 0) 418 { 419 innerClassesInfo.u2innerClassIndex = 420 remapConstantIndex(innerClassesInfo.u2innerClassIndex); 421 } 422 423 if (innerClassesInfo.u2outerClassIndex != 0) 424 { 425 innerClassesInfo.u2outerClassIndex = 426 remapConstantIndex(innerClassesInfo.u2outerClassIndex); 427 } 428 429 if (innerClassesInfo.u2innerNameIndex != 0) 430 { 431 innerClassesInfo.u2innerNameIndex = 432 remapConstantIndex(innerClassesInfo.u2innerNameIndex); 433 } 434 } 435 436 437 // Implementations for ExceptionInfoVisitor. 438 visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)439 public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) 440 { 441 if (exceptionInfo.u2catchType != 0) 442 { 443 exceptionInfo.u2catchType = 444 remapConstantIndex(exceptionInfo.u2catchType); 445 } 446 } 447 448 449 // Implementations for InstructionVisitor. 450 visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)451 public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} 452 453 visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)454 public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction) 455 { 456 // Is the new constant pool index different from the original one? 457 int newConstantIndex = remapConstantIndex(constantInstruction.constantIndex); 458 if (newConstantIndex != constantInstruction.constantIndex) 459 { 460 // Replace the instruction. 461 Instruction replacementInstruction = 462 new ConstantInstruction(constantInstruction.opcode, 463 newConstantIndex, 464 constantInstruction.constant).shrink(); 465 466 codeAttributeEditor.replaceInstruction(offset, replacementInstruction); 467 } 468 } 469 470 471 // Implementations for StackMapFrameVisitor. 472 visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame)473 public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {} 474 475 visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)476 public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame) 477 { 478 // Remap the constant pool references of the verification types. 479 sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this); 480 } 481 482 visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)483 public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame) 484 { 485 // Remap the constant pool references of the verification types. 486 moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this); 487 } 488 489 visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)490 public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame) 491 { 492 // Remap the constant pool references of the verification types. 493 fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this); 494 fullFrame.stackAccept(clazz, method, codeAttribute, offset, this); 495 } 496 497 498 // Implementations for VerificationTypeVisitor. 499 visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType)500 public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {} 501 502 visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)503 public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType) 504 { 505 objectType.u2classIndex = 506 remapConstantIndex(objectType.u2classIndex); 507 } 508 509 510 // Implementations for LocalVariableInfoVisitor. 511 visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)512 public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) 513 { 514 localVariableInfo.u2nameIndex = 515 remapConstantIndex(localVariableInfo.u2nameIndex); 516 localVariableInfo.u2descriptorIndex = 517 remapConstantIndex(localVariableInfo.u2descriptorIndex); 518 } 519 520 521 // Implementations for LocalVariableTypeInfoVisitor. 522 visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)523 public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) 524 { 525 localVariableTypeInfo.u2nameIndex = 526 remapConstantIndex(localVariableTypeInfo.u2nameIndex); 527 localVariableTypeInfo.u2signatureIndex = 528 remapConstantIndex(localVariableTypeInfo.u2signatureIndex); 529 } 530 531 532 // Implementations for AnnotationVisitor. 533 visitAnnotation(Clazz clazz, Annotation annotation)534 public void visitAnnotation(Clazz clazz, Annotation annotation) 535 { 536 annotation.u2typeIndex = 537 remapConstantIndex(annotation.u2typeIndex); 538 539 // Remap the constant pool references of the element values. 540 annotation.elementValuesAccept(clazz, this); 541 } 542 543 544 // Implementations for ElementValueVisitor. 545 visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)546 public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue) 547 { 548 constantElementValue.u2elementNameIndex = 549 remapConstantIndex(constantElementValue.u2elementNameIndex); 550 constantElementValue.u2constantValueIndex = 551 remapConstantIndex(constantElementValue.u2constantValueIndex); 552 } 553 554 visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)555 public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue) 556 { 557 enumConstantElementValue.u2elementNameIndex = 558 remapConstantIndex(enumConstantElementValue.u2elementNameIndex); 559 enumConstantElementValue.u2typeNameIndex = 560 remapConstantIndex(enumConstantElementValue.u2typeNameIndex); 561 enumConstantElementValue.u2constantNameIndex = 562 remapConstantIndex(enumConstantElementValue.u2constantNameIndex); 563 } 564 565 visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)566 public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue) 567 { 568 classElementValue.u2elementNameIndex = 569 remapConstantIndex(classElementValue.u2elementNameIndex); 570 classElementValue.u2classInfoIndex = 571 remapConstantIndex(classElementValue.u2classInfoIndex); 572 } 573 574 visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)575 public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue) 576 { 577 annotationElementValue.u2elementNameIndex = 578 remapConstantIndex(annotationElementValue.u2elementNameIndex); 579 580 // Remap the constant pool references of the annotation. 581 annotationElementValue.annotationAccept(clazz, this); 582 } 583 584 visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)585 public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue) 586 { 587 arrayElementValue.u2elementNameIndex = 588 remapConstantIndex(arrayElementValue.u2elementNameIndex); 589 590 // Remap the constant pool references of the element values. 591 arrayElementValue.elementValuesAccept(clazz, annotation, this); 592 } 593 594 595 // Small utility methods. 596 597 /** 598 * Remaps all constant pool indices in the given array. 599 */ remapConstantIndexArray(int[] array, int length)600 private void remapConstantIndexArray(int[] array, int length) 601 { 602 for (int index = 0; index < length; index++) 603 { 604 array[index] = remapConstantIndex(array[index]); 605 } 606 } 607 608 609 /** 610 * Returns the new constant pool index of the entry at the 611 * given index. 612 */ remapConstantIndex(int constantIndex)613 private int remapConstantIndex(int constantIndex) 614 { 615 return constantIndexMap[constantIndex]; 616 } 617 } 618