Merge pull request #262 from jonleighton/stacktraces

Error.stack returns a string to match V8/Node.js
1.6
Ariya Hidayat 2012-06-12 08:41:48 -07:00
commit 8d366f9328
3 changed files with 40 additions and 45 deletions

View File

@ -33,6 +33,7 @@
#include "NativeErrorConstructor.h"
#include "SourceCode.h"
#include "CodeBlock.h"
#include "UStringBuilder.h"
namespace JSC {
@ -40,7 +41,6 @@ static const char* linePropertyName = "line";
static const char* sourceIdPropertyName = "sourceId";
static const char* sourceURLPropertyName = "sourceURL";
static const char* stackPropertyName = "stack";
static const char* functionPropertyName = "function";
JSObject* createError(JSGlobalObject* globalObject, const UString& message)
{
@ -140,52 +140,56 @@ JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceC
addErrorInfo(globalData, error, line, source);
JSArray* stack = constructEmptyArray(exec);
UStringBuilder stack;
CallFrame* frame = exec;
JSObject* stackFrame;
CodeBlock* codeBlock;
UString sourceURL;
UString functionName;
stack.append(error->toString(exec));
bool functionKnown;
ReturnAddressPtr pc;
while (!frame->hasHostCallFrameFlag()) {
stackFrame = constructEmptyObject(exec);
codeBlock = frame->codeBlock();
CodeBlock* codeBlock = frame->codeBlock();
// sourceURL
sourceURL = codeBlock->ownerExecutable()->sourceURL();
stackFrame->putWithAttributes(
globalData, Identifier(globalData, sourceURLPropertyName),
jsString(globalData, sourceURL), ReadOnly | DontDelete
);
stack.append("\n at ");
JSObject* callee = frame->callee();
UString functionName;
if (callee && callee->inherits(&JSFunction::s_info)) {
functionName = asFunction(callee)->calculatedDisplayName(exec);
functionKnown = !functionName.isEmpty();
} else {
functionKnown = false;
}
if (functionKnown) {
stack.append(functionName);
stack.append(" (");
}
stack.append(codeBlock->ownerExecutable()->sourceURL());
stack.append(":");
// line
if (frame != exec) {
line = codeBlock->lineNumberForBytecodeOffset(codeBlock->bytecodeOffset(pc));
}
stackFrame->putWithAttributes(
globalData, Identifier(globalData, linePropertyName),
jsNumber(line), ReadOnly | DontDelete
);
// function
JSObject* function = frame->callee();
if (function && function->inherits(&JSFunction::s_info)) {
functionName = asFunction(function)->calculatedDisplayName(exec);
stackFrame->putWithAttributes(
globalData, Identifier(globalData, functionPropertyName),
jsString(globalData, functionName), ReadOnly | DontDelete
);
stack.append(UString::number(line));
if (functionKnown) {
stack.append(")");
}
stack->push(exec, JSValue(stackFrame));
pc = frame->returnPC();
frame = frame->callerFrame();
}
error->putWithAttributes(globalData, Identifier(globalData, stackPropertyName), stack, ReadOnly | DontDelete);
error->putWithAttributes(
globalData, Identifier(globalData, stackPropertyName),
jsString(globalData, stack.toUString()), ReadOnly | DontDelete
);
return error;
}

View File

@ -1,5 +1,5 @@
ErrorHelper = {
foo: function foo() {
foo: function() {
this.bar()
},

View File

@ -331,21 +331,12 @@ describe("WebPage object", function() {
err = e
};
var frame;
var lines = err.stack.split("\n");
frame = err.stack[0];
expect(frame.sourceURL).toEqual(helperFile);
expect(frame.line).toEqual(7);
expect(frame.function).toEqual("bar");
frame = err.stack[1];
expect(frame.sourceURL).toEqual(helperFile);
expect(frame.line).toEqual(3);
expect(frame.function).toEqual("foo");
frame = err.stack[2];
expect(frame.sourceURL).toMatch(/webpage-spec.js$/);
expect(frame.function).toEqual("test");
expect(lines[0]).toEqual("ReferenceError: Can't find variable: referenceError");
expect(lines[1]).toEqual(" at bar (./fixtures/error-helper.js:7)");
expect(lines[2]).toEqual(" at ./fixtures/error-helper.js:3");
expect(lines[3]).toMatch(/ at test \(\.\/webpage-spec\.js:\d+\)/);
});
});