History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tools/tree/AddExpression.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tools/tree/AddExpression.java+253−0
@@ -0,0 +1,253 @@
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;
30
31/**
32 * WARNING: The contents of this source file are not part of any
33 * supported API. Code that depends on them does so at its own risk:
34 * they are subject to change or removal without notice.
35 */
36public
37class AddExpression extends BinaryArithmeticExpression {
38 /**
39 * constructor
40 */
41 public AddExpression(long where, Expression left, Expression right) {
42 super(ADD, where, left, right);
43 }
44
45 /**
46 * Select the type
47 */
48 void selectType(Environment env, Context ctx, int tm) {
49 if ((left.type == Type.tString) && !right.type.isType(TC_VOID)) {
50 type = Type.tString;
51 return;
52 } else if ((right.type == Type.tString) && !left.type.isType(TC_VOID)) {
53 type = Type.tString;
54 return;
55 }
56 super.selectType(env, ctx, tm);
57 }
58
59 public boolean isNonNull() {
60 // an addition expression cannot yield a null reference as a result
61 return true;
62 }
63
64 /**
65 * Evaluate
66 */
67 Expression eval(int a, int b) {
68 return new IntExpression(where, a + b);
69 }
70 Expression eval(long a, long b) {
71 return new LongExpression(where, a + b);
72 }
73 Expression eval(float a, float b) {
74 return new FloatExpression(where, a + b);
75 }
76 Expression eval(double a, double b) {
77 return new DoubleExpression(where, a + b);
78 }
79 Expression eval(String a, String b) {
80 return new StringExpression(where, a + b);
81 }
82
83 /**
84 * Inline the value of an AddExpression. If this AddExpression
85 * represents a concatenation of compile-time constant strings,
86 * dispatch to the special method inlineValueSB, which handles
87 * the inlining more efficiently.
88 */
89 public Expression inlineValue(Environment env, Context ctx) {
90 if (type == Type.tString && isConstant()) {
91 StringBuffer buffer = inlineValueSB(env, ctx, new StringBuffer());
92 if (buffer != null) {
93 // We were able to evaluate the String concatenation.
94 return new StringExpression(where, buffer.toString());
95 }
96 }
97 // For some reason inlinValueSB() failed to produce a value.
98 // Use the older, less efficient, inlining mechanism.
99 return super.inlineValue(env, ctx);
100 }
101
102 /**
103 * Attempt to evaluate this expression. If this expression
104 * yields a value, append it to the StringBuffer `buffer'.
105 * If this expression cannot be evaluated at this time (for
106 * example if it contains a division by zero, a non-constant
107 * subexpression, or a subexpression which "refuses" to evaluate)
108 * then return `null' to indicate failure.
109 *
110 * It is anticipated that this method will be called to evaluate
111 * concatenations of compile-time constant strings. The call
112 * originates from AddExpression#inlineValue().
113 *
114 * This method does not use associativity to good effect in
115 * folding string concatenations. This is room for improvement.
116 *
117 * -------------
118 *
119 * A bit of history: this method was added because an
120 * expression like...
121 *
122 * "a" + "b" + "c" + "d"
123 *
124 * ...was evaluated at compile-time as...
125 *
126 * (new StringBuffer((new StringBuffer("a")).append("b").toString())).
127 * append((new StringBuffer("c")).append("d").toString()).toString()
128 *
129 * Alex Garthwaite, in profiling the memory allocation of the
130 * compiler, noticed this and suggested that the method inlineValueSB()
131 * be added to evaluate constant string concatenations in a more
132 * efficient manner. The compiler now builds the string in a
133 * top-down fashion, by accumulating the result in a StringBuffer
134 * which is allocated once and passed in as a parameter. The new
135 * evaluation scheme is equivalent to...
136 *
137 * (new StringBuffer("a")).append("b").append("c").append("d")
138 * .toString()
139 *
140 * ...which is more efficient. Since then, the code has been modified
141 * to fix certain problems. Now, for example, it can return `null'
142 * when it encounters a concatenation which it is not able to
143 * evaluate.
144 *
145 * See also Expression#inlineValueSB() and ExprExpression#inlineValueSB().
146 */
147 protected StringBuffer inlineValueSB(Environment env,
148 Context ctx,
149 StringBuffer buffer) {
150 if (type != Type.tString) {
151 // This isn't a concatenation. It is actually an addition
152 // of some sort. Call the generic inlineValueSB()
153 return super.inlineValueSB(env, ctx, buffer);
154 }
155
156 buffer = left.inlineValueSB(env, ctx, buffer);
157 if (buffer != null) {
158 buffer = right.inlineValueSB(env, ctx, buffer);
159 }
160 return buffer;
161 }
162
163 /**
164 * Simplify
165 */
166 Expression simplify() {
167 if (!type.isType(TC_CLASS)) {
168 // Can't simplify floating point add because of -0.0 strangeness
169 if (type.inMask(TM_INTEGER)) {
170 if (left.equals(0)) {
171 return right;
172 }
173 if (right.equals(0)) {
174 return left;
175 }
176 }
177 } else if (right.type.isType(TC_NULL)) {
178 right = new StringExpression(right.where, "null");
179 } else if (left.type.isType(TC_NULL)) {
180 left = new StringExpression(left.where, "null");
181 }
182 return this;
183 }
184
185 /**
186 * The cost of inlining this expression
187 */
188 public int costInline(int thresh, Environment env, Context ctx) {
189 return (type.isType(TC_CLASS) ? 12 : 1)
190 + left.costInline(thresh, env, ctx)
191 + right.costInline(thresh, env, ctx);
192 }
193
194 /**
195 * Code
196 */
197 void codeOperation(Environment env, Context ctx, Assembler asm) {
198 asm.add(where, opc_iadd + type.getTypeCodeOffset());
199 }
200
201 /**
202 * Convert this expression to a string and append it to the string
203 * buffer on the top of the stack.
204 * If the needBuffer argument is true, the string buffer needs to be
205 * created, initialized, and pushed on the stack, first.
206 */
207 void codeAppend(Environment env, Context ctx, Assembler asm,
208 ClassDeclaration sbClass, boolean needBuffer)
209 throws ClassNotFound, AmbiguousMember {
210 if (type.isType(TC_CLASS)) {
211 left.codeAppend(env, ctx, asm, sbClass, needBuffer);
212 right.codeAppend(env, ctx, asm, sbClass, false);
213 } else {
214 super.codeAppend(env, ctx, asm, sbClass, needBuffer);
215 }
216 }
217
218 public void codeValue(Environment env, Context ctx, Assembler asm) {
219 if (type.isType(TC_CLASS)) {
220 try {
221 // optimize (""+foo) or (foo+"") to String.valueOf(foo)
222 if (left.equals("")) {
223 right.codeValue(env, ctx, asm);
224 right.ensureString(env, ctx, asm);
225 return;
226 }
227 if (right.equals("")) {
228 left.codeValue(env, ctx, asm);
229 left.ensureString(env, ctx, asm);
230 return;
231 }
232
233 ClassDeclaration sbClass =
234 env.getClassDeclaration(idJavaLangStringBuffer);
235 ClassDefinition sourceClass = ctx.field.getClassDefinition();
236 // Create the string buffer and append to it.
237 codeAppend(env, ctx, asm, sbClass, true);
238 // Convert the string buffer to a string
239 MemberDefinition f =
240 sbClass.getClassDefinition(env).matchMethod(env,
241 sourceClass,
242 idToString);
243 asm.add(where, opc_invokevirtual, f);
244 } catch (ClassNotFound e) {
245 throw new CompilerError(e);
246 } catch (AmbiguousMember e) {
247 throw new CompilerError(e);
248 }
249 } else {
250 super.codeValue(env, ctx, asm);
251 }
252 }
253}