Ignore:
Timestamp:
Oct 15, 2015, 7:35:12 AM (10 years ago)
Author:
Yusuke Suzuki
Message:

[ES6] Class expression should have lexical environment that has itself as an imutable binding
https://bugs.webkit.org/show_bug.cgi?id=150089

Reviewed by Geoffrey Garen.

According to ES6 spec, class expression has its own lexical environment that holds itself
as an immutable binding[1] (section 14.5.14 step 2, 3, 4, 23)

As a result, even if the binding declared in the outer scope is overridden, methods inside
class expression can refer its class by the class name.

[1]: http://ecma-international.org/ecma-262/6.0/#sec-runtime-semantics-classdefinitionevaluation

  • bytecompiler/NodesCodegen.cpp:

(JSC::ClassExprNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createClassExpr):

  • parser/NodeConstructors.h:

(JSC::ClassExprNode::ClassExprNode):

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

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

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createClassExpr):

  • tests/es6.yaml:
  • tests/stress/class-expression-generates-environment.js: Added.

(shouldBe):
(shouldThrow):
(prototype.method):
(staticMethod):
(A.prototype.method):
(A.staticMethod):
(A):

  • tests/stress/class-expression-should-be-tdz-in-heritage.js: Added.

(shouldThrow):
(shouldThrow.A):

File:
1 edited

Legend:

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

    r191086 r191110  
    19241924
    19251925    AutoPopScopeRef classScope(this, pushScope());
     1926    classScope->setIsLexicalScope();
     1927    classScope->preventVarDeclarations();
    19261928    classScope->setStrictMode();
    19271929
     
    19311933        info.className = className;
    19321934        next();
    1933         failIfTrue(classScope->declareVariable(className) & DeclarationResult::InvalidStrictMode, "'", className->impl(), "' is not a valid class name");
     1935        failIfTrue(classScope->declareLexicalVariable(className, true) & DeclarationResult::InvalidStrictMode, "'", className->impl(), "' is not a valid class name");
    19341936    } else if (requirements == FunctionNeedsName) {
    19351937        if (match(OPENBRACE))
     
    20472049    }
    20482050
     2051    consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
     2052
     2053    auto classExpression = context.createClassExpr(location, *className, classScope->finalizeLexicalEnvironment(), constructor, parentClass, instanceMethods, staticMethods);
    20492054    popScope(classScope, TreeBuilder::NeedsFreeVariableInfo);
    2050     consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
    2051 
    2052     return context.createClassExpr(location, *className, constructor, parentClass, instanceMethods, staticMethods);
     2055    return classExpression;
    20532056}
    20542057#endif
Note: See TracChangeset for help on using the changeset viewer.