Title: [181611] trunk
Revision
181611
Author
rn...@webkit.org
Date
2015-03-16 21:02:52 -0700 (Mon, 16 Mar 2015)

Log Message

Source/_javascript_Core:
Add support for default constructor
https://bugs.webkit.org/show_bug.cgi?id=142388

Reviewed by Filip Pizlo.

Added the support for default constructors. They're generated by ClassExprNode::emitBytecode
via BuiltinExecutables::createDefaultConstructor.

UnlinkedFunctionExecutable now has the ability to override SourceCode provided by the owner
executable. We can't make store SourceCode in UnlinkedFunctionExecutable since CodeCache can use
the same UnlinkedFunctionExecutable to generate code blocks for multiple functions.

Parser now has the ability to treat any function _expression_ as a constructor of the kind specified
by m_defaultConstructorKind member variable.

* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::createDefaultConstructor): Added.
(JSC::BuiltinExecutables::createExecutableInternal): Generalized from createBuiltinExecutable.
Parse default constructors as normal non-builtin functions. Override SourceCode in the unlinked
function executable since the Miranda function's code is definitely not in the owner executable's
source code. That's the whole point.
* builtins/BuiltinExecutables.h:
(UnlinkedFunctionExecutable::createBuiltinExecutable): Added. Wraps createExecutableInternal.
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::UnlinkedFunctionExecutable::linkInsideExecutable):
(JSC::UnlinkedFunctionExecutable::linkGlobalCode):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedFunctionExecutable::create):
(JSC::UnlinkedFunctionExecutable::symbolTable): Deleted.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewDefaultConstructor): Added.
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ClassExprNode::emitBytecode): Generate the default constructor if needed.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parseFunctionInfo): Override ownerClassKind and assume the function as
a constructor if we're parsing a default constructor.
(JSC::Parser<LexerType>::parseClass): Allow omission of the class constructor.
* parser/Parser.h:
(JSC::parse):

LayoutTests:
Implement default constructor

Add support for default constructor
https://bugs.webkit.org/show_bug.cgi?id=142388

Reviewed by Filip Pizlo.

Added tests for default constructors.

* TestExpectations: Skipped the test since ES6 class syntax isn't enabled by default.
* js/class-syntax-default-constructor-expected.txt: Added.
* js/class-syntax-default-constructor.html: Added.
* js/script-tests/class-syntax-default-constructor.js: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (181610 => 181611)


--- trunk/LayoutTests/ChangeLog	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/LayoutTests/ChangeLog	2015-03-17 04:02:52 UTC (rev 181611)
@@ -1,3 +1,19 @@
+2015-03-16  Ryosuke Niwa  <rn...@webkit.org>
+
+        Implement default constructor
+
+        Add support for default constructor
+        https://bugs.webkit.org/show_bug.cgi?id=142388
+
+        Reviewed by Filip Pizlo.
+
+        Added tests for default constructors.
+
+        * TestExpectations: Skipped the test since ES6 class syntax isn't enabled by default.
+        * js/class-syntax-default-constructor-expected.txt: Added.
+        * js/class-syntax-default-constructor.html: Added.
+        * js/script-tests/class-syntax-default-constructor.js: Added.
+
 2015-03-16  Hunseop Jeong  <hs85.je...@samsung.com>
 
         [EFL] fast/css/outline-auto-empty-rects.html is failing 

Modified: trunk/LayoutTests/TestExpectations (181610 => 181611)


--- trunk/LayoutTests/TestExpectations	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/LayoutTests/TestExpectations	2015-03-17 04:02:52 UTC (rev 181611)
@@ -69,6 +69,7 @@
 # ES6 class syntax hasn't been enabled yet.
 webkit.org/b/140491 js/class-syntax-call.html [ Failure ]
 webkit.org/b/140491 js/class-syntax-declaration.html [ Failure ]
+webkit.org/b/140491 js/class-syntax-default-constructor.html [ Failure ]
 webkit.org/b/140491 js/class-syntax-_expression_.html [ Failure ]
 webkit.org/b/140491 js/class-syntax-extends.html [ Failure ]
 webkit.org/b/140491 js/class-syntax-scoping.html [ Failure ]

