Ignore:
Timestamp:
Aug 14, 2015, 4:50:25 PM (10 years ago)
Author:
[email protected]
Message:

ES6 class syntax should allow computed name method
https://bugs.webkit.org/show_bug.cgi?id=142690

Reviewed by Saam Barati.

Source/JavaScriptCore:

Added a new "attributes" attribute to op_put_getter_by_id, op_put_setter_by_id, op_put_getter_setter to specify
the property descriptor options so that we can use use op_put_setter_by_id and op_put_getter_setter to define
getters and setters for classes. Without this, getters and setters could erroneously override methods.

  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitDirectPutById):
(JSC::BytecodeGenerator::emitPutGetterById):
(JSC::BytecodeGenerator::emitPutSetterById):
(JSC::BytecodeGenerator::emitPutGetterSetter):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::PropertyListNode::emitBytecode): Always use emitPutGetterSetter to emit getters and setters for classes
as done for object literals.
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::ClassExprNode::emitBytecode):

  • jit/CCallHelpers.h:

(JSC::CCallHelpers::setupArgumentsWithExecState):

  • jit/JIT.h:
  • jit/JITInlines.h:

(JSC::JIT::callOperation):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_put_getter_by_id):
(JSC::JIT::emit_op_put_setter_by_id):
(JSC::JIT::emit_op_put_getter_setter):
(JSC::JIT::emit_op_del_by_id):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_put_getter_by_id):
(JSC::JIT::emit_op_put_setter_by_id):
(JSC::JIT::emit_op_put_getter_setter):
(JSC::JIT::emit_op_del_by_id):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LowLevelInterpreter.asm:
  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createProperty):
(JSC::ASTBuilder::createPropertyList):

  • parser/NodeConstructors.h:

(JSC::PropertyNode::PropertyNode):

  • parser/Nodes.h:

(JSC::PropertyNode::expressionName):
(JSC::PropertyNode::name):

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseClass): Added the support for computed property name. We don't support computed names
for getters and setters.

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createProperty):

  • runtime/JSObject.cpp:

(JSC::JSObject::allowsAccessFrom):
(JSC::JSObject::putGetter):
(JSC::JSObject::putSetter):

  • runtime/JSObject.h:
  • runtime/PropertyDescriptor.h:

LayoutTests:

Added test cases for computed method names.

  • js/class-syntax-method-names-expected.txt:
  • js/script-tests/class-syntax-method-names.js:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r188417 r188498  
    19621962        // FIXME: Figure out a way to share more code with parseProperty.
    19631963        const CommonIdentifiers& propertyNames = *m_vm->propertyNames;
    1964         const Identifier* ident = nullptr;
     1964        const Identifier* ident = &propertyNames.nullIdentifier;
     1965        TreeExpression computedPropertyName = 0;
    19651966        bool isGetter = false;
    19661967        bool isSetter = false;
     
    19861987            next();
    19871988            break;
     1989        case OPENBRACKET:
     1990            next();
     1991            computedPropertyName = parseAssignmentExpression(context);
     1992            failIfFalse(computedPropertyName, "Cannot parse computed property name");
     1993            handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
     1994            break;
    19881995        default:
    19891996            failDueToUnexpectedToken();
     
    20002007            bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
    20012008            failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::MethodMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method");
    2002             failIfTrue(!ident || (declareVariable(ident) & DeclarationResult::InvalidStrictMode), "Cannot declare a method named '", methodInfo.name->impl(), "'");
     2009            failIfTrue(!computedPropertyName && (declareVariable(ident) & DeclarationResult::InvalidStrictMode), "Cannot declare a method named '", methodInfo.name->impl(), "'");
    20032010            methodInfo.name = isConstructor ? className : ident;
    20042011
     
    20132020            semanticFailIfTrue(isStaticMethod && methodInfo.name && *methodInfo.name == propertyNames.prototype,
    20142021                "Cannot declare a static method named 'prototype'");
    2015             property = context.createProperty(methodInfo.name, method, PropertyNode::Constant, PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed);
     2022            if (computedPropertyName) {
     2023                property = context.createProperty(computedPropertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed),
     2024                    PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed);
     2025            } else
     2026                property = context.createProperty(methodInfo.name, method, PropertyNode::Constant, PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed);
    20162027        }
    20172028
Note: See TracChangeset for help on using the changeset viewer.