1.bnf正規化
%token t_paamayim_nekudotayim ":: (t_paamayim_nekudotayim)"//類名::靜態方法(...);
function_call: | class_name t_paamayim_nekudotayim variable_name '('
function_call_parameter_list
')'
2.呼叫靜態方法的編譯 zend_do_begin_class_member_function_call
int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name tsrmls_dc) /*lcname = zend_str_tolower_dup(z_strval(method_name->u.constant), z_strlen(method_name->u.constant));
if ((sizeof(zend_constructor_func_name)-1) == z_strlen(method_name->u.constant) &&memcmp(lcname, zend_constructor_func_name,
sizeof(zend_constructor_func_name)-1) == 0
) efree(lcname);
}if (class_name->op_type == is_const &&zend_fetch_class_default == zend_get_class_fetch_type(z_strval(class_name->u.constant), z_strlen(class_name->u.constant)))
else
opline->opcode =zend_init_static_method_call;
if (class_node.op_type ==is_const)
else
if (method_name->op_type ==is_const)
else
} else
//**忽略
return
1; /*
dynamic */}
static
intzend_fastcallzend_init_static_method_call_spec_const_const_handler(zend_opcode_handler_args)
else
cache_ptr(opline->op1.literal->cache_slot, ce);//放入eg(active_op_array)->run_time_cache這個陣列中,以便下次呼叫時提高速度}
ex(called_scope) =ce;
} else
if (is_const == is_const &&is_const == is_const &&cached_ptr(opline->op2.literal->cache_slot))
else
if (is_const != is_const &&is_const == is_const &&(ex(fbc) = cached_polymorphic_ptr(opline->op2.literal->cache_slot, ce)))
else
if (is_const !=is_unused)
else
if(function_name_strval)
else
if (unexpected(ex(fbc) ==null))
if (is_const == is_const &&expected(ex(fbc)->type <= zend_user_function) &&expected((ex(fbc)->common.fn_flags & (zend_acc_call_via_handler|zend_acc_never_cache)) == 0
))
else}}
if (is_const !=is_const)
} else
//**省略
check_exception();
zend_vm_next_opcode();
}
zend_class_entry *zend_fetch_class_by_name(constchar *class_name, uint class_name_len, const zend_literal *key, int fetch_type tsrmls_dc) /*
return *pce;
}zend_api
int zend_lookup_class_ex(const
char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce tsrmls_dc) /*
else
hash =zend_inline_hash_func(lc_name, lc_length);
}if (zend_hash_quick_find(eg(class_table), lc_name, lc_length, hash, (void **) ce) ==success)
return
success;
}}
3.呼叫靜態方法的編譯 zend_do_end_function_call
void zend_do_end_function_call(znode *function_name, znode *result, const znode *argument_list, int is_method, int is_dynamic_fcall tsrmls_dc) /*else
else
}opline->result.var =get_temporary_variable(cg(active_op_array));
opline->result_type =is_var;
get_node(result, opline->result) ;
set_unused(opline->op2);
zend_stack_del_top(&cg(function_call_stack));
opline->extended_value = z_lval(argument_list->u.constant);
}
staticintzend_fastcall zend_do_fcall_by_name_spec_handler(zend_opcode_handler_args)
static
intzend_fastcall zend_do_fcall_common_helper_spec(zend_opcode_handler_args)
if (unexpected((fbc->common.fn_flags & zend_acc_deprecated) != 0
)) }
if (fbc->common.scope &&
!(fbc->common.fn_flags & zend_acc_static) &&
!ex(object
))
else
}if (fbc->type == zend_user_function || fbc->common.scope)
zend_arg_types_stack_3_pop(&eg(arg_types_stack), &ex(called_scope), &ex(current_object), &ex(fbc));
ex(function_state).arguments = zend_vm_stack_push_args(opline->extended_value tsrmls_cc);
load_opline();
if (fbc->type ==zend_internal_function)
else
if (fbc->type ==zend_user_function)
if (expected(zend_execute ==execute))
} }
else
}
php 類物件呼叫靜態方法
以前一直以為 靜態方法的呼叫 類名 靜態方法 非靜態方法的呼叫 類物件 非靜態方法 最近研究乙個類,發現乙個比較奇怪的問題,用 類物件 靜態方法 這種方式居然成功的呼叫了靜態方法。很疑惑,還以為是該類中定義了 call魔術方法,在通過物件呼叫不到該靜態方法的時候,做了處理,通過類名呼叫了該方法。但是...
物件呼叫靜態方法 C 中靜態成員 靜態方法 靜態類
平時在用c 做開發的朋友都知道,不論是靜態成員還是靜態方法還是靜態類都是用static關鍵字來修飾。也就是說只要看到了static,那麼它後面的東西就是靜態!在c 中,靜態成員或者靜態方法是屬於類的,不是屬於物件。假如我們有乙個類myclass,需要例項化這個 類,就應該這麼做 myclass my...
靜態方法(物件方法) 例項方法的呼叫
1 靜態方法被 static 修飾 例項方法沒有被 static 修飾。3 例項方法中可呼叫例項方法 靜態方法。4 靜態方法中可呼叫靜態方法。5 靜態方法中不能呼叫例項方法。結合2 6條 6 呼叫同乙個類中的例項方法 成員變數的標準格式為 物件名.方法名 物件名.成員變數名 也可通過方法名 成員變數...