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_vm_gen.php | |
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_vm_gen.php')
-rw-r--r-- | Zend/zend_vm_gen.php | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index ff181ce1e7..250b2467e0 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -921,6 +921,8 @@ function gen_null_handler($f) { $done = 1; out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n"); out($f,"{\n"); + out($f,"\tUSE_OPLINE\n"); + out($f,"\n"); out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n"); out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n"); out($f,"}\n\n"); @@ -1030,11 +1032,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) case ZEND_VM_KIND_CALL: out($f,"\n"); out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n"); - out($f,"register zend_execute_data *execute_data __asm__(ZEND_VM_FP_GLOBAL_REG);\n"); + out($f,"register zend_execute_data* volatile execute_data __asm__(ZEND_VM_FP_GLOBAL_REG);\n"); out($f,"#endif\n"); out($f,"\n"); out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n"); - out($f,"register const zend_op *opline __asm__(ZEND_VM_IP_GLOBAL_REG);\n"); + out($f,"register const zend_op* volatile opline __asm__(ZEND_VM_IP_GLOBAL_REG);\n"); out($f,"#endif\n"); out($f,"\n"); out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n"); @@ -1067,23 +1069,24 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#undef DCL_OPLINE\n"); out($f,"#undef USE_OPLINE\n"); out($f,"#undef LOAD_OPLINE\n"); + out($f,"#undef LOAD_OPLINE_EX\n"); out($f,"#undef SAVE_OPLINE\n"); out($f,"#define DCL_OPLINE\n"); out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n"); out($f,"# define OPLINE opline\n"); out($f,"# define USE_OPLINE\n"); out($f,"# define LOAD_OPLINE() opline = EX(opline)\n"); + out($f,"# define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n"); out($f,"# define SAVE_OPLINE() EX(opline) = opline\n"); out($f,"#else\n"); out($f,"# define OPLINE EX(opline)\n"); out($f,"# define USE_OPLINE const zend_op *opline = EX(opline);\n"); out($f,"# define LOAD_OPLINE()\n"); + out($f,"# define LOAD_NEXT_OPLINE() ZEND_VM_INC_OPCODE()\n"); out($f,"# define SAVE_OPLINE()\n"); out($f,"#endif\n"); - out($f,"#undef CHECK_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); - out($f,"#define CHECK_EXCEPTION() LOAD_OPLINE()\n"); out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n"); out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG)\n"); @@ -1105,16 +1108,16 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#undef DCL_OPLINE\n"); out($f,"#undef USE_OPLINE\n"); out($f,"#undef LOAD_OPLINE\n"); + out($f,"#undef LOAD_NEXT_OPLINE\n"); out($f,"#undef SAVE_OPLINE\n"); out($f,"#define OPLINE opline\n"); out($f,"#define DCL_OPLINE const zend_op *opline;\n"); out($f,"#define USE_OPLINE\n"); out($f,"#define LOAD_OPLINE() opline = EX(opline)\n"); + out($f,"#define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n"); out($f,"#define SAVE_OPLINE() EX(opline) = opline\n"); - out($f,"#undef CHECK_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); - out($f,"#define CHECK_EXCEPTION() LOAD_OPLINE()\n"); out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n"); out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n"); @@ -1130,21 +1133,20 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#undef DCL_OPLINE\n"); out($f,"#undef USE_OPLINE\n"); out($f,"#undef LOAD_OPLINE\n"); + out($f,"#undef LOAD_NEXT_OPLINE()\n"); out($f,"#undef SAVE_OPLINE\n"); out($f,"#define OPLINE opline\n"); out($f,"#define DCL_OPLINE const zend_op *opline;\n"); out($f,"#define USE_OPLINE\n"); out($f,"#define LOAD_OPLINE() opline = EX(opline)\n"); + out($f,"#define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n"); out($f,"#define SAVE_OPLINE() EX(opline) = opline\n"); - out($f,"#undef CHECK_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); if (ZEND_VM_SPEC) { - out($f,"#define CHECK_EXCEPTION() if (UNEXPECTED(EG(exception) != NULL)) goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); } else { - out($f,"#define CHECK_EXCEPTION() if (UNEXPECTED(EG(exception) != NULL)) goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); } @@ -1632,16 +1634,16 @@ function gen_vm($def, $skel) { out($f,"#undef DCL_OPLINE\n"); out($f,"#undef USE_OPLINE\n"); out($f,"#undef LOAD_OPLINE\n"); + out($f,"#undef LOAD_NEXT_OPLINE()\n"); out($f,"#undef SAVE_OPLINE\n"); out($f,"#define OPLINE EX(opline)\n"); out($f,"#define DCL_OPLINE\n"); out($f,"#define USE_OPLINE const zend_op *opline = EX(opline);\n"); out($f,"#define LOAD_OPLINE()\n"); + out($f,"#define LOAD_NEXT_OPLINE() ZEND_VM_INC_OPCODE()\n"); out($f,"#define SAVE_OPLINE()\n"); - out($f,"#undef CHECK_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); - out($f,"#define CHECK_EXCEPTION() LOAD_OPLINE()\n"); out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n"); out($f,"#undef ZEND_VM_CONTINUE\n"); |