| <?php | |
| require "tests.php"; | |
| // New functions | |
| check::functions(array('deleteFoo','getStatus','launder','resetStatus')); | |
| // New classes | |
| check::classes(array('director_finalizer','Foo')); | |
| // No new vars | |
| check::globals(array()); | |
| class MyFoo extends Foo { | |
| function __destruct() { | |
| # It's not safe to call methods on the C++ object from the PHP destructor | |
| # if the object has been disowned, since the C++ object will already have | |
| # been destroyed by the time the PHP destructor runs. | |
| if ($this->thisown) { | |
| $this->orStatus(2); | |
| } | |
| if (method_exists(parent::class, "__destruct")) { | |
| parent::__destruct(); | |
| } | |
| } | |
| } | |
| resetStatus(); | |
| $a = new MyFoo(); | |
| unset($a); | |
| check::equal(getStatus(), 3, "getStatus() failed #1"); | |
| resetStatus(); | |
| $a = new MyFoo(); | |
| launder($a); | |
| check::equal(getStatus(), 0, "getStatus() failed #2"); | |
| unset($a); | |
| check::equal(getStatus(), 3, "getStatus() failed #3"); | |
| resetStatus(); | |
| $a = new MyFoo(); | |
| $a->thisown = 0; | |
| check::equal(getStatus(), 0, "shadow release does not fire destructor of disowned object"); | |
| deleteFoo($a); | |
| unset($a); | |
| # getStatus() would ideally return 3 here. | |
| check::equal(getStatus(), 1, "getStatus() failed #4"); | |
| resetStatus(); | |
| $a = new MyFoo(); | |
| $a->thisown = 0; | |
| $g = launder($a); | |
| unset($a); | |
| deleteFoo($g); | |
| # getStatus() would ideally return 3 here. | |
| check::equal(getStatus(), 1, "getStatus() failed #5"); | |
| resetStatus(); | |
| check::done(); |