这次来讲讲 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