Bug 1398273 - Rename LegacyIterator to PropertyIterator in jsiter. r=luke
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 08 Sep 2017 22:53:35 +0200
changeset 663383 e62cc9325a2b6124cda2a1e219a66fe161ca353b
parent 663382 adc30ee91284e7d4ab9393a53d27eb5f489cc97b
child 663384 daaddc22f93fc7d435c8816626790587f4c59ae4
push id79424
push userbmo:tchiovoloni@mozilla.com
push dateTue, 12 Sep 2017 23:17:54 +0000
reviewersluke
bugs1398273
milestone57.0a1
Bug 1398273 - Rename LegacyIterator to PropertyIterator in jsiter. r=luke And remove more unused legacy iterator stuff.
js/src/builtin/Iterator.js
js/src/builtin/TestingFunctions.cpp
js/src/jit-test/lib/range.js
js/src/jit-test/tests/basic/testShiftLeft.js
js/src/jit-test/tests/basic/testShiftRightArithmetic.js
js/src/jit-test/tests/basic/testShiftRightLogical.js
js/src/jsfriendapi.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/tests/ecma_5/Object/15.2.3.14-01.js
js/src/tests/ecma_6/Proxy/proxy-proto-lazy-props.js
js/src/tests/ecma_7/Object/entries.js
js/src/tests/ecma_7/Object/values.js
--- a/js/src/builtin/Iterator.js
+++ b/js/src/builtin/Iterator.js
@@ -25,20 +25,16 @@ function LegacyIteratorThrow(exn) {
         return { value: callContentFunction(iter.throw, iter, exn), done: false };
     } catch (e) {
         if (e instanceof std_StopIteration)
             return { value: undefined, done: true };
         throw e;
     }
 }
 
