ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER

coder_study發表於2019-11-06
Breakpoint 3, ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER () at /php-7.1.26/Zend/zend_vm_execute.h:38252
38252           SAVE_OPLINE();
(gdb) n
38253           container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
(gdb) n
38261           offset = EX_CONSTANT(opline->op2);
(gdb) p offset
$9 = (zval *) 0x7ffff40582d8
(gdb) p *offset
$10 = {value = {lval = 0, dval = 0, counted = 0x0, str = 0x0, arr = 0x0, obj = 0x0, res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0,
    func = 0x0, ww = {w1 = 0, w2 = 0}}, u1 = {v = {type = 56 '8', type_flags = 0 '\000', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 56},
  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) p container
$11 = (zval *) 0x7ffff4013080
(gdb) p *container
$12 = {value = {lval = 140737287389856, dval = 6.9533458788214328e-310, counted = 0x7ffff40582a0, str = 0x7ffff40582a0, arr = 0x7ffff40582a0,
    obj = 0x7ffff40582a0, res = 0x7ffff40582a0, ref = 0x7ffff40582a0, ast = 0x7ffff40582a0, zv = 0x7ffff40582a0, ptr = 0x7ffff40582a0, ce = 0x7ffff40582a0,
    func = 0x7ffff40582a0, ww = {w1 = 4094001824, 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) p  *container->ce
There is no member named ce.
(gdb) n
38264               (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
(gdb) n
38263           if (IS_CV == IS_CONST ||
(gdb) n
38277                   zend_object *zobj = Z_OBJ_P(container);
(gdb) n
38281                           EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
(gdb) p *zobj
$13 = {gc = {refcount = 1, u = {v = {type = 8 '\b', flags = 0 '\000', gc_info = 0}, type_info = 8}}, handle = 1, ce = 0x7ffff4002018,
  handlers = 0x55555639d000 <std_object_handlers>, properties = 0x0, properties_table = {{value = {lval = 1, dval = 4.9406564584124654e-324, counted = 0x1,
        str = 0x1, arr = 0x1, obj = 0x1, res = 0x1, ref = 0x1, ast = 0x1, zv = 0x1, ptr = 0x1, ce = 0x1, func = 0x1, ww = {w1 = 1, w2 = 0}}, u1 = {v = {
          type = 4 '\004', type_flags = 0 '\000', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 4}, 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
38280                   if (IS_CONST == IS_CONST &&
(gdb) n
38299                   if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
(gdb) n
38304                           retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
(gdb) s
zend_std_read_property (object=0x7ffff4013080, member=0x7ffff4058380, type=0, cache_slot=0x7ffff40770b0, rv=0x7ffff40130d0) at /php-7.1.26/Zend/zend_object_handlers.c:575
575     {
(gdb) n
580             uint32_t *guard = NULL;
(gdb) n
582             zobj = Z_OBJ_P(object);
(gdb) n
584             ZVAL_UNDEF(&tmp_member);
(gdb) n
585             if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) {
(gdb) n
596             property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), cache_slot);
(gdb) s
zend_get_property_offset (ce=0x7ffff4002018, member=0x7ffff4057840, silent=0, cache_slot=0x7ffff40770b0) at /php-7.1.26/Zend/zend_object_handlers.c:324
324             zend_property_info *property_info = NULL;
(gdb) n
328             if (cache_slot && EXPECTED(ce == CACHED_PTR_EX(cache_slot))) {
(gdb) n
332             if (UNEXPECTED(ZSTR_VAL(member)[0] == '\0' && ZSTR_LEN(member) != 0)) {
(gdb) n
339             if (UNEXPECTED(zend_hash_num_elements(&ce->properties_info) == 0)) {
(gdb) n
343             zv = zend_hash_find(&ce->properties_info, member);
(gdb) n
344             if (EXPECTED(zv != NULL)) {
(gdb) n
345                     property_info = (zend_property_info*)Z_PTR_P(zv);
(gdb) n
346                     flags = property_info->flags;
(gdb) n
347                     if (UNEXPECTED((flags & ZEND_ACC_SHADOW) != 0)) {
(gdb) n
351                             if (EXPECTED(zend_verify_property_access(property_info, ce) != 0)) {
(gdb) n
352                                     if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))
(gdb) n
354                                             if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
(gdb) n
360                                             goto exit;
(gdb) n
399             if (cache_slot) {
(gdb) n
400                     CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, (void*)(intptr_t)property_info->offset);
(gdb) n
402             return property_info->offset;
(gdb) n
403     }
(gdb) n
zend_std_read_property (object=0x7ffff4013080, member=0x7ffff4058380, type=0, cache_slot=0x7ffff40770b0, rv=0x7ffff40130d0) at /php-7.1.26/Zend/zend_object_handlers.c:598
598             if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) {
(gdb) nn
Undefined command: "nn".  Try "help".
(gdb) n
599                     if (EXPECTED(property_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
(gdb) n
600                             retval = OBJ_PROP(zobj, property_offset);
(gdb) n
601                             if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
(gdb) n
602                                     goto exit;
(gdb) n
687             if (UNEXPECTED(Z_REFCOUNTED(tmp_member))) {
(gdb) n
691             return retval;
(gdb) n
692     }
(gdb) n
ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER () at /php-7.1.26/Zend/zend_vm_execute.h:38306
38306                           if (retval != EX_VAR(opline->result.var)) {
(gdb) n
38307                                   ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
(gdb) n
38313           ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
//查詢物件的變數屬性
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
    USE_OPLINE

    zval *container;

    zval *offset;

    SAVE_OPLINE();
    container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);

    if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
        zend_throw_error(NULL, "Using $this when not in object context");

        HANDLE_EXCEPTION();
    }

    offset = EX_CONSTANT(opline->op2);

    if (IS_CV == IS_CONST ||
        (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) 

    /* here we are sure we are dealing with an object */
    do {
        zend_object *zobj = Z_OBJ_P(container);
        zval *retval;

        if (IS_CONST == IS_CONST &&
            EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
            uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));

            if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
                retval = OBJ_PROP(zobj, prop_offset);
                if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
                    ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
                    break;
                }
            } else if (EXPECTED(zobj->properties != NULL)) {
                retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
                if (EXPECTED(retval)) {
                    ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
                    break;
                }
            }
        }

        if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
fetch_obj_r_no_object:
                //獲取一個不是物件的屬性
            zend_error(E_NOTICE, "Trying to get property of non-object");
            ZVAL_NULL(EX_VAR(opline->result.var));
        } else {
            //讀取屬性進入到這:
            retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));

            if (retval != EX_VAR(opline->result.var)) {
                ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
            }
        }
    } while (0);

    ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}

zend_std_read_propertyt

本作品採用《CC 協議》,轉載必須註明作者和本文連結