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