On Dec 17, 2007, at 10:30 PM, Larry Garfield wrote:

I'm assuming that making the function above GC-able would be a herculean task at this point, based on previous comments, but I do not actually know myself.

Hi Larry,

Let me use a different example than yours.

function getAdder($x) {
  return function ($y) {
    lexical $x;
    return $x + $y;
  }
}

$plusFive = getAdder(5);
$plusTen = getAdder(10);

echo $plusFive(4); // 9
echo $plusTen(7); // 17

If the closure definition (and thus getAddr) returns a string representing an anonymous function name, then there is no where to hold the enclosing variable $x and no way to know when to free it. Notice that in this example, we have two different enclosing contexts, one where $x is 5 and one where $x is 10.

If we introduce a new variable type, a new kind of zval, then internally, that variable can hold:
1) A reference to the local variables of getAddr.  (here $x)
2) A reference to $this if the closure is declared in a method
3) A reference to the opcodes of the compiled anonymous function.

The opcodes for the closure would be compiled and squirreled away when the script is compiled.

When getAddr is executed, a zval would be created that holds the reference to the enclosing locals and a reference to the proper opcodes. Note that $plusFive and $plusTen would hold two different zvals, one for each invocation of getAddr, but that both would refer to the same opcodes structure.

When a codeblock zval is executed, such as at $plusFive(4), the enclosing context can be passed to the anonymous function function to make the lexical $x statement bind to the proper variable.

When the zval in $plusFive reaches zero references, it can subsequently free its references to the local variables of getAddr.

As far as I can see, no herculean garbage collection or reference counting is required.

Adding a new kind of zval?  Perhaps that's Herculean.  I don't know.

I hope I've gotten my zval terminology right.

Best Regards,

Jeff

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to