[JSC] AI should not propagate AbstractValue relying on constant folding phase
[WebKit-https.git] / JSTests / stress / async-await-mozilla.js
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://moz.org/MPL/2.0/. */
4
5 function shouldBe(expected, actual, msg = "") {
6     if (msg)
7         msg = " for " + msg;
8     if (actual !== expected)
9         throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
10 }
11
12 function shouldBeAsync(expected, run, msg) {
13     let actual;
14     var hadError = false;
15     run().then(function(value) { actual = value; },
16                function(error) { hadError = true; actual = error; });
17     drainMicrotasks();
18     if (hadError)
19         throw actual;
20     shouldBe(expected, actual, msg);
21 }
22
23 function shouldThrow(run, errorType, message) {
24     let actual;
25     var hadError = false;
26     try {
27         actual = run();
28     } catch (e) {
29         hadError = true;
30         actual = e;
31     }
32     if (!hadError)
33         throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
34     if (!(actual instanceof errorType))
35         throw new Error("Expeced " + run + "() to throw " + errorType.name + " , but threw '" + actual + "'");
36     if (message !== void 0 && actual.message !== message)
37         throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
38 }
39
40 function shouldThrowAsync(run, errorType, message) {
41     let actual;
42     var hadError = false;
43     run().then(function(value) { actual = value; },
44                function(error) { hadError = true; actual = error; });
45     drainMicrotasks();
46     if (!hadError)
47         throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
48     if (!(actual instanceof errorType))
49         throw new Error("Expected " + run + "() to throw " + errorType.name + ", but threw '" + actual + "'");
50     if (message !== void 0 && actual.message !== message)
51         throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
52 }
53
54 function assert(cond, msg = "") {
55     if (!cond)
56         throw new Error(msg);
57 }
58
59 function shouldThrowSyntaxError(str, message) {
60     var hadError = false;
61     try {
62         eval(str);
63     } catch (e) {
64         if (e instanceof SyntaxError) {
65             hadError = true;
66             if (typeof message === "string")
67                 assert(e.message === message, "Expected '" + message + "' but threw '" + e.message + "'");
68         }
69     }
70     assert(hadError, "Did not throw syntax error");
71 }
72
73 // semantics.js
74 (function mozSemantics() {
75
76 async function empty() {
77 }
78
79 async function simpleReturn() {
80     return 1;
81 }
82
83 async function simpleAwait() {
84     var result = await 2;
85     return result;
86 }
87
88 async function simpleAwaitAsync() {
89     var result = await simpleReturn();
90     return 2 + result;
91 }
92
93 async function returnOtherAsync() {
94     return 1 + await simpleAwaitAsync();
95 }
96
97 async function simpleThrower() {
98     throw new Error();
99 }
100
101 async function delegatedThrower() {
102     var val = await simpleThrower();
103     return val;
104 }
105
106 async function tryCatch() {
107     try {
108         await delegatedThrower();
109         return 'FAILED';
110     } catch (_) {
111         return 5;
112     }
113 }
114
115 async function tryCatchThrow() {
116     try {
117         await delegatedThrower();
118         return 'FAILED';
119     } catch (_) {
120         return delegatedThrower();
121     }
122 }
123
124 async function wellFinally() {
125     try {
126         await delegatedThrower();
127     } catch (_) {
128         return 'FAILED';
129     } finally {
130         return 6;
131     }
132 }
133
134 async function finallyMayFail() {
135     try {
136         await delegatedThrower();
137     } catch (_) {
138         return 5;
139     } finally {
140         return delegatedThrower();
141     }
142 }
143
144 async function embedded() {
145     async function inner() {
146         return 7;
147     }
148     return await inner();
149 }
150
151 // recursion, it works!
152 async function fib(n) {
153     return (n == 0 || n == 1) ? n : await fib(n - 1) + await fib(n - 2);
154 }
155
156 // mutual recursion
157 async function isOdd(n) {
158     async function isEven(n) {
159         return n === 0 || await isOdd(n - 1);
160     }
161     return n !== 0 && await isEven(n - 1);
162 }
163
164 // recursion, take three!
165 var hardcoreFib = async function fib2(n) {
166     return (n == 0 || n == 1) ? n : await fib2(n - 1) + await fib2(n - 2);
167 }
168
169 var asyncExpr = async function() {
170     return 10;
171 }
172
173 var namedAsyncExpr = async function simple() {
174     return 11;
175 }
176
177 async function executionOrder() {
178     var value = 0;
179     async function first() {
180         return (value = value === 0 ? 1 : value);
181     }
182     async function second() {
183         return (value = value === 0 ? 2 : value);
184     }
185     async function third() {
186         return (value = value === 0 ? 3 : value);
187     }
188     return await first() + await second() + await third() + 6;
189 }
190
191 async function miscellaneous() {
192     if (arguments.length === 3 &&
193         arguments.callee.name === "miscellaneous")
194         return 14;
195 }
196
197 function thrower() {
198     throw 15;
199 }
200
201 async function defaultArgs(arg = thrower()) {
202 }
203
204 // Async functions are not constructible
205 shouldThrow(() => {
206     async function Person() {
207     }
208     new Person();
209 }, TypeError);
210
211 shouldBeAsync(undefined, empty);
212 shouldBeAsync(1, simpleReturn);
213 shouldBeAsync(2, simpleAwait);
214 shouldBeAsync(3, simpleAwaitAsync);
215 shouldBeAsync(4, returnOtherAsync);
216 shouldThrowAsync(simpleThrower, Error);
217 shouldBeAsync(5, tryCatch);
218 shouldBeAsync(6, wellFinally);
219 shouldThrowAsync(finallyMayFail, Error);
220 shouldBeAsync(7, embedded);
221 shouldBeAsync(8, () => fib(6));
222 shouldBeAsync(9, executionOrder);
223 shouldBeAsync(10, asyncExpr);
224 shouldBeAsync(11, namedAsyncExpr);
225 shouldBeAsync(12, () => isOdd(12).then(v => v ? "oops" : 12));
226 shouldBeAsync(13, () => hardcoreFib(7));
227 shouldBeAsync(14, () => miscellaneous(1, 2, 3));
228 shouldBeAsync(15, () => defaultArgs().catch(e => e));
229
230 })();
231
232 // methods.js
233 (function mozMethods() {
234
235 class X {
236     constructor() {
237         this.value = 42;
238     }
239     async getValue() {
240         return this.value;
241     }
242     setValue(value) {
243         this.value = value;
244     }
245     async increment() {
246         var value = await this.getValue();
247         this.setValue(value + 1);
248         return this.getValue();
249     }
250     async getBaseClassName() {
251         return 'X';
252     }
253     static async getStaticValue() {
254         return 44;
255     }
256 }
257
258 class Y extends X {
259     async getBaseClassName() {
260         return super.getBaseClassName();
261     }
262 }
263
264 var objLiteral = {
265     async get() {
266         return 45;
267     },
268     someStuff: 5
269 };
270
271 var x = new X();
272 var y = new Y();
273
274 shouldBeAsync(42, () => x.getValue());
275 shouldBeAsync(43, () => x.increment());
276 shouldBeAsync(44, () => X.getStaticValue());
277 shouldBeAsync(45, () => objLiteral.get());
278 shouldBeAsync('X', () => y.getBaseClassName());
279
280 })();
281
282 (function mozFunctionNameInferrence() {
283
284 async function test() { }
285
286 var anon = async function() { }
287
288 shouldBe("test", test.name);
289 shouldBe("anon", anon.name);
290
291 })();
292
293 (function mozSyntaxErrors() {
294
295 shouldThrowSyntaxError("'use strict'; async function eval() {}");
296 shouldThrowSyntaxError("'use strict'; async function arguments() {}");
297 shouldThrowSyntaxError("async function a(k = super.prop) { }");
298 shouldThrowSyntaxError("async function a() { super.prop(); }");
299 shouldThrowSyntaxError("async function a() { super(); }");
300 shouldThrowSyntaxError("async function a(k = await 3) {}");
301
302 })();