Ignore:
Timestamp:
Sep 5, 2012, 7:02:54 PM (13 years ago)
Author:
[email protected]
Message:

a = data[a]++; sets the wrong key in data
https://bugs.webkit.org/show_bug.cgi?id=91270

Reviewed by Oliver Hunt.

Source/JavaScriptCore:

Postfix inc/dec is unsafely using finalDestination, can trample base/subscript prior to the result being put.

  • bytecompiler/NodesCodegen.cpp:

(JSC::PostfixNode::emitResolve):

  • Remove redundant parens.

(JSC::PostfixNode::emitBracket):
(JSC::PostfixNode::emitDot):

  • Refactored to use tempDestination instead of finalDestination.

(JSC::PrefixNode::emitBracket):
(JSC::PrefixNode::emitDot):

  • Should be using emitPreIncOrDec.

LayoutTests:

Added test cases.

  • fast/js/post-inc-assign-overwrites-expected.txt: Added.
  • fast/js/post-inc-assign-overwrites.html: Added.
  • fast/js/script-tests/post-inc-assign-overwrites.js: Added.

(postIncDotAssignToBase):
(postIncBracketAssignToBase):
(postIncBracketAssignToSubscript):

File:
1 edited

Legend:

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

    r127666 r127676  
    629629            oldValue = 0;
    630630            emitPreIncOrDec(generator, value.get(), m_operator);
    631         } else {
     631        } else
    632632            oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
    633         }
    634633        generator.emitPutStaticVar(resolveResult, ident, value.get());
    635634        return oldValue;
     
    643642        oldValue = 0;
    644643        emitPreIncOrDec(generator, value.get(), m_operator);
    645     } else {
     644    } else
    646645        oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
    647     }
    648646    generator.emitPutById(base.get(), ident, value.get());
    649647    return oldValue;
     
    662660    generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
    663661    RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
    664     RegisterID* oldValue;
    665662    if (dst == generator.ignoredResult()) {
    666         oldValue = 0;
    667         if (m_operator == OpPlusPlus)
    668             generator.emitPreInc(value.get());
    669         else
    670             generator.emitPreDec(value.get());
    671     } else {
    672         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
    673     }
     663        emitPreIncOrDec(generator, value.get(), m_operator);
     664        generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     665        generator.emitPutByVal(base.get(), property.get(), value.get());
     666        return 0;
     667    }
     668    RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
    674669    generator.emitExpressionInfo(divot(), startOffset(), endOffset());
    675670    generator.emitPutByVal(base.get(), property.get(), value.get());
    676     return oldValue;
     671    return generator.moveToDestinationIfNeeded(dst, oldValue);
    677672}
    678673
     
    688683    generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
    689684    RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
    690     RegisterID* oldValue;
    691685    if (dst == generator.ignoredResult()) {
    692         oldValue = 0;
    693         if (m_operator == OpPlusPlus)
    694             generator.emitPreInc(value.get());
    695         else
    696             generator.emitPreDec(value.get());
    697     } else {
    698         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
    699     }
     686        emitPreIncOrDec(generator, value.get(), m_operator);
     687        generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     688        generator.emitPutById(base.get(), ident, value.get());
     689        return 0;
     690    }
     691    RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
    700692    generator.emitExpressionInfo(divot(), startOffset(), endOffset());
    701693    generator.emitPutById(base.get(), ident, value.get());
    702     return oldValue;
     694    return generator.moveToDestinationIfNeeded(dst, oldValue);
    703695}
    704696
     
    855847    generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
    856848    RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
    857     if (m_operator == OpPlusPlus)
    858         generator.emitPreInc(value);
    859     else
    860         generator.emitPreDec(value);
     849    emitPreIncOrDec(generator, value, m_operator);
    861850    generator.emitExpressionInfo(divot(), startOffset(), endOffset());
    862851    generator.emitPutByVal(base.get(), property.get(), value);
     
    876865    generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
    877866    RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
    878     if (m_operator == OpPlusPlus)
    879         generator.emitPreInc(value);
    880     else
    881         generator.emitPreDec(value);
     867    emitPreIncOrDec(generator, value, m_operator);
    882868    generator.emitExpressionInfo(divot(), startOffset(), endOffset());
    883869    generator.emitPutById(base.get(), ident, value);
Note: See TracChangeset for help on using the changeset viewer.