Added: trunk/LayoutTests/js/class-syntax-default-constructor-expected.txt (0 => 181611)


--- trunk/LayoutTests/js/class-syntax-default-constructor-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/class-syntax-default-constructor-expected.txt	2015-03-17 04:02:52 UTC (rev 181611)
@@ -0,0 +1,19 @@
+Tests for ES6 class syntax default constructor
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS class A { }; window.A = A; new A instanceof A is true
+PASS A() threw exception TypeError: Cannot call a class constructor.
+PASS A.prototype.constructor instanceof Function is true
+PASS A.prototype.constructor.name is "A"
+PASS class B extends A { }; new B instanceof A; new B instanceof A is true
+PASS B() threw exception TypeError: Cannot call a class constructor.
+PASS B.prototype.constructor.name is "B"
+PASS A is not B
+FAIL A.prototype.constructor should be function B() { super(...arguments); }. Was function A() { }.
+PASS new (class extends (class { constructor(a, b) { return [a, b]; } }) {})(1, 2) is [1, 2]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/class-syntax-default-constructor.html (0 => 181611)


--- trunk/LayoutTests/js/class-syntax-default-constructor.html	                        (rev 0)
+++ trunk/LayoutTests/js/class-syntax-default-constructor.html	2015-03-17 04:02:52 UTC (rev 181611)
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/script-tests/class-syntax-default-constructor.js (0 => 181611)


--- trunk/LayoutTests/js/script-tests/class-syntax-default-constructor.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/class-syntax-default-constructor.js	2015-03-17 04:02:52 UTC (rev 181611)
@@ -0,0 +1,16 @@
+//@ skip
+
+description('Tests for ES6 class syntax default constructor');
+
+shouldBeTrue('class A { }; window.A = A; new A instanceof A');
+shouldThrow('A()', '"TypeError: Cannot call a class constructor"');
+shouldBeTrue('A.prototype.constructor instanceof Function');
+shouldBe('A.prototype.constructor.name', '"A"');
+shouldBeTrue('class B extends A { }; new B instanceof A; new B instanceof A');
+shouldThrow('B()', '"TypeError: Cannot call a class constructor"');
+shouldBe('B.prototype.constructor.name', '"B"');
+shouldNotBe('A', 'B');
+shouldBe('A.prototype.constructor', 'B.prototype.constructor');
+shouldBe('new (class extends (class { constructor(a, b) { return [a, b]; } }) {})(1, 2)', '[1, 2]');
+
+var successfullyParsed = true;

Modified: trunk/Source/_javascript_Core/ChangeLog (181610 => 181611)


--- trunk/Source/_javascript_Core/ChangeLog	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-03-17 04:02:52 UTC (rev 181611)
@@ -1,3 +1,48 @@
+2015-03-16  Ryosuke Niwa  <rn...@webkit.org>
+
+        Add support for default constructor
+        https://bugs.webkit.org/show_bug.cgi?id=142388
+
+        Reviewed by Filip Pizlo.
+
+        Added the support for default constructors. They're generated by ClassExprNode::emitBytecode
+        via BuiltinExecutables::createDefaultConstructor.
+
+        UnlinkedFunctionExecutable now has the ability to override SourceCode provided by the owner
+        executable. We can't make store SourceCode in UnlinkedFunctionExecutable since CodeCache can use
+        the same UnlinkedFunctionExecutable to generate code blocks for multiple functions.
+
+        Parser now has the ability to treat any function _expression_ as a constructor of the kind specified
+        by m_defaultConstructorKind member variable.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createDefaultConstructor): Added.
+        (JSC::BuiltinExecutables::createExecutableInternal): Generalized from createBuiltinExecutable.
+        Parse default constructors as normal non-builtin functions. Override SourceCode in the unlinked
+        function executable since the Miranda function's code is definitely not in the owner executable's
+        source code. That's the whole point.
+        * builtins/BuiltinExecutables.h:
+        (UnlinkedFunctionExecutable::createBuiltinExecutable): Added. Wraps createExecutableInternal.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        (JSC::UnlinkedFunctionExecutable::linkInsideExecutable):
+        (JSC::UnlinkedFunctionExecutable::linkGlobalCode):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedFunctionExecutable::create):
+        (JSC::UnlinkedFunctionExecutable::symbolTable): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitNewDefaultConstructor): Added.
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ClassExprNode::emitBytecode): Generate the default constructor if needed.
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseFunctionInfo): Override ownerClassKind and assume the function as
+        a constructor if we're parsing a default constructor.
+        (JSC::Parser<LexerType>::parseClass): Allow omission of the class constructor.
+        * parser/Parser.h:
+        (JSC::parse):
+
 2015-03-16  Alex Christensen  <achristen...@webkit.org>
 
         Progress towards CMake on Mac

