| // Copyright 2009 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. |
| // Testing basic functionality of the arguments object. |
| // Introduced to ensure that the fast compiler does the right thing. |
| // The arguments object itself. |
| assertEquals(42, function(){ return arguments;}(42)[0], |
| "return arguments value"); |
| assertEquals(42, function(){ return arguments;}(42)[0], |
| "arguments in plain value context"); |
| assertEquals(42, function(){ arguments;return 42}(37), |
| "arguments in effect context"); |
| assertEquals(42, function(){ if(arguments)return 42;}(), |
| "arguments in a boolean context"); |
| assertEquals(42, function(){ return arguments || true;}(42)[0], |
| "arguments in a short-circuit boolean context - or"); |
| assertEquals(true, function(){ return arguments && [true];}(42)[0], |
| "arguments in a short-circuit boolean context - and"); |
| assertEquals(42, function(){ arguments = 42; return 42;}(), |
| "arguments assignment"); |
| // Properties of the arguments object. |
| assertEquals(42, function(){ return arguments[0]; }(42), |
| "args[0] value returned"); |
| assertEquals(42, function(){ arguments[0]; return 42}(), |
| "args[0] value ignored"); |
| assertEquals(42, function(){ if (arguments[0]) return 42; }(37), |
| "args[0] to boolean"); |
| assertEquals(42, function(){ return arguments[0] || "no"; }(42), |
| "args[0] short-circuit boolean or true"); |
| assertEquals(42, function(){ return arguments[0] || 42; }(0), |
| "args[0] short-circuit boolean or false"); |
| assertEquals(37, function(){ return arguments[0] && 37; }(42), |
| "args[0] short-circuit boolean and true"); |
| assertEquals(0, function(){ return arguments[0] && 42; }(0), |
| "args[0] short-circuit boolean and false"); |
| assertEquals(42, function(){ arguments[0] = 42; return arguments[0]; }(37), |
| "args[0] assignment"); |
| // Link between arguments and parameters. |
| assertEquals(42, function(a) { arguments[0] = 42; return a; }(37), |
| "assign args[0]->a"); |
| assertEquals(42, function(a) { a = 42; return arguments[0]; }(37), |
| "assign a->args[0]"); |
| assertEquals(54, function(a, b) { arguments[1] = 54; return b; }(42, 37), |
| "assign args[1]->b:b"); |
| assertEquals(54, function(a, b) { b = 54; return arguments[1]; }(42, 47), |
| "assign b->args[1]:b"); |
| assertEquals(42, function(a, b) { arguments[1] = 54; return a; }(42, 37), |
| "assign args[1]->b:a"); |
| assertEquals(42, function(a, b) { b = 54; return arguments[0]; }(42, 47), |
| "assign b->args[1]:a"); |
| |
| // Capture parameters in nested contexts. |
| assertEquals(33, |
| function(a,b) { |
| return a + arguments[0] + |
| function(b){ return a + b + arguments[0]; }(b); }(7,6), |
| "captured parameters"); |
| assertEquals(42, function(a) { |
| arguments[0] = 42; |
| return function(b){ return a; }(); |
| }(37), |
| "capture value returned"); |
| assertEquals(42, |
| function(a) { |
| arguments[0] = 26; |
| return function(b){ a; return 42; }(); |
| }(37), |
| "capture value ignored"); |
| assertEquals(42, |
| function(a) { |
| arguments[0] = 26; |
| return function(b){ if (a) return 42; }(); |
| }(37), |
| "capture to boolean"); |
| assertEquals(42, |
| function(a) { |
| arguments[0] = 42; |
| return function(b){ return a || "no"; }(); |
| }(37), |
| "capture short-circuit boolean or true"); |
| assertEquals(0, |
| function(a) { |
| arguments[0] = 0; |
| return function(b){ return a && 42; }(); |
| }(37), |
| "capture short-circuit boolean and false"); |
| // Deeply nested. |
| assertEquals(42, |
| function(a,b) { |
| return arguments[2] + |
| function(){ |
| return b + |
| function() { |
| return a; |
| }(); |
| }(); |
| }(7,14,21), |
| "deep nested capture"); |
| |
| // Assignment to captured parameters. |
| assertEquals(42, function(a,b) { |
| arguments[1] = 11; |
| return a + function(){ a = b; return a; }() + a; |
| }(20, 37), "captured assignment"); |
| |
| // Inside non-function scopes. |
| assertEquals(42, |
| function(a) { |
| arguments[0] = 20; |
| with ({ b : 22 }) { return a + b; } |
| }(37), |
| "a in with"); |
| assertEquals(42, |
| function(a) { |
| with ({ b : 22 }) { return arguments[0] + b; } |
| }(20), |
| "args in with"); |
| assertEquals(42, |
| function(a) { |
| arguments[0] = 20; |
| with ({ b : 22 }) { |
| return function() { return a; }() + b; } |
| }(37), |
| "captured a in with"); |
| assertEquals(42, |
| function(a) { |
| arguments[0] = 12; |
| with ({ b : 22 }) { |
| return function f() { |
| try { throw 8 } catch(e) { return e + a }; |
| }() + b; |
| } |
| }(37), |
| "in a catch in a named function captured a in with "); |
| // Escaping arguments. |
| function weirdargs(a,b,c) { if (!a) return arguments; |
| return [b[2],c]; } |
| var args1 = weirdargs(false, null, 40); |
| var res = weirdargs(true, args1, 15); |
| assertEquals(40, res[0], "return old args element"); |
| assertEquals(15, res[1], "return own args element"); |