Changeset 266264 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Aug 27, 2020, 5:27:19 PM (5 years ago)
Author:
Alexey Shvayka
Message:

proto in object literal should perform SetPrototypeOf directly
https://bugs.webkit.org/show_bug.cgi?id=215769

Reviewed by Ross Kirsling.

JSTests:

  • microbenchmarks/object-literal-underscore-proto-setter.js: Added.
  • stress/syntax-checker-duplicate-underscore-proto.js:

Rewrite the test to ensure each eval() call throws a SyntaxError.

Source/JavaScriptCore:

To fix proto usage in object literals if Object.prototype.proto is overridden
or removed, this patch sets the Prototype directly, aligning JSC with V8 and
SpiderMonkey. We are safe to skip method table lookups and cycle checks, as the
spec [1] calls SetPrototypeOf on newly created (unreferenced) ordinary objects.

This change removes PropertyNode::PutType because its only purpose was to accomodate
proto in object literals. Since emitPutConstantProperty() handles static public
class fields, which don't need super binding, PropertyNode::isUnderscoreProtoSetter()
is extended to reject class properties.

This patch speeds up creating object literals with proto by 25%.

[1]: https://tc39.es/ecma262/#sec-__proto__-property-names-in-object-initializers (step 7.a)

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitDirectPutById):
(JSC::BytecodeGenerator::emitDirectSetPrototypeOf):

  1. Remove unused dst parameter to align with other put methods.
  2. Remove divot* parameters as it's cumbersome to pass them through, and globalFuncSetPrototypeDirect() never throws anyway.
  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_putByIdDirect):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_putByIdDirectPrivate):
(JSC::ClassExprNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createGetterOrSetterProperty):
(JSC::ASTBuilder::createProperty):
(JSC::ASTBuilder::isUnderscoreProtoSetter const):

  • parser/NodeConstructors.h:

(JSC::PropertyNode::PropertyNode):

  • parser/Nodes.h:
  • parser/Parser.cpp:

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

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createProperty):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncSetPrototypeDirect):

  1. Ignore a prototype value of incorrect type as per spec [1], which is unobservable for call sites in ClassExprNode::emitBytecode().
  2. Assert that JSObject::setPrototypeDirect() doesn't throw.

LayoutTests:

  • js/script-tests/object-literal-direct-put.js:
