| 1 | /* |
| 2 | * Copyright 1999-2006 Sun Microsystems, Inc. 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. Sun designates this |
| 8 | * particular file as subject to the "Classpath" exception as provided |
| 9 | * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 22 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 23 | * have any questions. |
| 24 | */ |
| 25 | |
| 26 | package com.sun.tools.javac.code; |
| 27 | |
| 28 | import java.util.*; |
| 29 | |
| 30 | import com.sun.tools.javac.util.*; |
| 31 | import com.sun.tools.javac.util.List; |
| 32 | import com.sun.tools.javac.code.Symbol.*; |
| 33 | import com.sun.tools.javac.code.Type.*; |
| 34 | import com.sun.tools.javac.jvm.*; |
| 35 | |
| 36 | import static com.sun.tools.javac.jvm.ByteCodes.*; |
| 37 | import static com.sun.tools.javac.code.Flags.*; |
| 38 | |
| 39 | /** A class that defines all predefined constants and operators |
| 40 | * as well as special classes such as java.lang.Object, which need |
| 41 | * to be known to the compiler. All symbols are held in instance |
| 42 | * fields. This makes it possible to work in multiple concurrent |
| 43 | * projects, which might use different class files for library classes. |
| 44 | * |
| 45 | * <p><b>This is NOT part of any API supported by Sun Microsystems. If |
| 46 | * you write code that depends on this, you do so at your own risk. |
| 47 | * This code and its internal interfaces are subject to change or |
| 48 | * deletion without notice.</b> |
| 49 | */ |
| 50 | public class Symtab { |
| 51 | /** The context key for the symbol table. */ |
| 52 | protected static final Context.Key<Symtab> symtabKey = |
| 53 | new Context.Key<Symtab>(); |
| 54 | |
| 55 | /** Get the symbol table instance. */ |
| 56 | public static Symtab instance(Context context) { |
| 57 | Symtab instance = context.get(symtabKey); |
| 58 | if (instance == null) |
| 59 | instance = new Symtab(context); |
| 60 | return instance; |
| 61 | } |
| 62 | |
| 63 | /** Builtin types. |
| 64 | */ |
| 65 | public final Type byteType = new Type(TypeTags.BYTE, null); |
| 66 | public final Type charType = new Type(TypeTags.CHAR, null); |
| 67 | public final Type shortType = new Type(TypeTags.SHORT, null); |
| 68 | public final Type intType = new Type(TypeTags.INT, null); |
| 69 | public final Type longType = new Type(TypeTags.LONG, null); |
| 70 | public final Type floatType = new Type(TypeTags.FLOAT, null); |
| 71 | public final Type doubleType = new Type(TypeTags.DOUBLE, null); |
| 72 | public final Type booleanType = new Type(TypeTags.BOOLEAN, null); |
| 73 | public final Type botType = new BottomType(); |
| 74 | public final JCNoType voidType = new JCNoType(TypeTags.VOID); |
| 75 | |
| 76 | private final Name.Table names; |
| 77 | private final ClassReader reader; |
| 78 | |
| 79 | /** A symbol for the root package. |
| 80 | */ |
| 81 | public final PackageSymbol rootPackage; |
| 82 | |
| 83 | /** A symbol for the unnamed package. |
| 84 | */ |
| 85 | public final PackageSymbol unnamedPackage; |
| 86 | |
| 87 | /** A symbol that stands for a missing symbol. |
| 88 | */ |
| 89 | public final TypeSymbol noSymbol; |
| 90 | |
| 91 | /** The error symbol. |
| 92 | */ |
| 93 | public final ClassSymbol errSymbol; |
| 94 | |
| 95 | /** An instance of the error type. |
| 96 | */ |
| 97 | public final Type errType; |
| 98 | |
| 99 | /** A value for the unknown type. */ |
| 100 | public final Type unknownType; |
| 101 | |
| 102 | /** The builtin type of all arrays. */ |
| 103 | public final ClassSymbol arrayClass; |
| 104 | public final MethodSymbol arrayCloneMethod; |
| 105 | |
| 106 | /** VGJ: The (singleton) type of all bound types. */ |
| 107 | public final ClassSymbol boundClass; |
| 108 | |
| 109 | /** The builtin type of all methods. */ |
| 110 | public final ClassSymbol methodClass; |
| 111 | |
| 112 | /** Predefined types. |
| 113 | */ |
| 114 | public final Type objectType; |
| 115 | public final Type classType; |
| 116 | public final Type classLoaderType; |
| 117 | public final Type stringType; |
| 118 | public final Type stringBufferType; |
| 119 | public final Type stringBuilderType; |
| 120 | public final Type cloneableType; |
| 121 | public final Type serializableType; |
| 122 | public final Type throwableType; |
| 123 | public final Type errorType; |
| 124 | public final Type illegalArgumentExceptionType; |
| 125 | public final Type exceptionType; |
| 126 | public final Type runtimeExceptionType; |
| 127 | public final Type classNotFoundExceptionType; |
| 128 | public final Type noClassDefFoundErrorType; |
| 129 | public final Type noSuchFieldErrorType; |
| 130 | public final Type assertionErrorType; |
| 131 | public final Type cloneNotSupportedExceptionType; |
| 132 | public final Type annotationType; |
| 133 | public final TypeSymbol enumSym; |
| 134 | public final Type listType; |
| 135 | public final Type collectionsType; |
| 136 | public final Type comparableType; |
| 137 | public final Type arraysType; |
| 138 | public final Type iterableType; |
| 139 | public final Type iteratorType; |
| 140 | public final Type annotationTargetType; |
| 141 | public final Type overrideType; |
| 142 | public final Type retentionType; |
| 143 | public final Type deprecatedType; |
| 144 | public final Type suppressWarningsType; |
| 145 | public final Type inheritedType; |
| 146 | public final Type proprietaryType; |
| 147 | |
| 148 | /** The symbol representing the length field of an array. |
| 149 | */ |
| 150 | public final VarSymbol lengthVar; |
| 151 | |
| 152 | /** The null check operator. */ |
| 153 | public final OperatorSymbol nullcheck; |
| 154 | |
| 155 | /** The symbol representing the final finalize method on enums */ |
| 156 | public final MethodSymbol enumFinalFinalize; |
| 157 | |
| 158 | /** The predefined type that belongs to a tag. |
| 159 | */ |
| 160 | public final Type[] typeOfTag = new Type[TypeTags.TypeTagCount]; |
| 161 | |
| 162 | /** The name of the class that belongs to a basix type tag. |
| 163 | */ |
| 164 | public final Name[] boxedName = new Name[TypeTags.TypeTagCount]; |
| 165 | |
| 166 | /** A hashtable containing the encountered top-level and member classes, |
| 167 | * indexed by flat names. The table does not contain local classes. |
| 168 | * It should be updated from the outside to reflect classes defined |
| 169 | * by compiled source files. |
| 170 | */ |
| 171 | public final Map<Name, ClassSymbol> classes = new HashMap<Name, ClassSymbol>(); |
| 172 | |
| 173 | /** A hashtable containing the encountered packages. |
| 174 | * the table should be updated from outside to reflect packages defined |
| 175 | * by compiled source files. |
| 176 | */ |
| 177 | public final Map<Name, PackageSymbol> packages = new HashMap<Name, PackageSymbol>(); |
| 178 | |
| 179 | public void initType(Type type, ClassSymbol c) { |
| 180 | type.tsym = c; |
| 181 | typeOfTag[type.tag] = type; |
| 182 | } |
| 183 | |
| 184 | public void initType(Type type, String name) { |
| 185 | initType( |
| 186 | type, |
| 187 | new ClassSymbol( |
| 188 | PUBLIC, names.fromString(name), type, rootPackage)); |
| 189 | } |
| 190 | |
| 191 | public void initType(Type type, String name, String bname) { |
| 192 | initType(type, name); |
| 193 | boxedName[type.tag] = names.fromString("java.lang." + bname); |
| 194 | } |
| 195 | |
| 196 | /** The class symbol that owns all predefined symbols. |
| 197 | */ |
| 198 | public final ClassSymbol predefClass; |
| 199 | |
| 200 | /** Enter a constant into symbol table. |
| 201 | * @param name The constant's name. |
| 202 | * @param type The constant's type. |
| 203 | */ |
| 204 | private VarSymbol enterConstant(String name, Type type) { |
| 205 | VarSymbol c = new VarSymbol( |
| 206 | PUBLIC | STATIC | FINAL, |
| 207 | names.fromString(name), |
| 208 | type, |
| 209 | predefClass); |
| 210 | c.setData(type.constValue()); |
| 211 | predefClass.members().enter(c); |
| 212 | return c; |
| 213 | } |
| 214 | |
| 215 | /** Enter a binary operation into symbol table. |
| 216 | * @param name The name of the operator. |
| 217 | * @param left The type of the left operand. |
| 218 | * @param right The type of the left operand. |
| 219 | * @param res The operation's result type. |
| 220 | * @param opcode The operation's bytecode instruction. |
| 221 | */ |
| 222 | private void enterBinop(String name, |
| 223 | Type left, Type right, Type res, |
| 224 | int opcode) { |
| 225 | predefClass.members().enter( |
| 226 | new OperatorSymbol( |
| 227 | names.fromString(name), |
| 228 | new MethodType(List.of(left, right), res, |
| 229 | List.<Type>nil(), methodClass), |
| 230 | opcode, |
| 231 | predefClass)); |
| 232 | } |
| 233 | |
| 234 | /** Enter a binary operation, as above but with two opcodes, |
| 235 | * which get encoded as (opcode1 << ByteCodeTags.preShift) + opcode2. |
| 236 | * @param opcode1 First opcode. |
| 237 | * @param opcode2 Second opcode. |
| 238 | */ |
| 239 | private void enterBinop(String name, |
| 240 | Type left, Type right, Type res, |
| 241 | int opcode1, int opcode2) { |
| 242 | enterBinop( |
| 243 | name, left, right, res, (opcode1 << ByteCodes.preShift) | opcode2); |
| 244 | } |
| 245 | |
| 246 | /** Enter a unary operation into symbol table. |
| 247 | * @param name The name of the operator. |
| 248 | * @param arg The type of the operand. |
| 249 | * @param res The operation's result type. |
| 250 | * @param opcode The operation's bytecode instruction. |
| 251 | */ |
| 252 | private OperatorSymbol enterUnop(String name, |
| 253 | Type arg, |
| 254 | Type res, |
| 255 | int opcode) { |
| 256 | OperatorSymbol sym = |
| 257 | new OperatorSymbol(names.fromString(name), |
| 258 | new MethodType(List.of(arg), |
| 259 | res, |
| 260 | List.<Type>nil(), |
| 261 | methodClass), |
| 262 | opcode, |
| 263 | predefClass); |
| 264 | predefClass.members().enter(sym); |
| 265 | return sym; |
| 266 | } |
| 267 | |
| 268 | /** Enter a class into symbol table. |
| 269 | * @param The name of the class. |
| 270 | */ |
| 271 | private Type enterClass(String s) { |
| 272 | return reader.enterClass(names.fromString(s)).type; |
| 273 | } |
| 274 | |
| 275 | /** Constructor; enters all predefined identifiers and operators |
| 276 | * into symbol table. |
| 277 | */ |
| 278 | protected Symtab(Context context) throws CompletionFailure { |
| 279 | context.put(symtabKey, this); |
| 280 | |
| 281 | names = Name.Table.instance(context); |
| 282 | |
| 283 | // Create the unknown type |
| 284 | unknownType = new Type(TypeTags.UNKNOWN, null); |
| 285 | |
| 286 | // create the basic builtin symbols |
| 287 | rootPackage = new PackageSymbol(names.empty, null); |
| 288 | final Messages messages = Messages.instance(context); |
| 289 | unnamedPackage = new PackageSymbol(names.empty, rootPackage) { |
| 290 | public String toString() { |
| 291 | return messages.getLocalizedString("compiler.misc.unnamed.package"); |
| 292 | } |
| 293 | }; |
| 294 | noSymbol = new TypeSymbol(0, names.empty, Type.noType, rootPackage); |
| 295 | noSymbol.kind = Kinds.NIL; |
| 296 | |
| 297 | // create the error symbols |
| 298 | errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage); |
| 299 | errType = new ErrorType(errSymbol); |
| 300 | |
| 301 | // initialize builtin types |
| 302 | initType(byteType, "byte", "Byte"); |
| 303 | initType(shortType, "short", "Short"); |
| 304 | initType(charType, "char", "Character"); |
| 305 | initType(intType, "int", "Integer"); |
| 306 | initType(longType, "long", "Long"); |
| 307 | initType(floatType, "float", "Float"); |
| 308 | initType(doubleType, "double", "Double"); |
| 309 | initType(booleanType, "boolean", "Boolean"); |
| 310 | initType(voidType, "void", "Void"); |
| 311 | initType(botType, "<nulltype>"); |
| 312 | initType(errType, errSymbol); |
| 313 | initType(unknownType, "<any?>"); |
| 314 | |
| 315 | // the builtin class of all arrays |
| 316 | arrayClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Array, noSymbol); |
| 317 | |
| 318 | // VGJ |
| 319 | boundClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Bound, noSymbol); |
| 320 | |
| 321 | // the builtin class of all methods |
| 322 | methodClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Method, noSymbol); |
| 323 | |
| 324 | // Create class to hold all predefined constants and operations. |
| 325 | predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage); |
| 326 | Scope scope = new Scope(predefClass); |
| 327 | predefClass.members_field = scope; |
| 328 | |
| 329 | // Enter symbols for basic types. |
| 330 | scope.enter(byteType.tsym); |
| 331 | scope.enter(shortType.tsym); |
| 332 | scope.enter(charType.tsym); |
| 333 | scope.enter(intType.tsym); |
| 334 | scope.enter(longType.tsym); |
| 335 | scope.enter(floatType.tsym); |
| 336 | scope.enter(doubleType.tsym); |
| 337 | scope.enter(booleanType.tsym); |
| 338 | scope.enter(errType.tsym); |
| 339 | |
| 340 | classes.put(predefClass.fullname, predefClass); |
| 341 | |
| 342 | reader = ClassReader.instance(context); |
| 343 | reader.init(this); |
| 344 | |
| 345 | // Enter predefined classes. |
| 346 | objectType = enterClass("java.lang.Object"); |
| 347 | classType = enterClass("java.lang.Class"); |
| 348 | stringType = enterClass("java.lang.String"); |
| 349 | stringBufferType = enterClass("java.lang.StringBuffer"); |
| 350 | stringBuilderType = enterClass("java.lang.StringBuilder"); |
| 351 | cloneableType = enterClass("java.lang.Cloneable"); |
| 352 | throwableType = enterClass("java.lang.Throwable"); |
| 353 | serializableType = enterClass("java.io.Serializable"); |
| 354 | errorType = enterClass("java.lang.Error"); |
| 355 | illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException"); |
| 356 | exceptionType = enterClass("java.lang.Exception"); |
| 357 | runtimeExceptionType = enterClass("java.lang.RuntimeException"); |
| 358 | classNotFoundExceptionType = enterClass("java.lang.ClassNotFoundException"); |
| 359 | noClassDefFoundErrorType = enterClass("java.lang.NoClassDefFoundError"); |
| 360 | noSuchFieldErrorType = enterClass("java.lang.NoSuchFieldError"); |
| 361 | assertionErrorType = enterClass("java.lang.AssertionError"); |
| 362 | cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException"); |
| 363 | annotationType = enterClass("java.lang.annotation.Annotation"); |
| 364 | classLoaderType = enterClass("java.lang.ClassLoader"); |
| 365 | enumSym = reader.enterClass(names.java_lang_Enum); |
| 366 | enumFinalFinalize = |
| 367 | new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL, |
| 368 | names.finalize, |
| 369 | new MethodType(List.<Type>nil(), voidType, |
| 370 | List.<Type>nil(), methodClass), |
| 371 | enumSym); |
| 372 | listType = enterClass("java.util.List"); |
| 373 | collectionsType = enterClass("java.util.Collections"); |
| 374 | comparableType = enterClass("java.lang.Comparable"); |
| 375 | arraysType = enterClass("java.util.Arrays"); |
| 376 | iterableType = Target.instance(context).hasIterable() |
| 377 | ? enterClass("java.lang.Iterable") |
| 378 | : enterClass("java.util.Collection"); |
| 379 | iteratorType = enterClass("java.util.Iterator"); |
| 380 | annotationTargetType = enterClass("java.lang.annotation.Target"); |
| 381 | overrideType = enterClass("java.lang.Override"); |
| 382 | retentionType = enterClass("java.lang.annotation.Retention"); |
| 383 | deprecatedType = enterClass("java.lang.Deprecated"); |
| 384 | suppressWarningsType = enterClass("java.lang.SuppressWarnings"); |
| 385 | inheritedType = enterClass("java.lang.annotation.Inherited"); |
| 386 | |
| 387 | // Enter a synthetic class that is used to mark Sun |
| 388 | // proprietary classes in ct.sym. This class does not have a |
| 389 | // class file. |
| 390 | ClassType proprietaryType = (ClassType)enterClass("sun.Proprietary+Annotation"); |
| 391 | this.proprietaryType = proprietaryType; |
| 392 | ClassSymbol proprietarySymbol = (ClassSymbol)proprietaryType.tsym; |
| 393 | proprietarySymbol.completer = null; |
| 394 | proprietarySymbol.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; |
| 395 | proprietarySymbol.erasure_field = proprietaryType; |
| 396 | proprietarySymbol.members_field = new Scope(proprietarySymbol); |
| 397 | proprietaryType.typarams_field = List.nil(); |
| 398 | proprietaryType.allparams_field = List.nil(); |
| 399 | proprietaryType.supertype_field = annotationType; |
| 400 | proprietaryType.interfaces_field = List.nil(); |
| 401 | |
| 402 | // Enter a class for arrays. |
| 403 | // The class implements java.lang.Cloneable and java.io.Serializable. |
| 404 | // It has a final length field and a clone method. |
| 405 | ClassType arrayClassType = (ClassType)arrayClass.type; |
| 406 | arrayClassType.supertype_field = objectType; |
| 407 | arrayClassType.interfaces_field = List.of(cloneableType, serializableType); |
| 408 | arrayClass.members_field = new Scope(arrayClass); |
| 409 | lengthVar = new VarSymbol( |
| 410 | PUBLIC | FINAL, |
| 411 | names.length, |
| 412 | intType, |
| 413 | arrayClass); |
| 414 | arrayClass.members().enter(lengthVar); |
| 415 | arrayCloneMethod = new MethodSymbol( |
| 416 | PUBLIC, |
| 417 | names.clone, |
| 418 | new MethodType(List.<Type>nil(), objectType, |
| 419 | List.<Type>nil(), methodClass), |
| 420 | arrayClass); |
| 421 | arrayClass.members().enter(arrayCloneMethod); |
| 422 | |
| 423 | // Enter operators. |
| 424 | enterUnop("+", doubleType, doubleType, nop); |
| 425 | enterUnop("+", floatType, floatType, nop); |
| 426 | enterUnop("+", longType, longType, nop); |
| 427 | enterUnop("+", intType, intType, nop); |
| 428 | |
| 429 | enterUnop("-", doubleType, doubleType, dneg); |
| 430 | enterUnop("-", floatType, floatType, fneg); |
| 431 | enterUnop("-", longType, longType, lneg); |
| 432 | enterUnop("-", intType, intType, ineg); |
| 433 | |
| 434 | enterUnop("~", longType, longType, lxor); |
| 435 | enterUnop("~", intType, intType, ixor); |
| 436 | |
| 437 | enterUnop("++", doubleType, doubleType, dadd); |
| 438 | enterUnop("++", floatType, floatType, fadd); |
| 439 | enterUnop("++", longType, longType, ladd); |
| 440 | enterUnop("++", intType, intType, iadd); |
| 441 | enterUnop("++", charType, charType, iadd); |
| 442 | enterUnop("++", shortType, shortType, iadd); |
| 443 | enterUnop("++", byteType, byteType, iadd); |
| 444 | |
| 445 | enterUnop("--", doubleType, doubleType, dsub); |
| 446 | enterUnop("--", floatType, floatType, fsub); |
| 447 | enterUnop("--", longType, longType, lsub); |
| 448 | enterUnop("--", intType, intType, isub); |
| 449 | enterUnop("--", charType, charType, isub); |
| 450 | enterUnop("--", shortType, shortType, isub); |
| 451 | enterUnop("--", byteType, byteType, isub); |
| 452 | |
| 453 | enterUnop("!", booleanType, booleanType, bool_not); |
| 454 | nullcheck = enterUnop("<*nullchk*>", objectType, objectType, nullchk); |
| 455 | |
| 456 | // string concatenation |
| 457 | enterBinop("+", stringType, objectType, stringType, string_add); |
| 458 | enterBinop("+", objectType, stringType, stringType, string_add); |
| 459 | enterBinop("+", stringType, stringType, stringType, string_add); |
| 460 | enterBinop("+", stringType, intType, stringType, string_add); |
| 461 | enterBinop("+", stringType, longType, stringType, string_add); |
| 462 | enterBinop("+", stringType, floatType, stringType, string_add); |
| 463 | enterBinop("+", stringType, doubleType, stringType, string_add); |
| 464 | enterBinop("+", stringType, booleanType, stringType, string_add); |
| 465 | enterBinop("+", stringType, botType, stringType, string_add); |
| 466 | enterBinop("+", intType, stringType, stringType, string_add); |
| 467 | enterBinop("+", longType, stringType, stringType, string_add); |
| 468 | enterBinop("+", floatType, stringType, stringType, string_add); |
| 469 | enterBinop("+", doubleType, stringType, stringType, string_add); |
| 470 | enterBinop("+", booleanType, stringType, stringType, string_add); |
| 471 | enterBinop("+", botType, stringType, stringType, string_add); |
| 472 | |
| 473 | // these errors would otherwise be matched as string concatenation |
| 474 | enterBinop("+", botType, botType, botType, error); |
| 475 | enterBinop("+", botType, intType, botType, error); |
| 476 | enterBinop("+", botType, longType, botType, error); |
| 477 | enterBinop("+", botType, floatType, botType, error); |
| 478 | enterBinop("+", botType, doubleType, botType, error); |
| 479 | enterBinop("+", botType, booleanType, botType, error); |
| 480 | enterBinop("+", botType, objectType, botType, error); |
| 481 | enterBinop("+", intType, botType, botType, error); |
| 482 | enterBinop("+", longType, botType, botType, error); |
| 483 | enterBinop("+", floatType, botType, botType, error); |
| 484 | enterBinop("+", doubleType, botType, botType, error); |
| 485 | enterBinop("+", booleanType, botType, botType, error); |
| 486 | enterBinop("+", objectType, botType, botType, error); |
| 487 | |
| 488 | enterBinop("+", doubleType, doubleType, doubleType, dadd); |
| 489 | enterBinop("+", floatType, floatType, floatType, fadd); |
| 490 | enterBinop("+", longType, longType, longType, ladd); |
| 491 | enterBinop("+", intType, intType, intType, iadd); |
| 492 | |
| 493 | enterBinop("-", doubleType, doubleType, doubleType, dsub); |
| 494 | enterBinop("-", floatType, floatType, floatType, fsub); |
| 495 | enterBinop("-", longType, longType, longType, lsub); |
| 496 | enterBinop("-", intType, intType, intType, isub); |
| 497 | |
| 498 | enterBinop("*", doubleType, doubleType, doubleType, dmul); |
| 499 | enterBinop("*", floatType, floatType, floatType, fmul); |
| 500 | enterBinop("*", longType, longType, longType, lmul); |
| 501 | enterBinop("*", intType, intType, intType, imul); |
| 502 | |
| 503 | enterBinop("/", doubleType, doubleType, doubleType, ddiv); |
| 504 | enterBinop("/", floatType, floatType, floatType, fdiv); |
| 505 | enterBinop("/", longType, longType, longType, ldiv); |
| 506 | enterBinop("/", intType, intType, intType, idiv); |
| 507 | |
| 508 | enterBinop("%", doubleType, doubleType, doubleType, dmod); |
| 509 | enterBinop("%", floatType, floatType, floatType, fmod); |
| 510 | enterBinop("%", longType, longType, longType, lmod); |
| 511 | enterBinop("%", intType, intType, intType, imod); |
| 512 | |
| 513 | enterBinop("&", booleanType, booleanType, booleanType, iand); |
| 514 | enterBinop("&", longType, longType, longType, land); |
| 515 | enterBinop("&", intType, intType, intType, iand); |
| 516 | |
| 517 | enterBinop("|", booleanType, booleanType, booleanType, ior); |
| 518 | enterBinop("|", longType, longType, longType, lor); |
| 519 | enterBinop("|", intType, intType, intType, ior); |
| 520 | |
| 521 | enterBinop("^", booleanType, booleanType, booleanType, ixor); |
| 522 | enterBinop("^", longType, longType, longType, lxor); |
| 523 | enterBinop("^", intType, intType, intType, ixor); |
| 524 | |
| 525 | enterBinop("<<", longType, longType, longType, lshll); |
| 526 | enterBinop("<<", intType, longType, intType, ishll); |
| 527 | enterBinop("<<", longType, intType, longType, lshl); |
| 528 | enterBinop("<<", intType, intType, intType, ishl); |
| 529 | |
| 530 | enterBinop(">>", longType, longType, longType, lshrl); |
| 531 | enterBinop(">>", intType, longType, intType, ishrl); |
| 532 | enterBinop(">>", longType, intType, longType, lshr); |
| 533 | enterBinop(">>", intType, intType, intType, ishr); |
| 534 | |
| 535 | enterBinop(">>>", longType, longType, longType, lushrl); |
| 536 | enterBinop(">>>", intType, longType, intType, iushrl); |
| 537 | enterBinop(">>>", longType, intType, longType, lushr); |
| 538 | enterBinop(">>>", intType, intType, intType, iushr); |
| 539 | |
| 540 | enterBinop("<", doubleType, doubleType, booleanType, dcmpg, iflt); |
| 541 | enterBinop("<", floatType, floatType, booleanType, fcmpg, iflt); |
| 542 | enterBinop("<", longType, longType, booleanType, lcmp, iflt); |
| 543 | enterBinop("<", intType, intType, booleanType, if_icmplt); |
| 544 | |
| 545 | enterBinop(">", doubleType, doubleType, booleanType, dcmpl, ifgt); |
| 546 | enterBinop(">", floatType, floatType, booleanType, fcmpl, ifgt); |
| 547 | enterBinop(">", longType, longType, booleanType, lcmp, ifgt); |
| 548 | enterBinop(">", intType, intType, booleanType, if_icmpgt); |
| 549 | |
| 550 | enterBinop("<=", doubleType, doubleType, booleanType, dcmpg, ifle); |
| 551 | enterBinop("<=", floatType, floatType, booleanType, fcmpg, ifle); |
| 552 | enterBinop("<=", longType, longType, booleanType, lcmp, ifle); |
| 553 | enterBinop("<=", intType, intType, booleanType, if_icmple); |
| 554 | |
| 555 | enterBinop(">=", doubleType, doubleType, booleanType, dcmpl, ifge); |
| 556 | enterBinop(">=", floatType, floatType, booleanType, fcmpl, ifge); |
| 557 | enterBinop(">=", longType, longType, booleanType, lcmp, ifge); |
| 558 | enterBinop(">=", intType, intType, booleanType, if_icmpge); |
| 559 | |
| 560 | enterBinop("==", objectType, objectType, booleanType, if_acmpeq); |
| 561 | enterBinop("==", booleanType, booleanType, booleanType, if_icmpeq); |
| 562 | enterBinop("==", doubleType, doubleType, booleanType, dcmpl, ifeq); |
| 563 | enterBinop("==", floatType, floatType, booleanType, fcmpl, ifeq); |
| 564 | enterBinop("==", longType, longType, booleanType, lcmp, ifeq); |
| 565 | enterBinop("==", intType, intType, booleanType, if_icmpeq); |
| 566 | |
| 567 | enterBinop("!=", objectType, objectType, booleanType, if_acmpne); |
| 568 | enterBinop("!=", booleanType, booleanType, booleanType, if_icmpne); |
| 569 | enterBinop("!=", doubleType, doubleType, booleanType, dcmpl, ifne); |
| 570 | enterBinop("!=", floatType, floatType, booleanType, fcmpl, ifne); |
| 571 | enterBinop("!=", longType, longType, booleanType, lcmp, ifne); |
| 572 | enterBinop("!=", intType, intType, booleanType, if_icmpne); |
| 573 | |
| 574 | enterBinop("&&", booleanType, booleanType, booleanType, bool_and); |
| 575 | enterBinop("||", booleanType, booleanType, booleanType, bool_or); |
| 576 | } |
| 577 | } |