expr_without_variable    { Z_LVAL($$.u.constant) = ;  zend_do_pass_param(&$, ZEND_SEND_VAL, Z_LVAL($$.u.constant) TSRMLS_CC); }
| variable { Z_LVAL($$.u.constant) = ; zend_do_pass_param(&$, ZEND_SEND_VAR, Z_LVAL($$.u.constant) TSRMLS_CC); }
| '&' w_variable { Z_LVAL($$.u.constant) = ; zend_do_pass_param(&$, ZEND_SEND_REF, Z_LVAL($$.u.constant) TSRMLS_CC); }
| non_empty_function_call_parameter_list ',' expr_without_variable { Z_LVAL($$.u.constant)=Z_LVAL($.u.constant)+; zend_do_pass_param(&$, ZEND_SEND_VAL, Z_LVAL($$.u.constant) TSRMLS_CC); }
| non_empty_function_call_parameter_list ',' variable { Z_LVAL($$.u.constant)=Z_LVAL($.u.constant)+; zend_do_pass_param(&$, ZEND_SEND_VAR, Z_LVAL($$.u.constant) TSRMLS_CC); }
| non_empty_function_call_parameter_list ',' '&' w_variable { Z_LVAL($$.u.constant)=Z_LVAL($.u.constant)+; zend_do_pass_param(&$, ZEND_SEND_REF, Z_LVAL($$.u.constant) TSRMLS_CC); }
;

将参数从左到在依次放到栈里

static int ZEND_FASTCALL  ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
{
zval *valptr;
zval *value; value = opline->op1.zv; ALLOC_ZVAL(valptr);
INIT_PZVAL_COPY(valptr, value);
if (!) {
zval_copy_ctor(valptr);
}
zend_vm_stack_push(valptr TSRMLS_CC); } ZEND_VM_NEXT_OPCODE();
}
static zend_always_inline void zend_vm_stack_push(void *ptr TSRMLS_DC)
{
*(EG(argument_stack)->top++) = ptr;
}

当调用函数时,将

