这次来讲讲 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内核源码阅读过程(四)相关推荐

  1. 【转载】ubuntu下linux内核源码阅读工具和调试方法总结

    http://blog.chinaunix.net/space.php?uid=20940095&do=blog&cuid=2377369 一 linux内核源码阅读工具 window ...

  2. xilinx linux内核,Xilinx-Zynq Linux内核源码编译过程

    本文内容依据http://www.wiki.xilinx.com网址编写,编译所用操作系统为ubuntu 14 1.交叉编译环境的安装配置 2.uboot的编译 1)下载uboot源代码 下载uboo ...

  3. Alibaba Druid 源码阅读(四) 数据库连接池中连接获取探索

    Alibaba Druid 源码阅读(四) 数据库连接池中连接获取探索 简介 上文中分析了数据库连接池的初始化部分,接下来我们来看看获取连接部分的代码 数据库连接池中连接获取 下面的相关的代码,在代码 ...

  4. Soul 网关源码阅读(四)Dubbo请求概览

    Soul 网关源码阅读(四)Dubbo请求概览 简介     本次启动一个dubbo服务示例,初步探索Soul网关源码的Dubbo请求处理流程 示例运行 环境配置     在Soul源码clone下来 ...

  5. Linux内核源码阅读以及工具(转)

    Linux内核源码阅读以及工具(转) 转载地址:Linux内核源码阅读以及工具(转)

  6. Linux内核源码阅读以及工具详解

    接上篇Linux内核源码下载方法 这篇总结了如何利用source insight对Linux内核代码进行阅读和学习(资料来源于网络) 随着linux的逐步普及,现在有不少人对于Linux的安装及设置已 ...

  7. Mybatis源码阅读(四):核心接口4.1——StatementHandler

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...

  8. Werkzeug源码阅读笔记(四)

    今天主要讲一下werkzeug中的routing模块.这个模块是werkzeug中的重点模块,Flask中的路由相关的操作使用的都是这个模块 routing模块的用法 在讲解模块的源码之前,先讲讲这个 ...

  9. Flask源码阅读-第四篇(flask\app.py)

    flask.app该模块2000多行代码,主要完成应用的配置.初始化.蓝图注册.请求装饰器定义.应用的启动和监听,其中以下方法可以重点品读和关注 def setupmethod(f): @setupm ...

最新文章

  1. 爬虫之常用数据解析方法
  2. matlab 格式化文件,格式化matlab文件01_新建普通文件
  3. [2021-06-19] 提高组新手副本Ⅱ(联网,欧几里得,分解树,开关灯)
  4. linux查找时间文件,Linux基础教程 linux下使用find命令根据系统时间查找文件用法(示例代码)...
  5. Spring| BeanCurrentlyInCreationException: Error creating bean with name ‘‘xxx“
  6. Pytorch中model.eval()的作用分析
  7. win2003 server重启故障
  8. Unable to convert MySQL date/time value to System.DateTime
  9. 期货市场的大户黑手(最大的是华尔街 高盛之流)
  10. Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币,以及面值1024元的纸币。现在小Y使用1024元的纸币购买了一件价值为N的商品,请问最少他会收到多少硬币?
  11. Visual SourceSafe 2005 简体中文语言包
  12. 高等数学 关于反三角函数arcsin(sinx)的问题
  13. 1~20以内的加减法
  14. 电脑安装android系统 锤子,锤子系统手机桌面
  15. 小白福利-手把手教你如何重新安装你的系统
  16. 利用BaiduPCS-Go批量秒传与备份
  17. java 微信文章评论点赞_微信文章留言评论刷赞怎么弄?如何给微信文章
  18. 一些与OWL相关的推理机的区别(如:Jess、Jena、Pellet等)
  19. AudioEffect与Equalizer解析(Java侧)
  20. [THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导

热门文章

  1. 大数据架构之--Kappa架构
  2. 尚硅谷 java基础第二个项目之客户关系管理系统
  3. Django学习记录8
  4. 这 4 个超实用的 Docker 镜像构建技巧!你不会不知道吧?
  5. 基于树莓派的Azure物联网实践(一)
  6. Git泄露 之Stash(做题过程)
  7. JAVA学习笔记-----Thirteen(正则表达式,Math)
  8. proguard的使用
  9. (附源码)springboot高校学生健康打卡系统的设计与实现 毕业设计 021009
  10. JSTL: empty 可以减少很多繁冗的判空