Changeset 181293 in webkit
- Timestamp:
- Mar 9, 2015 4:47:06 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r181292 r181293 1 2015-03-09 Ryosuke Niwa <rniwa@webkit.org> 2 3 Support extends and super keywords 4 https://bugs.webkit.org/show_bug.cgi?id=142200 5 6 Reviewed by Filip Pizlo. 7 8 Added tests for "extends" and "super" keywords. 9 10 * TestExpectations: 11 * js/class-syntax-extends-expected.txt: Added. 12 * js/class-syntax-extends.html: Added. 13 * js/class-syntax-super-expected.txt: Added. 14 * js/class-syntax-super.html: Added. 15 * js/script-tests/class-syntax-extends.js: Added. 16 * js/script-tests/class-syntax-super.js: Added. 17 1 18 2015-03-09 Myles C. Maxfield <mmaxfield@apple.com> 2 19 -
trunk/LayoutTests/TestExpectations
r181132 r181293 70 70 webkit.org/b/140491 js/class-syntax-declaration.html [ Failure ] 71 71 webkit.org/b/140491 js/class-syntax-expression.html [ Failure ] 72 webkit.org/b/140491 js/class-syntax-extends.html [ Failure ] 73 webkit.org/b/140491 js/class-syntax-super.html [ Failure ] 72 74 73 75 # This test verifies dynamic manipulation of the mroot and msqrt elements. -
trunk/Source/JavaScriptCore/ChangeLog
r181250 r181293 1 2015-03-09 Ryosuke Niwa <rniwa@webkit.org> 2 3 Support extends and super keywords 4 https://bugs.webkit.org/show_bug.cgi?id=142200 5 6 Reviewed by Filip Pizlo. 7 8 Added the support for ES6 class syntax inheritance. 9 10 Added ConstructorKind as well as boolean flags indicating the constructor kind to 11 various classes in UnlinkedCodeBlock as well as AST nodes. 12 13 Each method stores the associated class as its homeObjectPrivateName. This value is used to 14 make super calls. 15 16 * bytecode/UnlinkedCodeBlock.cpp: 17 (JSC::generateFunctionCodeBlock): 18 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 19 (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): 20 21 * bytecode/UnlinkedCodeBlock.h: 22 (JSC::ExecutableInfo::ExecutableInfo): 23 (JSC::UnlinkedFunctionExecutable::constructorKindIsDerived): Added. 24 (JSC::UnlinkedCodeBlock::constructorKindIsDerived): Added. 25 26 * bytecompiler/BytecodeGenerator.cpp: 27 (JSC::BytecodeGenerator::BytecodeGenerator): Don't emit op_create_this in a derived class 28 as the object is allocated by the highest base class's constructor. Also set "this" to null 29 and store the original value in m_newTargetRegister. "this" is supposed to be in TDZ but 30 that will be implemented in a separate patch. 31 (JSC::BytecodeGenerator::emitReturn): Allow "undefined" to be returned from a derived class. 32 In a derived class's constructor, not returning "undefined" or an object results in a type 33 error instead of "this" being returned. 34 (JSC::BytecodeGenerator::emitThrowTypeError): Added. 35 36 * bytecompiler/BytecodeGenerator.h: 37 (JSC::BytecodeGenerator::constructorKindIsDerived): Added. 38 (JSC::BytecodeGenerator::newTarget): Added. 39 40 * bytecompiler/NodesCodegen.cpp: 41 (JSC::SuperNode::emitBytecode): Added. Emits the code to obtain the callee's parent class. 42 (JSC::emitSuperBaseForCallee): Added. Emits the code to obtain the parent class's prototype. 43 (JSC::emitPutHomeObject): Added. 44 (JSC::PropertyListNode::emitBytecode): Stores the home object when adding methods. 45 (JSC::PropertyListNode::emitPutConstantProperty): Ditto. 46 (JSC::BracketAccessorNode::emitBytecode): Added the support for super['foo']. 47 (JSC::DotAccessorNode::emitBytecode): Added the support for super.foo. 48 (JSC::FunctionCallValueNode::emitBytecode): Added the support for super(). 49 (JSC::FunctionCallBracketNode::emitBytecode): Added the support for super['foo'](). 50 (JSC::FunctionCallDotNode::emitBytecode): Added the support for super.foo(). 51 (JSC::DeleteBracketNode::emitBytecode): Forbid "delete super.foo". 52 (JSC::DeleteDotNode::emitBytecode): Forbid "delete super['foo']". 53 (JSC::ClassExprNode::emitBytecode): Added the support for "classHeritage". This is the main 54 logic for inheritance. When a class B inherits from a class A, set B.__proto__ to A and set 55 B.prototype.__proto__ to A.prototype. Throw exceptions when either A or A.__proto__ is not 56 an object. 57 58 * parser/ASTBuilder.h: 59 (JSC::ASTBuilder::superExpr): Added. 60 61 * parser/NodeConstructors.h: 62 (JSC::SuperNode::SuperNode): Added. 63 64 * parser/Nodes.cpp: 65 (JSC::FunctionBodyNode::FunctionBodyNode): 66 67 * parser/Nodes.h: 68 (JSC::ExpressionNode::isSuperNode): 69 (JSC::PropertyNode::type): 70 (JSC::PropertyNode::needsSuperBinding): 71 72 * parser/Parser.cpp: 73 (JSC::Parser<LexerType>::parseFunctionBody): 74 (JSC::Parser<LexerType>::parseFunctionInfo): Throw a parser error if super() is used outside 75 of class constructors. 76 (JSC::Parser<LexerType>::parseFunctionDeclaration): 77 (JSC::Parser<LexerType>::parseClass): ConstructorKind is "derived" if and only if the parent 78 class is specified in the declaration / expression. 79 (JSC::Parser<LexerType>::parseGetterSetter): 80 (JSC::Parser<LexerType>::parsePrimaryExpression): 81 (JSC::Parser<LexerType>::parseMemberExpression): Added the support for "super()", "super.foo", 82 and "super['foo']". Throw a semantic error if "super" appears by itself. 83 84 * parser/Parser.h: 85 (JSC::Scope::Scope): Added m_hasDirectSuper. This variable keeps track of the use of "super()" 86 so that parseFunctionInfo can spit an error if it's used outside of class constructors. 87 (JSC::Scope::hasDirectSuper): Added. 88 (JSC::Scope::setHasDirectSuper): Added. 89 90 * parser/ParserModes.h: 91 (JSC::ConstructorKind): Added. 92 93 * parser/SyntaxChecker.h: 94 (JSC::SyntaxChecker::superExpr): Added. 95 96 * runtime/CommonIdentifiers.h: Added homeObjectPrivateName. 97 98 * runtime/Executable.h: 99 (JSC::EvalExecutable::executableInfo): 100 (JSC::ProgramExecutable::executableInfo): 101 1 102 2015-03-08 Andreas Kling <akling@apple.com> 2 103 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
r181213 r181293 62 62 executable->recordParse(function->features(), function->hasCapturedVariables()); 63 63 64 UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction)); 64 UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, 65 ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKindIsDerived())); 65 66 auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode)); 66 67 error = generator->generate(); … … 85 86 , m_hasCapturedVariables(false) 86 87 , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction) 88 , m_constructorKindIsDerived(node->constructorKindIsDerived()) 87 89 , m_name(node->ident()) 88 90 , m_inferredName(node->inferredName()) … … 230 232 , m_hasCapturedVariables(false) 231 233 , m_isBuiltinFunction(info.m_isBuiltinFunction) 234 , m_constructorKindIsDerived(info.m_constructorKindIsDerived) 232 235 , m_firstLine(0) 233 236 , m_lineCount(0) -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r181213 r181293 66 66 67 67 struct ExecutableInfo { 68 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction )68 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, bool constructorKindIsDerived) 69 69 : m_needsActivation(needsActivation) 70 70 , m_usesEval(usesEval) … … 72 72 , m_isConstructor(isConstructor) 73 73 , m_isBuiltinFunction(isBuiltinFunction) 74 , m_constructorKindIsDerived(constructorKindIsDerived) 74 75 { 75 76 } … … 79 80 bool m_isConstructor : 1; 80 81 bool m_isBuiltinFunction : 1; 82 bool m_constructorKindIsDerived : 1; 81 83 }; 82 84 … … 117 119 return JSParseNormal; 118 120 } 121 bool constructorKindIsDerived() const { return m_constructorKindIsDerived; } 119 122 120 123 unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; } … … 168 171 bool m_hasCapturedVariables : 1; 169 172 bool m_isBuiltinFunction : 1; 173 bool m_constructorKindIsDerived : 1; 170 174 171 175 Identifier m_name; … … 342 346 343 347 bool isBuiltinFunction() const { return m_isBuiltinFunction; } 344 348 349 bool constructorKindIsDerived() const { return m_constructorKindIsDerived; } 350 345 351 void shrinkToFit() 346 352 { … … 534 540 bool m_hasCapturedVariables : 1; 535 541 bool m_isBuiltinFunction : 1; 542 bool m_constructorKindIsDerived : 1; 536 543 unsigned m_firstLine; 537 544 unsigned m_lineCount; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r181179 r181293 402 402 403 403 if (isConstructor()) { 404 emitCreateThis(&m_thisRegister); 404 if (constructorKindIsDerived()) { 405 m_newTargetRegister = addVar(); 406 emitMove(m_newTargetRegister, &m_thisRegister); 407 emitLoad(&m_thisRegister, jsNull()); 408 } else 409 emitCreateThis(&m_thisRegister); 405 410 } else if (functionNode->usesThis() || codeBlock->usesEval()) { 406 411 m_codeBlock->addPropertyAccessInstruction(instructions().size()); … … 1902 1907 } 1903 1908 1904 if (isConstructor() && src->index() != m_thisRegister.index()) { 1905 RefPtr<Label> isObjectLabel = newLabel(); 1906 1907 emitJumpIfTrue(emitIsObject(newTemporary(), src), isObjectLabel.get()); 1908 1909 emitUnaryNoDstOp(op_ret, &m_thisRegister); 1910 1911 emitLabel(isObjectLabel.get()); 1909 bool thisMightBeUninitialized = constructorKindIsDerived(); 1910 if (isConstructor() && (src->index() != m_thisRegister.index() || thisMightBeUninitialized)) { 1911 RefPtr<Label> isObjectOrUndefinedLabel = newLabel(); 1912 1913 emitJumpIfTrue(emitIsObject(newTemporary(), src), isObjectOrUndefinedLabel.get()); 1914 1915 if (constructorKindIsDerived()) { 1916 emitJumpIfTrue(emitIsUndefined(newTemporary(), src), isObjectOrUndefinedLabel.get()); 1917 emitThrowTypeError("Cannot return a non-object type in the constructor of a derived class."); 1918 } else 1919 emitUnaryNoDstOp(op_ret, &m_thisRegister); 1920 1921 emitLabel(isObjectOrUndefinedLabel.get()); 1912 1922 } 1913 1923 return emitUnaryNoDstOp(op_ret, src); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r181179 r181293 270 270 const CommonIdentifiers& propertyNames() const { return *m_vm->propertyNames; } 271 271 272 bool isConstructor() { return m_codeBlock->isConstructor(); } 272 bool isConstructor() const { return m_codeBlock->isConstructor(); } 273 #if ENABLE(ES6_CLASS_SYNTAX) 274 bool constructorKindIsDerived() const { return m_codeBlock->constructorKindIsDerived(); } 275 #else 276 bool constructorKindIsDerived() const { return false; } 277 #endif 273 278 274 279 ParserError generate(); … … 291 296 // Returns the register storing "this" 292 297 RegisterID* thisRegister() { return &m_thisRegister; } 293 298 RegisterID* newTarget() { return m_newTargetRegister; } 299 294 300 RegisterID* scopeRegister() { return m_scopeRegister; } 295 301 … … 764 770 RegisterID* m_globalObjectRegister { nullptr }; 765 771 RegisterID* m_localArgumentsRegister { nullptr }; 772 RegisterID* m_newTargetRegister { nullptr }; 766 773 767 774 Vector<Identifier, 16> m_watchableVariables; -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r181179 r181293 157 157 } 158 158 159 // ------------------------------ SuperNode ------------------------------------- 160 161 RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 162 { 163 if (dst == generator.ignoredResult()) 164 return 0; 165 166 RegisterID callee; 167 callee.setIndex(JSStack::Callee); 168 169 RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName); 170 RefPtr<RegisterID> protoParent = generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto); 171 return generator.emitGetById(generator.finalDestination(dst), protoParent.get(), generator.propertyNames().constructor); 172 } 173 174 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator) 175 { 176 RegisterID callee; 177 callee.setIndex(JSStack::Callee); 178 179 RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName); 180 return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto); 181 } 182 159 183 // ------------------------------ ResolveNode ---------------------------------- 160 184 … … 295 319 // ------------------------------ PropertyListNode ----------------------------- 296 320 321 static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject) 322 { 323 generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject); 324 } 325 297 326 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 298 327 { … … 331 360 332 361 RegisterID* value = generator.emitNode(node->m_assign); 362 if (node->needsSuperBinding()) 363 emitPutHomeObject(generator, value, dst); 333 364 334 365 // This is a get/set property, find its entry in the map. … … 345 376 RefPtr<RegisterID> getterReg; 346 377 RefPtr<RegisterID> setterReg; 378 RegisterID* secondReg = nullptr; 347 379 348 380 if (node->m_type == PropertyNode::Getter) { … … 351 383 ASSERT(pair.second->m_type == PropertyNode::Setter); 352 384 setterReg = generator.emitNode(pair.second->m_assign); 385 secondReg = setterReg.get(); 353 386 } else { 354 387 setterReg = generator.newTemporary(); … … 361 394 ASSERT(pair.second->m_type == PropertyNode::Getter); 362 395 getterReg = generator.emitNode(pair.second->m_assign); 396 secondReg = getterReg.get(); 363 397 } else { 364 398 getterReg = generator.newTemporary(); … … 367 401 } 368 402 403 if (pair.second && pair.second->needsSuperBinding()) 404 emitPutHomeObject(generator, secondReg, dst); 405 369 406 generator.emitPutGetterSetter(dst, *node->name(), getterReg.get(), setterReg.get()); 370 407 } … … 376 413 void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node) 377 414 { 415 RefPtr<RegisterID> value = generator.emitNode(node.m_assign); 416 if (node.needsSuperBinding()) 417 emitPutHomeObject(generator, value.get(), newObj); 378 418 if (node.name()) { 379 generator.emitDirectPutById(newObj, *node.name(), generator.emitNode(node.m_assign), node.putType());419 generator.emitDirectPutById(newObj, *node.name(), value.get(), node.putType()); 380 420 return; 381 421 } 382 422 RefPtr<RegisterID> propertyName = generator.emitNode(node.m_expression); 383 generator.emitDirectPutByVal(newObj, propertyName.get(), generator.emitNode(node.m_assign));423 generator.emitDirectPutByVal(newObj, propertyName.get(), value.get()); 384 424 } 385 425 … … 388 428 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 389 429 { 430 if (m_base->isSuperNode()) { 431 // FIXME: Should we generate the profiler info? 432 if (m_subscript->isString()) { 433 const Identifier& id = static_cast<StringNode*>(m_subscript)->value(); 434 return generator.emitGetById(generator.finalDestination(dst), emitSuperBaseForCallee(generator), id); 435 } 436 return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript)); 437 } 438 390 439 if (m_base->isResolveNode() 391 440 && generator.willResolveToArgumentsRegister(static_cast<ResolveNode*>(m_base)->identifier()) … … 432 481 433 482 nonArgumentsPath: 434 RefPtr<RegisterID> base = generator.emitNode(m_base);483 RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base); 435 484 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 436 485 RegisterID* finalDest = generator.finalDestination(dst); … … 522 571 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get()); 523 572 CallArguments callArguments(generator, m_args); 573 if (m_expr->isSuperNode()) { 574 ASSERT(generator.constructorKindIsDerived()); 575 generator.emitMove(callArguments.thisRegister(), generator.newTarget()); 576 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); 577 generator.emitMove(generator.thisRegister(), ret); 578 return ret; 579 } 524 580 generator.emitLoad(callArguments.thisRegister(), jsUndefined()); 525 581 RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); … … 575 631 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 576 632 { 577 RefPtr<RegisterID> base = generator.emitNode(m_base); 633 bool baseIsSuper = m_base->isSuperNode(); 634 RefPtr<RegisterID> base = baseIsSuper ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base); 578 635 RefPtr<RegisterID> property = generator.emitNode(m_subscript); 579 636 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd()); … … 581 638 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get()); 582 639 CallArguments callArguments(generator, m_args); 583 generator.emitMove(callArguments.thisRegister(), base.get()); 640 if (baseIsSuper) 641 generator.emitMove(callArguments.thisRegister(), generator.thisRegister()); 642 else 643 generator.emitMove(callArguments.thisRegister(), base.get()); 584 644 RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); 585 645 if (generator.vm()->typeProfiler()) { … … 597 657 RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get()); 598 658 CallArguments callArguments(generator, m_args); 599 generator.emitNode(callArguments.thisRegister(), m_base); 659 bool baseIsSuper = m_base->isSuperNode(); 660 if (baseIsSuper) 661 generator.emitMove(callArguments.thisRegister(), generator.thisRegister()); 662 else 663 generator.emitNode(callArguments.thisRegister(), m_base); 600 664 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd()); 601 generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);665 generator.emitGetById(function.get(), baseIsSuper ? emitSuperBaseForCallee(generator) : callArguments.thisRegister(), m_ident); 602 666 RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); 603 667 if (generator.vm()->typeProfiler()) { … … 941 1005 942 1006 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1007 if (m_base->isSuperNode()) 1008 return emitThrowReferenceError(generator, "Cannot delete a super property"); 943 1009 return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get()); 944 1010 } … … 951 1017 952 1018 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1019 if (m_base->isSuperNode()) 1020 return emitThrowReferenceError(generator, "Cannot delete a super property"); 953 1021 return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident); 954 1022 } … … 2808 2876 RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 2809 2877 { 2810 ASSERT(!m_parentClassExpression); 2878 RefPtr<RegisterID> superclass; 2879 if (m_classHeritage) { 2880 superclass = generator.newTemporary(); 2881 generator.emitNode(superclass.get(), m_classHeritage); 2882 } 2811 2883 2812 2884 RefPtr<RegisterID> constructor = generator.emitNode(dst, m_constructorExpression); 2885 // FIXME: Make the prototype non-configurable & non-writable. 2813 2886 RefPtr<RegisterID> prototype = generator.emitGetById(generator.newTemporary(), constructor.get(), generator.propertyNames().prototype); 2887 2888 if (superclass) { 2889 RefPtr<RegisterID> tempRegister = generator.newTemporary(); 2890 RefPtr<Label> superclassIsNullLabel = generator.newLabel(); 2891 generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get()); 2892 2893 // FIXME: Throw TypeError if it's a generator function. 2894 RefPtr<Label> superclassIsObjectLabel = generator.newLabel(); 2895 generator.emitJumpIfTrue(generator.emitIsObject(tempRegister.get(), superclass.get()), superclassIsObjectLabel.get()); 2896 generator.emitThrowTypeError(ASCIILiteral("The superclass is not an object.")); 2897 generator.emitLabel(superclassIsObjectLabel.get()); 2898 2899 RefPtr<RegisterID> protoParent = generator.newTemporary(); 2900 generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype); 2901 2902 RefPtr<Label> protoParentIsObjectOrNullLabel = generator.newLabel(); 2903 generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_object_or_null, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get()); 2904 generator.emitThrowTypeError(ASCIILiteral("The superclass's prototype is not an object.")); 2905 generator.emitLabel(protoParentIsObjectOrNullLabel.get()); 2906 2907 generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown); 2908 generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown); 2909 2910 generator.emitLabel(superclassIsNullLabel.get()); 2911 emitPutHomeObject(generator, constructor.get(), prototype.get()); 2912 } 2814 2913 2815 2914 if (m_staticMethods) -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r181179 r181293 170 170 return new (m_parserArena) ThisNode(location); 171 171 } 172 ExpressionNode* superExpr(const JSTokenLocation& location) 173 { 174 return new (m_parserArena) SuperNode(location); 175 } 172 176 ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start) 173 177 { … … 299 303 } 300 304 301 FunctionBodyNode* createFunctionBody(const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext )302 { 303 return new (m_parserArena) FunctionBodyNode(m_parserArena, startLocation, endLocation, startColumn, endColumn, inStrictContext );305 FunctionBodyNode* createFunctionBody(const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext, ConstructorKind constructorKind) 306 { 307 return new (m_parserArena) FunctionBodyNode(m_parserArena, startLocation, endLocation, startColumn, endColumn, inStrictContext, constructorKind); 304 308 } 305 309 … … 310 314 311 315 NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool, 312 const Identifier* name, const ParserFunctionInfo<ASTBuilder>& info, unsigned getOrSetStartOffset )316 const Identifier* name, const ParserFunctionInfo<ASTBuilder>& info, unsigned getOrSetStartOffset, SuperBinding superBinding) 313 317 { 314 318 ASSERT(name); … … 316 320 info.body->setInferredName(*name); 317 321 info.body->setFunctionKeywordStart(getOrSetStartOffset); 318 return new (m_parserArena) PropertyNode(*name, new (m_parserArena) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, 319 info.body, m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters), type, PropertyNode::Unknown); 320 } 321 322 NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type, bool, double name, const ParserFunctionInfo<ASTBuilder>& info, unsigned getOrSetStartOffset) 322 SourceCode source = m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn); 323 FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, info.body, source, info.parameters); 324 return new (m_parserArena) PropertyNode(*name, funcExpr, type, PropertyNode::Unknown, superBinding); 325 } 326 327 NEVER_INLINE PropertyNode* createGetterOrSetterProperty(VM* vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type, bool, 328 double name, const ParserFunctionInfo<ASTBuilder>& info, unsigned getOrSetStartOffset, SuperBinding superBinding) 323 329 { 324 330 info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset); 325 331 info.body->setFunctionKeywordStart(getOrSetStartOffset); 326 332 const Identifier& ident = parserArena.identifierArena().makeNumericIdentifier(vm, name); 327 return new (m_parserArena) PropertyNode(ident, new (m_parserArena) FuncExprNode(location, vm->propertyNames->nullIdentifier, 328 info.body, m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters), type, PropertyNode::Unknown); 333 SourceCode source = m_sourceCode->subExpression(info.openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn); 334 FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, vm->propertyNames->nullIdentifier, info.body, source, info.parameters); 335 return new (m_parserArena) PropertyNode(ident, funcExpr, type, PropertyNode::Unknown, superBinding); 329 336 } 330 337 … … 334 341 ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_parserArena) ArgumentListNode(location, args, arg); } 335 342 336 PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool )343 PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool, SuperBinding superBinding = SuperBinding::NotNeeded) 337 344 { 338 345 if (node->isFuncExprNode()) 339 346 static_cast<FuncExprNode*>(node)->body()->setInferredName(*propertyName); 340 return new (m_parserArena) PropertyNode(*propertyName, node, type, putType );347 return new (m_parserArena) PropertyNode(*propertyName, node, type, putType, superBinding); 341 348 } 342 349 PropertyNode* createProperty(VM* vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, PropertyNode::PutType putType, bool) -
trunk/Source/JavaScriptCore/parser/NodeConstructors.h
r181179 r181293 113 113 } 114 114 115 inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start) 115 inline SuperNode::SuperNode(const JSTokenLocation& location) 116 : ExpressionNode(location) 117 { 118 } 119 120 inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start) 116 121 : ExpressionNode(location) 117 122 , m_ident(ident) … … 160 165 } 161 166 162 inline PropertyNode::PropertyNode(const Identifier& name, ExpressionNode* assign, Type type, PutType putType )167 inline PropertyNode::PropertyNode(const Identifier& name, ExpressionNode* assign, Type type, PutType putType, SuperBinding superBinding = SuperBinding::NotNeeded) 163 168 : m_name(&name) 164 169 , m_assign(assign) 165 170 , m_type(type) 171 , m_needsSuperBinding(superBinding == SuperBinding::Needed) 166 172 , m_putType(putType) 167 173 { … … 173 179 , m_assign(assign) 174 180 , m_type(type) 181 , m_needsSuperBinding(false) 175 182 , m_putType(putType) 176 183 { … … 788 795 } 789 796 790 inline ClassExprNode::ClassExprNode(const JSTokenLocation& location, const Identifier& name, ExpressionNode* constructorExpression, ExpressionNode* parentClassExpression, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)797 inline ClassExprNode::ClassExprNode(const JSTokenLocation& location, const Identifier& name, ExpressionNode* constructorExpression, ExpressionNode* classHeritage, PropertyListNode* instanceMethods, PropertyListNode* staticMethods) 791 798 : ExpressionNode(location) 792 799 , m_name(name) 793 800 , m_constructorExpression(constructorExpression) 794 , m_ parentClassExpression(parentClassExpression)801 , m_classHeritage(classHeritage) 795 802 , m_instanceMethods(instanceMethods) 796 803 , m_staticMethods(staticMethods) -
trunk/Source/JavaScriptCore/parser/Nodes.cpp
r180012 r181293 168 168 } 169 169 170 FunctionBodyNode::FunctionBodyNode(ParserArena&, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool isInStrictContext )170 FunctionBodyNode::FunctionBodyNode(ParserArena&, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool isInStrictContext, ConstructorKind constructorKind) 171 171 : StatementNode(endLocation) 172 172 , m_startColumn(startColumn) … … 174 174 , m_startStartOffset(startLocation.startOffset) 175 175 , m_isInStrictContext(isInStrictContext) 176 , m_constructorKindIsDerived(constructorKind == ConstructorKind::Derived) 176 177 { 177 178 } -
trunk/Source/JavaScriptCore/parser/Nodes.h
r181179 r181293 165 165 virtual bool isBoolean() const { return false; } 166 166 virtual bool isSpreadExpression() const { return false; } 167 virtual bool isSuperNode() const { return false; } 167 168 168 169 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode); … … 446 447 }; 447 448 449 class SuperNode final : public ExpressionNode { 450 public: 451 SuperNode(const JSTokenLocation&); 452 453 private: 454 virtual bool isSuperNode() const override { return true; } 455 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 456 }; 457 448 458 class ResolveNode : public ExpressionNode { 449 459 public: … … 502 512 enum PutType { Unknown, KnownDirect }; 503 513 504 PropertyNode(const Identifier&, ExpressionNode*, Type, PutType );514 PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding); 505 515 PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType); 506 516 507 517 ExpressionNode* expressionName() const { return m_expression; } 508 518 const Identifier* name() const { return m_name; } 509 519 510 Type type() const { return m_type; } 511 PutType putType() const { return m_putType; } 520 Type type() const { return static_cast<Type>(m_type); } 521 bool needsSuperBinding() const { return m_needsSuperBinding; } 522 PutType putType() const { return static_cast<PutType>(m_putType); } 512 523 513 524 private: … … 516 527 ExpressionNode* m_expression; 517 528 ExpressionNode* m_assign; 518 Type m_type; 519 PutType m_putType; 529 unsigned m_type : 3; 530 unsigned m_needsSuperBinding : 1; 531 unsigned m_putType : 1; 520 532 }; 521 533 … … 1548 1560 using ParserArenaDeletable::operator new; 1549 1561 1550 FunctionBodyNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isInStrictContext );1562 FunctionBodyNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isInStrictContext, ConstructorKind); 1551 1563 1552 1564 FunctionParameters* parameters() const { return m_parameters.get(); } … … 1576 1588 int startStartOffset() const { return m_startStartOffset; } 1577 1589 bool isInStrictContext() const { return m_isInStrictContext; } 1590 bool constructorKindIsDerived() { return m_constructorKindIsDerived; } 1578 1591 1579 1592 protected: … … 1588 1601 SourceCode m_source; 1589 1602 int m_startStartOffset; 1590 bool m_isInStrictContext; 1603 bool m_isInStrictContext : 1; 1604 bool m_constructorKindIsDerived : 1; 1591 1605 }; 1592 1606 … … 1645 1659 const Identifier& m_name; 1646 1660 ExpressionNode* m_constructorExpression; 1647 ExpressionNode* m_ parentClassExpression;1661 ExpressionNode* m_classHeritage; 1648 1662 PropertyListNode* m_instanceMethods; 1649 1663 PropertyListNode* m_staticMethods; -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r181183 r181293 1256 1256 1257 1257 template <typename LexerType> 1258 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context )1258 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context, ConstructorKind constructorKind) 1259 1259 { 1260 1260 JSTokenLocation startLocation(tokenLocation()); … … 1264 1264 if (match(CLOSEBRACE)) { 1265 1265 unsigned endColumn = tokenColumn(); 1266 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode() );1266 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode(), constructorKind); 1267 1267 } 1268 1268 DepthManager statementDepth(&m_statementDepth); … … 1271 1271 failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode), "Cannot parse body of this function"); 1272 1272 unsigned endColumn = tokenColumn(); 1273 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode() );1273 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, strictMode(), constructorKind); 1274 1274 } 1275 1275 … … 1291 1291 1292 1292 template <typename LexerType> 1293 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ParserFunctionInfo<TreeBuilder>& info) 1293 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, 1294 bool nameIsInContainingScope, ConstructorKind constructorKind, ParserFunctionInfo<TreeBuilder>& info) 1294 1295 { 1295 1296 AutoPopScopeRef functionScope(this, pushScope()); … … 1344 1345 unsigned currentLineStartOffset = m_token.m_location.lineStartOffset; 1345 1346 1346 info.body = context.createFunctionBody(startLocation, endLocation, info.bodyStartColumn, bodyEndColumn, cachedInfo->strictMode );1347 info.body = context.createFunctionBody(startLocation, endLocation, info.bodyStartColumn, bodyEndColumn, cachedInfo->strictMode, constructorKind); 1347 1348 1348 1349 functionScope->restoreFromSourceProviderCache(cachedInfo); … … 1367 1368 m_lastFunctionName = lastFunctionName; 1368 1369 ParserState oldState = saveState(); 1369 info.body = parseFunctionBody(context );1370 info.body = parseFunctionBody(context, constructorKind); 1370 1371 restoreState(oldState); 1371 1372 failIfFalse(info.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); 1372 1373 context.setEndOffset(info.body, m_lexer->currentOffset()); 1373 1374 if (functionScope->strictMode() && info.name) { 1374 RELEASE_ASSERT(mode == FunctionMode );1375 RELEASE_ASSERT(mode == FunctionMode || mode == MethodMode); 1375 1376 semanticFailIfTrue(m_vm->propertyNames->arguments == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode"); 1376 1377 semanticFailIfTrue(m_vm->propertyNames->eval == *info.name, "'", info.name->impl(), "' is not a valid function name in strict mode"); 1378 } 1379 if (functionScope->hasDirectSuper()) { 1380 bool nameIsConstructor = info.name && *info.name == m_vm->propertyNames->constructor; 1381 semanticFailIfTrue(mode != MethodMode || !nameIsConstructor, "Cannot call super() outside of a class constructor"); 1377 1382 } 1378 1383 info.closeBraceOffset = m_token.m_data.offset; … … 1416 1421 next(); 1417 1422 ParserFunctionInfo<TreeBuilder> info; 1418 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, info)), "Cannot parse this function");1423 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, ConstructorKind::Base, info)), "Cannot parse this function"); 1419 1424 failIfFalse(info.name, "Function statements must have a name"); 1420 1425 failIfFalseIfStrict(declareVariable(info.name), "Cannot declare a function named '", info.name->impl(), "' in strict mode"); … … 1466 1471 parentClass = parsePrimaryExpression(context); 1467 1472 failIfFalse(parentClass, "Cannot parse the parent class name"); 1468 failWithMessage("Inheritance is not supported yet");1469 }1473 } 1474 const ConstructorKind constructorKind = parentClass ? ConstructorKind::Derived : ConstructorKind::Base; 1470 1475 1471 1476 consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings, "Expected opening '{' at the start of a class body"); … … 1499 1504 semanticFailIfTrue(isStaticMethod, "Cannot declare a static", stringForFunctionMode(isGetter ? GetterMode : SetterMode)); 1500 1505 nextExpectIdentifier(LexerFlagsIgnoreReservedWords); 1501 property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter, methodStart );1506 property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter, methodStart, SuperBinding::Needed); 1502 1507 failIfFalse(property, "Cannot parse this method"); 1503 1508 } else { 1504 1509 ParserFunctionInfo<TreeBuilder> methodInfo; 1505 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, false, methodInfo)), "Cannot parse this method");1510 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, MethodMode, false, constructorKind, methodInfo)), "Cannot parse this method"); 1506 1511 failIfFalse(methodInfo.name, "method must have a name"); 1507 1512 failIfFalse(declareVariable(methodInfo.name), "Cannot declare a method named '", methodInfo.name->impl(), "'"); … … 1521 1526 semanticFailIfTrue(isStaticMethod && *methodInfo.name == propertyNames.prototype, 1522 1527 "Cannot declare a static method named 'prototype'"); 1523 property = context.createProperty(methodInfo.name, method, PropertyNode::Constant, PropertyNode::Unknown, alwaysStrictInsideClass );1528 property = context.createProperty(methodInfo.name, method, PropertyNode::Constant, PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed); 1524 1529 } 1525 1530 … … 2008 2013 unsigned methodStart = tokenStart(); 2009 2014 ParserFunctionInfo<TreeBuilder> methodInfo; 2010 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, methodInfo)), "Cannot parse this method");2015 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, ConstructorKind::Base, methodInfo)), "Cannot parse this method"); 2011 2016 methodInfo.name = methodName; 2012 2017 return context.createFunctionExpr(methodLocation, methodInfo, methodStart); … … 2014 2019 2015 2020 template <typename LexerType> 2016 template <class TreeBuilder> TreeProperty Parser<LexerType>::parseGetterSetter(TreeBuilder& context, bool strict, PropertyNode::Type type, unsigned getterOrSetterStartOffset )2021 template <class TreeBuilder> TreeProperty Parser<LexerType>::parseGetterSetter(TreeBuilder& context, bool strict, PropertyNode::Type type, unsigned getterOrSetterStartOffset, SuperBinding superBinding) 2017 2022 { 2018 2023 const Identifier* stringPropertyName = 0; … … 2029 2034 if (type == PropertyNode::Getter) { 2030 2035 failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition"); 2031 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, info)), "Cannot parse getter definition");2036 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, ConstructorKind::Base, info)), "Cannot parse getter definition"); 2032 2037 } else { 2033 2038 failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition"); 2034 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, info)), "Cannot parse setter definition");2039 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, ConstructorKind::Base, info)), "Cannot parse setter definition"); 2035 2040 } 2036 2041 if (stringPropertyName) 2037 return context.createGetterOrSetterProperty(location, type, strict, stringPropertyName, info, getterOrSetterStartOffset );2038 return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, strict, numericPropertyName, info, getterOrSetterStartOffset );2042 return context.createGetterOrSetterProperty(location, type, strict, stringPropertyName, info, getterOrSetterStartOffset, superBinding); 2043 return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, strict, numericPropertyName, info, getterOrSetterStartOffset, superBinding); 2039 2044 } 2040 2045 … … 2221 2226 ParserFunctionInfo<TreeBuilder> info; 2222 2227 info.name = &m_vm->propertyNames->nullIdentifier; 2223 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, info)), "Cannot parse function expression");2228 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind::Base, info)), "Cannot parse function expression"); 2224 2229 return context.createFunctionExpr(location, info, functionKeywordStart); 2225 2230 } … … 2371 2376 } 2372 2377 2373 base = parsePrimaryExpression(context); 2374 2378 #if ENABLE(ES6_CLASS_SYNTAX) 2379 bool baseIsSuper = match(SUPER); 2380 #else 2381 bool baseIsSuper = false; 2382 #endif 2383 2384 if (baseIsSuper) { 2385 base = context.superExpr(location); 2386 next(); 2387 } else 2388 base = parsePrimaryExpression(context); 2389 2375 2390 failIfFalse(base, "Cannot parse base expression"); 2376 2391 while (true) { … … 2403 2418 TreeArguments arguments = parseArguments(context, AllowSpread); 2404 2419 failIfFalse(arguments, "Cannot parse call arguments"); 2420 if (baseIsSuper) 2421 currentScope()->setHasDirectSuper(); 2405 2422 base = context.makeFunctionCallNode(startLocation, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition()); 2406 2423 } … … 2420 2437 goto endMemberExpression; 2421 2438 } 2439 baseIsSuper = false; 2422 2440 } 2423 2441 endMemberExpression: 2442 semanticFailIfTrue(baseIsSuper && !newCount, "Cannot reference super"); 2424 2443 while (newCount--) 2425 2444 base = context.createNewExpr(location, base, expressionStart, lastTokenEndPosition()); -
trunk/Source/JavaScriptCore/parser/Parser.h
r181183 r181293 114 114 , m_usesEval(false) 115 115 , m_needsFullActivation(false) 116 , m_hasDirectSuper(false) 116 117 , m_allowsNewDecls(true) 117 118 , m_strictMode(strictMode) … … 129 130 , m_usesEval(rhs.m_usesEval) 130 131 , m_needsFullActivation(rhs.m_needsFullActivation) 132 , m_hasDirectSuper(rhs.m_hasDirectSuper) 131 133 , m_allowsNewDecls(rhs.m_allowsNewDecls) 132 134 , m_strictMode(rhs.m_strictMode) … … 263 265 264 266 void setNeedsFullActivation() { m_needsFullActivation = true; } 267 268 #if ENABLE(ES6_CLASS_SYNTAX) 269 bool hasDirectSuper() { return m_hasDirectSuper; } 270 #else 271 bool hasDirectSuper() { return false; } 272 #endif 273 void setHasDirectSuper() { m_hasDirectSuper = true; } 265 274 266 275 bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables) … … 357 366 bool m_usesEval : 1; 358 367 bool m_needsFullActivation : 1; 368 bool m_hasDirectSuper : 1; 359 369 bool m_allowsNewDecls : 1; 360 370 bool m_strictMode : 1; … … 739 749 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict); 740 750 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName); 741 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset );742 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder& );751 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, SuperBinding = SuperBinding::NotNeeded); 752 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, ConstructorKind); 743 753 template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&); 744 754 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext }; … … 750 760 template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&); 751 761 752 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ParserFunctionInfo<TreeBuilder>&);762 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, ParserFunctionInfo<TreeBuilder>&); 753 763 #if ENABLE(ES6_CLASS_SYNTAX) 754 764 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionRequirements); -
trunk/Source/JavaScriptCore/parser/ParserModes.h
r174821 r181293 34 34 enum JSParserStrictness { JSParseNormal, JSParseBuiltin, JSParseStrict }; 35 35 enum JSParserMode { JSParseProgramCode, JSParseFunctionCode }; 36 37 enum class ConstructorKind { Base, Derived }; 38 enum class SuperBinding { Needed, NotNeeded }; 36 39 37 40 enum ProfilerMode { ProfilerOff, ProfilerOn }; -
trunk/Source/JavaScriptCore/parser/SyntaxChecker.h
r181179 r181293 74 74 ResolveEvalExpr, ResolveExpr, IntegerExpr, DoubleExpr, StringExpr, 75 75 ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr, 76 FunctionExpr, ClassExpr, BracketExpr, DotExpr, CallExpr,76 FunctionExpr, ClassExpr, SuperExpr, BracketExpr, DotExpr, CallExpr, 77 77 NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr, 78 78 ConditionalExpr, AssignmentExpr, TypeofExpr, … … 147 147 ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; } 148 148 ExpressionType thisExpr(const JSTokenLocation&) { return ThisExpr; } 149 ExpressionType superExpr(const JSTokenLocation&) { return SuperExpr; } 149 150 ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int) { return ResolveExpr; } 150 151 ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; } … … 169 170 #endif 170 171 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; } 172 173 void setFunctionNameStart(int, int) { } 173 174 int createArguments() { return ArgumentsResult; } … … 176 177 int createArgumentsList(const JSTokenLocation&, int) { return ArgumentsListResult; } 177 178 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) 179 180 { 180 181 if (!complete) … … 231 232 int createConstStatement(const JSTokenLocation&, int, int, int) { return StatementResult; } 232 233 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) 234 235 { 235 236 ASSERT(name); … … 238 239 return Property(name, type); 239 240 } 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) 241 242 { 242 243 if (!strict) -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r181084 r181293 262 262 macro(TypeError) \ 263 263 macro(undefined) \ 264 macro(BuiltinLog) 264 macro(BuiltinLog) \ 265 macro(homeObject) 265 266 266 267 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/Executable.h
r181208 r181293 468 468 void clearCode(); 469 469 470 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false ); }470 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, false); } 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 ); }525 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, false); } 526 526 527 527 private:
Note: See TracChangeset
for help on using the changeset viewer.