// opcode处理器 --- ZEND_DO_FCALL_SPEC_CONST_HANDLER实现在 php-5.6.26\Zend\zend_vm_execute.h
static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE zval *fname = opline->op1.zv;
call_slot *call = EX(call_slots) + opline->op2.num; if (CACHED_PTR(opline->op1.literal->cache_slot)) {
EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot);
} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(fname), Z_STRLEN_P(fname)+, Z_HASH_P(fname), (void **) &EX(function_state).function)==FAILURE)) { // 查找函数,把函数指针放入 EX(function_state).function
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
} else {
CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function);
} call->fbc = EX(function_state).function; // 函数信息指针
call->object = NULL;
call->called_scope = NULL;
call->num_additional_args = ;
call->is_ctor_call = ;
EX(call) = call; // ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ---> execute_data TSRMLS_CC return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); // zend_do_fcall_common_helper_SPEC(execute_data)
{
... if (fbc->type == ZEND_INTERNAL_FUNCTION) { // 内建函数 --- 执行的是函数指针(扩展中定义的函数)
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_uint i;
void **p = EX(function_state).arguments - num_args; for (i = ; i < num_args; ++i, ++p) {
zend_verify_arg_type(fbc, i + , (zval *) *p, , NULL TSRMLS_CC);
}
} if (EXPECTED(EG(exception) == NULL)) {
temp_variable *ret = &EX_T(opline->result.var); MAKE_STD_ZVAL(ret->var.ptr);
ZVAL_NULL(ret->var.ptr);
ret->var.ptr_ptr = &ret->var.ptr;
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != ; if (!zend_execute_internal) { // !!! 执行函数
/* saves one function call if zend_execute_internal is not used */
fbc->internal_function.handler(num_args, ret->var.ptr, &ret->var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); // 调用扩展模块的函数
} else {
zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC);
} if (!RETURN_VALUE_USED(opline)) {
zval_ptr_dtor(&ret->var.ptr);
}
} else if (RETURN_VALUE_USED(opline)) {
EX_T(opline->result.var).var.ptr = NULL;
}
} else if (fbc->type == ZEND_USER_FUNCTION) { // 用户定义的函数 --- 执行的opcode
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 (RETURN_VALUE_USED(opline)) {
ret->var.ptr = NULL;
EG(return_value_ptr_ptr) = &ret->var.ptr;
ret->var.ptr_ptr = &ret->var.ptr;
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != ;
} if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != )) {
if (RETURN_VALUE_USED(opline)) {
ret->var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
ret->var.fcall_returned_reference = ;
}
} else if (EXPECTED(zend_execute_ex == execute_ex)) {
if (EXPECTED(EG(exception) == NULL)) {
ZEND_VM_ENTER();
}
} 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 */
MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
ZVAL_NULL(EX_T(opline->result.var).var.ptr); /* Not sure what should be done here if it's a static method */
if (EXPECTED(EX(object) != NULL)) {
// 调用对象方法
Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, num_args, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
} if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
efree((char*)fbc->common.function_name);
}
efree(fbc); if (!RETURN_VALUE_USED(opline)) {
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
} else {
Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, );
EX_T(opline->result.var).var.fcall_returned_reference = ;
EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
}
} ... EX(call)--; zend_vm_stack_clear_multiple( TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC); // 抛异常
if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
}
HANDLE_EXCEPTION();
} ZEND_VM_NEXT_OPCODE(); ...
}
}

