Add support for Error.stackTraceLimit.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Mar 2017 01:14:06 +0000 (01:14 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Mar 2017 01:14:06 +0000 (01:14 +0000)
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:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@214289 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
JSTests/ChangeLog
JSTests/stress/error-stack-trace-limit.js [new file with mode: 0644]
LayoutTests/ChangeLog
LayoutTests/js/Object-getOwnPropertyNames-expected.txt
LayoutTests/js/script-tests/Object-getOwnPropertyNames.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/runtime/CommonIdentifiers.h
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/ErrorConstructor.cpp
Source/JavaScriptCore/runtime/ErrorConstructor.h
Source/JavaScriptCore/runtime/Exception.cpp
Source/JavaScriptCore/runtime/Options.h

index de1eebb..f223a34 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-22  Mark Lam  <mark.lam@apple.com>
+
+        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.
+
 2017-03-22  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [JSC] Use jsNontrivialString for Number toString operations
diff --git a/JSTests/stress/error-stack-trace-limit.js b/JSTests/stress/error-stack-trace-limit.js
new file mode 100644 (file)
index 0000000..0221fcf
--- /dev/null
@@ -0,0 +1,94 @@
+function assert(testID, b) {
+    if (!b)
+        throw new Error("FAILED test " + testID);
+}
+
+function assertEquals(testID, a, b) {
+    assert(testID, a == b);
+}
+
+var desc = Object.getOwnPropertyDescriptor(Error, "stackTraceLimit");
+
+assertEquals(100, typeof desc.value, "number");
+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 == "")
+        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, "Error");
+    if (typeof expectedNumberOfFrames == "undefined")
+        assertEquals(testID + 2, exception.stack, undefined);
+    else
+        assertEquals(testID + 3, numberOfFrames(exception.stack), expectedNumberOfFrames);
+}
+
+testLimit(1000, () => { Error.stackTraceLimit = 0 }, 1000, 0, 0);
+// note: Chrome always prints a header line. So, Chrome expects "Error" here.
+assertEquals(1100, exception.stack, "");
+
+testLimit(2000, () => { Error.stackTraceLimit = 10 }, 1000, 10, 10);
+testLimit(3000, () => { Error.stackTraceLimit = 100 }, 1000, 100, 100);
+testLimit(4000, () => { 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, () => { Error.stackTraceLimit = 2000 }, 1000, 2000, 1003);
+
+var value = { };
+testLimit(6000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = { valueOf() { return 5 } };
+testLimit(7000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = [ 1, 2, 3 ];
+testLimit(8000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = "hello";
+testLimit(9000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = Symbol("hello");
+testLimit(10000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = true;
+testLimit(11000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = false;
+testLimit(12000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+var value = undefined;
+testLimit(13000, () => { Error.stackTraceLimit = value }, 1000, value, undefined);
+
+testLimit(14000, () => { Error.stackTraceLimit = 10 }, 1000, 10, 10);
+
+testLimit(15000, () => { delete Error.stackTraceLimit; }, 1000, undefined, undefined);
+
+testLimit(16000, () => { Error.stackTraceLimit = 10 }, 1000, 10, 10);
index ffbcbdf..b2118de 100644 (file)
@@ -1,3 +1,15 @@
+2017-03-22  Mark Lam  <mark.lam@apple.com>
+
+        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:
+
 2017-03-22  Carlos Alberto Lopez Perez  <clopez@igalia.com>
 
         [GTK] Update layout test expectations file.
index c22575f..91e8dae 100644 (file)
@@ -57,7 +57,7 @@ PASS getSortedOwnPropertyNames(Date) is ['UTC', 'length', 'name', 'now', 'parse'
 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']
 PASS getSortedOwnPropertyNames(RegExp) is ['$&', "$'", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']
 PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'flags', 'global', 'ignoreCase', 'multiline', 'source', 'sticky', 'test', 'toString', 'unicode']
-PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype', 'stackTraceLimit']
 PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
 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']
 PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
index 769451f..386438d 100644 (file)
@@ -66,7 +66,7 @@ var expectedPropertyNamesSet = {
     "Date.prototype": "['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']",
     "RegExp": "['$&', \"$'\", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']",
     "RegExp.prototype": "['compile', 'constructor', 'exec', 'flags', 'global', 'ignoreCase', 'multiline', 'source', 'sticky', 'test', 'toString', 'unicode']",
-    "Error": "['length', 'name', 'prototype']",
+    "Error": "['length', 'name', 'prototype', 'stackTraceLimit']",
     "Error.prototype": "['constructor', 'message', 'name', 'toString']",
     "Math": "['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']",
     "JSON": "['parse', 'stringify']",
index 8beab30..0984a05 100644 (file)
@@ -1,3 +1,56 @@
+2017-03-22  Mark Lam  <mark.lam@apple.com>
+
+        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:
+
 2017-03-22  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [JSC] Use jsNontrivialString for Number toString operations
index 42d7eb1..901987d 100644 (file)
@@ -682,7 +682,7 @@ NEVER_INLINE HandlerInfo* Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exc
     if (exceptionValue.isEmpty() || (exceptionValue.isCell() && !exceptionValue.asCell()))
         exceptionValue = jsNull();
 
-    ASSERT_UNUSED(scope, scope.exception() && scope.exception()->stack().size());
+    ASSERT_UNUSED(scope, scope.exception() && (!Options::exceptionStackTraceLimit() || scope.exception()->stack().size()));
 
     // Calculate an exception handler vPC, unwinding call frames as necessary.
     HandlerInfo* handler = nullptr;
index 265a7ca..ad4a314 100644 (file)
@@ -3350,8 +3350,11 @@ static void dumpException(GlobalObject* globalObject, JSValue exception)
             lineNumberValue.toWTFString(globalObject->globalExec()).utf8().data());
     }
     
-    if (!stackValue.isUndefinedOrNull())
-        printf("%s\n", stackValue.toWTFString(globalObject->globalExec()).utf8().data());
+    if (!stackValue.isUndefinedOrNull()) {
+        auto stackString = stackValue.toWTFString(globalObject->globalExec());
+        if (stackString.length())
+            printf("%s\n", stackString.utf8().data());
+    }
 
 #undef CHECK_EXCEPTION
 }
index c08c128..8adec3d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003, 2007, 2009, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
     macro(sourceCode) \
     macro(sourceURL) \
     macro(stack) \
+    macro(stackTraceLimit) \
     macro(sticky) \
     macro(subarray) \
     macro(summary) \
index 677dc9b..83d41ca 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003-2006, 2008, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
  *
  *  This library is free software; you can redistribute it and/or
@@ -157,10 +157,14 @@ private:
 
 bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bool useCurrentFrame, CallFrame*& callFrame, unsigned* bytecodeOffset)
 {
-    Vector<StackFrame> stackTrace = Vector<StackFrame>();
+    JSGlobalObject* globalObject = obj->globalObject();
+    ErrorConstructor* errorConstructor = globalObject->errorConstructor();
+    if (!errorConstructor->stackTraceLimit())
+        return false;
 
+    Vector<StackFrame> stackTrace = Vector<StackFrame>();
     size_t framesToSkip = useCurrentFrame ? 0 : 1;
-    vm.interpreter->getStackTrace(stackTrace, framesToSkip);
+    vm.interpreter->getStackTrace(stackTrace, framesToSkip, errorConstructor->stackTraceLimit().value());
     if (!stackTrace.isEmpty()) {
 
         ASSERT(exec == vm.topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());
@@ -196,6 +200,8 @@ bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bo
 
         return true;
     }
+
+    obj->putDirect(vm, vm.propertyNames->stack, vm.smallStrings.emptyString(), DontEnum);
     return false;
 }
 
index 1d822c7..5caafa8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2008, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -44,6 +44,10 @@ void ErrorConstructor::finishCreation(VM& vm, ErrorPrototype* errorPrototype)
     // ECMA 15.11.3.1 Error.prototype
     putDirectWithoutTransition(vm, vm.propertyNames->prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), DontEnum | ReadOnly);
+
+    unsigned defaultStackTraceLimit = Options::defaultErrorStackTraceLimit();
+    m_stackTraceLimit = defaultStackTraceLimit;
+    putDirectWithoutTransition(vm, vm.propertyNames->stackTraceLimit, jsNumber(defaultStackTraceLimit), None);
 }
 
 // ECMA 15.9.3
@@ -78,4 +82,33 @@ CallType ErrorConstructor::getCallData(JSCell*, CallData& callData)
     return CallType::Host;
 }
 
+bool ErrorConstructor::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+    VM& vm = exec->vm();
+    ErrorConstructor* thisObject = jsCast<ErrorConstructor*>(cell);
+
+    if (propertyName == vm.propertyNames->stackTraceLimit) {
+        if (value.isNumber()) {
+            double effectiveLimit = value.asNumber();
+            effectiveLimit = std::max(0., effectiveLimit);
+            effectiveLimit = std::min(effectiveLimit, static_cast<double>(std::numeric_limits<unsigned>::max()));
+            thisObject->m_stackTraceLimit = static_cast<unsigned>(effectiveLimit);
+        } else
+            thisObject->m_stackTraceLimit = { };
+    }
+
+    return Base::put(thisObject, exec, propertyName, value, slot);
+}
+
+bool ErrorConstructor::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
+{
+    VM& vm = exec->vm();
+    ErrorConstructor* thisObject = jsCast<ErrorConstructor*>(cell);
+
+    if (propertyName == vm.propertyNames->stackTraceLimit)
+        thisObject->m_stackTraceLimit = { };
+
+    return Base::deleteProperty(thisObject, exec, propertyName);
+}
+
 } // namespace JSC
index 1dc3090..3bdfd04 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2008-2017 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -46,13 +46,20 @@ public:
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 
     }
 
