Index: test/mjsunit/strict-mode-implicit-receiver.js |
diff --git a/test/mjsunit/strict-mode-implicit-receiver.js b/test/mjsunit/strict-mode-implicit-receiver.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..65cefb5f332ec13755fe4f1272c7db3973763bf4 |
--- /dev/null |
+++ b/test/mjsunit/strict-mode-implicit-receiver.js |
@@ -0,0 +1,176 @@ |
+// Copyright 2011 the V8 project authors. All rights reserved. |
+// Redistribution and use in source and binary forms, with or without |
+// modification, are permitted provided that the following conditions are |
+// met: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following |
+// disclaimer in the documentation and/or other materials provided |
+// with the distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived |
+// from this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+// Flags: --allow-natives-syntax |
+ |
+var y = 3; |
+ |
+function get_y() { return this.y; } |
+function strict_get_y() { "use strict"; return this.y; } |
+ |
+// Test calls to strict mode function as methods. |
+for (var i = 0; i < 10; i++) assertEquals(3, strict_get_y.call(this)); |
+var o = { y: 42 }; |
+for (var i = 0; i < 10; i++) assertEquals(42, strict_get_y.call(o)); |
+ |
+// Test calls to strict mode function with implicit receiver. |
+function g() { |
+ var exception = false; |
+ try { strict_get_y(); } catch(e) { exception = true; } |
+ assertTrue(exception); |
+} |
+for (var i = 0; i < 3; i++) g(); |
+ |
+// Test calls to local strict mode function with implicit receiver. |
+function local_function_test() { |
+ function get_y() { return this.y; } |
+ function strict_get_y() { "use strict"; return this.y; } |
+ assertEquals(3, get_y()); |
+ assertEquals(3, get_y(23)); |
+ var exception = false; |
+ try { |
+ strict_get_y(); |
+ } catch(e) { |
+ exception = true; |
+ } |
+ assertTrue(exception); |
+} |
+ |
+for (var i = 0; i < 10; i++) { |
+ local_function_test(); |
+} |
+ |
+// Test call to catch variable strict-mode function. Implicit |
+// receiver. |
+var exception = false; |
+try { |
+ throw strict_get_y; |
+} catch(f) { |
+ try { |
+ f(); |
+ } catch(e) { |
+ exception = true; |
+ } |
+ assertTrue(exception); |
+} |
+ |
+ |
+// Test calls to strict-mode function with the object from a with |
+// statement as the receiver. |
+with(this) { |
+ assertEquals(3, strict_get_y()); |
+ assertEquals(3, strict_get_y(32)); |
+} |
+ |
+var o = { y: 27 }; |
+o.f = strict_get_y; |
+with(o) { |
+ assertEquals(27, f()); |
+ assertEquals(27, f(23)); |
+} |
+ |
+ |
+// Check calls to eval within a function with 'undefined' as receiver. |
+function implicit_receiver_eval() { |
+ "use strict"; |
+ return eval("this"); |
+} |
+ |
+assertEquals(void 0, implicit_receiver_eval()); |
+assertEquals(void 0, implicit_receiver_eval(32)); |
+ |
+ |
+// Strict mode function to get inlined. |
+function strict_return_receiver() { |
+ "use strict"; |
+ return this; |
+} |
+ |
+// Inline with implicit receiver. |
+function g() { |
+ return strict_return_receiver(); |
+} |
+ |
+for (var i = 0; i < 5; i++) { |
+ assertEquals(void 0, g()); |
+ assertEquals(void 0, g(42)); |
+} |
+%OptimizeFunctionOnNextCall(g); |
+assertEquals(void 0, g(42)); |
+assertEquals(void 0, g()); |
+ |
+// Inline with explicit receiver. |
+function g2() { |
+ var o = {}; |
+ o.f = strict_return_receiver; |
+ return o.f(); |
+} |
+ |
+for (var i = 0; i < 5; i++) { |
+ assertTrue(typeof g2() == "object"); |
+ assertTrue(typeof g2(42) == "object"); |
+} |
+%OptimizeFunctionOnNextCall(g2); |
+assertTrue(typeof g2() == "object"); |
+assertTrue(typeof g2(42) == "object"); |
+ |
+// Test calls of aliased eval. |
+function outer_eval_receiver() { |
+ var eval = function() { return this; } |
+ function inner_strict() { |
+ "use strict"; |
+ assertEquals('object', typeof eval()); |
+ } |
+ inner_strict(); |
+} |
+outer_eval_receiver(); |
+ |
+function outer_eval_conversion3(eval, expected) { |
+ function inner_strict() { |
+ "use strict"; |
+ var x = eval("this"); |
+ assertEquals(expected, typeof x); |
+ } |
+ inner_strict(); |
+} |
+ |
+function strict_return_this() { "use strict"; return this; } |
+function return_this() { return this; } |
+function strict_eval(s) { "use strict"; return eval(s); } |
+function non_strict_eval(s) { return eval(s); } |
+ |
+outer_eval_conversion3(strict_return_this, 'undefined'); |
+outer_eval_conversion3(return_this, 'object'); |
+outer_eval_conversion3(strict_eval, 'undefined'); |
+outer_eval_conversion3(non_strict_eval, 'object'); |
+ |
+// TODO(ager): I'm not sure this is in accordance with the spec. At |
+// the moment, any call to eval where eval is not bound in the global |
+// context is treated as an indirect call to eval which means that the |
+// global context is used and the global object is passed as the |
+// receiver. |
+outer_eval_conversion3(eval, 'object'); |