Diff
Modified: trunk/LayoutTests/ChangeLog (96130 => 96131)
--- trunk/LayoutTests/ChangeLog 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/LayoutTests/ChangeLog 2011-09-27 17:58:55 UTC (rev 96131)
@@ -1,3 +1,30 @@
+2011-09-27 Juan Carlos Montemayor Elosua <[email protected]>
+
+ Implement Error.stack
+ https://bugs.webkit.org/show_bug.cgi?id=66994
+
+ Reviewed by Oliver Hunt.
+
+ Unit tests that contain both normal and special cases for stack trace
+ generation.
+
+ * fast/js/exception-properties-expected.txt:
+ * fast/js/script-tests/exception-properties.js:
+ * fast/js/script-tests/stack-trace.js: Added.
+ (printStack):
+ (hostThrower):
+ (callbacker):
+ (outer):
+ (inner):
+ (evaler):
+ (normalOuter):
+ (normalInner):
+ (scripterInner):
+ (scripterOuter):
+ * fast/js/stack-trace-expected.txt: Added.
+ * fast/js/stack-trace.html: Added.
+ * platform/chromium/test_expectations.txt:
+
2011-09-27 Adrienne Walker <[email protected]>
[Chromium] Layout Test compositing/video-page-visibility.html is failing on GPU linux
Modified: trunk/LayoutTests/fast/js/exception-properties-expected.txt (96130 => 96131)
--- trunk/LayoutTests/fast/js/exception-properties-expected.txt 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/LayoutTests/fast/js/exception-properties-expected.txt 2011-09-27 17:58:55 UTC (rev 96131)
@@ -4,7 +4,7 @@
PASS enumerableProperties(error) is []
-PASS enumerableProperties(nativeError) is ["line", "sourceId", "sourceURL"]
+PASS enumerableProperties(nativeError) is ["line", "sourceId", "sourceURL", "jscStack"]
PASS Object.getPrototypeOf(nativeError).name is "RangeError"
PASS Object.getPrototypeOf(nativeError).message is ""
PASS successfullyParsed is true
Modified: trunk/LayoutTests/fast/js/script-tests/exception-properties.js (96130 => 96131)
--- trunk/LayoutTests/fast/js/script-tests/exception-properties.js 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/LayoutTests/fast/js/script-tests/exception-properties.js 2011-09-27 17:58:55 UTC (rev 96131)
@@ -16,7 +16,7 @@
var error = new Error("message");
shouldBe('enumerableProperties(error)', '[]');
- shouldBe('enumerableProperties(nativeError)', '["line", "sourceId", "sourceURL"]');
+ shouldBe('enumerableProperties(nativeError)', '["line", "sourceId", "sourceURL", "jscStack"]');
shouldBe('Object.getPrototypeOf(nativeError).name', '"RangeError"');
shouldBe('Object.getPrototypeOf(nativeError).message', '""');
Added: trunk/LayoutTests/fast/js/script-tests/stack-trace.js (0 => 96131)
--- trunk/LayoutTests/fast/js/script-tests/stack-trace.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/stack-trace.js 2011-09-27 17:58:55 UTC (rev 96131)
@@ -0,0 +1,42 @@
+description(
+'This test checks stack trace corectness in special cases.'
+);
+
+function printStack(stackTrace) {
+ debug("--> Stack Trace:")
+ var i = 0;
+ for (var level in stackTrace) {
+ debug(" " + i + " " + stackTrace[level].substring(0, stackTrace[level].indexOf('file:')) + stackTrace[level].substring(stackTrace[level].lastIndexOf('/')+1));
+ i++;
+ }
+ debug('');
+}
+
+function hostThrower() { Element.prototype.appendChild.call({ }, [{ }]); }
+function callbacker(f) { [0].map(f); }
+function outer(errorName) { inner(errorName); }
+function inner(errorName) { throw new Error("Error in " + errorName); }
+function evaler(code) { eval(code); }
+function normalOuter() { normalInner(); }
+function normalInner() { if(thisVarDoesntExist) failIfTrue("shouldFailBeforeThis") };
+function scripterInner() { htmlInner(); }
+function scripterOuter() { htmlOuter(); }
+ // Expected functions in stack trace
+// Normal Case
+try { normalOuter() } catch (e) { printStack(e.jscStack) } // normalOuter -> normalInner
+
+// Eval Case
+try { evaler("inner('inner eval');"); } catch (e) { printStack(e.jscStack) } // evaler -> eval -> inner
+try { evaler("outer('outer eval');"); } catch (e) { printStack(e.jscStack) } // evaler -> eval -> outer -> inner
+
+// Function Callback Case
+try { callbacker(inner('inner map')); } catch (e) { printStack(e.jscStack); } // callbacker -> map -> inner
+try { callbacker(outer('outer map')); } catch (e) { printStack(e.jscStack); } // callbacker -> map -> outer -> inner
+
+// Host Code Case
+try { hostThrower(); } catch (e) { printStack(e.jscStack); } // hostThrower
+
+try { scripterInner(); } catch (e) { printStack(e.jscStack) } // program -> scripter -> inner
+try { scripterOuter(); } catch (e) { printStack(e.jscStack) } // program -> scripter -> outer -> inner
+
+successfullyParsed = true;
Added: trunk/LayoutTests/fast/js/stack-trace-expected.txt (0 => 96131)
--- trunk/LayoutTests/fast/js/stack-trace-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/stack-trace-expected.txt 2011-09-27 17:58:55 UTC (rev 96131)
@@ -0,0 +1,48 @@
+This test checks stack trace corectness in special cases.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+--> Stack Trace:
+ 0 normalInner at stack-trace.js:21
+ 1 normalOuter at stack-trace.js:20
+ 2 at stack-trace.js:26
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:18
+ 1 eval
+ 2 evaler at stack-trace.js
+ 3 at stack-trace.js:29
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:18
+ 1 outer at stack-trace.js:17
+ 2 eval
+ 3 evaler at stack-trace.js
+ 4 at stack-trace.js:30
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:18
+ 1 at stack-trace.js:33
+
+--> Stack Trace:
+ 0 inner at stack-trace.js:18
+ 1 outer at stack-trace.js:17
+ 2 at stack-trace.js:34
+
+--> Stack Trace:
+ 0 hostThrower at stack-trace.js:15
+ 1 at stack-trace.js:37
+
+--> Stack Trace:
+ 0 htmlInner at stack-trace.html:10
+ 1 scripterInner at stack-trace.js:22
+ 2 at stack-trace.js:39
+
+--> Stack Trace:
+ 0 htmlInner at stack-trace.html:10
+ 1 htmlOuter at stack-trace.html:11
+ 2 scripterOuter at stack-trace.js:23
+ 3 at stack-trace.js:40
+
+
Added: trunk/LayoutTests/fast/js/stack-trace.html (0 => 96131)
--- trunk/LayoutTests/fast/js/stack-trace.html (rev 0)
+++ trunk/LayoutTests/fast/js/stack-trace.html 2011-09-27 17:58:55 UTC (rev 96131)
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+ <link rel="stylesheet" href=""
+ <script src=""
+</head>
+<body>
+ <p id="description"></p>
+ <p id="console"></p>
+ <script>function htmlInner() { throw new Error("Error in HTML"); }</script>
+ <script>function htmlOuter() { htmlInner(); }</script>
+ <script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (96130 => 96131)
--- trunk/LayoutTests/platform/chromium/test_expectations.txt 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt 2011-09-27 17:58:55 UTC (rev 96131)
@@ -489,6 +489,10 @@
// throw. V8 follows the spec.
WONTFIX SKIP : fast/js/reparsing-semicolon-insertion.html = FAIL
+// This tests stack-traces that are generated by JSC. This test should
+// fail since it is specific to jsc.
+WONTFIX SKIP : fast/js/stack-trace.html = FAIL
+
// Rubber-banding is currently a CG only feature.
WONTFIX CPU GPU : platform/chromium/rubberbanding = FAIL
WONTFIX CPU GPU : platform/chromium-gpu/compositing/rubberbanding = IMAGE
Modified: trunk/Source/_javascript_Core/ChangeLog (96130 => 96131)
--- trunk/Source/_javascript_Core/ChangeLog 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-09-27 17:58:55 UTC (rev 96131)
@@ -1,3 +1,34 @@
+2011-09-27 Juan Carlos Montemayor Elosua <[email protected]>
+
+ Implement Error.stack
+ https://bugs.webkit.org/show_bug.cgi?id=66994
+
+ Reviewed by Oliver Hunt.
+
+ This patch utilizes topCallFrame to create a stack trace when
+ an error is thrown. Users will also be able to use the stack()
+ command in jsc to get arrays with stack trace information.
+
+ * _javascript_Core.exp:
+ * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.def:
+ * interpreter/Interpreter.cpp:
+ (JSC::getCallerLine):
+ (JSC::getSourceURLFromCallFrame):
+ (JSC::getStackFrameCodeType):
+ (JSC::Interpreter::getStackTrace):
+ (JSC::Interpreter::throwException):
+ * interpreter/Interpreter.h:
+ (JSC::StackFrame::toString):
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ (functionJSCStack):
+ * parser/Parser.h:
+ (JSC::Parser::parse):
+ * runtime/CommonIdentifiers.h:
+ * runtime/Error.cpp:
+ (JSC::addErrorInfo):
+ * runtime/Error.h:
+
2011-09-27 Carlos Garcia Campos <[email protected]>
[GTK] Reorganize header files
Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (96130 => 96131)
--- trunk/Source/_javascript_Core/_javascript_Core.exp 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp 2011-09-27 17:58:55 UTC (rev 96131)
@@ -114,6 +114,7 @@
__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE
__ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE
+__ZN3JSC11Interpreter13getStackTraceEPNS_12JSGlobalDataEiRN3WTF6VectorINS_10StackFrameELm0EEE
__ZN3JSC11JSByteArray13s_defaultInfoE
__ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataEPNS_14JSGlobalObjectENS_7JSValueEPKNS_9ClassInfoE
__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (96130 => 96131)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2011-09-27 17:58:55 UTC (rev 96131)
@@ -211,6 +211,7 @@
?getPropertyDescriptor@JSObject@JSC@@QAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z
?getPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
?getSlice@ArgList@JSC@@QBEXHAAV12@@Z
+ ?getStackTrace@Interpreter@JSC@@SAXPAVJSGlobalData@2@HAAV?$Vector@UStackFrame@JSC@@$0A@@WTF@@@Z
?getString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z
?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVUString@2@@Z
?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (96130 => 96131)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-09-27 17:58:55 UTC (rev 96131)
@@ -45,7 +45,6 @@
#include "JSActivation.h"
#include "JSArray.h"
#include "JSByteArray.h"
-#include "JSFunction.h"
#include "JSNotAnObject.h"
#include "JSPropertyNameIterator.h"
#include "LiteralParser.h"
@@ -687,6 +686,88 @@
exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
}
+static void getCallerLine(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber)
+{
+ (void)globalData;
+ unsigned bytecodeOffset;
+ lineNumber = -1;
+ callFrame = callFrame->removeHostCallFrameFlag();
+
+ if (callFrame->callerFrame() == CallFrame::noCaller() || callFrame->callerFrame()->hasHostCallFrameFlag())
+ return;
+
+ CodeBlock* callerCodeBlock = callFrame->callerFrame()->removeHostCallFrameFlag()->codeBlock();
+
+#if ENABLE(INTERPRETER)
+ if (!globalData->canUseJIT())
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
+#if ENABLE(JIT)
+ else
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
+#endif
+#else
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
+#endif
+
+ lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
+}
+
+static ALWAYS_INLINE const UString getSourceURLFromCallFrame(CallFrame* callFrame)
+{
+ if (callFrame->hasHostCallFrameFlag())
+ return UString();
+#if ENABLE(INTERPRETER)
+ if (!callFrame->globalData().canUseJIT())
+ return callFrame->codeBlock()->source()->url();
+#if ENABLE(JIT)
+ return callFrame->codeBlock()->ownerExecutable()->sourceURL();
+#endif
+#else
+ return callFrame->codeBlock()->ownerExecutable()->sourceURL();
+#endif
+}
+
+static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame)
+{
+ if (callFrame->hasHostCallFrameFlag())
+ return StackFrameNativeCode;
+
+ switch (callFrame->codeBlock()->codeType()) {
+ case EvalCode:
+ return StackFrameEvalCode;
+ case FunctionCode:
+ return StackFrameFunctionCode;
+ case GlobalCode:
+ return StackFrameGlobalCode;
+ }
+ ASSERT_NOT_REACHED();
+ return StackFrameGlobalCode;
+}
+
+void Interpreter::getStackTrace(JSGlobalData* globalData, int line, Vector<StackFrame>& results)
+{
+ int stackLimit = 15;
+ CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag();
+ if (!callFrame || callFrame == CallFrame::noCaller() || !callFrame->codeBlock())
+ return;
+ UString sourceURL;
+ UString traceLevel;
+
+ for (int i = 0; i < stackLimit; ++i) {
+ if (!callFrame || callFrame == CallFrame::noCaller())
+ break;
+ if (callFrame->codeBlock()) {
+ sourceURL = getSourceURLFromCallFrame(callFrame);
+
+ StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), Strong<CallFrame>(*globalData, callFrame), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(*globalData, callFrame->codeBlock()->ownerExecutable()), line, sourceURL};
+
+ results.append(s);
+ }
+ getCallerLine(globalData, callFrame, line);
+ callFrame = callFrame->callerFrame()->removeHostCallFrameFlag();
+ }
+}
+
NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
{
CodeBlock* codeBlock = callFrame->codeBlock();
@@ -705,7 +786,9 @@
// FIXME: should only really be adding these properties to VM generated exceptions,
// but the inspector currently requires these for all thrown objects.
- addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source());
+ Vector<StackFrame> stackTrace;
+ getStackTrace(&callFrame->globalData(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), stackTrace);
+ addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source(), stackTrace);
}
isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception);
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (96130 => 96131)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.h 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h 2011-09-27 17:58:55 UTC (rev 96131)
@@ -31,6 +31,7 @@
#include "ArgList.h"
#include "JSCell.h"
+#include "JSFunction.h"
#include "JSValue.h"
#include "JSObject.h"
#include "Opcode.h"
@@ -42,8 +43,8 @@
class CodeBlock;
class EvalExecutable;
+ class ExecutableBase;
class FunctionExecutable;
- class JSFunction;
class JSGlobalObject;
class ProgramExecutable;
class Register;
@@ -62,6 +63,56 @@
WillExecuteStatement
};
+ enum StackFrameCodeType {
+ StackFrameGlobalCode,
+ StackFrameEvalCode,
+ StackFrameFunctionCode,
+ StackFrameNativeCode
+ };
+
+ struct StackFrame {
+ Strong<JSObject> callee;
+ Strong<CallFrame> callFrame;
+ StackFrameCodeType codeType;
+ Strong<ExecutableBase> executable;
+ int line;
+ UString sourceURL;
+ UString toString() const
+ {
+ bool hasSourceURLInfo = !sourceURL.isNull() && !sourceURL.isEmpty();
+ bool hasLineInfo = line > -1;
+ String traceLine;
+ JSObject* stackFrameCallee = callee.get();
+
+ switch (codeType) {
+ case StackFrameEvalCode:
+ if (hasSourceURLInfo)
+ traceLine = hasLineInfo ? String::format("eval at %s:%d", sourceURL.ascii().data(), line)
+ : String::format("eval at %s", sourceURL.ascii().data());
+ else
+ traceLine = String::format("eval");
+ break;
+ case StackFrameNativeCode:
+ traceLine = "Native code";
+ break;
+ case StackFrameFunctionCode:
+ if (stackFrameCallee && stackFrameCallee->inherits(&JSFunction::s_info)) {
+ UString functionName = asFunction(stackFrameCallee)->name(callFrame.get());
+ if (hasSourceURLInfo)
+ traceLine = hasLineInfo ? String::format("%s at %s:%d", functionName.ascii().data(), sourceURL.ascii().data(), line)
+ : String::format("%s at %s", functionName.ascii().data(), sourceURL.ascii().data());
+ else
+ traceLine = String::format("%s\n", functionName.ascii().data());
+ break;
+ }
+ case StackFrameGlobalCode:
+ traceLine = hasLineInfo ? String::format("at %s:%d", sourceURL.ascii().data(), line)
+ : String::format("at %s", sourceURL.ascii().data());
+ }
+ return traceLine.impl();
+ }
+ };
+
class TopCallFrameSetter {
public:
TopCallFrameSetter(JSGlobalData& global, CallFrame* callFrame)
@@ -128,6 +179,8 @@
NEVER_INLINE JSValue callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset);
NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
+ static const UString getTraceLine(CallFrame*, StackFrameCodeType, const UString&, int);
+ static void getStackTrace(JSGlobalData*, int line, Vector<StackFrame>& results);
void dumpSampleData(ExecState* exec);
void startSampling();
Modified: trunk/Source/_javascript_Core/jsc.cpp (96130 => 96131)
--- trunk/Source/_javascript_Core/jsc.cpp 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/jsc.cpp 2011-09-27 17:58:55 UTC (rev 96131)
@@ -27,6 +27,7 @@
#include "CurrentTime.h"
#include "ExceptionHelpers.h"
#include "InitializeThreading.h"
+#include "Interpreter.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "JSLock.h"
@@ -73,6 +74,7 @@
static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
static EncodedJSValue JSC_HOST_CALL functionGC(ExecState*);
#ifndef NDEBUG
static EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState*);
@@ -174,6 +176,7 @@
addFunction(globalData, "run", functionRun, 1);
addFunction(globalData, "load", functionLoad, 1);
addFunction(globalData, "checkSyntax", functionCheckSyntax, 1);
+ addFunction(globalData, "jscStack", functionJSCStack, 1);
addFunction(globalData, "readline", functionReadline, 0);
addFunction(globalData, "preciseTime", functionPreciseTime, 0);
#if ENABLE(SAMPLING_FLAGS)
@@ -221,6 +224,22 @@
return JSValue::encode(jsUndefined());
}
+EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState* exec)
+{
+ String trace = "--> Stack trace:\n";
+ Vector<StackFrame> stackTrace;
+ Interpreter::getStackTrace(&exec->globalData(), -1, stackTrace);
+ int i = 0;
+
+ for (Vector<StackFrame>::iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) {
+ StackFrame level = *iter;
+ trace += String::format(" %i %s\n", i, level.toString().utf8().data());
+ i++;
+ }
+ fprintf(stderr, "%s", trace.utf8().data());
+ return JSValue::encode(jsUndefined());
+}
+
EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
{
JSLock lock(SilenceAssertionsOnly);
Modified: trunk/Source/_javascript_Core/parser/Parser.h (96130 => 96131)
--- trunk/Source/_javascript_Core/parser/Parser.h 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/parser/Parser.h 2011-09-27 17:58:55 UTC (rev 96131)
@@ -114,7 +114,7 @@
else if (isEvalNode<ParsedNode>())
*exception = createSyntaxError(lexicalGlobalObject, errMsg);
else
- *exception = addErrorInfo(&lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, source);
+ *exception = addErrorInfo(&lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, source, Vector<StackFrame>());
}
m_arena.reset();
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (96130 => 96131)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2011-09-27 17:58:55 UTC (rev 96131)
@@ -52,6 +52,7 @@
macro(input) \
macro(isArray) \
macro(isPrototypeOf) \
+ macro(jscStack) \
macro(length) \
macro(message) \
macro(multiline) \
Modified: trunk/Source/_javascript_Core/runtime/Error.cpp (96130 => 96131)
--- trunk/Source/_javascript_Core/runtime/Error.cpp 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/runtime/Error.cpp 2011-09-27 17:58:55 UTC (rev 96131)
@@ -26,6 +26,7 @@
#include "ConstructData.h"
#include "ErrorConstructor.h"
+#include "JSArray.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
@@ -116,7 +117,7 @@
return createURIError(exec->lexicalGlobalObject(), message);
}
-JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, const SourceCode& source)
+JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, const SourceCode& source, const Vector<StackFrame>& stackTrace)
{
intptr_t sourceID = source.provider()->asID();
const UString& sourceURL = source.provider()->url();
@@ -127,13 +128,21 @@
error->putWithAttributes(globalData, Identifier(globalData, sourceIdPropertyName), jsNumber((double)sourceID), ReadOnly | DontDelete);
if (!sourceURL.isNull())
error->putWithAttributes(globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete);
+ if (!stackTrace.isEmpty()) {
+ JSArray* stackTraceArray = JSArray::create(*globalData, globalData->dynamicGlobalObject->arrayStructure());
+ for (unsigned i = 0; i < stackTrace.size(); i++) {
+ UString stackLevel = stackTrace[i].toString();
+ stackTraceArray->push(globalData->topCallFrame, jsString(globalData, stackLevel));
+ }
+ error->putWithAttributes(globalData, globalData->propertyNames->jscStack, stackTraceArray, ReadOnly | DontDelete);
+ }
return error;
}
-JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source)
+JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source, const Vector<StackFrame>& stackTrace)
{
- return addErrorInfo(&exec->globalData(), error, line, source);
+ return addErrorInfo(&exec->globalData(), error, line, source, stackTrace);
}
bool hasErrorInfo(ExecState* exec, JSObject* error)
Modified: trunk/Source/_javascript_Core/runtime/Error.h (96130 => 96131)
--- trunk/Source/_javascript_Core/runtime/Error.h 2011-09-27 17:55:02 UTC (rev 96130)
+++ trunk/Source/_javascript_Core/runtime/Error.h 2011-09-27 17:58:55 UTC (rev 96131)
@@ -23,6 +23,7 @@
#ifndef Error_h
#define Error_h
+#include "Interpreter.h"
#include "JSObject.h"
#include <stdint.h>
@@ -55,9 +56,9 @@
// Methods to add
bool hasErrorInfo(ExecState*, JSObject* error);
- JSObject* addErrorInfo(JSGlobalData*, JSObject* error, int line, const SourceCode&);
+ JSObject* addErrorInfo(JSGlobalData*, JSObject* error, int line, const SourceCode&, const Vector<StackFrame>&);
// ExecState wrappers.
- JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
+ JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&, const Vector<StackFrame>&);
// Methods to throw Errors.
JSValue throwError(ExecState*, JSValue);