Location:
trunk/Source/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r266257 r266264  
     12020-08-27  Alexey Shvayka  <[email protected]>
     2
     3        __proto__ in object literal should perform [[SetPrototypeOf]] directly
     4        https://bugs.webkit.org/show_bug.cgi?id=215769
     5
     6        Reviewed by Ross Kirsling.
     7
     8        To fix __proto__ usage in object literals if Object.prototype.__proto__ is overridden
     9        or removed, this patch sets the [[Prototype]] directly, aligning JSC with V8 and
     10        SpiderMonkey. We are safe to skip method table lookups and cycle checks, as the
     11        spec [1] calls [[SetPrototypeOf]] on newly created (unreferenced) ordinary objects.
     12
     13        This change removes PropertyNode::PutType because its only purpose was to accomodate
     14        __proto__ in object literals. Since emitPutConstantProperty() handles static public
     15        class fields, which don't need `super` binding, PropertyNode::isUnderscoreProtoSetter()
     16        is extended to reject class properties.
     17
     18        This patch speeds up creating object literals with __proto__ by 25%.
     19
     20        [1]: https://tc39.es/ecma262/#sec-__proto__-property-names-in-object-initializers (step 7.a)
     21
     22        * bytecompiler/BytecodeGenerator.cpp:
     23        (JSC::BytecodeGenerator::emitDirectPutById):
     24        (JSC::BytecodeGenerator::emitDirectSetPrototypeOf):
     25        1. Remove unused `dst` parameter to align with other `put` methods.
     26        2. Remove `divot*` parameters as it's cumbersome to pass them through,
     27           and globalFuncSetPrototypeDirect() never throws anyway.
     28
     29        * bytecompiler/BytecodeGenerator.h:
     30        * bytecompiler/NodesCodegen.cpp:
     31        (JSC::PropertyListNode::emitPutConstantProperty):
     32        (JSC::BytecodeIntrinsicNode::emit_intrinsic_putByIdDirect):
     33        (JSC::BytecodeIntrinsicNode::emit_intrinsic_putByIdDirectPrivate):
     34        (JSC::ClassExprNode::emitBytecode):
     35        * parser/ASTBuilder.h:
     36        (JSC::ASTBuilder::createGetterOrSetterProperty):
     37        (JSC::ASTBuilder::createProperty):
     38        (JSC::ASTBuilder::isUnderscoreProtoSetter const):
     39        * parser/NodeConstructors.h:
     40        (JSC::PropertyNode::PropertyNode):
     41        * parser/Nodes.h:
     42        * parser/Parser.cpp:
     43        (JSC::Parser<LexerType>::parseClass):
     44        (JSC::Parser<LexerType>::parseProperty):
     45        * parser/SyntaxChecker.h:
     46        (JSC::SyntaxChecker::createProperty):
     47        * runtime/JSGlobalObjectFunctions.cpp:
     48        (JSC::globalFuncSetPrototypeDirect):
     49        1. Ignore a prototype value of incorrect type as per spec [1],
     50           which is unobservable for call sites in ClassExprNode::emitBytecode().
     51        2. Assert that JSObject::setPrototypeDirect() doesn't throw.
     52
    1532020-08-27  Yusuke Suzuki  <[email protected]>
    254
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r266106 r266264  
    25772577}
    25782578
    2579 RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType putType)
     2579RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
    25802580{
    25812581    ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with put_by_val(direct).");
     
    25852585    m_staticPropertyAnalyzer.putById(base, propertyIndex);
    25862586
    2587     PutByIdFlags type = (putType == PropertyNode::KnownDirect || property != m_vm.propertyNames->underscoreProto) ? PutByIdFlags::createDirect(ecmaMode()) : PutByIdFlags::create(ecmaMode());
     2587    PutByIdFlags type = PutByIdFlags::createDirect(ecmaMode());
    25882588    OpPutById::emit(this, base, propertyIndex, value, type);
    25892589    return value;
     
    26932693}
    26942694
    2695 RegisterID* BytecodeGenerator::emitDirectSetPrototypeOf(RegisterID* dst, RegisterID* base, RegisterID* prototype, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
     2695RegisterID* BytecodeGenerator::emitDirectSetPrototypeOf(RegisterID* base, RegisterID* prototype)
    26962696{
    26972697    RefPtr<RegisterID> setPrototypeDirect = moveLinkTimeConstant(nullptr, LinkTimeConstant::setPrototypeDirect);
     
    27012701    move(args.argumentRegister(0), prototype);
    27022702
    2703     emitCall(newTemporary(), setPrototypeDirect.get(), NoExpectedFunction, args, divot, divotStart, divotEnd, DebuggableCall::No);
    2704     return dst;
     2703    JSTextPosition position;
     2704    emitCall(newTemporary(), setPrototypeDirect.get(), NoExpectedFunction, args, position, position, position, DebuggableCall::No);
     2705    return base;
    27052706}
    27062707
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r266106 r266264  
    808808        RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
    809809        RegisterID* emitPutById(RegisterID* base, RegisterID* thisValue, const Identifier& property, RegisterID* value);
    810         RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
     810        RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value);
    811811        RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
    812812        RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
    813813        RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property);
    814814        RegisterID* emitGetPrototypeOf(RegisterID* dst, RegisterID* value);
    815         RegisterID* emitDirectSetPrototypeOf(RegisterID* dst, RegisterID* base, RegisterID* prototype, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
     815        RegisterID* emitDirectSetPrototypeOf(RegisterID* base, RegisterID* prototype);
    816816        RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
    817817        RegisterID* emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value);
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r266106 r266264  
    748748    ASSERT(!(node.type() & PropertyNode::Private));
    749749
     750    if (PropertyNode::isUnderscoreProtoSetter(generator.vm(), node)) {
     751        RefPtr<RegisterID> prototype = generator.emitNode(node.m_assign);
     752        generator.emitDirectSetPrototypeOf(newObj, prototype.get());
     753        return;
     754    }
     755
    750756    bool shouldSetFunctionName = generator.shouldSetFunctionName(node.m_assign);
    751757
     
    778784        Optional<uint32_t> optionalIndex = parseIndex(*identifier);
    779785        if (!optionalIndex) {
    780             generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
     786            generator.emitDirectPutById(newObj, *identifier, value.get());
    781787            return;
    782788        }
     
    13951401    ASSERT(!node->m_next);
    13961402
    1397     return generator.move(dst, generator.emitDirectPutById(base.get(), ident, value.get(), PropertyNode::KnownDirect));
     1403    return generator.move(dst, generator.emitDirectPutById(base.get(), ident, value.get()));
    13981404}
    13991405
     
    14111417    ASSERT(!node->m_next);
    14121418
    1413     return generator.move(dst, generator.emitDirectPutById(base.get(), generator.parserArena().identifierArena().makeIdentifier(generator.vm(), symbol), value.get(), PropertyNode::KnownDirect));
     1419    return generator.move(dst, generator.emitDirectPutById(base.get(), generator.parserArena().identifierArena().makeIdentifier(generator.vm(), symbol), value.get()));
    14141420}
    14151421
     
    49094915        generator.emitLabel(protoParentIsObjectOrNullLabel.get());
    49104916
    4911         generator.emitDirectSetPrototypeOf(tempRegister.get(), constructor.get(), superclass.get(), divot(), divotStart(), divotEnd());
     4917        generator.emitDirectSetPrototypeOf(constructor.get(), superclass.get());
    49124918        generator.emitLabel(superclassIsNullLabel.get());
    4913         generator.emitDirectSetPrototypeOf(tempRegister.get(), prototype.get(), protoParent.get(), divot(), divotStart(), divotEnd());
     4919        generator.emitDirectSetPrototypeOf(prototype.get(), protoParent.get());
    49144920    }
    49154921
     
    49364942            emitPutHomeObject(generator, instanceFieldInitializer.get(), prototype.get());
    49374943
    4938             generator.emitDirectPutById(constructor.get(), generator.propertyNames().builtinNames().instanceFieldInitializerPrivateName(), instanceFieldInitializer.get(), PropertyNode::Unknown);
     4944            generator.emitDirectPutById(constructor.get(), generator.propertyNames().builtinNames().instanceFieldInitializerPrivateName(), instanceFieldInitializer.get());
    49394945        }
    49404946    }
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r266117 r266264  
    490490        SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
    491491        MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm.propertyNames->nullIdentifier, functionInfo.body, source);
    492         return new (m_parserArena) PropertyNode(*name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, tag);
     492        return new (m_parserArena) PropertyNode(*name, methodDef, type, SuperBinding::Needed, tag);
    493493    }
    494494
     
    500500        SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
    501501        MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm.propertyNames->nullIdentifier, functionInfo.body, source);
    502         return new (m_parserArena) PropertyNode(name, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, tag);
     502        return new (m_parserArena) PropertyNode(name, methodDef, type, SuperBinding::Needed, tag);
    503503    }
    504504
     
    510510        SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
    511511        MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, vm.propertyNames->nullIdentifier, functionInfo.body, source);
    512         return new (m_parserArena) PropertyNode(ident, methodDef, type, PropertyNode::Unknown, SuperBinding::Needed, tag);
    513     }
    514 
    515     PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, SuperBinding superBinding, InferName inferName, ClassElementTag tag)
     512        return new (m_parserArena) PropertyNode(ident, methodDef, type, SuperBinding::Needed, tag);
     513    }
     514
     515    PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, InferName inferName, ClassElementTag tag)
    516516    {
    517517        if (inferName == InferName::Allowed) {
     
    522522                static_cast<ClassExprNode*>(node)->setEcmaName(*propertyName);
    523523        }
    524         return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding, tag);
    525     }
    526     PropertyNode* createProperty(ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, SuperBinding superBinding, ClassElementTag tag)
    527     {
    528         return new (m_parserArena) PropertyNode(node, type, putType, superBinding, tag);
    529     }
    530     PropertyNode* createProperty(VM& vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, SuperBinding superBinding, ClassElementTag tag)
    531     {
    532         return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, putType, superBinding, tag);
    533     }
    534     PropertyNode* createProperty(ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, SuperBinding superBinding, ClassElementTag tag) { return new (m_parserArena) PropertyNode(propertyName, node, type, putType, superBinding, tag); }
    535     PropertyNode* createProperty(const Identifier* identifier, ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, SuperBinding superBinding, ClassElementTag tag) { return new (m_parserArena) PropertyNode(*identifier, propertyName, node, type, putType, superBinding, tag); }
     524        return new (m_parserArena) PropertyNode(*propertyName, node, type, superBinding, tag);
     525    }
     526    PropertyNode* createProperty(ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag)
     527    {
     528        return new (m_parserArena) PropertyNode(node, type, superBinding, tag);
     529    }
     530    PropertyNode* createProperty(VM& vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag)
     531    {
     532        return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, superBinding, tag);
     533    }
     534    PropertyNode* createProperty(ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag) { return new (m_parserArena) PropertyNode(propertyName, node, type, superBinding, tag); }
     535    PropertyNode* createProperty(const Identifier* identifier, ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag) { return new (m_parserArena) PropertyNode(*identifier, propertyName, node, type, superBinding, tag); }
    536536    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_parserArena) PropertyListNode(location, property); }
    537537    PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_parserArena) PropertyListNode(location, property, tail); }
     
    961961
    962962    PropertyNode::Type getType(const Property& property) const { return property->type(); }
    963     bool isUnderscoreProtoSetter(const Property& property) const
    964     {
    965         return PropertyNode::isUnderscoreProtoSetter(m_vm, property->name(), property->type(), property->needsSuperBinding());
    966     }
    967 
     963    bool isUnderscoreProtoSetter(const Property& property) const { return PropertyNode::isUnderscoreProtoSetter(m_vm, *property); }
    968964    bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
    969965
  • trunk/Source/JavaScriptCore/parser/NodeConstructors.h

    r264750 r266264  
    244244    }
    245245
    246     inline PropertyNode::PropertyNode(const Identifier& name, ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding, ClassElementTag tag)
     246    inline PropertyNode::PropertyNode(const Identifier& name, ExpressionNode* assign, Type type, SuperBinding superBinding, ClassElementTag tag)
    247247        : m_name(&name)
    248248        , m_expression(nullptr)
     
    250250        , m_type(type)
    251251        , m_needsSuperBinding(superBinding == SuperBinding::Needed)
    252         , m_putType(putType)
    253252        , m_classElementTag(static_cast<unsigned>(tag))
    254253        , m_isOverriddenByDuplicate(false)
     
    256255    }
    257256   
    258     inline PropertyNode::PropertyNode(ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding, ClassElementTag tag)
     257    inline PropertyNode::PropertyNode(ExpressionNode* assign, Type type, SuperBinding superBinding, ClassElementTag tag)
    259258        : m_name(nullptr)
    260259        , m_expression(nullptr)
     
    262261        , m_type(type)
    263262        , m_needsSuperBinding(superBinding == SuperBinding::Needed)
    264         , m_putType(putType)
    265263        , m_classElementTag(static_cast<unsigned>(tag))
    266264        , m_isOverriddenByDuplicate(false)
     
    268266    }
    269267
    270     inline PropertyNode::PropertyNode(ExpressionNode* name, ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding, ClassElementTag tag)
     268    inline PropertyNode::PropertyNode(ExpressionNode* name, ExpressionNode* assign, Type type, SuperBinding superBinding, ClassElementTag tag)
    271269        : m_name(nullptr)
    272270        , m_expression(name)
     
    274272        , m_type(type)
    275273        , m_needsSuperBinding(superBinding == SuperBinding::Needed)
    276         , m_putType(putType)
    277274        , m_classElementTag(static_cast<unsigned>(tag))
    278275        , m_isOverriddenByDuplicate(false)
     
    280277    }
    281278
    282     inline PropertyNode::PropertyNode(const Identifier& ident, ExpressionNode* name, ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding, ClassElementTag tag)
     279    inline PropertyNode::PropertyNode(const Identifier& ident, ExpressionNode* name, ExpressionNode* assign, Type type, SuperBinding superBinding, ClassElementTag tag)
    283280        : m_name(&ident)
    284281        , m_expression(name)
     
    286283        , m_type(type)
    287284        , m_needsSuperBinding(superBinding == SuperBinding::Needed)
    288         , m_putType(putType)
    289285        , m_classElementTag(static_cast<unsigned>(tag))
    290286        , m_isOverriddenByDuplicate(false)
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r266117 r266264  
    723723    public:
    724724        enum Type : uint8_t { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16, Spread = 32, Private = 64 };
    725         enum PutType : uint8_t { Unknown, KnownDirect };
    726 
    727         PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
    728         PropertyNode(ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
    729         PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
    730         PropertyNode(const Identifier&, ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
     725
     726        PropertyNode(const Identifier&, ExpressionNode*, Type, SuperBinding, ClassElementTag);
     727        PropertyNode(ExpressionNode*, Type, SuperBinding, ClassElementTag);
     728        PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, SuperBinding, ClassElementTag);
     729        PropertyNode(const Identifier&, ExpressionNode* propertyName, ExpressionNode*, Type, SuperBinding, ClassElementTag);
    731730
    732731        ExpressionNode* expressionName() const { return m_expression; }
     
    745744        bool isComputedClassField() const { return isClassField() && hasComputedName(); }
    746745        void setIsOverriddenByDuplicate() { m_isOverriddenByDuplicate = true; }
    747         PutType putType() const { return static_cast<PutType>(m_putType); }
    748 
    749         ALWAYS_INLINE static bool isUnderscoreProtoSetter(VM& vm, const Identifier* name, Type type, bool needsSuperBinding)
    750         {
    751             return name && *name == vm.propertyNames->underscoreProto && type == Type::Constant && !needsSuperBinding;
     746
     747        ALWAYS_INLINE static bool isUnderscoreProtoSetter(VM& vm, const PropertyNode& node)
     748        {
     749            return isUnderscoreProtoSetter(vm, node.name(), node.type(), node.needsSuperBinding(), node.isClassProperty());
     750        }
     751
     752        ALWAYS_INLINE static bool isUnderscoreProtoSetter(VM& vm, const Identifier* name, Type type, bool needsSuperBinding, bool isClassProperty)
     753        {
     754            return name && *name == vm.propertyNames->underscoreProto && type == Type::Constant && !needsSuperBinding && !isClassProperty;
    752755        }
    753756
     
    759762        unsigned m_type : 7;
    760763        unsigned m_needsSuperBinding : 1;
    761         unsigned m_putType : 1;
    762764        static_assert(1 << 2 > static_cast<unsigned>(ClassElementTag::LastTag), "ClassElementTag shouldn't use more than two bits");
    763765        unsigned m_classElementTag : 2;
     
    23292331    };
    23302332
    2331     class ClassExprNode final : public ExpressionNode, public ThrowableExpressionData, public VariableEnvironmentNode {
     2333    class ClassExprNode final : public ExpressionNode, public VariableEnvironmentNode {
    23322334        JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ClassExprNode);
    23332335    public:
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r266117 r266264  
    30103010            auto inferName = initializer ? InferName::Allowed : InferName::Disallowed;
    30113011            if (computedPropertyName)
    3012                 property = context.createProperty(ident, computedPropertyName, initializer, type, PropertyNode::Unknown, SuperBinding::NotNeeded, tag);
     3012                property = context.createProperty(ident, computedPropertyName, initializer, type, SuperBinding::NotNeeded, tag);
    30133013            else
    3014                 property = context.createProperty(ident, initializer, type, PropertyNode::Unknown, SuperBinding::NotNeeded, inferName, tag);
     3014                property = context.createProperty(ident, initializer, type, SuperBinding::NotNeeded, inferName, tag);
    30153015        } else {
    30163016            ParserFunctionInfo<TreeBuilder> methodInfo;
     
    30333033
    30343034            if (computedPropertyName) {
    3035                 property = context.createProperty(computedPropertyName, method, type, PropertyNode::Unknown, SuperBinding::Needed, tag);
     3035                property = context.createProperty(computedPropertyName, method, type, SuperBinding::Needed, tag);
    30363036            } else {
    3037                 property = context.createProperty(methodInfo.name, method, type, PropertyNode::Unknown, SuperBinding::Needed, InferName::Allowed, tag);
     3037                property = context.createProperty(methodInfo.name, method, type, SuperBinding::Needed, InferName::Allowed, tag);
    30383038            }
    30393039        }
     
    41564156            context.setEndOffset(node, m_lexer->currentOffset());
    41574157            InferName inferName = ident && *ident == m_vm.propertyNames->underscoreProto ? InferName::Disallowed : InferName::Allowed;
    4158             return context.createProperty(ident, node, PropertyNode::Constant, PropertyNode::Unknown, SuperBinding::NotNeeded, inferName, ClassElementTag::No);
     4158            return context.createProperty(ident, node, PropertyNode::Constant, SuperBinding::NotNeeded, inferName, ClassElementTag::No);
    41594159        }
    41604160
     
    41624162            auto method = parsePropertyMethod(context, ident, parseMode);
    41634163            propagateError();
    4164             return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, SuperBinding::Needed, InferName::Allowed, ClassElementTag::No);
     4164            return context.createProperty(ident, method, PropertyNode::Constant, SuperBinding::Needed, InferName::Allowed, ClassElementTag::No);
    41654165        }
    41664166        failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list");
     
    41764176                currentScope()->setInnerArrowFunctionUsesEval();
    41774177            TreeExpression node = context.createResolve(location, *ident, start, lastTokenEndPosition());
    4178             return context.createProperty(ident, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Shorthand), PropertyNode::KnownDirect, SuperBinding::NotNeeded, InferName::Allowed, ClassElementTag::No);
     4178            return context.createProperty(ident, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Shorthand), SuperBinding::NotNeeded, InferName::Allowed, ClassElementTag::No);
    41794179        }
    41804180
     
    42004200            auto method = parsePropertyMethod(context, &ident, parseMode);
    42014201            propagateError();
    4202             return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, SuperBinding::Needed, InferName::Allowed, ClassElementTag::No);
     4202            return context.createProperty(&ident, method, PropertyNode::Constant, SuperBinding::Needed, InferName::Allowed, ClassElementTag::No);
    42034203        }
    42044204        failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list");
     
    42084208        failIfFalse(node, "Cannot parse expression for property declaration");
    42094209        context.setEndOffset(node, m_lexer->currentOffset());
    4210         return context.createProperty(const_cast<VM&>(m_vm), m_parserArena, propertyName, node, PropertyNode::Constant, PropertyNode::Unknown, SuperBinding::NotNeeded, ClassElementTag::No);
     4210        return context.createProperty(const_cast<VM&>(m_vm), m_parserArena, propertyName, node, PropertyNode::Constant, SuperBinding::NotNeeded, ClassElementTag::No);
    42114211    }
    42124212    case BIGINT: {
     
    42174217            auto method = parsePropertyMethod(context, ident, parseMode);
    42184218            propagateError();
    4219             return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::Unknown, SuperBinding::Needed, InferName::Allowed, ClassElementTag::No);
     4219            return context.createProperty(ident, method, PropertyNode::Constant, SuperBinding::Needed, InferName::Allowed, ClassElementTag::No);
    42204220        }
    42214221        failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list");
     
    42254225        failIfFalse(node, "Cannot parse expression for property declaration");
    42264226        context.setEndOffset(node, m_lexer->currentOffset());
    4227         return context.createProperty(ident, node, PropertyNode::Constant, PropertyNode::Unknown, SuperBinding::NotNeeded, InferName::Allowed, ClassElementTag::No);
     4227        return context.createProperty(ident, node, PropertyNode::Constant, SuperBinding::NotNeeded, InferName::Allowed, ClassElementTag::No);
    42284228    }
    42294229    case OPENBRACKET: {
     
    42364236            auto method = parsePropertyMethod(context, &m_vm.propertyNames->nullIdentifier, parseMode);
    42374237            propagateError();
    4238             return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, SuperBinding::Needed, ClassElementTag::No);
     4238            return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), SuperBinding::Needed, ClassElementTag::No);
    42394239        }
    42404240        failIfTrue(parseMode != SourceParseMode::MethodMode, "Expected a parenthesis for argument list");
     
    42444244        failIfFalse(node, "Cannot parse expression for property declaration");
    42454245        context.setEndOffset(node, m_lexer->currentOffset());
    4246         return context.createProperty(propertyName, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::Unknown, SuperBinding::NotNeeded, ClassElementTag::No);
     4246        return context.createProperty(propertyName, node, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), SuperBinding::NotNeeded, ClassElementTag::No);
    42474247    }
    42484248    case DOTDOTDOT: {
     
    42544254        failIfFalse(elem, "Cannot parse subject of a spread operation");
    42554255        auto node = context.createObjectSpreadExpression(spreadLocation, elem, start, divot, m_lastTokenEndPosition);
    4256         return context.createProperty(node, PropertyNode::Spread, PropertyNode::Unknown, SuperBinding::NotNeeded, ClassElementTag::No);
     4256        return context.createProperty(node, PropertyNode::Spread, SuperBinding::NotNeeded, ClassElementTag::No);
    42574257    }
    42584258    default:
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r266117 r266264  
    215215    int createArgumentsList(const JSTokenLocation&, int) { return ArgumentsListResult; }
    216216    int createArgumentsList(const JSTokenLocation&, int, int) { return ArgumentsListResult; }
    217     Property createProperty(const Identifier* name, int, PropertyNode::Type type, PropertyNode::PutType, SuperBinding superBinding, InferName, ClassElementTag)
    218     {
    219         return Property(type, PropertyNode::isUnderscoreProtoSetter(m_vm, name, type, superBinding == SuperBinding::Needed));
    220     }
    221     Property createProperty(int, PropertyNode::Type type, PropertyNode::PutType, SuperBinding, ClassElementTag)
    222     {
    223         return Property(type);
    224     }
    225     Property createProperty(VM&, ParserArena&, double, int, PropertyNode::Type type, PropertyNode::PutType, SuperBinding, ClassElementTag)
    226     {
    227         return Property(type);
    228     }
    229     Property createProperty(int, int, PropertyNode::Type type, PropertyNode::PutType, SuperBinding, ClassElementTag)
    230     {
    231         return Property(type);
    232     }
    233     Property createProperty(const Identifier*, int, int, PropertyNode::Type type, PropertyNode::PutType, SuperBinding, ClassElementTag)
     217    Property createProperty(const Identifier* name, int, PropertyNode::Type type, SuperBinding superBinding, InferName, ClassElementTag tag)
     218    {
     219        bool needsSuperBinding = superBinding == SuperBinding::Needed;
     220        bool isClassProperty = tag != ClassElementTag::No;
     221        return Property(type, PropertyNode::isUnderscoreProtoSetter(m_vm, name, type, needsSuperBinding, isClassProperty));
     222    }
     223    Property createProperty(int, PropertyNode::Type type, SuperBinding, ClassElementTag)
     224    {
     225        return Property(type);
     226    }
     227    Property createProperty(VM&, ParserArena&, double, int, PropertyNode::Type type, SuperBinding, ClassElementTag)
     228    {
     229        return Property(type);
     230    }
     231    Property createProperty(int, int, PropertyNode::Type type, SuperBinding, ClassElementTag)
     232    {
     233        return Property(type);
     234    }
     235    Property createProperty(const Identifier*, int, int, PropertyNode::Type type, SuperBinding, ClassElementTag)
    234236    {
    235237        return Property(type);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r266106 r266264  
    734734{
    735735    VM& vm = globalObject->vm();
     736    auto scope = DECLARE_THROW_SCOPE(vm);
    736737
    737738    JSValue value = callFrame->uncheckedArgument(0);
    738     ASSERT(value.isObject() || value.isNull());
    739 
    740     JSObject* object = asObject(callFrame->thisValue());
    741     object->setPrototypeDirect(vm, value);
    742 
     739    if (value.isObject() || value.isNull()) {
     740        JSObject* object = asObject(callFrame->thisValue());
     741        object->setPrototypeDirect(vm, value);
     742    }
     743
     744    scope.assertNoException();
    743745    return { };
    744746}
Note: See TracChangeset for help on using the changeset viewer.