From 3ef96c2cc6f3a1dddd8479e6c733f44e8dbcb5e9 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 26 Oct 2015 17:09:42 -0700 Subject: [PATCH 01/13] Fixed bug #70656 (require() statement broken after opcache_reset() or a few hours of use) --- NEWS | 6 +++++- ext/opcache/ZendAccelerator.c | 38 +++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index f4e6c8d6f5e..d3f01376ce8 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,13 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2015, PHP 7.0.1 +- Opcache: + . Fixed bug #70656 (require() statement broken after opcache_reset() or a + few hours of use). (Laruence) + - Standard: . Fixed bug #70808 (array_merge_recursive corrupts memory of unset items). - (laruence) + (Laruence) - XSL: . Fixed bug #70678 (PHP7 returns true when false is expected). (Felipe) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index eaadac6e3a9..a7fb07bf379 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -249,24 +249,28 @@ static void accel_interned_strings_restore_state(void) uint nIndex; Bucket *p; - ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top); - while (idx > 0) { - idx--; - p = ZCSG(interned_strings).arData + idx; - if ((char*)p->key < ZCSG(interned_strings_top)) break; - ZCSG(interned_strings).nNumUsed--; - ZCSG(interned_strings).nNumOfElements--; + if (EXPECTED(ZCSG(interned_strings_top) > ZCSG(interned_strings_saved_top))) { + memset(ZCSG(interned_strings_saved_top), + 0, ZCSG(interned_strings_top) - ZCSG(interned_strings_saved_top)); + ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top); + while (idx > 0) { + idx--; + p = ZCSG(interned_strings).arData + idx; + if ((char*)p->key < ZCSG(interned_strings_top)) break; + ZCSG(interned_strings).nNumUsed--; + ZCSG(interned_strings).nNumOfElements--; - nIndex = p->h | ZCSG(interned_strings).nTableMask; - if (HT_HASH(&ZCSG(interned_strings), nIndex) == HT_IDX_TO_HASH(idx)) { - HT_HASH(&ZCSG(interned_strings), nIndex) = Z_NEXT(p->val); - } else { - uint32_t prev = HT_HASH(&ZCSG(interned_strings), nIndex); - while (Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) != idx) { - prev = Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val); - } - Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) = Z_NEXT(p->val); - } + nIndex = p->h | ZCSG(interned_strings).nTableMask; + if (HT_HASH(&ZCSG(interned_strings), nIndex) == HT_IDX_TO_HASH(idx)) { + HT_HASH(&ZCSG(interned_strings), nIndex) = Z_NEXT(p->val); + } else { + uint32_t prev = HT_HASH(&ZCSG(interned_strings), nIndex); + while (Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) != idx) { + prev = Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val); + } + Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) = Z_NEXT(p->val); + } + } } } From 06c6b51e7d680defdb1d2e718af7289b8b5fa600 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 Oct 2015 12:05:54 -0200 Subject: [PATCH 02/13] new tests to openssl module, don't covered yet. --- .../tests/openssl_get_cipher_methods.phpt | 16 ++++++++++++++++ ext/openssl/tests/openssl_get_md_methods.phpt | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 ext/openssl/tests/openssl_get_cipher_methods.phpt create mode 100644 ext/openssl/tests/openssl_get_md_methods.phpt diff --git a/ext/openssl/tests/openssl_get_cipher_methods.phpt b/ext/openssl/tests/openssl_get_cipher_methods.phpt new file mode 100644 index 00000000000..90c7e17c739 --- /dev/null +++ b/ext/openssl/tests/openssl_get_cipher_methods.phpt @@ -0,0 +1,16 @@ +--TEST-- +array openssl_get_cipher_methods ([ bool $aliases = false ] ); +--CREDITS-- +marcosptf - +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +bool(true) \ No newline at end of file diff --git a/ext/openssl/tests/openssl_get_md_methods.phpt b/ext/openssl/tests/openssl_get_md_methods.phpt new file mode 100644 index 00000000000..28f8abfe89c --- /dev/null +++ b/ext/openssl/tests/openssl_get_md_methods.phpt @@ -0,0 +1,16 @@ +--TEST-- +array openssl_get_md_methods ([ bool $aliases = false ] ); +--CREDITS-- +marcosptf - +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +bool(true) \ No newline at end of file From e62db721114f60c7e8a9ff8c3ddc38d5a40b84be Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 29 Oct 2015 19:11:57 +0000 Subject: [PATCH 03/13] Use standard title for new openssl tests --- ext/openssl/tests/openssl_get_cipher_methods.phpt | 4 ++-- ext/openssl/tests/openssl_get_md_methods.phpt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/openssl/tests/openssl_get_cipher_methods.phpt b/ext/openssl/tests/openssl_get_cipher_methods.phpt index 90c7e17c739..cae223f4c47 100644 --- a/ext/openssl/tests/openssl_get_cipher_methods.phpt +++ b/ext/openssl/tests/openssl_get_cipher_methods.phpt @@ -1,5 +1,5 @@ --TEST-- -array openssl_get_cipher_methods ([ bool $aliases = false ] ); +openssl_get_cipher_methods basic test --CREDITS-- marcosptf - --SKIPIF-- @@ -13,4 +13,4 @@ var_dump(is_array(openssl_get_cipher_methods(false))); ?> --EXPECT-- bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/openssl/tests/openssl_get_md_methods.phpt b/ext/openssl/tests/openssl_get_md_methods.phpt index 28f8abfe89c..b35e55d69f5 100644 --- a/ext/openssl/tests/openssl_get_md_methods.phpt +++ b/ext/openssl/tests/openssl_get_md_methods.phpt @@ -1,5 +1,5 @@ --TEST-- -array openssl_get_md_methods ([ bool $aliases = false ] ); +openssl_get_md_methods basic test --CREDITS-- marcosptf - --SKIPIF-- @@ -13,4 +13,4 @@ var_dump(is_array(openssl_get_md_methods(false))); ?> --EXPECT-- bool(true) -bool(true) \ No newline at end of file +bool(true) From 3c5a3e77d4d56b08747205faba22dfcc6b2b569b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Oct 2015 07:15:56 +0300 Subject: [PATCH 04/13] Fixed incomplete initialization. --- sapi/phpdbg/phpdbg_list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c index dfacc0f5337..5a4ca215832 100644 --- a/sapi/phpdbg/phpdbg_list.c +++ b/sapi/phpdbg/phpdbg_list.c @@ -234,7 +234,7 @@ void phpdbg_list_function_byname(const char *str, size_t len) /* {{{ */ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) { phpdbg_file_source data, *dataptr; - zend_file_handle fake = {{0}}; + zend_file_handle fake; zend_op_array *ret; char *filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename); uint line; @@ -253,11 +253,11 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) { data.filename = filename; data.line[0] = 0; + memset(&fake, 0, sizeof(fake)); fake.type = ZEND_HANDLE_MAPPED; fake.handle.stream.mmap.buf = data.buf; fake.handle.stream.mmap.len = data.len; fake.free_filename = 0; - fake.opened_path = file->opened_path; fake.filename = filename; fake.opened_path = file->opened_path; From d83600a2d5d40b1785a0bbe5188f626c736ec93f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 28 Oct 2015 23:25:05 +0300 Subject: [PATCH 05/13] Added zend_get_opcode_flags() function to get information about opcode operands and extended_value meaning --- Zend/zend_vm_def.h | 146 +++++++++++++++---------------- Zend/zend_vm_gen.php | 140 +++++++++++++++++++++++++++--- Zend/zend_vm_opcodes.c | 192 ++++++++++++++++++++++++++++++++++++++++- Zend/zend_vm_opcodes.h | 28 ++++++ 4 files changed, 419 insertions(+), 87 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3296eaaedff..6089ab05248 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -872,7 +872,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -892,7 +892,7 @@ ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -912,7 +912,7 @@ ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -932,7 +932,7 @@ ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -952,7 +952,7 @@ ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -972,7 +972,7 @@ ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -992,7 +992,7 @@ ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -1012,7 +1012,7 @@ ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -1032,7 +1032,7 @@ ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -1052,7 +1052,7 @@ ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -1072,7 +1072,7 @@ ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -1092,7 +1092,7 @@ ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) #endif } -ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE @@ -1564,22 +1564,22 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int ty ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R); } -ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W); } -ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW); } -ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { USE_OPLINE @@ -1590,12 +1590,12 @@ ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED) } } -ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET); } -ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS); } @@ -2514,7 +2514,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) } } -ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY) +ZEND_VM_HANDLER(42, ZEND_JMP, ADDR, ANY) { USE_OPLINE @@ -2522,7 +2522,7 @@ ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY) ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2557,7 +2557,7 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2591,7 +2591,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ADDR, REL_LINE) { USE_OPLINE zend_free_op free_op1; @@ -2628,7 +2628,7 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2671,7 +2671,7 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2801,7 +2801,7 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -2834,7 +2834,7 @@ ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -2867,7 +2867,7 @@ ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -2920,7 +2920,7 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV, CLASS_FETCH) { USE_OPLINE @@ -2963,7 +2963,7 @@ ZEND_VM_C_LABEL(try_class_name): } } -ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV, NUM) { USE_OPLINE zval *function_name; @@ -3084,7 +3084,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CONST|VAR, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CONST|VAR, CONST|TMPVAR|UNUSED|CV, NUM) { USE_OPLINE zval *function_name; @@ -3220,7 +3220,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CONST|VAR, CONST|TMPVA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST) +ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM) { USE_OPLINE zend_function *fbc; @@ -3247,7 +3247,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_function *fbc; @@ -3460,7 +3460,7 @@ ZEND_VM_C_LABEL(try_function_name): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -3519,7 +3519,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) +ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM) { USE_OPLINE zval *func_name; @@ -3552,7 +3552,7 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST) +ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST, NUM) { USE_OPLINE zend_free_op free_op2; @@ -4205,7 +4205,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) +ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, LINE) { USE_OPLINE zend_class_entry *ce, *catch_ce; @@ -4255,7 +4255,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) } } -ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) +ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, NUM) { USE_OPLINE zval *value, *arg; @@ -4272,7 +4272,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, ANY) +ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, NUM) { USE_OPLINE zval *value, *arg; @@ -4303,7 +4303,7 @@ ZEND_VM_C_LABEL(send_val_by_ref): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY) +ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM) { USE_OPLINE zval *varptr, *arg; @@ -4342,7 +4342,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, ANY) +ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, NUM) { USE_OPLINE zend_free_op free_op1; @@ -4379,7 +4379,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) +ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, NUM) { USE_OPLINE zend_free_op free_op1; @@ -4414,7 +4414,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY) +ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, NUM) { USE_OPLINE zval *varptr, *arg; @@ -4725,7 +4725,7 @@ ZEND_VM_C_LABEL(send_array): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY) +ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, NUM) { USE_OPLINE zval *arg, *param; @@ -4780,7 +4780,7 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY) +ZEND_VM_HANDLER(63, ZEND_RECV, NUM, ANY) { USE_OPLINE uint32_t arg_num = opline->op1.num; @@ -4801,7 +4801,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) +ZEND_VM_HANDLER(64, ZEND_RECV_INIT, NUM, CONST) { USE_OPLINE uint32_t arg_num; @@ -4840,7 +4840,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY) +ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, ANY) { USE_OPLINE uint32_t arg_num = opline->op1.num; @@ -4971,7 +4971,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CONST|VAR, ANY) +ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CONST|VAR, ADDR, NUM) { USE_OPLINE zval object_zval; @@ -5106,7 +5106,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST) +ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH) { USE_OPLINE zend_constant *c; @@ -5225,7 +5225,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|CV, NUM) { USE_OPLINE zend_free_op free_op1; @@ -5324,7 +5324,7 @@ ZEND_VM_C_LABEL(num_index): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, ARRAY_INIT) { zval *array; uint32_t size; @@ -5355,7 +5355,7 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSE } } -ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) { USE_OPLINE zend_free_op free_op1; @@ -5457,7 +5457,7 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL) { USE_OPLINE zend_op_array *new_op_array=NULL; @@ -5586,7 +5586,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { USE_OPLINE zval tmp, *varname; @@ -5828,7 +5828,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -5933,7 +5933,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, ANY) } } -ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -6097,7 +6097,7 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ANY) } } -ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY) +ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, REL_LINE) { USE_OPLINE zval *array; @@ -6274,7 +6274,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY) +ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, REL_LINE) { USE_OPLINE zval *array; @@ -6475,7 +6475,7 @@ ZEND_VM_C_LABEL(fe_fetch_w_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED) +ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { USE_OPLINE zval *value; @@ -6533,7 +6533,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED) } } -ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR, ISSET) { USE_OPLINE zval *value; @@ -6609,7 +6609,7 @@ ZEND_VM_C_LABEL(is_static_prop_return): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV, ISSET) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -6746,7 +6746,7 @@ ZEND_VM_C_LABEL(isset_dim_obj_exit): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV, ISSET) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -6865,7 +6865,7 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -6904,7 +6904,7 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, ADDR) { USE_OPLINE zend_free_op free_op1; @@ -7023,7 +7023,7 @@ ZEND_VM_HANDLER(139, ZEND_DECLARE_CLASS, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, ANY) +ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, ANY, VAR) { USE_OPLINE @@ -7032,7 +7032,7 @@ ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY) +ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY, VAR) { USE_OPLINE zval *zce, *orig_zce; @@ -7046,7 +7046,7 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY) +ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ADDR, ANY) { zend_class_entry *ce; USE_OPLINE @@ -7067,7 +7067,7 @@ ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ANY, ANY) +ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ADDR, ANY, VAR) { zend_class_entry *ce; USE_OPLINE @@ -7095,7 +7095,7 @@ ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY) +ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM) { USE_OPLINE @@ -7671,7 +7671,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY) +ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ADDR, LINE, FCALL) { USE_OPLINE zval *fast_call = EX_VAR(opline->result.var); @@ -7687,7 +7687,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY) ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY) +ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, LINE, FRET) { USE_OPLINE zval *fast_call = EX_VAR(opline->op1.var); @@ -7857,7 +7857,7 @@ ZEND_VM_C_LABEL(try_strlen): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY, TYPE) { USE_OPLINE zval *value; @@ -7913,7 +7913,7 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY) +ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ADDR) { USE_OPLINE @@ -7930,7 +7930,7 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY) } } -ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY) +ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY, CLASS_FETCH) { uint32_t fetch_type; USE_OPLINE diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 613b4c9338d..35b865731cf 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -54,6 +54,71 @@ define("ZEND_VM_KIND_CALL", 1); define("ZEND_VM_KIND_SWITCH", 2); define("ZEND_VM_KIND_GOTO", 3); +$vm_op_flags = array( + "ZEND_VM_OP1_SPEC" => 1<<0, + "ZEND_VM_OP1_CONST" => 1<<1, + "ZEND_VM_OP1_TMPVAR" => 1<<2, + "ZEND_VM_OP1_NUM" => 1<<3, + "ZEND_VM_OP1_ADDR" => 1<<4, + "ZEND_VM_OP1_LINE" => 1<<5, + + "ZEND_VM_OP2_SPEC" => 1<<8, + "ZEND_VM_OP2_CONST" => 1<<9, + "ZEND_VM_OP2_TMPVAR" => 1<<10, + "ZEND_VM_OP2_NUM" => 1<<11, + "ZEND_VM_OP2_ADDR" => 1<<12, + "ZEND_VM_OP2_LINE" => 1<<13, + + "ZEND_VM_EXT_NUM" => 1<<16, + "ZEND_VM_EXT_VAR" => 1<<17, + "ZEND_VM_EXT_LINE" => 1<<18, + "ZEND_VM_EXT_REL_LINE" => 1<<19, + "ZEND_VM_EXT_DIM_OBJ" => 1<<20, + "ZEND_VM_EXT_CLASS_FETCH" => 1<<21, + "ZEND_VM_EXT_CONST_FETCH" => 1<<22, + "ZEND_VM_EXT_VAR_FETCH" => 1<<23, + "ZEND_VM_EXT_ARRAY_INIT" => 1<<24, + "ZEND_VM_EXT_TYPE" => 1<<25, + "ZEND_VM_EXT_EVAL" => 1<<26, + "ZEND_VM_EXT_FCALL" => 1<<27, + "ZEND_VM_EXT_FRET" => 1<<28, + "ZEND_VM_EXT_ISSET" => 1<<29, +); + +foreach ($vm_op_flags as $name => $val) { + define($name, $val); +} + +$vm_op_decode = array( + "ANY" => 0, + "CONST" => ZEND_VM_OP1_SPEC | ZEND_VM_OP1_CONST, + "TMP" => ZEND_VM_OP1_SPEC, + "VAR" => ZEND_VM_OP1_SPEC, + "UNUSED" => ZEND_VM_OP1_SPEC, + "CV" => ZEND_VM_OP1_SPEC, + "TMPVAR" => ZEND_VM_OP1_SPEC | ZEND_VM_OP1_TMPVAR, + "NUM" => ZEND_VM_OP1_NUM, + "ADDR" => ZEND_VM_OP1_ADDR, + "LINE" => ZEND_VM_OP1_LINE, +); + +$vm_ext_decode = array( + "NUM" => ZEND_VM_EXT_NUM, + "VAR" => ZEND_VM_EXT_VAR, + "LINE" => ZEND_VM_EXT_LINE, + "REL_LINE" => ZEND_VM_EXT_REL_LINE, + "DIM_OBJ" => ZEND_VM_EXT_DIM_OBJ, + "CLASS_FETCH" => ZEND_VM_EXT_CLASS_FETCH, + "CONST_FETCH" => ZEND_VM_EXT_CONST_FETCH, + "VAR_FETCH" => ZEND_VM_EXT_VAR_FETCH, + "ARRAY_INIT" => ZEND_VM_EXT_ARRAY_INIT, + "TYPE" => ZEND_VM_EXT_TYPE, + "EVAL" => ZEND_VM_EXT_EVAL, + "FCALL" => ZEND_VM_EXT_FCALL, + "FRET" => ZEND_VM_EXT_FRET, + "ISSET" => ZEND_VM_EXT_ISSET, +); + $vm_kind_name = array( ZEND_VM_KIND_CALL => "ZEND_VM_KIND_CALL", ZEND_VM_KIND_SWITCH => "ZEND_VM_KIND_SWITCH", @@ -1310,9 +1375,41 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) } } +function parse_operand_spec($def, $lineno, $str, &$flags) { + global $vm_op_decode; + + $flags = 0; + $a = explode("|",$str); + foreach($a as $val) { + if (isset($vm_op_decode[$val])) { + $flags |= $vm_op_decode[$val]; + } else { + die("ERROR ($def:$lineno): Wrong operand type '$str'\n"); + } + } + if (!($flags & ZEND_VM_OP1_SPEC)) { + if (count($a) != 1) { + die("ERROR ($def:$lineno): Wrong operand type '$str'\n"); + } + $a = array("ANY"); + } + return array_flip($a); +} + +function parse_ext_spec($def, $lineno, $str) { + global $vm_ext_decode; + + if (isset($vm_ext_decode[$str])) { + return $vm_ext_decode[$str]; + } else { + die("ERROR ($def:$lineno): Wrong extended_value type '$str'\n"); + } +} + function gen_vm($def, $skel) { global $definition_file, $skeleton_file, $executor_file, - $op_types, $list, $opcodes, $helpers, $params, $opnames; + $op_types, $list, $opcodes, $helpers, $params, $opnames, + $vm_op_flags; // Load definition file $in = @file($def); @@ -1342,7 +1439,7 @@ function gen_vm($def, $skel) { if (strpos($line,"ZEND_VM_HANDLER(") === 0) { // Parsing opcode handler's definition if (preg_match( - "/^ZEND_VM_HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*\)/", + "/^ZEND_VM_HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*(,\s*([A-Z_|]+)\s*)?\)/", $line, $m) == 0) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HANDLER definition.\n"); @@ -1350,8 +1447,12 @@ function gen_vm($def, $skel) { $code = (int)$m[1]; $op = $m[2]; $len = strlen($op); - $op1 = array_flip(explode("|",$m[3])); - $op2 = array_flip(explode("|",$m[4])); + $op1 = parse_operand_spec($def, $lineno, $m[3], $flags1); + $op2 = parse_operand_spec($def, $lineno, $m[4], $flags2); + $flags = $flags1 | ($flags2 << 8); + if (isset($m[6])) { + $flags |= parse_ext_spec($def, $lineno, $m[6]); + } if ($len > $max_opcode_len) { $max_opcode_len = $len; @@ -1365,7 +1466,7 @@ function gen_vm($def, $skel) { if (isset($opnames[$op])) { die("ERROR ($def:$lineno): Opcode with name '$op' is already defined.\n"); } - $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>""); + $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags); $opnames[$op] = $code; $handler = $code; $helper = null; @@ -1379,8 +1480,8 @@ function gen_vm($def, $skel) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n"); } $helper = $m[1]; - $op1 = array_flip(explode("|",$m[2])); - $op2 = array_flip(explode("|",$m[3])); + $op1 = parse_operand_spec($def, $lineno, $m[2], $flags1); + $op2 = parse_operand_spec($def, $lineno, $m[3], $flags2); if (isset($helpers[$helper])) { die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n"); } @@ -1396,8 +1497,8 @@ function gen_vm($def, $skel) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n"); } $helper = $m[1]; - $op1 = array_flip(explode("|",$m[2])); - $op2 = array_flip(explode("|",$m[3])); + $op1 = parse_operand_spec($def, $lineno, $m[2], $flags1); + $op2 = parse_operand_spec($def, $lineno, $m[3], $flags2); $param = $m[4]; if (isset($helpers[$helper])) { die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n"); @@ -1493,8 +1594,13 @@ function gen_vm($def, $skel) { fputs($f, "#define ZEND_VM_KIND_GOTO\t" . ZEND_VM_KIND_GOTO . "\n"); fputs($f, "#define ZEND_VM_KIND\t\t" . $GLOBALS["vm_kind_name"][ZEND_VM_KIND] . "\n"); fputs($f, "\n"); + foreach($vm_op_flags as $name => $val) { + fprintf($f, "#define %-24s 0x%08x\n", $name, $val); + } + fputs($f, "\n"); fputs($f, "BEGIN_EXTERN_C()\n\n"); - fputs($f, "ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);\n\n"); + fputs($f, "ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);\n"); + fputs($f, "ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode);\n\n"); fputs($f, "END_EXTERN_C()\n\n"); foreach ($opcodes as $code => $dsc) { @@ -1515,14 +1621,24 @@ function gen_vm($def, $skel) { fputs($f,"#include \n"); fputs($f,"#include \n\n"); - fputs($f,"const char *zend_vm_opcodes_map[".($max_opcode + 1)."] = {\n"); + fputs($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n"); for ($i = 0; $i <= $max_opcode; $i++) { fputs($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n"); } fputs($f, "};\n\n"); + fputs($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n"); + for ($i = 0; $i <= $max_opcode; $i++) { + fprintf($f, "\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0); + } + fputs($f, "};\n\n"); + fputs($f, "ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {\n"); - fputs($f, "\treturn zend_vm_opcodes_map[opcode];\n"); + fputs($f, "\treturn zend_vm_opcodes_names[opcode];\n"); + fputs($f, "}\n"); + + fputs($f, "ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode) {\n"); + fputs($f, "\treturn zend_vm_opcodes_flags[opcode];\n"); fputs($f, "}\n"); fclose($f); diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 000d39044b9..4b2913b5e14 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -21,7 +21,7 @@ #include #include -const char *zend_vm_opcodes_map[182] = { +static const char *zend_vm_opcodes_names[182] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -206,6 +206,194 @@ const char *zend_vm_opcodes_map[182] = { "ZEND_FETCH_CLASS_CONSTANT", }; +static uint32_t zend_vm_opcodes_flags[182] = { + 0x00000000, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000007, + 0x00000007, + 0x00000707, + 0x00000303, + 0x00000303, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x02000003, + 0x00000003, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00100701, + 0x00000001, + 0x00000001, + 0x00000001, + 0x00000001, + 0x00000301, + 0x00000101, + 0x00000007, + 0x00000000, + 0x00000010, + 0x00001007, + 0x00001007, + 0x00081007, + 0x00001007, + 0x00001007, + 0x00000707, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000007, + 0x00000707, + 0x00010701, + 0x00010701, + 0x00010701, + 0x00000000, + 0x00000001, + 0x00010300, + 0x00000000, + 0x00010300, + 0x00000003, + 0x00000008, + 0x00000308, + 0x00000803, + 0x00000801, + 0x00000801, + 0x00011003, + 0x00010300, + 0x00000005, + 0x01000703, + 0x00010703, + 0x04000007, + 0x00800107, + 0x00000701, + 0x00000701, + 0x00001003, + 0x00080001, + 0x00000007, + 0x00800107, + 0x00000707, + 0x00000703, + 0x00800107, + 0x00000701, + 0x00000701, + 0x00800107, + 0x00000701, + 0x00000701, + 0x00800107, + 0x00000707, + 0x00000707, + 0x00800107, + 0x00000703, + 0x00000703, + 0x00800107, + 0x00000701, + 0x00000701, + 0x00000307, + 0x00400301, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00010000, + 0x00000801, + 0x00040103, + 0x00000003, + 0x00200700, + 0x00000007, + 0x00000003, + 0x00010707, + 0x00010703, + 0x00800107, + 0x20000707, + 0x00000803, + 0x00000801, + 0x00010703, + 0x00000000, + 0x00000801, + 0x00000007, + 0x00000003, + 0x02000003, + 0x00000103, + 0x00001003, + 0x00080001, + 0x00000005, + 0x00010700, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000701, + 0x00000701, + 0x00000701, + 0x00000701, + 0x00000701, + 0x00000000, + 0x00000305, + 0x00000000, + 0x00020000, + 0x00000000, + 0x00000003, + 0x00000303, + 0x00000300, + 0x00020000, + 0x00000000, + 0x00000701, + 0x20000707, + 0x00000000, + 0x00000000, + 0x00001000, + 0x00001003, + 0x00000103, + 0x00000000, + 0x00000000, + 0x00000101, + 0x00200000, + 0x00000000, + 0x00000000, + 0x00000303, + 0x00000003, + 0x08002010, + 0x10002000, + 0x00000008, + 0x00000000, + 0x00000707, + 0x00100701, + 0x00000301, + 0x00001003, + 0x00000707, + 0x00000010, + 0x00020010, + 0x00000307, + 0x00000307, + 0x00000307, + 0x00000307, + 0x00000307, + 0x00000307, + 0x00000307, + 0x20000307, + 0x00000303, +}; + ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) { - return zend_vm_opcodes_map[opcode]; + return zend_vm_opcodes_names[opcode]; +} +ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode) { + return zend_vm_opcodes_flags[opcode]; } diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index c6fa3a1dc57..72a04699e0f 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -28,9 +28,37 @@ #define ZEND_VM_KIND_GOTO 3 #define ZEND_VM_KIND ZEND_VM_KIND_CALL +#define ZEND_VM_OP1_SPEC 0x00000001 +#define ZEND_VM_OP1_CONST 0x00000002 +#define ZEND_VM_OP1_TMPVAR 0x00000004 +#define ZEND_VM_OP1_NUM 0x00000008 +#define ZEND_VM_OP1_ADDR 0x00000010 +#define ZEND_VM_OP1_LINE 0x00000020 +#define ZEND_VM_OP2_SPEC 0x00000100 +#define ZEND_VM_OP2_CONST 0x00000200 +#define ZEND_VM_OP2_TMPVAR 0x00000400 +#define ZEND_VM_OP2_NUM 0x00000800 +#define ZEND_VM_OP2_ADDR 0x00001000 +#define ZEND_VM_OP2_LINE 0x00002000 +#define ZEND_VM_EXT_NUM 0x00010000 +#define ZEND_VM_EXT_VAR 0x00020000 +#define ZEND_VM_EXT_LINE 0x00040000 +#define ZEND_VM_EXT_REL_LINE 0x00080000 +#define ZEND_VM_EXT_DIM_OBJ 0x00100000 +#define ZEND_VM_EXT_CLASS_FETCH 0x00200000 +#define ZEND_VM_EXT_CONST_FETCH 0x00400000 +#define ZEND_VM_EXT_VAR_FETCH 0x00800000 +#define ZEND_VM_EXT_ARRAY_INIT 0x01000000 +#define ZEND_VM_EXT_TYPE 0x02000000 +#define ZEND_VM_EXT_EVAL 0x04000000 +#define ZEND_VM_EXT_FCALL 0x08000000 +#define ZEND_VM_EXT_FRET 0x10000000 +#define ZEND_VM_EXT_ISSET 0x20000000 + BEGIN_EXTERN_C() ZEND_API const char *zend_get_opcode_name(zend_uchar opcode); +ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode); END_EXTERN_C() From 5c65fc29adce41c4a33ff8def971de96ad01d5dc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 29 Oct 2015 09:15:37 +0300 Subject: [PATCH 06/13] Fixed few issues: - Added ZEND_VM_LAST_OPCODE macro - Use better names LINE->OPLINE, REL_LINE->REL_OPLINE, FCALL->FAST_CALL, FRET->FAST_RET - Added ISSET flag to extended value of ZEND_ISSET_ISEMPTY_VAR opcode --- Zend/zend_vm_def.h | 14 +++++++------- Zend/zend_vm_gen.php | 39 ++++++++++++++++++++++++--------------- Zend/zend_vm_opcodes.c | 2 +- Zend/zend_vm_opcodes.h | 14 ++++++++------ 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 6089ab05248..41040596e04 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2591,7 +2591,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ADDR) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ADDR, REL_LINE) +ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ADDR, REL_OPLINE) { USE_OPLINE zend_free_op free_op1; @@ -4205,7 +4205,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, LINE) +ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, OPLINE) { USE_OPLINE zend_class_entry *ce, *catch_ce; @@ -6097,7 +6097,7 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ADDR) } } -ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, REL_LINE) +ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, REL_OPLINE) { USE_OPLINE zval *array; @@ -6274,7 +6274,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, REL_LINE) +ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, REL_OPLINE) { USE_OPLINE zval *array; @@ -6475,7 +6475,7 @@ ZEND_VM_C_LABEL(fe_fetch_w_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET) { USE_OPLINE zval *value; @@ -7671,7 +7671,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ADDR, LINE, FCALL) +ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ADDR, OPLINE, FAST_CALL) { USE_OPLINE zval *fast_call = EX_VAR(opline->result.var); @@ -7687,7 +7687,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ADDR, LINE, FCALL) ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, LINE, FRET) +ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, OPLINE, FAST_RET) { USE_OPLINE zval *fast_call = EX_VAR(opline->op1.var); diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 35b865731cf..2f93acc1d60 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -60,19 +60,19 @@ $vm_op_flags = array( "ZEND_VM_OP1_TMPVAR" => 1<<2, "ZEND_VM_OP1_NUM" => 1<<3, "ZEND_VM_OP1_ADDR" => 1<<4, - "ZEND_VM_OP1_LINE" => 1<<5, + "ZEND_VM_OP1_OPLINE" => 1<<5, "ZEND_VM_OP2_SPEC" => 1<<8, "ZEND_VM_OP2_CONST" => 1<<9, "ZEND_VM_OP2_TMPVAR" => 1<<10, "ZEND_VM_OP2_NUM" => 1<<11, "ZEND_VM_OP2_ADDR" => 1<<12, - "ZEND_VM_OP2_LINE" => 1<<13, + "ZEND_VM_OP2_OPLINE" => 1<<13, "ZEND_VM_EXT_NUM" => 1<<16, "ZEND_VM_EXT_VAR" => 1<<17, - "ZEND_VM_EXT_LINE" => 1<<18, - "ZEND_VM_EXT_REL_LINE" => 1<<19, + "ZEND_VM_EXT_OPLINE" => 1<<18, + "ZEND_VM_EXT_REL_OPLINE" => 1<<19, "ZEND_VM_EXT_DIM_OBJ" => 1<<20, "ZEND_VM_EXT_CLASS_FETCH" => 1<<21, "ZEND_VM_EXT_CONST_FETCH" => 1<<22, @@ -80,8 +80,8 @@ $vm_op_flags = array( "ZEND_VM_EXT_ARRAY_INIT" => 1<<24, "ZEND_VM_EXT_TYPE" => 1<<25, "ZEND_VM_EXT_EVAL" => 1<<26, - "ZEND_VM_EXT_FCALL" => 1<<27, - "ZEND_VM_EXT_FRET" => 1<<28, + "ZEND_VM_EXT_FAST_CALL" => 1<<27, + "ZEND_VM_EXT_FAST_RET" => 1<<28, "ZEND_VM_EXT_ISSET" => 1<<29, ); @@ -99,14 +99,14 @@ $vm_op_decode = array( "TMPVAR" => ZEND_VM_OP1_SPEC | ZEND_VM_OP1_TMPVAR, "NUM" => ZEND_VM_OP1_NUM, "ADDR" => ZEND_VM_OP1_ADDR, - "LINE" => ZEND_VM_OP1_LINE, + "OPLINE" => ZEND_VM_OP1_OPLINE, ); $vm_ext_decode = array( "NUM" => ZEND_VM_EXT_NUM, "VAR" => ZEND_VM_EXT_VAR, - "LINE" => ZEND_VM_EXT_LINE, - "REL_LINE" => ZEND_VM_EXT_REL_LINE, + "OPLINE" => ZEND_VM_EXT_OPLINE, + "REL_OPLINE" => ZEND_VM_EXT_REL_OPLINE, "DIM_OBJ" => ZEND_VM_EXT_DIM_OBJ, "CLASS_FETCH" => ZEND_VM_EXT_CLASS_FETCH, "CONST_FETCH" => ZEND_VM_EXT_CONST_FETCH, @@ -114,8 +114,8 @@ $vm_ext_decode = array( "ARRAY_INIT" => ZEND_VM_EXT_ARRAY_INIT, "TYPE" => ZEND_VM_EXT_TYPE, "EVAL" => ZEND_VM_EXT_EVAL, - "FCALL" => ZEND_VM_EXT_FCALL, - "FRET" => ZEND_VM_EXT_FRET, + "FAST_CALL" => ZEND_VM_EXT_FAST_CALL, + "FAST_RET" => ZEND_VM_EXT_FAST_RET, "ISSET" => ZEND_VM_EXT_ISSET, ); @@ -1399,11 +1399,16 @@ function parse_operand_spec($def, $lineno, $str, &$flags) { function parse_ext_spec($def, $lineno, $str) { global $vm_ext_decode; - if (isset($vm_ext_decode[$str])) { - return $vm_ext_decode[$str]; - } else { - die("ERROR ($def:$lineno): Wrong extended_value type '$str'\n"); + $flags = 0; + $a = explode("|",$str); + foreach($a as $val) { + if (isset($vm_ext_decode[$val])) { + $flags |= $vm_ext_decode[$val]; + } else { + die("ERROR ($def:$lineno): Wrong extended_value type '$str'\n"); + } } + return $flags; } function gen_vm($def, $skel) { @@ -1609,6 +1614,10 @@ function gen_vm($def, $skel) { fputs($f,"#define $op $code\n"); } + $code = str_pad((string)$max_opcode,$code_len," ",STR_PAD_LEFT); + $op = str_pad("ZEND_VM_LAST_OPCODE",$max_opcode_len); + fputs($f,"\n#define $op $code\n"); + fputs($f, "\n#endif\n"); fclose($f); echo "zend_vm_opcodes.h generated successfully.\n"; diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 4b2913b5e14..d575e04a282 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -321,7 +321,7 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00000003, 0x00010707, 0x00010703, - 0x00800107, + 0x20800107, 0x20000707, 0x00000803, 0x00000801, diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 72a04699e0f..2eab6e75859 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -33,17 +33,17 @@ #define ZEND_VM_OP1_TMPVAR 0x00000004 #define ZEND_VM_OP1_NUM 0x00000008 #define ZEND_VM_OP1_ADDR 0x00000010 -#define ZEND_VM_OP1_LINE 0x00000020 +#define ZEND_VM_OP1_OPLINE 0x00000020 #define ZEND_VM_OP2_SPEC 0x00000100 #define ZEND_VM_OP2_CONST 0x00000200 #define ZEND_VM_OP2_TMPVAR 0x00000400 #define ZEND_VM_OP2_NUM 0x00000800 #define ZEND_VM_OP2_ADDR 0x00001000 -#define ZEND_VM_OP2_LINE 0x00002000 +#define ZEND_VM_OP2_OPLINE 0x00002000 #define ZEND_VM_EXT_NUM 0x00010000 #define ZEND_VM_EXT_VAR 0x00020000 -#define ZEND_VM_EXT_LINE 0x00040000 -#define ZEND_VM_EXT_REL_LINE 0x00080000 +#define ZEND_VM_EXT_OPLINE 0x00040000 +#define ZEND_VM_EXT_REL_OPLINE 0x00080000 #define ZEND_VM_EXT_DIM_OBJ 0x00100000 #define ZEND_VM_EXT_CLASS_FETCH 0x00200000 #define ZEND_VM_EXT_CONST_FETCH 0x00400000 @@ -51,8 +51,8 @@ #define ZEND_VM_EXT_ARRAY_INIT 0x01000000 #define ZEND_VM_EXT_TYPE 0x02000000 #define ZEND_VM_EXT_EVAL 0x04000000 -#define ZEND_VM_EXT_FCALL 0x08000000 -#define ZEND_VM_EXT_FRET 0x10000000 +#define ZEND_VM_EXT_FAST_CALL 0x08000000 +#define ZEND_VM_EXT_FAST_RET 0x10000000 #define ZEND_VM_EXT_ISSET 0x20000000 BEGIN_EXTERN_C() @@ -240,4 +240,6 @@ END_EXTERN_C() #define ZEND_ISSET_ISEMPTY_STATIC_PROP 180 #define ZEND_FETCH_CLASS_CONSTANT 181 +#define ZEND_VM_LAST_OPCODE 181 + #endif From 9ccb432cab331e3905e4c746324d0bd6dc31286a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 29 Oct 2015 22:50:45 +0300 Subject: [PATCH 07/13] Argument type renaming (ADDR->JMP_ADDR, OPLINE->JMP_ABS, REL_OPLINE->JMP_REL) --- Zend/zend_vm_def.h | 38 +++++++++++++++++++------------------- Zend/zend_vm_gen.php | 26 +++++++++++++------------- Zend/zend_vm_opcodes.h | 12 ++++++------ 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 41040596e04..3e34be18cdd 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2514,7 +2514,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) } } -ZEND_VM_HANDLER(42, ZEND_JMP, ADDR, ANY) +ZEND_VM_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY) { USE_OPLINE @@ -2522,7 +2522,7 @@ ZEND_VM_HANDLER(42, ZEND_JMP, ADDR, ANY) ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ADDR) +ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2557,7 +2557,7 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ADDR) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ADDR) +ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2591,7 +2591,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ADDR) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ADDR, REL_OPLINE) +ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_REL) { USE_OPLINE zend_free_op free_op1; @@ -2628,7 +2628,7 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ADDR, REL_OPLINE) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ADDR) +ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2671,7 +2671,7 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ADDR) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, ADDR) +ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -4205,7 +4205,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, OPLINE) +ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ABS) { USE_OPLINE zend_class_entry *ce, *catch_ce; @@ -4971,7 +4971,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CONST|VAR, ADDR, NUM) +ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CONST|VAR, JMP_ADDR, NUM) { USE_OPLINE zval object_zval; @@ -5828,7 +5828,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, ADDR) +ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -5933,7 +5933,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, ADDR) } } -ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ADDR) +ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -6097,7 +6097,7 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ADDR) } } -ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, REL_OPLINE) +ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_REL) { USE_OPLINE zval *array; @@ -6274,7 +6274,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, REL_OPLINE) +ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_REL) { USE_OPLINE zval *array; @@ -6865,7 +6865,7 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ADDR) +ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -6904,7 +6904,7 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ADDR) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, ADDR) +ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -7046,7 +7046,7 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY, VAR) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ADDR, ANY) +ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, JMP_ADDR, ANY) { zend_class_entry *ce; USE_OPLINE @@ -7067,7 +7067,7 @@ ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ADDR, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ADDR, ANY, VAR) +ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, JMP_ADDR, ANY, VAR) { zend_class_entry *ce; USE_OPLINE @@ -7671,7 +7671,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ADDR, OPLINE, FAST_CALL) +ZEND_VM_HANDLER(162, ZEND_FAST_CALL, JMP_ADDR, JMP_ABS, FAST_CALL) { USE_OPLINE zval *fast_call = EX_VAR(opline->result.var); @@ -7687,7 +7687,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ADDR, OPLINE, FAST_CALL) ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, OPLINE, FAST_RET) +ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, JMP_ABS, FAST_RET) { USE_OPLINE zval *fast_call = EX_VAR(opline->op1.var); @@ -7913,7 +7913,7 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ADDR) +ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR) { USE_OPLINE diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 2f93acc1d60..5c5a9aa289e 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -59,20 +59,20 @@ $vm_op_flags = array( "ZEND_VM_OP1_CONST" => 1<<1, "ZEND_VM_OP1_TMPVAR" => 1<<2, "ZEND_VM_OP1_NUM" => 1<<3, - "ZEND_VM_OP1_ADDR" => 1<<4, - "ZEND_VM_OP1_OPLINE" => 1<<5, + "ZEND_VM_OP1_JMP_ADDR" => 1<<4, + "ZEND_VM_OP1_JMP_ABS" => 1<<5, "ZEND_VM_OP2_SPEC" => 1<<8, "ZEND_VM_OP2_CONST" => 1<<9, "ZEND_VM_OP2_TMPVAR" => 1<<10, "ZEND_VM_OP2_NUM" => 1<<11, - "ZEND_VM_OP2_ADDR" => 1<<12, - "ZEND_VM_OP2_OPLINE" => 1<<13, + "ZEND_VM_OP2_JMP_ADDR" => 1<<12, + "ZEND_VM_OP2_JMP_ABS" => 1<<13, "ZEND_VM_EXT_NUM" => 1<<16, "ZEND_VM_EXT_VAR" => 1<<17, - "ZEND_VM_EXT_OPLINE" => 1<<18, - "ZEND_VM_EXT_REL_OPLINE" => 1<<19, + "ZEND_VM_EXT_JMP_ABS" => 1<<18, + "ZEND_VM_EXT_JMP_REL" => 1<<19, "ZEND_VM_EXT_DIM_OBJ" => 1<<20, "ZEND_VM_EXT_CLASS_FETCH" => 1<<21, "ZEND_VM_EXT_CONST_FETCH" => 1<<22, @@ -98,15 +98,15 @@ $vm_op_decode = array( "CV" => ZEND_VM_OP1_SPEC, "TMPVAR" => ZEND_VM_OP1_SPEC | ZEND_VM_OP1_TMPVAR, "NUM" => ZEND_VM_OP1_NUM, - "ADDR" => ZEND_VM_OP1_ADDR, - "OPLINE" => ZEND_VM_OP1_OPLINE, + "JMP_ADDR" => ZEND_VM_OP1_JMP_ADDR, + "JMP_ABS" => ZEND_VM_OP1_JMP_ABS, ); $vm_ext_decode = array( "NUM" => ZEND_VM_EXT_NUM, "VAR" => ZEND_VM_EXT_VAR, - "OPLINE" => ZEND_VM_EXT_OPLINE, - "REL_OPLINE" => ZEND_VM_EXT_REL_OPLINE, + "JMP_ABS" => ZEND_VM_EXT_JMP_ABS, + "JMP_REL" => ZEND_VM_EXT_JMP_REL, "DIM_OBJ" => ZEND_VM_EXT_DIM_OBJ, "CLASS_FETCH" => ZEND_VM_EXT_CLASS_FETCH, "CONST_FETCH" => ZEND_VM_EXT_CONST_FETCH, @@ -1444,7 +1444,7 @@ function gen_vm($def, $skel) { if (strpos($line,"ZEND_VM_HANDLER(") === 0) { // Parsing opcode handler's definition if (preg_match( - "/^ZEND_VM_HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*(,\s*([A-Z_|]+)\s*)?\)/", + "/^ZEND_VM_HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?\)/", $line, $m) == 0) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HANDLER definition.\n"); @@ -1479,7 +1479,7 @@ function gen_vm($def, $skel) { } else if (strpos($line,"ZEND_VM_HELPER(") === 0) { // Parsing helper's definition if (preg_match( - "/^ZEND_VM_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*\)/", + "/^ZEND_VM_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*\)/", $line, $m) == 0) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n"); @@ -1496,7 +1496,7 @@ function gen_vm($def, $skel) { } else if (strpos($line,"ZEND_VM_HELPER_EX(") === 0) { // Parsing helper with parameter definition if (preg_match( - "/^ZEND_VM_HELPER_EX\(\s*([A-Za-z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*,\s*(.*)\s*\)/", + "/^ZEND_VM_HELPER_EX\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*,\s*(.*)\s*\)/", $line, $m) == 0) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n"); diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 2eab6e75859..612406fb8be 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -32,18 +32,18 @@ #define ZEND_VM_OP1_CONST 0x00000002 #define ZEND_VM_OP1_TMPVAR 0x00000004 #define ZEND_VM_OP1_NUM 0x00000008 -#define ZEND_VM_OP1_ADDR 0x00000010 -#define ZEND_VM_OP1_OPLINE 0x00000020 +#define ZEND_VM_OP1_JMP_ADDR 0x00000010 +#define ZEND_VM_OP1_JMP_ABS 0x00000020 #define ZEND_VM_OP2_SPEC 0x00000100 #define ZEND_VM_OP2_CONST 0x00000200 #define ZEND_VM_OP2_TMPVAR 0x00000400 #define ZEND_VM_OP2_NUM 0x00000800 -#define ZEND_VM_OP2_ADDR 0x00001000 -#define ZEND_VM_OP2_OPLINE 0x00002000 +#define ZEND_VM_OP2_JMP_ADDR 0x00001000 +#define ZEND_VM_OP2_JMP_ABS 0x00002000 #define ZEND_VM_EXT_NUM 0x00010000 #define ZEND_VM_EXT_VAR 0x00020000 -#define ZEND_VM_EXT_OPLINE 0x00040000 -#define ZEND_VM_EXT_REL_OPLINE 0x00080000 +#define ZEND_VM_EXT_JMP_ABS 0x00040000 +#define ZEND_VM_EXT_JMP_REL 0x00080000 #define ZEND_VM_EXT_DIM_OBJ 0x00100000 #define ZEND_VM_EXT_CLASS_FETCH 0x00200000 #define ZEND_VM_EXT_CONST_FETCH 0x00400000 From 68b431e37d680a6d071bfaf1129ef7a4caa228ea Mon Sep 17 00:00:00 2001 From: Reeze Xia Date: Fri, 30 Oct 2015 19:49:04 +0800 Subject: [PATCH 08/13] Use h parameter to avoid duplicate ht access of `array_combine()` --- ext/standard/array.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 88818fe78f4..a02a33b5b95 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -5474,17 +5474,17 @@ PHP_FUNCTION(array_chunk) Creates an array by using the elements of the first parameter as keys and the elements of the second as the corresponding values */ PHP_FUNCTION(array_combine) { - zval *values, *keys; + HashTable *values, *keys; uint32_t pos_values = 0; zval *entry_keys, *entry_values; int num_keys, num_values; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "aa", &keys, &values) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "hh", &keys, &values) == FAILURE) { return; } - num_keys = zend_hash_num_elements(Z_ARRVAL_P(keys)); - num_values = zend_hash_num_elements(Z_ARRVAL_P(values)); + num_keys = zend_hash_num_elements(keys); + num_values = zend_hash_num_elements(values); if (num_keys != num_values) { php_error_docref(NULL, E_WARNING, "Both parameters should have an equal number of elements"); @@ -5497,12 +5497,12 @@ PHP_FUNCTION(array_combine) return; } - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry_keys) { + ZEND_HASH_FOREACH_VAL(keys, entry_keys) { while (1) { - if (pos_values >= Z_ARRVAL_P(values)->nNumUsed) { + if (pos_values >= values->nNumUsed) { break; - } else if (Z_TYPE(Z_ARRVAL_P(values)->arData[pos_values].val) != IS_UNDEF) { - entry_values = &Z_ARRVAL_P(values)->arData[pos_values].val; + } else if (Z_TYPE(values->arData[pos_values].val) != IS_UNDEF) { + entry_values = &values->arData[pos_values].val; if (Z_TYPE_P(entry_keys) == IS_LONG) { entry_values = zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry_keys), entry_values); From c4297a5a2949c11a8f49bc90a661ba74f2f03f03 Mon Sep 17 00:00:00 2001 From: Reeze Xia Date: Fri, 30 Oct 2015 19:50:54 +0800 Subject: [PATCH 09/13] This couldn't be false as it has been checked before --- ext/standard/array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index a02a33b5b95..a327da84b0e 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -163,7 +163,7 @@ static int php_array_key_compare(const void *a, const void *b) /* {{{ */ l2 = 0; } } - } else if (f->key) { + } else { if (s->key) { return zendi_smart_strcmp(f->key, s->key); } else { From 3e89c883bbfc1c67ff356b547046f2d7f7325058 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Oct 2015 14:53:53 +0300 Subject: [PATCH 10/13] Changed ZEND_CLONE->extended_value meaning to relative offset (previously it was absolute opline number) --- Zend/zend_opcode.c | 4 ++ Zend/zend_vm_def.h | 16 +++--- Zend/zend_vm_execute.h | 8 +-- Zend/zend_vm_gen.php | 26 +++++----- Zend/zend_vm_opcodes.c | 70 +++++++++++++------------- Zend/zend_vm_opcodes.h | 23 ++++----- ext/opcache/Optimizer/zend_optimizer.c | 8 +++ 7 files changed, 82 insertions(+), 73 deletions(-) diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 8abfd7a56c3..4cf131af53b 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -646,6 +646,10 @@ ZEND_API int pass_two(zend_op_array *op_array) case ZEND_DECLARE_ANON_CLASS: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); break; + case ZEND_CATCH: + /* absolute index to relative offset */ + opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); + break; case ZEND_JMPZNZ: /* absolute index to relative offset */ opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3e34be18cdd..561d79354b7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2591,7 +2591,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_REL) +ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -4205,7 +4205,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ABS) +ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR) { USE_OPLINE zend_class_entry *ce, *catch_ce; @@ -4215,8 +4215,8 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ABS) /* Check whether an exception has been thrown, if not, jump over code */ zend_exception_restore(); if (EG(exception) == NULL) { - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); if (UNEXPECTED(catch_ce == NULL)) { @@ -4238,8 +4238,8 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ABS) zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); } - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } } @@ -6097,7 +6097,7 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR) } } -ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_REL) +ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR) { USE_OPLINE zval *array; @@ -6274,7 +6274,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_REL) +ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) { USE_OPLINE zval *array; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5d5db9130e9..34f5fbe90e8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -9395,8 +9395,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZE /* Check whether an exception has been thrown, if not, jump over code */ zend_exception_restore(); if (EG(exception) == NULL) { - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); if (UNEXPECTED(catch_ce == NULL)) { @@ -9418,8 +9418,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZE zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); } - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 5c5a9aa289e..d55b876dba4 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -71,18 +71,17 @@ $vm_op_flags = array( "ZEND_VM_EXT_NUM" => 1<<16, "ZEND_VM_EXT_VAR" => 1<<17, - "ZEND_VM_EXT_JMP_ABS" => 1<<18, - "ZEND_VM_EXT_JMP_REL" => 1<<19, - "ZEND_VM_EXT_DIM_OBJ" => 1<<20, - "ZEND_VM_EXT_CLASS_FETCH" => 1<<21, - "ZEND_VM_EXT_CONST_FETCH" => 1<<22, - "ZEND_VM_EXT_VAR_FETCH" => 1<<23, - "ZEND_VM_EXT_ARRAY_INIT" => 1<<24, - "ZEND_VM_EXT_TYPE" => 1<<25, - "ZEND_VM_EXT_EVAL" => 1<<26, - "ZEND_VM_EXT_FAST_CALL" => 1<<27, - "ZEND_VM_EXT_FAST_RET" => 1<<28, - "ZEND_VM_EXT_ISSET" => 1<<29, + "ZEND_VM_EXT_JMP_ADDR" => 1<<18, + "ZEND_VM_EXT_DIM_OBJ" => 1<<19, + "ZEND_VM_EXT_CLASS_FETCH" => 1<<20, + "ZEND_VM_EXT_CONST_FETCH" => 1<<21, + "ZEND_VM_EXT_VAR_FETCH" => 1<<22, + "ZEND_VM_EXT_ARRAY_INIT" => 1<<23, + "ZEND_VM_EXT_TYPE" => 1<<24, + "ZEND_VM_EXT_EVAL" => 1<<25, + "ZEND_VM_EXT_FAST_CALL" => 1<<26, + "ZEND_VM_EXT_FAST_RET" => 1<<27, + "ZEND_VM_EXT_ISSET" => 1<<28, ); foreach ($vm_op_flags as $name => $val) { @@ -105,8 +104,7 @@ $vm_op_decode = array( $vm_ext_decode = array( "NUM" => ZEND_VM_EXT_NUM, "VAR" => ZEND_VM_EXT_VAR, - "JMP_ABS" => ZEND_VM_EXT_JMP_ABS, - "JMP_REL" => ZEND_VM_EXT_JMP_REL, + "JMP_ADDR" => ZEND_VM_EXT_JMP_ADDR, "DIM_OBJ" => ZEND_VM_EXT_DIM_OBJ, "CLASS_FETCH" => ZEND_VM_EXT_CLASS_FETCH, "CONST_FETCH" => ZEND_VM_EXT_CONST_FETCH, diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index d575e04a282..70b3e81f843 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -228,19 +228,19 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00000707, 0x00000707, 0x00000707, - 0x02000003, + 0x01000003, 0x00000003, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, - 0x00100701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, + 0x00080701, 0x00000001, 0x00000001, 0x00000001, @@ -252,7 +252,7 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00000010, 0x00001007, 0x00001007, - 0x00081007, + 0x00041007, 0x00001007, 0x00001007, 0x00000707, @@ -278,35 +278,35 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00011003, 0x00010300, 0x00000005, - 0x01000703, + 0x00800703, 0x00010703, - 0x04000007, - 0x00800107, + 0x02000007, + 0x00400107, 0x00000701, 0x00000701, 0x00001003, - 0x00080001, + 0x00040001, 0x00000007, - 0x00800107, + 0x00400107, 0x00000707, 0x00000703, - 0x00800107, + 0x00400107, 0x00000701, 0x00000701, - 0x00800107, + 0x00400107, 0x00000701, 0x00000701, - 0x00800107, + 0x00400107, 0x00000707, 0x00000707, - 0x00800107, + 0x00400107, 0x00000703, 0x00000703, - 0x00800107, + 0x00400107, 0x00000701, 0x00000701, 0x00000307, - 0x00400301, + 0x00200301, 0x00000000, 0x00000000, 0x00000000, @@ -316,13 +316,13 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00000801, 0x00040103, 0x00000003, - 0x00200700, + 0x00100700, 0x00000007, 0x00000003, 0x00010707, 0x00010703, - 0x20800107, - 0x20000707, + 0x10400107, + 0x10000707, 0x00000803, 0x00000801, 0x00010703, @@ -330,10 +330,10 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00000801, 0x00000007, 0x00000003, - 0x02000003, + 0x01000003, 0x00000103, 0x00001003, - 0x00080001, + 0x00040001, 0x00000005, 0x00010700, 0x00000000, @@ -355,7 +355,7 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00020000, 0x00000000, 0x00000701, - 0x20000707, + 0x10000707, 0x00000000, 0x00000000, 0x00001000, @@ -364,17 +364,17 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00000000, 0x00000000, 0x00000101, - 0x00200000, + 0x00100000, 0x00000000, 0x00000000, 0x00000303, 0x00000003, - 0x08002010, - 0x10002000, + 0x04002010, + 0x08002000, 0x00000008, 0x00000000, 0x00000707, - 0x00100701, + 0x00080701, 0x00000301, 0x00001003, 0x00000707, @@ -387,7 +387,7 @@ static uint32_t zend_vm_opcodes_flags[182] = { 0x00000307, 0x00000307, 0x00000307, - 0x20000307, + 0x10000307, 0x00000303, }; diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 612406fb8be..62dbe2205d5 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -42,18 +42,17 @@ #define ZEND_VM_OP2_JMP_ABS 0x00002000 #define ZEND_VM_EXT_NUM 0x00010000 #define ZEND_VM_EXT_VAR 0x00020000 -#define ZEND_VM_EXT_JMP_ABS 0x00040000 -#define ZEND_VM_EXT_JMP_REL 0x00080000 -#define ZEND_VM_EXT_DIM_OBJ 0x00100000 -#define ZEND_VM_EXT_CLASS_FETCH 0x00200000 -#define ZEND_VM_EXT_CONST_FETCH 0x00400000 -#define ZEND_VM_EXT_VAR_FETCH 0x00800000 -#define ZEND_VM_EXT_ARRAY_INIT 0x01000000 -#define ZEND_VM_EXT_TYPE 0x02000000 -#define ZEND_VM_EXT_EVAL 0x04000000 -#define ZEND_VM_EXT_FAST_CALL 0x08000000 -#define ZEND_VM_EXT_FAST_RET 0x10000000 -#define ZEND_VM_EXT_ISSET 0x20000000 +#define ZEND_VM_EXT_JMP_ADDR 0x00040000 +#define ZEND_VM_EXT_DIM_OBJ 0x00080000 +#define ZEND_VM_EXT_CLASS_FETCH 0x00100000 +#define ZEND_VM_EXT_CONST_FETCH 0x00200000 +#define ZEND_VM_EXT_VAR_FETCH 0x00400000 +#define ZEND_VM_EXT_ARRAY_INIT 0x00800000 +#define ZEND_VM_EXT_TYPE 0x01000000 +#define ZEND_VM_EXT_EVAL 0x02000000 +#define ZEND_VM_EXT_FAST_CALL 0x04000000 +#define ZEND_VM_EXT_FAST_RET 0x08000000 +#define ZEND_VM_EXT_ISSET 0x10000000 BEGIN_EXTERN_C() diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index f37b5f72413..b4bc9712861 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -516,6 +516,10 @@ static void zend_accel_optimize(zend_op_array *op_array, case ZEND_DECLARE_ANON_INHERITED_CLASS: ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, ZEND_OP1(opline)); break; + case ZEND_CATCH: + /* relative offset into absolute index */ + opline->extended_value = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value); + break; case ZEND_JMPZNZ: /* relative offset into absolute index */ opline->extended_value = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value); @@ -560,6 +564,10 @@ static void zend_accel_optimize(zend_op_array *op_array, case ZEND_DECLARE_ANON_INHERITED_CLASS: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, ZEND_OP1(opline)); break; + case ZEND_CATCH: + /* absolute index to relative offset */ + opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); + break; case ZEND_JMPZNZ: /* absolute index to relative offset */ opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); From faf835be2bd4db8e57e2529a8022b208cd9201b2 Mon Sep 17 00:00:00 2001 From: Leigh Date: Fri, 30 Oct 2015 19:08:20 +0000 Subject: [PATCH 11/13] Use arc4random on OpenBSD 5.5+ and NetBSD 7+ As discussed with @weltling, keeping arc4random on the condition that the OS has a solid implementation of it --- ext/standard/config.m4 | 5 +++++ ext/standard/random.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index f41df7e9861..c435f965540 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -592,6 +592,11 @@ dnl Check for atomic operation API availability in Solaris dnl AC_CHECK_HEADERS([atomic.h]) +dnl +dnl Check for arc4random on BSD systems +dnl +AC_CHECK_DECLS([arc4random_buf]) + dnl dnl Check for getrandom on newer Linux kernels dnl diff --git a/ext/standard/random.c b/ext/standard/random.c index fd730d1bfd7..70568799dea 100644 --- a/ext/standard/random.c +++ b/ext/standard/random.c @@ -33,6 +33,9 @@ #ifdef __linux__ # include #endif +#if defined(__OpenBSD__) || defined(__NetBSD__) +# include +#endif #ifdef ZTS int random_globals_id; @@ -87,6 +90,8 @@ static int php_random_bytes(void *bytes, size_t size) zend_throw_exception(zend_ce_exception, "Could not gather sufficient random data", 0); return FAILURE; } +#elif HAVE_DECL_ARC4RANDOM_BUF && ((defined(__OpenBSD__) && OpenBSD >= 201405) || (defined(__NetBSD__) && __NetBSD_Version__ >= 700000001)) + arc4random_buf(bytes, size); #elif HAVE_DECL_GETRANDOM /* Linux getrandom(2) syscall */ size_t read_bytes = 0; From 31553f07f25184ff451ddb3c91c3cc90b88c6da1 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 26 Oct 2015 17:26:30 -0700 Subject: [PATCH 12/13] Revert "Fixed bug #70656 (require() statement broken after opcache_reset() or a few hours of use)" This reverts commit 3ef96c2cc6f3a1dddd8479e6c733f44e8dbcb5e9. --- NEWS | 6 +----- ext/opcache/ZendAccelerator.c | 38 ++++++++++++++++------------------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/NEWS b/NEWS index d3f01376ce8..f4e6c8d6f5e 100644 --- a/NEWS +++ b/NEWS @@ -2,13 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2015, PHP 7.0.1 -- Opcache: - . Fixed bug #70656 (require() statement broken after opcache_reset() or a - few hours of use). (Laruence) - - Standard: . Fixed bug #70808 (array_merge_recursive corrupts memory of unset items). - (Laruence) + (laruence) - XSL: . Fixed bug #70678 (PHP7 returns true when false is expected). (Felipe) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index a7fb07bf379..eaadac6e3a9 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -249,28 +249,24 @@ static void accel_interned_strings_restore_state(void) uint nIndex; Bucket *p; - if (EXPECTED(ZCSG(interned_strings_top) > ZCSG(interned_strings_saved_top))) { - memset(ZCSG(interned_strings_saved_top), - 0, ZCSG(interned_strings_top) - ZCSG(interned_strings_saved_top)); - ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top); - while (idx > 0) { - idx--; - p = ZCSG(interned_strings).arData + idx; - if ((char*)p->key < ZCSG(interned_strings_top)) break; - ZCSG(interned_strings).nNumUsed--; - ZCSG(interned_strings).nNumOfElements--; + ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top); + while (idx > 0) { + idx--; + p = ZCSG(interned_strings).arData + idx; + if ((char*)p->key < ZCSG(interned_strings_top)) break; + ZCSG(interned_strings).nNumUsed--; + ZCSG(interned_strings).nNumOfElements--; - nIndex = p->h | ZCSG(interned_strings).nTableMask; - if (HT_HASH(&ZCSG(interned_strings), nIndex) == HT_IDX_TO_HASH(idx)) { - HT_HASH(&ZCSG(interned_strings), nIndex) = Z_NEXT(p->val); - } else { - uint32_t prev = HT_HASH(&ZCSG(interned_strings), nIndex); - while (Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) != idx) { - prev = Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val); - } - Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) = Z_NEXT(p->val); - } - } + nIndex = p->h | ZCSG(interned_strings).nTableMask; + if (HT_HASH(&ZCSG(interned_strings), nIndex) == HT_IDX_TO_HASH(idx)) { + HT_HASH(&ZCSG(interned_strings), nIndex) = Z_NEXT(p->val); + } else { + uint32_t prev = HT_HASH(&ZCSG(interned_strings), nIndex); + while (Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) != idx) { + prev = Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val); + } + Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) = Z_NEXT(p->val); + } } } From 008d8b6789081241c9aaafc13f6f28896e079b99 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 26 Oct 2015 17:28:19 -0700 Subject: [PATCH 13/13] Fixed bug #70656 (require() statement broken after opcache_reset() or a few hours of use) --- NEWS | 6 +++++- ext/opcache/ZendAccelerator.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f4e6c8d6f5e..d3f01376ce8 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,13 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2015, PHP 7.0.1 +- Opcache: + . Fixed bug #70656 (require() statement broken after opcache_reset() or a + few hours of use). (Laruence) + - Standard: . Fixed bug #70808 (array_merge_recursive corrupts memory of unset items). - (laruence) + (Laruence) - XSL: . Fixed bug #70678 (PHP7 returns true when false is expected). (Felipe) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index eaadac6e3a9..e23e7515b8f 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -249,6 +249,8 @@ static void accel_interned_strings_restore_state(void) uint nIndex; Bucket *p; + memset(ZCSG(interned_strings_saved_top), + 0, ZCSG(interned_strings_top) - ZCSG(interned_strings_saved_top)); ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top); while (idx > 0) { idx--;