1 cananian 1.2.2.4 // OpConstant.java, created Sun Sep 13 22:49:22 1998 by cananian 2 cananian 1.2 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.2 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1 package harpoon.IR.Bytecode; 5 cananian 1.1 6 cananian 1.2.2.3 import harpoon.ClassFile.HClass; 7 cananian 1.2.2.6 import harpoon.ClassFile.Linker; 8 cananian 1.2.2.2 import harpoon.IR.RawClass.Constant; 9 cananian 1.2.2.2 import harpoon.IR.RawClass.ConstantValue; 10 cananian 1.2.2.2 import harpoon.IR.RawClass.ConstantDouble; 11 cananian 1.2.2.2 import harpoon.IR.RawClass.ConstantFloat; 12 cananian 1.2.2.2 import harpoon.IR.RawClass.ConstantInteger; 13 cananian 1.2.2.2 import harpoon.IR.RawClass.ConstantLong; 14 cananian 1.2.2.2 import harpoon.IR.RawClass.ConstantString; 15 cananian 1.1 import harpoon.Util.Util; 16 cananian 1.1 17 cananian 1.1 /** 18 cananian 1.1 * <code>OpConstant</code> represents a constant operand of a java bytecode 19 cananian 1.1 * instruction. This would typically be taken from the 20 cananian 1.1 * <code>constant_pool</code>.<p> 21 cananian 1.1 * <code>OpConstant</code> represents constant pool entries of type 22 cananian 1.1 * <code>CONSTANT_Double</code>, <code>CONSTANT_Float</code>, 23 cananian 1.1 * <code>CONSTANT_Integer</code>, <code>CONSTANT_Long</code>, 24 cananian 1.1 * and <code>CONSTANT_String</code>. 25 cananian 1.1 * 26 cananian 1.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 27 cananian 1.4 * @version $Id: OpConstant.java,v 1.4 2003/10/03 17:41:47 cananian Exp $ 28 cananian 1.1 * @see Operand 29 cananian 1.1 * @see Instr 30 cananian 1.2.2.2 * @see harpoon.IR.RawClass.ConstantDouble 31 cananian 1.2.2.2 * @see harpoon.IR.RawClass.ConstantFloat 32 cananian 1.2.2.2 * @see harpoon.IR.RawClass.ConstantInteger 33 cananian 1.2.2.2 * @see harpoon.IR.RawClass.ConstantLong 34 cananian 1.2.2.2 * @see harpoon.IR.RawClass.ConstantString 35 cananian 1.1 */ 36 cananian 1.2.2.1 public final class OpConstant extends Operand { 37 cananian 1.2.2.1 final Object value; 38 cananian 1.2.2.1 final HClass type; 39 cananian 1.1 /** Make a new <code>OpConstant</code> with the specified value and type. */ 40 cananian 1.1 public OpConstant(Object value, HClass type) { 41 cananian 1.1 this.value = value; this.type=type; check(); 42 cananian 1.1 } 43 cananian 1.1 private void check() { 44 cananian 1.1 // assert that value matches type. 45 cananian 1.2.2.6 Linker l = type.getLinker(); // use a consistent linker, whichever that is. 46 cananian 1.4 if (!Boolean.getBoolean("harpoon.runtime1.minilib")) { 47 cananian 1.4 // skip this check for minilib, because it doesn't necessarily have 48 cananian 1.4 // all the wrapper classes necessary for type.getWrapper() to work. 49 cananian 1.2.2.6 HClass check = l.forClass(value.getClass()); 50 cananian 1.1 if ((!type.isPrimitive() && check!=type) || 51 cananian 1.2.2.6 ( type.isPrimitive() && check!=type.getWrapper(l))) 52 cananian 1.1 throw new Error("value doesn't match type of OpConstant: " + 53 cananian 1.1 type + "/" + check); 54 cananian 1.4 } 55 cananian 1.1 } 56 cananian 1.1 /** Make a new <code>OpConstant</code> from a 57 cananian 1.1 * <code>constant_pool</code> entry. */ 58 cananian 1.1 public OpConstant(Code parent, int constant_pool_index) { 59 cananian 1.1 Constant c = parent.getConstant(constant_pool_index); 60 cananian 1.1 if (c instanceof ConstantValue) { 61 cananian 1.1 this.value=((ConstantValue)c).value(); 62 cananian 1.1 if (c instanceof ConstantDouble) this.type=HClass.Double; 63 cananian 1.1 else if (c instanceof ConstantFloat) this.type=HClass.Float; 64 cananian 1.1 else if (c instanceof ConstantInteger) this.type=HClass.Int; 65 cananian 1.1 else if (c instanceof ConstantLong) this.type=HClass.Long; 66 cananian 1.1 else if (c instanceof ConstantString) 67 cananian 1.2.2.5 this.type=parent.linker.forName("java.lang.String"); 68 cananian 1.1 else throw new Error("Unknown ConstantValue type: "+c); 69 cananian 1.1 } else throw new Error("Unknown constant pool entry: "+c); 70 cananian 1.1 check(); 71 cananian 1.1 } 72 cananian 1.1 /** Return the value of this <code>Operand</code>. */ 73 cananian 1.1 public Object getValue() { return value; } 74 cananian 1.1 /** Return the <code>HClass</code> type of this <Code>Operand</code>. */ 75 cananian 1.1 public HClass getType() { return type; } 76 cananian 1.1 77 cananian 1.1 /** Return a human-readable representation of this OpConstant. */ 78 cananian 1.1 public String toString() { 79 cananian 1.2.2.5 if (getType().getName().equals("java.lang.String")) 80 cananian 1.1 return "(String)\""+Util.escape(getValue().toString())+"\""; 81 cananian 1.1 return "("+getType().getName()+")"+getValue().toString(); 82 cananian 1.1 } 83 cananian 1.1 }