1/* 2 * Copyright (c) 1994, 2003, 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 26package sun.tools.tree; 27 28import sun.tools.java.*; 29import sun.tools.asm.Assembler; 30import sun.tools.asm.Label; 31import java.io.PrintStream; 32import java.util.Hashtable; 33 34/** 35 * WARNING: The contents of this source file are not part of any 36 * supported API. Code that depends on them does so at its own risk: 37 * they are subject to change or removal without notice. 38 */ 39public 40class InstanceOfExpression extends BinaryExpression { 41 /** 42 * constructor 43 */ 44 public InstanceOfExpression(long where, Expression left, Expression right) { 45 super(INSTANCEOF, where, Type.tBoolean, left, right); 46 } 47 48 /** 49 * Check the expression 50 */ 51 public Vset checkValue(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp) { 52 vset = left.checkValue(env, ctx, vset, exp); 53 right = new TypeExpression(right.where, right.toType(env, ctx)); 54 55 if (right.type.isType(TC_ERROR) || left.type.isType(TC_ERROR)) { 56 // An error was already reported 57 return vset; 58 } 59 60 if (!right.type.inMask(TM_CLASS|TM_ARRAY)) { 61 env.error(right.where, "invalid.arg.type", right.type, opNames[op]); 62 return vset; 63 } 64 try { 65 if (!env.explicitCast(left.type, right.type)) { 66 env.error(where, "invalid.instanceof", left.type, right.type); 67 } 68 } catch (ClassNotFound e) { 69 env.error(where, "class.not.found", e.name, opNames[op]); 70 } 71 return vset; 72 } 73 74 /** 75 * Inline 76 */ 77 public Expression inline(Environment env, Context ctx) { 78 return left.inline(env, ctx); 79 } 80 public Expression inlineValue(Environment env, Context ctx) { 81 left = left.inlineValue(env, ctx); 82 return this; 83 } 84 85 public int costInline(int thresh, Environment env, Context ctx) { 86 if (ctx == null) { 87 return 1 + left.costInline(thresh, env, ctx); 88 } 89 // sourceClass is the current class trying to inline this method 90 ClassDefinition sourceClass = ctx.field.getClassDefinition(); 91 try { 92 // We only allow the inlining if the current class can access 93 // the "instance of" class 94 if (right.type.isType(TC_ARRAY) || 95 sourceClass.permitInlinedAccess(env, env.getClassDeclaration(right.type))) 96 return 1 + left.costInline(thresh, env, ctx); 97 } catch (ClassNotFound e) { 98 } 99 return thresh; 100 } 101 102 103 104 105 /** 106 * Code 107 */ 108 public void codeValue(Environment env, Context ctx, Assembler asm) { 109 left.codeValue(env, ctx, asm); 110 if (right.type.isType(TC_CLASS)) { 111 asm.add(where, opc_instanceof, env.getClassDeclaration(right.type)); 112 } else { 113 asm.add(where, opc_instanceof, right.type); 114 } 115 } 116 void codeBranch(Environment env, Context ctx, Assembler asm, Label lbl, boolean whenTrue) { 117 codeValue(env, ctx, asm); 118 asm.add(where, whenTrue ? opc_ifne : opc_ifeq, lbl, whenTrue); 119 } 120 public void code(Environment env, Context ctx, Assembler asm) { 121 left.code(env, ctx, asm); 122 } 123 124 /** 125 * Print 126 */ 127 public void print(PrintStream out) { 128 out.print("(" + opNames[op] + " "); 129 left.print(out); 130 out.print(" "); 131 if (right.op == TYPE) { 132 out.print(right.type.toString()); 133 } else { 134 right.print(out); 135 } 136 out.print(")"); 137 } 138} 139