ZEND_RETURN_SPEC_CONST_HANDLER

static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
    USE_OPLINE
    zval *retval_ptr;
    zval *return_value;
    zend_free_op free_op1;

    retval_ptr = EX_CONSTANT(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_REFCOUNT(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);
            }
        }
    }
    //直接到这
    ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
}

gdb 走的代码:


ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER () at /php-7.1.26/Zend/zend_vm_execute.h:41202
41202           ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
(gdb) s
41203   }
(gdb) n
execute_ex (ex=0x7ffff4013030) at /php-7.1.26/Zend/zend_vm_execute.h:430
430                     if (UNEXPECTED(!OPLINE)) {
(gdb) n
429                     ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
(gdb) n

Breakpoint 5, ZEND_RETURN_SPEC_CONST_HANDLER () at /php-7.1.26/Zend/zend_vm_execute.h:2857
2857            retval_ptr = EX_CONSTANT(opline->op1);
(gdb) p opline
Missing ELF symbol "opline".
(gdb) p retval_ptr
$25 = (zval *) 0x7ffff4013080
(gdb) p *retval_ptr
$26 = {value = {lval = 140737287435600, dval = 6.9533458810814867e-310, counted = 0x7ffff4063550, str = 0x7ffff4063550, arr = 0x7ffff4063550,
    obj = 0x7ffff4063550, res = 0x7ffff4063550, ref = 0x7ffff4063550, ast = 0x7ffff4063550, zv = 0x7ffff4063550, ptr = 0x7ffff4063550, ce = 0x7ffff4063550,
    func = 0x7ffff4063550, ww = {w1 = 4094047568, w2 = 32767}}, u1 = {v = {type = 8 '\b', type_flags = 12 '\f', const_flags = 0 '\000',
      reserved = 0 '\000'}, type_info = 3080}, u2 = {next = 0, cache_slot = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0,
    property_guard = 0, extra = 0}}
(gdb) n
2858            return_value = EX(return_value);
(gdb) p return_value
$27 = (zval *) 0x555555ba3d3c <ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER+106>
(gdb) p *return_value
$28 = {value = {lval = 5255851728548759880, dval = 2.3048279784435938e+43, counted = 0x48f0894ce8458948, str = 0x48f0894ce8458948,
    arr = 0x48f0894ce8458948, obj = 0x48f0894ce8458948, res = 0x48f0894ce8458948, ref = 0x48f0894ce8458948, ast = 0x48f0894ce8458948,
    zv = 0x48f0894ce8458948, ptr = 0x48f0894ce8458948, ce = 0x48f0894ce8458948, func = 0x48f0894ce8458948, ww = {w1 = 3896871240, w2 = 1223723340}}, u1 = {
    v = {type = 139 '\213', type_flags = 0 '\000', const_flags = 72 'H', reserved = 131 '\203'}, type_info = 2202534027}, u2 = {next = 2303271104,
    cache_slot = 2303271104, lineno = 2303271104, num_args = 2303271104, fe_pos = 2303271104, fe_iter_idx = 2303271104, access_flags = 2303271104,
    property_guard = 2303271104, extra = 2303271104}}
(gdb) n
2865            } else if (!return_value) {
(gdb) n
2912            ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
(gdb) s
zend_leave_helper_SPEC () at /php-7.1.26/Zend/zend_vm_execute.h:481
481             uint32_t call_info = EX_CALL_INFO();
(gdb) n
483             if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
(gdb) n
515             } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
(gdb) n
553             } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
(gdb) n
570                     if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
(gdb) n
584                             zend_array *symbol_table = EX(symbol_table);
(gdb) p *symbol_table
$29 = {gc = {refcount = 4094047568, u = {v = {type = 255 '\377', flags = 127 '\177', gc_info = 0}, type_info = 32767}}, u = {v = {flags = 8 '\b',
      nApplyCount = 12 '\f', nIteratorsCount = 0 '\000', consistency = 0 '\000'}, flags = 3080}, nTableMask = 0, arData = 0x0, nNumUsed = 0,
  nNumOfElements = 0, nTableSize = 0, nInternalPointer = 0, nNextFreeElement = 0, pDestructor = 0x0}
