<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[214289] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/214289">214289</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2017-03-22 18:14:06 -0700 (Wed, 22 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for Error.stackTraceLimit.
https://bugs.webkit.org/show_bug.cgi?id=169904

Reviewed by Saam Barati.

JSTests:

* stress/error-stack-trace-limit.js: Added.

Source/JavaScriptCore:

Since there's no standard for this yet, we'll implement Error.stackTraceLimit
based on how Chrome does it.  This includes some idiosyncrasies like:
1. If we set Error.stackTraceLimit = 0, then new Error().stack yields an empty
   stack trace (Chrome has a title with no stack frame entries).
2. If we set Error.stackTraceLimit = {] (i.e. to a non-number value), then
   new Error().stack is undefined.

Chrome and IE defaults their Error.stackTraceLimit to 10.  We'll default ours to
100 because 10 may be a bit too skimpy and it is not that costly to allow up to
100 frames instead of 10.

The default value for Error.stackTraceLimit is specified by
Options::defaultErrorStackTraceLimit().

Also, the Exception object now limits the number of stack trace frames it captures
to the limit specified by Options::exceptionStackTraceLimit().

Note: the Exception object captures a stack trace that is not necessarily the
same as the one in an Error object being thrown:

- The Error object captures the stack trace at the point of object creation.

- The Exception object captures the stack trace at the point that the exception
  is thrown.  This stack trace is captured even when throwing a value that is not
  an Error object e.g. a primitive value.  The Exception object stack trace is
  only used by WebInspector to identify where a value is thrown from.  Hence,
  it does not necessary make sense the Exception object stack trace limited by
  Error.stackTraceLimit.  Instead, we have it use own Options::exceptionStackTraceLimit().

* interpreter/Interpreter.cpp:
(JSC::Interpreter::unwind):
* jsc.cpp:
(dumpException):
* runtime/CommonIdentifiers.h:
* runtime/Error.cpp:
(JSC::addErrorInfoAndGetBytecodeOffset):
* runtime/ErrorConstructor.cpp:
(JSC::ErrorConstructor::finishCreation):
(JSC::ErrorConstructor::put):
(JSC::ErrorConstructor::deleteProperty):
* runtime/ErrorConstructor.h:
(JSC::ErrorConstructor::stackTraceLimit):
* runtime/Exception.cpp:
(JSC::Exception::finishCreation):
* runtime/Options.h:

LayoutTests:

Rebased test.

