summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-07-08 18:33:58 +0300
committerDmitry Stogov <dmitry@zend.com>2015-07-08 18:33:58 +0300
commit301ee26568af14bafa3938768ac00962bcf2ee66 (patch)
treef2b84e7a1d03772f53bfea21bbe44f56008b7137 /Zend/zend_execute.c
parent993a658adae4813ef55a5d2fe71b453c306d7c84 (diff)
downloadphp-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.c14
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