]> granicus.if.org Git - php/commitdiff
Added specialized handlers for SEND_VAR/SEND_VAR_EX opcodes.
authorDmitry Stogov <dmitry@zend.com>
Wed, 15 Jun 2016 20:07:46 +0000 (23:07 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 15 Jun 2016 20:07:46 +0000 (23:07 +0300)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 331ebdb85d68557a73e12bcd17f169ddde8fe3c6..c53c561ebd91676ac4ac49edb1bf0c4df06c54e5 100644 (file)
@@ -8523,4 +8523,50 @@ ZEND_VM_C_LABEL(fetch_dim_r_index_undef):
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SEND_VAR, (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_SIMPLE, CV|VAR, NUM)
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+       zend_free_op free_op1;
+
+       varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (OP1_TYPE == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (OP1_TYPE == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SEND_VAR_EX, (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_EX_SIMPLE, CV|VAR, NUM, SPEC(QUICK_ARG))
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+       zend_free_op free_op1;
+       uint32_t arg_num = opline->op2.num;
+
+       if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+               if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+                       ZEND_VM_C_GOTO(send_var_by_ref);
+               }
+       } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ZEND_VM_C_LABEL(send_var_by_ref):
+               ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
+       }
+
+       varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (OP1_TYPE == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (OP1_TYPE == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
index ca5b343cf5456d007cfe41955cbfe49e444d19bf..64642024f793a09f19110e1cc211650c0ab362c1 100644 (file)
@@ -16994,6 +16994,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZE
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+       zend_free_op free_op1;
+
+       varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (IS_VAR == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (IS_VAR == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+       zend_free_op free_op1;
+       uint32_t arg_num = opline->op2.num;
+
+       if (EXPECTED(0)) {
+               if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+                       goto send_var_by_ref;
+               }
+       } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+               ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       }
+
+       varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (IS_VAR == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (IS_VAR == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+       zend_free_op free_op1;
+       uint32_t arg_num = opline->op2.num;
+
+       if (EXPECTED(1)) {
+               if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+                       goto send_var_by_ref;
+               }
+       } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+               ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       }
+
+       varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (IS_VAR == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (IS_VAR == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -37917,6 +37991,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEN
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+
+
+       varptr = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (IS_CV == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (IS_CV == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+
+       uint32_t arg_num = opline->op2.num;
+
+       if (EXPECTED(0)) {
+               if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+                       goto send_var_by_ref;
+               }
+       } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+               ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       }
+
+       varptr = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (IS_CV == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (IS_CV == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zval *varptr, *arg;
+
+       uint32_t arg_num = opline->op2.num;
+
+       if (EXPECTED(1)) {
+               if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+                       goto send_var_by_ref;
+               }
+       } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+               ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       }
+
+       varptr = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+       arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+       if (IS_CV == IS_CV) {
+               ZVAL_COPY(arg, varptr);
+       } else /* if (IS_CV == IS_VAR) */ {
+               ZVAL_COPY_VALUE(arg, varptr);
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -63737,6 +63885,21 @@ void zend_init_opcodes_handlers(void)
                ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER,
                ZEND_NULL_HANDLER,
                ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_HANDLER,
+               ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_QUICK_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_HANDLER,
+               ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_QUICK_HANDLER,
                ZEND_NULL_HANDLER
        };
        static const uint32_t specs[] = {
@@ -63789,9 +63952,9 @@ void zend_init_opcodes_handlers(void)
                1423 | SPEC_RULE_OP1,
                1428 | SPEC_RULE_OP1,
                1433 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-               4481,
+               4496,
                1458 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG,
-               4481,
+               4496,
                1468 | SPEC_RULE_OP1,
                1473 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                1498 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
@@ -63840,7 +64003,7 @@ void zend_init_opcodes_handlers(void)
                2207 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                2232 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                2257 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-               4481,
+               4496,
                2282,
                2283,
                2284,
@@ -63924,7 +64087,7 @@ void zend_init_opcodes_handlers(void)
                3456 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                3481 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                3506 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-               4481
+               4496
        };
        zend_opcode_handlers = labels;
                zend_handlers_count = sizeof(labels) / sizeof(void*);
@@ -64205,11 +64368,21 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
                                spec = 4441 | SPEC_RULE_OP1;
                        }
                        break;
+               case ZEND_SEND_VAR_EX:
+                       if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
+                               spec = 4486 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG;
+                       }
+                       break;
                case ZEND_FETCH_DIM_R:
                        if ((!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)))) {
                                spec = 4456 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
                        }
                        break;
+               case ZEND_SEND_VAR:
+                       if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
+                               spec = 4481 | SPEC_RULE_OP1;
+                       }
+                       break;
                default:
                        break;
        }