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 <arv@chromium.org>.
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12875
ce2b1a6d-e550-0410-aec6-
3dcde31c8c00
}
+function SetGetSize() {
+ if (!IS_SET(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Set.prototype.size', this]);
+ }
+ return %SetGetSize(this);
+}
+
+
function MapConstructor() {
if (%_IsConstructCall()) {
%MapInitialize(this);
}
+function MapGetSize() {
+ if (!IS_MAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Map.prototype.size', this]);
+ }
+ return %MapGetSize(this);
+}
+
+
function WeakMapConstructor() {
if (%_IsConstructCall()) {
%WeakMapInitialize(this);
%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,
));
// 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,
}
+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) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
}
+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) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
F(SetAdd, 2, 1) \
F(SetHas, 2, 1) \
F(SetDelete, 2, 1) \
+ F(SetGetSize, 1, 1) \
\
/* Harmony maps */ \
F(MapInitialize, 1, 1) \
F(MapHas, 2, 1) \
F(MapDelete, 2, 1) \
F(MapSet, 3, 1) \
+ F(MapGetSize, 1, 1) \
\
/* Harmony weakmaps */ \
F(WeakMapInitialize, 1, 1) \
%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,
// and the prototype object is made non-extensible. The latter prevents
// Stress Test
// 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
\ No newline at end of file
+// 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);
+}