Bug 1098412 - Remove the legacy Iterator constructor. r?luke draft
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 25 Aug 2017 22:29:07 +0900
changeset 655312 9914da93bfe9b665025d17df808a34a170447f38
parent 655311 6b631a79464b7f713de5580c71f1a879bfd6fdd6
child 728789 f6027f1df8f195faed0517e7d087e3ee81bd42bc
push id76825
push userVYV03354@nifty.ne.jp
push dateTue, 29 Aug 2017 20:26:22 +0000
reviewersluke
bugs1098412
milestone57.0a1
Bug 1098412 - Remove the legacy Iterator constructor. r?luke MozReview-Commit-ID: 4GmodzFsZsY
js/src/jscntxtinlines.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsprototypes.h
js/src/vm/GlobalObject.h
js/src/vm/HelperThreads.cpp
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -336,23 +336,19 @@ CallJSNativeConstructor(JSContext* cx, N
      * Exceptions:
      *
      * - Proxies are exceptions to both rules: they can return primitives and
      *   they allow content to return the callee.
      *
      * - CallOrConstructBoundFunction is an exception as well because we might
      *   have used bind on a proxy function.
      *
-     * - new Iterator(x) is user-hookable; it returns x.__iterator__() which
-     *   could be any object.
-     *
      * - (new Object(Object)) returns the callee.
      */
     MOZ_ASSERT_IF(native != js::proxy_Construct &&
-                  native != js::IteratorConstructor &&
                   (!callee->is<JSFunction>() || callee->as<JSFunction>().native() != obj_construct),
                   args.rval().isObject() && callee != &args.rval().toObject());
 
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 CallJSGetterOp(JSContext* cx, GetterOp op, HandleObject obj, HandleId id,
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -1017,37 +1017,16 @@ js::ThrowStopIteration(JSContext* cx)
     RootedObject ctor(cx);
     if (GetBuiltinConstructor(cx, JSProto_StopIteration, &ctor))
         cx->setPendingException(ObjectValue(*ctor));
     return false;
 }
 
 /*** Iterator objects ****************************************************************************/
 
-bool
-js::IteratorConstructor(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() == 0) {
-        ReportMissingArg(cx, args.calleev(), 0);
-        return false;
-    }
-
-    bool keyonly = false;
-    if (args.length() >= 2)
-        keyonly = ToBoolean(args[1]);
-    unsigned flags = JSITER_OWNONLY | (keyonly ? 0 : (JSITER_FOREACH | JSITER_KEYVALUE));
-
-    RootedObject iterobj(cx, ValueToIterator(cx, flags, args[0]));
-    if (!iterobj)
-        return false;
-    args.rval().setObject(*iterobj);
-    return true;
-}
-
 MOZ_ALWAYS_INLINE bool
 NativeIteratorNext(JSContext* cx, NativeIterator* ni, MutableHandleValue rval, bool* done)
 {
     *done = false;
 
     if (ni->props_cursor >= ni->props_end) {
         *done = true;
         return true;
@@ -1106,22 +1085,16 @@ legacy_iterator_next_impl(JSContext* cx,
 
 static bool
 legacy_iterator_next(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsLegacyIterator, legacy_iterator_next_impl>(cx, args);
 }
 
-static const JSFunctionSpec legacy_iterator_methods[] = {
-    JS_SELF_HOSTED_SYM_FN(iterator, "LegacyIteratorShim", 0, 0),
-    JS_FN("next",      legacy_iterator_next,       0, 0),
-    JS_FS_END
-};
-
 size_t
 PropertyIteratorObject::sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf) const
 {
     return mallocSizeOf(getPrivate());
 }
 
 void
 PropertyIteratorObject::trace(JSTracer* trc, JSObject* obj)
@@ -1148,17 +1121,16 @@ const ClassOps PropertyIteratorObject::c
     nullptr, /* call        */
     nullptr, /* hasInstance */
     nullptr, /* construct   */
     trace
 };
 
 const Class PropertyIteratorObject::class_ = {
     "Iterator",
-    JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
     JSCLASS_HAS_PRIVATE |
     JSCLASS_BACKGROUND_FINALIZE,
     &PropertyIteratorObject::classOps_
 };
 
 static const Class ArrayIteratorPrototypeClass = {
     "Array Iterator",
     0
@@ -1629,54 +1601,16 @@ GlobalObject::initStringIteratorProto(JS
         return false;
     }
 
     global->setReservedSlot(STRING_ITERATOR_PROTO, ObjectValue(*proto));
     return true;
 }
 
 JSObject*
-js::InitLegacyIteratorClass(JSContext* cx, HandleObject obj)
-{
-    Handle<GlobalObject*> global = obj.as<GlobalObject>();
-
-    if (global->getPrototype(JSProto_Iterator).isObject())
-        return &global->getPrototype(JSProto_Iterator).toObject();
-
-    RootedObject iteratorProto(cx);
-    iteratorProto = GlobalObject::createBlankPrototype(cx, global,
-                                                       &PropertyIteratorObject::class_);
-    if (!iteratorProto)
-        return nullptr;
-
-    NativeIterator* ni = NativeIterator::allocateIterator(cx, 0, 0);
-    if (!ni)
-        return nullptr;
-
-    iteratorProto->as<PropertyIteratorObject>().setNativeIterator(ni);
-    ni->init(nullptr, nullptr, 0 /* flags */, 0, 0);
-
-    Rooted<JSFunction*> ctor(cx);
-    ctor = GlobalObject::createConstructor(cx, IteratorConstructor, cx->names().Iterator, 2);
-    if (!ctor)
-        return nullptr;
-    if (!LinkConstructorAndPrototype(cx, ctor, iteratorProto))
-        return nullptr;
-    if (!DefinePropertiesAndFunctions(cx, iteratorProto, nullptr, legacy_iterator_methods))
-        return nullptr;
-    if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Iterator,
-                                              ctor, iteratorProto))
-    {
-        return nullptr;
-    }
-
-    return &global->getPrototype(JSProto_Iterator).toObject();
-}
-
-JSObject*
 js::InitStopIterationClass(JSContext* cx, HandleObject obj)
 {
     Handle<GlobalObject*> global = obj.as<GlobalObject>();
     if (!global->getPrototype(JSProto_StopIteration).isObject()) {
         RootedObject proto(cx, GlobalObject::createBlankPrototype(cx, global,
                                                                   &StopIterationObject::class_));
         if (!proto || !FreezeObject(cx, proto))
             return nullptr;
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -189,19 +189,16 @@ bool
 UnwindIteratorForException(JSContext* cx, HandleObject obj);
 
 bool
 IteratorCloseForException(JSContext* cx, HandleObject obj);
 
 void
 UnwindIteratorForUncatchableException(JSContext* cx, JSObject* obj);
 
-bool
-IteratorConstructor(JSContext* cx, unsigned argc, Value* vp);
-
 extern bool
 SuppressDeletedProperty(JSContext* cx, HandleObject obj, jsid id);
 
 extern bool
 SuppressDeletedElement(JSContext* cx, HandleObject obj, uint32_t index);
 
 /*
  * IteratorMore() returns the next iteration value. If no value is available,
@@ -215,19 +212,16 @@ 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);
 
-extern JSObject*
-InitLegacyIteratorClass(JSContext* cx, HandleObject obj);
-
 bool
 IsLegacyIterator(HandleValue v);
 
 extern JSObject*
 InitStopIterationClass(JSContext* cx, HandleObject obj);
 
 enum class IteratorKind { Sync, Async };
 
--- a/js/src/jsprototypes.h
+++ b/js/src/jsprototypes.h
@@ -79,17 +79,17 @@
     real(ReferenceError,        InitViaClassSpec,       ERROR_CLASP(JSEXN_REFERENCEERR)) \
     real(SyntaxError,           InitViaClassSpec,       ERROR_CLASP(JSEXN_SYNTAXERR)) \
     real(TypeError,             InitViaClassSpec,       ERROR_CLASP(JSEXN_TYPEERR)) \
     real(URIError,              InitViaClassSpec,       ERROR_CLASP(JSEXN_URIERR)) \
     real(DebuggeeWouldRun,      InitViaClassSpec,       ERROR_CLASP(JSEXN_DEBUGGEEWOULDRUN)) \
     real(CompileError,          InitViaClassSpec,       ERROR_CLASP(JSEXN_WASMCOMPILEERROR)) \
     real(LinkError,             InitViaClassSpec,       ERROR_CLASP(JSEXN_WASMLINKERROR)) \
     real(RuntimeError,          InitViaClassSpec,       ERROR_CLASP(JSEXN_WASMRUNTIMEERROR)) \
-    real(Iterator,              InitLegacyIteratorClass,OCLASP(PropertyIterator)) \
+    imaginary(Iterator,         dummy,                  dummy) \
     real(StopIteration,         InitStopIterationClass, OCLASP(StopIteration)) \
     real(ArrayBuffer,           InitViaClassSpec,       OCLASP(ArrayBuffer)) \
     real(Int8Array,             InitViaClassSpec,       TYPED_ARRAY_CLASP(Int8)) \
     real(Uint8Array,            InitViaClassSpec,       TYPED_ARRAY_CLASP(Uint8)) \
     real(Int16Array,            InitViaClassSpec,       TYPED_ARRAY_CLASP(Int16)) \
     real(Uint16Array,           InitViaClassSpec,       TYPED_ARRAY_CLASP(Uint16)) \
     real(Int32Array,            InitViaClassSpec,       TYPED_ARRAY_CLASP(Int32)) \
     real(Uint32Array,           InitViaClassSpec,       TYPED_ARRAY_CLASP(Uint32)) \
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -434,20 +434,16 @@ class GlobalObject : public NativeObject
     // Get the type descriptor for one of the SIMD types.
     // simdType is one of the JS_SIMDTYPEREPR_* constants.
     // Implemented in builtin/SIMD.cpp.
     static SimdTypeDescr*
     getOrCreateSimdTypeDescr(JSContext* cx, Handle<GlobalObject*> global, SimdType simdType);
 
     TypedObjectModuleObject& getTypedObjectModule() const;
 
-    JSObject* getLegacyIteratorPrototype() {
-        return &getPrototype(JSProto_Iterator).toObject();
-    }
-
     static JSObject*
     getOrCreateCollatorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
         return getOrCreateObject(cx, global, COLLATOR_PROTO, initIntlObject);
     }
 
     static JSFunction*
     getOrCreateNumberFormatConstructor(JSContext* cx, Handle<GlobalObject*> global) {
         JSObject* obj = getOrCreateObject(cx, global, NUMBER_FORMAT, initIntlObject);
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -682,19 +682,16 @@ EnsureParserCreatedClasses(JSContext* cx
         return false; // needed by functions, also adds object literals' proto
 
     if (!EnsureConstructor(cx, global, JSProto_Array))
         return false; // needed by array literals
 
     if (!EnsureConstructor(cx, global, JSProto_RegExp))
         return false; // needed by regular expression literals
 
-    if (!EnsureConstructor(cx, global, JSProto_Iterator))
-        return false; // needed by ???
-
     if (!GlobalObject::initStarGenerators(cx, global))
         return false; // needed by function*() {} and generator comprehensions
 
     if (kind == ParseTaskKind::Module && !GlobalObject::ensureModulePrototypesCreated(cx, global))
         return false;
 
     return true;
 }
@@ -1792,18 +1789,17 @@ GlobalHelperThreadState::mergeParseTaskC
                 continue;
 
             JSObject* protoObj = proto.toObject();
 
             JSObject* newProto;
             JSProtoKey key = JS::IdentifyStandardPrototype(protoObj);
             if (key != JSProto_Null) {
                 MOZ_ASSERT(key == JSProto_Object || key == JSProto_Array ||
-                           key == JSProto_Function || key == JSProto_RegExp ||
-                           key == JSProto_Iterator);
+                           key == JSProto_Function || key == JSProto_RegExp);
                 newProto = GetBuiltinPrototypePure(global, key);
             } else if (protoObj == parseTaskStarGenFunctionProto) {
                 newProto = global->getStarGeneratorFunctionPrototype();
             } else if (protoObj == moduleProto) {
                 newProto = global->getModulePrototype();
             } else if (protoObj == importEntryProto) {
                 newProto = global->getImportEntryPrototype();
             } else if (protoObj == exportEntryProto) {