|  | // 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"); |