(threadObject, generator)
| 2599 | return null; |
| 2600 | }, |
| 2601 | spawn(threadObject, generator) { |
| 2602 | const thread = { id: this.nextThreadId++, object: threadObject, generator: generator, waiting: null, interrupted: false, done: false }; |
| 2603 | this.threads.push(thread); |
| 2604 | if (shouldTraceThread(thread)) { |
| 2605 | vmTrace("runtime.spawn.thread-" + thread.id + ":" + threadDebugLabel(threadObject)); |
| 2606 | } |
| 2607 | if (VM_DIAG_ENABLED && (thread.id | 0) > 1 && (thread.id | 0) <= 4) { |
| 2608 | vmTrace("runtime.spawn.stack.thread-" + thread.id + ":" + String(new Error().stack || "")); |
| 2609 | } |
| 2610 | // Sync methods (translated to plain ``function`` instead of |
| 2611 | // ``function*``) return non-iterable values — most commonly |
| 2612 | // ``undefined`` for a ``void`` return. ``drain`` calls |
| 2613 | // ``generator.next()`` and would explode on such a value, so |
| 2614 | // short-circuit here: the method already ran to completion when |
| 2615 | // the caller evaluated its arg, so the thread is done the moment |
| 2616 | // it's spawned. |
| 2617 | if (generator == null || typeof generator.next !== "function") { |
| 2618 | thread.done = true; |
| 2619 | if (threadObject) { |
| 2620 | threadObject[CN1_THREAD_ALIVE] = 0; |
| 2621 | } |
| 2622 | return thread; |
| 2623 | } |
| 2624 | this.enqueue(thread); |
| 2625 | return thread; |
| 2626 | }, |
| 2627 | flushPendingFireAndForget() { |
| 2628 | if (this.pendingFireAndForget.length === 0) return; |
| 2629 | const batch = this.pendingFireAndForget; |
no test coverage detected