static int ZEND_FASTCALL ZEND_FETCH_W_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) |
{ |
return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_W, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); |
} |
|
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_ARGS) |
{ |
... //省略 |
|
if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) { |
retval = zend_std_get_static_property(EX_T(opline->op2.u. var ).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC); |
} else { |
// 取符号表,这里我们取的是EG(active_op_array)->static_variables |
target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC); |
... // 省略 |
if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) { |
switch (type) { |
... //省略 |
// 在前面的调用中我们知道type = case BP_VAR_W,于是程序会走按case BP_VAR_W的流程走。 |
case BP_VAR_W: { |
zval *new_zval = &EG(uninitialized_zval); |
|
Z_ADDREF_P(new_zval); |
zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval); |
// 更新符号表,执行赋值操作 |
} |
break ; |
EMPTY_SWITCH_DEFAULT_CASE() |
} |
} |
switch (opline->op2.u.EA.type) { |
... //省略 |
case ZEND_FETCH_STATIC: |
zval_update_constant(retval, (void*) 1 TSRMLS_CC); |
break ; |
case ZEND_FETCH_GLOBAL_LOCK: |
if (IS_CV == IS_VAR && !free_op1. var ) { |
PZVAL_LOCK(*EX_T(opline->op1.u. var ). var .ptr_ptr); |
} |
break ; |
} |
} |
|
... //省略 |
} |