Bug 1197094 - ForOfIterator calls ToObject on iterable; r=evilpie
authorMorgan Phillips <winter2718@gmail.com>
Fri, 04 Dec 2015 15:07:03 -0800
changeset 309920 ec1df10696abe9fdb1f54c50e1e7cdb2d8405f21
parent 309919 68a9e4279f60a9e16e5ad57668c2dbe53dbe5a89
child 309921 cfa2b6acc2baa6dea84a3254295139562ed071d2
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1197094
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1197094 - ForOfIterator calls ToObject on iterable; r=evilpie Remove a needless cast from ValueHandle to Object to ValueHandle, where type information was lost.
js/src/tests/ecma_6/Map/iterable.js
js/src/vm/ForOfIterator.cpp
--- a/js/src/tests/ecma_6/Map/iterable.js
+++ b/js/src/tests/ecma_6/Map/iterable.js
@@ -2,14 +2,27 @@
  * http://creativecommons.org/licenses/publicdomain/ */
 
 let length;
 let iterable = {
    [Symbol.iterator]() { return this; },
    next() { length = arguments.length; return {done: true}; }
 };
 
-let m = new Map(iterable);
+new Map(iterable);
 // ensure no arguments are passed to next() during construction (Bug 1197095)
 assertEq(length, 0);
 
+let typeofThis;
+Object.defineProperty(Number.prototype, Symbol.iterator, {
+  value() {
+    "use strict";
+    typeofThis = typeof this;
+    return { next() { return {done: true}; } };
+  }
+});
+
+new Map(0);
+// ensure that iterable objects retain their type (Bug 1197094)
+assertEq(typeofThis, "number");
+
 if (typeof reportCompare === "function")
   reportCompare(0, 0);
--- a/js/src/vm/ForOfIterator.cpp
+++ b/js/src/vm/ForOfIterator.cpp
@@ -48,17 +48,17 @@ ForOfIterator::init(HandleValue iterable
     }
 
     MOZ_ASSERT(index == NOT_ARRAY);
 
     // The iterator is the result of calling obj[@@iterator]().
     InvokeArgs args(cx);
     if (!args.init(0))
         return false;
-    args.setThis(ObjectValue(*iterableObj));
+    args.setThis(iterable);
 
     RootedValue callee(cx);
     RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
     if (!GetProperty(cx, iterableObj, iterableObj, iteratorId, &callee))
         return false;
 
     // If obj[@@iterator] is undefined and we were asked to allow non-iterables,
     // bail out now without setting iterator.  This will make valueIsIterable(),