(gdb) n
586                             zend_detach_symbol_table(execute_data);
(gdb) s
zend_detach_symbol_table (execute_data=0x7ffff4013030) at /php-7.1.26/Zend/zend_execute_API.c:1630
1630            zend_op_array *op_array = &execute_data->func->op_array;
(gdb) n
1631            HashTable *ht = execute_data->symbol_table;
(gdb) n
1634            if (EXPECTED(op_array->last_var)) {
(gdb) p *ht
$30 = {gc = {refcount = 1, u = {v = {type = 7 '\a', flags = 0 '\000', gc_info = 0}, type_info = 7}}, u = {v = {flags = 10 '\n', nApplyCount = 0 '\000',
      nIteratorsCount = 0 '\000', consistency = 0 '\000'}, flags = 10}, nTableMask = 4294967232, arData = 0x7ffff4059100, nNumUsed = 8, nNumOfElements = 8,
  nTableSize = 64, nInternalPointer = 0, nNextFreeElement = 0, pDestructor = 0x555555ae1fbf <_zval_ptr_dtor_wrapper>}
(gdb) p *op_array
$31 = {type = 2 '\002', arg_flags = "\000\000", fn_flags = 134217728, function_name = 0x0, scope = 0x0, prototype = 0x0, num_args = 0,
  required_num_args = 0, arg_info = 0x0, refcount = 0x7ffff4001028, last = 5, opcodes = 0x7ffff40790c0, last_var = 1, T = 4, vars = 0x7ffff4001050,
  last_live_range = 0, last_try_catch = 0, live_range = 0x0, try_catch_array = 0x0, static_variables = 0x0, filename = 0x7ffff40577c0, line_start = 1,
  line_end = 6, doc_comment = 0x0, early_binding = 4294967295, last_literal = 3, literals = 0x7ffff4063500, cache_size = 8,
  run_time_cache = 0x7ffff4001078, reserved = {0x0, 0x0, 0x0, 0x0}}
(gdb) p *op_array->opcodes
$32 = {handler = 0x555555b4c981 <ZEND_NOP_SPEC_HANDLER>, op1 = {constant = 0, var = 0, num = 0, opline_num = 0, jmp_offset = 0}, op2 = {constant = 0,
    var = 0, num = 0, opline_num = 0, jmp_offset = 0}, result = {constant = 0, var = 0, num = 0, opline_num = 0, jmp_offset = 0}, extended_value = 0,
  lineno = 3, opcode = 0 '\000', op1_type = 8 '\b', op2_type = 8 '\b', result_type = 8 '\b'}
(gdb) n
1635                    zend_string **str = op_array->vars;
(gdb) p **str
$33 = {gc = {refcount = 1, u = {v = {type = 8 '\b', flags = 0 '\000', gc_info = 0}, type_info = 8}}, h = 1, len = 140737287036952, val = ""}
(gdb) n
1636                    zend_string **end = str + op_array->last_var;
(gdb) p **end
Cannot access memory at address 0xc0400000008
(gdb) n
1637                    zval *var = EX_VAR_NUM(0);
(gdb) n
1640                            if (Z_TYPE_P(var) == IS_UNDEF) {
(gdb) n
1643                                    zend_hash_update(ht, *str, var);
(gdb) n
1644                                    ZVAL_UNDEF(var);
(gdb) n
1646                            str++;
(gdb) n
1647                            var++;
(gdb) n
1648                    } while (str != end);
(gdb) n
1650    }
(gdb) n
zend_leave_helper_SPEC () at /php-7.1.26/Zend/zend_vm_execute.h:587
587                             old_execute_data = EX(prev_execute_data);
(gdb) n
588                             while (old_execute_data) {
(gdb) n
597                             EG(current_execute_data) = EX(prev_execute_data);
(gdb) n
598                             ZEND_VM_RETURN();
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!