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/Nodes.h

    r227692 r229608  
    696696    };
    697697
     698    enum class ClassElementTag { No, Instance, Static, LastTag };
    698699    class PropertyNode : public ParserArenaFreeable {
    699700    public:
     
    701702        enum PutType { Unknown, KnownDirect };
    702703
    703         PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);
    704         PropertyNode(ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);
    705         PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);
     704        PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
     705        PropertyNode(ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
     706        PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
    706707
    707708        ExpressionNode* expressionName() const { return m_expression; }
     
    710711        Type type() const { return static_cast<Type>(m_type); }
    711712        bool needsSuperBinding() const { return m_needsSuperBinding; }
    712         bool isClassProperty() const { return m_isClassProperty; }
     713        bool isClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) != ClassElementTag::No; }
     714        bool isStaticClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) == ClassElementTag::Static; }
     715        bool isInstanceClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) == ClassElementTag::Instance; }
    713716        bool isOverriddenByDuplicate() const { return m_isOverriddenByDuplicate; }
    714717        void setIsOverriddenByDuplicate() { m_isOverriddenByDuplicate = true; }
     
    723726        unsigned m_needsSuperBinding : 1;
    724727        unsigned m_putType : 1;
    725         unsigned m_isClassProperty: 1;
     728        static_assert(1 << 2 > static_cast<unsigned>(ClassElementTag::LastTag), "ClassElementTag shouldn't use more than two bits");
     729        unsigned m_classElementTag : 2;
    726730        unsigned m_isOverriddenByDuplicate: 1;
    727731    };
     
    734738        bool hasStaticallyNamedProperty(const Identifier& propName);
    735739
    736     private:
    737         RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     740        RegisterID* emitBytecode(BytecodeGenerator&, RegisterID*, RegisterID*);
     741
     742    private:
     743        RegisterID* emitBytecode(BytecodeGenerator& generator, RegisterID* dst = nullptr) override
     744        {
     745            return emitBytecode(generator, dst, nullptr);
     746        }
    738747        void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
    739748
     
    21402149        ClassExprNode(const JSTokenLocation&, const Identifier&, const SourceCode& classSource,
    21412150            VariableEnvironment& classEnvironment, ExpressionNode* constructorExpresssion,
    2142             ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods);
     2151            ExpressionNode* parentClass, PropertyListNode* classElements);
    21432152
    21442153        const Identifier& name() { return m_name; }
     
    21462155        void setEcmaName(const Identifier& name) { m_ecmaName = m_name.isNull() ? &name : &m_name; }
    21472156
    2148         bool hasStaticProperty(const Identifier& propName) { return m_staticMethods ? m_staticMethods->hasStaticallyNamedProperty(propName) : false; }
     2157        bool hasStaticProperty(const Identifier& propName) { return m_classElements ? m_classElements->hasStaticallyNamedProperty(propName) : false; }
    21492158
    21502159    private:
     
    21582167        ExpressionNode* m_constructorExpression;
    21592168        ExpressionNode* m_classHeritage;
    2160         PropertyListNode* m_instanceMethods;
    2161         PropertyListNode* m_staticMethods;
     2169        PropertyListNode* m_classElements;
    21622170    };
    21632171
Note: See TracChangeset for help on using the changeset viewer.