001: /*
002: * Copyright 1994-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.tree;
027:
028: import sun.tools.java.*;
029: import sun.tools.asm.Assembler;
030: import sun.tools.asm.Label;
031: import java.io.PrintStream;
032: import java.util.Hashtable;
033:
034: /**
035: * WARNING: The contents of this source file are not part of any
036: * supported API. Code that depends on them does so at its own risk:
037: * they are subject to change or removal without notice.
038: */
039: public class InstanceOfExpression extends BinaryExpression {
040: /**
041: * constructor
042: */
043: public InstanceOfExpression(long where, Expression left,
044: Expression right) {
045: super (INSTANCEOF, where, Type.tBoolean, left, right);
046: }
047:
048: /**
049: * Check the expression
050: */
051: public Vset checkValue(Environment env, Context ctx, Vset vset,
052: Hashtable exp) {
053: vset = left.checkValue(env, ctx, vset, exp);
054: right = new TypeExpression(right.where, right.toType(env, ctx));
055:
056: if (right.type.isType(TC_ERROR) || left.type.isType(TC_ERROR)) {
057: // An error was already reported
058: return vset;
059: }
060:
061: if (!right.type.inMask(TM_CLASS | TM_ARRAY)) {
062: env.error(right.where, "invalid.arg.type", right.type,
063: opNames[op]);
064: return vset;
065: }
066: try {
067: if (!env.explicitCast(left.type, right.type)) {
068: env.error(where, "invalid.instanceof", left.type,
069: right.type);
070: }
071: } catch (ClassNotFound e) {
072: env.error(where, "class.not.found", e.name, opNames[op]);
073: }
074: return vset;
075: }
076:
077: /**
078: * Inline
079: */
080: public Expression inline(Environment env, Context ctx) {
081: return left.inline(env, ctx);
082: }
083:
084: public Expression inlineValue(Environment env, Context ctx) {
085: left = left.inlineValue(env, ctx);
086: return this ;
087: }
088:
089: public int costInline(int thresh, Environment env, Context ctx) {
090: if (ctx == null) {
091: return 1 + left.costInline(thresh, env, ctx);
092: }
093: // sourceClass is the current class trying to inline this method
094: ClassDefinition sourceClass = ctx.field.getClassDefinition();
095: try {
096: // We only allow the inlining if the current class can access
097: // the "instance of" class
098: if (right.type.isType(TC_ARRAY)
099: || sourceClass.permitInlinedAccess(env, env
100: .getClassDeclaration(right.type)))
101: return 1 + left.costInline(thresh, env, ctx);
102: } catch (ClassNotFound e) {
103: }
104: return thresh;
105: }
106:
107: /**
108: * Code
109: */
110: public void codeValue(Environment env, Context ctx, Assembler asm) {
111: left.codeValue(env, ctx, asm);
112: if (right.type.isType(TC_CLASS)) {
113: asm.add(where, opc_instanceof , env
114: .getClassDeclaration(right.type));
115: } else {
116: asm.add(where, opc_instanceof , right.type);
117: }
118: }
119:
120: void codeBranch(Environment env, Context ctx, Assembler asm,
121: Label lbl, boolean whenTrue) {
122: codeValue(env, ctx, asm);
123: asm.add(where, whenTrue ? opc_ifne : opc_ifeq, lbl, whenTrue);
124: }
125:
126: public void code(Environment env, Context ctx, Assembler asm) {
127: left.code(env, ctx, asm);
128: }
129:
130: /**
131: * Print
132: */
133: public void print(PrintStream out) {
134: out.print("(" + opNames[op] + " ");
135: left.print(out);
136: out.print(" ");
137: if (right.op == TYPE) {
138: out.print(right.type.toString());
139: } else {
140: right.print(out);
141: }
142: out.print(")");
143: }
144: }
|