| 
、初始化 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, ){
                // 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;
 }
 }    
、注入opcode处理器
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) {  // !!!汇编成功
                // pass_two实现在文件 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,  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 *  + zend_vm_decode[op->op1_type] *  + zend_vm_decode[op->op2_type]];
 }
 }
 }
 }
 }
 opline++;
 }
                    op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
 return ;
 ...
 }
 zend_release_labels( TSRMLS_CC);
 } else {
 efree(op_array);
 retval = NULL;
 }
 }
 ...
 }
、执行opcode处理器
 // execute_ex 实现在文件 “php-5.6.26\Zend\zend_vm_execute.h”
 ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC)
 {
 if (EG(exception)) {
 return;
 } 
    zend_execute_ex(i_create_execute_data_from_op_array(op_array,  TSRMLS_CC) TSRMLS_CC); // zend_execute_ex = execute_ex
 {
 // execute_ex 实现在文件 “php-5.6.26\Zend\zend_vm_execute.h”
 ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
 {
 DCL_OPLINE
 zend_bool original_in_execution;
            original_in_execution = EG(in_execution);  // 保存现场
 EG(in_execution) = ; // 正在执行中 
            if () {
 zend_vm_enter:
 execute_data = i_create_execute_data_from_op_array(EG(active_op_array),  TSRMLS_CC);
 }
            LOAD_REGS();
 LOAD_OPLINE();
            while () {
 int ret;
 #ifdef ZEND_WIN32
 if (EG(timed_out)) {
 zend_timeout();
 }
 #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)) > ) {  // execute_data.opline->handler(execute_data TSRMLS_CC) //  调用“opcode对应的处理函数”
 switch (ret) {
 case :
 EG(in_execution) = original_in_execution; // 还原现场
 return;
 case :
 goto zend_vm_enter; // 进入虚拟机
 break;
 case :
 execute_data = EG(current_execute_data);  // 当前正在执行的数据
 break;
 default:
 break;
 }
 }
            }
 zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
 }
 }
 }
 | 
、初始化 opcode处理器列表
// main实现在文件“php-7.2.3\sapi\cgi\cgi_main.c”int main(int argc, char *argv[])
 {
 if (cgi_sapi_module.startup(&cgi_sapi_module){
 ...
 // php_cgi_startup实现在文件“php-7.2.3\sapi\cgi\cgi_main.c”
 static int php_cgi_startup(sapi_module_struct *sapi_module)
 {
 if (php_module_startup(sapi_module, &cgi_module_entry, ){
 ...
 // zend_startup实现在文件“php-7.2.3\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-7.2.3\Zend\zend.c”
 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 void *labels[] = {
 ZEND_NOP_SPEC_HANDLER,
 ZEND_ADD_SPEC_CONST_CONST_HANDLER,
 ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER,
 ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER,
 ...省略...
 ZEND_NULL_HANDLER,
 ZEND_NULL_HANDLER,
 ZEND_NULL_HANDLER,
 ZEND_NULL_HANDLER
 };
                            static const uint32_t specs[] = {
 ,
 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
 ...省略...
 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                            };
                        #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) // 当 defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS)
 zend_opcode_handler_funcs = labels;
 zend_spec_handlers = specs;
 execute_ex(NULL);
 #else
 zend_opcode_handlers = labels;
 zend_handlers_count = sizeof(labels) / sizeof(void*);
 zend_spec_handlers = specs;
 #endif
 }
 ...
 }
 ...
 }
 }
 }
 ...
 }
 }
