haikuwebkit/LayoutTests/js/class-syntax-prototype-expe...

52 lines
3.6 KiB
Plaintext
Raw Permalink Normal View History

class methods should be non-enumerable https://bugs.webkit.org/show_bug.cgi?id=143181 Reviewed by Darin Adler. Source/JavaScriptCore: Fixed the bug by using Object.defineProperty to define methods. This patch adds the concept of link time constants and uses it to resolve Object.defineProperty inside CodeBlock's constructor since bytecode can be linked against multiple global objects. * bytecode/CodeBlock.cpp: (JSC::CodeBlock::CodeBlock): Resolve link time constants that are used. Ignore ones with register index of zero. * bytecode/SpecialPointer.h: Added a new enum for link time constants. It currently contains exactly one entry for Object.defineProperty. * bytecode/UnlinkedCodeBlock.h: (JSC::UnlinkedCodeBlock::addConstant): Added. Like addConstant that takes JSValue, allocate a new constant register for the link time constant we're adding. (JSC::UnlinkedCodeBlock::registerIndexForLinkTimeConstant): Added. * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitMoveLinkTimeConstant): Added. Like addConstantValue, allocate a new register for the specified link time constant and notify UnlinkedCodeBlock about it. (JSC::BytecodeGenerator::emitCallDefineProperty): Added. Create a new property descriptor and call Object.defineProperty with it. * bytecompiler/BytecodeGenerator.h: * bytecompiler/NodesCodegen.cpp: (JSC::PropertyListNode::emitBytecode): Make static and non-static getters and setters for classes non-enumerable by using emitCallDefineProperty to define them. (JSC::PropertyListNode::emitPutConstantProperty): Ditto for a non-accessor properties. (JSC::ClassExprNode::emitBytecode): Make prototype.constructor non-enumerable and make prototype property on the class non-writable, non-configurable, and non-enumerable by using defineProperty. * runtime/CommonIdentifiers.h: * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): Set m_definePropertyFunction. (JSC::JSGlobalObject::visitChildren): Visit m_definePropertyFunction. * runtime/JSGlobalObject.h: (JSC::JSGlobalObject::definePropertyFunction): Added. (JSC::JSGlobalObject::actualPointerFor): Added a variant that takes LinkTimeConstant. (JSC::JSGlobalObject::jsCellForLinkTimeConstant): Like actualPointerFor, takes LinkTimeConstant and returns a JSCell; e.g. Object.defineProperty. * runtime/ObjectConstructor.cpp: (JSC::ObjectConstructor::addDefineProperty): Added. Returns Object.defineProperty. * runtime/ObjectConstructor.h: LayoutTests: Added a regression test. Also fixed a test that previously relied on "prototype" property being writable since this is no longer the case. * js/class-syntax-extends-expected.txt: * js/class-syntax-prototype.html: Added. * js/script-tests/class-syntax-extends.js: * js/script-tests/class-syntax-prototype.js: Added. Canonical link: https://commits.webkit.org/162182@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183316 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-04-25 22:03:30 +00:00
Tests for the descriptors of the properties implicitly defined by ES6 class syntax
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS class A {}; descriptor(A, "prototype").writable is false
PASS class A {}; var x = A.prototype; A.prototype = 3; A.prototype is x
PASS class A {}; descriptor(A, "prototype").enumerable is false
PASS class A {}; A.foo = "foo"; enumeratedProperties(A).includes("foo") is true
PASS class A {}; enumeratedProperties(A).includes("prototype") is false
PASS class A {}; descriptor(A, "prototype").configurable is false
PASS class A {}; Object.defineProperty(A, "prototype", {value: "foo"}) threw exception TypeError: Attempting to change value of a readonly property..
PASS class A { static foo() {} }; descriptor(A, "foo").writable is true
PASS class A { static foo() {} }; A.foo = 3; A.foo is 3
PASS class A { static foo() {} }; descriptor(A, "foo").enumerable is false
PASS class A { static foo() {} }; enumeratedProperties(A).includes("foo") is false
PASS class A { static foo() {} }; descriptor(A, "foo").configurable is true
PASS class A { static foo() {} }; Object.defineProperty(A, "foo", {value: "bar"}); A.foo is "bar"
PASS class A { static get foo() {} }; descriptor(A, "foo").writable is undefined
PASS class A { static get foo() { return 5; } }; A.foo = 3; A.foo is 5
PASS class A { static get foo() {} }; descriptor(A, "foo").enumerable is false
PASS class A { static get foo() {} }; enumeratedProperties(A).includes("foo") is false
PASS class A { static get foo() {} }; enumeratedProperties(new A).includes("foo") is false
PASS class A { static get foo() {} }; descriptor(A, "foo").configurable is true
PASS class A { static get foo() {} }; Object.defineProperty(A, "foo", {value: "bar"}); A.foo is "bar"
PASS class A { foo() {} }; descriptor(A.prototype, "foo").writable is true
PASS class A { foo() {} }; A.prototype.foo = 3; A.prototype.foo is 3
PASS class A { foo() {} }; descriptor(A.prototype, "foo").enumerable is false
PASS class A { foo() {} }; enumeratedProperties(A.prototype).includes("foo") is false
PASS class A { foo() {} }; enumeratedProperties(new A).includes("foo") is false
PASS class A { foo() {} }; descriptor(A.prototype, "foo").configurable is true
PASS class A { foo() {} }; Object.defineProperty(A.prototype, "foo", {value: "bar"}); A.prototype.foo is "bar"
PASS class A { get foo() {} }; descriptor(A.prototype, "foo").writable is undefined
PASS class A { get foo() { return 5; } }; A.prototype.foo = 3; A.prototype.foo is 5
PASS class A { get foo() {} }; descriptor(A.prototype, "foo").enumerable is false
PASS class A { get foo() {} }; enumeratedProperties(A.prototype).includes("foo") is false
PASS class A { get foo() {} }; enumeratedProperties(new A).includes("foo") is false
PASS class A { get foo() {} }; descriptor(A.prototype, "foo").configurable is true
PASS class A { get foo() {} }; Object.defineProperty(A.prototype, "foo", {value: "bar"}); A.prototype.foo is "bar"
PASS class A { }; descriptor(A.prototype, "constructor").writable is true
PASS class A { }; A.prototype.constructor = 3; A.prototype.constructor is 3
PASS class A { }; x = {}; A.prototype.constructor = function () { return x; }; (new A) instanceof A is true
PASS class A { }; descriptor(A.prototype, "constructor").enumerable is false
PASS class A { }; enumeratedProperties(A.prototype).includes("constructor") is false
PASS class A { }; enumeratedProperties(new A).includes("constructor") is false
PASS class A { }; descriptor(A.prototype, "constructor").configurable is true
PASS class A { }; Object.defineProperty(A.prototype, "constructor", {value: "bar"}); A.prototype.constructor is "bar"
PASS successfullyParsed is true
TEST COMPLETE