Ignore:
Timestamp:
Sep 23, 2021, 10:24:52 AM (4 years ago)
Author:
Ross Kirsling
Message:

[JSC] Handle syntactic production for #x in expr correctly
https://bugs.webkit.org/show_bug.cgi?id=230668

Reviewed by Yusuke Suzuki.

JSTests:

  • stress/private-in.js: Add tests.
  • test262/expectations.yaml: Mark two test cases as passing.

Source/JavaScriptCore:

The production for #x in expr is easy to get wrong.

RelationalExpression[In, Yield, Await] :

ShiftExpression?Await
RelationalExpression?Yield, ?Await < ShiftExpression?Await
RelationalExpression?Yield, ?Await > ShiftExpression?Await
RelationalExpression?Yield, ?Await <= ShiftExpression?Await
RelationalExpression?Yield, ?Await >= ShiftExpression?Await
RelationalExpression?Yield, ?Await instanceof ShiftExpression?Await
[+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression?Await
[+In] PrivateIdentifier in ShiftExpression?Await

We were ensuring that a standalone private name #x is always followed by operator in;
this patch further ensures that that particular in can't have its LHS misparsed as a RelationalExpression.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseBinaryExpression):
Verify the precedence of the topmost operator on the stack (if any) when parsing standalone #x.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r281429 r282968  
    42394239    bool hasCoalesceOperator = false;
    42404240
     4241    int previousOperator = 0;
    42414242    while (true) {
    42424243        JSTextPosition exprStart = tokenStartPosition();
     
    42514252            m_seenPrivateNameUseInNonReparsingFunctionMode = true;
    42524253            next();
    4253             semanticFailIfTrue(m_token.m_type != INTOKEN, "Bare private name can only be used as the left-hand side of an `in` expression");
     4254            semanticFailIfTrue(m_token.m_type != INTOKEN || previousOperator >= INTOKEN, "Bare private name can only be used as the left-hand side of an `in` expression");
    42544255            current = context.createPrivateIdentifierNode(location, *ident);
    42554256        } else
     
    43084309        }
    43094310        context.operatorStackAppend(operatorStackDepth, operatorToken, precedence);
     4311        previousOperator = operatorToken;
    43104312    }
    43114313    while (operatorStackDepth) {
Note: See TracChangeset for help on using the changeset viewer.