Bug 1098412 - Remove __iterator__ implementation. r?luke draft
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Thu, 24 Aug 2017 22:17:40 +0900
changeset 655311 6b631a79464b7f713de5580c71f1a879bfd6fdd6
parent 655310 bfba5ae2c7b74157ebaecfecd241bb473a0fc494
child 655312 9914da93bfe9b665025d17df808a34a170447f38
push id76825
push userVYV03354@nifty.ne.jp
push dateTue, 29 Aug 2017 20:26:22 +0000
reviewersluke
bugs1098412
milestone57.0a1
Bug 1098412 - Remove __iterator__ implementation. r?luke MozReview-Commit-ID: 6qqSSrB4Vvh
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsiter.cpp
js/src/vm/CommonPropertyNames.h
js/src/vm/NativeObject.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
toolkit/components/telemetry/docs/data/main-ping.rst
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -541,25 +541,16 @@ extern size_t sSetProtoCalled;
 } // namespace js
 
 JS_FRIEND_API(size_t)
 JS_SetProtoCalled(JSContext*)
 {
     return sSetProtoCalled;
 }
 
-// Defined in jsiter.cpp.
-extern size_t sCustomIteratorCount;
-
-JS_FRIEND_API(size_t)
-JS_GetCustomIteratorCount(JSContext* cx)
-{
-    return sCustomIteratorCount;
-}
-
 JS_FRIEND_API(unsigned)
 JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp)
 {
     return PCToLineNumber(script, pc, columnp);
 }
 
 JS_FRIEND_API(bool)
 JS_IsDeadWrapper(JSObject* obj)
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -69,19 +69,16 @@ extern JS_FRIEND_API(JSObject*)
 JS_NewObjectWithoutMetadata(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
 
 extern JS_FRIEND_API(uint32_t)
 JS_ObjectCountDynamicSlots(JS::HandleObject obj);
 
 extern JS_FRIEND_API(size_t)
 JS_SetProtoCalled(JSContext* cx);
 
-extern JS_FRIEND_API(size_t)
-JS_GetCustomIteratorCount(JSContext* cx);
-
 extern JS_FRIEND_API(bool)
 JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
 
 extern JS_FRIEND_API(bool)
 JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
 
 // Raw JSScript* because this needs to be callable from a signal handler.
 extern JS_FRIEND_API(unsigned)
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -537,65 +537,16 @@ 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);
 }
 
-size_t sCustomIteratorCount = 0;
-
-static inline bool
-GetCustomIterator(JSContext* cx, HandleObject obj, unsigned flags, MutableHandleObject objp)
-{
-    if (MOZ_UNLIKELY(!CheckRecursionLimit(cx)))
-        return false;
-
-    RootedValue rval(cx);
-    /* Check whether we have a valid __iterator__ method. */
-    HandlePropertyName name = cx->names().iteratorIntrinsic;
-    if (!GetProperty(cx, obj, obj, name, &rval))
-        return false;
-
-    /* If there is no custom __iterator__ method, we are done here. */
-    if (MOZ_LIKELY(!rval.isObject())) {
-        objp.set(nullptr);
-        return true;
-    }
-
-    if (!cx->runningWithTrustedPrincipals())
-        ++sCustomIteratorCount;
-
-    /* Otherwise call it and return that object. */
-    {
-        FixedInvokeArgs<1> args(cx);
-
-        args[0].setBoolean((flags & JSITER_FOREACH) == 0);
-
-        RootedValue thisv(cx, ObjectValue(*obj));
-        if (!js::Call(cx, rval, thisv, args, &rval))
-            return false;
-    }
-
-    if (rval.isPrimitive()) {
-        // Ignore the stack when throwing. We can't tell whether we were
-        // supposed to skip over a new.target or not.
-        JSAutoByteString bytes;
-        if (!AtomToPrintableString(cx, name, &bytes))
-            return false;
-        RootedValue val(cx, ObjectValue(*obj));
-        ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
-                          JSDVG_IGNORE_STACK, val, nullptr, bytes.ptr());
-        return false;
-    }
-    objp.set(&rval.toObject());
-    return true;
-}
-
 static bool legacy_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)));
@@ -921,19 +872,16 @@ CanStoreInIteratorCache(JSContext* cx, J
 
             // Typed arrays have indexed properties not captured by the Shape guard.
             // Enumerate hooks may add extra properties.
             const Class* clasp = obj->getClass();
             if (MOZ_UNLIKELY(IsTypedArrayClass(clasp)))
                 return false;
             if (MOZ_UNLIKELY(clasp->getNewEnumerate() || clasp->getEnumerate()))
                 return false;
-
-            if (MOZ_UNLIKELY(obj->as<NativeObject>().containsPure(cx->names().iteratorIntrinsic)))
-                return false;
         } else {
             MOZ_ASSERT(obj->is<UnboxedPlainObject>());
         }
 
         obj = obj->staticPrototype();
     } while (obj);
 
     return true;
