Bug 1083482 part 8 - Clean up more generator code. r=arai
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 02 Nov 2017 15:36:18 +0100
changeset 443102 2aa956f09d3e1ba236b8bc3f08cd9b1fcaacabe6
parent 443097 de37bff8b0337070fa89ff0f15f01a2e516eae0a
child 443103 a4852b85f1c60546f88f80eefedd00e2aeef672a
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1083482
milestone58.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 1083482 part 8 - Clean up more generator code. r=arai
js/src/builtin/ModuleObject.cpp
js/src/builtin/Object.cpp
js/src/builtin/ReflectParse.cpp
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/ParseContext.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/frontend/SharedContext.h
js/src/jit/Ion.cpp
js/src/jit/IonAnalysis.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/vm/Debugger.cpp
js/src/vm/EnvironmentObject.cpp
js/src/vm/GeneratorObject.cpp
js/src/vm/ObjectGroup.cpp
js/src/vm/Probes-inl.h
js/src/vm/SelfHosting.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/wasm/AsmJS.cpp
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -1066,21 +1066,20 @@ ModuleObject::instantiateFunctionDeclara
 
     for (const auto& funDecl : *funDecls) {
         fun = funDecl.fun;
         obj = Lambda(cx, fun, env);
         if (!obj)
             return false;
 
         if (fun->isAsync()) {
-            if (fun->isStarGenerator()) {
+            if (fun->isGenerator())
                 obj = WrapAsyncGenerator(cx, obj.as<JSFunction>());
-            } else {
+            else
                 obj = WrapAsyncFunction(cx, obj.as<JSFunction>());
-            }
         }
 
         if (!obj)
             return false;
 
         value = ObjectValue(*obj);
         if (!SetProperty(cx, env, funDecl.name->asPropertyName(), value))
             return false;
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -350,17 +350,17 @@ js::ObjectToSource(JSContext* cx, Handle
                 if (!buf.append("set "))
                     return false;
             } else if (kind == PropertyKind::Method && fun) {
                 if (IsWrappedAsyncFunction(fun)) {
                     if (!buf.append("async "))
                         return false;
                 }
 
-                if (fun->isStarGenerator()) {
+                if (fun->isGenerator()) {
                     if (!buf.append('*'))
                         return false;
                 }
             }
         }
 
         bool needsBracket = JSID_IS_SYMBOL(id);
         if (needsBracket && !buf.append('['))
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -3422,17 +3422,17 @@ ASTSerializer::identifier(ParseNode* pn,
 }
 
 bool
 ASTSerializer::function(ParseNode* pn, ASTType type, MutableHandleValue dst)
 {
     RootedFunction func(cx, pn->pn_funbox->function());
 
     GeneratorStyle generatorStyle =
-        pn->pn_funbox->isStarGenerator()
+        pn->pn_funbox->isGenerator()
         ? GeneratorStyle::ES6
         : GeneratorStyle::None;
 
     bool isAsync = pn->pn_funbox->isAsync();
     bool isExpression = pn->pn_funbox->isExprBody();
 
     RootedValue id(cx);
     RootedAtom funcAtom(cx, func->explicitName());
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -725,46 +725,50 @@ frontend::CompileStandaloneFunction(JSCo
                                     const Maybe<uint32_t>& parameterListEnd,
                                     HandleScope enclosingScope /* = nullptr */)
 {
     RootedScope scope(cx, enclosingScope);
     if (!scope)
         scope = &cx->global()->emptyGlobalScope();
 
     BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, scope);
-    return compiler.compileStandaloneFunction(fun, NotGenerator, SyncFunction, parameterListEnd);
+    return compiler.compileStandaloneFunction(fun, GeneratorKind::NotGenerator, SyncFunction,
+                                              parameterListEnd);
 }
 
 bool
 frontend::CompileStandaloneGenerator(JSContext* cx, MutableHandleFunction fun,
                                      const ReadOnlyCompileOptions& options,
                                      JS::SourceBufferHolder& srcBuf,
                                      const Maybe<uint32_t>& parameterListEnd)
 {
     RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
 
     BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope);
-    return compiler.compileStandaloneFunction(fun, StarGenerator, SyncFunction, parameterListEnd);
+    return compiler.compileStandaloneFunction(fun, GeneratorKind::Generator, SyncFunction,
+                                              parameterListEnd);
 }
 
 bool
 frontend::CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fun,
                                          const ReadOnlyCompileOptions& options,
                                          JS::SourceBufferHolder& srcBuf,
                                          const Maybe<uint32_t>& parameterListEnd)
 {
     RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
 
     BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope);
-    return compiler.compileStandaloneFunction(fun, NotGenerator, AsyncFunction, parameterListEnd);
+    return compiler.compileStandaloneFunction(fun, GeneratorKind::NotGenerator, AsyncFunction,
+                                              parameterListEnd);
 }
 
 bool
 frontend::CompileStandaloneAsyncGenerator(JSContext* cx, MutableHandleFunction fun,
                                           const ReadOnlyCompileOptions& options,
                                           JS::SourceBufferHolder& srcBuf,
                                           const Maybe<uint32_t>& parameterListEnd)
 {
     RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
 
     BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope);
