Ignore:
Timestamp:
Mar 9, 2015, 4:47:06 PM (10 years ago)
Author:
[email protected]
Message:

Support extends and super keywords
https://bugs.webkit.org/show_bug.cgi?id=142200

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Added the support for ES6 class syntax inheritance.

Added ConstructorKind as well as boolean flags indicating the constructor kind to
various classes in UnlinkedCodeBlock as well as AST nodes.

Each method stores the associated class as its homeObjectPrivateName. This value is used to
make super calls.

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::generateFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::ExecutableInfo::ExecutableInfo):
(JSC::UnlinkedFunctionExecutable::constructorKindIsDerived): Added.
(JSC::UnlinkedCodeBlock::constructorKindIsDerived): Added.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator): Don't emit op_create_this in a derived class
as the object is allocated by the highest base class's constructor. Also set "this" to null
and store the original value in m_newTargetRegister. "this" is supposed to be in TDZ but
that will be implemented in a separate patch.
(JSC::BytecodeGenerator::emitReturn): Allow "undefined" to be returned from a derived class.
In a derived class's constructor, not returning "undefined" or an object results in a type
error instead of "this" being returned.
(JSC::BytecodeGenerator::emitThrowTypeError): Added.

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::constructorKindIsDerived): Added.
(JSC::BytecodeGenerator::newTarget): Added.

  • bytecompiler/NodesCodegen.cpp:

(JSC::SuperNode::emitBytecode): Added. Emits the code to obtain the callee's parent class.
(JSC::emitSuperBaseForCallee): Added. Emits the code to obtain the parent class's prototype.
(JSC::emitPutHomeObject): Added.
(JSC::PropertyListNode::emitBytecode): Stores the home object when adding methods.
(JSC::PropertyListNode::emitPutConstantProperty): Ditto.
(JSC::BracketAccessorNode::emitBytecode): Added the support for superfoo.
(JSC::DotAccessorNode::emitBytecode): Added the support for super.foo.
(JSC::FunctionCallValueNode::emitBytecode): Added the support for super().
(JSC::FunctionCallBracketNode::emitBytecode): Added the support for superfoo().
(JSC::FunctionCallDotNode::emitBytecode): Added the support for super.foo().
(JSC::DeleteBracketNode::emitBytecode): Forbid "delete super.foo".
(JSC::DeleteDotNode::emitBytecode): Forbid "delete superfoo".
(JSC::ClassExprNode::emitBytecode): Added the support for "classHeritage". This is the main
logic for inheritance. When a class B inherits from a class A, set B.proto to A and set
B.prototype.proto to A.prototype. Throw exceptions when either A or A.proto is not
an object.

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::superExpr): Added.

  • parser/NodeConstructors.h:

(JSC::SuperNode::SuperNode): Added.

  • parser/Nodes.cpp:

(JSC::FunctionBodyNode::FunctionBodyNode):

  • parser/Nodes.h:

(JSC::ExpressionNode::isSuperNode):
(JSC::PropertyNode::type):
(JSC::PropertyNode::needsSuperBinding):

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseFunctionBody):
(JSC::Parser<LexerType>::parseFunctionInfo): Throw a parser error if super() is used outside
of class constructors.
(JSC::Parser<LexerType>::parseFunctionDeclaration):
(JSC::Parser<LexerType>::parseClass): ConstructorKind is "derived" if and only if the parent
class is specified in the declaration / expression.
(JSC::Parser<LexerType>::parseGetterSetter):
(JSC::Parser<LexerType>::parsePrimaryExpression):
(JSC::Parser<LexerType>::parseMemberExpression): Added the support for "super()", "super.foo",
and "superfoo". Throw a semantic error if "super" appears by itself.

  • parser/Parser.h:

(JSC::Scope::Scope): Added m_hasDirectSuper. This variable keeps track of the use of "super()"
so that parseFunctionInfo can spit an error if it's used outside of class constructors.
(JSC::Scope::hasDirectSuper): Added.
(JSC::Scope::setHasDirectSuper): Added.

  • parser/ParserModes.h:

(JSC::ConstructorKind): Added.

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::superExpr): Added.

  • runtime/CommonIdentifiers.h: Added homeObjectPrivateName.
  • runtime/Executable.h:

(JSC::EvalExecutable::executableInfo):
(JSC::ProgramExecutable::executableInfo):

LayoutTests:

Added tests for "extends" and "super" keywords.

  • TestExpectations:
  • js/class-syntax-extends-expected.txt: Added.
  • js/class-syntax-extends.html: Added.
  • js/class-syntax-super-expected.txt: Added.
  • js/class-syntax-super.html: Added.
  • js/script-tests/class-syntax-extends.js: Added.
  • js/script-tests/class-syntax-super.js: Added.
File:
1 edited

Legend:

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

    r181179 r181293  
    7474        ResolveEvalExpr, ResolveExpr, IntegerExpr, DoubleExpr, StringExpr,
    7575        ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr,
    76         FunctionExpr, ClassExpr, BracketExpr, DotExpr, CallExpr,
     76        FunctionExpr, ClassExpr, SuperExpr, BracketExpr, DotExpr, CallExpr,
    7777        NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
    7878        ConditionalExpr, AssignmentExpr, TypeofExpr,
     
    147147    ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
    148148    ExpressionType thisExpr(const JSTokenLocation&) { return ThisExpr; }
     149    ExpressionType superExpr(const JSTokenLocation&) { return SuperExpr; }
    149150    ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int) { return ResolveExpr; }
    150151    ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; }
     
    169170#endif
    170171    ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&, int) { return FunctionExpr; }
    171     int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool) { return FunctionBodyResult; }
     172    int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, ConstructorKind) { return FunctionBodyResult; }
    172173    void setFunctionNameStart(int, int) { }
    173174    int createArguments() { return ArgumentsResult; }
     
    176177    int createArgumentsList(const JSTokenLocation&, int) { return ArgumentsListResult; }
    177178    int createArgumentsList(const JSTokenLocation&, int, int) { return ArgumentsListResult; }
    178     Property createProperty(const Identifier* name, int, PropertyNode::Type type, PropertyNode::PutType, bool complete)
     179    Property createProperty(const Identifier* name, int, PropertyNode::Type type, PropertyNode::PutType, bool complete, SuperBinding = SuperBinding::NotNeeded)
    179180    {
    180181        if (!complete)
     
    231232    int createConstStatement(const JSTokenLocation&, int, int, int) { return StatementResult; }
    232233    int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return StatementResult; }
    233     Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, const ParserFunctionInfo<SyntaxChecker>&, unsigned)
     234    Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, bool strict, const Identifier* name, const ParserFunctionInfo<SyntaxChecker>&, unsigned, SuperBinding)
    234235    {
    235236        ASSERT(name);
     
    238239        return Property(name, type);
    239240    }
    240     Property createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation&, PropertyNode::Type type, bool strict, double name, const ParserFunctionInfo<SyntaxChecker>&, unsigned)
     241    Property createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation&, PropertyNode::Type type, bool strict, double name, const ParserFunctionInfo<SyntaxChecker>&, unsigned, SuperBinding)
    241242    {
    242243        if (!strict)
Note: See TracChangeset for help on using the changeset viewer.