All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mockit.asm.classes.ConstantPoolCopying Maven / Gradle / Ivy

package mockit.asm.classes;

import javax.annotation.*;

import mockit.asm.constantPool.*;
import mockit.asm.util.*;
import static mockit.asm.jvmConstants.ConstantPoolTypes.*;

/**
 * Copies the constant pool data from a {@link ClassReader} into a {@link ClassWriter}.
 */
final class ConstantPoolCopying
{
   @Nonnull private final ClassReader source;
   @Nonnull private final ClassWriter destination;
   @Nonnull private final Item[] newItems;
   @Nonnegative private int itemIndex;

   ConstantPoolCopying(@Nonnull ClassReader source, @Nonnull ClassWriter destination) {
      this.source = source;
      this.destination = destination;
      newItems = new Item[source.items.length];
   }

   void copyPool(@Nullable BootstrapMethodsWriter bootstrapMethods) {
      if (bootstrapMethods != null) {
         bootstrapMethods.copyBootstrapMethods(source, newItems);
      }

      int[] items = source.items;
      int itemCount = items.length;

      for (itemIndex = 1; itemIndex < itemCount; itemIndex++) {
         source.codeIndex = items[itemIndex] - 1;
         int itemType = source.readSignedByte();

         Item newItem = copyItem(itemType);
         newItem.setNext(newItems);
      }

      int off = items[1] - 1;
      destination.getConstantPoolGeneration().copy(source.code, off, source.header, newItems);
   }

   @Nonnull @SuppressWarnings("OverlyComplexMethod")
   private Item copyItem(int itemType) {
      switch (itemType) {
         case UTF8:      return copyUTF8Item();
         case INT:       return copyIntItem();
         case FLOAT:     return copyFloatItem();
         case LONG:      return copyLongItem();
         case DOUBLE:    return copyDoubleItem();
         case FIELD:
         case METH:
         case IMETH:     return copyFieldOrMethodReferenceItem(itemType);
         case NAME_TYPE: return copyNameAndTypeItem();
         case HANDLE:    return copyHandleItem();
         case CONDY:
         case INDY:      return copyDynamicItem(itemType);
      // case STR|CLASS|MTYPE:
         default:        return copyNameReferenceItem(itemType);
      }
   }

   @Nonnull
   private Item copyIntItem() {
      int itemValue = source.readInt();
      IntItem item = new IntItem(itemIndex);
      item.setValue(itemValue);
      return item;
   }

   @Nonnull
   private Item copyLongItem() {
      long itemValue = source.readLong();
      LongItem item = new LongItem(itemIndex);
      item.setValue(itemValue);
      itemIndex++;
      return item;
   }

   @Nonnull
   private Item copyFloatItem() {
      float itemValue = source.readFloat();
      FloatItem item = new FloatItem(itemIndex);
      item.set(itemValue);
      return item;
   }

   @Nonnull
   private Item copyDoubleItem() {
      double itemValue = source.readDouble();
      DoubleItem item = new DoubleItem(itemIndex);
      item.set(itemValue);
      itemIndex++;
      return item;
   }

   @Nonnull
   private Item copyUTF8Item() {
      String strVal = source.readString(itemIndex);
      return new StringItem(itemIndex, UTF8, strVal);
   }

   @Nonnull
   private Item copyNameReferenceItem(int type) {
      String strVal = source.readNonnullUTF8();
      return new StringItem(itemIndex, type, strVal);
   }

   @Nonnull
   private Item copyNameAndTypeItem() {
      String name = source.readNonnullUTF8();
      String type = source.readNonnullUTF8();

      NameAndTypeItem item = new NameAndTypeItem(itemIndex);
      item.set(name, type);
      return item;
   }

   @Nonnull
   private Item copyFieldOrMethodReferenceItem(int type) {
      String classDesc = source.readNonnullClass();
      int nameCodeIndex = source.readItem();
      String methodName = source.readNonnullUTF8(nameCodeIndex);
      String methodDesc = source.readNonnullUTF8(nameCodeIndex + 2);

      ClassMemberItem item = new ClassMemberItem(itemIndex);
      item.set(type, classDesc, methodName, methodDesc);
      return item;
   }

   @Nonnull
   private Item copyHandleItem() {
      int tag = source.readUnsignedByte();

      int fieldOrMethodRef = source.readItem();
      int nameCodeIndex = source.readItem(fieldOrMethodRef + 2);

      String classDesc = source.readNonnullClass(fieldOrMethodRef);
      String name = source.readNonnullUTF8(nameCodeIndex);
      String desc = source.readNonnullUTF8(nameCodeIndex + 2);

      MethodHandle handle = new MethodHandle(tag, classDesc, name, desc);
      MethodHandleItem item = new MethodHandleItem(itemIndex);
      item.set(handle);
      return item;
   }

   @Nonnull
   private Item copyDynamicItem(int type) {
      int bsmIndex = source.readUnsignedShort();
      int nameCodeIndex = source.readItem();
      String name = source.readNonnullUTF8(nameCodeIndex);
      String desc = source.readNonnullUTF8(nameCodeIndex + 2);

      DynamicItem item = new DynamicItem(itemIndex);
      item.set(type, name, desc, bsmIndex);
      return item;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy