| 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 |