make mark_reactions non-recursive

pull/12069/head
Rich Harris 2 years ago
parent 36704e4b01
commit 282c167846

@ -1,4 +1,3 @@
import { DEV } from 'esm-env';
import { CLEAN, DERIVED, DESTROYED, DIRTY, MAYBE_DIRTY, UNOWNED } from '../constants.js';
import {
current_reaction,
@ -102,7 +101,7 @@ export function update_derived(derived, force_schedule) {
derived.v = value;
derived.version = increment_version();
mark_reactions(derived, DIRTY, force_schedule);
mark_reactions(derived, force_schedule);
}
}

@ -10,7 +10,6 @@ import {
mark_reactions,
schedule_effect,
set_current_untracked_writes,
set_last_inspected_signal,
set_signal_status,
untrack,
increment_version,
@ -95,7 +94,7 @@ export function set(source, value) {
source.v = value;
source.version = increment_version();
mark_reactions(source, DIRTY, true);
mark_reactions(source, true);
// If the current signal is running for the first time, it won't have any
// reactions as we only allocate and assign the reactions after the signal

@ -851,19 +851,25 @@ export function invalidate_inner_signals(fn) {
/**
* @param {import('#client').Value} signal
* @param {number} to_status should be DIRTY or MAYBE_DIRTY
* @param {boolean} force_schedule
* @returns {void}
*/
export function mark_reactions(signal, to_status, force_schedule) {
export function mark_reactions(signal, force_schedule) {
var reactions = signal.reactions;
if (reactions === null) return;
var runes = is_runes();
var length = reactions.length;
var stack = reactions.slice();
var n = stack.length;
while (stack.length > 0) {
// top-level reactions are DIRTY, others are MAYBE_DIRTY
var status = n < stack.length ? MAYBE_DIRTY : DIRTY;
var reaction = /** @type {import('#client').Reaction} */ (stack.pop());
if (stack.length < n) n = stack.length;
for (var i = 0; i < length; i++) {
var reaction = reactions[i];
var flags = reaction.f;
if (DEV && (flags & INSPECT_EFFECT) !== 0) {
@ -878,7 +884,7 @@ export function mark_reactions(signal, to_status, force_schedule) {
continue;
}
set_signal_status(reaction, to_status);
set_signal_status(reaction, status);
// If the signal is not clean, then skip over it with the exception of unowned signals that
// are already maybe dirty. Unowned signals might be dirty because they are not captured as part of an
@ -888,11 +894,12 @@ export function mark_reactions(signal, to_status, force_schedule) {
if ((flags & CLEAN) !== 0 || (maybe_dirty && unowned)) {
if ((reaction.f & DERIVED) !== 0) {
mark_reactions(
/** @type {import('#client').Derived} */ (reaction),
MAYBE_DIRTY,
force_schedule
);
// Push the derived reaction's reactions onto the stack with MAYBE_DIRTY status
var children = /** @type {import('#client').Derived} */ (reaction).reactions;
if (children !== null) {
stack.push(...children);
}
} else {
schedule_effect(/** @type {import('#client').Effect} */ (reaction));
}

Loading…
Cancel
Save