+    std::optional<unsigned> stackTraceLimit() const { return m_stackTraceLimit; }
+
 protected:
     void finishCreation(VM&, ErrorPrototype*);
-        
+
+    static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
+
 private:
     ErrorConstructor(VM&, Structure*);
     static ConstructType getConstructData(JSCell*, ConstructData&);
     static CallType getCallData(JSCell*, CallData&);
+
+    std::optional<unsigned> m_stackTraceLimit;
 };
 
 } // namespace JSC
index 93175ee..19aff7a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -77,7 +77,7 @@ void Exception::finishCreation(VM& vm, JSValue thrownValue, StackCaptureAction a
 
     Vector<StackFrame> stackTrace;
     if (action == StackCaptureAction::CaptureStack)
-        vm.interpreter->getStackTrace(stackTrace);
+        vm.interpreter->getStackTrace(stackTrace, 0, Options::exceptionStackTraceLimit());
     m_stack = WTFMove(stackTrace);
 }
 
index 6984358..b2ef843 100644 (file)
@@ -376,6 +376,8 @@ typedef const char* optionString;
     v(bool, verifyHeap, false, Normal, nullptr) \
     v(unsigned, numberOfGCCyclesToRecordForVerification, 3, Normal, nullptr) \
     \
+    v(unsigned, exceptionStackTraceLimit, 100, Normal, "Stack trace limit for internal Exception object") \
+    v(unsigned, defaultErrorStackTraceLimit, 100, Normal, "The default value for Error.stackTraceLimit") \
     v(bool, useExceptionFuzz, false, Normal, nullptr) \
     v(unsigned, fireExceptionFuzzAt, 0, Normal, nullptr) \
     v(bool, validateDFGExceptionHandling, false, Normal, "Causes the DFG to emit code validating exception handling for each node that can exit") /* This is true by default on Debug builds */\