Skip to content
ousado edited this page Feb 13, 2015 · 4 revisions

Capture Policy

The following assumes no dataflow analysis.

If a captured var is modified, it needs to be allocated on the heap.

Modified (always with respect to closures in the following) means that it's being assigned to after any closure capturing that var has been instantiated, where that modification may happen either in an outer scope (from the closures perspective) or within the closure.

{
  var v = 1;
  v+=1;
  (function() v+=1)();
}

In the above code, v is not being modified WRT the closure, while in the code below it is.

{
  var v = 1;
  (function() v+=1)();
  v+=1;
}

Instead of allocating one single-element array per captured&modified var, we combine all captured variables into one object. The first closure context that is being created unconditionally in a given scope always hosts these captured variables. If there is no such closure, as e.g. in the case below, we allocate one independent object per scope, that holds the captured&modified vars.

function f(cond){
  var v = 1;
  if(cond) (function() v+=1)() else (function() v+=2)()
}

A scope in that context can be either a functions root scope, or the scope of a loop within a root scope. Whether a closure is classified as being created conditionally has to be decided individually for every scope enclosing the closure. In the example below, the closure within is created conditionally from the root scopes perspective, and unconditionally from the loop scopes perspective, which makes it eligible as the host for captured vars in the loop scope, but not for those in the root scope.

function f(cond){
  // start of root scope
  var v = 1;
  if(cond) /* we're still in the root scope here */ (function() v+=1)() 
     else /* and here too */ (function() v+=2)()
  for (i in 0...v){ 
     /* start of a loop scope, 
        captured & modified vars in this scope need their own object,
        the same rules regarding closures being created (un)conditionally
        apply here. */
     var x = 1;
     (function() x+=1)()
     x +=1;
  }
}
Clone this wiki locally