-    return compiler.compileStandaloneFunction(fun, StarGenerator, AsyncFunction, parameterListEnd);
+    return compiler.compileStandaloneFunction(fun, GeneratorKind::Generator, AsyncFunction,
+                                              parameterListEnd);
 }
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -394,17 +394,17 @@ class BytecodeEmitter::EmitterScope : pu
         return true;
     }
 
     void updateFrameFixedSlots(BytecodeEmitter* bce, const BindingIter& bi) {
         nextFrameSlot_ = bi.nextFrameSlot();
         if (nextFrameSlot_ > bce->maxFixedSlots)
             bce->maxFixedSlots = nextFrameSlot_;
         MOZ_ASSERT_IF(bce->sc->isFunctionBox() &&
-                      (bce->sc->asFunctionBox()->isStarGenerator() ||
+                      (bce->sc->asFunctionBox()->isGenerator() ||
                        bce->sc->asFunctionBox()->isAsync()),
                       bce->maxFixedSlots == 0);
     }
 
     MOZ_MUST_USE bool putNameInCache(BytecodeEmitter* bce, JSAtom* name, NameLocation loc) {
         NameLocationMap& cache = *nameCache_;
         NameLocationMap::AddPtr p = cache.lookupForAdd(name);
         MOZ_ASSERT(!p);
@@ -4826,17 +4826,17 @@ BytecodeEmitter::isRunOnceLambda()
     if (!(parent && parent->emittingRunOnceLambda) &&
         (emitterMode != LazyFunction || !lazyScript->treatAsRunOnce()))
     {
         return false;
     }
 
     FunctionBox* funbox = sc->asFunctionBox();
     return !funbox->argumentsHasLocalBinding() &&
-           !funbox->isStarGenerator() &&
+           !funbox->isGenerator() &&
            !funbox->isAsync() &&
            !funbox->function()->explicitName();
 }
 
 bool
 BytecodeEmitter::emitYieldOp(JSOp op)
 {
     if (op == JSOP_FINALYIELDRVAL)
@@ -8234,17 +8234,17 @@ BytecodeEmitter::emitFunction(ParseNode*
 
     /* Non-hoisted functions simply emit their respective op. */
     if (!pn->functionIsHoisted()) {
         /* JSOP_LAMBDA_ARROW is always preceded by a new.target */
         MOZ_ASSERT(fun->isArrow() == (pn->getOp() == JSOP_LAMBDA_ARROW));
         if (funbox->isAsync()) {
             MOZ_ASSERT(!needsProto);
             return emitAsyncWrapper(index, funbox->needsHomeObject(), fun->isArrow(),
-                                    fun->isStarGenerator());
+                                    fun->isGenerator());
         }
 
         if (fun->isArrow()) {
             if (sc->allowNewTarget()) {
                 if (!emit1(JSOP_NEWTARGET))
                     return false;
             } else {
                 if (!emit1(JSOP_NULL))
@@ -8290,17 +8290,17 @@ BytecodeEmitter::emitFunction(ParseNode*
             if (!module->noteFunctionDeclaration(cx, name, fun))
                 return false;
         } else {
             MOZ_ASSERT(sc->isGlobalContext() || sc->isEvalContext());
             MOZ_ASSERT(pn->getOp() == JSOP_NOP);
             switchToPrologue();
             if (funbox->isAsync()) {
                 if (!emitAsyncWrapper(index, fun->isMethod(), fun->isArrow(),
-                                      fun->isStarGenerator()))
+                                      fun->isGenerator()))
                 {
                     return false;
                 }
             } else {
                 if (!emitIndex32(JSOP_LAMBDA, index))
                     return false;
             }
             if (!emit1(JSOP_DEFFUN))
@@ -8309,22 +8309,22 @@ BytecodeEmitter::emitFunction(ParseNode*
                 return false;
             switchToMain();
         }
     } else {
         // For functions nested within functions and blocks, make a lambda and
         // initialize the binding name of the function in the current scope.
 
         bool isAsync = funbox->isAsync();
-        bool isStarGenerator = funbox->isStarGenerator();
-        auto emitLambda = [index, isAsync, isStarGenerator](BytecodeEmitter* bce,
-                                                            const NameLocation&, bool) {
+        bool isGenerator = funbox->isGenerator();
+        auto emitLambda = [index, isAsync, isGenerator](BytecodeEmitter* bce,
+                                                        const NameLocation&, bool) {
             if (isAsync) {
                 return bce->emitAsyncWrapper(index, /* needsHomeObject = */ false,
-                                             /* isArrow = */ false, isStarGenerator);
+                                             /* isArrow = */ false, isGenerator);
             }
             return bce->emitIndexOp(JSOP_LAMBDA, index);
         };
 
         if (!emitInitializeName(name, emitLambda))
             return false;
         if (!emit1(JSOP_POP))
             return false;
@@ -8350,17 +8350,17 @@ BytecodeEmitter::emitAsyncWrapperLambda(
             return false;
     }
 
     return true;
 }
 
 bool
 BytecodeEmitter::emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow,
-                                  bool isStarGenerator)
+                                  bool isGenerator)
 {
     // needsHomeObject can be true for propertyList for extended class.
     // In that case push both unwrapped and wrapped function, in order to
     // initialize home object of unwrapped function, and set wrapped function
     // as a property.
     //
     //   lambda       // unwrapped
     //   dup          // unwrapped unwrapped
@@ -8382,17 +8382,17 @@ BytecodeEmitter::emitAsyncWrapper(unsign
     //
     // needsHomeObject is false for other cases, push wrapped function only.
     if (!emitAsyncWrapperLambda(index, isArrow))
         return false;
     if (needsHomeObject) {
         if (!emit1(JSOP_DUP))
             return false;
     }
-    if (isStarGenerator) {
+    if (isGenerator) {
         if (!emit1(JSOP_TOASYNCGEN))
             return false;
     } else {
         if (!emit1(JSOP_TOASYNC))
             return false;
     }
     return true;
 }
@@ -8636,17 +8636,17 @@ BytecodeEmitter::emitReturn(ParseNode* p
     }
 
     /* Push a return value */
     if (ParseNode* pn2 = pn->pn_kid) {
         if (!emitTree(pn2))
             return false;
 
         bool isAsyncGenerator = sc->asFunctionBox()->isAsync() &&
-                                sc->asFunctionBox()->isStarGenerator();
+                                sc->asFunctionBox()->isGenerator();
         if (isAsyncGenerator) {
             if (!emitAwait())
                 return false;
         }
     } else {
         /* No explicit return value provided */
         if (!emit1(JSOP_UNDEFINED))
             return false;
@@ -8800,17 +8800,17 @@ BytecodeEmitter::emitAwait(ParseNode* pn
         return false;
     return emitAwait();
 }
 
 bool
 BytecodeEmitter::emitYieldStar(ParseNode* iter)
 {
     MOZ_ASSERT(sc->isFunctionBox());
-    MOZ_ASSERT(sc->asFunctionBox()->isStarGenerator());
+    MOZ_ASSERT(sc->asFunctionBox()->isGenerator());
 
     bool isAsyncGenerator = sc->asFunctionBox()->isAsync();
 
     if (!emitTree(iter))                                  // ITERABLE
         return false;
     if (isAsyncGenerator) {
         if (!emitAsyncIterator())                         // ITER
             return false;
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -645,17 +645,17 @@ struct MOZ_STACK_CLASS BytecodeEmitter
     MOZ_MUST_USE bool emitAwait(ParseNode* pn);
 
     MOZ_MUST_USE bool emitPropLHS(ParseNode* pn);
     MOZ_MUST_USE bool emitPropOp(ParseNode* pn, JSOp op);
     MOZ_MUST_USE bool emitPropIncDec(ParseNode* pn);
 
     MOZ_MUST_USE bool emitAsyncWrapperLambda(unsigned index, bool isArrow);
     MOZ_MUST_USE bool emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow,
-                                       bool isStarGenerator);
+                                       bool isGenerator);
 
     MOZ_MUST_USE bool emitComputedPropertyName(ParseNode* computedPropName);
 
     // Emit bytecode to put operands for a JSOP_GETELEM/CALLELEM/SETELEM/DELELEM
     // opcode onto the stack in the right order. In the case of SETELEM, the
     // value to be assigned must already be pushed.
     enum class EmitElemOption { Get, Set, Call, IncDec, CompoundAssign, Ref };
     MOZ_MUST_USE bool emitElemOperands(ParseNode* pn, EmitElemOption opts);
--- a/js/src/frontend/ParseContext.h
+++ b/js/src/frontend/ParseContext.h
@@ -1,8 +1,14 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * 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/. */
+
 #ifndef frontend_ParseContext_h
 #define frontend_ParseContext_h
 
 #include "frontend/ErrorReporter.h"
 
 namespace js {
 
 namespace frontend {
@@ -617,29 +623,31 @@ class ParseContext : public Nestable<Par
     }
 
     bool useAsmOrInsideUseAsm() const {
         return sc_->isFunctionBox() && sc_->asFunctionBox()->useAsmOrInsideUseAsm();
     }
 
     // An ES6 generator is marked as a "star generator" before its body is parsed.
     GeneratorKind generatorKind() const {
-        return sc_->isFunctionBox() ? sc_->asFunctionBox()->generatorKind() : NotGenerator;
+        return sc_->isFunctionBox()
+               ? sc_->asFunctionBox()->generatorKind()
+               : GeneratorKind::NotGenerator;
     }
 
-    bool isStarGenerator() const {
-        return generatorKind() == StarGenerator;
+    bool isGenerator() const {
+        return generatorKind() == GeneratorKind::Generator;
     }
 
     bool isAsync() const {
         return sc_->isFunctionBox() && sc_->asFunctionBox()->isAsync();
     }
 
     bool needsDotGeneratorName() const {
-        return isStarGenerator() || isAsync();
+        return isGenerator() || isAsync();
     }
 
     FunctionAsyncKind asyncKind() const {
         return isAsync() ? AsyncFunction : SyncFunction;
     }
 
     bool isArrowFunction() const {
         return sc_->isFunctionBox() && sc_->asFunctionBox()->function()->isArrow();
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -461,17 +461,17 @@ FunctionBox::FunctionBox(JSContext* cx, 
     functionNode(nullptr),
     bufStart(0),
     bufEnd(0),
     startLine(1),
     startColumn(0),
     toStringStart(toStringStart),
     toStringEnd(0),
     length(0),
-    generatorKindBits_(GeneratorKindAsBits(generatorKind)),
+    generatorKind_(GeneratorKindAsBit(generatorKind)),
     asyncKindBits_(AsyncKindAsBits(asyncKind)),
     isGenexpLambda(false),
     hasDestructuringArgs(false),
     hasParameterExprs(false),
     hasDirectEvalInParameterExpr(false),
     hasDuplicateParameters(false),
     useAsm(false),
     insideUseAsm(false),
@@ -2510,17 +2510,17 @@ Parser<SyntaxParseHandler, char16_t>::fi
 
     fun->initLazyScript(lazy);
     return true;
 }
 
 static YieldHandling
 GetYieldHandling(GeneratorKind generatorKind)
 {
-    if (generatorKind == NotGenerator)
+    if (generatorKind == GeneratorKind::NotGenerator)
         return YieldIsName;
     return YieldIsKeyword;
 }
 
 static AwaitHandling
 GetAwaitHandling(FunctionAsyncKind asyncKind)
 {
     if (asyncKind == SyncFunction)
@@ -2548,17 +2548,17 @@ Parser<FullParseHandler, char16_t>::stan
         MOZ_ASSERT(tt == TOK_ASYNC);
         if (!tokenStream.getToken(&tt, TokenStream::Operand))
             return null();
     }
     MOZ_ASSERT(tt == TOK_FUNCTION);
 
     if (!tokenStream.getToken(&tt))
         return null();
-    if (generatorKind == StarGenerator) {
+    if (generatorKind == GeneratorKind::Generator) {
         MOZ_ASSERT(tt == TOK_MUL);
         if (!tokenStream.getToken(&tt))
             return null();
     }
 
     // Skip function name, if present.
     if (TokenKindIsPossibleIdentifierName(tt)) {
         MOZ_ASSERT(tokenStream.currentName() == fun->explicitName());
@@ -2740,21 +2740,21 @@ Parser<ParseHandler, CharT>::functionBod
 
         if (pc->isAsync()) {
             handler.addStatementToList(stmtList, pn);
             pn = stmtList;
         }
     }
 
     switch (pc->generatorKind()) {
-      case NotGenerator:
+      case GeneratorKind::NotGenerator:
         MOZ_ASSERT_IF(!pc->isAsync(), pc->lastYieldOffset == startYieldOffset);
         break;
 
-      case StarGenerator:
+      case GeneratorKind::Generator:
         MOZ_ASSERT(kind != Arrow);
         MOZ_ASSERT(type == StatementListBody);
         break;
     }
 
     if (pc->needsDotGeneratorName()) {
         MOZ_ASSERT_IF(!pc->isAsync(), type == StatementListBody);
         if (!declareDotGeneratorName())
@@ -2790,27 +2790,26 @@ ParserBase::newFunction(HandleAtom atom,
 
     gc::AllocKind allocKind = gc::AllocKind::FUNCTION;
     JSFunction::Flags flags;
 #ifdef DEBUG
     bool isGlobalSelfHostedBuiltin = false;
 #endif
     switch (kind) {
       case Expression:
-        flags = (generatorKind == NotGenerator && asyncKind == SyncFunction
+        flags = (generatorKind == GeneratorKind::NotGenerator && asyncKind == SyncFunction
                  ? JSFunction::INTERPRETED_LAMBDA
                  : JSFunction::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
         break;
       case Arrow:
         flags = JSFunction::INTERPRETED_LAMBDA_ARROW;
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         break;
       case Method:
-        MOZ_ASSERT(generatorKind == NotGenerator || generatorKind == StarGenerator);
-        flags = (generatorKind == NotGenerator && asyncKind == SyncFunction
+        flags = (generatorKind == GeneratorKind::NotGenerator && asyncKind == SyncFunction
                  ? JSFunction::INTERPRETED_METHOD
                  : JSFunction::INTERPRETED_METHOD_GENERATOR_OR_ASYNC);
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         break;
       case ClassConstructor:
       case DerivedClassConstructor:
         flags = JSFunction::INTERPRETED_CLASS_CONSTRUCTOR;
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
@@ -2828,17 +2827,17 @@ ParserBase::newFunction(HandleAtom atom,
       default:
         MOZ_ASSERT(kind == Statement);
 #ifdef DEBUG
         if (options().selfHostingMode && !pc->isFunctionBox()) {
             isGlobalSelfHostedBuiltin = true;
             allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         }
 #endif
-        flags = (generatorKind == NotGenerator && asyncKind == SyncFunction
+        flags = (generatorKind == GeneratorKind::NotGenerator && asyncKind == SyncFunction
                  ? JSFunction::INTERPRETED_NORMAL
                  : JSFunction::INTERPRETED_GENERATOR_OR_ASYNC);
     }
 
     // We store the async wrapper in a slot for later access.
     if (asyncKind == AsyncFunction)
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
 
@@ -3357,17 +3356,17 @@ Parser<ParseHandler, CharT>::functionDef
     // source extents are recorded and may be skipped.
     if (handler.canSkipLazyInnerFunctions()) {
         if (!skipLazyInnerFunction(pn, toStringStart, kind, tryAnnexB))
             return null();
         return pn;
     }
 
     RootedObject proto(context);
-    if (generatorKind == StarGenerator || asyncKind == AsyncFunction) {
+    if (generatorKind == GeneratorKind::Generator || asyncKind == AsyncFunction) {
         // If we are off thread, the generator meta-objects have
         // already been created by js::StartOffThreadParseTask, so cx will not
         // be necessary.
         JSContext* cx = context->helperThread() ? nullptr : context;
         proto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, context->global());
         if (!proto)
             return null();
     }
@@ -3429,18 +3428,22 @@ Parser<FullParseHandler, char16_t>::tryS
                                                                 Directives* newDirectives)
 {
     // Try a syntax parse for this inner function.
     do {
         // If we're assuming this function is an IIFE, always perform a full
         // parse to avoid the overhead of a lazy syntax-only parse. Although
         // the prediction may be incorrect, IIFEs are common enough that it
         // pays off for lots of code.
-        if (pn->isLikelyIIFE() && generatorKind == NotGenerator && asyncKind == SyncFunction)
+        if (pn->isLikelyIIFE() &&
+            generatorKind == GeneratorKind::NotGenerator &&
+            asyncKind == SyncFunction)
+        {
             break;
+        }
 
         if (!syntaxParser_)
             break;
 
         UsedNameTracker::RewindToken token = usedNames.getRewindToken();
 
         // Move the syntax parser to the current position in the stream.
         TokenStream::Position position(keepAtoms);
@@ -3707,17 +3710,17 @@ Parser<ParseHandler, CharT>::functionFor
     // Parse the function body.
     FunctionBodyType bodyType = StatementListBody;
     TokenKind tt;
     if (!tokenStream.getToken(&tt, TokenStream::Operand))
         return false;
     uint32_t openedPos = 0;
     if (tt != TOK_LC) {
         if (kind != Arrow) {
-            if (funbox->isStarGenerator() || funbox->isAsync() || kind == Method ||
+            if (funbox->isGenerator() || funbox->isAsync() || kind == Method ||
                 kind == GetterNoExpressionClosure || kind == SetterNoExpressionClosure ||
                 IsConstructorKind(kind))
             {
                 error(JSMSG_CURLY_BEFORE_BODY);
                 return false;
             }
 
 #if JS_HAS_EXPR_CLOSURES
@@ -3836,19 +3839,19 @@ Parser<ParseHandler, CharT>::functionStm
             return null();
         }
     }
 
     TokenKind tt;
     if (!tokenStream.getToken(&tt))
         return null();
 
-    GeneratorKind generatorKind = NotGenerator;
+    GeneratorKind generatorKind = GeneratorKind::NotGenerator;
     if (tt == TOK_MUL) {
-        generatorKind = StarGenerator;
+        generatorKind = GeneratorKind::Generator;
         if (!tokenStream.getToken(&tt))
             return null();
     }
 
     RootedPropertyName name(context);
     if (TokenKindIsPossibleIdentifier(tt)) {
         name = bindingIdentifier(yieldHandling);
         if (!name)
@@ -3863,19 +3866,21 @@ Parser<ParseHandler, CharT>::functionStm
     }
 
     // Note the declared name and check for early errors.
     DeclarationKind kind;
     if (declaredInStmt) {
         MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
         MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
 
-        kind = !pc->sc()->strict() && generatorKind == NotGenerator && asyncKind == SyncFunction
-               ? DeclarationKind::SloppyLexicalFunction
-               : DeclarationKind::LexicalFunction;
+        kind = (!pc->sc()->strict() &&
+                generatorKind == GeneratorKind::NotGenerator &&
+                asyncKind == SyncFunction)
+                ? DeclarationKind::SloppyLexicalFunction
+                : DeclarationKind::LexicalFunction;
     } else {
         kind = pc->atModuleLevel()
                ? DeclarationKind::ModuleBodyLevelFunction
                : DeclarationKind::BodyLevelFunction;
     }
 
     if (!noteDeclaredName(name, kind, pos()))
         return null();
@@ -3901,23 +3906,23 @@ Parser<ParseHandler, CharT>::functionStm
 template <class ParseHandler, typename CharT>
 typename ParseHandler::Node
 Parser<ParseHandler, CharT>::functionExpr(uint32_t toStringStart, InvokedPrediction invoked,
                                           FunctionAsyncKind asyncKind)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
 
     AutoAwaitIsKeyword<Parser> awaitIsKeyword(this, GetAwaitHandling(asyncKind));
-    GeneratorKind generatorKind = NotGenerator;
+    GeneratorKind generatorKind = GeneratorKind::NotGenerator;
     TokenKind tt;
     if (!tokenStream.getToken(&tt))
         return null();
 
     if (tt == TOK_MUL) {
-        generatorKind = StarGenerator;
+        generatorKind = GeneratorKind::Generator;
         if (!tokenStream.getToken(&tt))
             return null();
     }
 
     YieldHandling yieldHandling = GetYieldHandling(generatorKind);
 
     RootedPropertyName name(context);
     if (TokenKindIsPossibleIdentifier(tt)) {
@@ -6576,66 +6581,58 @@ Parser<ParseHandler, CharT>::returnState
 
 template <class ParseHandler, typename CharT>
 typename ParseHandler::Node
 Parser<ParseHandler, CharT>::yieldExpression(InHandling inHandling)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_YIELD));
     uint32_t begin = pos().begin;
 
-    switch (pc->generatorKind()) {
-      case StarGenerator:
-      {
-        MOZ_ASSERT(pc->isFunctionBox());
-
-        pc->lastYieldOffset = begin;
-
-        Node exprNode;
-        ParseNodeKind kind = PNK_YIELD;
-        TokenKind tt = TOK_EOF;
-        if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
-            return null();
-        switch (tt) {
-          // TOK_EOL is special; it implements the [no LineTerminator here]
-          // quirk in the grammar.
-          case TOK_EOL:
-          // The rest of these make up the complete set of tokens that can
-          // appear after any of the places where AssignmentExpression is used
-          // throughout the grammar.  Conveniently, none of them can also be the
-          // start an expression.
-          case TOK_EOF:
-          case TOK_SEMI:
-          case TOK_RC:
-          case TOK_RB:
-          case TOK_RP:
-          case TOK_COLON:
-          case TOK_COMMA:
-          case TOK_IN:
-            // No value.
-            exprNode = null();
-            tokenStream.addModifierException(TokenStream::NoneIsOperand);
-            break;
-          case TOK_MUL:
-            kind = PNK_YIELD_STAR;
-            tokenStream.consumeKnownToken(TOK_MUL, TokenStream::Operand);
-            MOZ_FALLTHROUGH;
-          default:
-            exprNode = assignExpr(inHandling, YieldIsKeyword, TripledotProhibited);
-            if (!exprNode)
-                return null();
-        }
-        if (kind == PNK_YIELD_STAR)
-            return handler.newYieldStarExpression(begin, exprNode);
-        return handler.newYieldExpression(begin, exprNode);
-      }
-      case NotGenerator:
+    MOZ_ASSERT(pc->isGenerator());
+    MOZ_ASSERT(pc->isFunctionBox());
+
+    pc->lastYieldOffset = begin;
+
+    Node exprNode;
+    ParseNodeKind kind = PNK_YIELD;
+    TokenKind tt = TOK_EOF;
+    if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
+        return null();
+    switch (tt) {
+      // TOK_EOL is special; it implements the [no LineTerminator here]
+      // quirk in the grammar.
+      case TOK_EOL:
+      // The rest of these make up the complete set of tokens that can
+      // appear after any of the places where AssignmentExpression is used
+      // throughout the grammar.  Conveniently, none of them can also be the
+      // start an expression.
+      case TOK_EOF:
+      case TOK_SEMI:
+      case TOK_RC:
+      case TOK_RB:
+      case TOK_RP:
+      case TOK_COLON:
+      case TOK_COMMA:
+      case TOK_IN:
+        // No value.
+        exprNode = null();
+        tokenStream.addModifierException(TokenStream::NoneIsOperand);
         break;
-    }
-
-    MOZ_CRASH("yieldExpr");
+      case TOK_MUL:
+        kind = PNK_YIELD_STAR;
+        tokenStream.consumeKnownToken(TOK_MUL, TokenStream::Operand);
+        MOZ_FALLTHROUGH;
+      default:
+        exprNode = assignExpr(inHandling, YieldIsKeyword, TripledotProhibited);
+        if (!exprNode)
+            return null();
+    }
+    if (kind == PNK_YIELD_STAR)
+        return handler.newYieldStarExpression(begin, exprNode);
+    return handler.newYieldExpression(begin, exprNode);
 }
 
 template <class ParseHandler, typename CharT>
 typename ParseHandler::Node
 Parser<ParseHandler, CharT>::withStatement(YieldHandling yieldHandling)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_WITH));
     uint32_t begin = pos().begin;
@@ -8109,17 +8106,17 @@ Parser<ParseHandler, CharT>::assignExpr(
                 tokenStream.ungetToken();
         }
 
         Node pn = handler.newArrowFunction(pos());
         if (!pn)
             return null();
 
         return functionDefinition(pn, toStringStart, inHandling, yieldHandling, nullptr,
-                                  Arrow, NotGenerator, asyncKind);
+                                  Arrow, GeneratorKind::NotGenerator, asyncKind);
       }
 
       default:
         MOZ_ASSERT(!tokenStream.isCurrentTokenAssignment());
         if (!possibleError) {
             if (!possibleErrorInner.checkForExpressionError())
                 return null();
         } else {
@@ -8384,24 +8381,24 @@ Parser<ParseHandler, CharT>::generatorCo
     // be necessary.
     RootedObject proto(context);
     JSContext* cx = context->helperThread() ? nullptr : context;
     proto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, context->global());
     if (!proto)
         return null();
 
     RootedFunction fun(context, newFunction(/* atom = */ nullptr, Expression,
-                                            StarGenerator, SyncFunction, proto));
+                                            GeneratorKind::Generator, SyncFunction, proto));
     if (!fun)
         return null();
 
     // Create box for fun->object early to root it.
     Directives directives(/* strict = */ outerpc->sc()->strict());
     FunctionBox* genFunbox = newFunctionBox(genfn, fun, /* toStringStart = */ begin, directives,
-                                            StarGenerator, SyncFunction);
+                                            GeneratorKind::Generator, SyncFunction);
     if (!genFunbox)
         return null();
     genFunbox->isGenexpLambda = true;
     genFunbox->initWithEnclosingParseContext(outerpc, Expression);
     genFunbox->setStart(tokenStream, begin);
 
     SourceParseContext genpc(this, genFunbox, /* newDirectives = */ nullptr);
     if (!genpc.init())
@@ -8418,17 +8415,17 @@ Parser<ParseHandler, CharT>::generatorCo
 
     if (!declareDotGeneratorName())
         return null();
 
     Node body = handler.newStatementList(TokenPos(begin, pos().end));
     if (!body)
         return null();
 
-    Node comp = comprehension(StarGenerator);
+    Node comp = comprehension(GeneratorKind::Generator);
     if (!comp)
         return null();
 
     MUST_MATCH_TOKEN_MOD(TOK_RP, TokenStream::Operand, JSMSG_PAREN_IN_PAREN);
 
     uint32_t end = pos().end;
     handler.setBeginPosition(comp, begin);
     handler.setEndPosition(comp, end);
@@ -8579,20 +8576,20 @@ Parser<ParseHandler, CharT>::comprehensi
         return comprehensionIf(comprehensionKind);
 
     uint32_t begin = pos().begin;
 
     Node bodyExpr = assignExpr(InAllowed, YieldIsKeyword, TripledotProhibited);
     if (!bodyExpr)
         return null();
 
-    if (comprehensionKind == NotGenerator)
+    if (comprehensionKind == GeneratorKind::NotGenerator)
         return handler.newArrayPush(begin, bodyExpr);
 
-    MOZ_ASSERT(comprehensionKind == StarGenerator);
+    MOZ_ASSERT(comprehensionKind == GeneratorKind::Generator);
     Node yieldExpr = handler.newYieldExpression(begin, bodyExpr);
     if (!yieldExpr)
         return null();
     yieldExpr = handler.parenthesize(yieldExpr);
 
     return handler.newExprStatement(yieldExpr, pos().end);
 }
 
@@ -8605,29 +8602,29 @@ Parser<ParseHandler, CharT>::comprehensi
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FOR));
 
     uint32_t startYieldOffset = pc->lastYieldOffset;
 
     Node body = comprehensionFor(comprehensionKind);
     if (!body)
         return null();
 
-    if (comprehensionKind != NotGenerator && pc->lastYieldOffset != startYieldOffset) {
+    if (comprehensionKind == GeneratorKind::Generator && pc->lastYieldOffset != startYieldOffset) {
         errorAt(pc->lastYieldOffset, JSMSG_BAD_GENEXP_BODY, js_yield_str);
         return null();
     }
 
     return body;
 }
 
 template <class ParseHandler, typename CharT>
 typename ParseHandler::Node
 Parser<ParseHandler, CharT>::arrayComprehension(uint32_t begin)
 {
-    Node inner = comprehension(NotGenerator);
+    Node inner = comprehension(GeneratorKind::NotGenerator);
     if (!inner)
         return null();
 
     MUST_MATCH_TOKEN_MOD(TOK_RB, TokenStream::Operand, JSMSG_BRACKET_AFTER_ARRAY_COMPREHENSION);
 
     Node comp = handler.newList(PNK_ARRAYCOMP, inner);
     if (!comp)
         return null();
@@ -9909,18 +9906,18 @@ Parser<ParseHandler, CharT>::methodDefin
         break;
 
       default:
         MOZ_CRASH("unexpected property type");
     }
 
     GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
                                    propType == PropertyType::AsyncGeneratorMethod)
-                                  ? StarGenerator
-                                  : NotGenerator;
+                                  ? GeneratorKind::Generator
+                                  : GeneratorKind::NotGenerator;
 
     FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
                                    propType == PropertyType::AsyncGeneratorMethod)
                                   ? AsyncFunction
                                   : SyncFunction;
 
     YieldHandling yieldHandling = GetYieldHandling(generatorKind);
 
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -167,18 +167,18 @@ class ParserBase : public StrictModeGett
                UsedNameTracker& usedNames, LazyScript* lazyOuterFunction);
     ~ParserBase();
 
     const char* getFilename() const { return tokenStream.getFilename(); }
     JSVersion versionNumber() const { return tokenStream.versionNumber(); }
     TokenPos pos() const { return tokenStream.currentToken().pos; }
 
     // Determine whether |yield| is a valid name in the current context.
-    bool yieldExpressionsSupported() {
-        return pc->isStarGenerator();
+    bool yieldExpressionsSupported() const {
+        return pc->isGenerator();
     }
 
     virtual bool strictMode() { return pc->sc()->strict(); }
     bool setLocalStrictMode(bool strict) {
         MOZ_ASSERT(tokenStream.debugHasNoLookahead());
         return pc->sc()->setLocalStrictMode(strict);
     }
 
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -399,17 +399,17 @@ class FunctionBox : public ObjectBox, pu
     uint32_t        bufStart;
     uint32_t        bufEnd;
     uint32_t        startLine;
     uint32_t        startColumn;
     uint32_t        toStringStart;
     uint32_t        toStringEnd;
     uint16_t        length;
 
-    uint8_t         generatorKindBits_;     /* The GeneratorKind of this function. */
+    uint8_t         generatorKind_;         /* The GeneratorKind of this function. */
     uint8_t         asyncKindBits_;         /* The FunctionAsyncKind of this function. */
 
     bool            isGenexpLambda:1;       /* lambda from generator expression */
     bool            hasDestructuringArgs:1; /* parameter list contains destructuring expression */
     bool            hasParameterExprs:1;    /* parameter list contains expressions */
     bool            hasDirectEvalInParameterExpr:1; /* parameter list contains direct eval */
     bool            hasDuplicateParameters:1; /* parameter list contains duplicate names */
     bool            useAsm:1;               /* see useAsmOrInsideUseAsm */
@@ -463,17 +463,17 @@ class FunctionBox : public ObjectBox, pu
                       enclosingScope_ == function()->lazyScript()->enclosingScope());
         return enclosingScope_;
     }
 
     bool needsCallObjectRegardlessOfBindings() const {
         return hasExtensibleScope() ||
                needsHomeObject() ||
                isDerivedClassConstructor() ||
-               isStarGenerator() ||
+               isGenerator() ||
                isAsync();
     }
 
     bool hasExtraBodyVarScope() const {
         return hasParameterExprs &&
                (extraVarScopeBindings_ ||
                 needsExtraBodyVarEnvironmentRegardlessOfBindings());
     }
@@ -482,51 +482,43 @@ class FunctionBox : public ObjectBox, pu
         MOZ_ASSERT(hasParameterExprs);
         return hasExtensibleScope() || needsDotGeneratorName();
     }
 
     bool isLikelyConstructorWrapper() const {
         return usesArguments && usesApply && usesThis && !usesReturn;
     }
 