Modified: trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp (181610 => 181611)


--- trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp	2015-03-17 04:02:52 UTC (rev 181611)
@@ -31,6 +31,7 @@
 #include "Executable.h"
 #include "JSCInlines.h"
 #include "Parser.h"
+#include <wtf/NeverDestroyed.h>
 
 namespace JSC {
 
@@ -42,11 +43,33 @@
 {
 }
 
-UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& source, const Identifier& name)
+UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name)
 {
+    static NeverDestroyed<const String> baseConstructorCode(ASCIILiteral("(function () { })"));
+    static NeverDestroyed<const String> derivedConstructorCode(ASCIILiteral("(function () { super(...arguments); })"));
+
+    switch (constructorKind) {
+    case ConstructorKind::None:
+        break;
+    case ConstructorKind::Base:
+        return createExecutableInternal(makeSource(baseConstructorCode), name, constructorKind);
+    case ConstructorKind::Derived:
+        return createExecutableInternal(makeSource(derivedConstructorCode), name, constructorKind);
+    }
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+UnlinkedFunctionExecutable* BuiltinExecutables::createExecutableInternal(const SourceCode& source, const Identifier& name, ConstructorKind constructorKind)
+{
     JSTextPosition positionBeforeLastNewline;
     ParserError error;
-    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(&m_vm, source, 0, Identifier(), JSParseBuiltin, JSParseProgramCode, error, &positionBeforeLastNewline);
+    bool isParsingDefaultConstructor = constructorKind != ConstructorKind::None;
+    JSParserStrictness strictness = isParsingDefaultConstructor ? JSParseNormal : JSParseBuiltin;
+    UnlinkedFunctionKind kind = isParsingDefaultConstructor ? UnlinkedNormalFunction : UnlinkedBuiltinFunction;
+    RefPtr<SourceProvider> sourceOverride = isParsingDefaultConstructor ? source.provider() : nullptr;
+    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(&m_vm, source, 0, Identifier(), strictness, JSParseProgramCode,
+        error, &positionBeforeLastNewline, false, constructorKind);
 
     if (!program) {
         dataLog("Fatal error compiling builtin function '", name.string(), "': ", error.message());
@@ -78,7 +101,7 @@
         RELEASE_ASSERT(closedVariable->isUnique());
     }
     body->overrideName(name);
-    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, UnlinkedBuiltinFunction);
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, kind, WTF::move(sourceOverride));
     functionExecutable->m_nameValue.set(m_vm, functionExecutable, jsString(&m_vm, name.string()));
     return functionExecutable;
 }

Modified: trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h (181610 => 181611)


--- trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h	2015-03-17 04:02:52 UTC (rev 181611)
@@ -27,6 +27,7 @@
 #define BuiltinExecutables_h
 
 #include "JSCBuiltins.h"
+#include "ParserModes.h"
 #include "SourceCode.h"
 #include "Weak.h"
 #include "WeakHandleOwner.h"
@@ -48,12 +49,20 @@
     
     JSC_FOREACH_BUILTIN(EXPOSE_BUILTIN_EXECUTABLES)
 #undef EXPOSE_BUILTIN_SOURCES
-    
+
+    UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name);
+
 private:
     void finalize(Handle<Unknown>, void* context) override;
 
     VM& m_vm;
-    UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&);
+
+    UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode& code, const Identifier& name)
+    {
+        return createExecutableInternal(code, name, ConstructorKind::None);
+    }
+    UnlinkedFunctionExecutable* createExecutableInternal(const SourceCode&, const Identifier&, ConstructorKind);
+
 #define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length)\
     SourceCode m_##name##Source; \
     Weak<UnlinkedFunctionExecutable> m_##name##Executable;

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (181610 => 181611)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2015-03-17 04:02:52 UTC (rev 181611)
@@ -80,7 +80,7 @@
     return addConstant(v);
 }
 
-UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind kind)
+UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode* node, UnlinkedFunctionKind kind)
     : Base(*vm, structure)
     , m_isInStrictContext(node->isInStrictContext())
     , m_hasCapturedVariables(false)
@@ -98,6 +98,7 @@
     , m_sourceLength(node->source().length())
     , m_typeProfilingStartOffset(node->functionKeywordStart())
     , m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1)
+    , m_sourceOverride(sourceOverride)
     , m_features(0)
     , m_functionMode(node->functionMode())
 {
@@ -121,8 +122,9 @@
     visitor.append(&thisObject->m_symbolTableForConstruct);
 }
 
-FunctionExecutable* UnlinkedFunctionExecutable::linkInsideExecutable(VM& vm, const SourceCode& source)
+FunctionExecutable* UnlinkedFunctionExecutable::linkInsideExecutable(VM& vm, const SourceCode& ownerSource)
 {
+    SourceCode source = m_sourceOverride ? SourceCode(m_sourceOverride) : ownerSource;
     unsigned firstLine = source.firstLine() + m_firstLineOffset;
     unsigned startOffset = source.startOffset() + m_startOffset;
 
@@ -137,6 +139,7 @@
 
 FunctionExecutable* UnlinkedFunctionExecutable::linkGlobalCode(VM& vm, const SourceCode& source)
 {
+    ASSERT(!m_sourceOverride);
     unsigned firstLine = source.firstLine() + m_firstLineOffset;
     unsigned startOffset = source.startOffset() + m_startOffset;
 

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (181610 => 181611)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2015-03-17 04:02:52 UTC (rev 181611)
@@ -103,9 +103,10 @@
     friend class CodeCache;
     friend class VM;
     typedef JSCell Base;
-    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind)
+    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind, RefPtr<SourceProvider>&& sourceOverride = nullptr)
     {
-        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind);
+        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
+            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind);
         instance->finishCreation(*vm);
         return instance;
     }
@@ -173,7 +174,7 @@
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
 
 private:
-    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, UnlinkedFunctionKind);
+    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode*, UnlinkedFunctionKind);
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
 
@@ -197,6 +198,7 @@
     unsigned m_sourceLength;
     unsigned m_typeProfilingStartOffset;
     unsigned m_typeProfilingEndOffset;
+    RefPtr<SourceProvider> m_sourceOverride;
 
     CodeFeatures m_features;
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (181610 => 181611)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2015-03-17 04:02:52 UTC (rev 181611)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "BytecodeGenerator.h"
 
+#include "BuiltinExecutables.h"
 #include "Interpreter.h"
 #include "JSFunction.h"
 #include "JSLexicalEnvironment.h"
@@ -1692,6 +1693,19 @@
     return r0;
 }
 
+RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier& name)
+{
+    UnlinkedFunctionExecutable* executable = m_vm->builtinExecutables()->createDefaultConstructor(constructorKind, name);
+
+    unsigned index = m_codeBlock->addFunctionExpr(executable);
+
+    emitOpcode(op_new_func_exp);
+    instructions().append(dst->index());
+    instructions().append(scopeRegister()->index());
+    instructions().append(index);
+    return dst;
+}
+
 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
 {
     return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, divotStart, divotEnd);

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (181610 => 181611)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2015-03-17 04:02:52 UTC (rev 181611)
@@ -466,6 +466,7 @@
         RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
         RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck);
         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
+        RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name);
         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
 
         RegisterID* emitMove(RegisterID* dst, RegisterID* src);

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (181610 => 181611)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2015-03-17 04:02:52 UTC (rev 181611)
@@ -2885,10 +2885,19 @@
         generator.emitNode(superclass.get(), m_classHeritage);
     }
 
-    RefPtr<RegisterID> constructor = generator.emitNode(dst, m_constructorExpression);
+    RefPtr<RegisterID> constructor;
+    RefPtr<RegisterID> prototype;
+
     // FIXME: Make the prototype non-configurable & non-writable.
