/******************************************************************************* * 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.shrikeBT; /** * This class represents instructions that convert from one primitive type to another. */ public final class ConversionInstruction extends Instruction implements IConversionInstruction { final private String fromType; final private String toType; protected ConversionInstruction(short opcode) { super(opcode); if (opcode < OP_i2b) { int k = opcode - OP_i2l; toType = indexedTypes[skip(k % 3, k / 3)]; } else { toType = indexedTypes[(opcode - OP_i2b) + TYPE_byte_index]; } if (opcode < OP_i2b) { fromType = indexedTypes[(opcode - OP_i2l) / 3]; } else { fromType = TYPE_int; } } private final static ConversionInstruction[] preallocated = preallocate(); private static ConversionInstruction[] preallocate() { ConversionInstruction[] r = new ConversionInstruction[OP_i2s - OP_i2l + 1]; for (short i = OP_i2l; i <= OP_i2s; i++) { r[i - OP_i2l] = new ConversionInstruction(i); } return r; } public static ConversionInstruction make(String fromType, String toType) throws IllegalArgumentException { int from = Util.getTypeIndex(fromType); int to = Util.getTypeIndex(toType); if (from < 0 || from > TYPE_double_index) { throw new IllegalArgumentException("Cannot convert from type " + fromType); } if (from == TYPE_int_index && (to >= TYPE_byte_index && to <= TYPE_short_index)) { return preallocated[(OP_i2b - OP_i2l) + (to - TYPE_byte_index)]; } else { if (to < 0 || to > TYPE_double_index) { throw new IllegalArgumentException("Cannot convert from type " + fromType + " to type " + toType); } if (to == from) { throw new IllegalArgumentException("Cannot convert from type " + fromType + " to same type"); } return preallocated[from * 3 + (to > from ? to - 1 : to)]; } } @Override public int getPoppedCount() { return 1; } @Override public String getFromType() { return fromType; } private static int skip(int a, int b) { return a < b ? a : a + 1; } @Override public String getToType() { return toType; } @Override public String getPushedType(String[] types) { return getToType(); } @Override public byte getPushedWordSize() { return Util.getWordSize(getToType()); } @Override public boolean equals(Object o) { if (o instanceof ConversionInstruction) { ConversionInstruction i = (ConversionInstruction) o; return i.opcode == opcode; } else { return false; } } @Override public int hashCode() { return opcode * 143111; } @Override public String toString() { return "Conversion(" + getFromType() + "," + getToType() + ")"; } @Override public void visit(IInstruction.Visitor v) throws NullPointerException { v.visitConversion(this); } @Override public boolean isPEI() { return false; } @Override public boolean throwsExceptionOnOverflow() { return false; } }