PHP内核源码阅读过程(四)
这次来讲讲 zend_startup
int zend_startup(zend_utility_functions *utility_functions, char **extensions)
其第一个参数是一些基本的函数指针
zuf.error_function = php_error_cb;zuf.printf_function = php_printf;zuf.write_function = php_output_wrapper;zuf.fopen_function = php_fopen_wrapper_for_zend;zuf.message_handler = php_message_handler_for_zend;zuf.get_configuration_directive = php_get_configuration_directive_for_zend;zuf.ticks_function = php_run_ticks;zuf.on_timeout = php_on_timeout;zuf.stream_open_function = php_stream_open_for_zend;zuf.printf_to_smart_string_function = php_printf_to_smart_string;zuf.printf_to_smart_str_function = php_printf_to_smart_str;zuf.getenv_function = sapi_getenv;zuf.resolve_path_function = php_resolve_path_for_zend;zend_startup(&zuf, NULL);
一、zend_cpu_startup 获取cpu支持的指令集
这个是通过"cpuid"指令获取本机cpu支持的指令集
#define __cpuid_count(level, count, a, b, c, d) \__asm__ ("cpuid\n\t" \: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \: "0" (level), "2" (count))static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) {__cpuid_count(func, subfunc, cpuinfo->eax, cpuinfo->ebx, cpuinfo->ecx, cpuinfo->edx);
}void zend_cpu_startup(void)
{if (!cpuinfo.initialized) {zend_cpu_info ebx;int max_feature;cpuinfo.initialized = 1;__zend_cpuid(0, 0, &cpuinfo); //获取最大功能号max_feature = cpuinfo.eax;if (max_feature == 0) {return;}__zend_cpuid(1, 0, &cpuinfo); //获取ecx和edx上的功能列表/* for avx2 */if (max_feature >= 7) {__zend_cpuid(7, 0, &ebx); //获取ebx上的功能列表cpuinfo.ebx = ebx.ebx;} else {cpuinfo.ebx = 0;}}
}
获取指令集的目的是为了优化字符串的处理,让一些操作直接由cpu指令完成,目前在两个地方使用: string和base64。
关于cpuid指令的详情,可以参考:CPUID
二、start_memory_manager 初始化内存管理器,这个话题很大,这里暂时不写。
三、virtual_cwd_startup 获取当前工作目录
将当前工作目录保存到全局变量 cwd_globals 中。
四、设置全局函数指针
zend_error_cb = utility_functions->error_function;zend_printf = utility_functions->printf_function;zend_write = (zend_write_func_t) utility_functions->write_function;zend_fopen = utility_functions->fopen_function;if (!zend_fopen) {zend_fopen = zend_fopen_wrapper;}zend_stream_open_function = utility_functions->stream_open_function;zend_message_dispatcher_p = utility_functions->message_handler;zend_get_configuration_directive_p = utility_functions->get_configuration_directive;zend_ticks_function = utility_functions->ticks_function;zend_on_timeout = utility_functions->on_timeout;zend_printf_to_smart_string = utility_functions->printf_to_smart_string_function;zend_printf_to_smart_str = utility_functions->printf_to_smart_str_function;zend_getenv = utility_functions->getenv_function;zend_resolve_path = utility_functions->resolve_path_function;zend_interrupt_function = NULL;zend_compile_file = compile_file;zend_execute_ex = execute_ex;zend_execute_internal = NULL;zend_compile_string = compile_string;zend_throw_exception_hook = NULL;gc_collect_cycles = zend_gc_collect_cycles;
五、zend_vm_init 初始化php指令集
六、初始化一些全局变量
//版本信息
zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;//全局函数表 compiler_globals.function_table
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));//全局类表 compiler_globals.class_table
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));//全局变量表 compiler_globals.auto_globals
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));//全局常量表 executor_globals.zend_constants
GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1, 0);
zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1, 0);//注册的模块
zend_hash_init_ex(&module_registry, 32, NULL, module_destructor_zval, 1, 0);//初始化ini全局变量(词语和语法分析时用,实际未用到)
ini_scanner_globals_ctor(&ini_scanner_globals);//初始化语言分析阶段的全局变量
php_scanner_globals_ctor(&language_scanner_globals);//资源类型的变量释放函数
zend_init_rsrc_list_dtors();//设置默认编译时间
zend_set_default_compile_time_values();//默认的错误报告类型:除了notice,其他都报告。
EG(error_reporting) = E_ALL & ~E_NOTICE;
七、zend_interned_strings_init 初始化内部字符串
其主要功能:
1. 设置字符串初始化函数指针
interned_string_request_handler = zend_new_interned_string_request;interned_string_init_request_handler = zend_string_init_interned_request;interned_string_copy_storage = NULL;interned_string_restore_storage = NULL;zend_new_interned_string = zend_new_interned_string_permanent;zend_string_init_interned = zend_string_init_interned_permanent;
2. 设置一些特殊的字符串
a. 空字符串
zend_empty_string = NULL;str = zend_string_alloc(sizeof("")-1, 1);ZSTR_VAL(str)[0] = '\000';zend_empty_string = zend_new_interned_string_permanent(str);
b. 单字符的字符串
char s[2];s[1] = 0;for (i = 0; i < 256; i++) {s[0] = i;zend_one_char_string[i] = zend_new_interned_string_permanent(zend_string_init(s, 1, 1));}
3. 设置内部预定义的字符串
#define ZEND_KNOWN_STRINGS(_) \_(ZEND_STR_FILE, "file") \_(ZEND_STR_LINE, "line") \_(ZEND_STR_FUNCTION, "function") \_(ZEND_STR_CLASS, "class") \_(ZEND_STR_OBJECT, "object") \_(ZEND_STR_TYPE, "type") \_(ZEND_STR_OBJECT_OPERATOR, "->") \_(ZEND_STR_PAAMAYIM_NEKUDOTAYIM, "::") \_(ZEND_STR_ARGS, "args") \_(ZEND_STR_UNKNOWN, "unknown") \_(ZEND_STR_EVAL, "eval") \_(ZEND_STR_INCLUDE, "include") \_(ZEND_STR_REQUIRE, "require") \_(ZEND_STR_INCLUDE_ONCE, "include_once") \_(ZEND_STR_REQUIRE_ONCE, "require_once") \_(ZEND_STR_SCALAR, "scalar") \_(ZEND_STR_ERROR_REPORTING, "error_reporting") \_(ZEND_STR_STATIC, "static") \_(ZEND_STR_THIS, "this") \_(ZEND_STR_VALUE, "value") \_(ZEND_STR_KEY, "key") \_(ZEND_STR_MAGIC_AUTOLOAD, "__autoload") \_(ZEND_STR_MAGIC_INVOKE, "__invoke") \_(ZEND_STR_PREVIOUS, "previous") \_(ZEND_STR_CODE, "code") \_(ZEND_STR_MESSAGE, "message") \_(ZEND_STR_SEVERITY, "severity") \_(ZEND_STR_STRING, "string") \_(ZEND_STR_TRACE, "trace") \_(ZEND_STR_SCHEME, "scheme") \_(ZEND_STR_HOST, "host") \_(ZEND_STR_PORT, "port") \_(ZEND_STR_USER, "user") \_(ZEND_STR_PASS, "pass") \_(ZEND_STR_PATH, "path") \_(ZEND_STR_QUERY, "query") \_(ZEND_STR_FRAGMENT, "fragment") \_(ZEND_STR_NULL, "NULL") \_(ZEND_STR_BOOLEAN, "boolean") \_(ZEND_STR_INTEGER, "integer") \_(ZEND_STR_DOUBLE, "double") \_(ZEND_STR_ARRAY, "array") \_(ZEND_STR_RESOURCE, "resource") \_(ZEND_STR_CLOSED_RESOURCE, "resource (closed)") \_(ZEND_STR_NAME, "name") \_(ZEND_STR_ARGV, "argv") \_(ZEND_STR_ARGC, "argc")static const char *known_strings[] = {
#define _ZEND_STR_DSC(id, str) str,
ZEND_KNOWN_STRINGS(_ZEND_STR_DSC)
#undef _ZEND_STR_DSCNULL
};zend_known_strings = pemalloc(sizeof(zend_string*) * ((sizeof(known_strings) / sizeof(known_strings[0]) - 1)), 1);for (i = 0; i < (sizeof(known_strings) / sizeof(known_strings[0])) - 1; i++) {str = zend_string_init(known_strings[i], strlen(known_strings[i]), 1);zend_known_strings[i] = zend_new_interned_string_permanent(str);}
八、zend_startup_builtin_functions 初始化内置函数
内置函数都定义于Core模块,函数列表如下:
static const zend_function_entry builtin_functions[] = { /* {{{ */ZEND_FE(zend_version, arginfo_zend__void)ZEND_FE(func_num_args, arginfo_zend__void)ZEND_FE(func_get_arg, arginfo_func_get_arg)ZEND_FE(func_get_args, arginfo_zend__void)ZEND_FE(strlen, arginfo_strlen)ZEND_FE(strcmp, arginfo_strcmp)ZEND_FE(strncmp, arginfo_strncmp)ZEND_FE(strcasecmp, arginfo_strcmp)ZEND_FE(strncasecmp, arginfo_strncmp)ZEND_FE(each, arginfo_each)ZEND_FE(error_reporting, arginfo_error_reporting)ZEND_FE(define, arginfo_define)ZEND_FE(defined, arginfo_defined)ZEND_FE(get_class, arginfo_get_class)ZEND_FE(get_called_class, arginfo_zend__void)ZEND_FE(get_parent_class, arginfo_get_class)ZEND_FE(method_exists, arginfo_method_exists)ZEND_FE(property_exists, arginfo_property_exists)ZEND_FE(class_exists, arginfo_class_exists)ZEND_FE(interface_exists, arginfo_class_exists)ZEND_FE(trait_exists, arginfo_trait_exists)ZEND_FE(function_exists, arginfo_function_exists)ZEND_FE(class_alias, arginfo_class_alias)ZEND_FE(get_included_files, arginfo_zend__void)ZEND_FALIAS(get_required_files, get_included_files, arginfo_zend__void)ZEND_FE(is_subclass_of, arginfo_is_subclass_of)ZEND_FE(is_a, arginfo_is_subclass_of)ZEND_FE(get_class_vars, arginfo_get_class_vars)ZEND_FE(get_object_vars, arginfo_get_object_vars)ZEND_FE(get_class_methods, arginfo_get_class_methods)ZEND_FE(trigger_error, arginfo_trigger_error)ZEND_FALIAS(user_error, trigger_error, arginfo_trigger_error)ZEND_FE(set_error_handler, arginfo_set_error_handler)ZEND_FE(restore_error_handler, arginfo_zend__void)ZEND_FE(set_exception_handler, arginfo_set_exception_handler)ZEND_FE(restore_exception_handler, arginfo_zend__void)ZEND_FE(get_declared_classes, arginfo_zend__void)ZEND_FE(get_declared_traits, arginfo_zend__void)ZEND_FE(get_declared_interfaces, arginfo_zend__void)ZEND_FE(get_defined_functions, arginfo_get_defined_functions)ZEND_FE(get_defined_vars, arginfo_zend__void)ZEND_DEP_FE(create_function, arginfo_create_function)ZEND_FE(get_resource_type, arginfo_get_resource_type)ZEND_FE(get_resources, arginfo_get_resources)ZEND_FE(get_loaded_extensions, arginfo_get_loaded_extensions)ZEND_FE(extension_loaded, arginfo_extension_loaded)ZEND_FE(get_extension_funcs, arginfo_extension_loaded)ZEND_FE(get_defined_constants, arginfo_get_defined_constants)ZEND_FE(debug_backtrace, arginfo_debug_backtrace)ZEND_FE(debug_print_backtrace, arginfo_debug_print_backtrace)ZEND_FE(gc_mem_caches, arginfo_zend__void)ZEND_FE(gc_collect_cycles, arginfo_zend__void)ZEND_FE(gc_enabled, arginfo_zend__void)ZEND_FE(gc_enable, arginfo_zend__void)ZEND_FE(gc_disable, arginfo_zend__void)ZEND_FE(gc_status, arginfo_zend__void)ZEND_FE_END
};
九、zend_register_standard_constants 定义内置的常量
常量都会写入到一个array里,其变量名:executor_globals.zend_constants
常量列表如下:
REGISTER_MAIN_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_RECOVERABLE_ERROR", E_RECOVERABLE_ERROR, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_NOTICE", E_NOTICE, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_STRICT", E_STRICT, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_DEPRECATED", E_DEPRECATED, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_CORE_ERROR", E_CORE_ERROR, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_CORE_WARNING", E_CORE_WARNING, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_ERROR", E_COMPILE_ERROR, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_WARNING", E_COMPILE_WARNING, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_USER_ERROR", E_USER_ERROR, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_USER_WARNING", E_USER_WARNING, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_USER_DEPRECATED", E_USER_DEPRECATED, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);/* true/false constants */{REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT | CONST_CT_SUBST);REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT | CONST_CT_SUBST);REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS);REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS);}REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT | CONST_CT_SUBST);
十、zend_register_auto_global 定义内置全局变量的容器
将"GLOBALS"全局变量容器放入 compiler_globals.auto_globals
int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback) /* {{{ */
{zend_auto_global auto_global;int retval;auto_global.name = name;auto_global.auto_global_callback = auto_global_callback;auto_global.jit = jit;retval = zend_hash_add_mem(CG(auto_globals), auto_global.name, &auto_global, sizeof(zend_auto_global)) != NULL ? SUCCESS : FAILURE;return retval;
}zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
十一、zend_ini_startup 初始化ini结构
ZEND_API int zend_ini_startup(void)
{registered_zend_ini_directives = (HashTable *) malloc(sizeof(HashTable));EG(ini_directives) = registered_zend_ini_directives;EG(modified_ini_directives) = NULL;EG(error_reporting_ini_entry) = NULL;zend_hash_init_ex(registered_zend_ini_directives, 128, NULL, free_ini_entry, 1, 0);return SUCCESS;
}
至此,zend_startup 已经执行完毕。
PHP内核源码阅读过程(四)相关推荐
- 【转载】ubuntu下linux内核源码阅读工具和调试方法总结
http://blog.chinaunix.net/space.php?uid=20940095&do=blog&cuid=2377369 一 linux内核源码阅读工具 window ...
- xilinx linux内核,Xilinx-Zynq Linux内核源码编译过程
本文内容依据http://www.wiki.xilinx.com网址编写,编译所用操作系统为ubuntu 14 1.交叉编译环境的安装配置 2.uboot的编译 1)下载uboot源代码 下载uboo ...
- Alibaba Druid 源码阅读(四) 数据库连接池中连接获取探索
Alibaba Druid 源码阅读(四) 数据库连接池中连接获取探索 简介 上文中分析了数据库连接池的初始化部分,接下来我们来看看获取连接部分的代码 数据库连接池中连接获取 下面的相关的代码,在代码 ...
- Soul 网关源码阅读(四)Dubbo请求概览
Soul 网关源码阅读(四)Dubbo请求概览 简介 本次启动一个dubbo服务示例,初步探索Soul网关源码的Dubbo请求处理流程 示例运行 环境配置 在Soul源码clone下来 ...
- Linux内核源码阅读以及工具(转)
Linux内核源码阅读以及工具(转) 转载地址:Linux内核源码阅读以及工具(转)
- Linux内核源码阅读以及工具详解
接上篇Linux内核源码下载方法 这篇总结了如何利用source insight对Linux内核代码进行阅读和学习(资料来源于网络) 随着linux的逐步普及,现在有不少人对于Linux的安装及设置已 ...
- Mybatis源码阅读(四):核心接口4.1——StatementHandler
*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...
- Werkzeug源码阅读笔记(四)
今天主要讲一下werkzeug中的routing模块.这个模块是werkzeug中的重点模块,Flask中的路由相关的操作使用的都是这个模块 routing模块的用法 在讲解模块的源码之前,先讲讲这个 ...
- Flask源码阅读-第四篇(flask\app.py)
flask.app该模块2000多行代码,主要完成应用的配置.初始化.蓝图注册.请求装饰器定义.应用的启动和监听,其中以下方法可以重点品读和关注 def setupmethod(f): @setupm ...
最新文章
- 爬虫之常用数据解析方法
- matlab 格式化文件,格式化matlab文件01_新建普通文件
- [2021-06-19] 提高组新手副本Ⅱ(联网,欧几里得,分解树,开关灯)
- linux查找时间文件,Linux基础教程 linux下使用find命令根据系统时间查找文件用法(示例代码)...
- Spring| BeanCurrentlyInCreationException: Error creating bean with name ‘‘xxx“
- Pytorch中model.eval()的作用分析
- win2003 server重启故障
- Unable to convert MySQL date/time value to System.DateTime
- 期货市场的大户黑手(最大的是华尔街 高盛之流)
- Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币,以及面值1024元的纸币。现在小Y使用1024元的纸币购买了一件价值为N的商品,请问最少他会收到多少硬币?
- Visual SourceSafe 2005 简体中文语言包
- 高等数学 关于反三角函数arcsin(sinx)的问题
- 1~20以内的加减法
- 电脑安装android系统 锤子,锤子系统手机桌面
- 小白福利-手把手教你如何重新安装你的系统
- 利用BaiduPCS-Go批量秒传与备份
- java 微信文章评论点赞_微信文章留言评论刷赞怎么弄?如何给微信文章
- 一些与OWL相关的推理机的区别(如:Jess、Jena、Pellet等)
- AudioEffect与Equalizer解析(Java侧)
- [THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导