-function LegacyIterator(iter) {
-    callFunction(std_WeakMap_set, LegacyIteratorWrapperMap, this, iter);
-}
-
 function LegacyGeneratorIterator(iter) {
     callFunction(std_WeakMap_set, LegacyIteratorWrapperMap, this, iter);
 }
 
 var LegacyIteratorsInitialized = std_Object_create(null);
 
 function InitLegacyIterators() {
     var props = std_Object_create(null);
@@ -50,37 +46,28 @@ function InitLegacyIterators() {
     props.next.writable = true;
 
     props[std_iterator] = std_Object_create(null);
     props[std_iterator].value = IteratorIdentity;
     props[std_iterator].enumerable = false;
     props[std_iterator].configurable = true;
     props[std_iterator].writable = true;
 
-    var LegacyIteratorProto = std_Object_create(GetIteratorPrototype(), props);
-    MakeConstructible(LegacyIterator, LegacyIteratorProto);
-
     props.throw = std_Object_create(null);
     props.throw.value = LegacyIteratorThrow;
     props.throw.enumerable = false;
     props.throw.configurable = true;
     props.throw.writable = true;
 
     var LegacyGeneratorIteratorProto = std_Object_create(GetIteratorPrototype(), props);
     MakeConstructible(LegacyGeneratorIterator, LegacyGeneratorIteratorProto);
 
     LegacyIteratorsInitialized.initialized = true;
 }
 
-function NewLegacyIterator(iter, wrapper) {
+function LegacyGeneratorIteratorShim() {
+    var iter = ToObject(this);
+
     if (!LegacyIteratorsInitialized.initialized)
         InitLegacyIterators();
 
-    return new wrapper(iter);
+    return new LegacyGeneratorIterator(iter);
 }
-
-function LegacyIteratorShim() {
-    return NewLegacyIterator(ToObject(this), LegacyIterator);
-}
-
-function LegacyGeneratorIteratorShim() {
-    return NewLegacyIterator(ToObject(this), LegacyGeneratorIterator);
-}
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -4438,17 +4438,17 @@ IsConstructor(JSContext* cx, unsigned ar
 
 static bool
 IsLegacyIterator(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() < 1)
         args.rval().setBoolean(false);
     else
-        args.rval().setBoolean(IsLegacyIterator(args[0]));
+        args.rval().setBoolean(IsPropertyIterator(args[0]));
     return true;
 }
 
 static const JSFunctionSpecWithHelp TestingFunctions[] = {
     JS_FN_HELP("gc", ::GC, 0, 0,
 "gc([obj] | 'zone' [, 'shrinking'])",
 "  Run the garbage collector. When obj is given, GC only its zone.\n"
 "  If 'zone' is given, GC any zones that were scheduled for\n"
deleted file mode 100644
--- a/js/src/jit-test/lib/range.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* 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/. */
-
-// Library file for tests to load.
-
-function Range(start, stop) {
-    this.i = start;
-    this.stop = stop;
-}
-Range.prototype = {
-    __iterator__: function() { return this; },
-    next: function() {
-        if (this.i >= this.stop)
-            throw StopIteration;
-        return this.i++;
-    }
-};
-
-function range(start, stop) {
-    return new Range(start, stop);
-}
--- a/js/src/jit-test/tests/basic/testShiftLeft.js
+++ b/js/src/jit-test/tests/basic/testShiftLeft.js
@@ -1,16 +1,14 @@
 // |jit-test| valgrind
 
 /* Test the proper operation of the left shift operator. This is especially
  * important on ARM as an explicit mask is required at the native instruction
  * level. */
 
-load(libdir + 'range.js');
-
 function testShiftLeft()
 {
     var r = [];
     var i = 0;
     var j = 0;
 
     var shifts = [0,1,7,8,15,16,23,24,31];
 
--- a/js/src/jit-test/tests/basic/testShiftRightArithmetic.js
+++ b/js/src/jit-test/tests/basic/testShiftRightArithmetic.js
@@ -1,14 +1,12 @@
 /* Test the proper operation of the arithmetic right shift operator. This is
  * especially important on ARM as an explicit mask is required at the native
  * instruction level. */
 
-load(libdir + 'range.js');
-
 /* Test different combinations of literals/variables. */
 var s = 4;
 var t = 100;
 assertEq(42 >> s, 2);
 assertEq(s >> 1, 2);
 assertEq(23 >> 3, 2);
 assertEq(t >> s, 6);
 
--- a/js/src/jit-test/tests/basic/testShiftRightLogical.js
+++ b/js/src/jit-test/tests/basic/testShiftRightLogical.js
@@ -1,14 +1,12 @@
 /* Test the proper operation of the logical right shift operator. This is
  * especially important on ARM as an explicit mask is required at the native
  * instruction level. */
 
-load(libdir + 'range.js');
-
 function testShiftRightLogical()
 {
     var r = [];
     var i = 0;
     var j = 0;
 
     var shifts = [0,1,7,8,15,16,23,24,31];
 
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1000,21 +1000,21 @@ StringIsArrayIndex(JSLinearString* str, 
 JS_FRIEND_API(void)
 SetPreserveWrapperCallback(JSContext* cx, PreserveWrapperCallback callback);
 
 JS_FRIEND_API(bool)
 IsObjectInContextCompartment(JSObject* obj, const JSContext* cx);
 
 /*
  * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h.
- * The first three are omitted because they shouldn't be used in new code.
+ * The first two are omitted because they shouldn't be used in new code.
  */
 #define JSITER_ENUMERATE  0x1   /* for-in compatible hidden default iterator */
 #define JSITER_FOREACH    0x2   /* get obj[key] for each property */
-#define JSITER_KEYVALUE   0x4   /* obsolete destructuring for-in wants [key, value] */
+/* 0x4 is no longer used */
 #define JSITER_OWNONLY    0x8   /* iterate over obj's own properties only */
 #define JSITER_HIDDEN     0x10  /* also enumerate non-enumerable properties */
 #define JSITER_SYMBOLS    0x20  /* also include symbol property keys */
 #define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */
 #define JSITER_FORAWAITOF 0x80  /* for-await-of */
 
 JS_FRIEND_API(bool)
 RunningWithTrustedPrincipals(JSContext* cx);
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -68,22 +68,16 @@ NativeIterator::trace(JSTracer* trc)
     // The SuppressDeletedPropertyHelper loop can GC, so make sure that if the
     // GC removes any elements from the list, it won't remove this one.
     if (iterObj_)
         TraceManuallyBarrieredEdge(trc, &iterObj_, "iterObj");
 }
 
 typedef HashSet<jsid, DefaultHasher<jsid>> IdSet;
 
-static inline bool
-NewKeyValuePair(JSContext* cx, jsid id, const Value& val, MutableHandleValue rval)
-{
-    return NewValuePair(cx, IdToValue(id), val, rval);
-}
-
 template <bool CheckForDuplicates>
 static inline bool
 Enumerate(JSContext* cx, HandleObject pobj, jsid id,
           bool enumerable, unsigned flags, Maybe<IdSet>& ht, AutoIdVector* props)
 {
     if (CheckForDuplicates) {
         if (!ht) {
             ht.emplace(cx);
@@ -537,17 +531,17 @@ Snapshot(JSContext* cx, HandleObject pob
 JS_FRIEND_API(bool)
 js::GetPropertyKeys(JSContext* cx, HandleObject obj, unsigned flags, AutoIdVector* props)
 {
     return Snapshot(cx, obj,
                     flags & (JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS | JSITER_SYMBOLSONLY),
                     props);
 }
 
-static bool legacy_iterator_next(JSContext* cx, unsigned argc, Value* vp);
+static bool property_iterator_next(JSContext* cx, unsigned argc, Value* vp);
 
 static inline PropertyIteratorObject*
 NewPropertyIteratorObject(JSContext* cx, unsigned flags)
 {
     if (flags & JSITER_ENUMERATE) {
         RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, &PropertyIteratorObject::class_,
                                                                  TaggedProto(nullptr)));
         if (!group)
@@ -578,17 +572,17 @@ NewPropertyIteratorObject(JSContext* cx,
     if (!res)
         return nullptr;
 
     if (flags == 0) {
         // Redefine next as an own property. This ensure that deleting the
         // next method on the prototype doesn't break cross-global for .. in.
         // We don't have to do this for JSITER_ENUMERATE because that object always
         // takes an optimized path.
-        RootedFunction next(cx, NewNativeFunction(cx, legacy_iterator_next, 0,
+        RootedFunction next(cx, NewNativeFunction(cx, property_iterator_next, 0,
                                                   HandlePropertyName(cx->names().next)));
         if (!next)
             return nullptr;
 
         RootedValue value(cx, ObjectValue(*next));
         if (!DefineDataProperty(cx, res, cx->names().next, value))
             return nullptr;
     }
@@ -1043,32 +1037,29 @@ NativeIteratorNext(JSContext* cx, Native
     RootedValue current(cx, StringValue(*ni->current()));
     if (!ValueToId<CanGC>(cx, current, &id))
         return false;
     ni->incCursor();
     RootedObject obj(cx, ni->obj);
     if (!GetProperty(cx, obj, obj, id, rval))
         return false;
 
-    // JS 1.7 only: for each (let [k, v] in obj)
-    if (ni->flags & JSITER_KEYVALUE)
-        return NewKeyValuePair(cx, id, rval, rval);
     return true;
 }
 
 bool
-js::IsLegacyIterator(HandleValue v)
+js::IsPropertyIterator(HandleValue v)
 {
-    return v.isObject() && v.toObject().hasClass(&PropertyIteratorObject::class_);
+    return v.isObject() && v.toObject().is<PropertyIteratorObject>();
 }
 
 MOZ_ALWAYS_INLINE bool
-legacy_iterator_next_impl(JSContext* cx, const CallArgs& args)
+property_iterator_next_impl(JSContext* cx, const CallArgs& args)
 {
-    MOZ_ASSERT(IsLegacyIterator(args.thisv()));
+    MOZ_ASSERT(IsPropertyIterator(args.thisv()));
 
     RootedObject thisObj(cx, &args.thisv().toObject());
 
     NativeIterator* ni = thisObj.as<PropertyIteratorObject>()->getNativeIterator();
     RootedValue value(cx);
     bool done;
     if (!NativeIteratorNext(cx, ni, &value, &done))
          return false;
@@ -1079,20 +1070,20 @@ legacy_iterator_next_impl(JSContext* cx,
         return false;
     }
 
     args.rval().set(value);
     return true;
 }
 
 static bool
-legacy_iterator_next(JSContext* cx, unsigned argc, Value* vp)
+property_iterator_next(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    return CallNonGenericMethod<IsLegacyIterator, legacy_iterator_next_impl>(cx, args);
+    return CallNonGenericMethod<IsPropertyIterator, property_iterator_next_impl>(cx, args);
 }
 
 size_t
 PropertyIteratorObject::sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf) const
 {
     return mallocSizeOf(getPrivate());
 }
 
@@ -1193,19 +1184,16 @@ js::NewStringIteratorObject(JSContext* c
         return nullptr;
 
     return NewObjectWithGivenProto<StringIteratorObject>(cx, proto, newKind);
 }
 
 JSObject*
 js::ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp)
 {
-    /* JSITER_KEYVALUE must always come with JSITER_FOREACH */
-    MOZ_ASSERT_IF(flags & JSITER_KEYVALUE, flags & JSITER_FOREACH);
-
     RootedObject obj(cx);
     if (vp.isObject()) {
         /* Common case. */
         obj = &vp.toObject();
     } else if ((flags & JSITER_ENUMERATE) && vp.isNullOrUndefined()) {
         /*
          * Enumerating over null and undefined gives an empty enumerator, so
          * that |for (var p in <null or undefined>) <loop>;| never executes
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -213,17 +213,17 @@ ThrowStopIteration(JSContext* cx);
 /*
  * Create an object of the form { value: VALUE, done: DONE }.
  * ES 2017 draft 7.4.7.
  */
 extern JSObject*
 CreateIterResultObject(JSContext* cx, HandleValue value, bool done);
 
 bool
-IsLegacyIterator(HandleValue v);
+IsPropertyIterator(HandleValue v);
 
 extern JSObject*
 InitStopIterationClass(JSContext* cx, HandleObject obj);
 
 enum class IteratorKind { Sync, Async };
 
 } /* namespace js */
 
--- a/js/src/tests/ecma_5/Object/15.2.3.14-01.js
+++ b/js/src/tests/ecma_5/Object/15.2.3.14-01.js
@@ -31,17 +31,17 @@ keys = Object.keys(o);
 assertEq(arraysEqual(keys, ["a", "b"]), true,
          "" + keys);
 
 o = { get a() { return 17; }, b: 2 };
 keys = Object.keys(o),
 assertEq(arraysEqual(keys, ["a", "b"]), true,
          "" + keys);
 
-o = { __iterator__: function() { return Iterator({a: 2, b: 3}); } };
+o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } };
 keys = Object.keys(o);
 assertEq(arraysEqual(keys, ["__iterator__"]), true,
          "" + keys);
 
 o = { a: 1, b: 2 };
 delete o.a;
 o.a = 3;
 keys = Object.keys(o);
--- a/js/src/tests/ecma_6/Proxy/proxy-proto-lazy-props.js
+++ b/js/src/tests/ecma_6/Proxy/proxy-proto-lazy-props.js
@@ -2,19 +2,17 @@ function makeProxyPrototype(target) {
     return Object.setPrototypeOf(target, new Proxy({}, new Proxy({
         getPrototypeOf() {
             return null;
         },
         ownKeys() {
             return [];
         },
         get(t, pk, r) {
-            // Handle the non-standard __iterator__ hook.
-            if (pk !== "__iterator__")
-                throw new Error("Unexpected [[Get]]: " + String(pk));
+            throw new Error("Unexpected [[Get]]: " + String(pk));
         }
     }, {
         get(t, pk, r) {
             if (pk in t)
                 return Reflect.get(t, pk, r);
             throw new Error("Unexpected trap called: " + pk);
         }
     })));
--- a/js/src/tests/ecma_7/Object/entries.js
+++ b/js/src/tests/ecma_7/Object/entries.js
@@ -11,17 +11,17 @@ if ("entries" in Object) {
     o = { a: 3, b: 2 };
     entries = Object.entries(o);
     assertDeepEq(entries, [["a", 3], ["b", 2]]);
 
     o = { get a() { return 17; }, b: 2 };
     entries = Object.entries(o),
     assertDeepEq(entries, [["a", 17], ["b", 2]]);
 
-    o = { __iterator__: function() { return Iterator({a: 2, b: 3}); } };
+    o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } };
     entries = Object.entries(o);
     assertDeepEq(entries, [["__iterator__", o.__iterator__]]);
 
     o = { a: 1, b: 2 };
     delete o.a;
     o.a = 3;
     entries = Object.entries(o);
     assertDeepEq(entries, [["b", 2], ["a", 3]]);
--- a/js/src/tests/ecma_7/Object/values.js
+++ b/js/src/tests/ecma_7/Object/values.js
@@ -11,17 +11,17 @@ if ("values" in Object) {
     o = { a: 3, b: 2 };
     values = Object.values(o);
     assertDeepEq(values, [3, 2]);
 
     o = { get a() { return 17; }, b: 2 };
     values = Object.values(o),
     assertDeepEq(values, [17, 2]);
 
-    o = { __iterator__: function() { return Iterator({a: 2, b: 3}); } };
+    o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } };
     values = Object.values(o);
     assertDeepEq(values, [o.__iterator__]);
 
     o = { a: 1, b: 2 };
     delete o.a;
     o.a = 3;
     values = Object.values(o);
     assertDeepEq(values, [2, 3]);