Hi all, I've made a slight modification of Interpreter::throwException method (see below).
The aim is to be able to evaluate if the current CallFrame OR ONE OF ITS CALLERS has an exception handler: the modification consists in a loop that traverses the call stack (frames) to perform this evaluation. We encounter a pb when the whole call stack consists in pure JavaScript code that calls (thanks to a javascript 'eval' instruction) C++-coded classes which generate an exception. Indeed the condition that ends the loop ('if (noCaller || hasHostCallFrame)')is reached although it is perfectly clear that we have not reached the end of the stack. Furthermore, it seems that, once hasHostCallFrameFlag() is true, the call frame cFrame is really not usable except for calling hasHostCallFrameFlag(): but it it not the last call frame. Is this a feature or a known problem? Is there is another way to traverse the call stack of the current frame even when hasHostCallFrameFlag() is true? thanks for your help BR GH NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset) { CodeBlock* codeBlock = callFrame->codeBlock(); bool isInterrupt = false; // Set up the exception object if (exceptionValue.isObject()) { JSObject* exception = asObject(exceptionValue); if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset); // Using hasExpressionInfo to imply we are interested in rich exception info. if (codeBlock->hasExpressionInfo() && !hasErrorInfo(callFrame, exception)) { ASSERT(codeBlock->hasLineInfo()); // FIXME: should only really be adding these properties to VM generated exceptions, // but the inspector currently requires these for all thrown objects. addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source()); } ComplType exceptionType = exception->exceptionType(); isInterrupt = exceptionType == Interrupted || exceptionType == Terminated; } if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) { /************* START MODIFS ******************/ bool hasHandler = false; unsigned bcOffset = bytecodeOffset; CodeBlock* cBlock = codeBlock; CallFrame* cFrame = callFrame; while ( cFrame != 0 && cFrame != CallFrame::noCaller() && !cFrame->hasHostCallFrameFlag() ) { #if ENABLE(JIT) ReturnAddressPtr returnPC = cFrame->returnPC(); #else JSC::Instruction* returnPC = cFrame-> returnVPC(); #endif if ( cBlock == 0 ) cFrame = 0; else { hasHandler = cBlock->handlerForBytecodeOffset( bcOffset ); if ( hasHandler ) break; cFrame = cFrame->callerFrame(); bool noCaller = ( cFrame == CallFrame::noCaller() ); bool hasHostCallFrame = cFrame->hasHostCallFrameFlag(); if ( noCaller || hasHostCallFrame ) { break; } JSObject* jsFuncCallee = cFrame->callee(); if ( jsFuncCallee == 0 ) break; cBlock = cFrame->codeBlock(); #if ENABLE(JIT) bcOffset = cBlock->bytecodeOffset(ReturnAddressPtr(returnPC)); #else bcOffset = cBlock->bytecodeOffset(returnPC); #endif } } /************* END MODIFS ******************/ DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); //bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset); debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), hasHandler); } // Calculate an exception handler vPC, unwinding call frames as necessary. HandlerInfo* handler = 0; while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) { if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) { if (Profiler* profiler = *Profiler::enabledProfilerReference()) profiler->exceptionUnwind(callFrame); return 0; } } if (Profiler* profiler = *Profiler::enabledProfilerReference()) profiler->exceptionUnwind(callFrame); // Shrink the JS stack, in case stack overflow made it huge. Register* highWaterMark = 0; for (CallFrame* callerFrame = callFrame; callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) { CodeBlock* codeBlock = callerFrame->codeBlock(); if (!codeBlock) continue; Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters; highWaterMark = max(highWaterMark, callerHighWaterMark); } m_registerFile.shrink(highWaterMark); // Unwind the scope chain within the exception handler's call frame. ScopeChainNode* scopeChain = callFrame->scopeChain(); int scopeDelta = 0; if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) scopeDelta = depth(codeBlock, scopeChain) - handler->scopeDepth; ASSERT(scopeDelta >= 0); while (scopeDelta--) scopeChain = scopeChain->pop(); callFrame->setScopeChain(scopeChain); return handler; } [cid:01e447.png@17f19175.439de047] Guy Hermann Développeur Senior Email : guy.herm...@4d.com<mailto:guy.herm...@4d.com> Web : www.4D.com<http://www.4D.com> 4D SAS 60, rue d'Alsace 92110 Clichy - Standard : +33 1 40 87 92 00
<<inline: 01e447.png>>
_______________________________________________ webkit-help mailing list webkit-help@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-help