diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-05-20 09:56:07 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-05-20 09:56:07 +0000 |
commit | 41386e9cb918eed93b3f13648cbef387e371e451 (patch) | |
tree | a97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/JavaScriptCore/runtime/ErrorInstance.cpp | |
parent | e15dd966d523731101f70ccf768bba12435a0208 (diff) | |
download | WebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz |
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/JavaScriptCore/runtime/ErrorInstance.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/ErrorInstance.cpp | 156 |
1 files changed, 7 insertions, 149 deletions
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp index 2bf1493bd..c831f9183 100644 --- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp +++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp @@ -22,171 +22,29 @@ #include "ErrorInstance.h" #include "JSScope.h" -#include "JSCInlines.h" -#include "JSGlobalObjectFunctions.h" -#include <wtf/Vector.h> +#include "Operations.h" namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ErrorInstance); -const ClassInfo ErrorInstance::s_info = { "Error", &JSNonFinalObject::s_info, 0, CREATE_METHOD_TABLE(ErrorInstance) }; +const ClassInfo ErrorInstance::s_info = { "Error", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorInstance) }; ErrorInstance::ErrorInstance(VM& vm, Structure* structure) : JSNonFinalObject(vm, structure) + , m_appendSourceToMessage(false) { } -static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset) -{ - ErrorInstance::SourceAppender appender = exception->sourceAppender(); - exception->clearSourceAppender(); - RuntimeType type = exception->runtimeTypeForCause(); - exception->clearRuntimeTypeForCause(); - - if (!callFrame->codeBlock()->hasExpressionInfo()) - return; - - int startOffset = 0; - int endOffset = 0; - int divotPoint = 0; - unsigned line = 0; - unsigned column = 0; - - CodeBlock* codeBlock = callFrame->codeBlock(); - codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column); - - int expressionStart = divotPoint - startOffset; - int expressionStop = divotPoint + endOffset; - - const String& sourceString = codeBlock->source()->source(); - if (!expressionStop || expressionStart > static_cast<int>(sourceString.length())) - return; - - VM* vm = &callFrame->vm(); - JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message); - if (!jsMessage || !jsMessage.isString()) - return; - - String message = asString(jsMessage)->value(callFrame); - if (expressionStart < expressionStop) - message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop) , type, ErrorInstance::FoundExactSource); - else { - // No range information, so give a few characters of context. - const StringImpl* data = sourceString.impl(); - int dataLength = sourceString.length(); - int start = expressionStart; - int stop = expressionStart; - // Get up to 20 characters of context to the left and right of the divot, clamping to the line. - // Then strip whitespace. - while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n') - start--; - while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start])) - start++; - while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n') - stop++; - while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1])) - stop--; - message = appender(message, codeBlock->source()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource); - } - exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message)); - -} - -class FindFirstCallerFrameWithCodeblockFunctor { -public: - FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame) - : m_startCallFrame(startCallFrame) - , m_foundCallFrame(nullptr) - , m_foundStartCallFrame(false) - , m_index(0) - { } - - StackVisitor::Status operator()(StackVisitor& visitor) - { - if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame)) - m_foundStartCallFrame = true; - - if (m_foundStartCallFrame) { - if (visitor->callFrame()->codeBlock()) { - m_foundCallFrame = visitor->callFrame(); - return StackVisitor::Done; - } - m_index++; - } - - return StackVisitor::Continue; - } - - CallFrame* foundCallFrame() const { return m_foundCallFrame; } - unsigned index() const { return m_index; } - -private: - CallFrame* m_startCallFrame; - CallFrame* m_foundCallFrame; - bool m_foundStartCallFrame; - unsigned m_index; -}; - -static bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM& vm, JSObject* obj, bool useCurrentFrame, CallFrame*& callFrame, unsigned &bytecodeOffset) -{ - Vector<StackFrame> stackTrace = Vector<StackFrame>(); - - if (exec && stackTrace.isEmpty()) - vm.interpreter->getStackTrace(stackTrace); - - if (!stackTrace.isEmpty()) { - - ASSERT(exec == vm.topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec()); - - StackFrame* stackFrame; - for (unsigned i = 0 ; i < stackTrace.size(); ++i) { - stackFrame = &stackTrace.at(i); - if (stackFrame->bytecodeOffset) - break; - } - - if (bytecodeOffset) { - FindFirstCallerFrameWithCodeblockFunctor functor(exec); - vm.topCallFrame->iterate(functor); - callFrame = functor.foundCallFrame(); - unsigned stackIndex = functor.index(); - bytecodeOffset = stackTrace.at(stackIndex).bytecodeOffset; - } - - unsigned line; - unsigned column; - stackFrame->computeLineAndColumn(line, column); - obj->putDirect(vm, vm.propertyNames->line, jsNumber(line), ReadOnly | DontDelete); - obj->putDirect(vm, vm.propertyNames->column, jsNumber(column), ReadOnly | DontDelete); - - if (!stackFrame->sourceURL.isEmpty()) - obj->putDirect(vm, vm.propertyNames->sourceURL, jsString(&vm, stackFrame->sourceURL), ReadOnly | DontDelete); - - if (!useCurrentFrame) - stackTrace.remove(0); - obj->putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum); - - return true; - } - return false; -} - -void ErrorInstance::finishCreation(ExecState* exec, VM& vm, const String& message, bool useCurrentFrame) +void ErrorInstance::finishCreation(VM& vm, const String& message, Vector<StackFrame> stackTrace) { Base::finishCreation(vm); ASSERT(inherits(info())); if (!message.isNull()) putDirect(vm, vm.propertyNames->message, jsString(&vm, message), DontEnum); - - unsigned bytecodeOffset = hasSourceAppender(); - CallFrame* callFrame = nullptr; - bool hasTrace = addErrorInfoAndGetBytecodeOffset(exec, vm, this, useCurrentFrame, callFrame, bytecodeOffset); - - if (hasTrace && callFrame && hasSourceAppender()) { - if (callFrame && callFrame->codeBlock()) - appendSourceToError(callFrame, this, bytecodeOffset); - } + + if (!stackTrace.isEmpty()) + putDirect(vm, vm.propertyNames->stack, vm.interpreter->stackTraceAsString(vm.topCallFrame, stackTrace), DontEnum); } } // namespace JSC |