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/bytecompiler/NodesCodegen.cpp

    r191037 r191110  
    30113011RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    30123012{
     3013    if (!m_name.isNull())
     3014        generator.pushLexicalScope(this, true);
     3015
    30133016    RefPtr<RegisterID> superclass;
    30143017    if (m_classHeritage) {
     
    30743077    if (m_instanceMethods)
    30753078        generator.emitNode(prototype.get(), m_instanceMethods);
     3079
     3080    if (!m_name.isNull()) {
     3081        Variable classNameVar = generator.variable(m_name);
     3082        RELEASE_ASSERT(classNameVar.isResolved());
     3083        RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, classNameVar);
     3084        generator.emitPutToScope(scope.get(), classNameVar, constructor.get(), ThrowIfNotFound, Initialization);
     3085        generator.popLexicalScope(this);
     3086    }
    30763087
    30773088    return generator.moveToDestinationIfNeeded(dst, constructor.get());
Note: See TracChangeset for help on using the changeset viewer.