1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met: 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Redistributions of source code must retain the above copyright 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer. 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Redistributions in binary form must reproduce the above 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// copyright notice, this list of conditions and the following 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// disclaimer in the documentation and/or other materials provided 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// with the distribution. 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Neither the name of Google Inc. nor the names of its 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// contributors may be used to endorse or promote products derived 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// from this software without specific prior written permission. 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Return the stack frames of an Error object. 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochError.prepareStackTrace = function(error, frames) { 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return frames; 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochError.prototype.getFrames = function() { 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frames = this.stack; 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return frames; 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString.prototype.contains = function(pattern) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return this.indexOf(pattern) > -1; 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check for every frame that a certain method returns the 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// expected value for every frame. 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochArray.prototype.verifyEquals = function(frames, func_name) { 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this.forEach( 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function(element, index) { 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frame = frames[index]; 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (element === null) return; 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assertEquals(element, (frame[func_name])()); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check for every frame that a certain method has a return value 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// that contains the expected pattern for every frame. 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochArray.prototype.verifyContains = function(frames, func_name) { 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this.forEach( 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function(element, index) { 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frame = frames[index]; 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (element === null) return; 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assertTrue((frame[func_name])().contains(element)); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check for every frame that a certain method returns undefined 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// when expected. 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochArray.prototype.verifyUndefined = function(frames, func_name) { 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch this.forEach( 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function(element, index) { 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frame = frames[index]; 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (element === null) return; 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assertEquals(element, (frame[func_name])() === undefined); 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Simple eval. 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar code1 = "function f() { \n" + 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " throw new Error(3); \n" + // Line 2 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "} \n" + 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "f(); \n"; // Line 4 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction g() { 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch eval(code1); 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry { 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g(); 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch (e) { 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect something like 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // f (eval at g (eval-stack.js:87:8), <anonymous>:2:9) 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eval (eval at g (eval-stack.js:87:8), <anonymous>:4:1) 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // g (eval-stack.js:87:3) 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eval-stack.js:94:3 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frames = e.getFrames(); 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assertEquals(4, frames.length); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["f", "eval", "g"] 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyEquals(frames, "getFunctionName"); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [2, 4] 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyEquals(frames, "getLineNumber"); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["<anonymous>:2:", "<anonymous>:4:"] 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyContains(frames, "toString"); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [true, true, false, false] 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyUndefined(frames, "getFileName"); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["eval at g", "eval at g"] 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyContains(frames, "getEvalOrigin"); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Nested eval. 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar code2 = "function h() { \n" + 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " // Empty \n" + 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " eval(code1); \n" + // Line 3 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "} \n" + 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "h(); \n"; // Line 5 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry { 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch eval(code2); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch (e) { 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect something like 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // f (eval at h (eval at <anonymous> (eval-stack.js:116:8)), 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // <anonymous>:2:9) 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eval (eval at h (eval at <anonymous> (eval-stack.js:116:8)), 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // <anonymous>:4:1) 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // h (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:3:3) 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eval (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:5:1) 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eval-stack.js:116:3 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frames = e.getFrames(); 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assertEquals(5, frames.length); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["f", "eval", "h", "eval"] 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyEquals(frames, "getFunctionName"); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [2, 4, 3, 5] 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyEquals(frames, "getLineNumber"); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["<anonymous>:2:", "<anonymous>:4:", "<anonymous>:3:", "<anonymous>:5:"] 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyContains(frames, "toString"); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [true, true, true, true, false] 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyUndefined(frames, "getFileName"); 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["eval at h (eval at <anonymous> (", 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "eval at h (eval at <anonymous> (", 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "eval at <anonymous> (", 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "eval at <anonymous> ("] 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyContains(frames, "getEvalOrigin"); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Nested eval calling through non-eval defined function. 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar code3 = "function h() { \n" + 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " // Empty \n" + 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " g(); \n" + // Line 3 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "} \n" + 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "h(); \n"; // Line 5 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry { 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch eval(code3); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch (e) { 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect something like 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // f (eval at g (test.js:83:8), <anonymous>:2:9) 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eval (eval at g (test.js:83:8), <anonymous>:4:1) 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // g (test.js:83:3) 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // h (eval at <anonymous> (test.js:149:8), <anonymous>:3:3) 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eval (eval at <anonymous> (test.js:149:8), <anonymous>:5:1) 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // test.js:149:3 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frames = e.getFrames(); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assertEquals(6, frames.length); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["f", "eval", "g", "h", "eval"] 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyEquals(frames, "getFunctionName"); 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [2, 4, null, 3, 5] 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyEquals(frames, "getLineNumber"); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["<anonymous>:2:", "<anonymous>:4:", null, "<anonymous>:3:", "<anonymous>:5:"] 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyContains(frames, "toString"); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [true, true, false, true, true, false] 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyUndefined(frames, "getFileName"); 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["eval at g (", 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "eval at g (", 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch null, 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "eval at <anonymous> (", 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "eval at <anonymous> ("] 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch .verifyContains(frames, "getEvalOrigin"); 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Calling function defined in eval. 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdocheval("function f() { \n" + 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " throw new Error(3); \n" + 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "} \n"); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry { 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f(); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch (e) { 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We expect something like 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // f (eval at <anonymous> (test.js:182:40), <anonymous>:2:9) 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // test.js:186:3 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch var frames = e.getFrames(); 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assertEquals(2, frames.length); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["f"].verifyEquals(frames, "getFunctionName"); 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [2].verifyEquals(frames, "getLineNumber"); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["<anonymous>:2:"].verifyContains(frames, "toString"); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [true, false].verifyUndefined(frames, "getFileName"); 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ["eval at <anonymous> ("].verifyContains(frames, "getEvalOrigin"); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 204