10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Copyright 2012 the V8 project authors. All rights reserved.
20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Redistribution and use in source and binary forms, with or without
30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// modification, are permitted provided that the following conditions are
40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// met:
50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     * Redistributions of source code must retain the above copyright
70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       notice, this list of conditions and the following disclaimer.
80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     * Redistributions in binary form must reproduce the above
90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       copyright notice, this list of conditions and the following
100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       disclaimer in the documentation and/or other materials provided
110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       with the distribution.
120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//     * Neither the name of Google Inc. nor the names of its
130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       contributors may be used to endorse or promote products derived
140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//       from this software without specific prior written permission.
150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Return the stack frames of an Error object.
290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongError.prepareStackTrace = function(error, frames) {
310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  return frames;
3279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez}
3379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
3479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezError.prototype.getFrames = function() {
351d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  var frames = this.stack;
361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  return frames;
370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongString.prototype.contains = function(pattern) {
400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  return this.indexOf(pattern) > -1;
410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Check for every frame that a certain method returns the
440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// expected value for every frame.
450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongArray.prototype.verifyEquals = function(frames, func_name) {
460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  this.forEach(
470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    function(element, index) {
480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      var frame = frames[index];
490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      if (element === null) return;
500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      assertEquals(element, (frame[func_name])());
510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  );
530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Check for every frame that a certain method has a return value
560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// that contains the expected pattern for every frame.
570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongArray.prototype.verifyContains = function(frames, func_name) {
580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  this.forEach(
590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    function(element, index) {
600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      var frame = frames[index];
610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      if (element === null) return;
620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      assertTrue((frame[func_name])().contains(element));
630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  );
650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Check for every frame that a certain method returns undefined
680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// when expected.
690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongArray.prototype.verifyUndefined = function(frames, func_name) {
700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  this.forEach(
710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    function(element, index) {
720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      var frame = frames[index];
730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      if (element === null) return;
740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      assertEquals(element, (frame[func_name])() === undefined);
750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong    }
760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  );
770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Simple eval.
810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvar code1 = "function f() {        \n" +
820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "  throw new Error(3); \n" +  // Line 2
830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "}                     \n" +
840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "f();                  \n";   // Line 4
850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongfunction g() {
870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  eval(code1);
880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtry {
910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  g();
920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} catch (e) {
930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // We expect something like
940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   f (eval at g (eval-stack.js:87:8), <anonymous>:2:9)
950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   eval (eval at g (eval-stack.js:87:8), <anonymous>:4:1)
960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   g (eval-stack.js:87:3)
970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   eval-stack.js:94:3
980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  var frames = e.getFrames();
990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  assertEquals(4, frames.length);
1000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["f", "eval", "g"]
1010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyEquals(frames, "getFunctionName");
1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [2, 4]
1030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyEquals(frames, "getLineNumber");
1040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["<anonymous>:2:", "<anonymous>:4:"]
1050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyContains(frames, "toString");
1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [true, true, false, false]
1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyUndefined(frames, "getFileName");
1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["eval at g", "eval at g"]
1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyContains(frames, "getEvalOrigin");
1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Nested eval.
1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvar code2 = "function h() {        \n" +
1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "  // Empty            \n" +
1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "  eval(code1);        \n" +  // Line 3
1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "}                     \n" +
1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "h();                  \n";   // Line 5
1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtry {
1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  eval(code2);
1220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} catch (e) {
1230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // We expect something like
1240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   f (eval at h (eval at <anonymous> (eval-stack.js:116:8)),
1250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //       <anonymous>:2:9)
1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   eval (eval at h (eval at <anonymous> (eval-stack.js:116:8)),
1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //       <anonymous>:4:1)
1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   h (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:3:3)
1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   eval (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:5:1)
1300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   eval-stack.js:116:3
1310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  var frames = e.getFrames();
1320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  assertEquals(5, frames.length);
1330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["f", "eval", "h", "eval"]
1340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyEquals(frames, "getFunctionName");
1350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [2, 4, 3, 5]
1360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyEquals(frames, "getLineNumber");
1370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["<anonymous>:2:", "<anonymous>:4:", "<anonymous>:3:", "<anonymous>:5:"]
1380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyContains(frames, "toString");
1390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [true, true, true, true, false]
1400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyUndefined(frames, "getFileName");
1410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["eval at h (eval at <anonymous> (",
1420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong   "eval at h (eval at <anonymous> (",
1430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong   "eval at <anonymous> (",
1440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong   "eval at <anonymous> ("]
1450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyContains(frames, "getEvalOrigin");
1460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
1470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Nested eval calling through non-eval defined function.
1500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvar code3 = "function h() {        \n" +
1510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "  // Empty            \n" +
1520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "  g();                \n" +  // Line 3
1530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "}                     \n" +
1540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong            "h();                  \n";   // Line 5
1550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtry {
1570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  eval(code3);
1580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} catch (e) {
1590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // We expect something like
1600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   f (eval at g (test.js:83:8), <anonymous>:2:9)
1610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   eval (eval at g (test.js:83:8), <anonymous>:4:1)
1620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   g (test.js:83:3)
1630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   h (eval at <anonymous> (test.js:149:8), <anonymous>:3:3)
1640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   eval (eval at <anonymous> (test.js:149:8), <anonymous>:5:1)
1650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   test.js:149:3
1660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  var frames = e.getFrames();
1670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  assertEquals(6, frames.length);
1680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["f", "eval", "g", "h", "eval"]
1690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyEquals(frames, "getFunctionName");
1700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [2, 4, null, 3, 5]
1710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyEquals(frames, "getLineNumber");
1720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["<anonymous>:2:", "<anonymous>:4:", null, "<anonymous>:3:", "<anonymous>:5:"]
1730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyContains(frames, "toString");
1740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [true, true, false, true, true, false]
1750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyUndefined(frames, "getFileName");
1760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["eval at g (",
1770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong   "eval at g (",
1780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong   null,
1790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong   "eval at <anonymous> (",
1800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong   "eval at <anonymous> ("]
1810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong      .verifyContains(frames, "getEvalOrigin");
1820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
1830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Calling function defined in eval.
1860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongeval("function f() {               \n" +
1870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong     "  throw new Error(3);        \n" +
1880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong     "}                            \n");
1890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongtry {
1910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  f();
1920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} catch (e) {
1930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // We expect something like
1940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   f (eval at <anonymous> (test.js:182:40), <anonymous>:2:9)
1950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  //   test.js:186:3
1960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  var frames = e.getFrames();
1970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  assertEquals(2, frames.length);
1980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["f"].verifyEquals(frames, "getFunctionName");
1990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [2].verifyEquals(frames, "getLineNumber");
2000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["<anonymous>:2:"].verifyContains(frames, "toString");
2010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  [true, false].verifyUndefined(frames, "getFileName");
2020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ["eval at <anonymous> ("].verifyContains(frames, "getEvalOrigin");
2030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}
2040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong