Revision: 12875
Author:   [email protected]
Date:     Tue Nov  6 10:14:45 2012
Log:      ES6: Adding support for size to Set and Map

Section 15.14.5.10 and 15.16.5.7 in the October 26, 2012 ES6 draft,
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts

This adds a getter for "size" to Set.prototype and Map.prototype which reflects
the number of elements in the Set and Map respectively.

BUG=v8:2395

Review URL: https://codereview.chromium.org/11360089
Patch from Erik Arvidsson <[email protected]>.
http://code.google.com/p/v8/source/detail?r=12875

Modified:
 /branches/bleeding_edge/src/collection.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/v8natives.js
 /branches/bleeding_edge/test/mjsunit/harmony/collections.js

=======================================
--- /branches/bleeding_edge/src/collection.js   Mon Jun 25 06:33:48 2012
+++ /branches/bleeding_edge/src/collection.js   Tue Nov  6 10:14:45 2012
@@ -86,6 +86,15 @@
     return false;
   }
 }
+
+
+function SetGetSize() {
+  if (!IS_SET(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Set.prototype.size', this]);
+  }
+  return %SetGetSize(this);
+}


 function MapConstructor() {
@@ -143,6 +152,15 @@
   }
   return %MapDelete(this, key);
 }
+
+
+function MapGetSize() {
+  if (!IS_MAP(this)) {
+    throw MakeTypeError('incompatible_method_receiver',
+                        ['Map.prototype.size', this]);
+  }
+  return %MapGetSize(this);
+}


 function WeakMapConstructor() {
@@ -215,6 +233,7 @@
   %SetProperty($Map.prototype, "constructor", $Map, DONT_ENUM);

   // Set up the non-enumerable functions on the Set prototype object.
+  InstallGetter($Set.prototype, "size", SetGetSize);
   InstallFunctions($Set.prototype, DONT_ENUM, $Array(
     "add", SetAdd,
     "has", SetHas,
@@ -222,6 +241,7 @@
   ));

   // Set up the non-enumerable functions on the Map prototype object.
+  InstallGetter($Map.prototype, "size", MapGetSize);
   InstallFunctions($Map.prototype, DONT_ENUM, $Array(
     "get", MapGet,
     "set", MapSet,
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Tue Nov  6 08:47:15 2012
+++ /branches/bleeding_edge/src/runtime.cc      Tue Nov  6 10:14:45 2012
@@ -781,6 +781,15 @@
   holder->set_table(*table);
   return isolate->heap()->undefined_value();
 }
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
+  return Smi::FromInt(table->NumberOfElements());
+}


 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) {
@@ -840,6 +849,15 @@
   holder->set_table(*new_table);
   return isolate->heap()->undefined_value();
 }
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+  return Smi::FromInt(table->NumberOfElements());
+}


 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Tue Nov  6 08:47:15 2012
+++ /branches/bleeding_edge/src/runtime.h       Tue Nov  6 10:14:45 2012
@@ -302,6 +302,7 @@
   F(SetAdd, 2, 1) \
   F(SetHas, 2, 1) \
   F(SetDelete, 2, 1) \
+  F(SetGetSize, 1, 1) \
   \
   /* Harmony maps */ \
   F(MapInitialize, 1, 1) \
@@ -309,6 +310,7 @@
   F(MapHas, 2, 1) \
   F(MapDelete, 2, 1) \
   F(MapSet, 3, 1) \
+  F(MapGetSize, 1, 1) \
   \
   /* Harmony weakmaps */ \
   F(WeakMapInitialize, 1, 1) \
=======================================
--- /branches/bleeding_edge/src/v8natives.js    Tue Nov  6 04:32:36 2012
+++ /branches/bleeding_edge/src/v8natives.js    Tue Nov  6 10:14:45 2012
@@ -59,6 +59,16 @@
   }
   %ToFastProperties(object);
 }
+
+
+// Helper function to install a getter only property.
+function InstallGetter(object, name, getter) {
+  %FunctionSetName(getter, name);
+  %FunctionRemovePrototype(getter);
+  %DefineOrRedefineAccessorProperty(object, name, getter, null, DONT_ENUM);
+  %SetNativeFlag(getter);
+}
+

 // Prevents changes to the prototype of a built-in function.
// The "prototype" property of the function object is made non-configurable,
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/collections.js Mon Jun 25 06:33:48 2012 +++ /branches/bleeding_edge/test/mjsunit/harmony/collections.js Tue Nov 6 10:14:45 2012
@@ -314,3 +314,44 @@
 // There is a proposed stress-test available at the es-discuss mailing list
 // which cannot be reasonably automated.  Check it out by hand if you like:
 // https://mail.mozilla.org/pipermail/es-discuss/2011-May/014096.html
+
+
+// Set and Map size getters
+var setSizeDescriptor = Object.getOwnPropertyDescriptor(Set.prototype, 'size');
+assertEquals(undefined, setSizeDescriptor.value);
+assertEquals(undefined, setSizeDescriptor.set);
+assertTrue(setSizeDescriptor.get instanceof Function);
+assertEquals(undefined, setSizeDescriptor.get.prototype);
+assertFalse(setSizeDescriptor.enumerable);
+assertTrue(setSizeDescriptor.configurable);
+
+var s = new Set();
+assertFalse(s.hasOwnProperty('size'));
+for (var i = 0; i < 10; i++) {
+  assertEquals(i, s.size);
+  s.add(i);
+}
+for (var i = 9; i >= 0; i--) {
+  s.delete(i);
+  assertEquals(i, s.size);
+}
+
+
+var mapSizeDescriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size');
+assertEquals(undefined, mapSizeDescriptor.value);
+assertEquals(undefined, mapSizeDescriptor.set);
+assertTrue(mapSizeDescriptor.get instanceof Function);
+assertEquals(undefined, mapSizeDescriptor.get.prototype);
+assertFalse(mapSizeDescriptor.enumerable);
+assertTrue(mapSizeDescriptor.configurable);
+
+var m = new Map();
+assertFalse(m.hasOwnProperty('size'));
+for (var i = 0; i < 10; i++) {
+  assertEquals(i, m.size);
+  m.set(i, i);
+}
+for (var i = 9; i >= 0; i--) {
+  m.delete(i);
+  assertEquals(i, m.size);
+}

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to