php-5.6.26源代码 - PHP文件汇编成opcode、执行

 

文件 php-5.6.26/Zend/zend.c

ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */
{
    va_list files;
    int i;
    zend_file_handle *file_handle;
    zend_op_array *orig_op_array = EG(active_op_array); // 保存现场,操作码数组 
    zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr); // 返回值“指针”
    long orig_interactive = CG(interactive);

    va_start(files, file_count);
    for (i = 0; i < file_count; i++) { // 
        file_handle = va_arg(files, zend_file_handle *); // 获取文件名(前置文件、主文件、后置文件)
        if (!file_handle) {
            continue;
        }

        if (orig_interactive) {
            if (file_handle->filename[0] != '-' || file_handle->filename[1]) {
                CG(interactive) = 0;
            } else {
                CG(interactive) = 1;
            }
        }
       
        EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC); // 编译PHP文件成操作码 op_code  , zend_compile_file == compile_file
        if (file_handle->opened_path) {
            int dummy = 1;
            zend_hash_add(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path) + 1, (void *)&dummy, sizeof(int), NULL); // included 的文件列表
        }
        zend_destroy_file_handle(file_handle TSRMLS_CC);  // 销毁文件句柄
        if (EG(active_op_array)) { // “操作码”数组
            EG(return_value_ptr_ptr) = retval ? retval : NULL;
            zend_execute(EG(active_op_array) TSRMLS_CC);  // 执行编译后的操作码 op_code  , zend_execute ==  execute_ex
            zend_exception_restore(TSRMLS_C); // 还原异常
            if (EG(exception)) { // 检查异常
                if (EG(user_exception_handler)) { // 用户的异常处理器
                    zval *orig_user_exception_handler;
                    zval **params[1], *retval2, *old_exception;
                    old_exception = EG(exception);
                    EG(exception) = NULL;
                    params[0] = &old_exception;
                    orig_user_exception_handler = EG(user_exception_handler);
                    if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) { // 调用用户的异常处理器
                        if (retval2 != NULL) {
                            zval_ptr_dtor(&retval2);
                        }
                        if (EG(exception)) {
                            zval_ptr_dtor(&EG(exception));
                            EG(exception) = NULL;
                        }
                        zval_ptr_dtor(&old_exception);
                    } else {
                        EG(exception) = old_exception;
                        zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
                    }
                } else {
                    zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
                }
            }
            destroy_op_array(EG(active_op_array) TSRMLS_CC); // 迭代执行所有 zend_extensions 扩展的 zend_extension_op_array_dtor_handler 函数 
            efree(EG(active_op_array));
        } else if (type==ZEND_REQUIRE) {
            va_end(files);
            EG(active_op_array) = orig_op_array;
            EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
            CG(interactive) = orig_interactive;
            return FAILURE;
        }
    }
    va_end(files);
    EG(active_op_array) = orig_op_array; // 还原现场
    EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
    CG(interactive) = orig_interactive;

    return SUCCESS;
}
/* }}} */

 

posted on 2018-03-23 10:07  周~~  阅读(273)  评论(0编辑  收藏  举报

导航