void StackIterator::Frame::print(int indentLevel) { int i = indentLevel; if (!this->callFrame()) { printif(i, "frame 0x0\n"); return; } CodeBlock* codeBlock = this->codeBlock(); printif(i, "frame %p {\n", this->callFrame()); CallFrame* callFrame = m_callFrame; CallFrame* callerFrame = this->callerFrame(); void* returnPC = callFrame->hasReturnPC() ? callFrame->returnPC().value() : 0; printif(i, " name '%s'\n", functionName().utf8().data()); printif(i, " sourceURL '%s'\n", sourceURL().utf8().data()); printif(i, " hostFlag %d\n", callerFrame->hasHostCallFrameFlag()); #if ENABLE(DFG_JIT) printif(i, " isInlinedFrame %d\n", isInlinedFrame()); if (isInlinedFrame()) printif(i, " InlineCallFrame %p\n", m_inlineCallFrame); #endif printif(i, " callee %p\n", callee()); printif(i, " returnPC %p\n", returnPC); printif(i, " callerFrame %p\n", callerFrame->removeHostCallFrameFlag()); unsigned locationRawBits = callFrame->locationAsRawBits(); printif(i, " rawLocationBits %u 0x%x\n", locationRawBits, locationRawBits); printif(i, " codeBlock %p\n", codeBlock); if (codeBlock) { JITCode::JITType jitType = codeBlock->jitType(); if (callFrame->hasLocationAsBytecodeOffset()) { unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset(); printif(i, " bytecodeOffset %u %p / %zu\n", bytecodeOffset, reinterpret_cast<void*>(bytecodeOffset), codeBlock->instructions().size()); #if ENABLE(DFG_JIT) } else { unsigned codeOriginIndex = callFrame->locationAsCodeOriginIndex(); printif(i, " codeOriginIdex %u %p / %zu\n", codeOriginIndex, reinterpret_cast<void*>(codeOriginIndex), codeBlock->codeOrigins().size()); #endif } unsigned line = 0; unsigned column = 0; computeLineAndColumn(line, column); printif(i, " line %d\n", line); printif(i, " column %d\n", column); printif(i, " jitType %d <%s> isOptimizingJIT %d\n", jitType, jitTypeName(jitType), JITCode::isOptimizingJIT(jitType)); #if ENABLE(DFG_JIT) printif(i, " hasCodeOrigins %d\n", codeBlock->hasCodeOrigins()); if (codeBlock->hasCodeOrigins()) { JITCode* jitCode = codeBlock->jitCode().get(); printif(i, " jitCode %p start %p end %p\n", jitCode, jitCode->start(), jitCode->end()); } #endif } printif(i, "}\n"); }
JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source) { JSGlobalData* globalData = &exec->globalData(); addErrorInfo(globalData, error, line, source); JSArray* stack = constructEmptyArray(exec); CallFrame* frame = exec; JSObject* stackFrame; CodeBlock* codeBlock; UString sourceURL; UString functionName; ReturnAddressPtr pc; while (!frame->hasHostCallFrameFlag()) { stackFrame = constructEmptyObject(exec); codeBlock = frame->codeBlock(); // sourceURL sourceURL = codeBlock->ownerExecutable()->sourceURL(); stackFrame->putWithAttributes( globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete ); // 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->push(exec, JSValue(stackFrame)); pc = frame->returnPC(); frame = frame->callerFrame(); } error->putWithAttributes(globalData, Identifier(globalData, stackPropertyName), stack, ReadOnly | DontDelete); return error; }
JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source) { JSGlobalData* globalData = &exec->globalData(); addErrorInfo(globalData, error, line, source); UStringBuilder stackString; JSArray* stackArray = constructEmptyArray(exec); CallFrame* frame = exec; stackString.append(error->toString(exec)); bool functionKnown; ReturnAddressPtr pc; while (!frame->hasHostCallFrameFlag()) { CodeBlock* codeBlock = frame->codeBlock(); JSObject* arrayItem = constructEmptyObject(exec); stackString.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) { stackString.append(functionName); stackString.append(" ("); arrayItem->putWithAttributes( globalData, Identifier(globalData, functionPropertyName), jsString(globalData, functionName), ReadOnly | DontDelete ); } UString sourceURL = codeBlock->ownerExecutable()->sourceURL(); arrayItem->putWithAttributes( globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete ); stackString.append(sourceURL); stackString.append(":"); if (frame != exec) { line = codeBlock->lineNumberForBytecodeOffset(codeBlock->bytecodeOffset(pc)); } arrayItem->putWithAttributes( globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete ); stackString.append(UString::number(line)); if (functionKnown) { stackString.append(")"); } stackArray->push(exec, JSValue(arrayItem)); pc = frame->returnPC(); frame = frame->callerFrame(); } error->putWithAttributes( globalData, Identifier(globalData, stackPropertyName), jsString(globalData, stackString.toUString()), ReadOnly | DontDelete ); error->putWithAttributes( globalData, Identifier(globalData, "stackArray"), stackArray, ReadOnly | DontDelete ); return error; }