diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-07-08 18:33:58 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-07-08 18:33:58 +0300 |
commit | 301ee26568af14bafa3938768ac00962bcf2ee66 (patch) | |
tree | f2b84e7a1d03772f53bfea21bbe44f56008b7137 /Zend/zend_execute.c | |
parent | 993a658adae4813ef55a5d2fe71b453c306d7c84 (diff) | |
download | php-git-301ee26568af14bafa3938768ac00962bcf2ee66.tar.gz |
Fixed situation, when CHECH_EXCEPTION() might change value of "opline" variable and the following "opline" useages would access elements of different opcode. That might lead to unpredictable behavior. (Only PHP-7 with GCC global register variables was affected).
CHECK_EXCEPTION() macro is removed. ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTIO() should be used instead. It's equivalent to old CHECK_EXCEPTION() + ZEND_VM_NEXT_OPCODE().
As a side effect, this also slightly improved performnce of builds with GCC >= 4.8.
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 54841e26b5..7aa34bb2df 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2552,11 +2552,21 @@ void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t # endif #endif -#define ZEND_VM_NEXT_OPCODE() \ +#define ZEND_VM_NEXT_OPCODE_EX(check_exception, skip) \ CHECK_SYMBOL_TABLES() \ - ZEND_VM_INC_OPCODE(); \ + if (check_exception) { \ + OPLINE = EX(opline) + (skip); \ + } else { \ + OPLINE = opline + (skip); \ + } \ ZEND_VM_CONTINUE() +#define ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION() \ + ZEND_VM_NEXT_OPCODE_EX(1, 1) + +#define ZEND_VM_NEXT_OPCODE() \ + ZEND_VM_NEXT_OPCODE_EX(0, 1) + #define ZEND_VM_SET_NEXT_OPCODE(new_op) \ CHECK_SYMBOL_TABLES() \ OPLINE = new_op |