Ignore:
Timestamp:
Aug 25, 2020, 8:58:40 AM (5 years ago)
Author:
Alexey Shvayka
Message:

Invalid early error for object literal method named "proto"
https://bugs.webkit.org/show_bug.cgi?id=215760

Reviewed by Ross Kirsling.

JSTests:

  • test262/expectations.yaml: Mark 2 test cases as passing.

Source/JavaScriptCore:

According to Annex B [1], { __proto__: null, __proto__() {} } is a valid object literal as the second
__proto__ wasn't obtained from PropertyDefinition : PropertyName : AssignmentExpression production.
Currently, JSC throws an early SyntaxError, unlike V8 and SpiderMonkey.

Since a method needs super binding, the most straightforward fix would be adding SuperBinding field
to SyntaxChecker::Property and exposing it via an accessor. However, given that Property is a very
common structure, this approach would noticeably increase memory pressure during parsing.

Instead, this patch reworks SyntaxChecker::Property to accept isUnderscoreProtoSetter parameter,
removing optional name field, its accessor, and shouldCheckPropertyForUnderscoreProtoDuplicate(),
which reduces sizeof(SyntaxChecker::Property) by a factor of 8: from 16 to 2 bytes.
Also, this change avoids two extra makeNumericIdentifier() calls, speeding up numeric keys parsing.

This approach is feasible because "proto" is the only identifier-based early error for object
literals [2], with no such errors being added in upcoming stage 2-4 proposals.

Additionally, this patch removes strict / complete bool parameter from {parse,create}Property()
signatures as a) it was always true, b) is now unused, and c) strict mode can be checked via scope.

[1]: https://tc39.es/ecma262/#sec-__proto__-property-names-in-object-initializers
[2]: https://tc39.es/ecma262/#sec-object-initializer-static-semantics-early-errors

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createGetterOrSetterProperty):
(JSC::ASTBuilder::createProperty):
(JSC::ASTBuilder::isUnderscoreProtoSetter const):
(JSC::ASTBuilder::getName const): Deleted.

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

(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parseGetterSetter):
(JSC::Parser<LexerType>::parseObjectLiteral):
(JSC::Parser<LexerType>::shouldCheckPropertyForUnderscoreProtoDuplicate): Deleted.

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

(JSC::SyntaxChecker::SyntaxChecker):
(JSC::SyntaxChecker::Property::Property):
(JSC::SyntaxChecker::Property::operator!):
(JSC::SyntaxChecker::createProperty):
(JSC::SyntaxChecker::createGetterOrSetterProperty):
(JSC::SyntaxChecker::operatorStackPop):

File:
1 edited

Legend:

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

    r266106 r266117  
    747747        PutType putType() const { return static_cast<PutType>(m_putType); }
    748748
     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;
     752        }
     753
    749754    private:
    750755        friend class PropertyListNode;
Note: See TracChangeset for help on using the changeset viewer.