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.LCONST_0; 32 import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_1; 33 import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD; 34 import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN; 35 import static jdk.internal.org.objectweb.asm.Opcodes.LSTORE; 36 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; 37 import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG; 38 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; 39 40 import jdk.internal.org.objectweb.asm.MethodVisitor; 41 import jdk.nashorn.internal.codegen.CompilerConstants; 42 import jdk.nashorn.internal.runtime.JSType; 43 44 /** 45 * Type class: LONG 46 */ 47 class LongType extends Type { 48 private static final long serialVersionUID = 1L; 49 50 private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Long.class, "valueOf", Long.class, long.class); 51 52 protected LongType(final String name) { 53 super(name, long.class, 3, 2); 54 } 55 56 protected LongType() { 57 this("long"); 58 } 59 60 @Override 61 public Type nextWider() { 62 return NUMBER; 63 } 64 65 @Override 66 public Class<?> getBoxedType() { 67 return Long.class; 68 } 69 70 @Override 71 public char getBytecodeStackType() { 72 return 'J'; 73 } 74 75 @Override 76 public Type load(final MethodVisitor method, final int slot) { 77 assert slot != -1; 78 method.visitVarInsn(LLOAD, slot); 79 return LONG; 80 } 81 82 @Override 83 public void store(final MethodVisitor method, final int slot) { 84 assert slot != -1; 85 method.visitVarInsn(LSTORE, slot); 86 } 87 88 @Override 89 public Type ldc(final MethodVisitor method, final Object c) { 90 assert c instanceof Long; 91 92 final long value = (Long) c; 93 94 if (value == 0L) { 95 method.visitInsn(LCONST_0); 96 } else if (value == 1L) { 97 method.visitInsn(LCONST_1); 98 } else { 99 method.visitLdcInsn(c); 100 } 101 102 return Type.LONG; 103 } 104 105 @Override 106 public Type convert(final MethodVisitor method, final Type to) { 107 if (isEquivalentTo(to)) { 108 return to; 109 } 110 111 if (to.isNumber()) { 112 method.visitInsn(L2D); 113 } else if (to.isInteger()) { 114 invokestatic(method, JSType.TO_INT32_L); 115 } else if (to.isBoolean()) { 116 method.visitInsn(L2I); 117 } else if (to.isObject()) { 118 invokestatic(method, VALUE_OF); 119 } else { 120 assert false : "Illegal conversion " + this + " -> " + to; 121 } 122 123 return to; 124 } 125 126 @Override 127 public Type add(final MethodVisitor method, final int programPoint) { 128 if(programPoint == INVALID_PROGRAM_POINT) { 129 method.visitInsn(LADD); 130 } else { 131 method.visitInvokeDynamicInsn("ladd", "(JJ)J", MATHBOOTSTRAP, programPoint); 132 } 133 return LONG; 134 } 135 136 @Override 137 public void _return(final MethodVisitor method) { 138 method.visitInsn(LRETURN); 139 } 140 141 @Override 142 public Type loadUndefined(final MethodVisitor method) { 143 method.visitLdcInsn(UNDEFINED_LONG); 144 return LONG; 145 } 146 147 @Override 148 public Type loadForcedInitializer(final MethodVisitor method) { 149 method.visitInsn(LCONST_0); 150 return LONG; 151 } 152 }