Hi,
I'm working on the AOP_PHP extension (http://pecl.php.net/package/AOP dedicated
to bring the AOP paradigm to PHP (may it be evil or not)) and I'm
struggling to make it compatible with PHP 5.5
As you probably expect, as the AOP paradigm is something like a magical
hook, I have to overload the zend_execute function (and zend_execute_ex in
PHP 5.5).
Sometimes, I want to call the hooks before the execution of the actual
called method.
If an exception is raised in the hook, I won't always call the former
called method.
This was working like a charm in PHP 5.4.X (zend_execute) and before, but
in PHP 5.5(zend_execute_ex) I have troubles with memory management.
First, it seems that if I don't replace the EG(execute_data) by
EG(execute_data)->prev_execute_data, I end in a infinite loop.
If I EG(execute_data) = EG(execute_data)->prev_execute_data, there is no
loop anymore, but I have freeing error (apparently in
zend_clear_multiple_stack).
I've tried to zend_stack_push(0) in order to not free any arguments in
the stack (as I don't have any), but trying this, I still have another
freeing error in the handle of the exception because there is a loop (and
freeing) until we can get the zend_vm_stack_frame_base().
Am I doing wrong ? Any pointers ? Is there something simplier to just
ignore the real execution without having memory problem ?
Thanks for your time and help.
Hi Julien,
On Wed, Jul 31, 2013 at 6:24 PM, Julien SALLEYRON <
julien.salleyron@gmail.com> wrote:
If I EG(execute_data) = EG(execute_data)->prev_execute_data, there is no
loop anymore, but I have freeing error
Don't over write EG(execute_data), but use your own pointer when it is
needed.
I think this will fix your problem.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Julien,
Hi and thank you for taking the time to help.
Don't over write EG(execute_data), but use your own pointer when it is
needed. I think this will fix your problem.
The problem here is that I have came to the conclusion (wrong
conclusion ?) that I need to update the EG(current_execute_data) "as
if" the former called function had been processed, to actually skip
the function that was called in PHP.
Maybe some code will be more explicit...
<?php
myFunction(); //the function is expected to be called (and will)
$hook = function () {throw new Exception()};
aop_add_before('myFunction()', $hook); //now we ask the extension to
call hook() before myFunction()
myFunction();//Now myFunction should never be called, as the hook is
raising an exception
Extension-wise, the code is located here
(https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L390), where I test
if the hook raised an exception or not.
If it did not, I'm calling the function
(https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L392
https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L391) and it ends
up updating EG(current_execute_data) with
EG(current_execute_data)->prev_execute_data.
Now, when the hook is raising an exception, I'd like to just skip the
function call. If I just "return"
(https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L397
https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L396) it ends up in
an infinite loop. reason why I tried EG (current_execute_data) =
EG(current_execute_data)->prev_execute_data;
But this solution ends up in memory headakes...
2013/7/31 Yasuo Ohgaki yohgaki@ohgaki.net
Hi Julien,
On Wed, Jul 31, 2013 at 6:24 PM, Julien SALLEYRON <
julien.salleyron@gmail.com> wrote:If I EG(execute_data) = EG(execute_data)->prev_execute_data, there is no
loop anymore, but I have freeing errorDon't over write EG(execute_data), but use your own pointer when it is
needed.
I think this will fix your problem.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Julien,
On Wed, Jul 31, 2013 at 10:05 PM, Julien SALLEYRON <
julien.salleyron@gmail.com> wrote:
The problem here is that I have came to the conclusion (wrong conclusion
?) that I need to update the EG(current_execute_data) "as if" the former
called function had been processed, to actually skip the function that was
called in PHP.
I guess I understand what you would like to to. I might be wrong, though.
Maybe some code will be more explicit...
<?php
myFunction(); //the function is expected to be called (and will)
$hook = function () {throw new Exception()};
aop_add_before('myFunction()', $hook); //now we ask the extension to
call hook() before myFunction()myFunction();//Now myFunction should never be called, as the hook is
raising an exceptionExtension-wise, the code is located here (
https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L390), where I test if
the hook raised an exception or not.If it did not, I'm calling the function (
https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L392) and it ends up
updating EG(current_execute_data) with
EG(current_execute_data)->prev_execute_data.Now, when the hook is raising an exception, I'd like to just skip the
function call. If I just "return" (
https://github.com/AOP-PHP/AOP/blob/php5-5/aop.c#L397) it ends up in an
infinite loop. reason why I tried EG (current_execute_data) =
EG(current_execute_data)->prev_execute_data;But this solution ends up in memory headakes..
Unless you clean up EG(current_execute_data) by yourself, I suppose you'll
have memory issues.
If you would like to skip function to be executed, all you have to do is
"do not call zend_execute()/zend_execute_ex()" when the function is called.
$hook = function () {throw new Exception()};
Since your code raise exception, you don't have to skip myfunction(). Just
let PHP die with unhandled exception.
It would be easier if you keep functions in hash to determine hooked one
and call hook as needed/skip function as needed. I might not understand
what you really would like to do, but hope this comment helps.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net