diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
commit | 9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /js/src/builtin/Generator.js | |
parent | Initial commit. (diff) | |
download | thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/builtin/Generator.js')
-rw-r--r-- | js/src/builtin/Generator.js | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/js/src/builtin/Generator.js b/js/src/builtin/Generator.js new file mode 100644 index 0000000000..ada80e3006 --- /dev/null +++ b/js/src/builtin/Generator.js @@ -0,0 +1,114 @@ +/* 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 GeneratorNext(val) { + // The IsSuspendedGenerator 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 (!IsSuspendedGenerator(this)) { + if (!IsObject(this) || !IsGeneratorObject(this)) { + return callFunction( + CallGeneratorMethodIfWrapped, + this, + val, + "GeneratorNext" + ); + } + + if (GeneratorObjectIsClosed(this)) { + return { value: undefined, done: true }; + } + + if (GeneratorIsRunning(this)) { + ThrowTypeError(JSMSG_NESTING_GENERATOR); + } + } + + try { + return resumeGenerator(this, val, "next"); + } catch (e) { + if (!GeneratorObjectIsClosed(this)) { + GeneratorSetClosed(this); + } + throw e; + } +} + +function GeneratorThrow(val) { + if (!IsSuspendedGenerator(this)) { + if (!IsObject(this) || !IsGeneratorObject(this)) { + return callFunction( + CallGeneratorMethodIfWrapped, + this, + val, + "GeneratorThrow" + ); + } + + if (GeneratorObjectIsClosed(this)) { + throw val; + } + + if (GeneratorIsRunning(this)) { + ThrowTypeError(JSMSG_NESTING_GENERATOR); + } + } + + try { + return resumeGenerator(this, val, "throw"); + } catch (e) { + if (!GeneratorObjectIsClosed(this)) { + GeneratorSetClosed(this); + } + throw e; + } +} + +function GeneratorReturn(val) { + if (!IsSuspendedGenerator(this)) { + if (!IsObject(this) || !IsGeneratorObject(this)) { + return callFunction( + CallGeneratorMethodIfWrapped, + this, + val, + "GeneratorReturn" + ); + } + + if (GeneratorObjectIsClosed(this)) { + return { value: val, done: true }; + } + + if (GeneratorIsRunning(this)) { + ThrowTypeError(JSMSG_NESTING_GENERATOR); + } + } + + try { + var rval = { value: val, done: true }; + return resumeGenerator(this, rval, "return"); + } catch (e) { + if (!GeneratorObjectIsClosed(this)) { + GeneratorSetClosed(this); + } + throw e; + } +} + +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 === "return", "Invalid resume kind"); + return resumeGenerator(gen, val, "return"); +} |