Mercurial > urweb
changeset 692:09df0c85f306
Fix overzealous Marshalcheck; garbage-collect string-embedded closures when no dyns are active
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sat, 04 Apr 2009 12:54:39 -0400 |
parents | cc58941da3e2 |
children | 655bcc9b77e0 |
files | lib/js/urweb.js src/compiler.sig src/compiler.sml src/jscomp.sml src/marshalcheck.sml |
diffstat | 5 files changed, 79 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/js/urweb.js Sat Apr 04 11:46:24 2009 -0400 +++ b/lib/js/urweb.js Sat Apr 04 12:54:39 2009 -0400 @@ -1,3 +1,5 @@ +// Lists + function cons(v, ls) { return { next : ls, data : v }; } @@ -18,6 +20,43 @@ } +// 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 @@ 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 @@ } +// 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 @@ x.innerHTML = v; runScripts(x); + + if (--dynDepth == 0) + clearClosures(); }; populate(x); addNode(x); @@ -131,6 +179,9 @@ return x; } + +// Basic string operations + function eh(x) { return x.split("&").join("&").split("<").join("<").split(">").join(">"); } @@ -154,10 +205,17 @@ 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 @@ 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 @@ 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"), " "); -}
--- a/src/compiler.sig Sat Apr 04 11:46:24 2009 -0400 +++ b/src/compiler.sig Sat Apr 04 12:54:39 2009 -0400 @@ -69,10 +69,10 @@ val shake : (Core.file, Core.file) phase val rpcify : (Core.file, Core.file) phase val tag : (Core.file, Core.file) phase - val marshalcheck : (Core.file, Core.file) phase val reduce : (Core.file, Core.file) phase val unpoly : (Core.file, Core.file) phase val specialize : (Core.file, Core.file) phase + val marshalcheck : (Core.file, Core.file) phase val monoize : (Core.file, Mono.file) phase val mono_opt : (Mono.file, Mono.file) phase val untangle : (Mono.file, Mono.file) phase @@ -100,11 +100,11 @@ val toCore_untangle2 : (string, Core.file) transform val toShake2 : (string, Core.file) transform val toTag : (string, Core.file) transform - val toMarshalcheck : (string, Core.file) transform val toReduce : (string, Core.file) transform val toUnpoly : (string, Core.file) transform val toSpecialize : (string, Core.file) transform val toShake3 : (string, Core.file) transform + val toMarshalcheck : (string, Core.file) transform val toMonoize : (string, Mono.file) transform val toMono_opt1 : (string, Mono.file) transform val toUntangle : (string, Mono.file) transform
--- a/src/compiler.sml Sat Apr 04 11:46:24 2009 -0400 +++ b/src/compiler.sml Sat Apr 04 12:54:39 2009 -0400 @@ -475,19 +475,12 @@ val toTag = transform tag "tag" o toCore_untangle2 -val marshalcheck = { - func = (fn file => (MarshalCheck.check file; file)), - print = CorePrint.p_file CoreEnv.empty -} - -val toMarshalcheck = transform marshalcheck "marshalcheck" o toTag - val reduce = { func = Reduce.reduce, print = CorePrint.p_file CoreEnv.empty } -val toReduce = transform reduce "reduce" o toMarshalcheck +val toReduce = transform reduce "reduce" o toTag val unpoly = { func = Unpoly.unpoly, @@ -505,12 +498,19 @@ val toShake3 = transform shake "shake3" o toSpecialize +val marshalcheck = { + func = (fn file => (MarshalCheck.check file; file)), + print = CorePrint.p_file CoreEnv.empty +} + +val toMarshalcheck = transform marshalcheck "marshalcheck" o toShake3 + val monoize = { func = Monoize.monoize CoreEnv.empty, print = MonoPrint.p_file MonoEnv.empty } -val toMonoize = transform monoize "monoize" o toShake3 +val toMonoize = transform monoize "monoize" o toMarshalcheck val mono_opt = { func = MonoOpt.optimize,
--- a/src/jscomp.sml Sat Apr 04 11:46:24 2009 -0400 +++ b/src/jscomp.sml Sat Apr 04 12:54:39 2009 -0400 @@ -891,9 +891,9 @@ | EJavaScript (Source _, _, SOME _) => (e, st) | EJavaScript (_, _, SOME e) => - (strcat [str "\"cr(\"+ca(function(){return ", + (strcat [str "function(){return ", e, - str "})+\")\""], + str "}"], st) | EClosure _ => unsupported "EClosure" @@ -905,9 +905,9 @@ let val (e, st) = jsE inner (e, st) in - (strcat [str "\"cr(\"+ca(function(){return ", + (strcat [str "function(){return ", e, - str "})+\")\""], + str "}"], st) end
--- a/src/marshalcheck.sml Sat Apr 04 11:46:24 2009 -0400 +++ b/src/marshalcheck.sml Sat Apr 04 12:54:39 2009 -0400 @@ -58,7 +58,8 @@ ("Basis", "string"), ("Basis", "time"), ("Basis", "unit"), - ("Basis", "option")] + ("Basis", "option"), + ("Basis", "bool")] val clientToServer = PS.addList (PS.empty, clientToServer)