Ignore:
Timestamp:
Mar 14, 2018, 1:00:21 PM (7 years ago)
Author:
[email protected]
Message:

[JSC] fix order of evaluation for ClassDefinitionEvaluation
https://bugs.webkit.org/show_bug.cgi?id=183523

Reviewed by Keith Miller.

Computed property names need to be evaluated in source order during class
definition evaluation, as it's observable (and specified to work this way).

This change improves compatibility with Chromium.

JSTests:

  • stress/class_elements.js: Added.

(test):
(test.C.prototype.effect):
(test.C.effect):
(test.C.prototype.get effect):
(test.C.prototype.set effect):
(test.C):

Source/JavaScriptCore:

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::emitDefineClassElements):

  • bytecompiler/NodesCodegen.cpp:

(JSC::PropertyListNode::emitBytecode):
(JSC::ClassExprNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createClassExpr):
(JSC::ASTBuilder::createGetterOrSetterProperty):
(JSC::ASTBuilder::createProperty):

  • parser/NodeConstructors.h:

(JSC::PropertyNode::PropertyNode):
(JSC::ClassExprNode::ClassExprNode):

  • parser/Nodes.cpp:

(JSC::PropertyListNode::hasStaticallyNamedProperty):

  • parser/Nodes.h:

(JSC::PropertyNode::isClassProperty const):
(JSC::PropertyNode::isStaticClassProperty const):
(JSC::PropertyNode::isInstanceClassProperty const):

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parseGetterSetter):

  • parser/Parser.h:
  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createClassExpr):
(JSC::SyntaxChecker::createProperty):
(JSC::SyntaxChecker::createGetterOrSetterProperty):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r226128 r229608  
    398398
    399399    ClassExprNode* createClassExpr(const JSTokenLocation& location, const ParserClassInfo<ASTBuilder>& classInfo, VariableEnvironment& classEnvironment, ExpressionNode* constructor,
    400         ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
     400        ExpressionNode* parentClass, PropertyListNode* classElements)
    401401    {
    402402        SourceCode source = m_sourceCode->subExpression(classInfo.startOffset, classInfo.endOffset, classInfo.startLine, classInfo.startColumn);
    403         return new (m_parserArena) ClassExprNode(location, *classInfo.className, source, classEnvironment, constructor, parentClass, instanceMethods, staticMethods);
     403        return new (m_parserArena) ClassExprNode(location, *classInfo.className, source, classEnvironment, constructor, parentClass, classElements);
    404404    }
    405405
     
    471471
    472472    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool,
    473         const Identifier* name, const ParserFunctionInfo<ASTBuilder>& functionInfo, bool isClassProperty)
     473        const Identifier* name, const ParserFunctionInfo<ASTBuilder>& functionInfo, ClassElementTag tag)
    474474    {
    475475        ASSERT(name);
     
    479479        SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
    480480        MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm->propertyNames->nullIdentifier, functionInfo.body, source);
    481         return new (m_parserArena) PropertyNode(*name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, isClassProperty);
     481        return new (m_parserArena) PropertyNode(*name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, tag);
    482482    }
    483483
    484484    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool,
    485         ExpressionNode* name, const ParserFunctionInfo<ASTBuilder>& functionInfo, bool isClassProperty)
     485        ExpressionNode* name, const ParserFunctionInfo<ASTBuilder>& functionInfo, ClassElementTag tag)
    486486    {
    487487        ASSERT(name);
     
    489489        SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
    490490        MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm->propertyNames->nullIdentifier, functionInfo.body, source);
    491         return new (m_parserArena) PropertyNode(name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, isClassProperty);
     491        return new (m_parserArena) PropertyNode(name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, tag);
    492492    }
    493493
    494494    NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type, bool,
    495         double name, const ParserFunctionInfo<ASTBuilder>& functionInfo, bool isClassProperty)
     495        double name, const ParserFunctionInfo<ASTBuilder>& functionInfo, ClassElementTag tag)
    496496    {
    497497        functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
     
    499499        SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
    500500        MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, vm->propertyNames->nullIdentifier, functionInfo.body, source);
    501         return new (m_parserArena) PropertyNode(ident, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, isClassProperty);
    502     }
    503 
    504     PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, InferName inferName, bool isClassProperty)
     501        return new (m_parserArena) PropertyNode(ident, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, tag);
     502    }
     503
     504    PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, InferName inferName, ClassElementTag tag)
    505505    {
    506506        if (inferName == InferName::Allowed) {
     
    512512                static_cast<ClassExprNode*>(node)->setEcmaName(*propertyName);
    513513        }
    514         return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding, isClassProperty);
    515     }
    516     PropertyNode* createProperty(ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, bool isClassProperty)
    517     {
    518         return new (m_parserArena) PropertyNode(node, type, putType, superBinding, isClassProperty);
    519     }
    520     PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, bool isClassProperty)
    521     {
    522         return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, putType, superBinding, isClassProperty);
    523     }
    524     PropertyNode* createProperty(ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, bool isClassProperty) { return new (m_parserArena) PropertyNode(propertyName, node, type, putType, superBinding, isClassProperty); }
     514        return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding, tag);
     515    }
     516    PropertyNode* createProperty(ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, ClassElementTag tag)
     517    {
     518        return new (m_parserArena) PropertyNode(node, type, putType, superBinding, tag);
     519    }
     520    PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, ClassElementTag tag)
     521    {
     522        return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, putType, superBinding, tag);
     523    }
     524    PropertyNode* createProperty(ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding, ClassElementTag tag) { return new (m_parserArena) PropertyNode(propertyName, node, type, putType, superBinding, tag); }
    525525    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_parserArena) PropertyListNode(location, property); }
    526526    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_parserArena) PropertyListNode(location, property, tail); }
Note: See TracChangeset for help on using the changeset viewer.