(0002573)
|
koreth
|
12-14-07 19:54
|
|
Found the problem. In Env.importPage(), the code checks to see if it has a cached copy of the definition state from the page. But the definition state is cumulative, not per-page -- it includes the definition state for all the pages that have already been included at that point. So if you have an include chain like
file1 -> file2 -> file3
and file2 is modified, the definition state for file3 will include the *old* functions for file2, and it'll get used in preference to the version that was just reconstructed from file3.
The crux of the bug seems to be that the definition state CRC doesn't change when the contents of one of the functions changes. It assumes that a function name uniquely identifies a function, when in fact it's really the name plus the code. Since Quercus allocates a new object with a different ID when it does a fresh parse of a function, the object ID can be used as a proxy for the contents. Here's a quick patch that seems to fix the problem; it's not exactly elegant but might be adequate.
(Edited to call hashCode() instead of toString())
--- a/modules/quercus/src/com/caucho/quercus/env/DefinitionState.java
+++ b/modules/quercus/src/com/caucho/quercus/env/DefinitionState.java
@@ -284,7 +284,7 @@ public final class DefinitionState {
copyOnWrite();
_funMap.put(name, fun);
- _crc = Crc64.generate(_crc, name);
+ _crc = Crc64.generate(_crc, name + fun.hashCode());
if (_lowerFunMap != null)
_lowerFunMap.put(name.toLowerCase(), fun);
@@ -315,7 +315,7 @@ public final class DefinitionState {
copyOnWrite();
_funMap.put(name, fun);
- _crc = Crc64.generate(_crc, name);
+ _crc = Crc64.generate(_crc, name + fun.hashCode());
if (_lowerFunMap != null)
_lowerFunMap.put(lowerName, fun);
@@ -330,7 +330,7 @@ public final class DefinitionState {
{
copyOnWrite();
_classDefMap.put(name, cl);
- _crc = Crc64.generate(_crc, name);
+ _crc = Crc64.generate(_crc, name + cl.hashCode());
if (_lowerClassDefMap != null)
_lowerClassDefMap.put(name.toLowerCase(), cl);
|
|