Index: test/mjsunit/strong/implicit-conversions.js |
diff --git a/test/mjsunit/strong/implicit-conversions.js b/test/mjsunit/strong/implicit-conversions.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..dd22db152eb3aae91133383cf0cdfb4dd106f787 |
--- /dev/null |
+++ b/test/mjsunit/strong/implicit-conversions.js |
@@ -0,0 +1,164 @@ |
+// Copyright 2015 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Flags: --strong-mode --allow-natives-syntax |
+ |
+'use strict'; |
+ |
+// TODO(conradw): Implement other strong operators |
+let strong_arith = [ |
+ "-", |
arv (Not doing code reviews)
2015/04/24 14:14:23
Don't mix ' and " in the same file. ' is preferred
arv (Not doing code reviews)
2015/04/24 14:14:23
Array and Object literals should be indented 2 spa
conradw
2015/04/24 14:42:32
Will add to my followup https://codereview.chromiu
conradw
2015/04/24 14:42:32
I've been trying to be consistent in using ", whic
|
+ "*", |
+ "/", |
+ "%" |
+] |
arv (Not doing code reviews)
2015/04/24 14:14:23
semicolon
conradw
2015/04/24 14:42:32
followup
|
+ |
+let nonnumber_values = [ |
arv (Not doing code reviews)
2015/04/24 14:14:23
nonNumberValues
https://google-styleguide.googlec
conradw
2015/04/24 14:42:32
followup
|
+ "{}", |
+ "'foo'", |
+ "(function(){})", |
+ "[]", |
+ "'0'", |
+ "'NaN'", |
+ "(class Foo {})" |
+] |
+ |
+let number_values = [ |
+ "0", |
+ "(-0)", |
+ "1", |
+ "0.79", |
+ "(-0.79)", |
+ "4294967295", |
+ "4294967296", |
+ "(-4294967295)", |
+ "(-4294967296)", |
+ "9999999999999", |
+ "(-9999999999999)", |
+ "1.5e10", |
+ "(-1.5e10)", |
+ "0xFFF", |
+ "(-0xFFF)", |
+ "NaN", |
+ "Infinity", |
+ "(-Infinity)" |
+] |
+ |
+function sub_strong(x, y) { |
+ "use strong"; |
+ let v = x - y; |
+ return v; |
arv (Not doing code reviews)
2015/04/24 14:14:23
why not just `return x - y`?
Is this to prevent i
conradw
2015/04/24 14:42:32
there's no particular reason for it, will change i
|
+} |
+ |
+function mul_strong(x, y) { |
+ "use strong"; |
+ let v = x * y; |
+ return v; |
+} |
+ |
+function div_strong(x, y) { |
+ "use strong"; |
+ let v = x / y; |
+ return v; |
+} |
+ |
+function mod_strong(x, y) { |
+ "use strong"; |
+ let v = x % y; |
+ return v; |
+} |
+ |
+let strong_funcs = [sub_strong, mul_strong, div_strong, mod_strong]; |
+ |
+function inline_sub_strong(x, y) { |
+ "use strong"; |
+ let v = x - y; |
+ return v; |
+} |
+ |
+function inline_outer(x, y) { |
+ return inline_sub_strong(x, y); |
+} |
+ |
+function inline_sub(x, y) { |
+ let v = x - y; |
+ return v; |
+} |
+ |
+function inline_outer_strong(x, y) { |
+ "use strong"; |
+ return inline_sub(x, y); |
+} |
+ |
+for (let op of strong_arith) { |
+ for (let left of number_values) { |
+ for (let right of number_values) { |
+ let expr = "(" + left + op + right + ")"; |
+ assertEquals(eval(expr), eval("'use strong';" + expr)); |
+ assertDoesNotThrow("'use strong'; " + expr + ";"); |
+ assertDoesNotThrow("'use strong'; let v = " + expr + ";"); |
+ } |
+ } |
+ for (let left of number_values) { |
+ for (let right of nonnumber_values) { |
+ let expr = "(" + left + op + right + ")"; |
+ assertDoesNotThrow("'use strict'; " + expr + ";"); |
+ assertDoesNotThrow("'use strict'; let v = " + expr + ";"); |
+ assertThrows("'use strong'; " + expr + ";", TypeError); |
+ assertThrows("'use strong'; let v = " + expr + ";", TypeError); |
arv (Not doing code reviews)
2015/04/24 14:14:23
These things might be easier to read with template
conradw
2015/04/24 14:42:32
Probably. It doesn't sound like a bad idea for me
|
+ } |
+ } |
+ for (let left of nonnumber_values) { |
+ for (let right of number_values.concat(nonnumber_values)) { |
+ let expr = "(" + left + op + right + ")"; |
+ assertDoesNotThrow("'use strict'; " + expr + ";"); |
+ assertDoesNotThrow("'use strict'; let v = " + expr + ";"); |
+ assertThrows("'use strong'; " + expr + ";", TypeError); |
+ assertThrows("'use strong'; let v = " + expr + ";", TypeError); |
+ } |
+ } |
+} |
+ |
+for (let func of strong_funcs) { |
+ let a = func(4, 5); |
+ let b = func(4, 5); |
+ assertTrue(a === b); |
+ %OptimizeFunctionOnNextCall(func); |
+ let c = func(4, 5); |
+ assertOptimized(func); |
+ assertTrue(b === c); |
+ %DeoptimizeFunction(func); |
+ let d = func(4, 5); |
+ assertTrue(c === d); |
+ %DeoptimizeFunction(func); |
+ %ClearFunctionTypeFeedback(func); |
+} |
+ |
+for (let func of strong_funcs) { |
+ try { |
+ let a = func(2, 3); |
+ let b = func(2, 3); |
+ assertTrue(a === b); |
+ %OptimizeFunctionOnNextCall(func); |
+ let c = func(2, "foo"); |
+ assertUnreachable(); |
+ } catch(e) { |
arv (Not doing code reviews)
2015/04/24 14:14:23
catch (e)
Just like if, for etc
conradw
2015/04/24 14:42:32
followup
|
+ assertTrue(e instanceof TypeError); |
arv (Not doing code reviews)
2015/04/24 14:14:23
or assertInstanceof
conradw
2015/04/24 14:42:32
followup
|
+ assertUnoptimized(func); |
+ assertThrows(function(){func(2, "foo");}, TypeError); |
+ assertDoesNotThrow(function(){func(2, 3);}); |
+ } |
+} |
+ |
+assertThrows(function(){inline_outer(1, {})}, TypeError); |
+for (var i = 0; i < 100; i++) { |
+ inline_outer(1, 2); |
+} |
+assertThrows(function(){inline_outer(1, {})}, TypeError); |
+ |
+assertDoesNotThrow(function(){inline_outer_strong(1, {})}); |
+for (var i = 0; i < 100; i++) { |
+ inline_outer_strong(1, 2); |
+} |
+assertDoesNotThrow(function(){inline_outer_strong(1, {})}); |