、注入opcode处理器
 op_array = zend_compile_file(file_handle, type);  // 编译PHP文件成操作码 op_code ,zend_compile_file == compile_file
 {
 // compile_file实现在文件“php-7.2.3\Zend\zend_language_scanner.c”
 ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type)
 {
 zend_lex_state original_lex_state;
 // 和 php-5.6.26不同,没有所谓的“保存现场”的操作
 zend_op_array *op_array = NULL;
 zend_save_lexical_state(&original_lex_state);  // 保存词法分析器的状态(保存现场)
        if (open_file_for_scanning(file_handle)==FAILURE) { // 打开文件、设置扫描器的指针
 if (type==ZEND_REQUIRE) {
 zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
 zend_bailout(); // !!! require、require_once 会抛出异常
 } else {
 zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
 // 没有抛出异常
 }
 } else {
 // zend_compile实现在文件“php-7.2.3\Zend\zend_language_scanner.c”
 op_array = zend_compile(ZEND_USER_FUNCTION); // 编译文件、给每个op_code注册“op_code处理器”
 {
 zend_op_array *op_array = NULL;
 zend_bool original_in_compilation = CG(in_compilation);
                CG(in_compilation) = ;
 CG(ast) = NULL;
 CG(ast_arena) = zend_arena_create( * );
                if (!zendparse()) {
 int last_lineno = CG(zend_lineno);
 zend_file_context original_file_context;
 zend_oparray_context original_oparray_context;
 zend_op_array *original_active_op_array = CG(active_op_array); // 保存 op_code 现场(保存现场)
                    op_array = emalloc(sizeof(zend_op_array));
 init_op_array(op_array, type, INITIAL_OP_ARRAY_SIZE); // 1、初始化一些数据、申请空间  2、迭代调用所有 zend_extensions 扩展的 op_array_ctor 函数
 CG(active_op_array) = op_array; // 操作码数组
                    if (zend_ast_process) {
 zend_ast_process(CG(ast)); // !!!! “抽象语法树”处理器
 }
                    zend_file_context_begin(&original_file_context);
 zend_oparray_context_begin(&original_oparray_context);
 zend_compile_top_stmt(CG(ast));
 CG(zend_lineno) = last_lineno;
 zend_emit_final_return(type == ZEND_USER_FUNCTION);
 op_array->line_start = ;
 op_array->line_end = last_lineno;
 // pass_two实现在文件“php-7.2.3\Zend\zend_opcode.c”
 pass_two(op_array); // !!!! 给每个op_code注册“op_code处理器”
 {
 opline = op_array->opcodes;
 end = opline + op_array->last;
 while (opline < end) {
 switch (opline->opcode) {
 case ZEND_FAST_CALL:
 opline->op1.opline_num = op_array->try_catch_array[opline->op1.num].finally_op;
 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
 break;
 case ZEND_BRK:
 case ZEND_CONT:
 {
 uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline);
                                        if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
 zend_check_finally_breakout(op_array, opline - op_array->opcodes, jmp_target);
 }
 opline->opcode = ZEND_JMP;
 opline->op1.opline_num = jmp_target;
 opline->op2.num = ;
 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
 }
 break;
 case ZEND_GOTO:
 zend_resolve_goto_label(op_array, opline);
 if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
 zend_check_finally_breakout(op_array, opline - op_array->opcodes, opline->op1.opline_num);
 }
 /* break omitted intentionally */
 case ZEND_JMP:
 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
 break;
 case ZEND_JMPZNZ:
 /* absolute index to relative offset */
 opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
 /* break omitted intentionally */
 case ZEND_JMPZ:
 case ZEND_JMPNZ:
 case ZEND_JMPZ_EX:
 case ZEND_JMPNZ_EX:
 case ZEND_JMP_SET:
 case ZEND_COALESCE:
 case ZEND_FE_RESET_R:
 case ZEND_FE_RESET_RW:
 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
 break;
 case ZEND_ASSERT_CHECK:
 {
 /* If result of assert is unused, result of check is unused as well */
 zend_op *call = &op_array->opcodes[opline->op2.opline_num - ];
 if (call->opcode == ZEND_EXT_FCALL_END) {
 call--;
 }
 if (call->result_type == IS_UNUSED) {
 opline->result_type = IS_UNUSED;
 }
 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
 break;
 }
 case ZEND_DECLARE_ANON_CLASS:
 case ZEND_DECLARE_ANON_INHERITED_CLASS:
 case ZEND_CATCH:
 case ZEND_FE_FETCH_R:
 case ZEND_FE_FETCH_RW:
 /* absolute index to relative offset */
 opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
 break;
 case ZEND_RETURN:
 case ZEND_RETURN_BY_REF:
 if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
 opline->opcode = ZEND_GENERATOR_RETURN;
 }
 break;
 case ZEND_SWITCH_LONG:
 case ZEND_SWITCH_STRING:
 {
 /* absolute indexes to relative offsets */
 HashTable *jumptable = Z_ARRVAL_P(CT_CONSTANT(opline->op2));
 zval *zv;
 ZEND_HASH_FOREACH_VAL(jumptable, zv) {
 Z_LVAL_P(zv) = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, Z_LVAL_P(zv));
 } ZEND_HASH_FOREACH_END();
                                    opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
 break;
 }
 }
 if (opline->op1_type == IS_CONST) {
 ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
 } else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
 opline->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op1.var);
 }
 if (opline->op2_type == IS_CONST) {
 ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
 } else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
 opline->op2.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op2.var);
 }
 if (opline->result_type & (IS_VAR|IS_TMP_VAR)) {
 opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->result.var);
 }
 ZEND_VM_SET_OPCODE_HANDLER(opline); // 设置“opcode处理器”
 {
 // ZEND_VM_SET_OPCODE_HANDLER 宏定义在文件 “php-7.2.3\Zend\zend_vm.h ”
 #define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline)
 {
 // zend_vm_set_opcode_handler 实现在文件“php-7.2.3\Zend\zend_vm_execute.h”
 ZEND_API void zend_vm_set_opcode_handler(zend_op* op)
 {
 op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);
 {
 // zend_vm_get_opcode_handler_ex 实现在文件“php-7.2.3\Zend\zend_vm_execute.h”
 return zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);
 {
 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     */
 };
 uint32_t offset = ;
 if (spec & SPEC_RULE_OP1) offset = offset *  + zend_vm_decode[op->op1_type];
 if (spec & SPEC_RULE_OP2) offset = offset *  + zend_vm_decode[op->op2_type];
 if (spec & SPEC_RULE_OP_DATA) offset = offset *  + zend_vm_decode[(op + )->op1_type];
 if (spec & SPEC_RULE_RETVAL) offset = offset *  + (op->result_type != IS_UNUSED);
 if (spec & SPEC_RULE_QUICK_ARG) offset = offset *  + (op->op2.num < MAX_ARG_FLAG_NUM);
 if (spec & SPEC_RULE_SMART_BRANCH) {
 offset = offset * ;
 if ((op+)->opcode == ZEND_JMPZ) {
 offset += ;
 } else if ((op+)->opcode == ZEND_JMPNZ) {
 offset += ;
 }
 }
 if (spec & SPEC_RULE_DIM_OBJ) {
 offset = offset * ;
 if (op->extended_value == ZEND_ASSIGN_DIM) {
 offset += ;
 } else if (op->extended_value == ZEND_ASSIGN_OBJ) {
 offset += ;
 }
 }
 return zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];
 }
 }
 }
 }
                            }
 opline++;
 }
                        if (op_array->live_range) {
 int i;
                            for (i = ; i < op_array->last_live_range; i++) {
 op_array->live_range[i].var =
 (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + (op_array->live_range[i].var / sizeof(zval))) |
 (op_array->live_range[i].var & ZEND_LIVE_MASK);
 }
 }
 }
 zend_oparray_context_end(&original_oparray_context);
 zend_file_context_end(&original_file_context);
                    CG(active_op_array) = original_active_op_array;  // 还原原来 op_code 现场(还原现场)
 }
                zend_ast_destroy(CG(ast));
 zend_arena_destroy(CG(ast_arena));
                CG(in_compilation) = original_in_compilation;
                return op_array;
 }
 }
        zend_restore_lexical_state(&original_lex_state); // 还原原来词法解析器的状态(还原现场)
 return op_array;
 }
 }
