OLD | NEW |
| (Empty) |
1 // Copyright 2015 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Flags: --strong-mode --allow-natives-syntax | |
6 | |
7 "use strict"; | |
8 | |
9 // Boolean indicates whether an operator can be part of a compound assignment. | |
10 let strongNumberBinops = [ | |
11 ["-", true], | |
12 ["*", true], | |
13 ["/", true], | |
14 ["%", true], | |
15 ["|", true], | |
16 ["&", true], | |
17 ["^", true], | |
18 ["<<", true], | |
19 [">>", true], | |
20 [">>>", true] | |
21 ]; | |
22 | |
23 let strongStringOrNumberBinops = [ | |
24 ["+", true], | |
25 ["<", false], | |
26 [">", false], | |
27 ["<=", false], | |
28 [">=", false] | |
29 ]; | |
30 | |
31 let strongBinops = strongNumberBinops.concat(strongStringOrNumberBinops); | |
32 | |
33 let strongUnops = [ | |
34 "~", | |
35 "+", | |
36 "-" | |
37 ]; | |
38 | |
39 let nonStringOrNumberValues = [ | |
40 "null", | |
41 "undefined", | |
42 "{}", | |
43 "false", | |
44 "(function(){})", | |
45 "[]", | |
46 "(class Foo {})" | |
47 ]; | |
48 | |
49 let stringValues = [ | |
50 "''", | |
51 "' '", | |
52 "'foo'", | |
53 "'f\\u006F\\u006F'", | |
54 "'0'", | |
55 "'NaN'" | |
56 ]; | |
57 | |
58 let nonNumberValues = nonStringOrNumberValues.concat(stringValues); | |
59 | |
60 let numberValues = [ | |
61 "0", | |
62 "(-0)", | |
63 "1", | |
64 "(-4294967295)", | |
65 "(-4294967296)", | |
66 "9999999999999", | |
67 "(-9999999999999)", | |
68 "NaN", | |
69 "Infinity", | |
70 "(-Infinity)" | |
71 ]; | |
72 | |
73 //****************************************************************************** | |
74 // Relational comparison function declarations | |
75 function add_strong(x, y) { | |
76 "use strong"; | |
77 return x + y; | |
78 } | |
79 | |
80 function add_num_strong(x, y) { | |
81 "use strong"; | |
82 return x + y; | |
83 } | |
84 | |
85 function sub_strong(x, y) { | |
86 "use strong"; | |
87 return x - y; | |
88 } | |
89 | |
90 function mul_strong(x, y) { | |
91 "use strong"; | |
92 return x * y; | |
93 } | |
94 | |
95 function div_strong(x, y) { | |
96 "use strong"; | |
97 return x / y; | |
98 } | |
99 | |
100 function mod_strong(x, y) { | |
101 "use strong"; | |
102 return x % y; | |
103 } | |
104 | |
105 function or_strong(x, y) { | |
106 "use strong"; | |
107 return x | y; | |
108 } | |
109 | |
110 function and_strong(x, y) { | |
111 "use strong"; | |
112 return x & y; | |
113 } | |
114 | |
115 function xor_strong(x, y) { | |
116 "use strong"; | |
117 return x ^ y; | |
118 } | |
119 | |
120 function shl_strong(x, y) { | |
121 "use strong"; | |
122 return x << y; | |
123 } | |
124 | |
125 function shr_strong(x, y) { | |
126 "use strong"; | |
127 return x >> y; | |
128 } | |
129 | |
130 function sar_strong(x, y) { | |
131 "use strong"; | |
132 return x >>> y; | |
133 } | |
134 | |
135 function less_strong(x, y) { | |
136 "use strong"; | |
137 return x < y; | |
138 } | |
139 | |
140 function less_num_strong(x, y) { | |
141 "use strong"; | |
142 return x < y; | |
143 } | |
144 | |
145 function greater_strong(x, y) { | |
146 "use strong"; | |
147 return x > y; | |
148 } | |
149 | |
150 function greater_num_strong(x, y) { | |
151 "use strong"; | |
152 return x > y; | |
153 } | |
154 | |
155 function less_equal_strong(x, y) { | |
156 "use strong"; | |
157 return x <= y; | |
158 } | |
159 | |
160 function less_equal_num_strong(x, y) { | |
161 "use strong"; | |
162 return x <= y; | |
163 } | |
164 | |
165 function greater_equal_strong(x, y) { | |
166 "use strong"; | |
167 return x >= y; | |
168 } | |
169 | |
170 function greater_equal_num_strong(x, y) { | |
171 "use strong"; | |
172 return x >= y; | |
173 } | |
174 | |
175 function typed_add_strong(x, y) { | |
176 "use strong"; | |
177 return (+x) + (+y); | |
178 } | |
179 | |
180 function typed_sub_strong(x, y) { | |
181 "use strong"; | |
182 return (+x) - (+y); | |
183 } | |
184 | |
185 function typed_mul_strong(x, y) { | |
186 "use strong"; | |
187 return (+x) * (+y); | |
188 } | |
189 | |
190 function typed_div_strong(x, y) { | |
191 "use strong"; | |
192 return (+x) / (+y); | |
193 } | |
194 | |
195 function typed_mod_strong(x, y) { | |
196 "use strong"; | |
197 return (+x) % (+y); | |
198 } | |
199 | |
200 function typed_or_strong(x, y) { | |
201 "use strong"; | |
202 return (+x) | (+y); | |
203 } | |
204 | |
205 function typed_and_strong(x, y) { | |
206 "use strong"; | |
207 return (+x) & (+y); | |
208 } | |
209 | |
210 function typed_xor_strong(x, y) { | |
211 "use strong"; | |
212 return (+x) ^ (+y); | |
213 } | |
214 | |
215 function typed_shl_strong(x, y) { | |
216 "use strong"; | |
217 return (+x) << (+y); | |
218 } | |
219 | |
220 function typed_shr_strong(x, y) { | |
221 "use strong"; | |
222 return (+x) >> (+y); | |
223 } | |
224 | |
225 function typed_sar_strong(x, y) { | |
226 "use strong"; | |
227 return (+x) >>> (+y); | |
228 } | |
229 | |
230 function typed_less_strong(x, y) { | |
231 "use strong"; | |
232 return (+x) < (+y); | |
233 } | |
234 | |
235 function typed_greater_strong(x, y) { | |
236 "use strong"; | |
237 return (+x) > (+y); | |
238 } | |
239 | |
240 function typed_less_equal_strong(x, y) { | |
241 "use strong"; | |
242 return (+x) <= (+y); | |
243 } | |
244 | |
245 function typed_greater_equal_strong(x, y) { | |
246 "use strong"; | |
247 return (+x) >= (+y); | |
248 } | |
249 | |
250 //****************************************************************************** | |
251 // (in)equality function declarations | |
252 function str_equal_strong(x, y) { | |
253 "use strong"; | |
254 return x === y; | |
255 } | |
256 | |
257 function str_ineq_strong(x, y) { | |
258 "use strong"; | |
259 return x !== y; | |
260 } | |
261 | |
262 let strongNumberFuncs = [add_num_strong, sub_strong, mul_strong, div_strong, | |
263 mod_strong, or_strong, and_strong, xor_strong, | |
264 shl_strong, shr_strong, sar_strong, less_num_strong, | |
265 greater_num_strong, less_equal_num_strong, | |
266 greater_equal_num_strong, typed_add_strong, | |
267 typed_sub_strong, typed_mul_strong, typed_div_strong, | |
268 typed_mod_strong, typed_or_strong, typed_and_strong, | |
269 typed_xor_strong, typed_shl_strong, typed_shr_strong, | |
270 typed_sar_strong, typed_less_strong, | |
271 typed_greater_strong, typed_less_equal_strong, | |
272 typed_greater_equal_strong]; | |
273 | |
274 let strongStringOrNumberFuncs = [add_strong, less_strong, greater_strong, | |
275 less_equal_strong, greater_equal_strong]; | |
276 | |
277 let strongFuncs = strongNumberFuncs.concat(strongStringOrNumberFuncs); | |
278 | |
279 function assertStrongNonThrowBehaviour(expr) { | |
280 assertEquals(eval(expr), eval("'use strong';" + expr)); | |
281 assertDoesNotThrow("'use strong'; " + expr + ";"); | |
282 assertDoesNotThrow("'use strong'; let v = " + expr + ";"); | |
283 } | |
284 | |
285 function assertStrongThrowBehaviour(expr) { | |
286 assertDoesNotThrow("'use strict'; " + expr + ";"); | |
287 assertDoesNotThrow("'use strict'; let v = " + expr + ";"); | |
288 assertThrows("'use strong'; " + expr + ";", TypeError); | |
289 assertThrows("'use strong'; let v = " + expr + ";", TypeError); | |
290 } | |
291 | |
292 function checkArgumentCombinations(op, leftList, rightList, willThrow) { | |
293 for (let v1 of leftList) { | |
294 let assignExpr = "foo " + op[0] + "= " + v1 + ";"; | |
295 for (let v2 of rightList) { | |
296 let compoundAssignment = "'use strong'; let foo = " + v2 + "; " + | |
297 assignExpr; | |
298 if (willThrow) { | |
299 if (op[1]) { | |
300 assertThrows(compoundAssignment, TypeError); | |
301 } | |
302 assertStrongThrowBehaviour("(" + v1 + op[0] + v2 + ")"); | |
303 } else { | |
304 if (op[1]) { | |
305 assertDoesNotThrow(compoundAssignment); | |
306 } | |
307 assertStrongNonThrowBehaviour("(" + v1 + op[0] + v2 + ")"); | |
308 } | |
309 } | |
310 } | |
311 } | |
312 | |
313 for (let op of strongBinops) { | |
314 checkArgumentCombinations(op, numberValues, numberValues, false); | |
315 checkArgumentCombinations(op, numberValues, nonNumberValues, true); | |
316 } | |
317 | |
318 for (let op of strongNumberBinops) { | |
319 checkArgumentCombinations(op, nonNumberValues, | |
320 numberValues.concat(nonNumberValues), true); | |
321 } | |
322 | |
323 for (let op of strongStringOrNumberBinops) { | |
324 checkArgumentCombinations(op, nonNumberValues, | |
325 numberValues.concat(nonStringOrNumberValues), true); | |
326 checkArgumentCombinations(op, nonStringOrNumberValues, stringValues, true); | |
327 checkArgumentCombinations(op, stringValues, stringValues, false); | |
328 } | |
329 | |
330 for (let op of strongUnops) { | |
331 for (let value of numberValues) { | |
332 assertStrongNonThrowBehaviour("(" + op + value + ")"); | |
333 } | |
334 for (let value of nonNumberValues) { | |
335 assertStrongThrowBehaviour("(" + op + value + ")"); | |
336 } | |
337 } | |
338 | |
339 for (let func of strongNumberFuncs) { | |
340 // Check IC None*None->None throws | |
341 for (let v of nonNumberValues) { | |
342 let value = eval(v); | |
343 assertThrows(function(){func(2, value);}, TypeError); | |
344 %OptimizeFunctionOnNextCall(func); | |
345 assertThrows(function(){func(2, value);}, TypeError); | |
346 %DeoptimizeFunction(func); | |
347 } | |
348 func(4, 5); | |
349 func(4, 5); | |
350 // Check IC Smi*Smi->Smi throws | |
351 for (let v of nonNumberValues) { | |
352 let value = eval(v); | |
353 assertThrows(function(){func(2, value);}, TypeError); | |
354 %OptimizeFunctionOnNextCall(func); | |
355 assertThrows(function(){func(2, value);}, TypeError); | |
356 %DeoptimizeFunction(func); | |
357 } | |
358 func(NaN, NaN); | |
359 func(NaN, NaN); | |
360 // Check IC Number*Number->Number throws | |
361 for (let v of nonNumberValues) { | |
362 let value = eval(v); | |
363 assertThrows(function(){func(2, value);}, TypeError); | |
364 %OptimizeFunctionOnNextCall(func); | |
365 assertThrows(function(){func(2, value);}, TypeError); | |
366 %DeoptimizeFunction(func); | |
367 } | |
368 } | |
369 | |
370 for (let func of strongStringOrNumberFuncs) { | |
371 // Check IC None*None->None throws | |
372 for (let v of nonNumberValues) { | |
373 let value = eval(v); | |
374 assertThrows(function(){func(2, value);}, TypeError); | |
375 %OptimizeFunctionOnNextCall(func); | |
376 assertThrows(function(){func(2, value);}, TypeError); | |
377 %DeoptimizeFunction(func); | |
378 } | |
379 func("foo", "bar"); | |
380 func("foo", "bar"); | |
381 // Check IC String*String->String throws | |
382 for (let v of nonNumberValues) { | |
383 let value = eval(v); | |
384 assertThrows(function(){func(2, value);}, TypeError); | |
385 %OptimizeFunctionOnNextCall(func); | |
386 assertThrows(function(){func(2, value);}, TypeError); | |
387 %DeoptimizeFunction(func); | |
388 } | |
389 func(NaN, NaN); | |
390 func(NaN, NaN); | |
391 // Check IC Generic*Generic->Generic throws | |
392 for (let v of nonNumberValues) { | |
393 let value = eval(v); | |
394 assertThrows(function(){func(2, value);}, TypeError); | |
395 %OptimizeFunctionOnNextCall(func); | |
396 assertThrows(function(){func(2, value);}, TypeError); | |
397 %DeoptimizeFunction(func); | |
398 } | |
399 } | |
400 | |
401 for (let func of [str_equal_strong, str_ineq_strong]) { | |
402 assertDoesNotThrow(function(){func(2, undefined)}); | |
403 assertDoesNotThrow(function(){func(2, undefined)}); | |
404 %OptimizeFunctionOnNextCall(func); | |
405 assertDoesNotThrow(function(){func(2, undefined)}); | |
406 %DeoptimizeFunction(func); | |
407 assertDoesNotThrow(function(){func(true, {})}); | |
408 assertDoesNotThrow(function(){func(true, {})}); | |
409 %OptimizeFunctionOnNextCall(func); | |
410 assertDoesNotThrow(function(){func(true, {})}); | |
411 %DeoptimizeFunction(func); | |
412 } | |
OLD | NEW |