1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,303 @@ 1.4 +/* 1.5 + * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javac.jvm; 1.30 + 1.31 +import java.util.*; 1.32 + 1.33 +import com.sun.tools.javac.code.Flags; 1.34 +import com.sun.tools.javac.code.Symbol; 1.35 +import com.sun.tools.javac.util.*; 1.36 + 1.37 +/** The classfile version target. 1.38 + * 1.39 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 1.40 + * you write code that depends on this, you do so at your own risk. 1.41 + * This code and its internal interfaces are subject to change or 1.42 + * deletion without notice.</b> 1.43 + */ 1.44 +public enum Target { 1.45 + JDK1_1("1.1", 45, 3), 1.46 + JDK1_2("1.2", 46, 0), 1.47 + JDK1_3("1.3", 47, 0), 1.48 + 1.49 + /** J2SE1.4 = Merlin. */ 1.50 + JDK1_4("1.4", 48, 0), 1.51 + 1.52 + /** Support for the JSR14 prototype compiler (targeting 1.4 VMs 1.53 + * augmented with a few support classes). This is a transitional 1.54 + * option that will not be supported in the product. */ 1.55 + JSR14("jsr14", 48, 0), 1.56 + 1.57 + /** The following are undocumented transitional targets that we 1.58 + * had used to test VM fixes in update releases. We do not 1.59 + * promise to retain support for them. */ 1.60 + JDK1_4_1("1.4.1", 48, 0), 1.61 + JDK1_4_2("1.4.2", 48, 0), 1.62 + 1.63 + /** Tiger. */ 1.64 + JDK1_5("1.5", 49, 0), 1.65 + 1.66 + /** JDK 6. */ 1.67 + JDK1_6("1.6", 50, 0), 1.68 + 1.69 + /** JDK 7. */ 1.70 + JDK1_7("1.7", 51, 0); 1.71 + 1.72 + private static final Context.Key<Target> targetKey = 1.73 + new Context.Key<Target>(); 1.74 + 1.75 + public static Target instance(Context context) { 1.76 + Target instance = context.get(targetKey); 1.77 + if (instance == null) { 1.78 + Options options = Options.instance(context); 1.79 + String targetString = options.get("-target"); 1.80 + if (targetString != null) instance = lookup(targetString); 1.81 + if (instance == null) instance = DEFAULT; 1.82 + context.put(targetKey, instance); 1.83 + } 1.84 + return instance; 1.85 + } 1.86 + 1.87 + private static Target MIN; 1.88 + public static Target MIN() { return MIN; } 1.89 + 1.90 + private static Target MAX; 1.91 + public static Target MAX() { return MAX; } 1.92 + 1.93 + private static Map<String,Target> tab = new HashMap<String,Target>(); 1.94 + static { 1.95 + for (Target t : values()) { 1.96 + if (MIN == null) MIN = t; 1.97 + MAX = t; 1.98 + tab.put(t.name, t); 1.99 + } 1.100 + tab.put("5", JDK1_5); 1.101 + tab.put("6", JDK1_6); 1.102 + tab.put("7", JDK1_7); 1.103 + } 1.104 + 1.105 + public final String name; 1.106 + public final int majorVersion; 1.107 + public final int minorVersion; 1.108 + private Target(String name, int majorVersion, int minorVersion) { 1.109 + this.name = name; 1.110 + this.majorVersion = majorVersion; 1.111 + this.minorVersion = minorVersion; 1.112 + } 1.113 + 1.114 + public static final Target DEFAULT = JDK1_6; 1.115 + 1.116 + public static Target lookup(String name) { 1.117 + return tab.get(name); 1.118 + } 1.119 + 1.120 + /** In -target 1.1 and earlier, the compiler is required to emit 1.121 + * synthetic method definitions in abstract classes for interface 1.122 + * methods that are not overridden. We call them "Miranda" methods. 1.123 + */ 1.124 + public boolean requiresIproxy() { 1.125 + return compareTo(JDK1_1) <= 0; 1.126 + } 1.127 + 1.128 + /** Beginning in 1.4, we take advantage of the possibility of emitting 1.129 + * code to initialize fields before calling the superclass constructor. 1.130 + * This is allowed by the VM spec, but the verifier refused to allow 1.131 + * it until 1.4. This is necesary to translate some code involving 1.132 + * inner classes. See, for example, 4030374. 1.133 + */ 1.134 + public boolean initializeFieldsBeforeSuper() { 1.135 + return compareTo(JDK1_4) >= 0; 1.136 + } 1.137 + 1.138 + /** Beginning with -target 1.2 we obey the JLS rules for binary 1.139 + * compatibility, emitting as the qualifying type of a reference 1.140 + * to a method or field the type of the qualifier. In earlier 1.141 + * targets we use as the qualifying type the class in which the 1.142 + * member was found. The following methods named 1.143 + * *binaryCompatibility() indicate places where we vary from this 1.144 + * general rule. */ 1.145 + public boolean obeyBinaryCompatibility() { 1.146 + return compareTo(JDK1_2) >= 0; 1.147 + } 1.148 + 1.149 + /** Starting in 1.5, the compiler uses an array type as 1.150 + * the qualifier for method calls (such as clone) where required by 1.151 + * the language and VM spec. Earlier versions of the compiler 1.152 + * qualified them by Object. 1.153 + */ 1.154 + public boolean arrayBinaryCompatibility() { 1.155 + return compareTo(JDK1_5) >= 0; 1.156 + } 1.157 + 1.158 + /** Beginning after 1.2, we follow the binary compatibility rules for 1.159 + * interface fields. The 1.2 VMs had bugs handling interface fields 1.160 + * when compiled using binary compatibility (see 4400598), so this is 1.161 + * an accommodation to them. 1.162 + */ 1.163 + public boolean interfaceFieldsBinaryCompatibility() { 1.164 + return compareTo(JDK1_2) > 0; 1.165 + } 1.166 + 1.167 + /** Beginning in -target 1.5, we follow the binary compatibility 1.168 + * rules for interface methods that redefine Object methods. 1.169 + * Earlier VMs had bugs handling such methods compiled using binary 1.170 + * compatibility (see 4392595, 4398791, 4392595, 4400415). 1.171 + * The VMs were fixed during or soon after 1.4. See 4392595. 1.172 + */ 1.173 + public boolean interfaceObjectOverridesBinaryCompatibility() { 1.174 + return compareTo(JDK1_5) >= 0; 1.175 + } 1.176 + 1.177 + /** Beginning in -target 1.4.2, we make synthetic variables 1.178 + * package-private instead of private. This is to prevent the 1.179 + * necessity of access methods, which effectively relax the 1.180 + * protection of the field but bloat the class files and affect 1.181 + * execution. 1.182 + */ 1.183 + public boolean usePrivateSyntheticFields() { 1.184 + return compareTo(JDK1_4_2) < 0; 1.185 + } 1.186 + 1.187 + /** Sometimes we need to create a field to cache a value like a 1.188 + * class literal of the assertions flag. In -target 1.4.2 and 1.189 + * later we create a new synthetic class for this instead of 1.190 + * using the outermost class. See 4401576. 1.191 + */ 1.192 + public boolean useInnerCacheClass() { 1.193 + return compareTo(JDK1_4_2) >= 0; 1.194 + } 1.195 + 1.196 + /** Return true if cldc-style stack maps need to be generated. */ 1.197 + public boolean generateCLDCStackmap() { 1.198 + return false; 1.199 + } 1.200 + 1.201 + /** Beginning in -target 6, we generate stackmap attribute in 1.202 + * compact format. */ 1.203 + public boolean generateStackMapTable() { 1.204 + return compareTo(JDK1_6) >= 0; 1.205 + } 1.206 + 1.207 + /** Beginning in -target 6, package-info classes are marked synthetic. 1.208 + */ 1.209 + public boolean isPackageInfoSynthetic() { 1.210 + return compareTo(JDK1_6) >= 0; 1.211 + } 1.212 + 1.213 + /** Do we generate "empty" stackmap slots after double and long? 1.214 + */ 1.215 + public boolean generateEmptyAfterBig() { 1.216 + return false; 1.217 + } 1.218 + 1.219 + /** Beginning in 1.5, we have an unsynchronized version of 1.220 + * StringBuffer called StringBuilder that can be used by the 1.221 + * compiler for string concatenation. 1.222 + */ 1.223 + public boolean useStringBuilder() { 1.224 + return compareTo(JDK1_5) >= 0; 1.225 + } 1.226 + 1.227 + /** Beginning in 1.5, we have flag bits we can use instead of 1.228 + * marker attributes. 1.229 + */ 1.230 + public boolean useSyntheticFlag() { 1.231 + return compareTo(JDK1_5) >= 0; 1.232 + } 1.233 + public boolean useEnumFlag() { 1.234 + return compareTo(JDK1_5) >= 0; 1.235 + } 1.236 + public boolean useAnnotationFlag() { 1.237 + return compareTo(JDK1_5) >= 0; 1.238 + } 1.239 + public boolean useVarargsFlag() { 1.240 + return compareTo(JDK1_5) >= 0; 1.241 + } 1.242 + public boolean useBridgeFlag() { 1.243 + return compareTo(JDK1_5) >= 0; 1.244 + } 1.245 + 1.246 + /** Return the character to be used in constructing synthetic 1.247 + * identifiers, where not specified by the JLS. 1.248 + */ 1.249 + public char syntheticNameChar() { 1.250 + return '$'; 1.251 + } 1.252 + 1.253 + /** Does the VM have direct support for class literals? 1.254 + */ 1.255 + public boolean hasClassLiterals() { 1.256 + return compareTo(JDK1_5) >= 0; 1.257 + } 1.258 + 1.259 + /** Although we may not have support for class literals, should we 1.260 + * avoid initializing the class that the literal refers to? 1.261 + * See 4468823 1.262 + */ 1.263 + public boolean classLiteralsNoInit() { 1.264 + return compareTo(JDK1_4_2) >= 0; 1.265 + } 1.266 + 1.267 + /** Although we may not have support for class literals, when we 1.268 + * throw a NoClassDefFoundError, should we initialize its cause? 1.269 + */ 1.270 + public boolean hasInitCause() { 1.271 + return compareTo(JDK1_4) >= 0; 1.272 + } 1.273 + 1.274 + /** For bootstrapping, we use J2SE1.4's wrapper class constructors 1.275 + * to implement boxing. 1.276 + */ 1.277 + public boolean boxWithConstructors() { 1.278 + return compareTo(JDK1_5) < 0; 1.279 + } 1.280 + 1.281 + /** For bootstrapping, we use J2SE1.4's java.util.Collection 1.282 + * instead of java.lang.Iterable. 1.283 + */ 1.284 + public boolean hasIterable() { 1.285 + return compareTo(JDK1_5) >= 0; 1.286 + } 1.287 + 1.288 + /** For bootstrapping javac only, we do without java.lang.Enum if 1.289 + * necessary. 1.290 + */ 1.291 + public boolean compilerBootstrap(Symbol c) { 1.292 + return 1.293 + this == JSR14 && 1.294 + (c.flags() & Flags.ENUM) != 0 && 1.295 + c.flatName().toString().startsWith("com.sun.tools.") 1.296 + // && !Target.class.getSuperclass().getName().equals("java.lang.Enum") 1.297 + ; 1.298 + } 1.299 + 1.300 + /** In J2SE1.5.0, we introduced the "EnclosingMethod" attribute 1.301 + * for improved reflection support. 1.302 + */ 1.303 + public boolean hasEnclosingMethodAttribute() { 1.304 + return compareTo(JDK1_5) >= 0 || this == JSR14; 1.305 + } 1.306 +}