php-5.6.26源代码 - opcode处理器,“函数调用opcode”处理器,如何调用扩展模块的函数的更多相关文章

  1. php-5.6.26源代码 - opcode处理器的注入

    .初始化 opcode处理器列表 // main实现在文件“php-5.6.26\sapi\cgi\cgi_main.c” int main(int argc, char *argv[]) { if ...

  2. php-5.6.26源代码 - 扩展模块的加载、注册

    // main实现在文件 php-5.6.26\sapi\cgi\cgi_main.c int main(int argc, char *argv[]) { .... cgi_sapi_module- ...

  3. SQL SERVER 2008:内部查询处理器错误: 查询处理器在执行过程中遇到意外错误

       今天一个同事突然告诉我,以前跑得很正常的一个SQL语句,执行时突然报如下错误:         消息1222,级别16,状态18,第1 行         已超过了锁请求超时时段.        ...

  4. css预处理器和后处理器

    因为我是前端刚入门,昨天看了一个大神写的的初级前端需要掌握的知识,然后我就开始一一搜索,下面是我对css预处理器和后处理器的搜索结果,一是和大家分享下这方面的知识,另一方面方便自己以后翻阅.所以感兴趣 ...

  5. 2018/1/21 Netty通过解码处理器和编码处理器来发送接收POJO,Zookeeper深入学习

    package com.demo.netty; import org.junit.Before;import org.junit.Test; import io.netty.bootstrap.Boo ...

  6. JS的一些总结(函数声明和函数表达式的区别,函数中的this指向的问题,函数不同的调用方式,函数也是对象,数组中的函数调用)

    一.函数声明和函数表达式的区别: 函数声明放在if——else语句中,在IE8中会出现问题 函数表达式则不会 <script> if(true){ function f1(){ conso ...

  7. DSP处理器和ARM处理器的区别以及各自应用在那些领域

    由于工作经常接触到各种多核的处理器,如TI的达芬奇系列芯片拥有1个DSP核3个ARM核.那么DSP处理器和ARM处理器各自有什么区别,各自适合那些领域? DSP:digital signal proc ...

  8. 二、冯式结构与哈佛结构及ARM处理器状态和处理器模式

    2.1 冯式结构与哈佛结构 2.1.1 两者的区别 如果是独立的存储架构和信号通道那就是哈佛结构,否则就是冯式结构 结构与是否统一编址没有关系,也与 CPU 没有关系,与计算机的整体设计有关 CACH ...

  9. php-5.6.26源代码 - include_once、require_once、include、require、eval 的opcode处理器

    # ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER 实现在文件 php-\Zend\zend_vm_execute.h static int ZEND_FASTCALL ...

随机推荐

  1. nodejs操作文件

    var fs = require('fs'); var txt = "以上程序使用fs.readFileSync从源路径读取文件内容,并使用fs.writeFileSync将文件内容写入目标 ...

  2. Winform窗体“空闲事件”

    Application.Idle += Application_Idle; void Application_Idle(object sender, EventArgs e){ } 当应用程序完成处理 ...

  3. java 通过反射获取和设置对象属性值

    public static Object parseDate(Object object){ SimpleDateFormat sdf = new SimpleDateFormat("yyy ...

  4. iOS 时间戳转成今天,上午,下午,星期几,几月几日,某年某月某日

    项目中有聊天功能,老板让聊天的时间转换成和 QQ 的聊天时间一样的格式, 研究了一下,来分析下 QQ 的聊天格式时间 代码: 会话列表显示的时间 如需转成24小时制,需要使用 HH //时间显示内容 ...

  5. 【转载】了解CSS/CSS3原生变量var

    文章转载自:鑫空间鑫生活(https://www.zhangxinxu.com/) 原文链接:http://www.zhangxinxu.com/wordpress/?p=5804 内容摘要: 在任何 ...

  6. 特殊的流程控制语句break continue exit

    break语句可以结束当前的for.foreach.while.do-while.或者switch的执行. for($i=1; $i<10; $i++) { if($i == 5) { echo ...

  7. js的垃圾收集机制以及写代码如何处理

    程序都自己的内存,一旦内存过多就会清楚以前的缓存.所以,在写代码的时候,不要仅仅只会推变量到栈中,还要会将变量从栈中释放. 那么问题来了,我们应该如何将内存从栈中释放呢? 要释放变量,那就要从java ...

  8. 【Node.js】初识Node.js

    因组里项目需要,我和另外一名同事要学习Node.js.之前接触过Javascript,都是前台处理html时用到,现在要用Javascript做后端,学习Node.js,用一段时间专心学习一门新技术, ...

  9. Struts2_带参数的结果集

    页面请求: <a href="user/user?type=1">传参数</a> action: public Integer type; public S ...

  10. nginx配置vhost配置文件详解

    //千锋PHP-PHP培训的实力派server { listen 80; server_name www.sina.com; root /data/www/sina; index index.php; ...