From 8e8c217003dcda28e14b330039062d9bf8463e64 Mon Sep 17 00:00:00 2001 From: Adam Chlipala Date: Sat, 4 Apr 2009 12:54:39 -0400 Subject: Fix overzealous Marshalcheck; garbage-collect string-embedded closures when no dyns are active --- lib/js/urweb.js | 84 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 22 deletions(-) (limited to 'lib/js/urweb.js') 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("&").split("<").join("<").split(">").join(">"); } @@ -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"), " "); -} -- cgit v1.2.3