
com.ibm.wala.shrike.shrikeBT.SwitchInstruction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.ibm.wala.shrike Show documentation
Show all versions of com.ibm.wala.shrike Show documentation
T. J. Watson Libraries for Analysis
The newest version!
/*
* Copyright (c) 2002,2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*/
package com.ibm.wala.shrike.shrikeBT;
import java.util.Arrays;
/** This instruction represents all forms of switch instructions. */
public final class SwitchInstruction extends Instruction {
private final int[] casesAndLabels;
private final int defaultLabel;
private SwitchInstruction(short opcode, int[] casesAndLabels, int defaultLabel) {
super(opcode);
this.casesAndLabels = casesAndLabels;
this.defaultLabel = defaultLabel;
}
/**
* @return the label which is branched to if none of the cases match
*/
public int getDefaultLabel() {
return defaultLabel;
}
/**
* @return an array of flattened (case, label) pairs, sorted in increasing order by case
*/
public int[] getCasesAndLabels() {
return casesAndLabels;
}
/**
* Make a switch instruction.
*
* @param casesAndLabels an array of flattened (case, label) pairs, sorted in increasing order by
* case
* @param defaultLabel the default label to branch to if no cases match
* @throws IllegalArgumentException if casesAndLabels is null
*/
public static SwitchInstruction make(int[] casesAndLabels, int defaultLabel) {
if (casesAndLabels == null) {
throw new IllegalArgumentException("casesAndLabels is null");
}
short opcode = OP_tableswitch;
for (int i = 2; i < casesAndLabels.length; i += 2) {
int curCase = casesAndLabels[i];
int lastCase = casesAndLabels[i - 2];
if (curCase <= lastCase) {
throw new IllegalArgumentException("Cases and labels array must be sorted by case");
}
if (curCase != lastCase + 1) {
opcode = OP_lookupswitch;
}
}
if (casesAndLabels.length == 0) {
opcode = OP_lookupswitch;
}
return new SwitchInstruction(opcode, casesAndLabels, defaultLabel);
}
@Override
public boolean isFallThrough() {
return false;
}
@Override
public int[] getBranchTargets() {
int[] r = new int[casesAndLabels.length / 2 + 1];
r[0] = defaultLabel;
for (int i = 1; i < r.length; i++) {
r[i] = casesAndLabels[(i - 1) * 2 + 1];
}
return r;
}
@Override
public IInstruction redirectTargets(int[] targetMap) throws IllegalArgumentException {
if (targetMap == null) {
throw new IllegalArgumentException("targetMap is null");
}
try {
int[] cs = new int[casesAndLabels.length];
for (int i = 0; i < cs.length; i += 2) {
cs[i] = casesAndLabels[i];
cs[i + 1] = targetMap[casesAndLabels[i + 1]];
}
return make(cs, targetMap[defaultLabel]);
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Illegal target map", e);
}
}
@Override
public boolean equals(Object o) {
if (o instanceof SwitchInstruction) {
SwitchInstruction i = (SwitchInstruction) o;
return i.defaultLabel == defaultLabel && Arrays.equals(i.casesAndLabels, casesAndLabels);
} else {
return false;
}
}
@Override
public int hashCode() {
int h = defaultLabel * 1348091 + 111311;
for (int i = 0; i < casesAndLabels.length; i++) {
h += (i * 9301 + 38101) * casesAndLabels[i];
}
return h;
}
@Override
public int getPoppedCount() {
return 1;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder("Switch(");
b.append(defaultLabel);
for (int casesAndLabel : casesAndLabels) {
b.append(',');
b.append(casesAndLabel);
}
b.append(')');
return b.toString();
}
@Override
public void visit(IInstruction.Visitor v) throws IllegalArgumentException {
if (v == null) {
throw new IllegalArgumentException();
}
v.visitSwitch(this);
}
@Override
public boolean isPEI() {
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy