haikuwebkit/LayoutTests/js/class-syntax-extends-expect...

72 lines
6.2 KiB
Plaintext
Raw Permalink Normal View History

Support extends and super keywords https://bugs.webkit.org/show_bug.cgi?id=142200 Reviewed by Filip Pizlo. Source/JavaScriptCore: Added the support for ES6 class syntax inheritance. Added ConstructorKind as well as boolean flags indicating the constructor kind to various classes in UnlinkedCodeBlock as well as AST nodes. Each method stores the associated class as its homeObjectPrivateName. This value is used to make super calls. * bytecode/UnlinkedCodeBlock.cpp: (JSC::generateFunctionCodeBlock): (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): * bytecode/UnlinkedCodeBlock.h: (JSC::ExecutableInfo::ExecutableInfo): (JSC::UnlinkedFunctionExecutable::constructorKindIsDerived): Added. (JSC::UnlinkedCodeBlock::constructorKindIsDerived): Added. * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): Don't emit op_create_this in a derived class as the object is allocated by the highest base class's constructor. Also set "this" to null and store the original value in m_newTargetRegister. "this" is supposed to be in TDZ but that will be implemented in a separate patch. (JSC::BytecodeGenerator::emitReturn): Allow "undefined" to be returned from a derived class. In a derived class's constructor, not returning "undefined" or an object results in a type error instead of "this" being returned. (JSC::BytecodeGenerator::emitThrowTypeError): Added. * bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::constructorKindIsDerived): Added. (JSC::BytecodeGenerator::newTarget): Added. * bytecompiler/NodesCodegen.cpp: (JSC::SuperNode::emitBytecode): Added. Emits the code to obtain the callee's parent class. (JSC::emitSuperBaseForCallee): Added. Emits the code to obtain the parent class's prototype. (JSC::emitPutHomeObject): Added. (JSC::PropertyListNode::emitBytecode): Stores the home object when adding methods. (JSC::PropertyListNode::emitPutConstantProperty): Ditto. (JSC::BracketAccessorNode::emitBytecode): Added the support for super['foo']. (JSC::DotAccessorNode::emitBytecode): Added the support for super.foo. (JSC::FunctionCallValueNode::emitBytecode): Added the support for super(). (JSC::FunctionCallBracketNode::emitBytecode): Added the support for super['foo'](). (JSC::FunctionCallDotNode::emitBytecode): Added the support for super.foo(). (JSC::DeleteBracketNode::emitBytecode): Forbid "delete super.foo". (JSC::DeleteDotNode::emitBytecode): Forbid "delete super['foo']". (JSC::ClassExprNode::emitBytecode): Added the support for "classHeritage". This is the main logic for inheritance. When a class B inherits from a class A, set B.__proto__ to A and set B.prototype.__proto__ to A.prototype. Throw exceptions when either A or A.__proto__ is not an object. * parser/ASTBuilder.h: (JSC::ASTBuilder::superExpr): Added. * parser/NodeConstructors.h: (JSC::SuperNode::SuperNode): Added. * parser/Nodes.cpp: (JSC::FunctionBodyNode::FunctionBodyNode): * parser/Nodes.h: (JSC::ExpressionNode::isSuperNode): (JSC::PropertyNode::type): (JSC::PropertyNode::needsSuperBinding): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseFunctionBody): (JSC::Parser<LexerType>::parseFunctionInfo): Throw a parser error if super() is used outside of class constructors. (JSC::Parser<LexerType>::parseFunctionDeclaration): (JSC::Parser<LexerType>::parseClass): ConstructorKind is "derived" if and only if the parent class is specified in the declaration / expression. (JSC::Parser<LexerType>::parseGetterSetter): (JSC::Parser<LexerType>::parsePrimaryExpression): (JSC::Parser<LexerType>::parseMemberExpression): Added the support for "super()", "super.foo", and "super['foo']". Throw a semantic error if "super" appears by itself. * parser/Parser.h: (JSC::Scope::Scope): Added m_hasDirectSuper. This variable keeps track of the use of "super()" so that parseFunctionInfo can spit an error if it's used outside of class constructors. (JSC::Scope::hasDirectSuper): Added. (JSC::Scope::setHasDirectSuper): Added. * parser/ParserModes.h: (JSC::ConstructorKind): Added. * parser/SyntaxChecker.h: (JSC::SyntaxChecker::superExpr): Added. * runtime/CommonIdentifiers.h: Added homeObjectPrivateName. * runtime/Executable.h: (JSC::EvalExecutable::executableInfo): (JSC::ProgramExecutable::executableInfo): LayoutTests: Added tests for "extends" and "super" keywords. * TestExpectations: * js/class-syntax-extends-expected.txt: Added. * js/class-syntax-extends.html: Added. * js/class-syntax-super-expected.txt: Added. * js/class-syntax-super.html: Added. * js/script-tests/class-syntax-extends.js: Added. * js/script-tests/class-syntax-super.js: Added. Canonical link: https://commits.webkit.org/160546@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@181293 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-09 23:47:06 +00:00
Tests for ES6 class syntax "extends"
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS (new Base) instanceof Base
PASS Object.getPrototypeOf(new Base):::Base.prototype
PASS (new Derived) instanceof Derived
PASS Object.getPrototypeOf(new Derived):::Derived.prototype
PASS Object.getPrototypeOf(Derived.prototype):::Base.prototype
PASS (new Derived).baseMethod():::"base"
PASS (new Derived).overridenMethod():::"derived"
PASS Derived.staticBaseMethod():::"base"
PASS Derived.staticOverridenMethod():::"derived"
PASS x = class extends:::SyntaxError: Unexpected end of script
PASS x = class extends:::SyntaxError: Unexpected end of script
PASS x = class extends Base {:::SyntaxError: Unexpected end of script
PASS x = class extends Base { }
PASS x = class extends Base { constructor() { } }
PASS x.__proto__:::Base
PASS Object.getPrototypeOf(x):::Base
PASS x.prototype.__proto__:::Base.prototype
PASS Object.getPrototypeOf(x.prototype):::Base.prototype
PASS x = class extends null { constructor() { } }; x.__proto__:::Function.prototype
PASS x.__proto__:::Function.prototype
Implement @isConstructor bytecode intrinsic and bytecode for that https://bugs.webkit.org/show_bug.cgi?id=144093 Reviewed by Keith Miller. JSTests: * microbenchmarks/is-constructor.js: Added. * stress/async-arrow-function-in-class-heritage.js: * stress/is-constructor.js: * test262/expectations.yaml: Mark 2 test cases as passing. LayoutTests/imported/w3c: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * web-platform-tests/custom-elements/Document-createElement-expected.txt: * web-platform-tests/custom-elements/Document-createElementNS-expected.txt: * web-platform-tests/custom-elements/HTMLElement-constructor-expected.txt: * web-platform-tests/custom-elements/builtin-coverage-expected.txt: * web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt: * web-platform-tests/custom-elements/parser/serializing-html-fragments-expected.txt: * web-platform-tests/custom-elements/upgrading/Document-importNode-expected.txt: * web-platform-tests/custom-elements/upgrading/Node-cloneNode-expected.txt: * web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt: Source/JavaScriptCore: This change replaces @isConstructor link-time-constant with bytecode intrinsic and utilizes it in ClassExprNode::emitBytecode() according to the spec [1], aligning JSC with V8 and SpiderMonkey. Before this patch, we checked if "prototype" of superclass is an object, which is incorrect for generators and bound non-constructor functions with own "prototype". OpIsConstructor's fast path can't be easily compiled, and it's not a hot code anyway, so instead we reduce code bloat by just calling slow ops from DFG and FTL (if we bail out, we slow down all @isConstructor call sites). This advances microbenchmarks/is-constructor.js by ~35%. [1]: https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation (step 5.f) * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * builtins/BuiltinNames.h: * bytecode/BytecodeIntrinsicRegistry.h: * bytecode/BytecodeList.rb: * bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitIsConstructor): * bytecompiler/BytecodeGenerator.h: * bytecompiler/NodesCodegen.cpp: (JSC::ClassExprNode::emitBytecode): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGHeapLocation.cpp: (WTF::printInternal): * dfg/DFGHeapLocation.h: * dfg/DFGNodeType.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileIsConstructor): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileIsConstructor): * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * llint/LowLevelInterpreter.asm: * runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL): * runtime/CommonSlowPaths.h: * runtime/ECMAScriptSpecInternalFunctions.cpp: Removed. * runtime/ECMAScriptSpecInternalFunctions.h: Removed. * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): LayoutTests: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * js/class-syntax-extends-expected.txt: * js/script-tests/class-syntax-extends.js: * platform/gtk/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/ios-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/mac-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: Canonical link: https://commits.webkit.org/224709@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-13 06:41:34 +00:00
PASS x = class extends 3 { constructor() { } }; x.__proto__:::TypeError: The superclass is not a constructor.
PASS x = class extends "abc" { constructor() { } }; x.__proto__:::TypeError: The superclass is not a constructor.
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS baseWithBadPrototype = function () {}; baseWithBadPrototype.prototype = 3; new baseWithBadPrototype
Remove OpIsObjectOrNull from ClassExprNode::emitBytecode() https://bugs.webkit.org/show_bug.cgi?id=214525 Reviewed by Keith Miller. Source/JavaScriptCore: This patch: 1. Replaces OpIsObjectOrNull in ClassExprNode::emitBytecode() [1] with emitIsObject() + emitIsNull(), preventing DFG/FTL from throwing a TypeError if `document.all` is the value of superclass "prototype" property, which aligns JSC with V8 and SpiderMonkey. Also, tweaks error message to reflect that `null` is allowed. 2. Renames is_object_or_null bytecode op to typeof_is_object, fixing the confusing operationObjectIsObject() name, and aligns it with typeof_is_undefined. New name offers better semantics and clearly communicates the op should be avoided when implementing new features because of `typeof` behavior with [[IsHTMLDDA]] objects [2]. [1]: https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation (step 5.g.ii) [2]: https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-typeof * bytecode/BytecodeList.rb: * bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitEqualityOpImpl): * bytecompiler/NodesCodegen.cpp: (JSC::ClassExprNode::emitBytecode): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGHeapLocation.cpp: (WTF::printInternal): * dfg/DFGHeapLocation.h: * dfg/DFGNodeType.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileTypeOfIsObject): (JSC::DFG::SpeculativeJIT::compileIsObjectOrNull): Deleted. * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileTypeOfIsObject): (JSC::FTL::DFG::LowerDFGToB3::compileIsObjectOrNull): Deleted. * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * llint/LowLevelInterpreter.asm: * runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL): * runtime/CommonSlowPaths.h: * runtime/Operations.cpp: (JSC::jsTypeofIsObject): (JSC::jsIsObjectTypeOrNull): Deleted. * runtime/Operations.h: LayoutTests: New tests are added for `document.all` rather than `makeMasquerader()` since the latter has sufficient test coverage and takes the short path as JSFunction. * js/class-syntax-extends-expected.txt: * js/dom/document-all-class-extends-expected.txt: Added. * js/dom/document-all-class-extends.html: Added. * js/dom/document-all-typeof-is-object-fold-expected.txt: Added. * js/dom/document-all-typeof-is-object-fold.html: Added. * js/dom/script-tests/document-all-class-extends.js: Added. * js/dom/script-tests/document-all-typeof-is-object-fold.js: Added. * js/script-tests/class-syntax-extends.js: Canonical link: https://commits.webkit.org/228315@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265744 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-16 20:40:17 +00:00
PASS x = class extends baseWithBadPrototype { constructor() { } }:::TypeError: The value of the superclass's prototype property is not an object or null.
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS baseWithBadPrototype.prototype = "abc"
Remove OpIsObjectOrNull from ClassExprNode::emitBytecode() https://bugs.webkit.org/show_bug.cgi?id=214525 Reviewed by Keith Miller. Source/JavaScriptCore: This patch: 1. Replaces OpIsObjectOrNull in ClassExprNode::emitBytecode() [1] with emitIsObject() + emitIsNull(), preventing DFG/FTL from throwing a TypeError if `document.all` is the value of superclass "prototype" property, which aligns JSC with V8 and SpiderMonkey. Also, tweaks error message to reflect that `null` is allowed. 2. Renames is_object_or_null bytecode op to typeof_is_object, fixing the confusing operationObjectIsObject() name, and aligns it with typeof_is_undefined. New name offers better semantics and clearly communicates the op should be avoided when implementing new features because of `typeof` behavior with [[IsHTMLDDA]] objects [2]. [1]: https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation (step 5.g.ii) [2]: https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-typeof * bytecode/BytecodeList.rb: * bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitEqualityOpImpl): * bytecompiler/NodesCodegen.cpp: (JSC::ClassExprNode::emitBytecode): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGHeapLocation.cpp: (WTF::printInternal): * dfg/DFGHeapLocation.h: * dfg/DFGNodeType.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileTypeOfIsObject): (JSC::DFG::SpeculativeJIT::compileIsObjectOrNull): Deleted. * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileTypeOfIsObject): (JSC::FTL::DFG::LowerDFGToB3::compileIsObjectOrNull): Deleted. * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * llint/LowLevelInterpreter.asm: * runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL): * runtime/CommonSlowPaths.h: * runtime/Operations.cpp: (JSC::jsTypeofIsObject): (JSC::jsIsObjectTypeOrNull): Deleted. * runtime/Operations.h: LayoutTests: New tests are added for `document.all` rather than `makeMasquerader()` since the latter has sufficient test coverage and takes the short path as JSFunction. * js/class-syntax-extends-expected.txt: * js/dom/document-all-class-extends-expected.txt: Added. * js/dom/document-all-class-extends.html: Added. * js/dom/document-all-typeof-is-object-fold-expected.txt: Added. * js/dom/document-all-typeof-is-object-fold.html: Added. * js/dom/script-tests/document-all-class-extends.js: Added. * js/dom/script-tests/document-all-typeof-is-object-fold.js: Added. * js/script-tests/class-syntax-extends.js: Canonical link: https://commits.webkit.org/228315@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265744 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-08-16 20:40:17 +00:00
PASS x = class extends baseWithBadPrototype { constructor() { } }:::TypeError: The value of the superclass's prototype property is not an object or null.
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS baseWithBadPrototype.prototype = null; x = class extends baseWithBadPrototype { constructor() { } }
PASS x = 1; c = class extends ++x { constructor() { } };:::SyntaxError: Unexpected token '++'
PASS x = 1; c = class extends x++ { constructor() { } };:::SyntaxError: Unexpected token '++'. Expected opening '{' at the start of a class body.
Implement @isConstructor bytecode intrinsic and bytecode for that https://bugs.webkit.org/show_bug.cgi?id=144093 Reviewed by Keith Miller. JSTests: * microbenchmarks/is-constructor.js: Added. * stress/async-arrow-function-in-class-heritage.js: * stress/is-constructor.js: * test262/expectations.yaml: Mark 2 test cases as passing. LayoutTests/imported/w3c: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * web-platform-tests/custom-elements/Document-createElement-expected.txt: * web-platform-tests/custom-elements/Document-createElementNS-expected.txt: * web-platform-tests/custom-elements/HTMLElement-constructor-expected.txt: * web-platform-tests/custom-elements/builtin-coverage-expected.txt: * web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt: * web-platform-tests/custom-elements/parser/serializing-html-fragments-expected.txt: * web-platform-tests/custom-elements/upgrading/Document-importNode-expected.txt: * web-platform-tests/custom-elements/upgrading/Node-cloneNode-expected.txt: * web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt: Source/JavaScriptCore: This change replaces @isConstructor link-time-constant with bytecode intrinsic and utilizes it in ClassExprNode::emitBytecode() according to the spec [1], aligning JSC with V8 and SpiderMonkey. Before this patch, we checked if "prototype" of superclass is an object, which is incorrect for generators and bound non-constructor functions with own "prototype". OpIsConstructor's fast path can't be easily compiled, and it's not a hot code anyway, so instead we reduce code bloat by just calling slow ops from DFG and FTL (if we bail out, we slow down all @isConstructor call sites). This advances microbenchmarks/is-constructor.js by ~35%. [1]: https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation (step 5.f) * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * builtins/BuiltinNames.h: * bytecode/BytecodeIntrinsicRegistry.h: * bytecode/BytecodeList.rb: * bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitIsConstructor): * bytecompiler/BytecodeGenerator.h: * bytecompiler/NodesCodegen.cpp: (JSC::ClassExprNode::emitBytecode): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGHeapLocation.cpp: (WTF::printInternal): * dfg/DFGHeapLocation.h: * dfg/DFGNodeType.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileIsConstructor): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileIsConstructor): * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * llint/LowLevelInterpreter.asm: * runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL): * runtime/CommonSlowPaths.h: * runtime/ECMAScriptSpecInternalFunctions.cpp: Removed. * runtime/ECMAScriptSpecInternalFunctions.h: Removed. * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): LayoutTests: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * js/class-syntax-extends-expected.txt: * js/script-tests/class-syntax-extends.js: * platform/gtk/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/ios-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/mac-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: Canonical link: https://commits.webkit.org/224709@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-13 06:41:34 +00:00
PASS x = 1; c = class extends (++x) { constructor() { } };:::TypeError: The superclass is not a constructor.
PASS x = 1; c = class extends (x++) { constructor() { } };:::TypeError: The superclass is not a constructor.
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS x = 1; try { c = class extends (++x) { constructor() { } } } catch (e) { }; x:::2
PASS x = 1; try { c = class extends (x++) { constructor() { } } } catch (e) { }; x:::2
PASS namespace = {}; namespace.A = class { }; namespace.B = class extends namespace.A { }
PASS namespace = {}; namespace.A = class A { }; namespace.B = class B extends namespace.A { }
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace.A { constructor() { } }
PASS namespace = {}; namespace.A = class A { constructor() { } }; namespace.B = class B extends namespace.A { constructor() { } }
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A) { constructor() { } }
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace["A"] { constructor() { } }
PASS namespace = {}; namespace.A = class { constructor() { } }; function getClassA() { return namespace.A }; namespace.B = class extends getClassA() { constructor() { } }
PASS namespace = {}; namespace.A = class { constructor() { } }; function getClass(prop) { return namespace[prop] }; namespace.B = class extends getClass("A") { constructor() { } }
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (false||null||namespace.A) { constructor() { } }
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends false||null||namespace.A { constructor() { } }:::SyntaxError: Unexpected token '||'. Expected opening '{' at the start of a class body.
PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (x++, namespace.A) { constructor() { } };
Implement @isConstructor bytecode intrinsic and bytecode for that https://bugs.webkit.org/show_bug.cgi?id=144093 Reviewed by Keith Miller. JSTests: * microbenchmarks/is-constructor.js: Added. * stress/async-arrow-function-in-class-heritage.js: * stress/is-constructor.js: * test262/expectations.yaml: Mark 2 test cases as passing. LayoutTests/imported/w3c: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * web-platform-tests/custom-elements/Document-createElement-expected.txt: * web-platform-tests/custom-elements/Document-createElementNS-expected.txt: * web-platform-tests/custom-elements/HTMLElement-constructor-expected.txt: * web-platform-tests/custom-elements/builtin-coverage-expected.txt: * web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt: * web-platform-tests/custom-elements/parser/serializing-html-fragments-expected.txt: * web-platform-tests/custom-elements/upgrading/Document-importNode-expected.txt: * web-platform-tests/custom-elements/upgrading/Node-cloneNode-expected.txt: * web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt: Source/JavaScriptCore: This change replaces @isConstructor link-time-constant with bytecode intrinsic and utilizes it in ClassExprNode::emitBytecode() according to the spec [1], aligning JSC with V8 and SpiderMonkey. Before this patch, we checked if "prototype" of superclass is an object, which is incorrect for generators and bound non-constructor functions with own "prototype". OpIsConstructor's fast path can't be easily compiled, and it's not a hot code anyway, so instead we reduce code bloat by just calling slow ops from DFG and FTL (if we bail out, we slow down all @isConstructor call sites). This advances microbenchmarks/is-constructor.js by ~35%. [1]: https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation (step 5.f) * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * builtins/BuiltinNames.h: * bytecode/BytecodeIntrinsicRegistry.h: * bytecode/BytecodeList.rb: * bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitIsConstructor): * bytecompiler/BytecodeGenerator.h: * bytecompiler/NodesCodegen.cpp: (JSC::ClassExprNode::emitBytecode): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGHeapLocation.cpp: (WTF::printInternal): * dfg/DFGHeapLocation.h: * dfg/DFGNodeType.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileIsConstructor): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileIsConstructor): * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * llint/LowLevelInterpreter.asm: * runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL): * runtime/CommonSlowPaths.h: * runtime/ECMAScriptSpecInternalFunctions.cpp: Removed. * runtime/ECMAScriptSpecInternalFunctions.h: Removed. * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): LayoutTests: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * js/class-syntax-extends-expected.txt: * js/script-tests/class-syntax-extends.js: * platform/gtk/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/ios-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/mac-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: Canonical link: https://commits.webkit.org/224709@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-13 06:41:34 +00:00
PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A, x++) { constructor() { } };:::TypeError: The superclass is not a constructor.
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A { constructor() { } }:::TypeError: The superclass is not a constructor.
PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A() { constructor() { } }:::TypeError: The superclass is not a constructor.
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (x++, namespace.A) { constructor() { } } } catch (e) { } x:::2
PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (namespace.A, x++) { constructor() { } } } catch (e) { } x:::2
PASS Object.getPrototypeOf((class { constructor () { } }).prototype):::Object.prototype
PASS Object.getPrototypeOf((class extends null { constructor () { super(); } }).prototype):::null
Implement @isConstructor bytecode intrinsic and bytecode for that https://bugs.webkit.org/show_bug.cgi?id=144093 Reviewed by Keith Miller. JSTests: * microbenchmarks/is-constructor.js: Added. * stress/async-arrow-function-in-class-heritage.js: * stress/is-constructor.js: * test262/expectations.yaml: Mark 2 test cases as passing. LayoutTests/imported/w3c: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * web-platform-tests/custom-elements/Document-createElement-expected.txt: * web-platform-tests/custom-elements/Document-createElementNS-expected.txt: * web-platform-tests/custom-elements/HTMLElement-constructor-expected.txt: * web-platform-tests/custom-elements/builtin-coverage-expected.txt: * web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt: * web-platform-tests/custom-elements/parser/serializing-html-fragments-expected.txt: * web-platform-tests/custom-elements/upgrading/Document-importNode-expected.txt: * web-platform-tests/custom-elements/upgrading/Node-cloneNode-expected.txt: * web-platform-tests/shadow-dom/Element-interface-attachShadow-custom-element-expected.txt: Source/JavaScriptCore: This change replaces @isConstructor link-time-constant with bytecode intrinsic and utilizes it in ClassExprNode::emitBytecode() according to the spec [1], aligning JSC with V8 and SpiderMonkey. Before this patch, we checked if "prototype" of superclass is an object, which is incorrect for generators and bound non-constructor functions with own "prototype". OpIsConstructor's fast path can't be easily compiled, and it's not a hot code anyway, so instead we reduce code bloat by just calling slow ops from DFG and FTL (if we bail out, we slow down all @isConstructor call sites). This advances microbenchmarks/is-constructor.js by ~35%. [1]: https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation (step 5.f) * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: * builtins/BuiltinNames.h: * bytecode/BytecodeIntrinsicRegistry.h: * bytecode/BytecodeList.rb: * bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitIsConstructor): * bytecompiler/BytecodeGenerator.h: * bytecompiler/NodesCodegen.cpp: (JSC::ClassExprNode::emitBytecode): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * dfg/DFGHeapLocation.cpp: (WTF::printInternal): * dfg/DFGHeapLocation.h: * dfg/DFGNodeType.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileIsConstructor): * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileIsConstructor): * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * llint/LowLevelInterpreter.asm: * runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL): * runtime/CommonSlowPaths.h: * runtime/ECMAScriptSpecInternalFunctions.cpp: Removed. * runtime/ECMAScriptSpecInternalFunctions.h: Removed. * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): LayoutTests: Tests for unsupported customized built-in elements now fail early since interfaces they extend lack Constructor WebIDL attribute. * js/class-syntax-extends-expected.txt: * js/script-tests/class-syntax-extends.js: * platform/gtk/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/ios-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: * platform/mac-wk2/imported/w3c/web-platform-tests/custom-elements/builtin-coverage-expected.txt: Canonical link: https://commits.webkit.org/224709@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-13 06:41:34 +00:00
PASS new (class extends undefined { constructor () { this } }):::TypeError: The superclass is not a constructor.
PASS x = undefined; new (class extends x { constructor () { super(); } }):::TypeError: The superclass is not a constructor.
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x
Improve error message for uninitialized |this| in derived constructor https://bugs.webkit.org/show_bug.cgi?id=220221 Reviewed by Yusuke Suzuki. JSTests: * stress/async-arrow-functions-lexical-binding-in-class.js: * stress/async-arrow-functions-lexical-super-binding.js: * stress/class-derived-from-null.js: * stress/generator-eval-this.js: * stress/super-property-access-tdz.js: LayoutTests/imported/w3c: * web-platform-tests/custom-elements/parser/parser-fallsback-to-unknown-element-expected.txt: Source/JavaScriptCore: Since class constructors perform `return this;` by default, and derived constructors require `super()` to be called before |this| access, regular TDZ error message is quite confusing, given the following code: `new (class extends Object { constructor() { } });` Considering that currently op_check_tdz is called on thisRegister() only in derived constructors, this patch modifies its slow path to throw a helpful error message that covers |this| access and non-object returns. V8 and SpiderMonkey have similar error messages, mentioning `super()`. slow_path_throw_tdz_error is merged into slow_path_check_tdz, which is invoked from baseline JIT, so we can reliably acquire the bytecode and avoid code duplication. * llint/LowLevelInterpreter32_64.asm: * llint/LowLevelInterpreter64.asm: * runtime/CommonSlowPaths.cpp: (JSC::JSC_DEFINE_COMMON_SLOW_PATH): * runtime/CommonSlowPaths.h: LayoutTests: * js/arrowfunction-supercall-expected.txt: * js/arrowfunction-superproperty-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/arrowfunction-supercall.js: * js/script-tests/arrowfunction-superproperty.js: * js/script-tests/class-syntax-super.js: Canonical link: https://commits.webkit.org/232717@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271120 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-02 19:27:42 +00:00
PASS new (class extends null { constructor () { this; } }):::ReferenceError: 'super()' must be called in derived constructor before accessing |this| or returning non-object.
PASS new (class extends null { constructor () { super(); } }):::TypeError: function is not a constructor (evaluating 'super()')
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS x = {}; new (class extends null { constructor () { return x } }):::x
PASS y = 12; class C extends null { constructor () { return y; } }; new C;:::TypeError: Cannot return a non-object type in the constructor of a derived class.
ES6 class syntax should use block scoping https://bugs.webkit.org/show_bug.cgi?id=142567 Reviewed by Geoffrey Garen. Source/JavaScriptCore: We treat class declarations like we do "let" declarations. The class name is under TDZ until the class declaration statement is evaluated. Class declarations also follow the same rules as "let": No duplicate definitions inside a lexical environment. * parser/ASTBuilder.h: (JSC::ASTBuilder::createClassDeclStatement): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseClassDeclaration): * tests/stress/class-syntax-block-scoping.js: Added. (assert): (truth): (.): * tests/stress/class-syntax-definition-semantics.js: Added. (shouldBeSyntaxError): (shouldNotBeSyntaxError): (truth): * tests/stress/class-syntax-tdz.js: (assert): (shouldThrowTDZ): (truth): (.): LayoutTests: * js/class-constructor-return-expected.txt: * js/class-syntax-call-expected.txt: * js/class-syntax-declaration-expected.txt: * js/class-syntax-default-constructor-expected.txt: * js/class-syntax-extends-expected.txt: * js/class-syntax-name-expected.txt: * js/class-syntax-super-expected.txt: * js/script-tests/class-constructor-return.js: (shouldThrow): (shouldNotThrow): (shouldBeTrue): (shouldBeFalse): * js/script-tests/class-syntax-call.js: (A): (B): (shouldThrow): (shouldNotThrow): * js/script-tests/class-syntax-declaration.js: (shouldThrow): (shouldNotThrow): (shouldBe): * js/script-tests/class-syntax-default-constructor.js: (shouldThrow): (shouldBe): (shouldBeTrue): (assert): (A): (B): * js/script-tests/class-syntax-extends.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (Base): (Base.prototype.baseMethod): * js/script-tests/class-syntax-name.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (runTestShouldBe): * js/script-tests/class-syntax-super.js: (shouldThrow): (shouldNotThrow): (shouldBe): (shouldBeTrue): (shouldBeFalse): Canonical link: https://commits.webkit.org/165577@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-07-31 21:05:19 +00:00
PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x
PASS x = null; Object.getPrototypeOf((class extends x { }).prototype):::null
PASS Object.prototype.isPrototypeOf(class { })
PASS Function.prototype.isPrototypeOf(class { })
PASS successfullyParsed
Support extends and super keywords https://bugs.webkit.org/show_bug.cgi?id=142200 Reviewed by Filip Pizlo. Source/JavaScriptCore: Added the support for ES6 class syntax inheritance. Added ConstructorKind as well as boolean flags indicating the constructor kind to various classes in UnlinkedCodeBlock as well as AST nodes. Each method stores the associated class as its homeObjectPrivateName. This value is used to make super calls. * bytecode/UnlinkedCodeBlock.cpp: (JSC::generateFunctionCodeBlock): (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): * bytecode/UnlinkedCodeBlock.h: (JSC::ExecutableInfo::ExecutableInfo): (JSC::UnlinkedFunctionExecutable::constructorKindIsDerived): Added. (JSC::UnlinkedCodeBlock::constructorKindIsDerived): Added. * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): Don't emit op_create_this in a derived class as the object is allocated by the highest base class's constructor. Also set "this" to null and store the original value in m_newTargetRegister. "this" is supposed to be in TDZ but that will be implemented in a separate patch. (JSC::BytecodeGenerator::emitReturn): Allow "undefined" to be returned from a derived class. In a derived class's constructor, not returning "undefined" or an object results in a type error instead of "this" being returned. (JSC::BytecodeGenerator::emitThrowTypeError): Added. * bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::constructorKindIsDerived): Added. (JSC::BytecodeGenerator::newTarget): Added. * bytecompiler/NodesCodegen.cpp: (JSC::SuperNode::emitBytecode): Added. Emits the code to obtain the callee's parent class. (JSC::emitSuperBaseForCallee): Added. Emits the code to obtain the parent class's prototype. (JSC::emitPutHomeObject): Added. (JSC::PropertyListNode::emitBytecode): Stores the home object when adding methods. (JSC::PropertyListNode::emitPutConstantProperty): Ditto. (JSC::BracketAccessorNode::emitBytecode): Added the support for super['foo']. (JSC::DotAccessorNode::emitBytecode): Added the support for super.foo. (JSC::FunctionCallValueNode::emitBytecode): Added the support for super(). (JSC::FunctionCallBracketNode::emitBytecode): Added the support for super['foo'](). (JSC::FunctionCallDotNode::emitBytecode): Added the support for super.foo(). (JSC::DeleteBracketNode::emitBytecode): Forbid "delete super.foo". (JSC::DeleteDotNode::emitBytecode): Forbid "delete super['foo']". (JSC::ClassExprNode::emitBytecode): Added the support for "classHeritage". This is the main logic for inheritance. When a class B inherits from a class A, set B.__proto__ to A and set B.prototype.__proto__ to A.prototype. Throw exceptions when either A or A.__proto__ is not an object. * parser/ASTBuilder.h: (JSC::ASTBuilder::superExpr): Added. * parser/NodeConstructors.h: (JSC::SuperNode::SuperNode): Added. * parser/Nodes.cpp: (JSC::FunctionBodyNode::FunctionBodyNode): * parser/Nodes.h: (JSC::ExpressionNode::isSuperNode): (JSC::PropertyNode::type): (JSC::PropertyNode::needsSuperBinding): * parser/Parser.cpp: (JSC::Parser<LexerType>::parseFunctionBody): (JSC::Parser<LexerType>::parseFunctionInfo): Throw a parser error if super() is used outside of class constructors. (JSC::Parser<LexerType>::parseFunctionDeclaration): (JSC::Parser<LexerType>::parseClass): ConstructorKind is "derived" if and only if the parent class is specified in the declaration / expression. (JSC::Parser<LexerType>::parseGetterSetter): (JSC::Parser<LexerType>::parsePrimaryExpression): (JSC::Parser<LexerType>::parseMemberExpression): Added the support for "super()", "super.foo", and "super['foo']". Throw a semantic error if "super" appears by itself. * parser/Parser.h: (JSC::Scope::Scope): Added m_hasDirectSuper. This variable keeps track of the use of "super()" so that parseFunctionInfo can spit an error if it's used outside of class constructors. (JSC::Scope::hasDirectSuper): Added. (JSC::Scope::setHasDirectSuper): Added. * parser/ParserModes.h: (JSC::ConstructorKind): Added. * parser/SyntaxChecker.h: (JSC::SyntaxChecker::superExpr): Added. * runtime/CommonIdentifiers.h: Added homeObjectPrivateName. * runtime/Executable.h: (JSC::EvalExecutable::executableInfo): (JSC::ProgramExecutable::executableInfo): LayoutTests: Added tests for "extends" and "super" keywords. * TestExpectations: * js/class-syntax-extends-expected.txt: Added. * js/class-syntax-extends.html: Added. * js/class-syntax-super-expected.txt: Added. * js/class-syntax-super.html: Added. * js/script-tests/class-syntax-extends.js: Added. * js/script-tests/class-syntax-super.js: Added. Canonical link: https://commits.webkit.org/160546@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@181293 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-09 23:47:06 +00:00
TEST COMPLETE