symisc / PH7

An Embedded Implementation of PHP (C Library)
http://ph7.symisc.net
Other
494 stars 68 forks source link

Included code behaves differently #4

Closed thekid closed 10 years ago

thekid commented 10 years ago
$ cat x.php
<?php
final class X {
  public static $variable = "Hello";
}

function bootstrap() {
  echo "Bootstrapping...\n";
  X::$variable.= "World";
}

bootstrap();
var_dump(X::$variable);

$ ./ph7.exe x.php
Bootstrapping...
string(10 'HelloWorld')

So far, so good. Now let x.php run inside an include() context:

$ cat hello.php
<?php
include("x.php");

$ ./ph7.exe hello.php
Bootstrapping...
null

Enabling errors yields the following:

Error: Cannot perform assignment on a constant class attribute,PH7 is loading NULL
thekid commented 10 years ago

Seems VmEvalChunk() forgets to to call VmMountUserClass on classes declared iside the given PHP chunk, so adding:

SyHashEntry *pEntry;

/* Initialize and install static and constants class attributes */
SyHashResetLoopCursor(&pVm->hClass);
while((pEntry = SyHashGetNextEntry(&pVm->hClass)) != 0 ){
    if( VmMountUserClass(&(*pVm),(ph7_class *)pEntry->pUserData) != SXRET_OK ) {
        if( pCtx ){
            ph7_result_bool(pCtx,0);
        }
        goto Cleanup;
    }
}

...inside the else block of if( pVm->sCodeGen.nErr > 0 ) and before if( SXRET_OK != PH7_VmEmitInstr(pVm,PH7_OP_DONE,0,0,0,0) ) (around line 13300 in ph7.c) fixes the thing

I'd come up with a PR but this is only the generated ("amalgamated") code here, so that's probably useless.

symisc commented 10 years ago

Nice hack, will merge this with with the main trunk soon. Thanks for your contribution!