1 /*
2  * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 package jdk.vm.ci.meta;
24 
25 import java.nio.ByteBuffer;
26 
27 /**
28  * Represents a primitive constant value, such as an integer or floating point number, within the
29  * compiler and across the compiler/runtime interface.
30  */
31 public class PrimitiveConstant implements JavaConstant, SerializableConstant {
32 
33     private final JavaKind kind;
34 
35     /**
36      * The boxed primitive value as a {@code long}. For {@code float} and {@code double} values,
37      * this value is the result of {@link Float#floatToRawIntBits(float)} and
38      * {@link Double#doubleToRawLongBits(double)} respectively.
39      */
40     private final long primitive;
41 
PrimitiveConstant(JavaKind kind, long primitive)42     protected PrimitiveConstant(JavaKind kind, long primitive) {
43         this.primitive = primitive;
44         this.kind = kind;
45 
46         assert kind.isPrimitive() || kind == JavaKind.Illegal;
47     }
48 
49     @Override
getJavaKind()50     public JavaKind getJavaKind() {
51         return kind;
52     }
53 
54     @Override
isNull()55     public boolean isNull() {
56         return false;
57     }
58 
59     @Override
isDefaultForKind()60     public boolean isDefaultForKind() {
61         return primitive == 0;
62     }
63 
64     @Override
asBoolean()65     public boolean asBoolean() {
66         assert getJavaKind() == JavaKind.Boolean;
67         return primitive != 0L;
68     }
69 
70     @Override
asInt()71     public int asInt() {
72         assert getJavaKind().getStackKind() == JavaKind.Int : getJavaKind().getStackKind();
73         return (int) primitive;
74     }
75 
76     @Override
asLong()77     public long asLong() {
78         assert getJavaKind().isNumericInteger();
79         return primitive;
80     }
81 
82     @Override
asFloat()83     public float asFloat() {
84         assert getJavaKind() == JavaKind.Float;
85         return Float.intBitsToFloat((int) primitive);
86     }
87 
88     @Override
asDouble()89     public double asDouble() {
90         assert getJavaKind() == JavaKind.Double;
91         return Double.longBitsToDouble(primitive);
92     }
93 
94     @Override
asBoxedPrimitive()95     public Object asBoxedPrimitive() {
96         switch (getJavaKind()) {
97             case Byte:
98                 return Byte.valueOf((byte) primitive);
99             case Boolean:
100                 return Boolean.valueOf(asBoolean());
101             case Short:
102                 return Short.valueOf((short) primitive);
103             case Char:
104                 return Character.valueOf((char) primitive);
105             case Int:
106                 return Integer.valueOf(asInt());
107             case Long:
108                 return Long.valueOf(asLong());
109             case Float:
110                 return Float.valueOf(asFloat());
111             case Double:
112                 return Double.valueOf(asDouble());
113             default:
114                 throw new IllegalArgumentException("unexpected kind " + getJavaKind());
115         }
116     }
117 
118     @Override
getSerializedSize()119     public int getSerializedSize() {
120         return getJavaKind().getByteCount();
121     }
122 
123     @Override
serialize(ByteBuffer buffer)124     public void serialize(ByteBuffer buffer) {
125         switch (getJavaKind()) {
126             case Byte:
127             case Boolean:
128                 buffer.put((byte) primitive);
129                 break;
130             case Short:
131                 buffer.putShort((short) primitive);
132                 break;
133             case Char:
134                 buffer.putChar((char) primitive);
135                 break;
136             case Int:
137                 buffer.putInt(asInt());
138                 break;
139             case Long:
140                 buffer.putLong(asLong());
141                 break;
142             case Float:
143                 buffer.putFloat(asFloat());
144                 break;
145             case Double:
146                 buffer.putDouble(asDouble());
147                 break;
148             default:
149                 throw new IllegalArgumentException("unexpected kind " + getJavaKind());
150         }
151     }
152 
153     @Override
hashCode()154     public int hashCode() {
155         return (int) (primitive ^ (primitive >>> 32)) * (getJavaKind().ordinal() + 31);
156     }
157 
158     @Override
equals(Object o)159     public boolean equals(Object o) {
160         if (o == this) {
161             return true;
162         }
163         if (!(o instanceof PrimitiveConstant)) {
164             return false;
165         }
166         PrimitiveConstant other = (PrimitiveConstant) o;
167         return this.kind.equals(other.kind) && this.primitive == other.primitive;
168     }
169 
170     @Override
toString()171     public String toString() {
172         if (getJavaKind() == JavaKind.Illegal) {
173             return "illegal";
174         } else {
175             return getJavaKind().getJavaName() + "[" + asBoxedPrimitive() + "|0x" + Long.toHexString(primitive) + "]";
176         }
177     }
178 }
179