6374ecf35e1a40e07f1461107a974b2e6f8a6f55
[WebKit-https.git] / Source / JavaScriptCore / tests / stress / op_sub.js
1 //@ runFTLNoCJIT
2
3 // This test module aims to test the subtraction operator by comparing its runtime
4 // behavior (using the different tiers) with expected values computed at initialization
5 // time using the LLINT / bytecode generator.
6 //
7 // It works by generating test scenarios from permutations of value pairs to exercise
8 // the subtraction operator. It computes the expected results by evaluating an expression
9 // to subtract the values in an initialization pass. The scenarios are later applied to
10 // a set of test functions of the forms:
11 //
12 //     variable - variable
13 //     constant - variable
14 //     variable - constant
15 //
16 // See generateScenarios() and initializeTestCases() for details on how the test
17 // cases are generated.
18 //
19 // If all goes well, this test module will terminate silently. If not, it will print
20 // errors.
21
22 var o1 = {
23     valueOf: function() { return 10; }
24 };
25
26 var set1 = [
27     'o1',
28     'null',
29     'undefined',
30     'NaN',
31     '"abc"',
32 ];
33
34 var set2 = [
35     '10',
36     '-10',
37     '2147483647',
38     '-2147483647',
39     '4294967296',
40     '-4294967296',
41     '100.2',
42     '-100.2',
43     'true',
44     'false',
45 ];
46
47 // Assemble the values that we'll be testing with:
48 var values = [];
49 for (var i = 0; i < set1.length; i++)
50     values.push(set1[i]);
51 for (var i = 0; i < set2.length; i++)
52     values.push(set2[i]);
53 for (var i = 0; i < set2.length; i++)
54     values.push('"' + set2[i] + '"');
55
56 function generateScenarios(xvalues, yvalues) {
57     var scenarios = [];
58     for (var i = 0; i < xvalues.length; i++) {
59         for (var j = 0; j < yvalues.length; j++) {
60             var xStr = xvalues[i];
61             var yStr = yvalues[j];
62             var x = eval(xStr);
63             var y = eval(yStr);
64             var name = "(" + xStr + " - " + yStr + ")";
65             var expected = eval("" + xStr + " - " + yStr);
66             var scenario = { name: name, x: x, y: y, expected: expected };
67
68             scenarios.push(scenario);
69         }
70     }
71     return scenarios;
72 }
73
74 function printScenarios(scenarios) {
75     for (var i = 0; i < scenarios.length; i++) {
76         var scenario = scenarios[i];
77         print("scenario[" + i + "]: { name: " + scenario.name + ", x: " + scenario.x, ", y: " + scenario.y + ", expected: " + scenario.expected + " }");
78     }
79 }
80
81 var testCases = [
82     {
83         name: "sub",
84         func: function(x, y) { return x - y; },
85         xvalues: values,
86         yvalues: values
87     },
88     {
89         name: "subI32V",
90         func: function(x, y) { return 10 - y; },
91         xvalues: [ '10' ],
92         yvalues: values
93     },
94     {
95         name: "subVI32",
96         func: function(x, y) { return x - 10; },
97         xvalues: values,
98         yvalues: [ '10' ]
99     },
100     {
101         name: "subI32oV",
102         func: function(x, y) { return -2147483647 - y; },
103         xvalues: [ '-2147483647' ],
104         yvalues: values
105     },
106     {
107         name: "subVI32o",
108         func: function(x, y) { return x - 2147483647; },
109         xvalues: values,
110         yvalues: [ '2147483647' ]
111     },
112     {
113         name: "subI52V",
114         func: function(x, y) { return 4294967296 - y; },
115         xvalues: [ '4294967296' ],
116         yvalues: values
117     },
118     {
119         name: "subVI52",
120         func: function(x, y) { return x - 4294967296; },
121         xvalues: values,
122         yvalues: [ '4294967296' ]
123     },
124     {
125         name: "subDV",
126         func: function(x, y) { return 100.2 - y; },
127         xvalues: [ '100.2' ],
128         yvalues: values
129     },
130     {
131         name: "subVD",
132         func: function(x, y) { return x - 100.2; },
133         xvalues: values,
134         yvalues: [ '100.2' ]
135     },
136     {
137         name: "subBV",
138         func: function(x, y) { return true - y; },
139         xvalues: [ 'true' ],
140         yvalues: values
141     },
142     {
143         name: "subVB",
144         func: function(x, y) { return x - true; },
145         xvalues: values,
146         yvalues: [ 'true' ]
147     },
148     {
149         name: "subSi32V",
150         func: function(x, y) { return "10" - y; },
151         xvalues: [ '"10"' ],
152         yvalues: values
153     },
154     {
155         name: "subVSi32",
156         func: function(x, y) { return x - "10"; },
157         xvalues: values,
158         yvalues: [ '"10"' ]
159     },
160
161     {
162         name: "subSi32oV",
163         func: function(x, y) { return "-2147483647" - y; },
164         xvalues: [ '"-2147483647"' ],
165         yvalues: values
166     },
167     {
168         name: "subVSi32o",
169         func: function(x, y) { return x - "2147483647"; },
170         xvalues: values,
171         yvalues: [ '"2147483647"' ]
172     },
173     {
174         name: "subSi52V",
175         func: function(x, y) { return "4294967296" - y; },
176         xvalues: [ '"4294967296"' ],
177         yvalues: values
178     },
179     {
180         name: "subVSi52",
181         func: function(x, y) { return x - "4294967296"; },
182         xvalues: values,
183         yvalues: [ '"4294967296"' ]
184     },
185     {
186         name: "subSdV",
187         func: function(x, y) { return "100.2" - y; },
188         xvalues: [ '"100.2"' ],
189         yvalues: values
190     },
191     {
192         name: "subVSd",
193         func: function(x, y) { return x - "100.2"; },
194         xvalues: values,
195         yvalues: [ '"100.2"' ]
196     },
197     {
198         name: "subSbV",
199         func: function(x, y) { return "true" - y; },
200         xvalues: [ '"true"' ],
201         yvalues: values
202     },
203     {
204         name: "subVSb",
205         func: function(x, y) { return x - "true"; },
206         xvalues: values,
207         yvalues: [ '"true"' ]
208     },
209
210     {
211         name: "subSV",
212         func: function(x, y) { return "abc" - y; },
213         xvalues: [ '"abc"' ],
214         yvalues: values
215     },
216     {
217         name: "subVS",
218         func: function(x, y) { return x - "abc"; },
219         xvalues: values,
220         yvalues: [ '"abc"' ]
221     },
222     {
223         name: "subNV",
224         func: function(x, y) { return null - y; },
225         xvalues: [ 'null' ],
226         yvalues: values
227     },
228     {
229         name: "subVN",
230         func: function(x, y) { return x - null; },
231         xvalues: values,
232         yvalues: [ 'null' ]
233     },
234     {
235         name: "subOV",
236         func: function(x, y) { return o1 - y; },
237         xvalues: [ 'o1' ],
238         yvalues: values
239     },
240     {
241         name: "subVO",
242         func: function(x, y) { return x - o1; },
243         xvalues: values,
244         yvalues: [ 'o1' ]
245     },
246     {
247         name: "subNaNV",
248         func: function(x, y) { return NaN - y; },
249         xvalues: [ 'NaN' ],
250         yvalues: values
251     },
252     {
253         name: "subVNaN",
254         func: function(x, y) { return x - NaN; },
255         xvalues: values,
256         yvalues: [ 'NaN' ]
257     },
258 ];
259
260 function initializeTestCases() {
261     for (var test of testCases) {
262         noInline(test.func);
263         test.scenarios = generateScenarios(test.xvalues, test.yvalues);
264     }
265 }
266 initializeTestCases();
267
268 var errorReport = "";
269
270 function runTest(test) {
271     var failedScenario = [];
272     var scenarios = test.scenarios;
273     var testFunc = test.func;
274     try {
275         for (var i = 0; i < 10000; i++) {
276             for (var scenarioID = 0; scenarioID < scenarios.length; scenarioID++) {
277                 var scenario = scenarios[scenarioID];
278                 var result = testFunc(scenario.x, scenario.y);
279                 if (result == scenario.expected)
280                     continue;
281                 if (Number.isNaN(result) && Number.isNaN(scenario.expected))
282                     continue;
283                 if (!failedScenario[scenarioID]) {
284                     errorReport += "FAIL: " + test.name + ":" + scenario.name + " started failing on iteration " + i + ": expected " + scenario.expected + ", actual " + result + "\n";
285                     failedScenario[scenarioID] = scenario;
286                 }
287             }
288         }
289     } catch(e) {
290         errorReport += "Unexpected exception: " + e + "\n";
291     }
292 }
293
294 for (var test of testCases)
295     runTest(test);
296
297 if (errorReport !== "")
298     throw "Error: bad result:\n" + errorReport;