Changeset 181490 in webkit
- Timestamp:
- Mar 13, 2015, 4:01:51 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 14 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/TestExpectations (modified) (1 diff)
-
LayoutTests/js/class-syntax-call-expected.txt (added)
-
LayoutTests/js/class-syntax-call.html (added)
-
LayoutTests/js/script-tests/class-syntax-call.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h (modified) (6 diffs)
-
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/parser/Nodes.cpp (modified) (1 diff)
-
Source/JavaScriptCore/parser/Nodes.h (modified) (2 diffs)
-
Source/JavaScriptCore/parser/Parser.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/parser/Parser.h (modified) (1 diff)
-
Source/JavaScriptCore/parser/ParserModes.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Executable.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r181484 r181490 1 2015-03-13 Ryosuke Niwa <rniwa@webkit.org> 2 3 Class constructor should throw TypeError when "called" 4 https://bugs.webkit.org/show_bug.cgi?id=142566 5 6 Reviewed by Michael Saboff. 7 8 Added tests for calling class constructors. 9 10 * TestExpectations: Skipped the test since ES6 class syntax isn't enabled by default. 11 * js/class-syntax-call-expected.txt: Added. 12 * js/class-syntax-call.html: Added. 13 * js/script-tests/class-syntax-call.js: Added. 14 1 15 2015-03-13 Doug Russell <d_russell@apple.com> 2 16 -
trunk/LayoutTests/TestExpectations
r181409 r181490 68 68 69 69 # ES6 class syntax hasn't been enabled yet. 70 webkit.org/b/140491 js/class-syntax-call.html [ Failure ] 70 71 webkit.org/b/140491 js/class-syntax-declaration.html [ Failure ] 71 72 webkit.org/b/140491 js/class-syntax-expression.html [ Failure ] -
trunk/Source/JavaScriptCore/ChangeLog
r181487 r181490 1 2015-03-13 Ryosuke Niwa <rniwa@webkit.org> 2 3 Class constructor should throw TypeError when "called" 4 https://bugs.webkit.org/show_bug.cgi?id=142566 5 6 Reviewed by Michael Saboff. 7 8 Added ConstructorKind::None to denote code that doesn't belong to an ES6 class. 9 This allows BytecodeGenerator to emit code to throw TypeError when generating code block 10 to call ES6 class constructors. 11 12 Most of changes are about increasing the number of bits to store ConstructorKind from one 13 bit to two bits. 14 15 * bytecode/UnlinkedCodeBlock.cpp: 16 (JSC::generateFunctionCodeBlock): 17 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 18 (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): 19 * bytecode/UnlinkedCodeBlock.h: 20 (JSC::ExecutableInfo::ExecutableInfo): 21 (JSC::ExecutableInfo::needsActivation): 22 (JSC::ExecutableInfo::usesEval): 23 (JSC::ExecutableInfo::isStrictMode): 24 (JSC::ExecutableInfo::isConstructor): 25 (JSC::ExecutableInfo::isBuiltinFunction): 26 (JSC::ExecutableInfo::constructorKind): 27 (JSC::UnlinkedFunctionExecutable::constructorKind): 28 (JSC::UnlinkedCodeBlock::constructorKind): 29 (JSC::UnlinkedFunctionExecutable::constructorKindIsDerived): Deleted. 30 (JSC::UnlinkedCodeBlock::constructorKindIsDerived): Deleted. 31 * bytecompiler/BytecodeGenerator.cpp: 32 (JSC::BytecodeGenerator::generate): Don't emit bytecode when we had already emitted code 33 to throw TypeError. 34 (JSC::BytecodeGenerator::BytecodeGenerator): Emit code to throw TypeError when generating 35 code to call. 36 (JSC::BytecodeGenerator::emitReturn): 37 * bytecompiler/BytecodeGenerator.h: 38 (JSC::BytecodeGenerator::constructorKind): 39 (JSC::BytecodeGenerator::constructorKindIsDerived): Deleted. 40 * bytecompiler/NodesCodegen.cpp: 41 (JSC::ThisNode::emitBytecode): 42 (JSC::FunctionCallValueNode::emitBytecode): 43 * parser/Nodes.cpp: 44 (JSC::FunctionBodyNode::FunctionBodyNode): 45 * parser/Nodes.h: 46 * parser/Parser.cpp: 47 (JSC::Parser<LexerType>::parseFunctionInfo): Renamed the incoming function argument to 48 ownerClassKind. Set constructorKind to Base or Derived only if we're parsing a constructor. 49 (JSC::Parser<LexerType>::parseFunctionDeclaration): 50 (JSC::Parser<LexerType>::parseClass): Don't parse static methods using MethodMode since that 51 would result in BytecodeGenerator erroneously treating static method named "constructor" as 52 a class constructor. 53 (JSC::Parser<LexerType>::parsePropertyMethod): 54 (JSC::Parser<LexerType>::parsePrimaryExpression): 55 * parser/Parser.h: 56 * parser/ParserModes.h: 57 * runtime/Executable.h: 58 (JSC::EvalExecutable::executableInfo): 59 (JSC::ProgramExecutable::executableInfo): 60 1 61 2015-03-13 Filip Pizlo <fpizlo@apple.com> 2 62 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
r181293 r181490 63 63 64 64 UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, 65 ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind IsDerived()));65 ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind())); 66 66 auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode)); 67 67 error = generator->generate(); … … 86 86 , m_hasCapturedVariables(false) 87 87 , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction) 88 , m_constructorKind IsDerived(node->constructorKindIsDerived())88 , m_constructorKind(static_cast<unsigned>(node->constructorKind())) 89 89 , m_name(node->ident()) 90 90 , m_inferredName(node->inferredName()) … … 102 102 , m_functionMode(node->functionMode()) 103 103 { 104 ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind())); 104 105 } 105 106 … … 225 226 , m_argumentsRegister(VirtualRegister()) 226 227 , m_globalObjectRegister(VirtualRegister()) 227 , m_needsFullScopeChain(info. m_needsActivation)228 , m_usesEval(info. m_usesEval)228 , m_needsFullScopeChain(info.needsActivation()) 229 , m_usesEval(info.usesEval()) 229 230 , m_isNumericCompareFunction(false) 230 , m_isStrictMode(info. m_isStrictMode)231 , m_isConstructor(info. m_isConstructor)231 , m_isStrictMode(info.isStrictMode()) 232 , m_isConstructor(info.isConstructor()) 232 233 , m_hasCapturedVariables(false) 233 , m_isBuiltinFunction(info. m_isBuiltinFunction)234 , m_constructorKind IsDerived(info.m_constructorKindIsDerived)234 , m_isBuiltinFunction(info.isBuiltinFunction()) 235 , m_constructorKind(static_cast<unsigned>(info.constructorKind())) 235 236 , m_firstLine(0) 236 237 , m_lineCount(0) … … 247 248 #endif 248 249 { 249 250 ASSERT(m_constructorKind == static_cast<unsigned>(info.constructorKind())); 250 251 } 251 252 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r181293 r181490 66 66 67 67 struct ExecutableInfo { 68 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, bool constructorKindIsDerived)68 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind) 69 69 : m_needsActivation(needsActivation) 70 70 , m_usesEval(usesEval) … … 72 72 , m_isConstructor(isConstructor) 73 73 , m_isBuiltinFunction(isBuiltinFunction) 74 , m_constructorKindIsDerived(constructorKindIsDerived) 75 { 76 } 77 bool m_needsActivation : 1; 78 bool m_usesEval : 1; 79 bool m_isStrictMode : 1; 80 bool m_isConstructor : 1; 81 bool m_isBuiltinFunction : 1; 82 bool m_constructorKindIsDerived : 1; 74 , m_constructorKind(static_cast<unsigned>(constructorKind)) 75 { 76 ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind)); 77 } 78 79 bool needsActivation() const { return m_needsActivation; } 80 bool usesEval() const { return m_usesEval; } 81 bool isStrictMode() const { return m_isStrictMode; } 82 bool isConstructor() const { return m_isConstructor; } 83 bool isBuiltinFunction() const { return m_isBuiltinFunction; } 84 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } 85 86 private: 87 unsigned m_needsActivation : 1; 88 unsigned m_usesEval : 1; 89 unsigned m_isStrictMode : 1; 90 unsigned m_isConstructor : 1; 91 unsigned m_isBuiltinFunction : 1; 92 unsigned m_constructorKind : 2; 83 93 }; 84 94 … … 119 129 return JSParseNormal; 120 130 } 121 bool constructorKindIsDerived() const { return m_constructorKindIsDerived; }131 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } 122 132 123 133 unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; } … … 168 178 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; 169 179 170 boolm_isInStrictContext : 1;171 boolm_hasCapturedVariables : 1;172 boolm_isBuiltinFunction : 1;173 bool m_constructorKindIsDerived : 1;180 unsigned m_isInStrictContext : 1; 181 unsigned m_hasCapturedVariables : 1; 182 unsigned m_isBuiltinFunction : 1; 183 unsigned m_constructorKind : 2; 174 184 175 185 Identifier m_name; … … 347 357 bool isBuiltinFunction() const { return m_isBuiltinFunction; } 348 358 349 bool constructorKindIsDerived() const { return m_constructorKindIsDerived; }359 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } 350 360 351 361 void shrinkToFit() … … 533 543 VirtualRegister m_globalObjectRegister; 534 544 535 bool m_needsFullScopeChain : 1; 536 bool m_usesEval : 1; 537 bool m_isNumericCompareFunction : 1; 538 bool m_isStrictMode : 1; 539 bool m_isConstructor : 1; 540 bool m_hasCapturedVariables : 1; 541 bool m_isBuiltinFunction : 1; 542 bool m_constructorKindIsDerived : 1; 545 unsigned m_needsFullScopeChain : 1; 546 unsigned m_usesEval : 1; 547 unsigned m_isNumericCompareFunction : 1; 548 unsigned m_isStrictMode : 1; 549 unsigned m_isConstructor : 1; 550 unsigned m_hasCapturedVariables : 1; 551 unsigned m_isBuiltinFunction : 1; 552 unsigned m_constructorKind : 2; 553 543 554 unsigned m_firstLine; 544 555 unsigned m_lineCount; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r181466 r181490 69 69 } 70 70 71 m_scopeNode->emitBytecode(*this); 71 bool callingClassConstructor = constructorKind() != ConstructorKind::None && !isConstructor(); 72 if (!callingClassConstructor) 73 m_scopeNode->emitBytecode(*this); 72 74 73 75 m_staticPropertyAnalyzer.kill(); … … 402 404 403 405 if (isConstructor()) { 404 if (constructorKind IsDerived()) {406 if (constructorKind() == ConstructorKind::Derived) { 405 407 m_newTargetRegister = addVar(); 406 408 emitMove(m_newTargetRegister, &m_thisRegister); … … 408 410 } else 409 411 emitCreateThis(&m_thisRegister); 412 } else if (constructorKind() != ConstructorKind::None) { 413 emitThrowTypeError("Cannot call a class constructor"); 410 414 } else if (functionNode->usesThis() || codeBlock->usesEval()) { 411 415 m_codeBlock->addPropertyAccessInstruction(instructions().size()); … … 1913 1917 } 1914 1918 1915 bool thisMightBeUninitialized = constructorKind IsDerived();1919 bool thisMightBeUninitialized = constructorKind() == ConstructorKind::Derived; 1916 1920 bool srcIsThis = src->index() == m_thisRegister.index(); 1917 1921 if (isConstructor() && (!srcIsThis || thisMightBeUninitialized)) { -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r181466 r181490 272 272 bool isConstructor() const { return m_codeBlock->isConstructor(); } 273 273 #if ENABLE(ES6_CLASS_SYNTAX) 274 bool constructorKindIsDerived() const { return m_codeBlock->constructorKindIsDerived(); }274 ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); } 275 275 #else 276 bool constructorKindIsDerived() const { return false; }276 ConstructorKind constructorKind() const { return ConstructorKind::None; } 277 277 #endif 278 278 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r181466 r181490 145 145 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 146 146 { 147 if (generator.constructorKind IsDerived())147 if (generator.constructorKind() == ConstructorKind::Derived) 148 148 generator.emitTDZCheck(generator.thisRegister()); 149 149 … … 575 575 CallArguments callArguments(generator, m_args); 576 576 if (m_expr->isSuperNode()) { 577 ASSERT(generator.constructorKindIsDerived()); 577 ASSERT(generator.isConstructor()); 578 ASSERT(generator.constructorKind() == ConstructorKind::Derived); 578 579 generator.emitMove(callArguments.thisRegister(), generator.newTarget()); 579 580 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); -
trunk/Source/JavaScriptCore/parser/Nodes.cpp
r181293 r181490 174 174 , m_startStartOffset(startLocation.startOffset) 175 175 , m_isInStrictContext(isInStrictContext) 176 , m_constructorKindIsDerived(constructorKind == ConstructorKind::Derived) 177 { 176 , m_constructorKind(static_cast<unsigned>(constructorKind)) 177 { 178 ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind)); 178 179 } 179 180 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r181293 r181490 1588 1588 int startStartOffset() const { return m_startStartOffset; } 1589 1589 bool isInStrictContext() const { return m_isInStrictContext; } 1590 bool constructorKindIsDerived() { return m_constructorKindIsDerived; }1590 ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); } 1591 1591 1592 1592 protected: … … 1601 1601 SourceCode m_source; 1602 1602 int m_startStartOffset; 1603 boolm_isInStrictContext : 1;1604 bool m_constructorKindIsDerived : 1;1603 unsigned m_isInStrictContext : 1; 1604 unsigned m_constructorKind : 2; 1605 1605 }; 1606 1606 -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r181419 r181490 1292 1292 template <typename LexerType> 1293 1293 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, 1294 bool nameIsInContainingScope, ConstructorKind constructorKind, ParserFunctionInfo<TreeBuilder>& info)1294 bool nameIsInContainingScope, ConstructorKind ownerClassKind, ParserFunctionInfo<TreeBuilder>& info) 1295 1295 { 1296 1296 AutoPopScopeRef functionScope(this, pushScope()); … … 1322 1322 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration"); 1323 1323 matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body"); 1324 1324 1325 // BytecodeGenerator emits code to throw TypeError when a class constructor is "call"ed. 1326 // Set ConstructorKind to None for non-constructor methods of classes. 1327 bool isClassConstructor = mode == MethodMode && info.name && *info.name == m_vm->propertyNames->constructor; 1328 ConstructorKind constructorKind = isClassConstructor ? ownerClassKind : ConstructorKind::None; 1329 1325 1330 info.openBraceOffset = m_token.m_data.offset; 1326 1331 info.bodyStartLine = tokenLine(); … … 1378 1383 } 1379 1384 if (functionScope->hasDirectSuper()) { 1380 bool isClassConstructor = mode == MethodMode && info.name && *info.name == m_vm->propertyNames->constructor;1381 1385 semanticFailIfTrue(!isClassConstructor, "Cannot call super() outside of a class constructor"); 1382 semanticFailIfTrue( constructorKind == ConstructorKind::Base, "Cannot call super() in a base class constructor");1386 semanticFailIfTrue(ownerClassKind != ConstructorKind::Derived, "Cannot call super() in a base class constructor"); 1383 1387 } 1384 1388 if (functionScope->needsSuperBinding()) 1385 semanticFailIfTrue( constructorKind == ConstructorKind::Base, "super can only be used in a method of a derived class");1389 semanticFailIfTrue(ownerClassKind != ConstructorKind::Derived, "super can only be used in a method of a derived class"); 1386 1390 1387 1391 info.closeBraceOffset = m_token.m_data.offset; … … 1425 1429 next(); 1426 1430 ParserFunctionInfo<TreeBuilder> info; 1427 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, ConstructorKind:: Base, info)), "Cannot parse this function");1431 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, ConstructorKind::None, info)), "Cannot parse this function"); 1428 1432 failIfFalse(info.name, "Function statements must have a name"); 1429 1433 failIfFalseIfStrict(declareVariable(info.name), "Cannot declare a function named '", info.name->impl(), "' in strict mode"); … … 1513 1517 } else { 1514 1518 ParserFunctionInfo<TreeBuilder> methodInfo; 1515 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, MethodMode, false, constructorKind, methodInfo)), "Cannot parse this method");1519 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, isStaticMethod ? FunctionMode : MethodMode, false, constructorKind, methodInfo)), "Cannot parse this method"); 1516 1520 failIfFalse(methodInfo.name, "method must have a name"); 1517 1521 failIfFalse(declareVariable(methodInfo.name), "Cannot declare a method named '", methodInfo.name->impl(), "'"); … … 2018 2022 unsigned methodStart = tokenStart(); 2019 2023 ParserFunctionInfo<TreeBuilder> methodInfo; 2020 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, ConstructorKind:: Base, methodInfo)), "Cannot parse this method");2024 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, ConstructorKind::None, methodInfo)), "Cannot parse this method"); 2021 2025 methodInfo.name = methodName; 2022 2026 return context.createFunctionExpr(methodLocation, methodInfo, methodStart); … … 2232 2236 ParserFunctionInfo<TreeBuilder> info; 2233 2237 info.name = &m_vm->propertyNames->nullIdentifier; 2234 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind:: Base, info)), "Cannot parse function expression");2238 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind::None, info)), "Cannot parse function expression"); 2235 2239 return context.createFunctionExpr(location, info, functionKeywordStart); 2236 2240 } -
trunk/Source/JavaScriptCore/parser/Parser.h
r181404 r181490 759 759 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict); 760 760 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName); 761 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind:: Base, SuperBinding = SuperBinding::NotNeeded);761 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind::None, SuperBinding = SuperBinding::NotNeeded); 762 762 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, ConstructorKind); 763 763 template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&); -
trunk/Source/JavaScriptCore/parser/ParserModes.h
r181293 r181490 35 35 enum JSParserMode { JSParseProgramCode, JSParseFunctionCode }; 36 36 37 enum class ConstructorKind { Base, Derived };37 enum class ConstructorKind { None, Base, Derived }; 38 38 enum class SuperBinding { Needed, NotNeeded }; 39 39 -
trunk/Source/JavaScriptCore/runtime/Executable.h
r181293 r181490 468 468 void clearCode(); 469 469 470 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, false); }470 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None); } 471 471 472 472 unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); } … … 523 523 void clearCode(); 524 524 525 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, false); }525 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None); } 526 526 527 527 private:
Note:
See TracChangeset
for help on using the changeset viewer.