/* 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/. */ function StarGeneratorNext(val) { // The IsSuspendedStarGenerator call below is not necessary for // correctness. It's a performance optimization to check for the // common case with a single call. It's also inlined in Baseline. if (!IsSuspendedStarGenerator(this)) { if (!IsObject(this) || !IsStarGeneratorObject(this)) return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorNext"); if (StarGeneratorObjectIsClosed(this)) return { value: undefined, done: true }; if (GeneratorIsRunning(this)) ThrowTypeError(JSMSG_NESTING_GENERATOR); } try { return resumeGenerator(this, val, 'next'); } catch (e) { if (!StarGeneratorObjectIsClosed(this)) GeneratorSetClosed(this); throw e; } } function StarGeneratorThrow(val) { if (!IsSuspendedStarGenerator(this)) { if (!IsObject(this) || !IsStarGeneratorObject(this)) return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorThrow"); if (StarGeneratorObjectIsClosed(this)) throw val; if (GeneratorIsRunning(this)) ThrowTypeError(JSMSG_NESTING_GENERATOR); } try { return resumeGenerator(this, val, 'throw'); } catch (e) { if (!StarGeneratorObjectIsClosed(this)) GeneratorSetClosed(this); throw e; } } function StarGeneratorReturn(val) { if (!IsSuspendedStarGenerator(this)) { if (!IsObject(this) || !IsStarGeneratorObject(this)) return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorReturn"); if (StarGeneratorObjectIsClosed(this)) return { value: val, done: true }; if (GeneratorIsRunning(this)) ThrowTypeError(JSMSG_NESTING_GENERATOR); } try { var rval = { value: val, done: true }; return resumeGenerator(this, rval, 'close'); } catch (e) { if (!StarGeneratorObjectIsClosed(this)) GeneratorSetClosed(this); throw e; } } function LegacyGeneratorNext(val) { if (!IsObject(this) || !IsLegacyGeneratorObject(this)) return callFunction(CallLegacyGeneratorMethodIfWrapped, this, val, "LegacyGeneratorNext"); if (LegacyGeneratorObjectIsClosed(this)) ThrowStopIteration(); if (GeneratorIsRunning(this)) ThrowTypeError(JSMSG_NESTING_GENERATOR); try { return resumeGenerator(this, val, 'next'); } catch(e) { if (!LegacyGeneratorObjectIsClosed(this)) GeneratorSetClosed(this); throw e; } } _SetCanonicalName(LegacyGeneratorNext, "next"); function LegacyGeneratorThrow(val) { if (!IsObject(this) || !IsLegacyGeneratorObject(this)) return callFunction(CallLegacyGeneratorMethodIfWrapped, this, val, "LegacyGeneratorThrow"); if (LegacyGeneratorObjectIsClosed(this)) throw val; if (GeneratorIsRunning(this)) ThrowTypeError(JSMSG_NESTING_GENERATOR); try { return resumeGenerator(this, val, 'throw'); } catch(e) { if (!LegacyGeneratorObjectIsClosed(this)) GeneratorSetClosed(this); throw e; } } // Called by js::CloseIterator. function LegacyGeneratorCloseInternal() { assert(IsObject(this), "Not an object: " + ToString(this)); assert(IsLegacyGeneratorObject(this), "Not a legacy generator object: " + ToString(this)); assert(!LegacyGeneratorObjectIsClosed(this), "Already closed: " + ToString(this)); if (GeneratorIsRunning(this)) ThrowTypeError(JSMSG_NESTING_GENERATOR); resumeGenerator(this, undefined, 'close'); if (!LegacyGeneratorObjectIsClosed(this)) CloseClosingLegacyGeneratorObject(this); } function LegacyGeneratorClose() { if (!IsObject(this) || !IsLegacyGeneratorObject(this)) return callFunction(CallLegacyGeneratorMethodIfWrapped, this, "LegacyGeneratorClose"); if (LegacyGeneratorObjectIsClosed(this)) return; callFunction(LegacyGeneratorCloseInternal, this); } function InterpretGeneratorResume(gen, val, kind) { // If we want to resume a generator in the interpreter, the script containing // the resumeGenerator/JSOP_RESUME also has to run in the interpreter. The // forceInterpreter() call below compiles to a bytecode op that prevents us // from JITing this script. forceInterpreter(); if (kind === "next") return resumeGenerator(gen, val, "next"); if (kind === "throw") return resumeGenerator(gen, val, "throw"); assert(kind === "close", "Invalid resume kind"); return resumeGenerator(gen, val, "close"); }