Mantis - Quercus
Viewing Issue Advanced Details
2258 major always 12-15-07 01:40 12-18-07 15:51
koreth  
ferg  
normal  
closed 3.1.4  
fixed  
none    
none 3.1.5  
0002258: Assignment to reference variables sometimes breaks in compiled mode
In a class, we call a function to queue up a data lookup for later, passing in a reference to a class variable that doesn't exist yet. Something like this:

class MyClass {
  function foo($id) {
    queue_up("myclass." . $id, $this->field);
  }
}

The queue_up function adds the reference to a list of pending lookups, something like this:

function queue_up($id, &$ref) {
  $GLOBALS['queue'][] = array('id' => $id, 'ref' => &$ref);
}

Then, later on, we call a dispatch function to perform all the pending lookups, something like this:

function dispatch() {
  ... do the actual lookups (this part works fine) ...
  foreach ($GLOBALS['queue'] as $item) {
    $id = $item['id'];
    $item['ref'][$id] = $looked_up_values[$id];
  }
}

The desired result is that $myclass_instance->field is an array with an entry whose key is the ID and whose value is the looked-up value. In vanilla PHP and in interpreted mode, this works fine. But when the dispatch function is compiled, it stops working; $myclass_instance->field gets created, but it is assigned an empty value.

A possibly big clue: if I tweak the dispatch function to look like

...
  foreach ($GLOBALS['queue'] as $item) {
    $id = $item['id'];
    $ref = &$item['ref'];
    $ref[$id] = $looked_up_values[$id];
  }

(that is, to explicitly access the reference as a reference before assigning to it) then the code starts working in compiled mode too. I'm doing that in a couple places in the code now as a workaround, but we make a lot of use of references and I'm sure there are still bad behaviors being caused by this bug.

Unfortunately I haven't been able to come up with a concise test case for this; in a test case as simple as the one above, the bug never occurs. But it is 100% reproducible in our actual code base. If there are syntax or logic errors in my example code above it's just because I made it up as I typed this report, not because that's what the real code does.

Notes
(0002590)
ferg   
12-18-07 15:51   
php/39o2