Changeset 181611 in webkit
- Timestamp:
- Mar 16, 2015 9:02:52 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r181609 r181611 1 2015-03-16 Ryosuke Niwa <rniwa@webkit.org> 2 3 Implement default constructor 4 5 Add support for default constructor 6 https://bugs.webkit.org/show_bug.cgi?id=142388 7 8 Reviewed by Filip Pizlo. 9 10 Added tests for default constructors. 11 12 * TestExpectations: Skipped the test since ES6 class syntax isn't enabled by default. 13 * js/class-syntax-default-constructor-expected.txt: Added. 14 * js/class-syntax-default-constructor.html: Added. 15 * js/script-tests/class-syntax-default-constructor.js: Added. 16 1 17 2015-03-16 Hunseop Jeong <hs85.jeong@samsung.com> 2 18 -
trunk/LayoutTests/TestExpectations
r181592 r181611 70 70 webkit.org/b/140491 js/class-syntax-call.html [ Failure ] 71 71 webkit.org/b/140491 js/class-syntax-declaration.html [ Failure ] 72 webkit.org/b/140491 js/class-syntax-default-constructor.html [ Failure ] 72 73 webkit.org/b/140491 js/class-syntax-expression.html [ Failure ] 73 74 webkit.org/b/140491 js/class-syntax-extends.html [ Failure ] -
trunk/Source/JavaScriptCore/ChangeLog
r181601 r181611 1 2015-03-16 Ryosuke Niwa <rniwa@webkit.org> 2 3 Add support for default constructor 4 https://bugs.webkit.org/show_bug.cgi?id=142388 5 6 Reviewed by Filip Pizlo. 7 8 Added the support for default constructors. They're generated by ClassExprNode::emitBytecode 9 via BuiltinExecutables::createDefaultConstructor. 10 11 UnlinkedFunctionExecutable now has the ability to override SourceCode provided by the owner 12 executable. We can't make store SourceCode in UnlinkedFunctionExecutable since CodeCache can use 13 the same UnlinkedFunctionExecutable to generate code blocks for multiple functions. 14 15 Parser now has the ability to treat any function expression as a constructor of the kind specified 16 by m_defaultConstructorKind member variable. 17 18 * builtins/BuiltinExecutables.cpp: 19 (JSC::BuiltinExecutables::createDefaultConstructor): Added. 20 (JSC::BuiltinExecutables::createExecutableInternal): Generalized from createBuiltinExecutable. 21 Parse default constructors as normal non-builtin functions. Override SourceCode in the unlinked 22 function executable since the Miranda function's code is definitely not in the owner executable's 23 source code. That's the whole point. 24 * builtins/BuiltinExecutables.h: 25 (UnlinkedFunctionExecutable::createBuiltinExecutable): Added. Wraps createExecutableInternal. 26 * bytecode/UnlinkedCodeBlock.cpp: 27 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 28 (JSC::UnlinkedFunctionExecutable::linkInsideExecutable): 29 (JSC::UnlinkedFunctionExecutable::linkGlobalCode): 30 * bytecode/UnlinkedCodeBlock.h: 31 (JSC::UnlinkedFunctionExecutable::create): 32 (JSC::UnlinkedFunctionExecutable::symbolTable): Deleted. 33 * bytecompiler/BytecodeGenerator.cpp: 34 (JSC::BytecodeGenerator::emitNewDefaultConstructor): Added. 35 * bytecompiler/BytecodeGenerator.h: 36 * bytecompiler/NodesCodegen.cpp: 37 (JSC::ClassExprNode::emitBytecode): Generate the default constructor if needed. 38 * parser/Parser.cpp: 39 (JSC::Parser<LexerType>::Parser): 40 (JSC::Parser<LexerType>::parseFunctionInfo): Override ownerClassKind and assume the function as 41 a constructor if we're parsing a default constructor. 42 (JSC::Parser<LexerType>::parseClass): Allow omission of the class constructor. 43 * parser/Parser.h: 44 (JSC::parse): 45 1 46 2015-03-16 Alex Christensen <achristensen@webkit.org> 2 47 -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
r181248 r181611 32 32 #include "JSCInlines.h" 33 33 #include "Parser.h" 34 #include <wtf/NeverDestroyed.h> 34 35 35 36 namespace JSC { … … 43 44 } 44 45 45 UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& source, const Identifier& name) 46 UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name) 47 { 48 static NeverDestroyed<const String> baseConstructorCode(ASCIILiteral("(function () { })")); 49 static NeverDestroyed<const String> derivedConstructorCode(ASCIILiteral("(function () { super(...arguments); })")); 50 51 switch (constructorKind) { 52 case ConstructorKind::None: 53 break; 54 case ConstructorKind::Base: 55 return createExecutableInternal(makeSource(baseConstructorCode), name, constructorKind); 56 case ConstructorKind::Derived: 57 return createExecutableInternal(makeSource(derivedConstructorCode), name, constructorKind); 58 } 59 ASSERT_NOT_REACHED(); 60 return nullptr; 61 } 62 63 UnlinkedFunctionExecutable* BuiltinExecutables::createExecutableInternal(const SourceCode& source, const Identifier& name, ConstructorKind constructorKind) 46 64 { 47 65 JSTextPosition positionBeforeLastNewline; 48 66 ParserError error; 49 std::unique_ptr<ProgramNode> program = parse<ProgramNode>(&m_vm, source, 0, Identifier(), JSParseBuiltin, JSParseProgramCode, error, &positionBeforeLastNewline); 67 bool isParsingDefaultConstructor = constructorKind != ConstructorKind::None; 68 JSParserStrictness strictness = isParsingDefaultConstructor ? JSParseNormal : JSParseBuiltin; 69 UnlinkedFunctionKind kind = isParsingDefaultConstructor ? UnlinkedNormalFunction : UnlinkedBuiltinFunction; 70 RefPtr<SourceProvider> sourceOverride = isParsingDefaultConstructor ? source.provider() : nullptr; 71 std::unique_ptr<ProgramNode> program = parse<ProgramNode>(&m_vm, source, 0, Identifier(), strictness, JSParseProgramCode, 72 error, &positionBeforeLastNewline, false, constructorKind); 50 73 51 74 if (!program) { … … 79 102 } 80 103 body->overrideName(name); 81 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, UnlinkedBuiltinFunction);104 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, kind, WTF::move(sourceOverride)); 82 105 functionExecutable->m_nameValue.set(m_vm, functionExecutable, jsString(&m_vm, name.string())); 83 106 return functionExecutable; -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.h
r181248 r181611 28 28 29 29 #include "JSCBuiltins.h" 30 #include "ParserModes.h" 30 31 #include "SourceCode.h" 31 32 #include "Weak.h" … … 49 50 JSC_FOREACH_BUILTIN(EXPOSE_BUILTIN_EXECUTABLES) 50 51 #undef EXPOSE_BUILTIN_SOURCES 51 52 53 UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name); 54 52 55 private: 53 56 void finalize(Handle<Unknown>, void* context) override; 54 57 55 58 VM& m_vm; 56 UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&); 59 60 UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode& code, const Identifier& name) 61 { 62 return createExecutableInternal(code, name, ConstructorKind::None); 63 } 64 UnlinkedFunctionExecutable* createExecutableInternal(const SourceCode&, const Identifier&, ConstructorKind); 65 57 66 #define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length)\ 58 67 SourceCode m_##name##Source; \ -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
r181490 r181611 81 81 } 82 82 83 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind kind)83 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode* node, UnlinkedFunctionKind kind) 84 84 : Base(*vm, structure) 85 85 , m_isInStrictContext(node->isInStrictContext()) … … 99 99 , m_typeProfilingStartOffset(node->functionKeywordStart()) 100 100 , m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1) 101 , m_sourceOverride(sourceOverride) 101 102 , m_features(0) 102 103 , m_functionMode(node->functionMode()) … … 122 123 } 123 124 124 FunctionExecutable* UnlinkedFunctionExecutable::linkInsideExecutable(VM& vm, const SourceCode& source) 125 { 125 FunctionExecutable* UnlinkedFunctionExecutable::linkInsideExecutable(VM& vm, const SourceCode& ownerSource) 126 { 127 SourceCode source = m_sourceOverride ? SourceCode(m_sourceOverride) : ownerSource; 126 128 unsigned firstLine = source.firstLine() + m_firstLineOffset; 127 129 unsigned startOffset = source.startOffset() + m_startOffset; … … 138 140 FunctionExecutable* UnlinkedFunctionExecutable::linkGlobalCode(VM& vm, const SourceCode& source) 139 141 { 142 ASSERT(!m_sourceOverride); 140 143 unsigned firstLine = source.firstLine() + m_firstLineOffset; 141 144 unsigned startOffset = source.startOffset() + m_startOffset; -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r181490 r181611 104 104 friend class VM; 105 105 typedef JSCell Base; 106 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind) 107 { 108 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind); 106 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind, RefPtr<SourceProvider>&& sourceOverride = nullptr) 107 { 108 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) 109 UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind); 109 110 instance->finishCreation(*vm); 110 111 return instance; … … 174 175 175 176 private: 176 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, UnlinkedFunctionKind);177 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode*, UnlinkedFunctionKind); 177 178 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall; 178 179 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; … … 198 199 unsigned m_typeProfilingStartOffset; 199 200 unsigned m_typeProfilingEndOffset; 201 RefPtr<SourceProvider> m_sourceOverride; 200 202 201 203 CodeFeatures m_features; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r181490 r181611 32 32 #include "BytecodeGenerator.h" 33 33 34 #include "BuiltinExecutables.h" 34 35 #include "Interpreter.h" 35 36 #include "JSFunction.h" … … 1691 1692 instructions().append(index); 1692 1693 return r0; 1694 } 1695 1696 RegisterID* BytecodeGenerator::emitNewDefaultConstructor(RegisterID* dst, ConstructorKind constructorKind, const Identifier& name) 1697 { 1698 UnlinkedFunctionExecutable* executable = m_vm->builtinExecutables()->createDefaultConstructor(constructorKind, name); 1699 1700 unsigned index = m_codeBlock->addFunctionExpr(executable); 1701 1702 emitOpcode(op_new_func_exp); 1703 instructions().append(dst->index()); 1704 instructions().append(scopeRegister()->index()); 1705 instructions().append(index); 1706 return dst; 1693 1707 } 1694 1708 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r181490 r181611 467 467 RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck); 468 468 RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func); 469 RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name); 469 470 RegisterID* emitNewRegExp(RegisterID* dst, RegExp*); 470 471 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r181490 r181611 2886 2886 } 2887 2887 2888 RefPtr<RegisterID> constructor = generator.emitNode(dst, m_constructorExpression); 2888 RefPtr<RegisterID> constructor; 2889 RefPtr<RegisterID> prototype; 2890 2889 2891 // FIXME: Make the prototype non-configurable & non-writable. 2890 RefPtr<RegisterID> prototype = generator.emitGetById(generator.newTemporary(), constructor.get(), generator.propertyNames().prototype); 2892 if (m_constructorExpression) 2893 constructor = generator.emitNode(dst, m_constructorExpression); 2894 else { 2895 constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst), 2896 m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base, m_name); 2897 } 2898 2899 prototype = generator.emitGetById(generator.newTemporary(), constructor.get(), generator.propertyNames().prototype); 2891 2900 2892 2901 if (superclass) { -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r181503 r181611 191 191 192 192 template <typename LexerType> 193 Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode )193 Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ConstructorKind defaultConstructorKind) 194 194 : m_vm(vm) 195 195 , m_source(&source) … … 205 205 , m_sourceElements(0) 206 206 , m_parsingBuiltin(strictness == JSParseBuiltin) 207 , m_defaultConstructorKind(defaultConstructorKind) 207 208 { 208 209 m_lexer = std::make_unique<LexerType>(vm, strictness); … … 1326 1327 // Set ConstructorKind to None for non-constructor methods of classes. 1327 1328 bool isClassConstructor = mode == MethodMode && info.name && *info.name == m_vm->propertyNames->constructor; 1329 if (m_defaultConstructorKind != ConstructorKind::None) { 1330 ownerClassKind = m_defaultConstructorKind; 1331 isClassConstructor = true; 1332 } 1328 1333 ConstructorKind constructorKind = isClassConstructor ? ownerClassKind : ConstructorKind::None; 1329 1334 … … 1549 1554 } 1550 1555 } 1551 1552 // FIXME: Create a Miranda function instead.1553 semanticFailIfFalse(constructor, "Class declaration without a constructor is not supported yet");1554 1556 1555 1557 failIfFalse(popScope(classScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error"); -
trunk/Source/JavaScriptCore/parser/Parser.h
r181490 r181611 427 427 428 428 public: 429 Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode); 429 Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode, 430 ConstructorKind defaultConstructorKind = ConstructorKind::None); 430 431 ~Parser(); 431 432 … … 873 874 SourceElements* m_sourceElements; 874 875 bool m_parsingBuiltin; 876 ConstructorKind m_defaultConstructorKind; 875 877 DeclarationStacks::VarStack m_varDeclarations; 876 878 DeclarationStacks::FunctionStack m_funcDeclarations; … … 980 982 981 983 template <class ParsedNode> 982 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) 984 std::unique_ptr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, 985 JSParserStrictness strictness, JSParserMode parserMode, ParserError& error, JSTextPosition* positionBeforeLastNewline = 0, 986 bool needReparsingAdjustment = false, ConstructorKind defaultConstructorKind = ConstructorKind::None) 983 987 { 984 988 SamplingRegion samplingRegion("Parsing"); … … 986 990 ASSERT(!source.provider()->source().isNull()); 987 991 if (source.provider()->source().is8Bit()) { 988 Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode );992 Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode, defaultConstructorKind); 989 993 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, needReparsingAdjustment); 990 994 if (positionBeforeLastNewline)
Note: See TracChangeset
for help on using the changeset viewer.