summaryrefslogtreecommitdiff
path: root/lib/js
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2009-04-04 12:54:39 -0400
committerGravatar Adam Chlipala <adamc@hcoop.net>2009-04-04 12:54:39 -0400
commitabb3bffd224cb7bdbbbc1461643a8e58fb03ed8f (patch)
treefffd7969dc6117fb442be22dfcbb86c15df35d0d /lib/js
parente74f91d28381be3758a53da75985afa05a06680d (diff)
Fix overzealous Marshalcheck; garbage-collect string-embedded closures when no dyns are active
Diffstat (limited to 'lib/js')
-rw-r--r--lib/js/urweb.js84
1 files changed, 62 insertions, 22 deletions
diff --git a/lib/js/urweb.js b/lib/js/urweb.js
index 4a447a5b..fe996833 100644
--- a/lib/js/urweb.js
+++ b/lib/js/urweb.js
@@ -1,3 +1,5 @@
+// Lists
+
function cons(v, ls) {
return { next : ls, data : v };
}
@@ -18,6 +20,43 @@ function union(ls1, ls2) {
}
+// Embedding closures in XML strings
+
+function cat(s1, s2) {
+ if (s1.length && s2.length)
+ return s1 + s2;
+ else
+ return {_1: s1, _2: s2};
+}
+
+var closures = [];
+
+function newClosure(f) {
+ var n = closures.length;
+ closures[n] = f;
+ return n;
+}
+
+function cr(n) {
+ return closures[n]();
+}
+
+function flatten(tr) {
+ if (tr.length)
+ return tr;
+ else if (tr._1)
+ return cs(tr._1) + cs(tr._2);
+ else
+ return "cr(" + newClosure(tr) + ")";
+}
+
+function clearClosures() {
+ closures = [];
+}
+
+
+// Dynamic tree management
+
function populate(node) {
var s = node.signal;
var oldSources = node.sources;
@@ -85,7 +124,7 @@ var thisScript = null;
function runScripts(node) {
var savedScript = thisScript;
- var scripts = node.getElementsByTagName("script"), scriptsCopy = {};
+ var scripts = node.getElementsByTagName("script"), scriptsCopy = [];
var len = scripts.length;
for (var i = 0; i < len; ++i)
scriptsCopy[i] = scripts[i];
@@ -98,12 +137,18 @@ function runScripts(node) {
}
+// Dynamic tree entry points
+
+var dynDepth = 0;
+
function dyn(s) {
var x = document.createElement("span");
x.dead = false;
x.signal = s;
x.sources = null;
x.recreate = function(v) {
+ ++dynDepth;
+
var spans = x.getElementsByTagName("span");
for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
@@ -114,6 +159,9 @@ function dyn(s) {
x.innerHTML = v;
runScripts(x);
+
+ if (--dynDepth == 0)
+ clearClosures();
};
populate(x);
addNode(x);
@@ -131,6 +179,9 @@ function inp(t, s) {
return x;
}
+
+// Basic string operations
+
function eh(x) {
return x.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;");
}
@@ -154,10 +205,17 @@ function pfl(s) {
throw "Can't parse float: " + s;
}
-function cat(s1, s2) {
- return s1 + s2;
+function uf(s) {
+ return escape(s).replace(new RegExp ("/", "g"), "%2F");
}
+function uu(s) {
+ return unescape(s).replace(new RegExp ("\\+", "g"), " ");
+}
+
+
+// Error handling
+
function whine(msg) {
alert(msg);
throw msg;
@@ -167,18 +225,8 @@ function pf() {
whine("Pattern match failure");
}
-var closures = [];
-
-function ca(f) {
- var n = closures.length;
- closures[n] = f;
- return n;
-}
-
-function cr(n) {
- return closures[n]();
-}
+// Remote calls
var client_id = 0;
var client_pass = 0;
@@ -364,11 +412,3 @@ function rv(chn, parse, k) {
k(parse(msg))(null);
}
}
-
-function uf(s) {
- return escape(s).replace(new RegExp ("/", "g"), "%2F");
-}
-
-function uu(s) {
- return unescape(s).replace(new RegExp ("\\+", "g"), " ");
-}