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/bytecompiler/NodesCodegen.cpp

    r228725 r229608  
    509509}
    510510
    511 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     511RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dstOrConstructor, RegisterID* prototype)
    512512{
    513513    // Fast case: this loop just handles regular value properties.
    514514    PropertyListNode* p = this;
    515     for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next)
     515    RegisterID* dst = nullptr;
     516    for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next) {
     517        dst = p->m_node->isInstanceClassProperty() ? prototype : dstOrConstructor;
    516518        emitPutConstantProperty(generator, dst, *p->m_node);
     519    }
    517520
    518521    // Were there any get/set properties?
     
    524527        typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
    525528        typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
    526         GetterSetterMap map;
     529        GetterSetterMap instanceMap;
     530        GetterSetterMap staticMap;
    527531
    528532        // Build a map, pairing get/set values together.
     
    539543            // Duplicates are possible.
    540544            GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
     545            GetterSetterMap& map = node->isStaticClassProperty() ? staticMap : instanceMap;
    541546            GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
    542547            auto& resultPair = result.iterator->value;
     
    556561        for (; p; p = p->m_next) {
    557562            PropertyNode* node = p->m_node;
     563            dst = node->isInstanceClassProperty() ? prototype : dstOrConstructor;
    558564
    559565            // Handle regular values.
     
    596602
    597603            // This is a get/set property pair.
     604            GetterSetterMap& map = node->isStaticClassProperty() ? staticMap : instanceMap;
    598605            GetterSetterMap::iterator it = map.find(node->name()->impl());
    599606            ASSERT(it != map.end());
     
    640647    }
    641648
    642     return dst;
     649    return dstOrConstructor;
    643650}
    644651
     
    39523959    generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
    39533960
    3954     if (m_staticMethods)
    3955         generator.emitNode(constructor.get(), m_staticMethods);
    3956 
    3957     if (m_instanceMethods)
    3958         generator.emitNode(prototype.get(), m_instanceMethods);
     3961    if (m_classElements)
     3962        generator.emitDefineClassElements(m_classElements, constructor.get(), prototype.get());
    39593963
    39603964    if (!m_name.isNull()) {
Note: See TracChangeset for help on using the changeset viewer.