Update JSC's standalone-pre.js for r187575
[WebKit-https.git] / LayoutTests / resources / standalone-pre.js
1 var wasPostTestScriptParsed = false;
2 var errorMessage;
3 var self = this;
4
5 self.testRunner = {
6     neverInlineFunction: neverInlineFunction,
7     numberOfDFGCompiles: numberOfDFGCompiles
8 };
9
10 var silentTestPass, didPassSomeTestsSilently, didFailSomeTests, successfullyParsed;
11 silentTestPass = false;
12 didPassSomeTestsSilenty = false;
13 didFaileSomeTests = false;
14
15 function description(msg)
16 {
17     print(msg);
18     print("\nOn success, you will see a series of \"PASS\" messages, followed by \"TEST COMPLETE\".\n");
19     print();
20 }
21
22 function debug(msg)
23 {
24     print(msg);
25 }
26
27 function escapeString(text)
28 {
29     return text.replace(/\0/g, "");
30 }
31
32 function testPassed(msg)
33 {
34     if (silentTestPass)
35         didPassSomeTestsSilently = true;
36     else
37         print("PASS", escapeString(msg));
38 }
39
40 function testFailed(msg)
41 {
42     didFailSomeTests = true;
43     print("FAIL", escapeString(msg));
44 }
45
46 function areNumbersEqual(_actual, _expected)
47 {
48     if (_expected === 0)
49         return _actual === _expected && (1/_actual) === (1/_expected);
50     if (_actual === _expected)
51         return true;
52     if (typeof(_expected) == "number" && isNaN(_expected))
53         return typeof(_actual) == "number" && isNaN(_actual);
54     return false;
55 }
56
57 function areArraysEqual(_a, _b)
58 {
59     try {
60         if (_a.length !== _b.length)
61             return false;
62         for (var i = 0; i < _a.length; i++)
63             if (!areNumbersEqual(_a[i], _b[i]))
64                 return false;
65     } catch (ex) {
66         return false;
67     }
68     return true;
69 }
70
71 function isMinusZero(n)
72 {
73     // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
74     // -Infinity instead of Infinity
75     return n === 0 && 1/n < 0;
76 }
77
78 function isTypedArray(array)
79 {
80     return array instanceof Int8Array
81         || array instanceof Int16Array
82         || array instanceof Int32Array
83         || array instanceof Uint8Array
84         || array instanceof Uint8ClampedArray
85         || array instanceof Uint16Array
86         || array instanceof Uint32Array
87         || array instanceof Float32Array
88         || array instanceof Float64Array;
89 }
90
91 function isResultCorrect(_actual, _expected)
92 {
93     if (areNumbersEqual(_actual, _expected))
94         return true;
95     if (_expected
96         && (Object.prototype.toString.call(_expected) ==
97             Object.prototype.toString.call([])
98             || isTypedArray(_expected)))
99         return areArraysEqual(_actual, _expected);
100     return false;
101 }
102
103 function stringify(v)
104 {
105     if (v === 0 && 1/v < 0)
106         return "-0";
107     else if (isTypedArray(v))
108         return v.__proto__.constructor.name + ":[" + Array.prototype.join.call(v, ",") + "]";
109     else
110         return "" + v;
111 }
112
113 function shouldBe(_a, _b)
114 {
115   if (typeof _a != "string" || typeof _b != "string")
116     debug("WARN: shouldBe() expects string arguments");
117   var exception;
118   var _av;
119   try {
120      _av = eval(_a);
121   } catch (e) {
122      exception = e;
123   }
124   var _bv = eval(_b);
125
126   if (exception)
127     testFailed(_a + " should be " + stringify(_bv) + ". Threw exception " + exception);
128   else if (isResultCorrect(_av, _bv))
129     testPassed(_a + " is " + _b);
130   else if (typeof(_av) == typeof(_bv))
131     testFailed(_a + " should be " + stringify(_bv) + ". Was " + stringify(_av) + ".");
132   else
133     testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
134 }
135
136 function dfgShouldBe(theFunction, _a, _b)
137 {
138   if (typeof theFunction != "function" || typeof _a != "string" || typeof _b != "string")
139     debug("WARN: dfgShouldBe() expects a function and two strings");
140   noInline(theFunction);
141   var exception;
142   var values = [];
143
144   // Defend against tests that muck with numeric properties on array.prototype.
145   values.__proto__ = null;
146   values.push = Array.prototype.push;
147   
148   try {
149     while (!dfgCompiled({f:theFunction}))
150       values.push(eval(_a));
151     values.push(eval(_a));
152   } catch (e) {
153     exception = e;
154   }
155
156   var _bv = eval(_b);
157   if (exception)
158     testFailed(_a + " should be " + stringify(_bv) + ". On iteration " + (values.length + 1) + ", threw exception " + exception);
159   else {
160     var allPassed = true;
161     for (var i = 0; i < values.length; ++i) {
162       var _av = values[i];
163       if (isResultCorrect(_av, _bv))
164         continue;
165       if (typeof(_av) == typeof(_bv))
166         testFailed(_a + " should be " + stringify(_bv) + ". On iteration " + (i + 1) + ", was " + stringify(_av) + ".");
167       else
168         testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). On iteration " + (i + 1) + ", was " + _av + " (of type " + typeof _av + ").");
169       allPassed = false;
170     }
171     if (allPassed)
172       testPassed(_a + " is " + _b + " on all iterations including after DFG tier-up.");
173   }
174   
175   return values.length;
176 }
177
178 function shouldBeType(_a, _type) {
179   var exception;
180   var _av;
181   try {
182     _av = eval(_a);
183   } catch (e) {
184     exception = e;
185   }
186
187   var _typev = eval(_type);
188   if (_av instanceof _typev) {
189     testPassed(_a + " is an instance of " + _type);
190   } else {
191     testFailed(_a + " is not an instance of " + _type);
192   }
193 }
194
195 function shouldBeTrue(_a) { shouldBe(_a, "true"); }
196 function shouldBeFalse(_a) { shouldBe(_a, "false"); }
197 function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
198 function shouldBeNull(_a) { shouldBe(_a, "null"); }
199
200 function shouldBeEqualToString(a, b)
201 {
202   if (typeof a !== "string" || typeof b !== "string")
203     debug("WARN: shouldBeEqualToString() expects string arguments");
204   var unevaledString = JSON.stringify(b);
205   shouldBe(a, unevaledString);
206 }
207
208 function shouldBeUndefined(_a)
209 {
210   var exception;
211   var _av;
212   try {
213      _av = eval(_a);
214   } catch (e) {
215      exception = e;
216   }
217
218   if (exception)
219     testFailed(_a + " should be undefined. Threw exception " + exception);
220   else if (typeof _av == "undefined")
221     testPassed(_a + " is undefined.");
222   else
223     testFailed(_a + " should be undefined. Was " + _av);
224 }
225
226 function shouldNotThrow(_a) {
227     try {
228         eval(_a);
229         testPassed(_a + " did not throw exception.");
230     } catch (e) {
231         testFailed(_a + " should not throw exception. Threw exception " + e + ".");
232     }
233 }
234
235 function shouldThrow(_a, _e)
236 {
237   var exception;
238   var _av;
239   try {
240      _av = eval(_a);
241   } catch (e) {
242      exception = e;
243   }
244
245   var _ev;
246   if (_e)
247       _ev =  eval(_e);
248
249   if (exception) {
250     if (typeof _e == "undefined" || exception == _ev)
251       testPassed(_a + " threw exception " + exception + ".");
252     else
253       testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + ".");
254   } else if (typeof _av == "undefined")
255     testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
256   else
257     testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
258 }
259
260 function isSuccessfullyParsed()
261 {
262     // FIXME: Remove this and only report unexpected syntax errors.
263     if (!errorMessage)
264         successfullyParsed = true;
265     shouldBeTrue("successfullyParsed");
266     if (silentTestPass && didPassSomeTestsSilently)
267         debug("Passed some tests silently.");
268     if (silentTestPass && didFailSomeTests)
269         debug("Some tests failed.");
270     debug("\nTEST COMPLETE\n");
271 }
272
273
274 function dfgCompiled(argument)
275 {
276     var numberOfCompiles = "compiles" in argument ? argument.compiles : 1;
277     
278     if (!("f" in argument))
279         throw new Error("dfgCompiled called with invalid argument.");
280     
281     if (argument.f instanceof Array) {
282         for (var i = 0; i < argument.f.length; ++i) {
283             if (testRunner.numberOfDFGCompiles(argument.f[i]) < numberOfCompiles)
284                 return false;
285         }
286     } else {
287         if (testRunner.numberOfDFGCompiles(argument.f) < numberOfCompiles)
288             return false;
289     }
290     
291     return true;
292 }
293
294 function dfgIncrement(argument)
295 {
296     if (!self.testRunner)
297         return argument.i;
298     
299     if (argument.i < argument.n)
300         return argument.i;
301     
302     if (didFailSomeTests)
303         return argument.i;
304     
305     if (!dfgCompiled(argument))
306         return "start" in argument ? argument.start : 0;
307     
308     return argument.i;
309 }
310
311 function noInline(theFunction)
312 {
313     if (!self.testRunner)
314         return;
315     
316     testRunner.neverInlineFunction(theFunction);
317 }
318
319 // It's possible for an async test to call finishJSTest() before js-test-post.js
320 // has been parsed.
321 function finishJSTest()
322 {
323     wasFinishJSTestCalled = true;
324     if (!wasPostTestScriptParsed)
325         return;
326     isSuccessfullyParsed();
327 }