BcBands.java

  1. /*
  2.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  3.  *  contributor license agreements.  See the NOTICE file distributed with
  4.  *  this work for additional information regarding copyright ownership.
  5.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  6.  *  (the "License"); you may not use this file except in compliance with
  7.  *  the License.  You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.commons.compress.harmony.pack200;

  18. import java.io.IOException;
  19. import java.io.OutputStream;
  20. import java.util.ArrayList;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.stream.Collectors;

  25. import org.objectweb.asm.Label;

  26. /**
  27.  * Bytecode bands (corresponds to the {@code bc_bands} set of bands in the pack200 specification)
  28.  */
  29. public class BcBands extends BandSet {

  30.     private static final int MULTIANEWARRAY = 197;
  31.     private static final int ALOAD_0 = 42;

  32.     private static final int WIDE = 196;

  33.     private static final int INVOKEINTERFACE = 185;
  34.     private static final int TABLESWITCH = 170;
  35.     private static final int IINC = 132;
  36.     private static final int LOOKUPSWITCH = 171;
  37.     private static final int endMarker = 255;
  38.     private final CpBands cpBands;

  39.     private final Segment segment;
  40.     private final IntList bcCodes = new IntList();
  41.     private final IntList bcCaseCount = new IntList();
  42.     private final IntList bcCaseValue = new IntList();
  43.     private final IntList bcByte = new IntList();
  44.     private final IntList bcShort = new IntList();
  45.     private final IntList bcLocal = new IntList();

  46.     // Integers and Labels
  47.     private final List bcLabel = new ArrayList();
  48.     private final List<CPInt> bcIntref = new ArrayList<>();
  49.     private final List<CPFloat> bcFloatRef = new ArrayList<>();
  50.     private final List<CPLong> bcLongRef = new ArrayList<>();
  51.     private final List<CPDouble> bcDoubleRef = new ArrayList<>();
  52.     private final List<CPString> bcStringRef = new ArrayList<>();
  53.     private final List<CPClass> bcClassRef = new ArrayList<>();
  54.     private final List<CPMethodOrField> bcFieldRef = new ArrayList<>();

  55.     private final List<CPMethodOrField> bcMethodRef = new ArrayList<>();
  56.     private final List<CPMethodOrField> bcIMethodRef = new ArrayList<>();

  57.     // Integers and CPMethodOrField
  58.     private List bcThisField = new ArrayList<>();

  59.     private final List bcSuperField = new ArrayList<>();
  60.     private List bcThisMethod = new ArrayList<>();
  61.     private List bcSuperMethod = new ArrayList<>();
  62.     private List bcInitRef = new ArrayList<>();
  63.     private String currentClass;
  64.     private String superClass;
  65.     private String currentNewClass;
  66.     private final IntList bciRenumbering = new IntList();

  67.     private final Map<Label, Integer> labelsToOffsets = new HashMap<>();
  68.     private int byteCodeOffset;
  69.     private int renumberedOffset;
  70.     private final IntList bcLabelRelativeOffsets = new IntList();

  71.     public BcBands(final CpBands cpBands, final Segment segment, final int effort) {
  72.         super(effort, segment.getSegmentHeader());
  73.         this.cpBands = cpBands;
  74.         this.segment = segment;
  75.     }

  76.     /**
  77.      * All input classes for the segment have now been read in, so this method is called so that this class can calculate/complete anything it could not do
  78.      * while classes were being read.
  79.      */
  80.     public void finaliseBands() {
  81.         bcThisField = getIndexInClass(bcThisField);
  82.         bcThisMethod = getIndexInClass(bcThisMethod);
  83.         bcSuperMethod = getIndexInClass(bcSuperMethod);
  84.         bcInitRef = getIndexInClassForConstructor(bcInitRef);
  85.     }

  86.     private List<Integer> getIndexInClass(final List<CPMethodOrField> cPMethodOrFieldList) {
  87.         return cPMethodOrFieldList.stream().collect(Collectors.mapping(CPMethodOrField::getIndexInClass, Collectors.toList()));
  88.     }

  89.     private List<Integer> getIndexInClassForConstructor(final List<CPMethodOrField> cPMethodList) {
  90.         return cPMethodList.stream().collect(Collectors.mapping(CPMethodOrField::getIndexInClassForConstructor, Collectors.toList()));
  91.     }

  92.     @Override
  93.     public void pack(final OutputStream out) throws IOException, Pack200Exception {
  94.         PackingUtils.log("Writing byte code bands...");
  95.         byte[] encodedBand = encodeBandInt("bcCodes", bcCodes.toArray(), Codec.BYTE1);
  96.         out.write(encodedBand);
  97.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcCodes[" + bcCodes.size() + "]");

  98.         encodedBand = encodeBandInt("bcCaseCount", bcCaseCount.toArray(), Codec.UNSIGNED5);
  99.         out.write(encodedBand);
  100.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcCaseCount[" + bcCaseCount.size() + "]");

  101.         encodedBand = encodeBandInt("bcCaseValue", bcCaseValue.toArray(), Codec.DELTA5);
  102.         out.write(encodedBand);
  103.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcCaseValue[" + bcCaseValue.size() + "]");

  104.         encodedBand = encodeBandInt("bcByte", bcByte.toArray(), Codec.BYTE1);
  105.         out.write(encodedBand);
  106.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcByte[" + bcByte.size() + "]");

  107.         encodedBand = encodeBandInt("bcShort", bcShort.toArray(), Codec.DELTA5);
  108.         out.write(encodedBand);
  109.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcShort[" + bcShort.size() + "]");

  110.         encodedBand = encodeBandInt("bcLocal", bcLocal.toArray(), Codec.UNSIGNED5);
  111.         out.write(encodedBand);
  112.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcLocal[" + bcLocal.size() + "]");

  113.         encodedBand = encodeBandInt("bcLabel", integerListToArray(bcLabel), Codec.BRANCH5);
  114.         out.write(encodedBand);
  115.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcLabel[" + bcLabel.size() + "]");

  116.         encodedBand = encodeBandInt("bcIntref", cpEntryListToArray(bcIntref), Codec.DELTA5);
  117.         out.write(encodedBand);
  118.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcIntref[" + bcIntref.size() + "]");

  119.         encodedBand = encodeBandInt("bcFloatRef", cpEntryListToArray(bcFloatRef), Codec.DELTA5);
  120.         out.write(encodedBand);
  121.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcFloatRef[" + bcFloatRef.size() + "]");

  122.         encodedBand = encodeBandInt("bcLongRef", cpEntryListToArray(bcLongRef), Codec.DELTA5);
  123.         out.write(encodedBand);
  124.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcLongRef[" + bcLongRef.size() + "]");

  125.         encodedBand = encodeBandInt("bcDoubleRef", cpEntryListToArray(bcDoubleRef), Codec.DELTA5);
  126.         out.write(encodedBand);
  127.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcDoubleRef[" + bcDoubleRef.size() + "]");

  128.         encodedBand = encodeBandInt("bcStringRef", cpEntryListToArray(bcStringRef), Codec.DELTA5);
  129.         out.write(encodedBand);
  130.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcStringRef[" + bcStringRef.size() + "]");

  131.         encodedBand = encodeBandInt("bcClassRef", cpEntryOrNullListToArray(bcClassRef), Codec.UNSIGNED5);
  132.         out.write(encodedBand);
  133.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcClassRef[" + bcClassRef.size() + "]");

  134.         encodedBand = encodeBandInt("bcFieldRef", cpEntryListToArray(bcFieldRef), Codec.DELTA5);
  135.         out.write(encodedBand);
  136.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcFieldRef[" + bcFieldRef.size() + "]");

  137.         encodedBand = encodeBandInt("bcMethodRef", cpEntryListToArray(bcMethodRef), Codec.UNSIGNED5);
  138.         out.write(encodedBand);
  139.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcMethodRef[" + bcMethodRef.size() + "]");

  140.         encodedBand = encodeBandInt("bcIMethodRef", cpEntryListToArray(bcIMethodRef), Codec.DELTA5);
  141.         out.write(encodedBand);
  142.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcIMethodRef[" + bcIMethodRef.size() + "]");

  143.         encodedBand = encodeBandInt("bcThisField", integerListToArray(bcThisField), Codec.UNSIGNED5);
  144.         out.write(encodedBand);
  145.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcThisField[" + bcThisField.size() + "]");

  146.         encodedBand = encodeBandInt("bcSuperField", integerListToArray(bcSuperField), Codec.UNSIGNED5);
  147.         out.write(encodedBand);
  148.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcSuperField[" + bcSuperField.size() + "]");

  149.         encodedBand = encodeBandInt("bcThisMethod", integerListToArray(bcThisMethod), Codec.UNSIGNED5);
  150.         out.write(encodedBand);
  151.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcThisMethod[" + bcThisMethod.size() + "]");

  152.         encodedBand = encodeBandInt("bcSuperMethod", integerListToArray(bcSuperMethod), Codec.UNSIGNED5);
  153.         out.write(encodedBand);
  154.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcSuperMethod[" + bcSuperMethod.size() + "]");

  155.         encodedBand = encodeBandInt("bcInitRef", integerListToArray(bcInitRef), Codec.UNSIGNED5);
  156.         out.write(encodedBand);
  157.         PackingUtils.log("Wrote " + encodedBand.length + " bytes from bcInitRef[" + bcInitRef.size() + "]");

  158.         // out.write(encodeBandInt(cpEntryintegerListToArray(bcEscRef),
  159.         // Codec.UNSIGNED5));
  160.         // out.write(encodeBandInt(integerListToArray(bcEscRefSize),
  161.         // Codec.UNSIGNED5));
  162.         // out.write(encodeBandInt(integerListToArray(bcEscSize),
  163.         // Codec.UNSIGNED5));
  164.         // out.write(encodeBandInt(integerListToArray(bcEscByte), Codec.BYTE1));
  165.     }

  166.     public void setCurrentClass(final String name, final String superName) {
  167.         currentClass = name;
  168.         superClass = superName;
  169.     }

  170.     private void updateRenumbering() {
  171.         if (bciRenumbering.isEmpty()) {
  172.             bciRenumbering.add(0);
  173.         }
  174.         renumberedOffset++;
  175.         for (int i = bciRenumbering.size(); i < byteCodeOffset; i++) {
  176.             bciRenumbering.add(-1);
  177.         }
  178.         bciRenumbering.add(renumberedOffset);
  179.     }

  180.     public void visitEnd() {
  181.         for (int i = 0; i < bciRenumbering.size(); i++) {
  182.             if (bciRenumbering.get(i) == -1) {
  183.                 bciRenumbering.remove(i);
  184.                 bciRenumbering.add(i, ++renumberedOffset);
  185.             }
  186.         }
  187.         if (renumberedOffset != 0) {
  188.             if (renumberedOffset + 1 != bciRenumbering.size()) {
  189.                 throw new IllegalStateException("Mistake made with renumbering");
  190.             }
  191.             for (int i = bcLabel.size() - 1; i >= 0; i--) {
  192.                 final Object label = bcLabel.get(i);
  193.                 if (label instanceof Integer) {
  194.                     break;
  195.                 }
  196.                 if (label instanceof Label) {
  197.                     bcLabel.remove(i);
  198.                     final Integer offset = labelsToOffsets.get(label);
  199.                     final int relativeOffset = bcLabelRelativeOffsets.get(i);
  200.                     bcLabel.add(i, Integer.valueOf(bciRenumbering.get(offset.intValue()) - bciRenumbering.get(relativeOffset)));
  201.                 }
  202.             }
  203.             bcCodes.add(endMarker);
  204.             segment.getClassBands().doBciRenumbering(bciRenumbering, labelsToOffsets);
  205.             bciRenumbering.clear();
  206.             labelsToOffsets.clear();
  207.             byteCodeOffset = 0;
  208.             renumberedOffset = 0;
  209.         }
  210.     }

  211.     public void visitFieldInsn(int opcode, final String owner, final String name, final String desc) {
  212.         byteCodeOffset += 3;
  213.         updateRenumbering();
  214.         boolean aload_0 = false;
  215.         if (bcCodes.size() > 0 && bcCodes.get(bcCodes.size() - 1) == ALOAD_0) {
  216.             bcCodes.remove(bcCodes.size() - 1);
  217.             aload_0 = true;
  218.         }
  219.         final CPMethodOrField cpField = cpBands.getCPField(owner, name, desc);
  220.         if (aload_0) {
  221.             opcode += 7;
  222.         }
  223.         if (owner.equals(currentClass)) {
  224.             opcode += 24; // change to getstatic_this, putstatic_this etc.
  225.             bcThisField.add(cpField);
  226. //        } else if (owner.equals(superClass)) {
  227. //            opcode += 38; // change to getstatic_super etc.
  228. //            bcSuperField.add(cpField);
  229.         } else {
  230.             if (aload_0) {
  231.                 opcode -= 7;
  232.                 bcCodes.add(ALOAD_0); // add aload_0 back in because
  233.                 // there's no special rewrite in
  234.                 // this case.
  235.             }
  236.             bcFieldRef.add(cpField);
  237.         }
  238.         aload_0 = false;
  239.         bcCodes.add(opcode);
  240.     }

  241.     public void visitIincInsn(final int var, final int increment) {
  242.         if (var > 255 || increment > 255) {
  243.             byteCodeOffset += 6;
  244.             bcCodes.add(WIDE);
  245.             bcCodes.add(IINC);
  246.             bcLocal.add(var);
  247.             bcShort.add(increment);
  248.         } else {
  249.             byteCodeOffset += 3;
  250.             bcCodes.add(IINC);
  251.             bcLocal.add(var);
  252.             bcByte.add(increment & 0xFF);
  253.         }
  254.         updateRenumbering();
  255.     }

  256.     public void visitInsn(final int opcode) {
  257.         if (opcode >= 202) {
  258.             throw new IllegalArgumentException("Non-standard bytecode instructions not supported");
  259.         }
  260.         bcCodes.add(opcode);
  261.         byteCodeOffset++;
  262.         updateRenumbering();
  263.     }

  264.     public void visitIntInsn(final int opcode, final int operand) {
  265.         switch (opcode) {
  266.         case 17: // sipush
  267.             bcCodes.add(opcode);
  268.             bcShort.add(operand);
  269.             byteCodeOffset += 3;
  270.             break;
  271.         case 16: // bipush
  272.         case 188: // newarray
  273.             bcCodes.add(opcode);
  274.             bcByte.add(operand & 0xFF);
  275.             byteCodeOffset += 2;
  276.         }
  277.         updateRenumbering();
  278.     }

  279.     public void visitJumpInsn(final int opcode, final Label label) {
  280.         bcCodes.add(opcode);
  281.         bcLabel.add(label);
  282.         bcLabelRelativeOffsets.add(byteCodeOffset);
  283.         byteCodeOffset += 3;
  284.         updateRenumbering();
  285.     }

  286.     public void visitLabel(final Label label) {
  287.         labelsToOffsets.put(label, Integer.valueOf(byteCodeOffset));
  288.     }

  289.     public void visitLdcInsn(final Object cst) {
  290.         final CPConstant<?> constant = cpBands.getConstant(cst);
  291.         if (segment.lastConstantHadWideIndex() || constant instanceof CPLong || constant instanceof CPDouble) {
  292.             byteCodeOffset += 3;
  293.             if (constant instanceof CPInt) {
  294.                 bcCodes.add(237); // ildc_w
  295.                 bcIntref.add((CPInt) constant);
  296.             } else if (constant instanceof CPFloat) {
  297.                 bcCodes.add(238); // fldc
  298.                 bcFloatRef.add((CPFloat) constant);
  299.             } else if (constant instanceof CPLong) {
  300.                 bcCodes.add(20); // lldc2_w
  301.                 bcLongRef.add((CPLong) constant);
  302.             } else if (constant instanceof CPDouble) {
  303.                 bcCodes.add(239); // dldc2_w
  304.                 bcDoubleRef.add((CPDouble) constant);
  305.             } else if (constant instanceof CPString) {
  306.                 bcCodes.add(19); // aldc
  307.                 bcStringRef.add((CPString) constant);
  308.             } else if (constant instanceof CPClass) {
  309.                 bcCodes.add(236); // cldc
  310.                 bcClassRef.add((CPClass) constant);
  311.             } else {
  312.                 throw new IllegalArgumentException("Constant should not be null");
  313.             }
  314.         } else {
  315.             byteCodeOffset += 2;
  316.             if (constant instanceof CPInt) {
  317.                 bcCodes.add(234); // ildc
  318.                 bcIntref.add((CPInt) constant);
  319.             } else if (constant instanceof CPFloat) {
  320.                 bcCodes.add(235); // fldc
  321.                 bcFloatRef.add((CPFloat) constant);
  322.             } else if (constant instanceof CPString) {
  323.                 bcCodes.add(18); // aldc
  324.                 bcStringRef.add((CPString) constant);
  325.             } else if (constant instanceof CPClass) {
  326.                 bcCodes.add(233); // cldc
  327.                 bcClassRef.add((CPClass) constant);
  328.             }
  329.         }
  330.         updateRenumbering();
  331.     }

  332.     public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
  333.         bcCodes.add(LOOKUPSWITCH);
  334.         bcLabel.add(dflt);
  335.         bcLabelRelativeOffsets.add(byteCodeOffset);
  336.         bcCaseCount.add(keys.length);
  337.         for (int i = 0; i < labels.length; i++) {
  338.             bcCaseValue.add(keys[i]);
  339.             bcLabel.add(labels[i]);
  340.             bcLabelRelativeOffsets.add(byteCodeOffset);
  341.         }
  342.         final int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - (byteCodeOffset + 1) % 4;
  343.         byteCodeOffset += 1 + padding + 8 + 8 * keys.length;
  344.         updateRenumbering();
  345.     }

  346.     public void visitMethodInsn(int opcode, final String owner, final String name, final String desc) {
  347.         byteCodeOffset += 3;
  348.         switch (opcode) {
  349.         case 182: // invokevirtual
  350.         case 183: // invokespecial
  351.         case 184: // invokestatic
  352.             boolean aload_0 = false;
  353.             if (bcCodes.size() > 0 && bcCodes.get(bcCodes.size() - 1) == ALOAD_0) {
  354.                 bcCodes.remove(bcCodes.size() - 1);
  355.                 aload_0 = true;
  356.                 opcode += 7;
  357.             }
  358.             if (owner.equals(currentClass)) {
  359.                 opcode += 24; // change to invokevirtual_this,
  360.                 // invokespecial_this etc.

  361.                 if (name.equals("<init>") && opcode == 207) {
  362.                     opcode = 230; // invokespecial_this_init
  363.                     bcInitRef.add(cpBands.getCPMethod(owner, name, desc));
  364.                 } else {
  365.                     bcThisMethod.add(cpBands.getCPMethod(owner, name, desc));
  366.                 }
  367.             } else if (owner.equals(superClass)) { // TODO
  368.                 opcode += 38; // change to invokevirtual_super,
  369.                 // invokespecial_super etc.
  370.                 if (name.equals("<init>") && opcode == 221) {
  371.                     opcode = 231; // invokespecial_super_init
  372.                     bcInitRef.add(cpBands.getCPMethod(owner, name, desc));
  373.                 } else {
  374.                     bcSuperMethod.add(cpBands.getCPMethod(owner, name, desc));
  375.                 }
  376.             } else {
  377.                 if (aload_0) {
  378.                     opcode -= 7;
  379.                     bcCodes.add(ALOAD_0); // add aload_0 back in
  380.                     // because there's no
  381.                     // special rewrite in this
  382.                     // case.
  383.                 }
  384.                 if (name.equals("<init>") && opcode == 183 && owner.equals(currentNewClass)) {
  385.                     opcode = 232; // invokespecial_new_init
  386.                     bcInitRef.add(cpBands.getCPMethod(owner, name, desc));
  387.                 } else {
  388.                     bcMethodRef.add(cpBands.getCPMethod(owner, name, desc));
  389.                 }
  390.             }
  391.             bcCodes.add(opcode);
  392.             break;
  393.         case 185: // invokeinterface
  394.             byteCodeOffset += 2;
  395.             final CPMethodOrField cpIMethod = cpBands.getCPIMethod(owner, name, desc);
  396.             bcIMethodRef.add(cpIMethod);
  397.             bcCodes.add(INVOKEINTERFACE);
  398.             break;
  399.         }
  400.         updateRenumbering();
  401.     }

  402.     public void visitMultiANewArrayInsn(final String desc, final int dimensions) {
  403.         byteCodeOffset += 4;
  404.         updateRenumbering();
  405.         bcCodes.add(MULTIANEWARRAY);
  406.         bcClassRef.add(cpBands.getCPClass(desc));
  407.         bcByte.add(dimensions & 0xFF);
  408.     }

  409.     public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) {
  410.         bcCodes.add(TABLESWITCH);
  411.         bcLabel.add(dflt);
  412.         bcLabelRelativeOffsets.add(byteCodeOffset);
  413.         bcCaseValue.add(min);
  414.         final int count = labels.length;
  415.         bcCaseCount.add(count);
  416.         for (int i = 0; i < count; i++) {
  417.             bcLabel.add(labels[i]);
  418.             bcLabelRelativeOffsets.add(byteCodeOffset);
  419.         }
  420.         final int padding = byteCodeOffset % 4 == 0 ? 0 : 4 - byteCodeOffset % 4;
  421.         byteCodeOffset += padding + 12 + 4 * labels.length;
  422.         updateRenumbering();
  423.     }

  424.     public void visitTypeInsn(final int opcode, final String type) {
  425.         // NEW, ANEWARRAY, CHECKCAST or INSTANCEOF
  426.         byteCodeOffset += 3;
  427.         updateRenumbering();
  428.         bcCodes.add(opcode);
  429.         bcClassRef.add(cpBands.getCPClass(type));
  430.         if (opcode == 187) { // NEW
  431.             currentNewClass = type;
  432.         }
  433.     }

  434.     public void visitVarInsn(final int opcode, final int var) {
  435.         // ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET
  436.         if (var > 255) {
  437.             byteCodeOffset += 4;
  438.             bcCodes.add(WIDE);
  439.             bcCodes.add(opcode);
  440.             bcLocal.add(var);
  441.         } else if (var > 3 || opcode == 169 /* RET */) {
  442.             byteCodeOffset += 2;
  443.             bcCodes.add(opcode);
  444.             bcLocal.add(var);
  445.         } else {
  446.             byteCodeOffset += 1;
  447.             switch (opcode) {
  448.             case 21: // ILOAD
  449.             case 54: // ISTORE
  450.                 bcCodes.add(opcode + 5 + var);
  451.                 break;
  452.             case 22: // LLOAD
  453.             case 55: // LSTORE
  454.                 bcCodes.add(opcode + 8 + var);
  455.                 break;
  456.             case 23: // FLOAD
  457.             case 56: // FSTORE
  458.                 bcCodes.add(opcode + 11 + var);
  459.                 break;
  460.             case 24: // DLOAD
  461.             case 57: // DSTORE
  462.                 bcCodes.add(opcode + 14 + var);
  463.                 break;
  464.             case 25: // A_LOAD
  465.             case 58: // A_STORE
  466.                 bcCodes.add(opcode + 17 + var);
  467.                 break;
  468.             }
  469.         }
  470.         updateRenumbering();
  471.     }

  472. }