static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_bool should_change_scope = ;
zend_function *fbc = EX(function_state).function; SAVE_OPLINE();
EX(object) = EX(call)->object;
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != )) {
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != )) {
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != )) {
zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
fbc->common.scope ? fbc->common.scope->name : "",
fbc->common.scope ? "::" : "",
fbc->common.function_name);
}
}
if (fbc->common.scope &&
!(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
!EX(object)) { if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
/* FIXME: output identifiers properly */
zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name);
} else {
/* FIXME: output identifiers properly */
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name, fbc->common.function_name);
}
} if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) {
should_change_scope = ;
EX(current_this) = EG(This);
EX(current_scope) = EG(scope);
EX(current_called_scope) = EG(called_scope);
EG(This) = EX(object);
EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
EG(called_scope) = EX(call)->called_scope;
} EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
zend_vm_stack_push((void*)(zend_uintptr_t)opline->extended_value TSRMLS_CC);
LOAD_OPLINE(); if (fbc->type == ZEND_INTERNAL_FUNCTION) { } else if (fbc->type == ZEND_USER_FUNCTION) {
temp_variable *ret = &EX_T(opline->result.var);
EX(original_return_value) = EG(return_value_ptr_ptr);
EG(active_symbol_table) = NULL;
EG(active_op_array) = &fbc->op_array;
EG(return_value_ptr_ptr) = NULL; if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != )) { } else if (EXPECTED(zend_execute_ex == execute_ex)) { } else {
zend_execute(EG(active_op_array) TSRMLS_CC);
} EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = EX(symbol_table);
} else { /* ZEND_OVERLOADED_FUNCTION */ } EX(function_state).function = (zend_function *) EX(op_array);
EX(function_state).arguments = NULL; EX(call)--; //删除栈中的数据
zend_vm_stack_clear_multiple( TSRMLS_CC); ZEND_VM_NEXT_OPCODE();
}
static zend_always_inline void zend_vm_stack_clear_multiple(int nested TSRMLS_DC)
{
void **p = EG(argument_stack)->top - ;
void **end = p - (int)(zend_uintptr_t)*p; while (p != end) {
zval *q = (zval *) *(--p);
*p = NULL;
i_zval_ptr_dtor(q ZEND_FILE_LINE_CC);
}
if (nested) {
EG(argument_stack)->top = p;
} else {
zend_vm_stack_free_int(p TSRMLS_CC);
}
}
non_empty_parameter_list:
optional_class_type T_VARIABLE { $$.op_type = IS_UNUSED; $$.u.op.num=; zend_do_receive_arg(ZEND_RECV, &$, &$$, NULL, &$, TSRMLS_CC); }
| optional_class_type '&' T_VARIABLE { $$.op_type = IS_UNUSED; $$.u.op.num=; zend_do_receive_arg(ZEND_RECV, &$, &$$, NULL, &$, TSRMLS_CC); }
| optional_class_type '&' T_VARIABLE '=' static_scalar { $$.op_type = IS_UNUSED; $$.u.op.num=; zend_do_receive_arg(ZEND_RECV_INIT, &$, &$$, &$, &$, TSRMLS_CC); }
| optional_class_type T_VARIABLE '=' static_scalar { $$.op_type = IS_UNUSED; $$.u.op.num=; zend_do_receive_arg(ZEND_RECV_INIT, &$, &$$, &$, &$, TSRMLS_CC); }
| non_empty_parameter_list ',' optional_class_type T_VARIABLE { $$=$; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV, &$, &$$, NULL, &$, TSRMLS_CC); }
| non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE { $$=$; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV, &$, &$$, NULL, &$, TSRMLS_CC); }
| non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '=' static_scalar { $$=$; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &$, &$$, &$, &$, TSRMLS_CC); }
| non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' static_scalar { $$=$; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &$, &$$, &$, &$, TSRMLS_CC); }
;
void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, const znode *initialization, znode *class_type, zend_uchar pass_by_reference TSRMLS_DC) /* {{{ */
{
zend_op *opline;
zend_arg_info *cur_arg_info;
znode var;
{
var.op_type = IS_CV;
var.u.op.var = lookup_cv(CG(active_op_array), varname->u.constant.value.str.val, varname->u.constant.value.str.len, TSRMLS_CC);
Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[var.u.op.var].name;
var.EA = ;
if (CG(active_op_array)->vars[var.u.op.var].hash_value == THIS_HASHVAL &&
Z_STRLEN(varname->u.constant) == sizeof("this")- &&
!memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")-)) {
if (CG(active_op_array)->scope &&
(CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == ) {
zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
}
CG(active_op_array)->this_var = var.u.op.var;
}
} opline = get_next_op(CG(active_op_array) TSRMLS_CC);
CG(active_op_array)->num_args++;
opline->opcode = op;
SET_NODE(opline->result, &var);
SET_NODE(opline->op1, offset);
if (op == ZEND_RECV_INIT) {
SET_NODE(opline->op2, initialization);
} else {
CG(active_op_array)->required_num_args = CG(active_op_array)->num_args;
SET_UNUSED(opline->op2);
}
CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-];
cur_arg_info->name = zend_new_interned_string(estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len), varname->u.constant.value.str.len + , TSRMLS_CC);
cur_arg_info->name_len = varname->u.constant.value.str.len;
cur_arg_info->type_hint = ;
cur_arg_info->allow_null = ;
cur_arg_info->pass_by_reference = pass_by_reference;
cur_arg_info->class_name = NULL;
cur_arg_info->class_name_len = ;
}
static int ZEND_FASTCALL  ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_uint arg_num = opline->op1.num; //得到参数
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC); SAVE_OPLINE();
if (UNEXPECTED(param == NULL)) { } else {
zval **var_ptr; zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
Z_DELREF_PP(var_ptr);
*var_ptr = *param;
Z_ADDREF_PP(var_ptr);
} CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}