、执行opcode处理器
 // execute_ex 实现在文件 “php-7.2.3\Zend\zend_vm_execute.h”
 ZEND_API void execute_ex(zend_execute_data *ex)
 {
 DCL_OPLINE // 空操作
#ifdef ZEND_VM_IP_GLOBAL_REG
 const zend_op *orig_opline = opline;
 #endif
 #ifdef ZEND_VM_FP_GLOBAL_REG
 zend_execute_data *orig_execute_data = execute_data;
 execute_data = ex;
 #else
 zend_execute_data *execute_data = ex;
 #endif
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) // 当 defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS)
 if (UNEXPECTED(execute_data == NULL)) {
 static const void* labels[] = {
 (void*)&&ZEND_NOP_SPEC_LABEL,
 (void*)&&ZEND_ADD_SPEC_CONST_CONST_LABEL,
 (void*)&&ZEND_ADD_SPEC_CONST_TMPVAR_LABEL,
 (void*)&&ZEND_ADD_SPEC_CONST_TMPVAR_LABEL,
 ...省略...
 (void*)&&ZEND_NULL_LABEL,
 (void*)&&ZEND_NULL_LABEL,
 (void*)&&ZEND_NULL_LABEL,
 (void*)&&ZEND_NULL_LABEL
 };
 zend_opcode_handlers = (const void **) labels;
 zend_handlers_count = sizeof(labels) / sizeof(void*);
 memset(&hybrid_halt_op, , sizeof(hybrid_halt_op));
 hybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;
 goto HYBRID_HALT_LABEL;
 }
 #endif
    LOAD_OPLINE(); //  opline = EX(opline);
 ZEND_VM_LOOP_INTERRUPT_CHECK();
    while () {
 #if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG)
 int ret;
 #endif
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) // 当 defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS)
 HYBRID_SWITCH() { // 宏展开为   goto *(void**)(OPLINE->handler) 跳转到函数指针入口,执行“opcode处理器”函数
 #else // !!!不使用 ZEND_VM_KIND_HYBRID
 #if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)
 ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);  // 调用“opcode处理器”函数
 if (UNEXPECTED(!OPLINE)) {
 #else
 if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != )) { // 调用“opcode处理器”函数,类似 php-5.6.26 的执行方式
 #endif
 #endif // 结束 ZEND_VM_KIND 判断
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) // 当 defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS)
 HYBRID_CASE(ZEND_JMP_SPEC):  // 宏展开为   ZEND_JMP_SPEC_LABEL
 ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);  // 调用函数!!!
 HYBRID_BREAK(); // 宏展开为   goto *(void**)(OPLINE->handler) 跳转到函数指针入口,执行“opcode处理器”函数
 HYBRID_CASE(ZEND_DO_ICALL_SPEC_RETVAL_UNUSED): // 宏展开为   ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_LABEL
 ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 HYBRID_BREAK();
 HYBRID_CASE(ZEND_DO_ICALL_SPEC_RETVAL_USED):
 ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 ...省略...
 HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ):
 ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 HYBRID_BREAK();
 HYBRID_CASE(HYBRID_HALT):
 execute_data = orig_execute_data;
 opline = orig_opline;
 return;
 HYBRID_DEFAULT:
 zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
 HYBRID_BREAK(); /* Never reached */
 #else // !!!不使用 ZEND_VM_KIND_HYBRID
 #ifdef ZEND_VM_FP_GLOBAL_REG
 execute_data = orig_execute_data;
 # ifdef ZEND_VM_IP_GLOBAL_REG
 opline = orig_opline;
 # endif
 return;
 #else
 if (EXPECTED(ret > )) {
 execute_data = EG(current_execute_data);
 ZEND_VM_LOOP_INTERRUPT_CHECK();
 } else {
 # ifdef ZEND_VM_IP_GLOBAL_REG
 opline = orig_opline;
 # endif
 return;
 }
 #endif
 #endif // 结束 ZEND_VM_KIND 判断
 }
 } // END while ...
 zend_error_noreturn(E_CORE_ERROR, "Arrived at end of main loop which shouldn't happen");
 }
 |