-    GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); }
-    bool isStarGenerator() const { return generatorKind() == StarGenerator; }
+    GeneratorKind generatorKind() const { return GeneratorKindFromBit(generatorKind_); }
+    bool isGenerator() const { return generatorKind() == GeneratorKind::Generator; }
     FunctionAsyncKind asyncKind() const { return AsyncKindFromBits(asyncKindBits_); }
 
     bool needsFinalYield() const {
-        return isStarGenerator() || isAsync();
+        return isGenerator() || isAsync();
     }
     bool needsDotGeneratorName() const {
-        return isStarGenerator() || isAsync();
+        return isGenerator() || isAsync();
     }
     bool needsIteratorResult() const {
-        return isStarGenerator();
+        return isGenerator();
     }
 
     bool isAsync() const { return asyncKind() == AsyncFunction; }
     bool isArrow() const { return function()->isArrow(); }
 
     bool hasRest() const { return hasRest_; }
     void setHasRest() {
         hasRest_ = true;
     }
 
     bool isExprBody() const { return isExprBody_; }
     void setIsExprBody() {
         isExprBody_ = true;
     }
 
-    void setGeneratorKind(GeneratorKind kind) {
-        // A generator kind can be set at initialization, or when "yield" is
-        // first seen.  In both cases the transition can only happen from
-        // NotGenerator.
-        MOZ_ASSERT(!isStarGenerator());
-        generatorKindBits_ = GeneratorKindAsBits(kind);
-    }
-
     bool hasExtensibleScope()        const { return funCxFlags.hasExtensibleScope; }
     bool hasThisBinding()            const { return funCxFlags.hasThisBinding; }
     bool argumentsHasLocalBinding()  const { return funCxFlags.argumentsHasLocalBinding; }
     bool definitelyNeedsArgsObj()    const { return funCxFlags.definitelyNeedsArgsObj; }
     bool needsHomeObject()           const { return funCxFlags.needsHomeObject; }
     bool isDerivedClassConstructor() const { return funCxFlags.isDerivedClassConstructor; }
     bool hasInnerFunctions()         const { return funCxFlags.hasInnerFunctions; }
 
