Ignore:
Timestamp:
Sep 8, 2015, 12:43:58 PM (10 years ago)
Author:
Yusuke Suzuki
Message:

[ES6] Implement computed accessors
https://bugs.webkit.org/show_bug.cgi?id=147883

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Implement the computed accessors functionality for class syntax and object literal syntax.
Added new opcodes, op_put_getter_by_val and op_put_setter_by_val. LLInt and baseline JIT support them.
As the same to the other accessor opcodes (like op_put_getter_by_id etc.), DFG / FTL does not support
them. This is handled here[1].

[1]: https://bugs.webkit.org/show_bug.cgi?id=148860

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

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitPutGetterByVal):
(JSC::BytecodeGenerator::emitPutSetterByVal):

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

(JSC::PropertyListNode::emitBytecode):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • 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_val):
(JSC::JIT::emit_op_put_setter_by_val):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_put_getter_by_val):
(JSC::JIT::emit_op_put_setter_by_val):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

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

(JSC::ASTBuilder::createGetterOrSetterProperty):

  • parser/Parser.cpp:

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

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createGetterOrSetterProperty):

  • tests/es6.yaml:
  • tests/stress/computed-accessor-parsing.js: Added.

(testShouldNotThrow):
(testShouldThrow):
(Val.prototype.get string_appeared_here):
(Val):

  • tests/stress/computed-accessor.js: Added.

(shouldBe):
(.):

  • tests/stress/duplicate-computed-accessors.js: Added.

(shouldBe):

LayoutTests:

Updated the existing tests.

  • js/parser-syntax-check-expected.txt:
  • js/script-tests/parser-syntax-check.js:
File:
1 edited

Legend:

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

    r189431 r189504  
    19781978            ASSERT(ident);
    19791979            next();
    1980             if (match(IDENT) || match(STRING) || match(DOUBLE) || match(INTEGER)) {
     1980            if (match(IDENT) || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET)) {
    19811981                isGetter = *ident == propertyNames.get;
    19821982                isSetter = *ident == propertyNames.set;
     
    29112911    const Identifier* stringPropertyName = 0;
    29122912    double numericPropertyName = 0;
    2913     if (m_token.m_type == IDENT || m_token.m_type == STRING || isLETMaskedAsIDENT()) {
     2913    TreeExpression computedPropertyName = 0;
     2914
     2915    JSTokenLocation location(tokenLocation());
     2916
     2917    if (match(IDENT) || match(STRING) || isLETMaskedAsIDENT()) {
    29142918        stringPropertyName = m_token.m_data.ident;
    29152919        semanticFailIfTrue(superBinding == SuperBinding::Needed && *stringPropertyName == m_vm->propertyNames->prototype,
     
    29172921        semanticFailIfTrue(superBinding == SuperBinding::Needed && *stringPropertyName == m_vm->propertyNames->constructor,
    29182922            "Cannot declare a getter or setter named 'constructor'");
    2919     } else if (m_token.m_type == DOUBLE || m_token.m_type == INTEGER)
     2923        next();
     2924    } else if (match(DOUBLE) || match(INTEGER)) {
    29202925        numericPropertyName = m_token.m_data.doubleValue;
    2921     else
     2926        next();
     2927    } else if (match(OPENBRACKET)) {
     2928        next();
     2929        computedPropertyName = parseAssignmentExpression(context);
     2930        failIfFalse(computedPropertyName, "Cannot parse computed property name");
     2931        handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
     2932    } else
    29222933        failDueToUnexpectedToken();
    2923     JSTokenLocation location(tokenLocation());
    2924     next();
     2934
    29252935    ParserFunctionInfo<TreeBuilder> info;
    29262936    if (type & PropertyNode::Getter) {
     
    29332943            getterOrSetterStartOffset, info, StandardFunctionParseType)), "Cannot parse setter definition");
    29342944    }
     2945
    29352946    if (stringPropertyName)
    29362947        return context.createGetterOrSetterProperty(location, type, strict, stringPropertyName, info, superBinding);
     2948
     2949    if (computedPropertyName)
     2950        return context.createGetterOrSetterProperty(location, static_cast<PropertyNode::Type>(type | PropertyNode::Computed), strict, computedPropertyName, info, superBinding);
     2951
    29372952    return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, strict, numericPropertyName, info, superBinding);
    29382953}
Note: See TracChangeset for help on using the changeset viewer.