Chromium Code Reviews| Index: test/mjsunit/strong/implicit-conversions.js |
| diff --git a/test/mjsunit/strong/implicit-conversions.js b/test/mjsunit/strong/implicit-conversions.js |
| index 6aa2b1dc2005e85224dc0065cfb62aee0a606369..49af153e520f56689a23b908994e49e9e4b2b69a 100644 |
| --- a/test/mjsunit/strong/implicit-conversions.js |
| +++ b/test/mjsunit/strong/implicit-conversions.js |
| @@ -7,7 +7,7 @@ |
| "use strict"; |
| // TODO(conradw): Implement other strong operators |
| -let strongBinops = [ |
| +let strongNumberBinops = [ |
| "-", |
| "*", |
| "/", |
| @@ -20,22 +20,37 @@ let strongBinops = [ |
| ">>>", |
| ]; |
| +let strongStringOrNumberBinops = [ |
| + "+" |
| +]; |
| + |
| +let strongBinops = strongNumberBinops.concat(strongStringOrNumberBinops); |
| + |
| let strongUnops = [ |
| "~", |
| "+", |
| "-" |
| ]; |
| -let nonNumberValues = [ |
| +let nonStringOrNumberValues = [ |
| "{}", |
| - "'foo'", |
| + "false", |
| "(function(){})", |
| "[]", |
| - "'0'", |
| - "'NaN'", |
| "(class Foo {})" |
| ]; |
| +let stringValues = [ |
| + "''", |
| + "' '", |
| + "'foo'", |
| + "'f\\u006F\\u006F'", |
| + "'0'", |
| + "'NaN'" |
| +]; |
| + |
| +let nonNumberValues = nonStringOrNumberValues.concat(stringValues); |
| + |
| let numberValues = [ |
| "0", |
| "(-0)", |
| @@ -57,6 +72,16 @@ let numberValues = [ |
| "(-Infinity)" |
| ]; |
| +function add_strong(x, y) { |
| + "use strong"; |
| + return x + y; |
| +} |
| + |
| +function add_num_strong(x, y) { |
|
arv (Not doing code reviews)
2015/04/30 16:07:32
Any reason for this over add_strong?
conradw
2015/05/04 09:28:22
It's a kind of unfortunate way to make sure that t
|
| + "use strong"; |
| + return x + y; |
| +} |
| + |
| function sub_strong(x, y) { |
| "use strong"; |
| return x - y; |
| @@ -107,6 +132,11 @@ function sar_strong(x, y) { |
| return x >>> y; |
| } |
| +function typed_add_strong(x, y) { |
| + "use strong"; |
| + return (+x) + (+y); |
| +} |
| + |
| function typed_sub_strong(x, y) { |
| "use strong"; |
| return (+x) - (+y); |
| @@ -157,12 +187,17 @@ function typed_sar_strong(x, y) { |
| return (+x) >>> (+y); |
| } |
| -let strongFuncs = [sub_strong, mul_strong, div_strong, mod_strong, or_strong, |
| - and_strong, xor_strong, shl_strong, shr_strong, sar_strong, |
| - typed_sub_strong, typed_mul_strong, typed_div_strong, |
| - typed_mod_strong, typed_or_strong, typed_and_strong, |
| - typed_xor_strong, typed_shl_strong, typed_shr_strong, |
| - typed_sar_strong]; |
| +let strongNumberFuncs = [add_num_strong, sub_strong, mul_strong, div_strong, |
| + mod_strong, or_strong, and_strong, xor_strong, |
| + shl_strong, shr_strong, sar_strong, typed_add_strong, |
| + typed_sub_strong, typed_mul_strong, typed_div_strong, |
| + typed_mod_strong, typed_or_strong, typed_and_strong, |
| + typed_xor_strong, typed_shl_strong, typed_shr_strong, |
| + typed_sar_strong]; |
| + |
| +let strongStringOrNumberFuncs = [add_strong]; |
| + |
| +let strongFuncs = strongNumberFuncs.concat(strongStringOrNumberFuncs); |
| function inline_sub_strong(x, y) { |
| "use strong"; |
| @@ -197,29 +232,40 @@ function assertStrongThrowBehaviour(expr) { |
| assertThrows("'use strong'; let v = " + expr + ";", TypeError); |
| } |
| -for (let op of strongBinops) { |
| - for (let v1 of numberValues) { |
| +function checkArgumentCombinations(op, leftList, rightList, willThrow) { |
| + for (let v1 of leftList) { |
| let assignExpr = "foo " + op + "= " + v1 + ";"; |
| - for (let v2 of numberValues) { |
| - assertDoesNotThrow("'use strong'; let foo = " + v2 + "; " + assignExpr); |
| - assertStrongNonThrowBehaviour("(" + v1 + op + v2 + ")"); |
| - } |
| - for (let v2 of nonNumberValues) { |
| - assertThrows("'use strong'; let foo = " + v2 + "; " + assignExpr, |
| - TypeError); |
| - assertStrongThrowBehaviour("(" + v1 + op + v2 + ")"); |
| - } |
| - } |
| - for (let v1 of nonNumberValues) { |
| - let assignExpr = "foo " + op + "= " + v1 + ";"; |
| - for (let v2 of numberValues.concat(nonNumberValues)) { |
| - assertThrows("'use strong'; let foo = " + v2 + "; " + assignExpr, |
| - TypeError); |
| - assertStrongThrowBehaviour("(" + v1 + op + v2 + ")"); |
| + for (let v2 of rightList) { |
| + let compoundAssignment = "'use strong'; let foo = " + v2 + "; " + |
| + assignExpr; |
| + if(willThrow) { |
| + assertThrows(compoundAssignment, TypeError); |
| + assertStrongThrowBehaviour("(" + v1 + op + v2 + ")"); |
| + } else { |
| + assertDoesNotThrow(compoundAssignment); |
| + assertStrongNonThrowBehaviour("(" + v1 + op + v2 + ")"); |
| + } |
| } |
| } |
| } |
| +for (let op of strongBinops) { |
| + checkArgumentCombinations(op, numberValues, numberValues, false); |
| + checkArgumentCombinations(op, numberValues, nonNumberValues, true); |
| +} |
| + |
| +for (let op of strongNumberBinops) { |
| + checkArgumentCombinations(op, nonNumberValues, |
| + numberValues.concat(nonNumberValues), true); |
| +} |
| + |
| +for (let op of strongStringOrNumberBinops) { |
| + checkArgumentCombinations(op, nonNumberValues, |
| + numberValues.concat(nonStringOrNumberValues), true); |
| + checkArgumentCombinations(op, nonStringOrNumberValues, stringValues, true); |
| + checkArgumentCombinations(op, stringValues, stringValues, false); |
| +} |
| + |
| for (let op of strongUnops) { |
| for (let value of numberValues) { |
| assertStrongNonThrowBehaviour("(" + op + value + ")"); |
| @@ -229,35 +275,48 @@ for (let op of strongUnops) { |
| } |
| } |
| -for (let func of strongFuncs) { |
| - let a = func(4, 5); |
| - let b = func(4, 5); |
| - assertTrue(a === b); |
| +for (let func of strongNumberFuncs) { |
| + // Check IC None*None->None throws |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %OptimizeFunctionOnNextCall(func); |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %DeoptimizeFunction(func); |
| + func(4, 5); |
| + func(4, 5); |
| + // Check IC Smi*Smi->Smi throws |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %OptimizeFunctionOnNextCall(func); |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %DeoptimizeFunction(func); |
| + func(NaN, NaN); |
| + func(NaN, NaN); |
| + // Check IC Number*Number->Number throws |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
|
arv (Not doing code reviews)
2015/04/30 16:07:32
Shouldn't this use a non smi?
conradw
2015/05/04 09:28:22
I'm not particularly worried in this case, because
|
| + %OptimizeFunctionOnNextCall(func); |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %DeoptimizeFunction(func); |
| +} |
| + |
| +for (let func of strongStringOrNumberFuncs) { |
| + // Check IC None*None->None throws |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| %OptimizeFunctionOnNextCall(func); |
| - let c = func(4, 5); |
| - assertOptimized(func); |
| - assertTrue(b === c); |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| %DeoptimizeFunction(func); |
| - let d = func(4, 5); |
| - assertTrue(c === d); |
| + func("foo", "bar"); |
| + func("foo", "bar"); |
| + // Check IC String*String->String throws |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %OptimizeFunctionOnNextCall(func); |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %DeoptimizeFunction(func); |
| + func(NaN, NaN); |
| + func(NaN, NaN); |
| + // Check IC Generic*Generic->Generic throws |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| + %OptimizeFunctionOnNextCall(func); |
| + assertThrows(function(){func(2, "foo");}, TypeError); |
| %DeoptimizeFunction(func); |
| - %ClearFunctionTypeFeedback(func); |
| -} |
| - |
| -for (let func of strongFuncs) { |
| - try { |
| - let a = func(2, 3); |
| - let b = func(2, 3); |
| - assertTrue(a === b); |
| - %OptimizeFunctionOnNextCall(func); |
| - let c = func(2, "foo"); |
| - assertUnreachable(); |
| - } catch (e) { |
| - assertInstanceof(e, TypeError); |
| - assertUnoptimized(func); |
| - assertThrows(function(){func(2, "foo");}, TypeError); |
| - assertDoesNotThrow(function(){func(2, 3);}); |
| - } |
| } |
| assertThrows(function(){inline_outer(1, {})}, TypeError); |