001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.dev.jjs.test;
017:
018: import com.google.gwt.junit.client.GWTTestCase;
019:
020: /**
021: * Tests method invocations including potential inlining bugs.
022: */
023: public class MethodCallTest extends GWTTestCase {
024:
025: private static final class MyException extends RuntimeException {
026: }
027:
028: private static int manyArgs(int i0, int i1, int i2, int i3, int i4,
029: int i5, int i6, int i7, int i8, int i9, int i10, int i11,
030: int i12, int i13, int i14, int i15, int i16, int i17,
031: int i18, int i19, int i20, int i21, int i22, int i23,
032: int i24, int i25, int i26, int i27, int i28, int i29,
033: int i30, int i31, int i32, int i33, int i34, int i35,
034: int i36, int i37, int i38, int i39, int i40, int i41,
035: int i42, int i43, int i44, int i45, int i46, int i47,
036: int i48, int i49, int i50, int i51, int i52, int i53,
037: int i54, int i55, int i56, int i57, int i58, int i59,
038: int i60, int i61, int i62, int i63, int i64, int i65,
039: int i66, int i67, int i68, int i69, int i70, int i71,
040: int i72, int i73, int i74, int i75, int i76, int i77,
041: int i78, int i79, int i80, int i81, int i82, int i83,
042: int i84, int i85, int i86, int i87, int i88, int i89,
043: int i90, int i91, int i92, int i93, int i94, int i95,
044: int i96, int i97, int i98, int i99, int i100, int i101,
045: int i102, int i103, int i104, int i105, int i106, int i107,
046: int i108, int i109, int i110, int i111, int i112, int i113,
047: int i114, int i115, int i116, int i117, int i118, int i119,
048: int i120, int i121, int i122, int i123, int i124, int i125,
049: int i126, int i127, int i128, int i129, int i130, int i131,
050: int i132, int i133, int i134, int i135, int i136, int i137,
051: int i138, int i139, int i140, int i141, int i142, int i143,
052: int i144, int i145, int i146, int i147, int i148, int i149,
053: int i150, int i151, int i152, int i153, int i154, int i155,
054: int i156, int i157, int i158, int i159, int i160, int i161,
055: int i162, int i163, int i164, int i165, int i166, int i167,
056: int i168, int i169, int i170, int i171, int i172, int i173,
057: int i174, int i175, int i176, int i177, int i178, int i179,
058: int i180, int i181, int i182, int i183, int i184, int i185,
059: int i186, int i187, int i188, int i189, int i190, int i191,
060: int i192, int i193, int i194, int i195, int i196, int i197,
061: int i198, int i199, int i200, int i201, int i202, int i203,
062: int i204, int i205, int i206, int i207, int i208, int i209,
063: int i210, int i211, int i212, int i213, int i214, int i215,
064: int i216, int i217, int i218, int i219, int i220, int i221,
065: int i222, int i223, int i224, int i225, int i226, int i227,
066: int i228, int i229, int i230, int i231, int i232, int i233,
067: int i234, int i235, int i236, int i237, int i238, int i239,
068: int i240, int i241, int i242, int i243, int i244, int i245,
069: int i246, int i247, int i248, int i249, int i250, int i251,
070: int i252, int i253, int i254) {
071: return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10
072: + i11 + i12 + i13 + i14 + i15 + i16 + i17 + i18 + i19
073: + i20 + i21 + i22 + i23 + i24 + i25 + i26 + i27 + i28
074: + i29 + i30 + i31 + i32 + i33 + i34 + i35 + i36 + i37
075: + i38 + i39 + i40 + i41 + i42 + i43 + i44 + i45 + i46
076: + i47 + i48 + i49 + i50 + i51 + i52 + i53 + i54 + i55
077: + i56 + i57 + i58 + i59 + i60 + i61 + i62 + i63 + i64
078: + i65 + i66 + i67 + i68 + i69 + i70 + i71 + i72 + i73
079: + i74 + i75 + i76 + i77 + i78 + i79 + i80 + i81 + i82
080: + i83 + i84 + i85 + i86 + i87 + i88 + i89 + i90 + i91
081: + i92 + i93 + i94 + i95 + i96 + i97 + i98 + i99 + i100
082: + i101 + i102 + i103 + i104 + i105 + i106 + i107 + i108
083: + i109 + i110 + i111 + i112 + i113 + i114 + i115 + i116
084: + i117 + i118 + i119 + i120 + i121 + i122 + i123 + i124
085: + i125 + i126 + i127 + i128 + i129 + i130 + i131 + i132
086: + i133 + i134 + i135 + i136 + i137 + i138 + i139 + i140
087: + i141 + i142 + i143 + i144 + i145 + i146 + i147 + i148
088: + i149 + i150 + i151 + i152 + i153 + i154 + i155 + i156
089: + i157 + i158 + i159 + i160 + i161 + i162 + i163 + i164
090: + i165 + i166 + i167 + i168 + i169 + i170 + i171 + i172
091: + i173 + i174 + i175 + i176 + i177 + i178 + i179 + i180
092: + i181 + i182 + i183 + i184 + i185 + i186 + i187 + i188
093: + i189 + i190 + i191 + i192 + i193 + i194 + i195 + i196
094: + i197 + i198 + i199 + i200 + i201 + i202 + i203 + i204
095: + i205 + i206 + i207 + i208 + i209 + i210 + i211 + i212
096: + i213 + i214 + i215 + i216 + i217 + i218 + i219 + i220
097: + i221 + i222 + i223 + i224 + i225 + i226 + i227 + i228
098: + i229 + i230 + i231 + i232 + i233 + i234 + i235 + i236
099: + i237 + i238 + i239 + i240 + i241 + i242 + i243 + i244
100: + i245 + i246 + i247 + i248 + i249 + i250 + i251 + i252
101: + i253 + i254;
102: }
103:
104: private int value;
105:
106: public String getModuleName() {
107: return "com.google.gwt.dev.jjs.CompilerSuite";
108: }
109:
110: /**
111: * Ensure that call-site side-effects happen before expressions in the callee
112: * are evaluated.
113: */
114: public void testArgumentEffectPreceedsCalleeEffect() {
115: value = 10;
116: int result = doubleValueAndAdd(value += 2);
117: assertEquals(24, value);
118: assertEquals(36, result);
119: }
120:
121: /**
122: * Ensure that call-site side-effects happen before expressions in the callee
123: * are evaluated.
124: */
125: public void testArgumentEffectPreceedsCalleeValue() {
126: value = 0;
127: int result = addToValue(value = 10);
128: assertEquals(10, value);
129: assertEquals(20, result);
130: }
131:
132: /**
133: * Ensure that side-effects are processed in the correct order.
134: */
135: public void testArgumentsEvalInCorrectOrder() {
136: value = 10;
137: int result = checkOrder(value, ++value);
138: assertEquals(11, value);
139: assertEquals(11010, result);
140:
141: int localValue = 20;
142: result = checkOrder(localValue, ++localValue);
143: assertEquals(21, localValue);
144: assertEquals(21020, result);
145: }
146:
147: /**
148: * Ensure that call-site evaluation happens before effects in the callee
149: * occur.
150: */
151: public void testArgumentValuePreceedsCalleeEffect() {
152: value = 10;
153: int result = resetValueAndAdd(value);
154: assertEquals(0, value);
155: assertEquals(10, result);
156: }
157:
158: public void testAssignsToParam() {
159: value = 10;
160: int result = assignsToParam(value);
161: assertEquals(10, value);
162: assertEquals(11, result);
163:
164: int localValue = 20;
165: result = assignsToParam(localValue);
166: assertEquals(20, localValue);
167: assertEquals(21, result);
168: }
169:
170: public void testManyArgs() {
171: assertEquals(32385, manyArgs(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
172: 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
173: 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
174: 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
175: 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
176: 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
177: 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
178: 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
179: 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
180: 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
181: 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
182: 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
183: 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
184: 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
185: 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
186: 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
187: 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
188: 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216,
189: 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
190: 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
191: 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
192: 250, 251, 252, 253, 254));
193: }
194:
195: /**
196: * Ensure that we correctly inline a method that ignores its parameters.
197: */
198: public void testNoParameterRefs() {
199: int value = 100;
200: assertEquals(1, ignoreParams(value++, value++));
201: assertEquals(102, value);
202: }
203:
204: public void testRecursion() {
205: assertEquals(20100, recursiveSum(200));
206: }
207:
208: /**
209: * Ensure that side-effects always execute.
210: */
211: public void testSideEffectsAlwaysExecute1() {
212: value = 1;
213: assertEquals(0, conditional1(value++));
214: assertEquals(2, value);
215:
216: int localValue = 1;
217: assertEquals(0, conditional1(localValue++));
218: assertEquals(2, localValue);
219: }
220:
221: /**
222: * Ensure that side-effects always execute.
223: */
224: public void testSideEffectsAlwaysExecute2() {
225: value = 1;
226: assertEquals(false, conditional2(value++));
227: assertEquals(2, value);
228:
229: int localValue = 1;
230: assertEquals(false, conditional2(localValue++));
231: assertEquals(2, localValue);
232: }
233:
234: /**
235: * Ensure that side-effects always execute.
236: */
237: public void testSideEffectsAlwaysExecute3() {
238: value = 1;
239: assertEquals(true, conditional3(value++));
240: assertEquals(2, value);
241:
242: int localValue = 1;
243: assertEquals(true, conditional3(localValue++));
244: assertEquals(2, localValue);
245: }
246:
247: /**
248: * Ensure that call-site side-effects happen before callee side-effects.
249: */
250: public void testSideEffectsInFields() {
251: value = 10;
252: int result = add(++value, ++value);
253: assertEquals(23, result);
254: }
255:
256: /**
257: * Ensure that side-effects always happen before the exception.
258: */
259: public void testSideEffectsVersusExceptions1() {
260: int value = 10;
261: try {
262: // Use the return value so it doesn't get pruned
263: assertEquals(0,
264: addCorrectOrder(++value, throwMyException()));
265: fail();
266: } catch (MyException e) {
267: // expected
268: assertEquals(11, value);
269: }
270:
271: try {
272: // Use the return value so it doesn't get pruned
273: assertEquals(0,
274: addReverseOrder(++value, throwMyException()));
275: fail();
276: } catch (MyException e) {
277: // expected
278: assertEquals(12, value);
279: }
280: }
281:
282: /**
283: * Ensure that the exception always happens before the side-effects.
284: */
285: public void testSideEffectsVersusExceptions2() {
286: int value = 10;
287:
288: try {
289: // Use the return value so it doesn't get pruned
290: assertEquals(0,
291: addCorrectOrder(throwMyException(), ++value));
292: fail();
293: } catch (MyException e) {
294: // expected
295: assertEquals(10, value);
296: }
297:
298: // Use the return value so it doesn't get pruned
299: try {
300: assertEquals(0,
301: addReverseOrder(throwMyException(), ++value));
302: fail();
303: } catch (MyException e) {
304: // expected
305: assertEquals(10, value);
306: }
307: }
308:
309: /**
310: * Ensure that the exception always happens before the side-effects.
311: */
312: public void testSideEffectsVersusExceptions3() {
313: int value = 10;
314:
315: try {
316: // Use the return value so it doesn't get pruned
317: assertEquals(0, throwExceptionAndReturn(++value));
318: fail();
319: } catch (MyException e) {
320: // expected
321: assertEquals(11, value);
322: }
323: }
324:
325: private int add(int i, int j) {
326: return (value = 0) + i + j;
327: }
328:
329: private int addCorrectOrder(int i, int j) {
330: return i + j;
331: }
332:
333: private int addReverseOrder(int i, int j) {
334: return j + i;
335: }
336:
337: private int addToValue(int i) {
338: return value + i;
339: }
340:
341: private int assignsToParam(int x) {
342: return ++x;
343: }
344:
345: private int checkOrder(int x, int y) {
346: return y * 1000 + x;
347: }
348:
349: private int conditional1(int i) {
350: return (this .value != Integer.MAX_VALUE) ? 0 : i;
351: }
352:
353: private boolean conditional2(int i) {
354: return (this .value == Integer.MAX_VALUE) && (i == 1);
355: }
356:
357: private boolean conditional3(int i) {
358: return (this .value != Integer.MAX_VALUE) || (i == 1);
359: }
360:
361: private int doubleValueAndAdd(int i) {
362: return (value *= 2) + i;
363: }
364:
365: private int ignoreParams(int i, int j) {
366: return 1;
367: }
368:
369: private int recursiveSum(int x) {
370: if (x == 0) {
371: return 0;
372: } else {
373: return x + recursiveSum(x - 1);
374: }
375: }
376:
377: private int resetValueAndAdd(int i) {
378: return (value = 0) + i;
379: }
380:
381: private int throwExceptionAndReturn(int i) {
382: return throwMyException() + i;
383: }
384:
385: private int throwMyException() {
386: throw new MyException();
387: }
388: }
|