blob: 00f48e8e4d0a4268dcd9eb535dd0a0de358f823b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1994-2003 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
26package sun.tools.tree;
27
28import sun.tools.java.*;
29import sun.tools.asm.Label;
30import sun.tools.asm.Assembler;
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 BinaryExpression extends UnaryExpression {
41 Expression left;
42
43 /**
44 * Constructor
45 */
46 BinaryExpression(int op, long where, Type type, Expression left, Expression right) {
47 super(op, where, type, right);
48 this.left = left;
49 }
50
51 /**
52 * Order the expression based on precedence
53 */
54 public Expression order() {
55 if (precedence() > left.precedence()) {
56 UnaryExpression e = (UnaryExpression)left;
57 left = e.right;
58 e.right = order();
59 return e;
60 }
61 return this;
62 }
63
64 /**
65 * Check a binary expression
66 */
67 public Vset checkValue(Environment env, Context ctx, Vset vset, Hashtable exp) {
68 vset = left.checkValue(env, ctx, vset, exp);
69 vset = right.checkValue(env, ctx, vset, exp);
70
71 int tm = left.type.getTypeMask() | right.type.getTypeMask();
72 if ((tm & TM_ERROR) != 0) {
73 return vset;
74 }
75 selectType(env, ctx, tm);
76
77 if (type.isType(TC_ERROR)) {
78 env.error(where, "invalid.args", opNames[op]);
79 }
80 return vset;
81 }
82
83 /**
84 * Check if constant
85 */
86 public boolean isConstant() {
87 switch (op) {
88 case MUL:
89 case DIV:
90 case REM:
91 case ADD:
92 case SUB:
93 case LSHIFT:
94 case RSHIFT:
95 case URSHIFT:
96 case LT:
97 case LE:
98 case GT:
99 case GE:
100 case EQ:
101 case NE:
102 case BITAND:
103 case BITXOR:
104 case BITOR:
105 case AND:
106 case OR:
107 return left.isConstant() && right.isConstant();
108 }
109 return false;
110 }
111 /**
112 * Evaluate
113 */
114 Expression eval(int a, int b) {
115 return this;
116 }
117 Expression eval(long a, long b) {
118 return this;
119 }
120 Expression eval(float a, float b) {
121 return this;
122 }
123 Expression eval(double a, double b) {
124 return this;
125 }
126 Expression eval(boolean a, boolean b) {
127 return this;
128 }
129 Expression eval(String a, String b) {
130 return this;
131 }
132 Expression eval() {
133 // See also the eval() code in BinaryShiftExpression.java.
134 if (left.op == right.op) {
135 switch (left.op) {
136 case BYTEVAL:
137 case CHARVAL:
138 case SHORTVAL:
139 case INTVAL:
140 return eval(((IntegerExpression)left).value, ((IntegerExpression)right).value);
141 case LONGVAL:
142 return eval(((LongExpression)left).value, ((LongExpression)right).value);
143 case FLOATVAL:
144 return eval(((FloatExpression)left).value, ((FloatExpression)right).value);
145 case DOUBLEVAL:
146 return eval(((DoubleExpression)left).value, ((DoubleExpression)right).value);
147 case BOOLEANVAL:
148 return eval(((BooleanExpression)left).value, ((BooleanExpression)right).value);
149 case STRINGVAL:
150 return eval(((StringExpression)left).value, ((StringExpression)right).value);
151 }
152 }
153 return this;
154 }
155
156 /**
157 * Inline
158 */
159 public Expression inline(Environment env, Context ctx) {
160 left = left.inline(env, ctx);
161 right = right.inline(env, ctx);
162 return (left == null) ? right : new CommaExpression(where, left, right);
163 }
164 public Expression inlineValue(Environment env, Context ctx) {
165 left = left.inlineValue(env, ctx);
166 right = right.inlineValue(env, ctx);
167 try {
168 return eval().simplify();
169 } catch (ArithmeticException e) {
170 // Got rid of this error message. It isn't illegal to
171 // have a program which does a constant division by
172 // zero. We return `this' to make the compiler to
173 // generate code here.
174 // (bugs 4019304, 4089107).
175 //
176 // env.error(where, "arithmetic.exception");
177 return this;
178 }
179 }
180
181 /**
182 * Create a copy of the expression for method inlining
183 */
184 public Expression copyInline(Context ctx) {
185 BinaryExpression e = (BinaryExpression)clone();
186 if (left != null) {
187 e.left = left.copyInline(ctx);
188 }
189 if (right != null) {
190 e.right = right.copyInline(ctx);
191 }
192 return e;
193 }
194
195 /**
196 * The cost of inlining this expression
197 */
198 public int costInline(int thresh, Environment env, Context ctx) {
199 return 1 + ((left != null) ? left.costInline(thresh, env, ctx) : 0) +
200 ((right != null) ? right.costInline(thresh, env, ctx) : 0);
201 }
202
203 /**
204 * Code
205 */
206 void codeOperation(Environment env, Context ctx, Assembler asm) {
207 throw new CompilerError("codeOperation: " + opNames[op]);
208 }
209 public void codeValue(Environment env, Context ctx, Assembler asm) {
210 if (type.isType(TC_BOOLEAN)) {
211 Label l1 = new Label();
212 Label l2 = new Label();
213
214 codeBranch(env, ctx, asm, l1, true);
215 asm.add(true, where, opc_ldc, new Integer(0));
216 asm.add(true, where, opc_goto, l2);
217 asm.add(l1);
218 asm.add(true, where, opc_ldc, new Integer(1));
219 asm.add(l2);
220 } else {
221 left.codeValue(env, ctx, asm);
222 right.codeValue(env, ctx, asm);
223 codeOperation(env, ctx, asm);
224 }
225 }
226
227 /**
228 * Print
229 */
230 public void print(PrintStream out) {
231 out.print("(" + opNames[op] + " ");
232 if (left != null) {
233 left.print(out);
234 } else {
235 out.print("<null>");
236 }
237 out.print(" ");
238 if (right != null) {
239 right.print(out);
240 } else {
241 out.print("<null>");
242 }
243 out.print(")");
244 }
245}