# HG changeset patch # Parent c8e47b184aba8cf8665a7d53ca74889390cb1d0e Bug 866847 - Implements map#forEach and Set#forEach; r=evilpie diff --git a/js/src/Makefile.in b/js/src/Makefile.in --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -970,16 +970,18 @@ selfhosting_srcs := \ $(srcdir)/builtin/Utilities.js \ $(srcdir)/builtin/Array.js \ $(srcdir)/builtin/Date.js \ $(srcdir)/builtin/Intl.js \ $(srcdir)/builtin/IntlData.js \ $(srcdir)/builtin/Number.js \ $(srcdir)/builtin/ParallelArray.js \ $(srcdir)/builtin/String.js \ + $(srcdir)/builtin/Set.js \ + $(srcdir)/builtin/Map.js \ $(NULL) selfhosted_out_h_deps := \ $(selfhosting_srcs) \ $(srcdir)/js.msg \ $(srcdir)/builtin/embedjs.py \ $(NULL) diff --git a/js/src/builtin/Map.js b/js/src/builtin/Map.js new file mode 100644 --- /dev/null +++ b/js/src/builtin/Map.js @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* ES6 20121122 draft 15.5.4.21. */ + +function Map_forEach(callbackfn, thisArg = undefined) { + var M = this; + if(typeof M != "object") + ThrowError(JSMSG_BAD_TYPE); + if (!IsCallable(callbackfn)) + ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + var entries = [...M]; + for (var i = 0; i < entries.length; i++) + callFunction(callbackfn, thisArg, [entries[i][1], entries[i][0]], M); + return undefined; +} diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -1036,16 +1036,17 @@ const JSFunctionSpec MapObject::methods[ JS_FN("has", has, 1, 0), JS_FN("set", set, 2, 0), JS_FN("delete", delete_, 1, 0), JS_FN("keys", keys, 0, 0), JS_FN("values", values, 0, 0), JS_FN("entries", entries, 0, 0), JS_FN("iterator", entries, 0, 0), JS_FN("clear", clear, 0, 0), + {"forEach", {NULL, NULL}, 1, 0, "Map_forEach"}, JS_FS_END }; static JSObject * InitClass(JSContext *cx, Handle global, Class *clasp, JSProtoKey key, Native construct, const JSPropertySpec *properties, const JSFunctionSpec *methods) { Rooted proto(cx, global->createBlankPrototype(cx, clasp)); @@ -1573,16 +1574,17 @@ const JSPropertySpec SetObject::properti }; const JSFunctionSpec SetObject::methods[] = { JS_FN("has", has, 1, 0), JS_FN("add", add, 1, 0), JS_FN("delete", delete_, 1, 0), JS_FN("iterator", iterator, 0, 0), JS_FN("clear", clear, 0, 0), + {"forEach", {NULL, NULL}, 1, 0, "Set_forEach"}, JS_FS_END }; JSObject * SetObject::initClass(JSContext *cx, JSObject *obj) { Rooted global(cx, &obj->asGlobal()); return InitClass(cx, global, &class_, JSProto_Set, construct, properties, methods); diff --git a/js/src/builtin/Set.js b/js/src/builtin/Set.js new file mode 100644 --- /dev/null +++ b/js/src/builtin/Set.js @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* ES6 20121122 draft 15.5.4.21. */ + +function Set_forEach(callbackfn, thisArg = undefined) { + var S = this; + if(typeof S != "object") + ThrowError(JSMSG_BAD_TYPE); + if (!IsCallable(callbackfn)) + ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + for (var e of S) + callFunction(callbackfn, thisArg, e, S); + return undefined; +} diff --git a/js/src/jit-test/tests/collections/Map-forEach.js b/js/src/jit-test/tests/collections/Map-forEach.js new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/collections/Map-forEach.js @@ -0,0 +1,19 @@ +// test Map.prototype.forEach + +var testMap = new Map(); + +function callback(entry, map) { + testMap.set(entry[1], entry[0]); + assertEq(map.has(entry[1]), true); + assertEq(map.get(entry[1]), entry[0]); +} + +var initialMap = new Map([['a', 1], ['b', 2.3], ['c', undefined]]); +initialMap.forEach(callback); + +var testArr = [...testMap]; +var initialArr = [...initialMap]; +for(var i = 0; i < initialArr.length; i++) { + assertEq(testArr[i][0], initialArr[i][0]); + assertEq(testArr[i][1], initialArr[i][1]); +} diff --git a/js/src/jit-test/tests/collections/Set-forEach.js b/js/src/jit-test/tests/collections/Set-forEach.js new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/collections/Set-forEach.js @@ -0,0 +1,16 @@ +// test Set.prototype.forEach + +var testSet = new Set(); + +function callback(elem, set) { + testSet.add(elem); + assertEq(set.has(elem), true); +} + +var initialSet = new Set([1, 2.1, 'test', undefined]); +initialSet.forEach(callback); + +var testArr = [...testSet]; +var initialArr = [...initialSet]; +for(var i = 0; i < initialArr.length; i++) + assertEq(testArr[i], initialArr[i]);