Ignore:
Timestamp:
Mar 21, 2014, 4:48:39 PM (11 years ago)
Author:
[email protected]
Message:

Crash when BytecodeGenerator::emitJump calls Label::bind on null pointer.
<https://webkit.org/b/124508>

Reviewed by Oliver Hunt.

Source/JavaScriptCore:

The issue is that BreakNode::emitBytecode() is holding onto a LabelScope
pointer from the BytecodeGenerator's m_localScopes vector, and then it
calls emitPopScopes(). emitPopScopes() may do finally clause handling
which will require the m_localScopes to be cloned so that it can change
the local scopes for the finally block, and then restore it after
handling the finally clause. These modifications of the m_localScopes
vector will result in the LabelScope pointer in BreakNode::emitBytecode()
becoming stale, thereby causing the crash.

The same issue applies to the ContinueNode as well.

The fix is to use the existing LabelScopePtr abstraction instead of raw
LabelScope pointers. The LabelScopePtr is resilient to the underlying
vector re-allocating its backing store.

I also changed the LabelScopePtr constructor that takes a LabelScopeStore
to expect a reference to the owner store instead of a pointer because the
owner store should never be a null pointer.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::newLabelScope):
(JSC::BytecodeGenerator::breakTarget):
(JSC::BytecodeGenerator::continueTarget):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/LabelScope.h:

(JSC::LabelScopePtr::LabelScopePtr):
(JSC::LabelScopePtr::operator bool):
(JSC::LabelScopePtr::null):

  • bytecompiler/NodesCodegen.cpp:

(JSC::ContinueNode::trivialTarget):
(JSC::ContinueNode::emitBytecode):
(JSC::BreakNode::trivialTarget):
(JSC::BreakNode::emitBytecode):

LayoutTests:

  • js/regress-124508-expected.txt: Added.
  • js/regress-124508.html: Added.
  • js/script-tests/regress-124508.js: Added.

(function_0):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r164835 r166107  
    19561956        return 0;
    19571957
    1958     LabelScope* scope = generator.continueTarget(m_ident);
     1958    LabelScopePtr scope = generator.continueTarget(m_ident);
    19591959    ASSERT(scope);
    19601960
     
    19691969    generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
    19701970   
    1971     LabelScope* scope = generator.continueTarget(m_ident);
     1971    LabelScopePtr scope = generator.continueTarget(m_ident);
    19721972    ASSERT(scope);
    19731973
     
    19831983        return 0;
    19841984
    1985     LabelScope* scope = generator.breakTarget(m_ident);
     1985    LabelScopePtr scope = generator.breakTarget(m_ident);
    19861986    ASSERT(scope);
    19871987
     
    19961996    generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
    19971997   
    1998     LabelScope* scope = generator.breakTarget(m_ident);
     1998    LabelScopePtr scope = generator.breakTarget(m_ident);
    19991999    ASSERT(scope);
    20002000
Note: See TracChangeset for help on using the changeset viewer.