-    RefPtr<RegisterID> prototype = generator.emitGetById(generator.newTemporary(), constructor.get(), generator.propertyNames().prototype);
+    if (m_constructorExpression)
+        constructor = generator.emitNode(dst, m_constructorExpression);
+    else {
+        constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst),
+            m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base, m_name);
+    }
 
+    prototype = generator.emitGetById(generator.newTemporary(), constructor.get(), generator.propertyNames().prototype);
+
     if (superclass) {
         RefPtr<RegisterID> tempRegister = generator.newTemporary();
         RefPtr<Label> superclassIsNullLabel = generator.newLabel();

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (181610 => 181611)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2015-03-17 04:02:52 UTC (rev 181611)
@@ -190,7 +190,7 @@
 }
 
 template <typename LexerType>
-Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode)
+Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ConstructorKind defaultConstructorKind)
     : m_vm(vm)
     , m_source(&source)
     , m_hasStackOverflow(false)
@@ -204,6 +204,7 @@
     , m_lastFunctionName(nullptr)
     , m_sourceElements(0)
     , m_parsingBuiltin(strictness == JSParseBuiltin)
+    , m_defaultConstructorKind(defaultConstructorKind)
 {
     m_lexer = std::make_unique<LexerType>(vm, strictness);
     m_lexer->setCode(source, &m_parserArena);
@@ -1325,6 +1326,10 @@
     // BytecodeGenerator emits code to throw TypeError when a class constructor is "call"ed.
     // Set ConstructorKind to None for non-constructor methods of classes.
     bool isClassConstructor = mode == MethodMode && info.name && *info.name == m_vm->propertyNames->constructor;
+    if (m_defaultConstructorKind != ConstructorKind::None) {
+        ownerClassKind = m_defaultConstructorKind;
+        isClassConstructor = true;
+    }
     ConstructorKind constructorKind = isClassConstructor ? ownerClassKind : ConstructorKind::None;
 
     info.openBraceOffset = m_token.m_data.offset;
@@ -1549,9 +1554,6 @@
         }
     }
 
-    // FIXME: Create a Miranda function instead.
-    semanticFailIfFalse(constructor, "Class declaration without a constructor is not supported yet");
-
     failIfFalse(popScope(classScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
     consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
 

Modified: trunk/Source/_javascript_Core/parser/Parser.h (181610 => 181611)


--- trunk/Source/_javascript_Core/parser/Parser.h	2015-03-17 03:56:18 UTC (rev 181610)
+++ trunk/Source/_javascript_Core/parser/Parser.h	2015-03-17 04:02:52 UTC (rev 181611)
@@ -426,7 +426,8 @@
     WTF_MAKE_FAST_ALLOCATED;
 
 public:
-    Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
+    Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode,
+        ConstructorKind defaultConstructorKind = ConstructorKind::None);
     ~Parser();
 
     template <class ParsedNode>
@@ -872,6 +873,7 @@
     RefPtr<SourceProviderCache> m_functionCache;
     SourceElements* m_sourceElements;
     bool m_parsingBuiltin;
+    ConstructorKind m_defaultConstructorKind;
     DeclarationStacks::VarStack m_varDeclarations;
     DeclarationStacks::FunctionStack m_funcDeclarations;
     IdentifierSet m_capturedVariables;
@@ -979,13 +981,15 @@
 }
 
 template <class ParsedNode>
-std::unique_ptr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error, JSTextPosition* positionBeforeLastNewline = 0, bool needReparsingAdjustment = false)
+std::unique_ptr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name,
+    JSParserStrictness strictness, JSParserMode parserMode, ParserError& error, JSTextPosition* positionBeforeLastNewline = 0,
+    bool needReparsingAdjustment = false, ConstructorKind defaultConstructorKind = ConstructorKind::None)
 {
     SamplingRegion samplingRegion("Parsing");
 
     ASSERT(!source.provider()->source().isNull());
     if (source.provider()->source().is8Bit()) {
-        Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode);
+        Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode, defaultConstructorKind);
         std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, needReparsingAdjustment);
         if (positionBeforeLastNewline)
             *positionBeforeLastNewline = parser.positionBeforeLastNewline();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to