    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.commons.compress.harmony.unpack200.bytecode.forms;
    020
    021import org.apache.commons.compress.harmony.unpack200.bytecode.ByteCode;
    022import org.apache.commons.compress.harmony.unpack200.bytecode.CodeAttribute;
    023
    024/**
    025 * Switch instruction form.
    026 */
    027public abstract class SwitchForm extends VariableInstructionForm {
    028
    029    /**
    030     * Constructs a new instance with the specified opcode, name, operandType and rewrite.
    031     *
    032     * @param opcode  index corresponding to the opcode's value.
    033     * @param name    String printable name of the opcode.
    034     */
    035    public SwitchForm(final int opcode, final String name) {
    036        super(opcode, name);
    037    }
    038
    039    /*
    040     * (non-Javadoc)
    041     *
    042     * @see org.apache.commons.compress.harmony.unpack200.bytecode.forms.ByteCodeForm#fixUpByteCodeTargets(org.apache.commons
    043     * .compress.harmony.unpack200.bytecode.ByteCode, org.apache.commons.compress.harmony.unpack200.bytecode.CodeAttribute)
    044     */
    045    @Override
    046    public void fixUpByteCodeTargets(final ByteCode byteCode, final CodeAttribute codeAttribute) {
    047        // SwitchForms need to fix up the target of label operations
    048        final int[] originalTargets = byteCode.getByteCodeTargets();
    049        final int numberOfLabels = originalTargets.length;
    050        final int[] replacementTargets = new int[numberOfLabels];
    051
    052        final int sourceIndex = byteCode.getByteCodeIndex();
    053        final int sourceValue = codeAttribute.byteCodeOffsets.get(sourceIndex).intValue();
    054        for (int index = 0; index < numberOfLabels; index++) {
    055            final int absoluteInstructionTargetIndex = sourceIndex + originalTargets[index];
    056            final int targetValue = codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex).intValue();
    057            replacementTargets[index] = targetValue - sourceValue;
    058        }
    059        final int[] rewriteArray = byteCode.getRewrite();
    060        for (int index = 0; index < numberOfLabels; index++) {
    061            setRewrite4Bytes(replacementTargets[index], rewriteArray);
    062        }
    063    }
    064
    065}