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

Reply via email to