- debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine(), 0);
- }
-
- JSValue activation;
- if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsActivation()) {
- activation = callFrame->uncheckedR(oldCodeBlock->activationRegister()).jsValue();
- if (activation)
- jsCast<JSActivation*>(activation)->tearOff(*scope->vm());
- }
-
- if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->usesArguments()) {
- if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
- if (activation)
- jsCast<Arguments*>(arguments)->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
- else
- jsCast<Arguments*>(arguments)->tearOff(callFrame);
- }
- }
-
- CallFrame* callerFrame = callFrame->callerFrame();
- callFrame->vm().topCallFrame = callerFrame;
- if (callerFrame->hasHostCallFrameFlag())
- return false;
- callFrame = getCallerInfo(&callFrame->vm(), callFrame, bytecodeOffset, codeBlock);
- return true;
-}
-
-static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
-{
- exception->clearAppendSourceToMessage();
-
- 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 = makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
- 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 = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
- }
-
- exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
-}
-
-static unsigned getBytecodeOffsetForCallFrame(CallFrame* callFrame)
-{
- callFrame = callFrame->removeHostCallFrameFlag();
- CodeBlock* codeBlock = callFrame->codeBlock();
- if (!codeBlock)
- return 0;
-#if ENABLE(DFG_JIT)
- if (codeBlock->getJITType() == JITCode::DFGJIT)
- return codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex;
-#endif
- return callFrame->bytecodeOffsetForNonDFGCode();
-}
-
-static CallFrame* getCallerInfo(VM* vm, CallFrame* callFrame, unsigned& bytecodeOffset, CodeBlock*& caller)
-{
- ASSERT_UNUSED(vm, vm);
- bytecodeOffset = 0;
- ASSERT(!callFrame->hasHostCallFrameFlag());
- CallFrame* trueCallerFrame = callFrame->trueCallerFrame();
- bool wasCalledByHost = callFrame->callerFrame()->hasHostCallFrameFlag();
- ASSERT(!trueCallerFrame->hasHostCallFrameFlag());
-
- if (trueCallerFrame == CallFrame::noCaller() || !trueCallerFrame || !trueCallerFrame->codeBlock()) {
- caller = 0;
- return trueCallerFrame;
- }
-
- CodeBlock* callerCodeBlock = trueCallerFrame->codeBlock();
-
- if (!callFrame->hasReturnPC())
- wasCalledByHost = true;
-
- if (wasCalledByHost) {
-#if ENABLE(DFG_JIT)
- if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
- unsigned codeOriginIndex = callFrame->callerFrame()->removeHostCallFrameFlag()->codeOriginIndexForDFG();
- CodeOrigin origin = callerCodeBlock->codeOrigin(codeOriginIndex);
- bytecodeOffset = origin.bytecodeIndex;
- if (InlineCallFrame* inlineCallFrame = origin.inlineCallFrame)
- callerCodeBlock = inlineCallFrame->baselineCodeBlock();
- } else
-#endif
- bytecodeOffset = trueCallerFrame->bytecodeOffsetForNonDFGCode();
- } else {
-#if ENABLE(DFG_JIT)
- if (callFrame->isInlineCallFrame()) {
- InlineCallFrame* icf = callFrame->inlineCallFrame();
- bytecodeOffset = icf->caller.bytecodeIndex;
- if (InlineCallFrame* parentCallFrame = icf->caller.inlineCallFrame) {
- FunctionExecutable* executable = static_cast<FunctionExecutable*>(parentCallFrame->executable.get());
- CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(parentCallFrame->isCall ? CodeForCall : CodeForConstruct);
- ASSERT(newCodeBlock);
- ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
- callerCodeBlock = newCodeBlock;
- }
- } else if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
- CodeOrigin origin;
- if (!callerCodeBlock->codeOriginForReturn(callFrame->returnPC(), origin)) {
- // This should not be possible, but we're seeing cases where it does happen
- // CallFrame already has robustness against bogus stack walks, so
- // we'll extend that to here as well.
- ASSERT_NOT_REACHED();
- caller = 0;
- return 0;
- }
- bytecodeOffset = origin.bytecodeIndex;
- if (InlineCallFrame* icf = origin.inlineCallFrame) {
- FunctionExecutable* executable = static_cast<FunctionExecutable*>(icf->executable.get());
- CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(icf->isCall ? CodeForCall : CodeForConstruct);
- ASSERT(newCodeBlock);
- ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
- callerCodeBlock = newCodeBlock;
- }
- } else
-#endif
- {
- RELEASE_ASSERT(callerCodeBlock);
- bytecodeOffset = callerCodeBlock->bytecodeOffset(trueCallerFrame, callFrame->returnPC());
- }