summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2018-06-05 17:19:17 +0800
committerXinchen Hui <laruence@gmail.com>2018-06-05 17:19:17 +0800
commit1ce4b484f84f9f43daee7e1fe75d42cac3b1ca34 (patch)
treeed7f301fb8ab1b929f67ea5209a9571c14738074
parent0a0f6c495fefdbc4b70751466d0ecb1e8de58dcc (diff)
parent59c2ff254368190687a030bab4ad0a61deb2026d (diff)
downloadphp-git-1ce4b484f84f9f43daee7e1fe75d42cac3b1ca34.tar.gz
Merge branch 'master' of git.php.net:/php-src
* 'master' of git.php.net:/php-src: Embed zend_leave_helper() into hybrid executor to avoid call overhead. Cleanup
-rw-r--r--Zend/zend_execute.c7
-rw-r--r--Zend/zend_vm_def.h84
-rw-r--r--Zend/zend_vm_execute.h599
-rw-r--r--Zend/zend_vm_gen.php102
4 files changed, 599 insertions, 193 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index bd9fcce771..e863328121 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -3269,14 +3269,17 @@ static zend_never_inline zend_bool ZEND_FASTCALL zend_fe_reset_iterator(zval *ar
#define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \
ZEND_VM_SET_OPCODE(ZEND_OFFSET_TO_OPLINE(opline, offset))
-#define ZEND_VM_JMP(new_op) do { \
- if (UNEXPECTED(EG(exception))) { \
+#define ZEND_VM_JMP_EX(new_op, check_exception) do { \
+ if (check_exception && UNEXPECTED(EG(exception))) { \
HANDLE_EXCEPTION(); \
} \
ZEND_VM_SET_OPCODE(new_op); \
ZEND_VM_CONTINUE(); \
} while (0)
+#define ZEND_VM_JMP(new_op) \
+ ZEND_VM_JMP_EX(new_op, 1)
+
#define ZEND_VM_INC_OPCODE() \
OPLINE++
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index fc6c547750..838daea88f 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2364,7 +2364,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
+ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
{
zend_execute_data *old_execute_data;
uint32_t call_info = EX_CALL_INFO();
@@ -2485,8 +2485,7 @@ ZEND_VM_HOT_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY)
{
USE_OPLINE
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
}
ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
@@ -2498,17 +2497,16 @@ ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -2530,16 +2528,16 @@ ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- ZEND_VM_NEXT_OPCODE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_NEXT_OPCODE();
}
SAVE_OPLINE();
@@ -2567,11 +2565,11 @@ ZEND_VM_HOT_NOCONST_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -2601,11 +2599,11 @@ ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -2632,8 +2630,7 @@ ZEND_VM_COLD_CONST_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
@@ -4083,8 +4080,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
/* Check whether an exception has been thrown, if not, jump over code */
zend_exception_restore();
if (EG(exception) == NULL) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
if (UNEXPECTED(catch_ce == NULL)) {
@@ -4106,8 +4102,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
zend_rethrow_exception(execute_data);
HANDLE_EXCEPTION();
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
}
@@ -5404,8 +5399,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
} else if (RETURN_VALUE_USED(opline)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
}
- ZEND_VM_SET_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(196, ZEND_UNSET_CV, CV, UNUSED)
@@ -5691,8 +5685,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -5780,8 +5773,7 @@ ZEND_VM_COLD_CONST_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -6139,8 +6131,7 @@ ZEND_VM_HOT_HANDLER(197, ZEND_ISSET_ISEMPTY_CV, CV, UNUSED, ISSET, SPEC(ISSET))
}
ZEND_VM_SMART_BRANCH(result, 0);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
@@ -6496,8 +6487,7 @@ ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
FREE_OP1();
@@ -6537,8 +6527,7 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
FREE_OP1();
@@ -6859,8 +6848,7 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
if (op_num < try_catch->catch_op && ex) {
/* Go to catch block */
cleanup_live_vars(execute_data, op_num, try_catch->catch_op);
- ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[try_catch->catch_op]);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->catch_op], 0);
} else if (op_num < try_catch->finally_op) {
/* Go to finally block */
@@ -6869,8 +6857,7 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
Z_OBJ_P(fast_call) = EG(exception);
EG(exception) = NULL;
Z_OPLINE_NUM_P(fast_call) = (uint32_t)-1;
- ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[try_catch->finally_op]);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->finally_op], 0);
} else if (op_num < try_catch->finally_end) {
zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[try_catch->finally_end].op1.var);
@@ -7366,8 +7353,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, JMP_ADDR, ANY)
Z_OBJ_P(fast_call) = NULL;
/* set return address */
Z_OPLINE_NUM_P(fast_call) = opline - EX(func)->op_array.opcodes;
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
}
ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH)
@@ -7379,8 +7365,7 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH)
if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1) {
const zend_op *fast_ret = EX(func)->op_array.opcodes + Z_OPLINE_NUM_P(fast_call);
- ZEND_VM_SET_OPCODE(fast_ret + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(fast_ret + 1, 0);
}
/* special case for unhandled exceptions */
@@ -7602,8 +7587,7 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR)
if (RETURN_VALUE_USED(opline)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
}
- ZEND_VM_SET_OPCODE(target);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(target, 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index e19f1159a3..5ab8a86351 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -622,8 +622,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(Z
{
USE_OPLINE
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
}
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1706,8 +1705,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try_catch_finally_hel
if (op_num < try_catch->catch_op && ex) {
/* Go to catch block */
cleanup_live_vars(execute_data, op_num, try_catch->catch_op);
- ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[try_catch->catch_op]);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->catch_op], 0);
} else if (op_num < try_catch->finally_op) {
/* Go to finally block */
@@ -1716,8 +1714,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try_catch_finally_hel
Z_OBJ_P(fast_call) = EG(exception);
EG(exception) = NULL;
Z_OPLINE_NUM_P(fast_call) = (uint32_t)-1;
- ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[try_catch->finally_op]);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->finally_op], 0);
} else if (op_num < try_catch->finally_end) {
zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[try_catch->finally_end].op1.var);
@@ -1892,8 +1889,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OP
Z_OBJ_P(fast_call) = NULL;
/* set return address */
Z_OPLINE_NUM_P(fast_call) = opline - EX(func)->op_array.opcodes;
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1905,8 +1901,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC
if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1) {
const zend_op *fast_ret = EX(func)->op_array.opcodes + Z_OPLINE_NUM_P(fast_call);
- ZEND_VM_SET_OPCODE(fast_ret + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(fast_ret + 1, 0);
}
/* special case for unhandled exceptions */
@@ -1926,8 +1921,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND
if (RETURN_VALUE_USED(opline)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
}
- ZEND_VM_SET_OPCODE(target);
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(target, 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -2603,17 +2597,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_O
val = RT_CONSTANT(opline, opline->op1);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -2635,16 +2628,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_
val = RT_CONSTANT(opline, opline->op1);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- ZEND_VM_NEXT_OPCODE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_NEXT_OPCODE();
}
SAVE_OPLINE();
@@ -2672,11 +2665,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -2706,11 +2699,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONS
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -2737,8 +2730,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CON
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
@@ -2984,8 +2976,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_
/* Check whether an exception has been thrown, if not, jump over code */
zend_exception_restore();
if (EG(exception) == NULL) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
if (UNEXPECTED(catch_ce == NULL)) {
@@ -3007,8 +2998,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_
zend_rethrow_exception(execute_data);
HANDLE_EXCEPTION();
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
}
@@ -3363,8 +3353,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
} else if (RETURN_VALUE_USED(opline)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
}
- ZEND_VM_SET_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -3408,8 +3397,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -3495,8 +3483,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -3586,8 +3573,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONS
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
ZEND_VM_NEXT_OPCODE();
@@ -3626,8 +3612,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
ZEND_VM_NEXT_OPCODE();
@@ -12273,17 +12258,16 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_TMPVAR_H
val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -12305,16 +12289,16 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_
val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- ZEND_VM_NEXT_OPCODE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_NEXT_OPCODE();
}
SAVE_OPLINE();
@@ -12342,11 +12326,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMPVAR
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -12376,11 +12360,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZE
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -12407,8 +12391,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(Z
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
@@ -12640,8 +12623,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA
} else if (RETURN_VALUE_USED(opline)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
}
- ZEND_VM_SET_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -18004,8 +17986,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -18091,8 +18072,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -18163,8 +18143,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -18204,8 +18183,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -21086,8 +21064,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -21175,8 +21152,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -21556,8 +21532,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -21597,8 +21572,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -36372,17 +36346,16 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDL
val = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -36404,16 +36377,16 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HAND
val = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC);
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- } else {
- ZEND_VM_NEXT_OPCODE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_NEXT_OPCODE();
}
SAVE_OPLINE();
@@ -36441,11 +36414,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HAN
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -36475,11 +36448,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_O
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
}
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
SAVE_OPLINE();
@@ -36506,8 +36479,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_
if (Z_TYPE_INFO_P(val) == IS_TRUE) {
ZVAL_TRUE(EX_VAR(opline->result.var));
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
@@ -37171,8 +37143,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
} else if (RETURN_VALUE_USED(opline)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
}
- ZEND_VM_SET_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -37216,8 +37187,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -37303,8 +37273,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
} else if (is_empty) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
} else {
ZEND_VM_NEXT_OPCODE();
}
@@ -37394,8 +37363,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_O
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
ZEND_VM_NEXT_OPCODE();
@@ -37434,8 +37402,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_
Z_ADDREF_P(result);
}
}
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
}
ZEND_VM_NEXT_OPCODE();
@@ -46595,8 +46562,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_S
}
ZEND_VM_SMART_BRANCH(result, 0);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -46620,8 +46586,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_S
}
ZEND_VM_SMART_BRANCH(result, 0);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -50432,6 +50397,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDL
}
+#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
+# undef ZEND_VM_TAIL_CALL
+# undef ZEND_VM_CONTINUE
+# undef ZEND_VM_RETURN
+
+# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE()
+# define ZEND_VM_CONTINUE() HYBRID_NEXT()
+# define ZEND_VM_RETURN() goto HYBRID_HALT_LABEL
+#endif
+
+
ZEND_API void execute_ex(zend_execute_data *ex)
{
DCL_OPLINE
@@ -54415,6 +54391,123 @@ ZEND_API void execute_ex(zend_execute_data *ex)
#endif
#endif
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
+zend_leave_helper_SPEC_LABEL:
+{
+ zend_execute_data *old_execute_data;
+ uint32_t call_info = EX_CALL_INFO();
+
+ if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
+ i_free_compiled_variables(execute_data);
+
+ EG(current_execute_data) = EX(prev_execute_data);
+ if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+ zend_object *object = Z_OBJ(execute_data->This);
+#if 0
+ if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
+#else
+ if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
+#endif
+ GC_DELREF(object);
+ zend_object_store_ctor_failed(object);
+ }
+ OBJ_RELEASE(object);
+ } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+ OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+ }
+ EG(vm_stack_top) = (zval*)execute_data;
+ execute_data = EX(prev_execute_data);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_rethrow_exception(execute_data);
+ HANDLE_EXCEPTION_LEAVE();
+ }
+
+ LOAD_NEXT_OPLINE();
+ ZEND_VM_LEAVE();
+ } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
+ i_free_compiled_variables(execute_data);
+
+ if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+ zend_clean_and_cache_symbol_table(EX(symbol_table));
+ }
+ EG(current_execute_data) = EX(prev_execute_data);
+ if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+ zend_object *object = Z_OBJ(execute_data->This);
+#if 0
+ if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
+#else
+ if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
+#endif
+ GC_DELREF(object);
+ zend_object_store_ctor_failed(object);
+ }
+ OBJ_RELEASE(object);
+ } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+ OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+ }
+
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
+ old_execute_data = execute_data;
+ execute_data = EX(prev_execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_rethrow_exception(execute_data);
+ HANDLE_EXCEPTION_LEAVE();
+ }
+
+ LOAD_NEXT_OPLINE();
+ ZEND_VM_LEAVE();
+ } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
+ zend_detach_symbol_table(execute_data);
+ destroy_op_array(&EX(func)->op_array);
+ efree_size(EX(func), sizeof(zend_op_array));
+ old_execute_data = execute_data;
+ execute_data = EG(current_execute_data) = EX(prev_execute_data);
+ zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
+
+ zend_attach_symbol_table(execute_data);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_rethrow_exception(execute_data);
+ HANDLE_EXCEPTION_LEAVE();
+ }
+
+ LOAD_NEXT_OPLINE();
+ ZEND_VM_LEAVE();
+ } else {
+ if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
+ i_free_compiled_variables(execute_data);
+ if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
+ if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+ zend_clean_and_cache_symbol_table(EX(symbol_table));
+ }
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
+ }
+ EG(current_execute_data) = EX(prev_execute_data);
+ if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+ OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+ }
+ ZEND_VM_RETURN();
+ } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
+ zend_array *symbol_table = EX(symbol_table);
+
+ zend_detach_symbol_table(execute_data);
+ old_execute_data = EX(prev_execute_data);
+ while (old_execute_data) {
+ if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+ if (old_execute_data->symbol_table == symbol_table) {
+ zend_attach_symbol_table(old_execute_data);
+ }
+ break;
+ }
+ old_execute_data = old_execute_data->prev_execute_data;
+ }
+ EG(current_execute_data) = EX(prev_execute_data);
+ ZEND_VM_RETURN();
+ }
+ }
+}
+
HYBRID_CASE(ZEND_JMP_SPEC):
VM_TRACE(ZEND_JMP_SPEC)
ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -54633,8 +54726,70 @@ ZEND_API void execute_ex(zend_execute_data *ex)
HYBRID_BREAK();
HYBRID_CASE(ZEND_RETURN_SPEC_CONST):
VM_TRACE(ZEND_RETURN_SPEC_CONST)
- ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- HYBRID_BREAK();
+{
+ USE_OPLINE
+ zval *retval_ptr;
+ zval *return_value;
+ zend_free_op free_op1;
+
+ retval_ptr = RT_CONSTANT(opline, opline->op1);
+ return_value = EX(return_value);
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+ SAVE_OPLINE();
+ retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
+ if (return_value) {
+ ZVAL_NULL(return_value);
+ }
+ } else if (!return_value) {
+ if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+ if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) {
+ SAVE_OPLINE();
+ zval_dtor_func(Z_COUNTED_P(free_op1));
+ }
+ }
+ } else {
+ if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (IS_CONST == IS_CONST) {
+ if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+ Z_ADDREF_P(return_value);
+ }
+ }
+ } else if (IS_CONST == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) {
+ ZVAL_NULL(retval_ptr);
+ } else {
+ Z_ADDREF_P(return_value);
+ }
+ } else {
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY(return_value, retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ } else /* if (IS_CONST == IS_VAR) */ {
+ if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+ efree_size(ref, sizeof(zend_reference));
+ } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ Z_ADDREF_P(retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ }
+ }
+ goto zend_leave_helper_SPEC_LABEL;
+}
+
HYBRID_CASE(ZEND_RETURN_BY_REF_SPEC_CONST):
VM_TRACE(ZEND_RETURN_BY_REF_SPEC_CONST)
ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -56225,8 +56380,70 @@ ZEND_API void execute_ex(zend_execute_data *ex)
HYBRID_BREAK();
HYBRID_CASE(ZEND_RETURN_SPEC_TMP):
VM_TRACE(ZEND_RETURN_SPEC_TMP)
- ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- HYBRID_BREAK();
+{
+ USE_OPLINE
+ zval *retval_ptr;
+ zval *return_value;
+ zend_free_op free_op1;
+
+ retval_ptr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ return_value = EX(return_value);
+ if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+ SAVE_OPLINE();
+ retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
+ if (return_value) {
+ ZVAL_NULL(return_value);
+ }
+ } else if (!return_value) {
+ if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) {
+ if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) {
+ SAVE_OPLINE();
+ zval_dtor_func(Z_COUNTED_P(free_op1));
+ }
+ }
+ } else {
+ if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (IS_TMP_VAR == IS_CONST) {
+ if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+ Z_ADDREF_P(return_value);
+ }
+ }
+ } else if (IS_TMP_VAR == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) {
+ ZVAL_NULL(retval_ptr);
+ } else {
+ Z_ADDREF_P(return_value);
+ }
+ } else {
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY(return_value, retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ } else /* if (IS_TMP_VAR == IS_VAR) */ {
+ if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+ efree_size(ref, sizeof(zend_reference));
+ } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ Z_ADDREF_P(retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ }
+ }
+ goto zend_leave_helper_SPEC_LABEL;
+}
+
HYBRID_CASE(ZEND_RETURN_BY_REF_SPEC_TMP):
VM_TRACE(ZEND_RETURN_BY_REF_SPEC_TMP)
ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -56457,8 +56674,70 @@ ZEND_API void execute_ex(zend_execute_data *ex)
HYBRID_BREAK();
HYBRID_CASE(ZEND_RETURN_SPEC_VAR):
VM_TRACE(ZEND_RETURN_SPEC_VAR)
- ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- HYBRID_BREAK();
+{
+ USE_OPLINE
+ zval *retval_ptr;
+ zval *return_value;
+ zend_free_op free_op1;
+
+ retval_ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ return_value = EX(return_value);
+ if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+ SAVE_OPLINE();
+ retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
+ if (return_value) {
+ ZVAL_NULL(return_value);
+ }
+ } else if (!return_value) {
+ if (IS_VAR & (IS_VAR|IS_TMP_VAR)) {
+ if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) {
+ SAVE_OPLINE();
+ zval_dtor_func(Z_COUNTED_P(free_op1));
+ }
+ }
+ } else {
+ if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (IS_VAR == IS_CONST) {
+ if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+ Z_ADDREF_P(return_value);
+ }
+ }
+ } else if (IS_VAR == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) {
+ ZVAL_NULL(retval_ptr);
+ } else {
+ Z_ADDREF_P(return_value);
+ }
+ } else {
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY(return_value, retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ } else /* if (IS_VAR == IS_VAR) */ {
+ if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+ efree_size(ref, sizeof(zend_reference));
+ } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ Z_ADDREF_P(retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ }
+ }
+ goto zend_leave_helper_SPEC_LABEL;
+}
+
HYBRID_CASE(ZEND_RETURN_BY_REF_SPEC_VAR):
VM_TRACE(ZEND_RETURN_BY_REF_SPEC_VAR)
ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -58045,8 +58324,70 @@ ZEND_API void execute_ex(zend_execute_data *ex)
HYBRID_BREAK();
HYBRID_CASE(ZEND_RETURN_SPEC_CV):
VM_TRACE(ZEND_RETURN_SPEC_CV)
- ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- HYBRID_BREAK();
+{
+ USE_OPLINE
+ zval *retval_ptr;
+ zval *return_value;
+ zend_free_op free_op1;
+
+ retval_ptr = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC);
+ return_value = EX(return_value);
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+ SAVE_OPLINE();
+ retval_ptr = GET_OP1_UNDEF_CV(retval_ptr, BP_VAR_R);
+ if (return_value) {
+ ZVAL_NULL(return_value);
+ }
+ } else if (!return_value) {
+ if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+ if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) {
+ SAVE_OPLINE();
+ zval_dtor_func(Z_COUNTED_P(free_op1));
+ }
+ }
+ } else {
+ if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (IS_CV == IS_CONST) {
+ if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+ Z_ADDREF_P(return_value);
+ }
+ }
+ } else if (IS_CV == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) {
+ ZVAL_NULL(retval_ptr);
+ } else {
+ Z_ADDREF_P(return_value);
+ }
+ } else {
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY(return_value, retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ } else /* if (IS_CV == IS_VAR) */ {
+ if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+ zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+ retval_ptr = Z_REFVAL_P(retval_ptr);
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+ efree_size(ref, sizeof(zend_reference));
+ } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+ Z_ADDREF_P(retval_ptr);
+ }
+ } else {
+ ZVAL_COPY_VALUE(return_value, retval_ptr);
+ }
+ }
+ }
+ goto zend_leave_helper_SPEC_LABEL;
+}
+
HYBRID_CASE(ZEND_RETURN_BY_REF_SPEC_CV):
VM_TRACE(ZEND_RETURN_BY_REF_SPEC_CV)
ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index a3db82acdf..20672c66c5 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -615,6 +615,16 @@ function out_line($f) {
++$line_no;
}
+function is_hot_helper($name) {
+ global $helpers;
+
+ if (isset($helpers[$name]["hot"])) {
+ return $helpers[$name]["hot"];
+ } else {
+ return false;
+ }
+}
+
// Returns name of specialized helper
function helper_name($name, $spec, $op1, $op2, $extra_spec) {
global $prefix, $helpers;
@@ -874,6 +884,41 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name, $extra_sp
}
// Updating code according to selected threading model
switch($kind) {
+ case ZEND_VM_KIND_HYBRID:
+ $code = preg_replace_callback(
+ array(
+ "/EXECUTE_DATA(?=[^_])/m",
+ "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
+ "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
+ ),
+ function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
+ if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+ return "execute_data";
+ } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+ global $opcodes, $opnames;
+
+ $name = $matches[1];
+ $opcode = $opcodes[$opnames[$name]];
+ if (is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
+ return "goto " . opcode_name($name, $spec, $op1, $op2) . "_LABEL";
+ } else {
+ return "ZEND_VM_TAIL_CALL(" . opcode_name($name, $spec, $op1, $op2) . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
+ }
+ } else {
+ // ZEND_VM_DISPATCH_TO_HELPER
+ if (isset($matches[2])) {
+ // extra args
+ $args = substr(preg_replace("/,\s*[A-Za-z_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
+ return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(" . $args. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC))";
+ }
+ if (is_hot_helper($matches[1])) {
+ return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+ }
+ return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
+ }
+ },
+ $code);
+ break;
case ZEND_VM_KIND_CALL:
$code = preg_replace_callback(
array(
@@ -1048,6 +1093,11 @@ function is_cold_handler($hot, $op1, $op2, $extra_spec) {
}
}
+function is_inline_hybrid_handler($name, $hot, $op1, $op2, $extra_spec) {
+ return $name == "ZEND_RETURN";
+ //return $hot && is_hot_handler($hot, $op1, $op2, $extra_spec);
+}
+
// Generates opcode handler
function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno, $opcode, $extra_spec = null, &$switch_labels = array()) {
global $definition_file, $prefix, $opnames, $gen_order;
@@ -1064,11 +1114,22 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
$spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
switch($kind) {
case ZEND_VM_KIND_HYBRID:
- $code =
- "\t\t\tHYBRID_CASE({$spec_name}):\n"
- . "\t\t\t\tVM_TRACE($spec_name)\n"
- . "\t\t\t\t{$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n"
- . "\t\t\t\tHYBRID_BREAK();\n";
+ if (is_inline_hybrid_handler($name, $opcode["hot"], $op1, $op2, $extra_spec)) {
+ $out = fopen('php://memory', 'w+');
+ gen_code($out, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec);
+ rewind($out);
+ $code =
+ "\t\t\tHYBRID_CASE({$spec_name}):\n"
+ . "\t\t\t\tVM_TRACE($spec_name)\n"
+ . stream_get_contents($out);
+ fclose($out);
+ } else {
+ $code =
+ "\t\t\tHYBRID_CASE({$spec_name}):\n"
+ . "\t\t\t\tVM_TRACE($spec_name)\n"
+ . "\t\t\t\t{$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n"
+ . "\t\t\t\tHYBRID_BREAK();\n";
+ }
if (is_array($gen_order)) {
$gen_order[$spec_name] = $code;
} else {
@@ -1109,10 +1170,10 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
}
// Generates helper
-function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $cold, $extra_spec = null) {
+function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $cold = false, $hot = false, $extra_spec = null) {
global $definition_file, $prefix;
- if ($kind == ZEND_VM_KIND_HYBRID) {
+ if ($kind == ZEND_VM_KIND_HYBRID && !$hot) {
return;
}
@@ -1128,6 +1189,9 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno,
// Generate helper's entry point according to selected threading model
switch($kind) {
+ case ZEND_VM_KIND_HYBRID:
+ out($f, $spec_name . "_LABEL:\n");
+ break;
case ZEND_VM_KIND_CALL:
if ($inline) {
$zend_attributes = " zend_always_inline";
@@ -1642,7 +1706,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
if (isset($helpers[$num]["op1"][$op1]) &&
isset($helpers[$num]["op2"][$op2])) {
// Generate helper code
- gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $extra_spec);
+ gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"], $extra_spec);
}
}
} else {
@@ -1666,7 +1730,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
} else if (isset($dsc["helper"])) {
$num = $dsc["helper"];
// Generate helper code
- gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"]);
+ gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"]);
} else {
var_dump($dsc);
die("??? $kind:$num\n");
@@ -1951,6 +2015,18 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
}
if ($kind == ZEND_VM_KIND_HYBRID) {
gen_executor_code($f, $spec, ZEND_VM_KIND_CALL, $m[1]);
+ out($f,"\n");
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"# undef ZEND_VM_TAIL_CALL\n");
+ out($f,"# undef ZEND_VM_CONTINUE\n");
+ out($f,"# undef ZEND_VM_RETURN\n");
+// out($f,"# undef ZEND_VM_INTERRUPT\n");
+ out($f,"\n");
+ out($f,"# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE()\n");
+ out($f,"# define ZEND_VM_CONTINUE() HYBRID_NEXT()\n");
+ out($f,"# define ZEND_VM_RETURN() goto HYBRID_HALT_LABEL\n");
+// out($f,"# define ZEND_VM_INTERRUPT() goto zend_interrupt_helper_SPEC_LABEL\n");
+ out($f,"#endif\n\n");
}
break;
case "EXECUTOR_NAME":
@@ -2355,16 +2431,18 @@ function gen_vm($def, $skel) {
$list[$lineno] = array("handler"=>$handler);
} else if (strpos($line,"ZEND_VM_HELPER(") === 0 ||
strpos($line,"ZEND_VM_INLINE_HELPER(") === 0 ||
- strpos($line,"ZEND_VM_COLD_HELPER(") === 0) {
+ strpos($line,"ZEND_VM_COLD_HELPER(") === 0 ||
+ strpos($line,"ZEND_VM_HOT_HELPER(") === 0) {
// Parsing helper's definition
if (preg_match(
- "/^ZEND_VM(_INLINE|_COLD)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*SPEC\(([A-Z_|=,]+)\)\s*)?(?:,\s*([^)]*)\s*)?\)/",
+ "/^ZEND_VM(_INLINE|_COLD|_HOT)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*SPEC\(([A-Z_|=,]+)\)\s*)?(?:,\s*([^)]*)\s*)?\)/",
$line,
$m) == 0) {
die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n");
}
$inline = !empty($m[1]) && $m[1] === "_INLINE";
$cold = !empty($m[1]) && $m[1] === "_COLD";
+ $hot = !empty($m[1]) && $m[1] === "_HOT";
$helper = $m[2];
$op1 = parse_operand_spec($def, $lineno, $m[3], $flags1);
$op2 = parse_operand_spec($def, $lineno, $m[4], $flags2);
@@ -2381,7 +2459,7 @@ function gen_vm($def, $skel) {
}
}
- $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline,"cold"=>$cold);
+ $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline,"cold"=>$cold,"hot"=>$hot);
if (!empty($m[5])) {
$helpers[$helper]["spec"] = parse_spec_rules($def, $lineno, $m[5]);