声明:本文为斯人原创,全部为作者一一分析得之,有不对的地方望赐教。 http://imsiren.com/archives/601 好久没有写博客了…最近事挺多, 换了工作,又搬了家.. 今天就来说说 我们经常用到的global语句吧.. 我们都知道,在函数体内声明的变量,作用域只是当前函
声明:本文为斯人原创,全部为作者一一分析得之,有不对的地方望赐教。
http://imsiren.com/archives/601
好久没有写博客了…最近事挺多,
换了工作,又搬了家..
今天就来说说 我们经常用到的global语句吧..
我们都知道,在函数体内声明的变量,作用域只是当前函数体中,一般情况下是访问不到外部声明的变量的.
因为全局变量和局部变量存放在不同的hashTable,
全局变量在symbol_table中,而局部变量则存在active_symbol_table中.
这样就将它们分开了,那 global是怎么实现的呢?
经过简单分析,通过RE2C&&YACC定位到 global的token
T_GLOBAL global_var_list ';' ................ global_var_list: global_var_list ',' global_var { zend_do_fetch_global_variable(&$3, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); } | global_var { zend_do_fetch_global_variable(&$1, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); } ;
void zend_do_fetch_global_variable(znode * varname,const znode * static_assignment,int fetch_type TSRMLS_DC) /* {{{ */ { zend_op * opline; znode lval; znode result; if(varname->op_type == IS_CONST) { if(Z_TYPE(varname->u . constant) != IS_STRING) { convert_to_string(&varname->u . constant); } } opline = get_next_op(CG(active_op_array)TSRMLS_CC); opline->opcode = ZEND_FETCH_W; /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */ opline->result . op_type = IS_VAR; opline->result . u . EA . type = 0; opline->result . u . var = get_temporary_variable(CG(active_op_array)); opline->op1 = * varname; SET_UNUSED(opline->op2); opline->op2 . u . EA . type = fetch_type; result = opline->result; if(varname->op_type == IS_CONST) { zval_copy_ctor(&varname->u . constant); } fetch_simple_variable(&lval,varname,0TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */ zend_do_assign_ref(NULL,&lval,&result TSRMLS_CC); CG(active_op_array)->opcodes[CG(active_op_array)->last - 1] . result . u . EA . type |= EXT_TYPE_UNUSED; }
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); }