Diff
Modified: trunk/LayoutTests/ChangeLog (196039 => 196040)
--- trunk/LayoutTests/ChangeLog 2016-02-03 02:27:26 UTC (rev 196039)
+++ trunk/LayoutTests/ChangeLog 2016-02-03 03:17:53 UTC (rev 196040)
@@ -1,3 +1,13 @@
+2016-02-02 Caitlin Potter <[email protected]>
+
+ [JSC] Implement Object.getOwnPropertyDescriptors() proposal
+ https://bugs.webkit.org/show_bug.cgi?id=153799
+
+ Reviewed by Darin Adler.
+
+ * js/Object-getOwnPropertyNames-expected.txt:
+ * js/script-tests/Object-getOwnPropertyNames.js:
+
2016-02-02 Brady Eidson <[email protected]>
Modern IDB: storage/indexeddb/cursor-primary-key-order.html fails with SQLite backend.
Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (196039 => 196040)
--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2016-02-03 02:27:26 UTC (rev 196039)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2016-02-03 03:17:53 UTC (rev 196040)
@@ -41,7 +41,7 @@
PASS getSortedOwnPropertyNames(decodeURIComponent) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURI) is ['length', 'name']
PASS getSortedOwnPropertyNames(encodeURIComponent) is ['length', 'name']
-PASS getSortedOwnPropertyNames(Object) is ['assign', 'create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf']
+PASS getSortedOwnPropertyNames(Object) is ['assign', 'create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyDescriptors', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf']
PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
PASS getSortedOwnPropertyNames(Function) is ['length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']
Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (196039 => 196040)
--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2016-02-03 02:27:26 UTC (rev 196039)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2016-02-03 03:17:53 UTC (rev 196040)
@@ -50,7 +50,7 @@
"encodeURI": "['length', 'name']",
"encodeURIComponent": "['length', 'name']",
// Built-in ECMA objects
- "Object": "['assign', 'create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf']",
+ "Object": "['assign', 'create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyDescriptors', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf']",
"Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
"Function": "['length', 'name', 'prototype']",
"Function.prototype": "['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']",
Modified: trunk/Source/_javascript_Core/ChangeLog (196039 => 196040)
--- trunk/Source/_javascript_Core/ChangeLog 2016-02-03 02:27:26 UTC (rev 196039)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-02-03 03:17:53 UTC (rev 196040)
@@ -1,3 +1,20 @@
+2016-02-02 Caitlin Potter <[email protected]>
+
+ [JSC] Implement Object.getOwnPropertyDescriptors() proposal
+ https://bugs.webkit.org/show_bug.cgi?id=153799
+
+ Reviewed by Darin Adler.
+
+ Implements the Object.getOwnPropertyDescriptors() proposal, which
+ reached Stage 3 in the TC39 process in January 2016.
+ https://github.com/tc39/proposal-object-getownpropertydescriptors
+
+ The method extracts a set of property descriptor objects, which can
+ be safely used via `Object.create()`.
+
+ * runtime/ObjectConstructor.cpp:
+ (JSC::objectConstructorGetOwnPropertyDescriptors):
+
2016-02-02 Filip Pizlo <[email protected]>
B3 should be able to compile trivial self-loops
Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (196039 => 196040)
--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2016-02-03 02:27:26 UTC (rev 196039)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2016-02-03 03:17:53 UTC (rev 196040)
@@ -68,6 +68,7 @@
getPrototypeOf objectConstructorGetPrototypeOf DontEnum|Function 1
setPrototypeOf objectConstructorSetPrototypeOf DontEnum|Function 2
getOwnPropertyDescriptor objectConstructorGetOwnPropertyDescriptor DontEnum|Function 2
+ getOwnPropertyDescriptors objectConstructorGetOwnPropertyDescriptors DontEnum|Function 1
getOwnPropertyNames objectConstructorGetOwnPropertyNames DontEnum|Function 1
keys objectConstructorKeys DontEnum|Function 1
defineProperty objectConstructorDefineProperty DontEnum|Function 3
@@ -247,6 +248,26 @@
return description;
}
+JSValue objectConstructorGetOwnPropertyDescriptors(ExecState* exec, JSObject* object)
+{
+ PropertyNameArray properties(exec, PropertyNameMode::StringsAndSymbols);
+ object->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include));
+ if (exec->hadException())
+ return jsUndefined();
+
+ JSObject* descriptors = constructEmptyObject(exec);
+
+ for (auto& propertyName : properties) {
+ JSValue fromDescriptor = objectConstructorGetOwnPropertyDescriptor(exec, object, propertyName);
+ if (exec->hadException())
+ return jsUndefined();
+
+ descriptors->putDirect(exec->vm(), propertyName, fromDescriptor, 0);
+ }
+
+ return descriptors;
+}
+
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec)
{
JSObject* object = exec->argument(0).toObject(exec);
@@ -258,6 +279,14 @@
return JSValue::encode(objectConstructorGetOwnPropertyDescriptor(exec, object, propertyName));
}
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptors(ExecState* exec)
+{
+ JSObject* object = exec->argument(0).toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ return JSValue::encode(objectConstructorGetOwnPropertyDescriptors(exec, object));
+}
+
// FIXME: Use the enumeration cache.
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec)
{
Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.h (196039 => 196040)
--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.h 2016-02-03 02:27:26 UTC (rev 196039)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.h 2016-02-03 03:17:53 UTC (rev 196040)
@@ -28,6 +28,7 @@
namespace JSC {
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*);
+EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptors(ExecState*);
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertySymbols(ExecState*);
EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState*);
EncodedJSValue JSC_HOST_CALL ownEnumerablePropertyKeys(ExecState*);
@@ -93,6 +94,7 @@
JSObject* objectConstructorFreeze(ExecState*, JSObject*);
JSValue objectConstructorGetPrototypeOf(ExecState*, JSObject*);
JSValue objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, const Identifier&);
+JSValue objectConstructorGetOwnPropertyDescriptors(ExecState*, JSObject*);
JSArray* ownPropertyKeys(ExecState*, JSObject*, PropertyNameMode, DontEnumPropertiesMode);
bool toPropertyDescriptor(ExecState*, JSValue, PropertyDescriptor&);
Added: trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js (0 => 196040)
--- trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js 2016-02-03 03:17:53 UTC (rev 196040)
@@ -0,0 +1,97 @@
+function shouldBe(expected, actual, msg) {
+ if (msg === void 0)
+ msg = '';
+ else
+ msg = ' for ' + msg;
+ if (actual !== expected)
+ throw new Error('bad value' + msg + ': ' + actual + '. Expected ' + expected);
+}
+
+function shouldThrow(func, errorType) {
+ try {
+ func();
+ throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but did not throw.');
+ } catch (e) {
+ if (e instanceof errorType) return;
+ throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but threw ' + e);
+ }
+}
+
+function shouldBeDataProperty(expected, value, name) {
+ if (name === void 0)
+ name = '<property descriptor>';
+ shouldBe(value, expected.value, name + '.value');
+ shouldBe(true, expected.enumerable, name + '.enumerable');
+ shouldBe(true, expected.configurable, name + '.configurable');
+ shouldBe(true, expected.writable, name + '.writable');
+ shouldBe(undefined, expected.get, name + '.get');
+ shouldBe(undefined, expected.set, name + '.set');
+}
+
+(function testPropertyFilteringAndOrder() {
+ var log = [];
+ var sym = Symbol('test');
+ var O = {
+ 0: 0,
+ [sym]: 3,
+ 'a': 2,
+ 1: 1
+ };
+
+ var P = new Proxy(O, {
+ ownKeys(target) {
+ log.push('ownKeys()');
+ return Reflect.ownKeys(target);
+ },
+ getOwnPropertyDescriptor(target, name) {
+ log.push(`getOwnPropertyDescriptor(${String(name)})`);
+ return Reflect.getOwnPropertyDescriptor(target, name);
+ },
+ get() { throw new Error('[[Get]] trap should be unreachable'); },
+ set() { throw new Error('[[Set]] trap should be unreachable'); },
+ deleteProperty() { throw new Error('[[Delete]] trap should be unreachable'); },
+ defineProperty() { throw new Error('[[DefineOwnProperty]] trap should be unreachable'); }
+ });
+
+ var result = Object.getOwnPropertyDescriptors(P);
+ shouldBe('ownKeys()|getOwnPropertyDescriptor(0)|getOwnPropertyDescriptor(1)|getOwnPropertyDescriptor(a)|getOwnPropertyDescriptor(Symbol(foo))', log.join('|'));
+ shouldBeDataProperty(result[0], 0, 'result[0]');
+ shouldBeDataProperty(result[1], 1, 'result[1]');
+ shouldBeDataProperty(result.a, 1, 'result["a"]');
+ shouldBeDataProperty(result[sym], 1, 'result[Symbol(foo)]');
+
+ var result2 = Object.getOwnPropertyDescriptors(O);
+ shouldBeDataProperty(result2[0], 0, 'result2[0]');
+ shouldBeDataProperty(result2[1], 1, 'result2[1]');
+ shouldBeDataProperty(result2.a, 1, 'result2["a"]');
+ shouldBeDataProperty(result2[sym], 1, 'result2[Symbol(foo)]');
+})();
+
+(function testDuplicatePropertyNames() {
+ var i = 0;
+ var log = [];
+ var P = new Proxy({}, {
+ ownKeys() {
+ log.push(`ownKeys()`);
+ return [ 'A', 'A' ];
+ },
+ getOwnPropertyDescriptor(t, name) {
+ log.push(`getOwnPropertyDescriptor(${name})`);
+ if (i++) return;
+ return {
+ configurable: true,
+ writable: false,
+ value: 'VALUE'
+ };
+ },
+ get() { throw new Error('[[Get]] trap should be unreachable'); },
+ set() { throw new Error('[[Set]] trap should be unreachable'); },
+ deleteProperty() { throw new Error('[[Delete]] trap should be unreachable'); },
+ defineProperty() { throw new Error('[[DefineOwnProperty]] trap should be unreachable'); }
+ });
+
+ var result = Object.getOwnPropertyDescriptors(P);
+ shouldBe(void 0, result.A);
+ shouldBe(true, Object.hasOwnProperty.call(result, 'A'));
+ shouldBe('ownKeys()|getOwnPropertyDescriptor(A)|getOwnPropertyDescriptor(A)', log.join('|'));
+})();
Added: trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js (0 => 196040)
--- trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/es6/Object_static_methods_Object.getOwnPropertyDescriptors.js 2016-02-03 03:17:53 UTC (rev 196040)
@@ -0,0 +1,83 @@
+function shouldBe(expected, actual, msg) {
+ if (msg === void 0)
+ msg = '';
+ else
+ msg = ' for ' + msg;
+ if (actual !== expected)
+ throw new Error('bad value' + msg + ': ' + actual + '. Expected ' + expected);
+}
+
+function shouldThrow(func, errorType) {
+ try {
+ func();
+ throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but did not throw.');
+ } catch (e) {
+ if (e instanceof errorType) return;
+ throw new Error('Expected ' + func + '() to throw ' + errorType.name + ', but threw ' + e);
+ }
+}
+
+function shouldBeDataProperty(expected, value, name) {
+ if (name === void 0)
+ name = '<property descriptor>';
+ shouldBe(value, expected.value, name + '.value');
+ shouldBe(true, expected.enumerable, name + '.enumerable');
+ shouldBe(true, expected.configurable, name + '.configurable');
+ shouldBe(true, expected.writable, name + '.writable');
+ shouldBe(undefined, expected.get, name + '.get');
+ shouldBe(undefined, expected.set, name + '.set');
+}
+
+(function testMeta() {
+ shouldBe(1, Object.getOwnPropertyDescriptors.length);
+
+ shouldBe('getOwnPropertyDescriptors', Object.getOwnPropertyDescriptors.name);
+
+ var propertyDescriptor = Reflect.getOwnPropertyDescriptor(Object, 'getOwnPropertyDescriptors');
+ shouldBe(false, propertyDescriptor.enumerable);
+ shouldBe(true, propertyDescriptor.writable);
+ shouldBe(true, propertyDescriptor.configurable);
+
+ shouldThrow(() => new Object.getOwnPropertyDescriptors({}), TypeError);
+})();
+
+(function testToObject() {
+ shouldThrow(() => Object.getOwnPropertyDescriptors(null), TypeError);
+ shouldThrow(() => Object.getOwnPropertyDescriptors(undefined), TypeError);
+ shouldThrow(() => Object.getOwnPropertyDescriptors(), TypeError);
+})();
+
+(function testPrototypeProperties() {
+ function F() {};
+ F.prototype.a = 'A';
+ F.prototype.b = 'B';
+
+ var F2 = new F();
+ Object.defineProperties(F2, {
+ 'b': {
+ enumerable: false,
+ configurable: true,
+ writable: false,
+ value: 'Shadowed "B"'
+ },
+ 'c': {
+ enumerable: false,
+ configurable: true,
+ writable: false,
+ value: 'C'
+ }
+ });
+
+ var result = Object.getOwnPropertyDescriptors(F2);
+ shouldBe(undefined, result.a);
+
+ shouldBe(result.b.enumerable, false);
+ shouldBe(result.b.configurable, true);
+ shouldBe(result.b.writable, false);
+ shouldBe(result.b.value, 'Shadowed "B"');
+
+ shouldBe(result.c.enumerable, false);
+ shouldBe(result.c.configurable, true);
+ shouldBe(result.c.writable, false);
+ shouldBe(result.c.value, 'C');
+})();
Modified: trunk/Source/_javascript_Core/tests/es6.yaml (196039 => 196040)
--- trunk/Source/_javascript_Core/tests/es6.yaml 2016-02-03 02:27:26 UTC (rev 196039)
+++ trunk/Source/_javascript_Core/tests/es6.yaml 2016-02-03 03:17:53 UTC (rev 196040)
@@ -1216,3 +1216,9 @@
cmd: runES6 :normal
- path: es6/well-known_symbols_Symbol.toStringTag_misc._built-ins.js
cmd: runES6 :normal
+# Late-stage proposals for a future ECMAScript standard
+# FIXME: move these to a new directory?
+- path: es6/Object_static_methods_Object.getOwnPropertyDescriptors.js
+ cmd: runES6 :normal
+- path: es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js
+ cmd: runES6 :fail
\ No newline at end of file