function参数的更多相关文章

  1. [SAP ABAP开发技术总结]Form(subroutine)、Function参数传值传址

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  2. js中function参数默认值

    --在dreamweaver做网站时,函数定义是在一个*.js文件中,其中定义了一个func,有四个参数,function func(string1,url,flag,icon),然后在另一个asp中 ...

  3. JavaScript的function参数的解释

    在js里面写function时其参数在内部表示为一个数组.也就是说:我们定义一个function,里面的参数和将来调用这个function时传入的实参是毫无关系的,如果我们要定义一个function ...

  4. theano function参数

    train_rbm = theano.function( [index], # inputs cost, # outputs updates=updates, givens={ x: train_se ...

  5. js function 参数

    JS 中 函数的调用非常完美, 例如 var myFun=function( num1,num2){ return num1+num2;} 调用喊出 1) myFun(1,1) 2) myFun(); ...

  6. jquery 添加方法 : $.fn.方法名 = function(参数a,b,c){

    $.fn.image_checked = function(self,status,img_body,csrf_token){             $(this).live('click', fu ...

  7. renderer:function参数介绍

    转载自:http://blog.sina.com.cn/s/blog_9eaf28f90101b7y3.html renderer:function(value, cellmeta, record, ...

  8. typedef 返回类型(*Function)(参数表) ——typedef函数指针

    //首先看一下函数指针怎么用 #include <iostream> using namespace std; //定义一个函数指针pFUN,它指向一个返回类型为char,有一个整型的参数 ...

  9. 【转】JavaScript里Function函数实现可变参数

    转载:  http://www.oschina.net/question/54100_15938 使用javascript类库函数时,经常会遇到一个函数,可以使用不同个数的参数的情况 比如:exp(v ...

随机推荐

  1. http mimetype为multipart/x-mixed-replace报文

    http://blog.csdn.net/gmstart/article/details/7064034 服务器推送(Server Push) 推送技术的基础思想是将浏览器主动查询信息改为服务器主动发 ...

  2. css页面组件

    页面组件 1 元素的尺寸/边框/背景 1.1 css尺寸相关属性 height 高度 min-height 最小高度 max-height 最大高度 width 宽度 min-width 最小宽度 m ...

  3. 26. The Greenhouse Effect and Its Consequences 温室效应及其后果

    26. The Greenhouse Effect and Its Consequences 温室效应及其后果 ①The greenhouse effect causes trouble by rai ...

  4. VS2010/MFC编程(对话框:模态对话框及其弹出过程)

    讲讲什么是模态对话框和非模态对话框,以及模态对话框怎样弹出. 一.模态对话框和非模态对话框 Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框是这样的对话框,当它弹出后,本应用程序其 ...

  5. gj6 深入python的set和dict

    6.1 collections中的abc from collections.abc import Mapping, MutableMapping #dict属于mapping类型 a = {} pri ...

  6. MyEclipse 过期

    package util; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamRea ...

  7. Mouse Touch Stylus

    Mouse操作: preview mouse down, StylusDevice:null mouse down,StylusDevice:null preview mouse up, Stylus ...

  8. 挂载镜像SD卡的FAT32文件系统分区到Linux中

    首先使用fdisk –l命令查看sd卡的分区息 可以看到,sd卡有三个分区,第一个分区是FAT32系统,主要存放内核img文件和dtb文件,第二个分区是Linux系统分区,第三个分区格式未知,实际是U ...

  9. hdu 1205 吃糖果【鸽巢原理】

    题目 这道题不难,看别人博客的时候发现大家都说用鸽巢原理,这是个什么鬼,于是乎百度之. 1.把某种糖果看做隔板,如果某种糖果有n个,那么就有n+1块区域,至少需要n-1块其他种糖果才能使得所有隔板不挨 ...

  10. 软件工程作业 - 实现WC功能(java)

    项目地址:https://github.com/yogurt1998/WordCount 要求 基本要求 -c 统计文件字符数(实现) -w 统计文件单词数(实现) -l 统计文件行数(实现) 扩展功 ...