1 /* 2 * Copyright (c) 2009, 2019, 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 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 static PrimitiveConstant forTypeChar(char kind, long i) { 50 return JavaConstant.forIntegerKind(JavaKind.fromPrimitiveOrVoidTypeChar(kind), i); 51 } 52 53 @Override 54 public JavaKind getJavaKind() { 55 return kind; 56 } 57 58 @Override 59 public boolean isNull() { 60 return false; 61 } 62 63 @Override 64 public boolean isDefaultForKind() { 65 return primitive == 0; 66 } 67 68 @Override 69 public boolean asBoolean() { 70 assert getJavaKind() == JavaKind.Boolean; 71 return primitive != 0L; 72 } 73 74 @Override 75 public int asInt() { 76 assert getJavaKind().getStackKind() == JavaKind.Int : getJavaKind().getStackKind(); 77 return (int) primitive; 78 } 79 80 @Override 81 public long asLong() { 82 assert getJavaKind().isNumericInteger(); 83 return primitive; 84 } 85 86 @Override 87 public float asFloat() { 88 assert getJavaKind() == JavaKind.Float; 89 return Float.intBitsToFloat((int) primitive); 90 } 91 92 @Override 93 public double asDouble() { 94 assert getJavaKind() == JavaKind.Double; 95 return Double.longBitsToDouble(primitive); 96 } 97 98 @Override 99 public Object asBoxedPrimitive() { 100 switch (getJavaKind()) { 101 case Byte: 102 return Byte.valueOf((byte) primitive); 103 case Boolean: 104 return Boolean.valueOf(asBoolean()); 105 case Short: 106 return Short.valueOf((short) primitive); 107 case Char: 108 return Character.valueOf((char) primitive); 109 case Int: 110 return Integer.valueOf(asInt()); 111 case Long: 112 return Long.valueOf(asLong()); 113 case Float: 114 return Float.valueOf(asFloat()); 115 case Double: 116 return Double.valueOf(asDouble()); 117 default: 118 throw new IllegalArgumentException("unexpected kind " + getJavaKind()); 119 } 120 } 121 122 @Override 123 public int getSerializedSize() { 124 return getJavaKind().getByteCount(); 125 } 126 127 @Override 128 public void serialize(ByteBuffer buffer) { 129 switch (getJavaKind()) { 130 case Byte: 131 case Boolean: 132 buffer.put((byte) primitive); 133 break; 134 case Short: 135 buffer.putShort((short) primitive); 136 break; 137 case Char: 138 buffer.putChar((char) primitive); 139 break; 140 case Int: 141 buffer.putInt(asInt()); 142 break; 143 case Long: 144 buffer.putLong(asLong()); 145 break; 146 case Float: 147 buffer.putFloat(asFloat()); 148 break; 149 case Double: 150 buffer.putDouble(asDouble()); 151 break; 152 default: 153 throw new IllegalArgumentException("unexpected kind " + getJavaKind()); 154 } 155 } 156 157 @Override 158 public int hashCode() { 159 return (int) (primitive ^ (primitive >>> 32)) * (getJavaKind().ordinal() + 31); 160 } 161 162 @Override 163 public boolean equals(Object o) { 164 if (o == this) { 165 return true; 166 } 167 if (!(o instanceof PrimitiveConstant)) { 168 return false; 169 } 170 PrimitiveConstant other = (PrimitiveConstant) o; 171 return this.kind.equals(other.kind) && this.primitive == other.primitive; 172 } 173 174 @Override 175 public String toString() { 176 if (getJavaKind() == JavaKind.Illegal) { 177 return "illegal"; 178 } else { 179 return getJavaKind().getJavaName() + "[" + asBoxedPrimitive() + "|0x" + Long.toHexString(primitive) + "]"; 180 } 181 } 182 }