Skip to content

Commit

Permalink
Test case and fix for memory leak in the JavaScript runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
saulo2 committed Aug 12, 2016
1 parent 3bcc7ed commit dcd280c
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 11 deletions.
25 changes: 14 additions & 11 deletions lib/js/urweb.js
Expand Up @@ -854,6 +854,16 @@ function runScripts(node) {


// Dynamic tree entry points
function killDyns(node) {
var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT, function (node) {
return node.dead !== undefined && node.dead === false
})
var node = nodeIterator.nextNode();
while (node) {
killScript(node);
node = nodeIterator.nextNode();
}
}

function killScript(scr) {
scr.dead = true;
Expand Down Expand Up @@ -923,12 +933,7 @@ function dyn(pnode, s) {
for (var child = firstChild; child && child != x; child = next) {
next = child.nextSibling;

killScript(child);
if (child.getElementsByTagName) {
var arr = child.getElementsByTagName("script");
for (var i = 0; i < arr.length; ++i)
killScript(arr[i]);
}
killDyns(child)

if (child.parentNode)
child.parentNode.removeChild(child);
Expand Down Expand Up @@ -1050,11 +1055,9 @@ function setInnerHTML(node, html) {
for (var ls = x.closures; ls; ls = ls.next)
freeClosure(ls.data);

if (node.getElementsByTagName) {
var arr = node.getElementsByTagName("script");
for (var i = 0; i < arr.length; ++i)
killScript(arr[i]);
}
var arr = node.childNodes;
for (var i = 0; i < arr.length; ++i)
killDyns(arr[i]);
} else {
x = document.createElement("script");
x.dead = false;
Expand Down
34 changes: 34 additions & 0 deletions tests/memoryLeak.ur
@@ -0,0 +1,34 @@
fun main () =
visibleSource <- source True;
ctextboxSource <- source "";
ctextareaSource <- source "";
cselectSource <- source "";
let val signal =
visible <- signal visibleSource;
if visible then
return
<xml>
<p>
<ctextbox source={ctextboxSource}/>
</p>
<p>
<ctextarea source={ctextboxSource}/>
</p>
<p>
<cselect source={cselectSource}/>
</p>
</xml>
else
return
<xml></xml>
in
return
<xml>
<body>
<p>
<button onclick={fn _ => visible <- get visibleSource; set visibleSource (not visible)}>Show / Hide</button>
</p>
<dyn signal={signal}/>
</body>
</xml>
end
1 change: 1 addition & 0 deletions tests/memoryLeak.urp
@@ -0,0 +1 @@
memoryLeak
1 change: 1 addition & 0 deletions tests/memoryLeak.urs
@@ -0,0 +1 @@
val main: unit -> transaction page

0 comments on commit dcd280c

Please sign in to comment.