* js/Object-getOwnPropertyNames-expected.txt:
* js/script-tests/Object-getOwnPropertyNames.js:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt">trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs">trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonIdentifiersh">trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeErrorcpp">trunk/Source/JavaScriptCore/runtime/Error.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeErrorConstructorcpp">trunk/Source/JavaScriptCore/runtime/ErrorConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeErrorConstructorh">trunk/Source/JavaScriptCore/runtime/ErrorConstructor.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeExceptioncpp">trunk/Source/JavaScriptCore/runtime/Exception.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstresserrorstacktracelimitjs">trunk/JSTests/stress/error-stack-trace-limit.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/JSTests/ChangeLog        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2017-03-22  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Add support for Error.stackTraceLimit.
+        https://bugs.webkit.org/show_bug.cgi?id=169904
+
+        Reviewed by Saam Barati.
+
+        * stress/error-stack-trace-limit.js: Added.
+
</ins><span class="cx"> 2017-03-22  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Use jsNontrivialString for Number toString operations
</span></span></pre></div>
<a id="trunkJSTestsstresserrorstacktracelimitjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/error-stack-trace-limit.js (0 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/error-stack-trace-limit.js                                (rev 0)
+++ trunk/JSTests/stress/error-stack-trace-limit.js        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+function assert(testID, b) {
+    if (!b)
+        throw new Error(&quot;FAILED test &quot; + testID);
+}
+
+function assertEquals(testID, a, b) {
+    assert(testID, a == b);
+}
+
+var desc = Object.getOwnPropertyDescriptor(Error, &quot;stackTraceLimit&quot;);
+
+assertEquals(100, typeof desc.value, &quot;number&quot;);
+assertEquals(200, desc.writable, true);
+assertEquals(300, desc.enumerable, true);
+assertEquals(400, desc.configurable, true);
+assertEquals(500, desc.get, undefined);
+assertEquals(600, desc.set, undefined);
+
+function recurse(x) {
+    if (x)
+        recurse(x - 1);
+    else
+        throw Error();
+}
+
+function numberOfFrames(str) {
+    if (str == &quot;&quot;)
+        return 0;
+    var lines = str.split(/\r\n|\r|\n/);
+    // note: Chrome always prints a header line. So, for Chrome, use lines.length - 1.
+    return lines.length;
+}
+
+var exception = undefined;
+
+function testLimit(testID, updateLimit, reentryCount, expectedLimit, expectedNumberOfFrames) {
+    exception = undefined;
+    updateLimit();
+    assertEquals(testID, Error.stackTraceLimit, expectedLimit);
+
+    try {
+        recurse(reentryCount);
+    } catch (e) {
+        exception = e;
+    }
+
+    assertEquals(testID + 1, exception, &quot;Error&quot;);
+    if (typeof expectedNumberOfFrames == &quot;undefined&quot;)
+        assertEquals(testID + 2, exception.stack, undefined);
+    else
+        assertEquals(testID + 3, numberOfFrames(exception.stack), expectedNumberOfFrames);
+}
+
+testLimit(1000, () =&gt; { Error.stackTraceLimit = 0 }, 1000, 0, 0);
+// note: Chrome always prints a header line. So, Chrome expects &quot;Error&quot; here.
+assertEquals(1100, exception.stack, &quot;&quot;);
+
+testLimit(2000, () =&gt; { Error.stackTraceLimit = 10 }, 1000, 10, 10);
+testLimit(3000, () =&gt; { Error.stackTraceLimit = 100 }, 1000, 100, 100);
+testLimit(4000, () =&gt; { Error.stackTraceLimit = 1000 }, 1000, 1000, 1000);
+
+// expectedNumberOfFrames includes (1) global + (2) testLimit + (3) 1000 recursion of
+// recurse() + (4) recurse() which discovered x == 0 i.e. expectedNumberOfFrames == 1003.
+testLimit(5000, () =&gt; { Error.stackTraceLimit = 2000 }, 1000, 2000, 1003);
+
+var value = { };
+testLimit(6000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = { valueOf() { return 5 } };
+testLimit(7000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = [ 1, 2, 3 ];
+testLimit(8000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = &quot;hello&quot;;
+testLimit(9000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = Symbol(&quot;hello&quot;);
+testLimit(10000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = true;
+testLimit(11000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = false;
+testLimit(12000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = undefined;
+testLimit(13000, () =&gt; { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+testLimit(14000, () =&gt; { Error.stackTraceLimit = 10 }, 1000, 10, 10);
+
+testLimit(15000, () =&gt; { delete Error.stackTraceLimit; }, 1000, undefined, undefined);
+
+testLimit(16000, () =&gt; { Error.stackTraceLimit = 10 }, 1000, 10, 10);
</ins></span></pre></div>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/LayoutTests/ChangeLog        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2017-03-22  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Add support for Error.stackTraceLimit.
+        https://bugs.webkit.org/show_bug.cgi?id=169904
+
+        Reviewed by Saam Barati.
+
+        Rebased test.
+
+        * js/Object-getOwnPropertyNames-expected.txt:
+        * js/script-tests/Object-getOwnPropertyNames.js:
+
</ins><span class="cx"> 2017-03-22  Carlos Alberto Lopez Perez  &lt;clopez@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Update layout test expectations file.
</span></span></pre></div>
<a id="trunkLayoutTestsjsObjectgetOwnPropertyNamesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx"> PASS getSortedOwnPropertyNames(Date.prototype) is ['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']
</span><span class="cx"> PASS getSortedOwnPropertyNames(RegExp) is ['$&amp;', &quot;$'&quot;, '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']
</span><span class="cx"> PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'flags', 'global', 'ignoreCase', 'multiline', 'source', 'sticky', 'test', 'toString', 'unicode']
</span><del>-PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype']
</del><ins>+PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype', 'stackTraceLimit']
</ins><span class="cx"> PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
</span><span class="cx"> PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
</span><span class="cx"> PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsObjectgetOwnPropertyNamesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">     &quot;Date.prototype&quot;: &quot;['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']&quot;,
</span><span class="cx">     &quot;RegExp&quot;: &quot;['$&amp;', \&quot;$'\&quot;, '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']&quot;,
</span><span class="cx">     &quot;RegExp.prototype&quot;: &quot;['compile', 'constructor', 'exec', 'flags', 'global', 'ignoreCase', 'multiline', 'source', 'sticky', 'test', 'toString', 'unicode']&quot;,
</span><del>-    &quot;Error&quot;: &quot;['length', 'name', 'prototype']&quot;,
</del><ins>+    &quot;Error&quot;: &quot;['length', 'name', 'prototype', 'stackTraceLimit']&quot;,
</ins><span class="cx">     &quot;Error.prototype&quot;: &quot;['constructor', 'message', 'name', 'toString']&quot;,
</span><span class="cx">     &quot;Math&quot;: &quot;['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']&quot;,
</span><span class="cx">     &quot;JSON&quot;: &quot;['parse', 'stringify']&quot;,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,3 +1,56 @@
</span><ins>+2017-03-22  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Add support for Error.stackTraceLimit.
+        https://bugs.webkit.org/show_bug.cgi?id=169904
+
+        Reviewed by Saam Barati.
+
+        Since there's no standard for this yet, we'll implement Error.stackTraceLimit
+        based on how Chrome does it.  This includes some idiosyncrasies like:
+        1. If we set Error.stackTraceLimit = 0, then new Error().stack yields an empty
+           stack trace (Chrome has a title with no stack frame entries).
+        2. If we set Error.stackTraceLimit = {] (i.e. to a non-number value), then
+           new Error().stack is undefined.
+
+        Chrome and IE defaults their Error.stackTraceLimit to 10.  We'll default ours to
+        100 because 10 may be a bit too skimpy and it is not that costly to allow up to
+        100 frames instead of 10.
+
+        The default value for Error.stackTraceLimit is specified by
+        Options::defaultErrorStackTraceLimit().
+
+        Also, the Exception object now limits the number of stack trace frames it captures
+        to the limit specified by Options::exceptionStackTraceLimit().
+
+        Note: the Exception object captures a stack trace that is not necessarily the
+        same as the one in an Error object being thrown:
+
+        - The Error object captures the stack trace at the point of object creation.
+
+        - The Exception object captures the stack trace at the point that the exception
+          is thrown.  This stack trace is captured even when throwing a value that is not
+          an Error object e.g. a primitive value.  The Exception object stack trace is
+          only used by WebInspector to identify where a value is thrown from.  Hence,
+          it does not necessary make sense the Exception object stack trace limited by
+          Error.stackTraceLimit.  Instead, we have it use own Options::exceptionStackTraceLimit().
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::unwind):
+        * jsc.cpp:
+        (dumpException):
+        * runtime/CommonIdentifiers.h:
+        * runtime/Error.cpp:
+        (JSC::addErrorInfoAndGetBytecodeOffset):
+        * runtime/ErrorConstructor.cpp:
+        (JSC::ErrorConstructor::finishCreation):
+        (JSC::ErrorConstructor::put):
+        (JSC::ErrorConstructor::deleteProperty):
+        * runtime/ErrorConstructor.h:
+        (JSC::ErrorConstructor::stackTraceLimit):
+        * runtime/Exception.cpp:
+        (JSC::Exception::finishCreation):
+        * runtime/Options.h:
+
</ins><span class="cx"> 2017-03-22  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Use jsNontrivialString for Number toString operations
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -682,7 +682,7 @@
</span><span class="cx">     if (exceptionValue.isEmpty() || (exceptionValue.isCell() &amp;&amp; !exceptionValue.asCell()))
</span><span class="cx">         exceptionValue = jsNull();
</span><span class="cx"> 
</span><del>-    ASSERT_UNUSED(scope, scope.exception() &amp;&amp; scope.exception()-&gt;stack().size());
</del><ins>+    ASSERT_UNUSED(scope, scope.exception() &amp;&amp; (!Options::exceptionStackTraceLimit() || scope.exception()-&gt;stack().size()));
</ins><span class="cx"> 
</span><span class="cx">     // Calculate an exception handler vPC, unwinding call frames as necessary.
</span><span class="cx">     HandlerInfo* handler = nullptr;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -3350,8 +3350,11 @@
</span><span class="cx">             lineNumberValue.toWTFString(globalObject-&gt;globalExec()).utf8().data());
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (!stackValue.isUndefinedOrNull())
-        printf(&quot;%s\n&quot;, stackValue.toWTFString(globalObject-&gt;globalExec()).utf8().data());
</del><ins>+    if (!stackValue.isUndefinedOrNull()) {
+        auto stackString = stackValue.toWTFString(globalObject-&gt;globalExec());
+        if (stackString.length())
+            printf(&quot;%s\n&quot;, stackString.utf8().data());
+    }
</ins><span class="cx"> 
</span><span class="cx"> #undef CHECK_EXCEPTION
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonIdentifiersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2003, 2007, 2009, 2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -281,6 +281,7 @@
</span><span class="cx">     macro(sourceCode) \
</span><span class="cx">     macro(sourceURL) \
</span><span class="cx">     macro(stack) \
</span><ins>+    macro(stackTraceLimit) \
</ins><span class="cx">     macro(sticky) \
</span><span class="cx">     macro(subarray) \
</span><span class="cx">     macro(summary) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeErrorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Error.cpp (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Error.cpp        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/runtime/Error.cpp        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003-2006, 2008, 2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -157,10 +157,14 @@
</span><span class="cx"> 
</span><span class="cx"> bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM&amp; vm, JSObject* obj, bool useCurrentFrame, CallFrame*&amp; callFrame, unsigned* bytecodeOffset)
</span><span class="cx"> {
</span><ins>+    JSGlobalObject* globalObject = obj-&gt;globalObject();
+    ErrorConstructor* errorConstructor = globalObject-&gt;errorConstructor();
+    if (!errorConstructor-&gt;stackTraceLimit())
+        return false;
+
</ins><span class="cx">     Vector&lt;StackFrame&gt; stackTrace = Vector&lt;StackFrame&gt;();
</span><del>-
</del><span class="cx">     size_t framesToSkip = useCurrentFrame ? 0 : 1;
</span><del>-    vm.interpreter-&gt;getStackTrace(stackTrace, framesToSkip);
</del><ins>+    vm.interpreter-&gt;getStackTrace(stackTrace, framesToSkip, errorConstructor-&gt;stackTraceLimit().value());
</ins><span class="cx">     if (!stackTrace.isEmpty()) {
</span><span class="cx"> 
</span><span class="cx">         ASSERT(exec == vm.topCallFrame || exec == exec-&gt;lexicalGlobalObject()-&gt;globalExec() || exec == exec-&gt;vmEntryGlobalObject()-&gt;globalExec());
</span><span class="lines">@@ -196,6 +200,8 @@
</span><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><ins>+
+    obj-&gt;putDirect(vm, vm.propertyNames-&gt;stack, vm.smallStrings.emptyString(), DontEnum);
</ins><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeErrorConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ErrorConstructor.cpp (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ErrorConstructor.cpp        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/runtime/ErrorConstructor.cpp        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2003, 2008, 2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -44,6 +44,10 @@
</span><span class="cx">     // ECMA 15.11.3.1 Error.prototype
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
</span><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;length, jsNumber(1), DontEnum | ReadOnly);
</span><ins>+
+    unsigned defaultStackTraceLimit = Options::defaultErrorStackTraceLimit();
+    m_stackTraceLimit = defaultStackTraceLimit;
+    putDirectWithoutTransition(vm, vm.propertyNames-&gt;stackTraceLimit, jsNumber(defaultStackTraceLimit), None);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // ECMA 15.9.3
</span><span class="lines">@@ -78,4 +82,33 @@
</span><span class="cx">     return CallType::Host;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool ErrorConstructor::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot&amp; slot)
+{
+    VM&amp; vm = exec-&gt;vm();
+    ErrorConstructor* thisObject = jsCast&lt;ErrorConstructor*&gt;(cell);
+
+    if (propertyName == vm.propertyNames-&gt;stackTraceLimit) {
+        if (value.isNumber()) {
+            double effectiveLimit = value.asNumber();
+            effectiveLimit = std::max(0., effectiveLimit);
+            effectiveLimit = std::min(effectiveLimit, static_cast&lt;double&gt;(std::numeric_limits&lt;unsigned&gt;::max()));
+            thisObject-&gt;m_stackTraceLimit = static_cast&lt;unsigned&gt;(effectiveLimit);
+        } else
+            thisObject-&gt;m_stackTraceLimit = { };
+    }
+
+    return Base::put(thisObject, exec, propertyName, value, slot);
+}
+
+bool ErrorConstructor::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
+{
+    VM&amp; vm = exec-&gt;vm();
+    ErrorConstructor* thisObject = jsCast&lt;ErrorConstructor*&gt;(cell);
+
+    if (propertyName == vm.propertyNames-&gt;stackTraceLimit)
+        thisObject-&gt;m_stackTraceLimit = { };
+
+    return Base::deleteProperty(thisObject, exec, propertyName);
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeErrorConstructorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ErrorConstructor.h (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ErrorConstructor.h        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/runtime/ErrorConstructor.h        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2008-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -46,13 +46,20 @@
</span><span class="cx">         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    std::optional&lt;unsigned&gt; stackTraceLimit() const { return m_stackTraceLimit; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     void finishCreation(VM&amp;, ErrorPrototype*);
</span><del>-        
</del><ins>+
+    static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&amp;);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+
</ins><span class="cx"> private:
</span><span class="cx">     ErrorConstructor(VM&amp;, Structure*);
</span><span class="cx">     static ConstructType getConstructData(JSCell*, ConstructData&amp;);
</span><span class="cx">     static CallType getCallData(JSCell*, CallData&amp;);
</span><ins>+
+    std::optional&lt;unsigned&gt; m_stackTraceLimit;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeExceptioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Exception.cpp (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Exception.cpp        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/runtime/Exception.cpp        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;StackFrame&gt; stackTrace;
</span><span class="cx">     if (action == StackCaptureAction::CaptureStack)
</span><del>-        vm.interpreter-&gt;getStackTrace(stackTrace);
</del><ins>+        vm.interpreter-&gt;getStackTrace(stackTrace, 0, Options::exceptionStackTraceLimit());
</ins><span class="cx">     m_stack = WTFMove(stackTrace);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (214288 => 214289)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2017-03-23 00:57:27 UTC (rev 214288)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2017-03-23 01:14:06 UTC (rev 214289)
</span><span class="lines">@@ -376,6 +376,8 @@
</span><span class="cx">     v(bool, verifyHeap, false, Normal, nullptr) \
</span><span class="cx">     v(unsigned, numberOfGCCyclesToRecordForVerification, 3, Normal, nullptr) \
</span><span class="cx">     \
</span><ins>+    v(unsigned, exceptionStackTraceLimit, 100, Normal, &quot;Stack trace limit for internal Exception object&quot;) \
+    v(unsigned, defaultErrorStackTraceLimit, 100, Normal, &quot;The default value for Error.stackTraceLimit&quot;) \
</ins><span class="cx">     v(bool, useExceptionFuzz, false, Normal, nullptr) \
</span><span class="cx">     v(unsigned, fireExceptionFuzzAt, 0, Normal, nullptr) \
</span><span class="cx">     v(bool, validateDFGExceptionHandling, false, Normal, &quot;Causes the DFG to emit code validating exception handling for each node that can exit&quot;) /* This is true by default on Debug builds */\
</span></span></pre>
</div>
</div>

</body>
</html>