@@ -616,16 +608,16 @@ SharedContext::asModuleContext()
 // and invalidate DebugScope proxies for unaliased locals in a generator
 // frame, as the generator frame will be copied out to the heap and released
 // only by GC.
 inline bool
 SharedContext::allBindingsClosedOver()
 {
     return bindingsAccessedDynamically() ||
            (isFunctionBox() &&
-            (asFunctionBox()->isStarGenerator() ||
+            (asFunctionBox()->isGenerator() ||
              asFunctionBox()->isAsync()));
 }
 
 } // namespace frontend
 } // namespace js
 
 #endif /* frontend_SharedContext_h */
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -2270,17 +2270,17 @@ IonCompile(JSContext* cx, JSScript* scri
     if (cx->isExceptionPending())
         return AbortReason::Error;
     return AbortReason::Disable;
 }
 
 static bool
 CheckFrame(JSContext* cx, BaselineFrame* frame)
 {
-    MOZ_ASSERT(!frame->script()->isStarGenerator());
+    MOZ_ASSERT(!frame->script()->isGenerator());
     MOZ_ASSERT(!frame->script()->isAsync());
     MOZ_ASSERT(!frame->isDebuggerEvalFrame());
     MOZ_ASSERT(!frame->isEvalFrame());
 
     // This check is to not overrun the stack.
     if (frame->isFunctionFrame()) {
         if (TooManyActualArguments(frame->numActualArgs())) {
             TrackAndSpewIonAbort(cx, frame->script(), "too many actual arguments");
@@ -2302,17 +2302,17 @@ CheckScript(JSContext* cx, JSScript* scr
     if (script->isForEval()) {
         // Eval frames are not yet supported. Supporting this will require new
         // logic in pushBailoutFrame to deal with linking prev.
         // Additionally, JSOP_DEFVAR support will require baking in isEvalFrame().
         TrackAndSpewIonAbort(cx, script, "eval script");
         return false;
     }
 
-    if (script->isStarGenerator()) {
+    if (script->isGenerator()) {
         TrackAndSpewIonAbort(cx, script, "generator script");
         return false;
     }
     if (script->isAsync()) {
         TrackAndSpewIonAbort(cx, script, "async script");
         return false;
     }
 
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -4411,17 +4411,17 @@ jit::AnalyzeArgumentsUsage(JSContext* cx
     script->setNeedsArgsObj(true);
 
     // Always construct arguments objects when in debug mode, for generator
     // scripts (generators can be suspended when speculation fails) or when
     // direct eval is present.
     //
     // FIXME: Don't build arguments for ES6 generator expressions.
     if (scriptArg->isDebuggee() ||
-        script->isStarGenerator() ||
+        script->isGenerator() ||
         script->isAsync() ||
         script->bindingsAccessedDynamically())
     {
         return true;
     }
 
     if (!jit::IsIonEnabled(cx))
         return true;
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -126,17 +126,17 @@ ThrowTypeErrorBehavior(JSContext* cx)
 static bool
 IsSloppyNormalFunction(JSFunction* fun)
 {
     // FunctionDeclaration or FunctionExpression in sloppy mode.
     if (fun->kind() == JSFunction::NormalFunction) {
         if (fun->isBuiltin() || fun->isBoundFunction())
             return false;
 
-        if (fun->isStarGenerator() || fun->isAsync())
+        if (fun->isGenerator() || fun->isAsync())
             return false;
 
         MOZ_ASSERT(fun->isInterpreted());
         return !fun->strict();
     }
 
     // Or asm.js function in sloppy mode.
     if (fun->kind() == JSFunction::AsmJS)
@@ -415,38 +415,38 @@ ResolveInterpretedFunctionPrototype(JSCo
     // Also assert that fun is not bound, per the ES5 15.3.4.5 ref above.
     MOZ_ASSERT_IF(!isAsyncGenerator, !IsInternalFunctionObject(*fun));
     MOZ_ASSERT(!fun->isBoundFunction());
 
     // Make the prototype object an instance of Object with the same parent as
     // the function object itself, unless the function is an ES6 generator.  In
     // that case, per the 15 July 2013 ES6 draft, section 15.19.3, its parent is
     // the GeneratorObjectPrototype singleton.
-    bool isStarGenerator = fun->isStarGenerator();
+    bool isGenerator = fun->isGenerator();
     Rooted<GlobalObject*> global(cx, &fun->global());
     RootedObject objProto(cx);
     if (isAsyncGenerator)
         objProto = GlobalObject::getOrCreateAsyncGeneratorPrototype(cx, global);
-    else if (isStarGenerator)
+    else if (isGenerator)
         objProto = GlobalObject::getOrCreateStarGeneratorObjectPrototype(cx, global);
     else
         objProto = GlobalObject::getOrCreateObjectPrototype(cx, global);
     if (!objProto)
         return false;
 
     RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, objProto,
                                                                      SingletonObject));
     if (!proto)
         return false;
 
     // Per ES5 13.2 the prototype's .constructor property is configurable,
     // non-enumerable, and writable.  However, per the 15 July 2013 ES6 draft,
     // section 15.19.3, the .prototype of a generator function does not link
     // back with a .constructor.
-    if (!isStarGenerator && !isAsyncGenerator) {
+    if (!isGenerator && !isAsyncGenerator) {
         RootedValue objVal(cx, ObjectValue(*fun));
         if (!DefineDataProperty(cx, proto, cx->names().constructor, objVal, 0))
             return false;
     }
 
     // Per ES5 15.3.5.2 a user-defined function's .prototype property is
     // initially non-configurable, non-enumerable, and writable.
     RootedValue protoVal(cx, ObjectValue(*proto));
@@ -472,17 +472,17 @@ JSFunction::needsPrototypeProperty()
      * Thus all of the following don't get a .prototype property:
      * - Methods (that are not class-constructors or generators)
      * - Arrow functions
      * - Function.prototype
      */
     if (isBuiltin())
         return IsWrappedAsyncGenerator(this);
 
-    return isConstructor() || isStarGenerator() || isAsync();
+    return isConstructor() || isGenerator() || isAsync();
 }
 
 static bool
 fun_mayResolve(const JSAtomState& names, jsid id, JSObject*)
 {
     if (!JSID_IS_ATOM(id))
         return false;
 
@@ -590,17 +590,17 @@ js::XDRInterpretedFunction(XDRState<mode
     if (mode == XDR_ENCODE) {
         fun = objp;
         if (!fun->isInterpreted())
             return xdr->fail(JS::TranscodeResult_Failure_NotInterpretedFun);
 
         if (fun->explicitName() || fun->hasCompileTimeName() || fun->hasGuessedAtom())
             firstword |= HasAtom;
 
-        if (fun->isStarGenerator() || fun->isAsync())
+        if (fun->isGenerator() || fun->isAsync())
             firstword |= HasStarGeneratorProto;
 
         if (fun->isInterpretedLazy()) {
             // Encode a lazy script.
             firstword |= IsLazy;
             lazy = fun->lazyScript();
         } else {
             // Encode the script.
@@ -1079,17 +1079,17 @@ js::FunctionToString(JSContext* cx, Hand
             if (!out.append("async "))
                 return nullptr;
         }
 
         if (!fun->isArrow()) {
             if (!out.append("function"))
                 return nullptr;
 
-            if (fun->isStarGenerator()) {
+            if (fun->isGenerator()) {
                 if (!out.append('*'))
                     return nullptr;
             }
         }
 
         if (fun->explicitName()) {
             if (!out.append(' '))
                 return nullptr;
@@ -1745,17 +1745,17 @@ fun_isGenerator(JSContext* cx, unsigned 
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     JSFunction* fun;
     if (!IsFunctionObject(args.thisv(), &fun)) {
         args.rval().setBoolean(false);
         return true;
     }
 
-    args.rval().setBoolean(fun->isStarGenerator());
+    args.rval().setBoolean(fun->isGenerator());
     return true;
 }
 
 const JSFunctionSpec js::function_methods[] = {
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str,   fun_toSource,   0,0),
 #endif
     JS_FN(js_toString_str,   fun_toString,   0,0),
@@ -1776,34 +1776,34 @@ CreateDynamicFunction(JSContext* cx, con
     // Steps 1-5.
     // Block this call if security callbacks forbid it.
     Rooted<GlobalObject*> global(cx, &args.callee().global());
     if (!GlobalObject::isRuntimeCodeGenEnabled(cx, global)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_FUNCTION);
         return false;
     }
 
-    bool isStarGenerator = generatorKind == StarGenerator;
+    bool isGenerator = generatorKind == GeneratorKind::Generator;
     bool isAsync = asyncKind == AsyncFunction;
 
     RootedScript maybeScript(cx);
     const char* filename;
     unsigned lineno;
     bool mutedErrors;
     uint32_t pcOffset;
     DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, &pcOffset,
                                          &mutedErrors);
 
     const char* introductionType = "Function";
     if (isAsync) {
-        if (isStarGenerator)
+        if (isGenerator)
             introductionType = "AsyncGenerator";
         else
             introductionType = "AsyncFunction";
-    } else if (generatorKind != NotGenerator) {
+    } else if (isGenerator) {
         introductionType = "GeneratorFunction";
     }
 
     const char* introducerFilename = filename;
     if (maybeScript && maybeScript->scriptSource()->introducerFilename())
         introducerFilename = maybeScript->scriptSource()->introducerFilename();
 
     CompileOptions options(cx);
@@ -1815,17 +1815,17 @@ CreateDynamicFunction(JSContext* cx, con
     StringBuffer sb(cx);
 
     if (isAsync) {
         if (!sb.append("async "))
             return false;
     }
     if (!sb.append("function"))
          return false;
-    if (isStarGenerator) {
+    if (isGenerator) {
         if (!sb.append('*'))
             return false;
     }
 
     if (!sb.append(" anonymous("))
         return false;
 
     if (args.length() > 1) {
@@ -1888,25 +1888,25 @@ CreateDynamicFunction(JSContext* cx, con
      */
     RootedAtom anonymousAtom(cx, cx->names().anonymous);
 
     // Initialize the function with the default prototype:
     // Leave as nullptr to get the default from clasp for normal functions.
     // Use %Generator% for generators and the unwrapped function of async
     // functions and async generators.
     RootedObject defaultProto(cx);
-    if (isStarGenerator || isAsync) {
+    if (isGenerator || isAsync) {
         defaultProto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, global);
         if (!defaultProto)
             return false;
     }
 
     // Step 30-37 (reordered).
     RootedObject globalLexical(cx, &global->lexicalEnvironment());
-    JSFunction::Flags flags = (isStarGenerator || isAsync)
+    JSFunction::Flags flags = (isGenerator || isAsync)
                               ? JSFunction::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC
                               : JSFunction::INTERPRETED_LAMBDA;
     AllocKind allocKind = isAsync ? AllocKind::FUNCTION_EXTENDED : AllocKind::FUNCTION;
     RootedFunction fun(cx, NewFunctionWithProto(cx, nullptr, 0,
                                                 flags, globalLexical,
                                                 anonymousAtom, defaultProto,
                                                 allocKind, TenuredObject));
     if (!fun)
@@ -1921,42 +1921,42 @@ CreateDynamicFunction(JSContext* cx, con
         return false;
 
     mozilla::Range<const char16_t> chars = stableChars.twoByteRange();
     SourceBufferHolder::Ownership ownership = stableChars.maybeGiveOwnershipToCaller()
                                               ? SourceBufferHolder::GiveOwnership
                                               : SourceBufferHolder::NoOwnership;
     SourceBufferHolder srcBuf(chars.begin().get(), chars.length(), ownership);
     if (isAsync) {
-        if (isStarGenerator) {
+        if (isGenerator) {
             if (!CompileStandaloneAsyncGenerator(cx, &fun, options, srcBuf, parameterListEnd))
                 return false;
         } else {
             if (!CompileStandaloneAsyncFunction(cx, &fun, options, srcBuf, parameterListEnd))
                 return false;
         }
     } else {
-        if (isStarGenerator) {
+        if (isGenerator) {
             if (!CompileStandaloneGenerator(cx, &fun, options, srcBuf, parameterListEnd))
                 return false;
         } else {
             if (!CompileStandaloneFunction(cx, &fun, options, srcBuf, parameterListEnd))
                 return false;
         }
     }
 
     // Steps 6, 29.
     RootedObject proto(cx);
     if (!GetPrototypeFromBuiltinConstructor(cx, args, &proto))
         return false;
 
     if (isAsync) {
         // Create the async function wrapper.
         JSObject* wrapped;
-        if (isStarGenerator) {
+        if (isGenerator) {
             wrapped = proto
                       ? WrapAsyncGeneratorWithProto(cx, fun, proto)
                       : WrapAsyncGenerator(cx, fun);
         } else {
             // Step 9.d, use %AsyncFunctionPrototype% as the fallback prototype.
             wrapped = proto
                       ? WrapAsyncFunctionWithProto(cx, fun, proto)
                       : WrapAsyncFunction(cx, fun);
@@ -1976,38 +1976,38 @@ CreateDynamicFunction(JSContext* cx, con
     args.rval().setObject(*fun);
     return true;
 }
 
 bool
 js::Function(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    return CreateDynamicFunction(cx, args, NotGenerator, SyncFunction);
+    return CreateDynamicFunction(cx, args, GeneratorKind::NotGenerator, SyncFunction);
 }
 
 bool
 js::Generator(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    return CreateDynamicFunction(cx, args, StarGenerator, SyncFunction);
+    return CreateDynamicFunction(cx, args, GeneratorKind::Generator, SyncFunction);
 }
 
 bool
 js::AsyncFunctionConstructor(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    return CreateDynamicFunction(cx, args, NotGenerator, AsyncFunction);
+    return CreateDynamicFunction(cx, args, GeneratorKind::NotGenerator, AsyncFunction);
 }
 
 bool
 js::AsyncGeneratorConstructor(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    return CreateDynamicFunction(cx, args, StarGenerator, AsyncFunction);
+    return CreateDynamicFunction(cx, args, GeneratorKind::Generator, AsyncFunction);
 }
 
 bool
 JSFunction::isBuiltinFunctionConstructor()
 {
     return maybeNative() == Function || maybeNative() == Generator;
 }
 
@@ -2140,17 +2140,17 @@ js::CanReuseScriptForClone(JSCompartment
     return fun->hasScript() && fun->nonLazyScript()->hasNonSyntacticScope();
 }
 
 static inline JSFunction*
 NewFunctionClone(JSContext* cx, HandleFunction fun, NewObjectKind newKind,
                  gc::AllocKind allocKind, HandleObject proto)
 {
     RootedObject cloneProto(cx, proto);
-    if (!proto && (fun->isStarGenerator() || fun->isAsync())) {
+    if (!proto && (fun->isGenerator() || fun->isAsync())) {
         cloneProto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, cx->global());
         if (!cloneProto)
             return nullptr;
     }
 
     JSObject* cloneobj = NewObjectWithClassProto(cx, &JSFunction::class_, cloneProto,
                                                  allocKind, newKind);
     if (!cloneobj)
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -144,17 +144,17 @@ class JSFunction : public js::NativeObje
         if (isNative())
             return false;
 
         // Note: this should be kept in sync with
         // FunctionBox::needsCallObjectRegardlessOfBindings().
         MOZ_ASSERT_IF(nonLazyScript()->funHasExtensibleScope() ||
                       nonLazyScript()->needsHomeObject()       ||
                       nonLazyScript()->isDerivedClassConstructor() ||
-                      isStarGenerator() ||
+                      isGenerator() ||
                       isAsync(),
                       nonLazyScript()->bodyScope()->hasEnvironment());
 
         return nonLazyScript()->bodyScope()->hasEnvironment();
     }
 
     bool needsExtraBodyVarEnvironment() const;
     bool needsNamedLambdaEnvironment() const;
@@ -505,26 +505,26 @@ class JSFunction : public js::NativeObje
 
     js::LazyScript* lazyScriptOrNull() const {
         MOZ_ASSERT(isInterpretedLazy());
         return u.i.s.lazy_;
     }
 
     js::GeneratorKind generatorKind() const {
         if (!isInterpreted())
-            return js::NotGenerator;
+            return js::GeneratorKind::NotGenerator;
         if (hasScript())
             return nonLazyScript()->generatorKind();
         if (js::LazyScript* lazy = lazyScriptOrNull())
             return lazy->generatorKind();
         MOZ_ASSERT(isSelfHostedBuiltin());
-        return js::NotGenerator;
+        return js::GeneratorKind::NotGenerator;
     }
 
-    bool isStarGenerator() const { return generatorKind() == js::StarGenerator; }
+    bool isGenerator() const { return generatorKind() == js::GeneratorKind::Generator; }
 
     js::FunctionAsyncKind asyncKind() const {
         return isInterpretedLazy() ? lazyScript()->asyncKind() : nonLazyScript()->asyncKind();
     }
 
     bool isAsync() const {
         if (isInterpretedLazy())
             return lazyScript()->isAsync();
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -336,17 +336,17 @@ js::XDRScript(XDRState<mode>* xdr, Handl
         FunHasExtensibleScope,
         FunHasAnyAliasedFormal,
         ArgumentsHasVarBinding,
         NeedsArgsObj,
         HasMappedArgsObj,
         FunctionHasThisBinding,
         FunctionHasExtraBodyVarScope,
         IsGeneratorExp,
-        IsStarGenerator,
+        IsGenerator,
         IsAsync,
         HasRest,
         IsExprBody,
         OwnSource,
         ExplicitUseStrict,
         SelfHosted,
         HasSingleton,
         TreatAsRunOnce,
@@ -451,18 +451,18 @@ js::XDRScript(XDRState<mode>* xdr, Handl
             scriptBits |= (1 << FunctionHasThisBinding);
         if (script->functionHasExtraBodyVarScope())
             scriptBits |= (1 << FunctionHasExtraBodyVarScope);
         MOZ_ASSERT_IF(sourceObjectArg, sourceObjectArg->source() == script->scriptSource());
         if (!sourceObjectArg)
             scriptBits |= (1 << OwnSource);
         if (script->isGeneratorExp())
             scriptBits |= (1 << IsGeneratorExp);
-        if (script->isStarGenerator())
-            scriptBits |= (1 << IsStarGenerator);
+        if (script->isGenerator())
+            scriptBits |= (1 << IsGenerator);
         if (script->asyncKind() == AsyncFunction)
             scriptBits |= (1 << IsAsync);
         if (script->hasRest())
             scriptBits |= (1 << HasRest);
         if (script->isExprBody())
             scriptBits |= (1 << IsExprBody);
         if (script->hasSingletons())
             scriptBits |= (1 << HasSingleton);
@@ -624,18 +624,18 @@ js::XDRScript(XDRState<mode>* xdr, Handl
         if (scriptBits & (1 << HasInnerFunctions))
             script->hasInnerFunctions_ = true;
         if (scriptBits & (1 << NeedsHomeObject))
             script->needsHomeObject_ = true;
         if (scriptBits & (1 << IsDerivedClassConstructor))
             script->isDerivedClassConstructor_ = true;
         if (scriptBits & (1 << IsDefaultClassConstructor))
             script->isDefaultClassConstructor_ = true;
-        if (scriptBits & (1 << IsStarGenerator))
-            script->setGeneratorKind(StarGenerator);
+        if (scriptBits & (1 << IsGenerator))
+            script->setGeneratorKind(GeneratorKind::Generator);
         if (scriptBits & (1 << IsAsync))
             script->setAsyncKind(AsyncFunction);
         if (scriptBits & (1 << HasRest))
             script->setHasRest();
         if (scriptBits & (1 << IsExprBody))
             script->setIsExprBody();
     }
 
@@ -2975,17 +2975,17 @@ JSScript::initFromModuleContext(JSContex
                                 frontend::ModuleSharedContext* modulesc)
 {
     script->funHasExtensibleScope_ = false;
     script->needsHomeObject_ = false;
     script->isDerivedClassConstructor_ = false;
     script->funLength_ = 0;
 
     script->isGeneratorExp_ = false;
-    script->setGeneratorKind(NotGenerator);
+    script->setGeneratorKind(GeneratorKind::NotGenerator);
 
     // Since modules are only run once, mark the script so that initializers
     // created within it may be given more precise types.
     script->setTreatAsRunOnce();
     MOZ_ASSERT(!script->hasRunOnce());
 }
 
 /* static */ bool
@@ -3451,17 +3451,17 @@ Rebase(JSScript* dst, JSScript* src, T* 
     return reinterpret_cast<T*>(dst->data + off);
 }
 
 static JSObject*
 CloneInnerInterpretedFunction(JSContext* cx, HandleScope enclosingScope, HandleFunction srcFun)
 {
     /* NB: Keep this in sync with XDRInterpretedFunction. */
     RootedObject cloneProto(cx);
-    if (srcFun->isStarGenerator() || srcFun->isAsync()) {
+    if (srcFun->isGenerator() || srcFun->isAsync()) {
         cloneProto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, cx->global());
         if (!cloneProto)
             return nullptr;
     }
 
     gc::AllocKind allocKind = srcFun->getAllocKind();
     uint16_t flags = srcFun->flags();
     if (srcFun->isSelfHostedBuiltin()) {
@@ -4191,17 +4191,17 @@ JSScript::argumentsOptimizationFailed(JS
      * everything has been fixed up, but there was an outstanding magic value
      * on the stack that has just now flowed into an apply. In this case, there
      * is nothing to do; GuardFunApplySpeculation will patch in the real
      * argsobj.
      */
     if (script->needsArgsObj())
         return true;
 
-    MOZ_ASSERT(!script->isStarGenerator());
+    MOZ_ASSERT(!script->isGenerator());
     MOZ_ASSERT(!script->isAsync());
 
     script->needsArgsObj_ = true;
 
     /*
      * Since we can't invalidate baseline scripts, set a flag that's checked from
      * JIT code to indicate the arguments optimization failed and JSOP_ARGUMENTS
      * should create an arguments object next time.
@@ -4380,17 +4380,17 @@ LazyScript::Create(JSContext* cx, Handle
     p.version = version;
     p.shouldDeclareArguments = false;
     p.hasThisBinding = false;
     p.isAsync = false;
     p.hasRest = false;
     p.isExprBody = false;
     p.numClosedOverBindings = closedOverBindings.length();
     p.numInnerFunctions = innerFunctions.length();
-    p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
+    p.generatorKind = GeneratorKindAsBit(GeneratorKind::NotGenerator);
     p.strict = false;
     p.bindingsAccessedDynamically = false;
     p.hasDebuggerStatement = false;
     p.hasDirectEval = false;
     p.isLikelyConstructorWrapper = false;
     p.isDerivedClassConstructor = false;
     p.needsHomeObject = false;
 
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -747,27 +747,29 @@ class ScriptSourceObject : public Native
   private:
     static const uint32_t SOURCE_SLOT = 0;
     static const uint32_t ELEMENT_SLOT = 1;
     static const uint32_t ELEMENT_PROPERTY_SLOT = 2;
     static const uint32_t INTRODUCTION_SCRIPT_SLOT = 3;
     static const uint32_t RESERVED_SLOTS = 4;
 };
 
-enum GeneratorKind { NotGenerator, StarGenerator };
+enum class GeneratorKind : bool { NotGenerator, Generator };
 enum FunctionAsyncKind { SyncFunction, AsyncFunction };
 
 static inline unsigned
-GeneratorKindAsBits(GeneratorKind generatorKind) {
+GeneratorKindAsBit(GeneratorKind generatorKind)
+{
     return static_cast<unsigned>(generatorKind);
 }
 
 static inline GeneratorKind
-GeneratorKindFromBits(unsigned val) {
-    MOZ_ASSERT(val <= StarGenerator);
+GeneratorKindFromBit(unsigned val)
+{
+    MOZ_ASSERT(val <= unsigned(GeneratorKind::Generator));
     return static_cast<GeneratorKind>(val);
 }
 
 static inline unsigned
 AsyncKindAsBits(FunctionAsyncKind asyncKind) {
     return static_cast<unsigned>(asyncKind);
 }
 
@@ -1028,17 +1030,17 @@ class JSScript : public js::gc::TenuredC
     };
 
   private:
     // The bits in this field indicate the presence/non-presence of several
     // optional arrays in |data|.  See the comments above Create() for details.
     uint8_t         hasArrayBits:ARRAY_KIND_BITS;
 
     // The GeneratorKind of the script.
-    uint8_t         generatorKindBits_:2;
+    uint8_t         generatorKind_:1;
 
     // 1-bit fields.
 
     // No need for result value of last expression statement.
     bool noScriptRval_:1;
 
     // Code is in strict mode.
     bool strict_:1;
@@ -1438,24 +1440,24 @@ class JSScript : public js::gc::TenuredC
         return argsHasVarBinding_;
     }
     void setArgumentsHasVarBinding();
     bool argumentsAliasesFormals() const {
         return argumentsHasVarBinding() && hasMappedArgsObj();
     }
 
     js::GeneratorKind generatorKind() const {
-        return js::GeneratorKindFromBits(generatorKindBits_);
+        return js::GeneratorKindFromBit(generatorKind_);
     }
-    bool isStarGenerator() const { return generatorKind() == js::StarGenerator; }
+    bool isGenerator() const { return generatorKind() == js::GeneratorKind::Generator; }
     void setGeneratorKind(js::GeneratorKind kind) {
         // A script only gets its generator kind set as part of initialization,
         // so it can only transition from not being a generator.
-        MOZ_ASSERT(!isStarGenerator());
-        generatorKindBits_ = GeneratorKindAsBits(kind);
+        MOZ_ASSERT(!isGenerator());
+        generatorKind_ = GeneratorKindAsBit(kind);
     }
 
     js::FunctionAsyncKind asyncKind() const {
         return isAsync_ ? js::AsyncFunction : js::SyncFunction;
     }
     bool isAsync() const {
         return isAsync_;
     }
@@ -1607,17 +1609,17 @@ class JSScript : public js::gc::TenuredC
         return baselineOrIonRaw;
     }
     static size_t offsetOfBaselineOrIonSkipArgCheck() {
         return offsetof(JSScript, baselineOrIonSkipArgCheck);
     }
 
     bool isRelazifiable() const {
         return (selfHosted() || lazyScript) && !hasInnerFunctions_ && !types_ &&
-               !isStarGenerator() && !isAsync() &&
+               !isGenerator() && !isAsync() &&
                !isDefaultClassConstructor() &&
                !hasBaselineScript() && !hasAnyIonScript() &&
                !doNotRelazify_;
     }
     void setLazyScript(js::LazyScript* lazy) {
         lazyScript = lazy;
     }
     js::LazyScript* maybeLazyScript() {
@@ -1829,17 +1831,17 @@ class JSScript : public js::gc::TenuredC
     void setHasArray(ArrayKind kind) { hasArrayBits |= (1 << kind); }
     void cloneHasArray(JSScript* script) { hasArrayBits = script->hasArrayBits; }
 
     bool hasConsts() const       { return hasArray(CONSTS); }
     bool hasObjects() const      { return hasArray(OBJECTS); }
     bool hasTrynotes() const     { return hasArray(TRYNOTES); }
     bool hasScopeNotes() const   { return hasArray(SCOPENOTES); }
     bool hasYieldAndAwaitOffsets() const {
-        return isStarGenerator() || isAsync();
+        return isGenerator() || isAsync();
     }
 
 #define OFF(fooOff, hasFoo, t)   (fooOff() + (hasFoo() ? sizeof(t) : 0))
 
     size_t scopesOffset() const       { return 0; }
     size_t constsOffset() const       { return scopesOffset() + sizeof(js::ScopeArray); }
     size_t objectsOffset() const      { return OFF(constsOffset,     hasConsts,     js::ConstArray); }
     size_t trynotesOffset() const     { return OFF(objectsOffset,    hasObjects,    js::ObjectArray); }
@@ -2124,17 +2126,17 @@ class LazyScript : public gc::TenuredCel
         uint32_t isExprBody : 1;
 
         uint32_t numClosedOverBindings : NumClosedOverBindingsBits;
 
         // -- 32bit boundary --
 
         uint32_t numInnerFunctions : NumInnerFunctionsBits;
 
-        uint32_t generatorKindBits : 2;
+        uint32_t generatorKind : 1;
 
         // N.B. These are booleans but need to be uint32_t to pack correctly on MSVC.
         // If you add another boolean here, make sure to initialze it in
         // LazyScript::CreateRaw().
         uint32_t strict : 1;
         uint32_t bindingsAccessedDynamically : 1;
         uint32_t hasDebuggerStatement : 1;
         uint32_t hasDirectEval : 1;
@@ -2248,25 +2250,25 @@ class LazyScript : public gc::TenuredCel
 
     uint32_t numInnerFunctions() const {
         return p_.numInnerFunctions;
     }
     GCPtrFunction* innerFunctions() {
         return (GCPtrFunction*)&closedOverBindings()[numClosedOverBindings()];
     }
 
-    GeneratorKind generatorKind() const { return GeneratorKindFromBits(p_.generatorKindBits); }
-
-    bool isStarGenerator() const { return generatorKind() == StarGenerator; }
+    GeneratorKind generatorKind() const { return GeneratorKindFromBit(p_.generatorKind); }
+
+    bool isGenerator() const { return generatorKind() == GeneratorKind::Generator; }
 
     void setGeneratorKind(GeneratorKind kind) {
         // A script only gets its generator kind set as part of initialization,
         // so it can only transition from NotGenerator.
-        MOZ_ASSERT(!isStarGenerator());
-        p_.generatorKindBits = GeneratorKindAsBits(kind);
+        MOZ_ASSERT(!isGenerator());
+        p_.generatorKind = GeneratorKindAsBit(kind);
     }
 
     FunctionAsyncKind asyncKind() const {
         return p_.isAsync ? AsyncFunction : SyncFunction;
     }
     bool isAsync() const {
         return p_.isAsync;
     }
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1587,17 +1587,17 @@ static bool
 CheckResumptionValue(JSContext* cx, AbstractFramePtr frame, const Maybe<HandleValue>& maybeThisv,
                      JSTrapStatus status, MutableHandleValue vp)
 {
     if (status == JSTRAP_RETURN && frame && frame.isFunctionFrame()) {
         // Don't let a { return: ... } resumption value make a generator
         // function violate the iterator protocol. The return value from
         // such a frame must have the form { done: <bool>, value: <anything> }.
         RootedFunction callee(cx, frame.callee());
-        if (callee->isStarGenerator()) {
+        if (callee->isGenerator()) {
             if (!CheckStarGeneratorResumptionValue(cx, vp)) {
                 JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_YIELD);
                 return false;
             }
         }
     }
 
     if (maybeThisv.isSome()) {
@@ -5370,17 +5370,17 @@ DebuggerScript_checkThis(JSContext* cx, 
     if (!obj)                                                                       \
         return false;                                                               \
     RootedScript script(cx, GetScriptReferent(obj).as<JSScript*>())
 
 static bool
 DebuggerScript_getIsGeneratorFunction(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get isGeneratorFunction)", args, obj, script);
-    args.rval().setBoolean(script->isStarGenerator());
+    args.rval().setBoolean(script->isGenerator());
     return true;
 }
 
 static bool
 DebuggerScript_getIsAsyncFunction(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get isAsyncFunction)", args, obj, script);
     args.rval().setBoolean(script->isAsync());
@@ -7643,17 +7643,17 @@ DebuggerFrame::getEnvironment(JSContext*
 
     return dbg->wrapEnvironment(cx, env, result);
 }
 
 /* static */ bool
 DebuggerFrame::getIsGenerator(HandleDebuggerFrame frame)
 {
     AbstractFramePtr referent = DebuggerFrame::getReferent(frame);
-    return referent.hasScript() && referent.script()->isStarGenerator();
+    return referent.hasScript() && referent.script()->isGenerator();
 }
 
 /* static */ bool
 DebuggerFrame::getOffset(JSContext* cx, HandleDebuggerFrame frame, size_t& result)
 {
     MOZ_ASSERT(frame->isLive());
 
     Maybe<FrameIter> maybeIter;
@@ -9957,17 +9957,17 @@ DebuggerObject::isAsyncFunction() const
 }
 
 bool
 DebuggerObject::isGeneratorFunction() const
 {
     MOZ_ASSERT(isDebuggeeFunction());
 
     JSFunction* fun = RemoveAsyncWrapper(&referent()->as<JSFunction>());
-    return fun->isStarGenerator();
+    return fun->isGenerator();
 }
 
 bool
 DebuggerObject::isGlobal() const
 {
     return referent()->is<GlobalObject>();
 }
 
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -2593,17 +2593,17 @@ DebugEnvironments::hasDebugEnvironment(J
 /* static */ bool
 DebugEnvironments::addDebugEnvironment(JSContext* cx, const EnvironmentIter& ei,
                                        Handle<DebugEnvironmentProxy*> debugEnv)
 {
     MOZ_ASSERT(!ei.hasSyntacticEnvironment());
     MOZ_ASSERT(cx->compartment() == debugEnv->compartment());
     // Generators should always have environments.
     MOZ_ASSERT_IF(ei.scope().is<FunctionScope>(),
-                  !ei.scope().as<FunctionScope>().canonicalFunction()->isStarGenerator() &&
+                  !ei.scope().as<FunctionScope>().canonicalFunction()->isGenerator() &&
                   !ei.scope().as<FunctionScope>().canonicalFunction()->isAsync());
 
     if (!CanUseDebugEnvironmentMaps(cx))
         return true;
 
     DebugEnvironments* envs = ensureCompartmentData(cx);
     if (!envs)
         return false;
@@ -2740,17 +2740,17 @@ DebugEnvironments::onPopCall(JSContext* 
 
         /*
          * The frame may be observed before the prologue has created the
          * CallObject. See EnvironmentIter::settle.
          */
         if (!frame.environmentChain()->is<CallObject>())
             return;
 
-        if (frame.callee()->isStarGenerator() || frame.callee()->isAsync())
+        if (frame.callee()->isGenerator() || frame.callee()->isAsync())
             return;
 
         CallObject& callobj = frame.environmentChain()->as<CallObject>();
         envs->liveEnvs.remove(&callobj);
         if (JSObject* obj = envs->proxiedEnvs.lookup(&callobj))
             debugEnv = &obj->as<DebugEnvironmentProxy>();
     } else {
         MissingEnvironmentKey key(frame, funScope);
@@ -2874,17 +2874,17 @@ DebugEnvironments::updateLiveEnvironment
         if (!i.hasUsableAbstractFramePtr())
             continue;
 
         AbstractFramePtr frame = i.abstractFramePtr();
         if (frame.environmentChain()->compartment() != cx->compartment())
             continue;
 
         if (frame.isFunctionFrame()) {
-            if (frame.callee()->isStarGenerator() || frame.callee()->isAsync())
+            if (frame.callee()->isGenerator() || frame.callee()->isAsync())
                 continue;
         }
 
         if (!frame.isDebuggee())
             continue;
 
         RootedObject env(cx);
         RootedScope scope(cx);
@@ -3038,17 +3038,17 @@ GetDebugEnvironmentForMissing(JSContext*
      * Note: to preserve envChain depth invariants, these lazily-reified
      * envs must not be put on the frame's environment chain; instead, they are
      * maintained via DebugEnvironments hooks.
      */
     Rooted<DebugEnvironmentProxy*> debugEnv(cx);
     if (ei.scope().is<FunctionScope>()) {
         RootedFunction callee(cx, ei.scope().as<FunctionScope>().canonicalFunction());
         // Generators should always reify their scopes.
-        MOZ_ASSERT(!callee->isStarGenerator() && !callee->isAsync());
+        MOZ_ASSERT(!callee->isGenerator() && !callee->isAsync());
 
         JS::ExposeObjectToActiveJS(callee);
         Rooted<CallObject*> callobj(cx, CallObject::createHollowForDebug(cx, callee));
         if (!callobj)
             return nullptr;
 
         debugEnv = DebugEnvironmentProxy::create(cx, *callobj, enclosingDebug);
     } else if (ei.scope().is<LexicalScope>()) {
--- a/js/src/vm/GeneratorObject.cpp
+++ b/js/src/vm/GeneratorObject.cpp
@@ -15,17 +15,17 @@
 #include "vm/NativeObject-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 
 JSObject*
 GeneratorObject::create(JSContext* cx, AbstractFramePtr frame)
 {
-    MOZ_ASSERT(frame.script()->isStarGenerator() || frame.script()->isAsync());
+    MOZ_ASSERT(frame.script()->isGenerator() || frame.script()->isAsync());
     MOZ_ASSERT(frame.script()->nfixed() == 0);
 
     Rooted<GlobalObject*> global(cx, cx->global());
 
     RootedValue pval(cx);
     RootedObject fun(cx, frame.callee());
     // FIXME: This would be faster if we could avoid doing a lookup to get
     // the prototype for the instance.  Bug 906600.
@@ -57,17 +57,17 @@ bool
 GeneratorObject::suspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame, jsbytecode* pc,
                          Value* vp, unsigned nvalues)
 {
     MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD || *pc == JSOP_AWAIT);
 
     Rooted<GeneratorObject*> genObj(cx, &obj->as<GeneratorObject>());
     MOZ_ASSERT(!genObj->hasExpressionStack() || genObj->isExpressionStackEmpty());
     MOZ_ASSERT_IF(*pc == JSOP_AWAIT, genObj->callee().isAsync());
-    MOZ_ASSERT_IF(*pc == JSOP_YIELD, genObj->callee().isStarGenerator());
+    MOZ_ASSERT_IF(*pc == JSOP_YIELD, genObj->callee().isGenerator());
 
     ArrayObject* stack = nullptr;
     if (nvalues > 0) {
         do {
             if (genObj->hasExpressionStack()) {
                 MOZ_ASSERT(genObj->expressionStack().getDenseInitializedLength() == 0);
                 auto result = genObj->expressionStack().setOrExtendDenseElements(
                     cx, 0, vp, nvalues, ShouldUpdateTypes::DontUpdate);
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -182,17 +182,17 @@ ObjectGroup::useSingletonForNewObject(JS
      *
      * Sub1.prototype = new Super();
      * Sub2.prototype = new Super();
      *
      * Using distinct groups for the particular prototypes of Sub1 and
      * Sub2 lets us continue to distinguish the two subclasses and any extra
      * properties added to those prototype objects.
      */
-    if (script->isStarGenerator() || script->isAsync())
+    if (script->isGenerator() || script->isAsync())
         return false;
     if (JSOp(*pc) != JSOP_NEW)
         return false;
     pc += JSOP_NEW_LENGTH;
     if (JSOp(*pc) == JSOP_SETPROP) {
         if (script->getName(pc) == cx->names().prototype)
             return true;
     }
--- a/js/src/vm/Probes-inl.h
+++ b/js/src/vm/Probes-inl.h
@@ -36,17 +36,17 @@ probes::EnterScript(JSContext* cx, JSScr
     if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
         DTraceEnterJSFun(cx, maybeFun, script);
 #endif
 
     JSRuntime* rt = cx->runtime();
     if (rt->geckoProfiler().enabled()) {
         if (!cx->geckoProfiler().enter(cx, script, maybeFun))
             return false;
-        MOZ_ASSERT_IF(!fp->script()->isStarGenerator() &&
+        MOZ_ASSERT_IF(!fp->script()->isGenerator() &&
                       !fp->script()->isAsync(),
                       !fp->hasPushedGeckoProfilerFrame());
         fp->setPushedGeckoProfilerFrame();
     }
 
     return true;
 }
 
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -3121,17 +3121,17 @@ bool
 JSRuntime::cloneSelfHostedFunctionScript(JSContext* cx, HandlePropertyName name,
                                          HandleFunction targetFun)
 {
     RootedFunction sourceFun(cx, getUnclonedSelfHostedFunction(cx, name));
     if (!sourceFun)
         return false;
     // JSFunction::generatorKind can't handle lazy self-hosted functions, so we make sure there
     // aren't any.
-    MOZ_ASSERT(!sourceFun->isStarGenerator() && !sourceFun->isAsync());
+    MOZ_ASSERT(!sourceFun->isGenerator() && !sourceFun->isAsync());
     MOZ_ASSERT(targetFun->isExtended());
     MOZ_ASSERT(targetFun->isInterpretedLazy());
     MOZ_ASSERT(targetFun->isSelfHostedBuiltin());
 
     RootedScript sourceScript(cx, JSFunction::getOrCreateScript(cx, sourceFun));
     if (!sourceScript)
         return false;
 
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -317,17 +317,17 @@ InterpreterStack::pushInlineFrame(JSCont
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 InterpreterStack::resumeGeneratorCallFrame(JSContext* cx, InterpreterRegs& regs,
                                            HandleFunction callee, HandleValue newTarget,
                                            HandleObject envChain)
 {
-    MOZ_ASSERT(callee->isStarGenerator() || callee->isAsync());
+    MOZ_ASSERT(callee->isGenerator() || callee->isAsync());
     RootedScript script(cx, JSFunction::getOrCreateScript(cx, callee));
     InterpreterFrame* prev = regs.fp();
     jsbytecode* prevpc = regs.pc;
     Value* prevsp = regs.sp;
     MOZ_ASSERT(prev);
 
     script->ensureNonLazyCanonicalFunction();
 
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -259,17 +259,17 @@ InterpreterFrame::epilogue(JSContext* cx
     // Check that the scope matches the environment at the point of leaving
     // the frame.
     AssertScopeMatchesEnvironment(this, pc);
 
     EnvironmentIter ei(cx, this, pc);
     UnwindAllEnvironmentsInFrame(cx, ei);
 
     if (isFunctionFrame()) {
-        if (!callee().isStarGenerator() &&
+        if (!callee().isGenerator() &&
             !callee().isAsync() &&
             isConstructing() &&
             thisArgument().isObject() &&
             returnValue().isPrimitive())
         {
             setReturnValue(thisArgument());
         }
 
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -709,17 +709,17 @@ class InterpreterFrame
     }
 
     void clearReturnValue() {
         rval_.setUndefined();
         markReturnValue();
     }
 
     void resumeGeneratorFrame(JSObject* envChain) {
-        MOZ_ASSERT(script()->isStarGenerator() || script()->isAsync());
+        MOZ_ASSERT(script()->isGenerator() || script()->isAsync());
         MOZ_ASSERT(isFunctionFrame());
         flags_ |= HAS_INITIAL_ENV;
         envChain_ = envChain;
     }
 
     /*
      * Other flags
      */
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -7147,17 +7147,17 @@ ParseFunction(ModuleValidator& m, ParseN
 
     RootedFunction& fun = m.dummyFunction();
     fun->setAtom(name);
     fun->setArgCount(0);
 
     ParseContext* outerpc = m.parser().pc;
     Directives directives(outerpc);
     FunctionBox* funbox = m.parser().newFunctionBox(fn, fun, toStringStart, directives,
-                                                    NotGenerator, SyncFunction);
+                                                    GeneratorKind::NotGenerator, SyncFunction);
     if (!funbox)
         return false;
     funbox->initWithEnclosingParseContext(outerpc, frontend::Statement);
 
     Directives newDirectives = directives;
     SourceParseContext funpc(&m.parser(), funbox, &newDirectives);
     if (!funpc.init())
         return false;
@@ -8675,17 +8675,17 @@ EstablishPreconditions(JSContext* cx, As
       case AsmJSOption::Disabled:
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by 'asmjs' runtime option");
       case AsmJSOption::DisabledByDebugger:
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by debugger");
       case AsmJSOption::Enabled:
         break;
     }
 
-    if (parser.pc->isStarGenerator())
+    if (parser.pc->isGenerator())
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by generator context");
 
     if (parser.pc->isAsync())
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by async context");
 
     if (parser.pc->isArrowFunction())
         return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by arrow function context");