1、初始化 opcode处理器列表 // main实现在文件“php-5.6.26\sapi\cgi\cgi_main.c” int main(int argc, char *argv[]) { if (cgi_sapi_module.startup(&cgi_sapi_module){ // php_cgi_startup实现在文件“php-5.6.26\sapi\cgi\cgi_main.c” static int php_cgi_startup(sapi_module_struct *sapi_module) { if (php_module_startup(sapi_module, &cgi_module_entry, 1){ // zend_startup实现在文件“php-5.6.26\sapi\cgi\cgi_main.c” int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules) { // zend_startup实现在文件“php-5.6.26\Zend\zend.c” zend_startup(&zuf, NULL TSRMLS_CC); // !!!! { int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC) { ... // zend_init_opcodes_handlers实现在文件php-7.2.3\Zend\zend_vm_execute.h zend_init_opcodes_handlers(); // !!! 初始化“opcodes处理器”列表 ------------ 初始化 { static const opcode_handler_t labels[] = { ZEND_NOP_SPEC_HANDLER, ZEND_NOP_SPEC_HANDLER, ZEND_NOP_SPEC_HANDLER, ZEND_NOP_SPEC_HANDLER, ZEND_NOP_SPEC_HANDLER, ... ZEND_ASSIGN_POW_SPEC_CV_TMP_HANDLER, ZEND_ASSIGN_POW_SPEC_CV_VAR_HANDLER, ZEND_ASSIGN_POW_SPEC_CV_UNUSED_HANDLER, ZEND_ASSIGN_POW_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; } ... } } } } == FAILURE) { return FAILURE; } return SUCCESS; } } == FAILURE) { // startup ---> php_cgi_startup ---> php_module_startup #ifdef ZTS --- tsrm_shutdown(); #endif return FAILURE; } } 2、注入opcode处理器 & 执行opcode处理器 // 在文件 php-5.6.26\main\main.c PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) { ... /* If cli primary file has shabang line and there is a prepend file, the `start_lineno` will be used by prepend file but not primary file, save it and restore after prepend file been executed. */ if (CG(start_lineno) && prepend_file_p) { int orig_start_lineno = CG(start_lineno); CG(start_lineno) = 0; if (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 1, prepend_file_p) == SUCCESS) { CG(start_lineno) = orig_start_lineno; retval = (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 2, primary_file, append_file_p) == SUCCESS); } } else { // 在文件 php-5.6.26\Zend\zend.c retval = (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS); // 执行primary_file的php脚本 { ... EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC); // 编译PHP文件成操作码 op_code ,zend_compile_file == compile_file { // 在文件 php-5.6.26\Zend\zend_language_scanner.c !!!编译文件,编译出opcode ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) { ... if (retval) { CG(active_op_array) = original_active_op_array; // 还原原来 op_code 现场(还原现场) if (compilation_successful) { // !!!汇编成功 // 在文件 php-5.6.26\Zend\zend_opcode.c pass_two(op_array TSRMLS_CC); // !!!! 给每个op_code注册“op_code处理器” { ... while (opline < end) { // 迭代所有操作码 if (opline->op1_type == IS_CONST) { // 如果是是常量 opline->op1.zv = &op_array->literals[opline->op1.constant].constant; } if (opline->op2_type == IS_CONST) { opline->op2.zv = &op_array->literals[opline->op2.constant].constant; } switch (opline->opcode) { case ZEND_GOTO: if (Z_TYPE_P(opline->op2.zv) != IS_LONG) { zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC); } /* break omitted intentionally */ case ZEND_JMP: case ZEND_FAST_CALL: opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num]; break; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_JMP_SET_VAR: opline->op2.jmp_addr = &op_array->opcodes[opline->op2.opline_num]; break; case ZEND_RETURN: case ZEND_RETURN_BY_REF: if (op_array->fn_flags & ZEND_ACC_GENERATOR) { if (opline->op1_type != IS_CONST || Z_TYPE_P(opline->op1.zv) != IS_NULL) { CG(zend_lineno) = opline->lineno; zend_error_noreturn(E_COMPILE_ERROR, "Generators cannot return values using \"return\""); } opline->opcode = ZEND_GENERATOR_RETURN; } break; } ZEND_VM_SET_OPCODE_HANDLER(opline); // 设置“opcode处理器” ------------ 注入 { // 宏定义在文件 “php-5.6.26\Zend\zend_vm.h ” #define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline) { // zend_vm_set_opcode_handler 实现在文件“php-5.6.26\Zend\zend_vm_execute.h”, ZEND_API void zend_vm_set_opcode_handler(zend_op* op) // 获取“opcode处理器” { op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op); { // zend_vm_get_opcode_handler实现在文件“php-5.6.26\Zend\zend_vm_execute.h”, static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op) // 获取“opcode处理器” { static const int zend_vm_decode[] = { _UNUSED_CODE, /* 0 */ _CONST_CODE, /* 1 = IS_CONST */ _TMP_CODE, /* 2 = IS_TMP_VAR */ _UNUSED_CODE, /* 3 */ _VAR_CODE, /* 4 = IS_VAR */ _UNUSED_CODE, /* 5 */ _UNUSED_CODE, /* 6 */ _UNUSED_CODE, /* 7 */ _UNUSED_CODE, /* 8 = IS_UNUSED */ _UNUSED_CODE, /* 9 */ _UNUSED_CODE, /* 10 */ _UNUSED_CODE, /* 11 */ _UNUSED_CODE, /* 12 */ _UNUSED_CODE, /* 13 */ _UNUSED_CODE, /* 14 */ _UNUSED_CODE, /* 15 */ _CV_CODE /* 16 = IS_CV */ }; return zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type]]; } } } } } opline++; } op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO; return 0; ... } zend_release_labels(0 TSRMLS_CC); } else { efree(op_array); retval = NULL; } } ... } // !!! 执行 opcode 列表 if (EG(active_op_array)) { // “操作码”数组 EG(return_value_ptr_ptr) = retval ? retval : NULL; // 在文件 php-5.6.26\Zend\zend_vm_execute.c zend_execute(EG(active_op_array) TSRMLS_CC); // 执行编译后的操作码 op_code , zend_execute == execute_ex { if (EG(exception)) { return; } // 在文件 php-5.6.26\Zend\zend_vm_execute.c zend_execute_ex(i_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC) TSRMLS_CC); // zend_execute_ex = execute_ex { DCL_OPLINE zend_bool original_in_execution; original_in_execution = EG(in_execution); // 保存现场 EG(in_execution) = 1; // 正在执行中 if (0) { zend_vm_enter: execute_data = i_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC); } LOAD_REGS(); LOAD_OPLINE(); while (1) { int ret; #ifdef ZEND_WIN32 if (EG(timed_out)) { zend_timeout(0); } #endif /* OPLINE->handler(execute_data TSRMLS_CC) EX(opline)->handler(execute_data TSRMLS_CC) execute_data.opline->handler(execute_data TSRMLS_CC) */ if ((ret = OPLINE->handler(execute_data TSRMLS_CC)) > 0) { // execute_data.opline->handler(execute_data TSRMLS_CC) // 调用“opcode对应的处理函数” ------------调用 switch (ret) { case 1: EG(in_execution) = original_in_execution; // 还原现场 return; case 2: goto zend_vm_enter; // 进入虚拟机 break; case 3: execute_data = EG(current_execute_data); // 当前正在执行的数据 break; default: break; } } } zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen"); } } ... } ... } ... } } ... }
所有评论(0)