Ignore:
Timestamp:
Sep 27, 2011, 10:58:55 AM (14 years ago)
Author:
[email protected]
Message:

Implement Error.stack
https://bugs.webkit.org/show_bug.cgi?id=66994

Patch by Juan Carlos Montemayor Elosua <[email protected]> on 2011-09-27
Reviewed by Oliver Hunt.

Source/JavaScriptCore:

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.

(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:

LayoutTests:

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:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r95901 r96131  
    3232#include "ArgList.h"
    3333#include "JSCell.h"
     34#include "JSFunction.h"
    3435#include "JSValue.h"
    3536#include "JSObject.h"
     
    4344    class CodeBlock;
    4445    class EvalExecutable;
     46    class ExecutableBase;
    4547    class FunctionExecutable;
    46     class JSFunction;
    4748    class JSGlobalObject;
    4849    class ProgramExecutable;
     
    6364    };
    6465
     66    enum StackFrameCodeType {
     67        StackFrameGlobalCode,
     68        StackFrameEvalCode,
     69        StackFrameFunctionCode,
     70        StackFrameNativeCode
     71    };
     72
     73    struct StackFrame {
     74        Strong<JSObject> callee;
     75        Strong<CallFrame> callFrame;
     76        StackFrameCodeType codeType;
     77        Strong<ExecutableBase> executable;
     78        int line;
     79        UString sourceURL;
     80        UString toString() const
     81        {
     82            bool hasSourceURLInfo = !sourceURL.isNull() && !sourceURL.isEmpty();
     83            bool hasLineInfo = line > -1;
     84            String traceLine;
     85            JSObject* stackFrameCallee = callee.get();
     86
     87            switch (codeType) {
     88            case StackFrameEvalCode:
     89                if (hasSourceURLInfo)
     90                    traceLine = hasLineInfo ? String::format("eval at %s:%d", sourceURL.ascii().data(), line)
     91                                            : String::format("eval at %s", sourceURL.ascii().data());
     92                else
     93                    traceLine = String::format("eval");
     94                break;
     95            case StackFrameNativeCode:
     96                traceLine = "Native code";
     97                break;
     98            case StackFrameFunctionCode:
     99                if (stackFrameCallee && stackFrameCallee->inherits(&JSFunction::s_info)) {
     100                    UString functionName = asFunction(stackFrameCallee)->name(callFrame.get());
     101                    if (hasSourceURLInfo)
     102                        traceLine = hasLineInfo ? String::format("%s at %s:%d", functionName.ascii().data(), sourceURL.ascii().data(), line)
     103                                                : String::format("%s at %s", functionName.ascii().data(), sourceURL.ascii().data());
     104                    else
     105                        traceLine = String::format("%s\n", functionName.ascii().data());
     106                    break;
     107                }
     108            case StackFrameGlobalCode:
     109                traceLine = hasLineInfo ? String::format("at %s:%d", sourceURL.ascii().data(), line)
     110                                        : String::format("at %s", sourceURL.ascii().data());
     111            }
     112            return traceLine.impl();
     113        }
     114    };
     115
    65116    class TopCallFrameSetter {
    66117    public:
     
    129180        NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
    130181        NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
     182        static const UString getTraceLine(CallFrame*, StackFrameCodeType, const UString&, int);
     183        static void getStackTrace(JSGlobalData*, int line, Vector<StackFrame>& results);
    131184
    132185        void dumpSampleData(ExecState* exec);
Note: See TracChangeset for help on using the changeset viewer.