1 /* 2 * Copyright (c) 2010, 2013, 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 26 package jdk.nashorn.internal.codegen.types; 27 28 import static jdk.internal.org.objectweb.asm.Opcodes.L2D; 29 import static jdk.internal.org.objectweb.asm.Opcodes.L2I; 30 import static jdk.internal.org.objectweb.asm.Opcodes.LADD; 31 import static jdk.internal.org.objectweb.asm.Opcodes.LAND; 32 import static jdk.internal.org.objectweb.asm.Opcodes.LCMP; 33 import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0; 34 import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_1; 35 import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD; 36 import static jdk.internal.org.objectweb.asm.Opcodes.LMUL; 37 import static jdk.internal.org.objectweb.asm.Opcodes.LOR; 38 import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN; 39 import static jdk.internal.org.objectweb.asm.Opcodes.LSHL; 40 import static jdk.internal.org.objectweb.asm.Opcodes.LSHR; 41 import static jdk.internal.org.objectweb.asm.Opcodes.LSTORE; 42 import static jdk.internal.org.objectweb.asm.Opcodes.LSUB; 43 import static jdk.internal.org.objectweb.asm.Opcodes.LUSHR; 44 import static jdk.internal.org.objectweb.asm.Opcodes.LXOR; 45 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; 46 import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG; 47 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; 48 49 import jdk.internal.org.objectweb.asm.MethodVisitor; 50 import jdk.nashorn.internal.codegen.CompilerConstants; 51 import jdk.nashorn.internal.runtime.JSType; 52 53 /** 54 * Type class: LONG 55 */ 56 class LongType extends BitwiseType { 57 private static final long serialVersionUID = 1L; 58 59 private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Long.class, "valueOf", Long.class, long.class); 60 61 protected LongType(final String name) { 62 super(name, long.class, 3, 2); 63 } 64 65 protected LongType() { 66 this("long"); 67 } 68 69 @Override 70 public Type nextWider() { 71 return NUMBER; 72 } 73 74 @Override 75 public Class<?> getBoxedType() { 76 return Long.class; 77 } 78 79 @Override 80 public char getBytecodeStackType() { 81 return 'J'; 82 } 83 84 @Override 85 public Type cmp(final MethodVisitor method) { 86 method.visitInsn(LCMP); 87 return INT; 88 } 89 90 @Override 91 public Type load(final MethodVisitor method, final int slot) { 92 assert slot != -1; 93 method.visitVarInsn(LLOAD, slot); 94 return LONG; 95 } 96 97 @Override 98 public void store(final MethodVisitor method, final int slot) { 99 assert slot != -1; 100 method.visitVarInsn(LSTORE, slot); 101 } 102 103 @Override 104 public Type ldc(final MethodVisitor method, final Object c) { 105 assert c instanceof Long; 106 107 final long value = (Long) c; 108 109 if (value == 0L) { 110 method.visitInsn(LCONST_0); 111 } else if (value == 1L) { 112 method.visitInsn(LCONST_1); 113 } else { 114 method.visitLdcInsn(c); 115 } 116 117 return Type.LONG; 118 } 119 120 @Override 121 public Type convert(final MethodVisitor method, final Type to) { 122 if (isEquivalentTo(to)) { 123 return to; 124 } 125 126 if (to.isNumber()) { 127 method.visitInsn(L2D); 128 } else if (to.isInteger()) { 129 invokestatic(method, JSType.TO_INT32_L); 130 } else if (to.isBoolean()) { 131 method.visitInsn(L2I); 132 } else if (to.isObject()) { 133 invokestatic(method, VALUE_OF); 134 } else { 135 assert false : "Illegal conversion " + this + " -> " + to; 136 } 137 138 return to; 139 } 140 141 @Override 142 public Type add(final MethodVisitor method, final int programPoint) { 143 if(programPoint == INVALID_PROGRAM_POINT) { 144 method.visitInsn(LADD); 145 } else { 146 method.visitInvokeDynamicInsn("ladd", "(JJ)J", MATHBOOTSTRAP, programPoint); 147 } 148 return LONG; 149 } 150 151 @Override 152 public Type sub(final MethodVisitor method, final int programPoint) { 153 if(programPoint == INVALID_PROGRAM_POINT) { 154 method.visitInsn(LSUB); 155 } else { 156 method.visitInvokeDynamicInsn("lsub", "(JJ)J", MATHBOOTSTRAP, programPoint); 157 } 158 return LONG; 159 } 160 161 @Override 162 public Type mul(final MethodVisitor method, final int programPoint) { 163 if(programPoint == INVALID_PROGRAM_POINT) { 164 method.visitInsn(LMUL); 165 } else { 166 method.visitInvokeDynamicInsn("lmul", "(JJ)J", MATHBOOTSTRAP, programPoint); 167 } 168 return LONG; 169 } 170 171 @Override 172 public Type div(final MethodVisitor method, final int programPoint) { 173 if (programPoint == INVALID_PROGRAM_POINT) { 174 JSType.DIV_ZERO_LONG.invoke(method); 175 } else { 176 method.visitInvokeDynamicInsn("ldiv", "(JJ)J", MATHBOOTSTRAP, programPoint); 177 } 178 return LONG; 179 } 180 181 @Override 182 public Type rem(final MethodVisitor method, final int programPoint) { 183 if (programPoint == INVALID_PROGRAM_POINT) { 184 JSType.REM_ZERO_LONG.invoke(method); 185 } else { 186 method.visitInvokeDynamicInsn("lrem", "(JJ)J", MATHBOOTSTRAP, programPoint); 187 } 188 return LONG; 189 } 190 191 @Override 192 public Type shr(final MethodVisitor method) { 193 method.visitInsn(LUSHR); 194 return LONG; 195 } 196 197 @Override 198 public Type sar(final MethodVisitor method) { 199 method.visitInsn(LSHR); 200 return LONG; 201 } 202 203 @Override 204 public Type shl(final MethodVisitor method) { 205 method.visitInsn(LSHL); 206 return LONG; 207 } 208 209 @Override 210 public Type and(final MethodVisitor method) { 211 method.visitInsn(LAND); 212 return LONG; 213 } 214 215 @Override 216 public Type or(final MethodVisitor method) { 217 method.visitInsn(LOR); 218 return LONG; 219 } 220 221 @Override 222 public Type xor(final MethodVisitor method) { 223 method.visitInsn(LXOR); 224 return LONG; 225 } 226 227 @Override 228 public Type neg(final MethodVisitor method, final int programPoint) { 229 method.visitInvokeDynamicInsn("lneg", "(J)J", MATHBOOTSTRAP, programPoint); 230 return LONG; 231 } 232 233 @Override 234 public void _return(final MethodVisitor method) { 235 method.visitInsn(LRETURN); 236 } 237 238 @Override 239 public Type loadUndefined(final MethodVisitor method) { 240 method.visitLdcInsn(UNDEFINED_LONG); 241 return LONG; 242 } 243 244 @Override 245 public Type loadForcedInitializer(final MethodVisitor method) { 246 method.visitInsn(LCONST_0); 247 return LONG; 248 } 249 250 @Override 251 public Type cmp(final MethodVisitor method, final boolean isCmpG) { 252 return cmp(method); 253 } 254 }