X-Git-Url: https://git.distorted.org.uk/~mdw/dep-ui/blobdiff_plain/5a0d36b9f9bcc3791114155e2a3b2657528cea19..6132735f4d4fe2bd9d4395f5cae34b662c999451:/dep.js?ds=sidebyside
diff --git a/dep.js b/dep.js
index f4b0ff9..989e871 100644
--- a/dep.js
+++ b/dep.js
@@ -18,13 +18,26 @@
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, see .
+ * along with this program; if not, see .
*/
var DEP = { }; (function () {
/*----- Utility functions and classes -------------------------------------*/
+DEP.DEBUG = false;
+function blather(msg) {
+ /* Report MSG to the log if we're debugging. */
+ if (DEP.DEBUG) console.log(";; " + msg);
+}
+function show(what, value) {
+ /* Report that WHAT has the value VALUE, if we're debugging; and,
+ * regardless, return VALUE.
+ */
+ blather(what + " = " + value);
+ return value;
+}
+
function dolist(list, func) {
/* Apply FUNC to each element of LIST, discarding the results.
*
@@ -118,7 +131,7 @@ var F_CHANGED = 4; // Changed in current phase.
var F_RECOMPUTING = 8; // Currently being recomputed.
var F_QUEUED = 16; // Queued for recomputation.
-var BAD = Tag('BAD') // Used for the value of `bad' deps.
+var BAD = new Tag('BAD'); // Used for the value of `bad' deps.
var DELAYED = []; // Actions delayed by `with_frozen'.
var PENDING = []; // Deps awaiting recomputation.
@@ -178,7 +191,7 @@ function Dep(value, maybefunc) {
func = value;
f |= F_QUEUED;
} else {
- val = value;
+ val = value === undefined ? BAD : value;
func = null;
f |= F_VALUE | F_DEPS;
}
@@ -203,9 +216,11 @@ function Dep(value, maybefunc) {
this._dependencies = { }; // Set of objects we depend on.
// If we have a recomputation function then exercise it.
+ blather("new dep " + me);
if (func !== null) {
with_frozen(function () {
PENDING.push(me);
+ blather("push new dep " + me);
});
}
}
@@ -235,7 +250,7 @@ Dep.prototype = {
s += ' #' + this._seq;
// The value, or some kind of marker that it doesn't have one.
- if (!(f & F_VALUE)) s += ' #{out-of-date}';
+ if (!(f & F_VALUE)) s += ' #{stale}';
else if (v === BAD) s += ' #{bad}';
else s += ' ' + v.toString();
@@ -255,7 +270,7 @@ Dep.prototype = {
* If the receiver isn't up-to-date then we synthesize the flags.
*/
- if (this.state === 'ready') return F_VALUE | F_DEPS;
+ if (STATE === 'ready') return F_VALUE | F_DEPS;
else if (this._generation === GENERATION) return this.__flags;
else if (this._value_function === null) return F_VALUE | F_DEPS;
else return 0;
@@ -268,6 +283,7 @@ Dep.prototype = {
* function which doesn't handle propagation or anything like that.
*/
+ blather("_update " + this + ": " + value);
if (value === BAD ?
this._value === BAD :
(this._value !== BAD &&
@@ -293,8 +309,9 @@ Dep.prototype = {
this._dependencies = { };
return try_finally(function () {
EVALUATING = me;
- return orelse(function () { return me._value_function(); },
- function () { return BAD; });
+ return show("_new_value for " + me,
+ orelse(function () { return me._value_function(); },
+ function () { return show("ret", BAD); }));
}, function() {
EVALUATING = old;
});
@@ -394,14 +411,15 @@ Dep.prototype = {
var val;
- if (state === 'recomputing') {
+ if (STATE === 'recomputing') {
+ this._force();
if (EVALUATING) {
this._dependents[EVALUATING._seq] = EVALUATING;
EVALUATING._dependencies[this._seq] = this;
}
- this._force();
}
val = this._value;
+ blather("value " + this + ": " + val);
if (val === BAD) throw BAD;
return val;
},
@@ -444,7 +462,7 @@ Dep.prototype = {
function orelse(thunk, errthunk) {
/* Call THUNK. If it succeeds, then return its result. If THUNK
- * reads a bad dep then call ERRTHINK and return its result instead.
+ * reads a bad dep then call ERRTHUNK and return its result instead.
*/
var e;
@@ -469,8 +487,9 @@ function recompute_pending() {
*/
var d, f;
-
- state = 'recomputing';
+ var old_state = STATE;
+ STATE = 'recomputing';
+ blather("STATE <- :recomputing");
try_finally(function () {
while (PENDING.length) {
d = PENDING.shift();
@@ -487,7 +506,10 @@ function recompute_pending() {
while (PENDING.length) {
d = PENDING.shift();
d._value = BAD;
+ blather("recompute_pending mark " + d);
}
+ STATE = old_state;
+ blather("STATE <- :" + old_state);
});
}
@@ -497,14 +519,13 @@ function with_frozen(body, delay) {
* If the BODY function changes any dep values (using D.set_value(...))
* then dependents won't be updated until the BODY completes.
*
- * It's very
- * bad to do this during a recomputation phase. If DELAY is true, then the
- * BODY is delayed until the recomputation completes; otherwise you get an
- * exception.
+ * It's very bad to do this during a recomputation phase. If DELAY is
+ * true, then the BODY is delayed until the recomputation completes;
+ * otherwise you get an exception.
*/
var op, val;
- var old_delayed, old_pending;
+ var old_delayed, old_pending, old_state;
switch (STATE) {
case 'frozen':
@@ -517,6 +538,9 @@ function with_frozen(body, delay) {
case 'ready':
old_delayed = DELAYED;
old_pending = PENDING;
+ old_state = STATE;
+ STATE = "frozen";
+ blather("STATE <- :frozen");
try_finally(function () {
DELAYED = [];
PENDING = [];
@@ -531,6 +555,8 @@ function with_frozen(body, delay) {
}, function () {
DELAYED = old_delayed;
PENDING = old_pending;
+ STATE = old_state;
+ blather("STATE <- :" + old_state);
});
break;
}