Reviewers: rossberg,

Message:
A few questions

1. Right now this handles interceptors using symbols. Is that even possible?

2. The spec has a shared internal function called GetOwnPropertyKeys (O, Type).
We could do the same and share more code but it would involve more runtime
branches.

3. The runtime function %GetLocalPropertyNames takes a boolean. true means only strings and false means strings and symbols. I see that some mirroring functions uses the latter. Would it be OK to change the runtime function to only include symbols when passed false and change the mirrorring function? That would mean that the ordering would change. Another option is to use a tri state (bitmask)
but that seems a bit of an overkill.

Thanks for reviewing

Description:
ES6: Add Object.getOwnPropertySymbols

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.getownpropertysymbols

This allows you to get the symbols used as property keys for an object.

  var object = {};
  var sym = Symbol();
  object[sym] = 42;
  assert(Object.getOwnPropertySymbols(object)[0] === sym);

This is only available with --harmony-symbols

BUG=3049

Please review this at https://codereview.chromium.org/108083005/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+92, -0 lines):
  M src/symbol.js
  M src/v8natives.js
  M test/mjsunit/harmony/symbols.js


Index: src/symbol.js
diff --git a/src/symbol.js b/src/symbol.js
index 050e7d918a02e83934883f280ec75be9424ba9db..7bc6b076eea7e8fc6433462db152f959d091c2d5 100644
--- a/src/symbol.js
+++ b/src/symbol.js
@@ -85,3 +85,14 @@ function SetUpSymbol() {
 }

 SetUpSymbol();
+
+
+function ExtendObject() {
+  %CheckIsBootstrapping();
+
+  InstallFunctions($Object, DONT_ENUM, $Array(
+    "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
+  ));
+}
+
+ExtendObject();
\ No newline at end of file
Index: src/v8natives.js
diff --git a/src/v8natives.js b/src/v8natives.js
index b715e8923ff26184b43d2f5f432e9e5a3cf778d3..1a7a1528723f7496c9bcf8fafae5170a49656b43 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -1038,6 +1038,76 @@ function ToNameArray(obj, trap, includeSymbols) {
 }


+function GetSymbolsInArray(propertyKeys) {
+  var symbols = new InternalArray();
+  var j = 0;
+  for (var i = 0; i < propertyKeys.length; i++) {
+    if (IS_SYMBOL(propertyKeys[i])) {
+      symbols[j++] = propertyKeys[i];
+    }
+  }
+  return symbols;
+}
+
+
+// ES6 19.1.2.8
+function ObjectGetOwnPropertySymbols(obj) {
+  if (!IS_SPEC_OBJECT(obj)) {
+    throw MakeTypeError("called_on_non_object",
+                        ["Object.getOwnPropertySymbols"]);
+  }
+
+  var nameArrays = new InternalArray();
+
+  // Find all the indexed properties.
+
+  // Get names for indexed interceptor properties.
+  var interceptorInfo = %GetInterceptorInfo(obj);
+
+
+  // Find all the named properties.
+
+  // Get the local property symbols.
+  // FIXME: Have the runtime do the filtering.
+  nameArrays.push(GetSymbolsInArray(%GetLocalPropertyNames(obj, true)));
+
+  // Get names for named interceptor properties if any.
+  if ((interceptorInfo & 2) != 0) {
+    // FIXME: Have the runtime do the filtering.
+    var namedInterceptorNames = %GetNamedInterceptorPropertyNames(obj);
+    if (!IS_UNDEFINED(namedInterceptorNames)) {
+      nameArrays.push(GetSymbolsInArray(namedInterceptorSymbols));
+    }
+  }
+
+  var propertySymbols =
+      %Apply(InternalArray.prototype.concat,
+             nameArrays[0], nameArrays, 1, nameArrays.length - 1);
+
+  // Property names are expected to be unique,
+  // but interceptors can interfere with that assumption.
+  if (interceptorInfo != 0) {
+    var propertySet = { __proto__: null };
+    var j = 0;
+    for (var i = 0; i < propertySymbols.length; ++i) {
+      var symbol = propertySymbols[i];
+      if (!IS_SYMBOL(symbol)) continue;
+
+      // We need to check for the exact property value since for intrinsic
+      // properties like toString if(propertySet["toString"]) will always
+      // succeed.
+      if (propertySet[symbol] === true) {
+        continue;
+      }
+      propertySet[symbol] = true;
+      propertySymbols[j++] = symbol;
+    }
+    propertySymbols.length = j;
+  }
+
+  return propertySymbols;
+}
+
 // ES5 section 15.2.3.4.
 function ObjectGetOwnPropertyNames(obj) {
   if (!IS_SPEC_OBJECT(obj)) {
@@ -1420,6 +1490,7 @@ function SetUpObject() {
     "getPrototypeOf", ObjectGetPrototypeOf,
     "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
     "getOwnPropertyNames", ObjectGetOwnPropertyNames,
+    // getOwnPropertySymbols is added in symbol.js
     "is", ObjectIs,
     "isExtensible", ObjectIsExtensible,
     "isFrozen", ObjectIsFrozen,
Index: test/mjsunit/harmony/symbols.js
diff --git a/test/mjsunit/harmony/symbols.js b/test/mjsunit/harmony/symbols.js index 3fcd06dfdca985fcd81abd8630cb8ededa8fe0d7..759d68693102cc03e7082d63b03de8581089ed25 100644
--- a/test/mjsunit/harmony/symbols.js
+++ b/test/mjsunit/harmony/symbols.js
@@ -298,6 +298,15 @@ function TestKeyNames(obj) {
 }


+function TestKeySymbols(obj) {
+  var syms = Object.getOwnPropertySymbols(obj)
+  assertEquals(syms.length, symbols.length)
+  for (var i in syms) {
+    assertEquals("symbol", typeof syms[i])
+  }
+}
+
+
 function TestKeyDescriptor(obj) {
   for (var i in symbols) {
     var desc = Object.getOwnPropertyDescriptor(obj, symbols[i]);
@@ -331,6 +340,7 @@ for (var i in objs) {
   TestKeyHas(obj)
   TestKeyEnum(obj)
   TestKeyNames(obj)
+  TestKeySymbols(obj)
   TestKeyDescriptor(obj)
   TestKeyDelete(obj)
 }


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to