Ignore:
Timestamp:
Jun 12, 2020, 8:09:21 PM (5 years ago)
Author:
[email protected]
Message:
The
operator (and similar ones) should produce valid bytecode even if the right side is a static error

https://bugs.webkit.org/show_bug.cgi?id=213154

Reviewed by Devin Rousso.

JSTests:

  • stress/bytecode-for-rmw-with-invalid-right-side.js: Added.

(catch):

Source/JavaScriptCore:

There were two minor issues here that interacted:

  • emitThrowReferenceError did not take an optional dst argument like everything else, and instead always returned a new temporary. As a result, the various functions that sometimes did "return emitThrowReferenceError(..);" could return a different RegisterID than the one provided to them through dst, breaking the invariant stated at the top of the file.
  • ShortCircuitReadModifyResolveNode::emitBytecode used the result of such a function, unnecessarily, and (correctly) relied on the invariant being upheld.

The combination of these led to the bytecode trying to do a move of a temporary that was only defined in one of the predecessors of the basic block it was on,
which was caught by validateBytecode.

I fixed both issues, and verified that either fix is enough to stop the bug.
I fixed the first because other code may depend on that invariant in more subtle ways.
I fixed the second because it was just unnecessary complexity and made the code misleading.

I also reworded the comment at the top of NodesCodegen.cpp based on Keith's explanation and Mark's advice to make it less cryptic.

  • bytecompiler/NodesCodegen.cpp:

(JSC::ThrowableExpressionData::emitThrowReferenceError):
(JSC::PostfixNode::emitBytecode):
(JSC::DeleteBracketNode::emitBytecode):
(JSC::DeleteDotNode::emitBytecode):
(JSC::PrefixNode::emitBytecode):
(JSC::ShortCircuitReadModifyResolveNode::emitBytecode):
(JSC::AssignErrorNode::emitBytecode):

  • parser/Nodes.h:
File:
1 edited

Legend:

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

    r262613 r262995  
    5656    Return value: The register holding the production's value.
    5757             dst: An optional parameter specifying the most efficient destination at
    58                   which to store the production's value. The callee must honor dst.
     58                  which to store the production's value.
     59                  If dst is null, you may return whatever VirtualRegister you want. Otherwise you have to return dst.
    5960
    6061    The dst argument provides for a crude form of copy propagation. For example,
     
    6364
    6465    becomes
    65    
     66
    6667        load r[x], 1
    67    
     68
    6869    instead of
    6970
    7071        load r0, 1
    7172        mov r[x], r0
    72    
     73
    7374    because the assignment node, "x =", passes r[x] as dst to the number node, "1".
    7475*/
     
    8586// ------------------------------ ThrowableExpressionData --------------------------------
    8687
    87 RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
     88RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message, RegisterID* dst)
    8889{
    8990    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    9091    generator.emitThrowReferenceError(message);
     92    if (dst)
     93        return dst;
    9194    return generator.newTemporary();
    9295}
     
    22482251    return emitThrowReferenceError(generator, m_operator == Operator::PlusPlus
    22492252        ? "Postfix ++ operator applied to value that is not a reference."_s
    2250         : "Postfix -- operator applied to value that is not a reference."_s);
     2253        : "Postfix -- operator applied to value that is not a reference."_s,
     2254        dst);
    22512255}
    22522256
     
    22802284    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    22812285    if (m_base->isSuperNode())
    2282         return emitThrowReferenceError(generator, "Cannot delete a super property");
     2286        return emitThrowReferenceError(generator, "Cannot delete a super property", dst);
    22832287    return generator.emitDeleteByVal(finalDest.get(), r0.get(), r1.get());
    22842288}
     
    22962300    generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
    22972301    if (m_base->isSuperNode())
    2298         return emitThrowReferenceError(generator, "Cannot delete a super property");
     2302        return emitThrowReferenceError(generator, "Cannot delete a super property", dst);
    22992303    return generator.emitDeleteById(finalDest.get(), r0.get(), m_ident);
    23002304}
     
    24852489    return emitThrowReferenceError(generator, m_operator == Operator::PlusPlus
    24862490        ? "Prefix ++ operator applied to value that is not a reference."_s
    2487         : "Prefix -- operator applied to value that is not a reference."_s);
     2491        : "Prefix -- operator applied to value that is not a reference."_s,
     2492        dst);
    24882493}
    24892494
     
    32003205    emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
    32013206
    3202     result = generator.emitNode(result.get(), m_right); // Execute side effects first.
     3207    generator.emitNode(result.get(), m_right); // Execute side effects first.
    32033208
    32043209    bool threwException = isReadOnly ? generator.emitReadOnlyExceptionIfNeeded(var) : false;
     
    33533358// ------------------------------ AssignErrorNode -----------------------------------
    33543359
    3355 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    3356 {
    3357     return emitThrowReferenceError(generator, "Left side of assignment is not a reference."_s);
     3360RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     3361{
     3362    return emitThrowReferenceError(generator, "Left side of assignment is not a reference."_s, dst);
    33583363}
    33593364
Note: See TracChangeset for help on using the changeset viewer.