@@ -992,28 +940,22 @@ js::GetIterator(JSContext* cx, HandleObj
     // Or when we call GetIterator from the Proxy [[Enumerate]] hook.
     // JSITER_ENUMERATE is just an optimization and the same
     // as flags == 0 otherwise.
     if (flags == 0 || flags == JSITER_ENUMERATE) {
         if (MOZ_UNLIKELY(obj->is<ProxyObject>()))
             return Proxy::enumerate(cx, obj);
     }
 
-    RootedObject res(cx);
-    if (!GetCustomIterator(cx, obj, flags, &res))
-        return nullptr;
-    if (res) {
-        assertSameCompartment(cx, res);
-        return res;
-    }
 
     AutoIdVector keys(cx);
     if (!Snapshot(cx, obj, flags, &keys))
         return nullptr;
 
+    JSObject* res;
     if (flags & JSITER_FOREACH) {
         MOZ_ASSERT(numGuards == 0);
         res = VectorToValueIterator(cx, obj, flags, keys);
         if (!res)
             return nullptr;
     } else {
         res = VectorToKeyIterator(cx, obj, flags, keys, numGuards);
         if (!res)
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -201,17 +201,16 @@
     macro(InterpretGeneratorResume, InterpretGeneratorResume, "InterpretGeneratorResume") \
     macro(isEntryPoint, isEntryPoint, "isEntryPoint") \
     macro(isExtensible, isExtensible, "isExtensible") \
     macro(isFinite, isFinite, "isFinite") \
     macro(isNaN, isNaN, "isNaN") \
     macro(isPrototypeOf, isPrototypeOf, "isPrototypeOf") \
     macro(IterableToList, IterableToList, "IterableToList") \
     macro(iterate, iterate, "iterate") \
-    macro(iteratorIntrinsic, iteratorIntrinsic, "__iterator__") \
     macro(join, join, "join") \
     macro(js, js, "js") \
     macro(keys, keys, "keys") \
     macro(label, label, "label") \
     macro(lastIndex, lastIndex, "lastIndex") \
     macro(LegacyGeneratorCloseInternal, LegacyGeneratorCloseInternal, "LegacyGeneratorCloseInternal") \
     macro(length, length, "length") \
     macro(let, let, "let") \
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -2230,20 +2230,16 @@ GetNonexistentProperty(JSContext* cx, Ha
         return true;
 
     // Don't warn in self-hosted code (where the further presence of
     // JS::RuntimeOptions::werror() would result in impossible-to-avoid
     // errors to entirely-innocent client code).
     if (script->selfHosted())
         return true;
 
-    // We may just be checking if that object has an iterator.
-    if (JSID_IS_ATOM(id, cx->names().iteratorIntrinsic))
-        return true;
-
     // Do not warn about tests like (obj[prop] == undefined).
     pc += CodeSpec[*pc].length;
     if (Detecting(cx, script, pc))
         return true;
 
     unsigned flags = JSREPORT_WARNING | JSREPORT_STRICT;
     script->setWarnedAboutUndefinedProp();
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3231,21 +3231,16 @@ nsXPCComponents_Utils::GetJSEngineTeleme
 
     unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
 
     size_t i = JS_SetProtoCalled(cx);
     RootedValue v(cx, DoubleValue(i));
     if (!JS_DefineProperty(cx, obj, "setProto", v, attrs))
         return NS_ERROR_OUT_OF_MEMORY;
 
-    i = JS_GetCustomIteratorCount(cx);
-    v.setDouble(i);
-    if (!JS_DefineProperty(cx, obj, "customIter", v, attrs))
-        return NS_ERROR_OUT_OF_MEMORY;
-
     rval.setObject(*obj);
     return NS_OK;
 }
 
 bool
 xpc::CloneInto(JSContext* aCx, HandleValue aValue, HandleValue aScope,
                HandleValue aOptions, MutableHandleValue aCloned)
 {
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -87,17 +87,16 @@ const char* const XPCJSRuntime::mStrings
     "Components",           // IDX_COMPONENTS
     "wrappedJSObject",      // IDX_WRAPPED_JSOBJECT
     "Object",               // IDX_OBJECT
     "Function",             // IDX_FUNCTION
     "prototype",            // IDX_PROTOTYPE
     "createInstance",       // IDX_CREATE_INSTANCE
     "item",                 // IDX_ITEM
     "__proto__",            // IDX_PROTO
-    "__iterator__",         // IDX_ITERATOR
     "__exposedProps__",     // IDX_EXPOSEDPROPS
     "eval",                 // IDX_EVAL
     "controllers",          // IDX_CONTROLLERS
     "Controllers",          // IDX_CONTROLLERS_CLASS
     "realFrameElement",     // IDX_REALFRAMEELEMENT
     "length",               // IDX_LENGTH
     "name",                 // IDX_NAME
     "undefined",            // IDX_UNDEFINED
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -453,17 +453,16 @@ public:
         IDX_COMPONENTS              ,
         IDX_WRAPPED_JSOBJECT        ,
         IDX_OBJECT                  ,
         IDX_FUNCTION                ,
         IDX_PROTOTYPE               ,
         IDX_CREATE_INSTANCE         ,
         IDX_ITEM                    ,
         IDX_PROTO                   ,
-        IDX_ITERATOR                ,
         IDX_EXPOSEDPROPS            ,
         IDX_EVAL                    ,
         IDX_CONTROLLERS             ,
         IDX_CONTROLLERS_CLASS       ,
         IDX_REALFRAMEELEMENT        ,
         IDX_LENGTH                  ,
         IDX_NAME                    ,
         IDX_UNDEFINED               ,
--- a/toolkit/components/telemetry/docs/data/main-ping.rst
+++ b/toolkit/components/telemetry/docs/data/main-ping.rst
@@ -184,17 +184,16 @@ js
 This section contains a series of counters from the JavaScript engine.
 
 Structure:
 
 .. code-block:: js
 
     "js" : {
       "setProto": <unsigned integer>, // Number of times __proto__ is set
-      "customIter": <unsigned integer> // Number of times __iterator__ is used (i.e., is found for a for-in loop)
     }
 
 maximalNumberOfConcurrentThreads
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 An integer representing the highest number of threads encountered so far during the session.
 
 startupSessionRestoreReadBytes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~