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     }