1/* 2 * Copyright (c) 2010, 2016, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.nashorn.internal.codegen.types; 27 28import static jdk.internal.org.objectweb.asm.Opcodes.BIPUSH; 29import static jdk.internal.org.objectweb.asm.Opcodes.I2D; 30import static jdk.internal.org.objectweb.asm.Opcodes.I2L; 31import static jdk.internal.org.objectweb.asm.Opcodes.IADD; 32import static jdk.internal.org.objectweb.asm.Opcodes.IAND; 33import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0; 34import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1; 35import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_2; 36import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_3; 37import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_4; 38import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_5; 39import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_M1; 40import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD; 41import static jdk.internal.org.objectweb.asm.Opcodes.IMUL; 42import static jdk.internal.org.objectweb.asm.Opcodes.INEG; 43import static jdk.internal.org.objectweb.asm.Opcodes.IOR; 44import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN; 45import static jdk.internal.org.objectweb.asm.Opcodes.ISHL; 46import static jdk.internal.org.objectweb.asm.Opcodes.ISHR; 47import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE; 48import static jdk.internal.org.objectweb.asm.Opcodes.ISUB; 49import static jdk.internal.org.objectweb.asm.Opcodes.IUSHR; 50import static jdk.internal.org.objectweb.asm.Opcodes.IXOR; 51import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH; 52import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; 53import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_INT; 54import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; 55 56import jdk.internal.org.objectweb.asm.MethodVisitor; 57import jdk.nashorn.internal.codegen.CompilerConstants; 58import jdk.nashorn.internal.runtime.JSType; 59 60/** 61 * Type class: INT 62 */ 63class IntType extends BitwiseType { 64 private static final long serialVersionUID = 1L; 65 66 private static final CompilerConstants.Call TO_STRING = staticCallNoLookup(Integer.class, "toString", String.class, int.class); 67 private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Integer.class, "valueOf", Integer.class, int.class); 68 69 protected IntType() { 70 super("int", int.class, 2, 1); 71 } 72 73 @Override 74 public Type nextWider() { 75 return NUMBER; 76 } 77 78 @Override 79 public Class<?> getBoxedType() { 80 return Integer.class; 81 } 82 83 @Override 84 public char getBytecodeStackType() { 85 return 'I'; 86 } 87 88 @Override 89 public Type ldc(final MethodVisitor method, final Object c) { 90 assert c instanceof Integer; 91 92 final int value = ((Integer) c); 93 94 switch (value) { 95 case -1: 96 method.visitInsn(ICONST_M1); 97 break; 98 case 0: 99 method.visitInsn(ICONST_0); 100 break; 101 case 1: 102 method.visitInsn(ICONST_1); 103 break; 104 case 2: 105 method.visitInsn(ICONST_2); 106 break; 107 case 3: 108 method.visitInsn(ICONST_3); 109 break; 110 case 4: 111 method.visitInsn(ICONST_4); 112 break; 113 case 5: 114 method.visitInsn(ICONST_5); 115 break; 116 default: 117 if (value == (byte) value) { 118 method.visitIntInsn(BIPUSH, value); 119 } else if (value == (short) value) { 120 method.visitIntInsn(SIPUSH, value); 121 } else { 122 method.visitLdcInsn(c); 123 } 124 break; 125 } 126 127 return Type.INT; 128 } 129 130 @Override 131 public Type convert(final MethodVisitor method, final Type to) { 132 if (to.isEquivalentTo(this)) { 133 return to; 134 } 135 136 if (to.isNumber()) { 137 method.visitInsn(I2D); 138 } else if (to.isLong()) { 139 method.visitInsn(I2L); 140 } else if (to.isBoolean()) { 141 //nop 142 } else if (to.isString()) { 143 invokestatic(method, TO_STRING); 144 } else if (to.isObject()) { 145 invokestatic(method, VALUE_OF); 146 } else { 147 throw new UnsupportedOperationException("Illegal conversion " + this + " -> " + to); 148 } 149 150 return to; 151 } 152 153 @Override 154 public Type add(final MethodVisitor method, final int programPoint) { 155 if(programPoint == INVALID_PROGRAM_POINT) { 156 method.visitInsn(IADD); 157 } else { 158 ldc(method, programPoint); 159 JSType.ADD_EXACT.invoke(method); 160 } 161 return INT; 162 } 163 164 @Override 165 public Type shr(final MethodVisitor method) { 166 method.visitInsn(IUSHR); 167 return INT; 168 } 169 170 @Override 171 public Type sar(final MethodVisitor method) { 172 method.visitInsn(ISHR); 173 return INT; 174 } 175 176 @Override 177 public Type shl(final MethodVisitor method) { 178 method.visitInsn(ISHL); 179 return INT; 180 } 181 182 @Override 183 public Type and(final MethodVisitor method) { 184 method.visitInsn(IAND); 185 return INT; 186 } 187 188 @Override 189 public Type or(final MethodVisitor method) { 190 method.visitInsn(IOR); 191 return INT; 192 } 193 194 @Override 195 public Type xor(final MethodVisitor method) { 196 method.visitInsn(IXOR); 197 return INT; 198 } 199 200 @Override 201 public Type load(final MethodVisitor method, final int slot) { 202 assert slot != -1; 203 method.visitVarInsn(ILOAD, slot); 204 return INT; 205 } 206 207 @Override 208 public void store(final MethodVisitor method, final int slot) { 209 assert slot != -1; 210 method.visitVarInsn(ISTORE, slot); 211 } 212 213 @Override 214 public Type sub(final MethodVisitor method, final int programPoint) { 215 if(programPoint == INVALID_PROGRAM_POINT) { 216 method.visitInsn(ISUB); 217 } else { 218 ldc(method, programPoint); 219 JSType.SUB_EXACT.invoke(method); 220 } 221 return INT; 222 } 223 224 @Override 225 public Type mul(final MethodVisitor method, final int programPoint) { 226 if(programPoint == INVALID_PROGRAM_POINT) { 227 method.visitInsn(IMUL); 228 } else { 229 ldc(method, programPoint); 230 JSType.MUL_EXACT.invoke(method); 231 } 232 return INT; 233 } 234 235 @Override 236 public Type div(final MethodVisitor method, final int programPoint) { 237 if (programPoint == INVALID_PROGRAM_POINT) { 238 JSType.DIV_ZERO.invoke(method); 239 } else { 240 ldc(method, programPoint); 241 JSType.DIV_EXACT.invoke(method); 242 } 243 return INT; 244 } 245 246 @Override 247 public Type rem(final MethodVisitor method, final int programPoint) { 248 if (programPoint == INVALID_PROGRAM_POINT) { 249 JSType.REM_ZERO.invoke(method); 250 } else { 251 ldc(method, programPoint); 252 JSType.REM_EXACT.invoke(method); 253 } 254 return INT; 255 } 256 257 @Override 258 public Type neg(final MethodVisitor method, final int programPoint) { 259 if(programPoint == INVALID_PROGRAM_POINT) { 260 method.visitInsn(INEG); 261 } else { 262 ldc(method, programPoint); 263 JSType.NEGATE_EXACT.invoke(method); 264 } 265 return INT; 266 } 267 268 @Override 269 public void _return(final MethodVisitor method) { 270 method.visitInsn(IRETURN); 271 } 272 273 @Override 274 public Type loadUndefined(final MethodVisitor method) { 275 method.visitLdcInsn(UNDEFINED_INT); 276 return INT; 277 } 278 279 @Override 280 public Type loadForcedInitializer(final MethodVisitor method) { 281 method.visitInsn(ICONST_0); 282 return INT; 283 } 284 285 @Override 286 public Type cmp(final MethodVisitor method, final boolean isCmpG) { 287 throw new UnsupportedOperationException("cmp" + (isCmpG ? 'g' : 'l')); 288 } 289 290 @Override 291 public Type cmp(final MethodVisitor method) { 292 throw new UnsupportedOperationException("cmp"); 293 } 294 295} 296