/* +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | https://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | | Stanislav Malyshev | | Dmitry Stogov | +----------------------------------------------------------------------+ */ #include #include #include #include #include "php.h" #include "ZendAccelerator.h" #include "zend_API.h" #include "zend_shared_alloc.h" #include "zend_file_cache.h" #include "zend_accelerator_blacklist.h" #include "php_ini.h" #include "SAPI.h" #include "zend_virtual_cwd.h" #include "ext/standard/info.h" #include "ext/standard/php_filestat.h" #include "ext/date/php_date.h" #include "opcache_arginfo.h" #include "zend_accelerator_module.h" #include "Zend/Optimizer/zend_dump.h" #include "Zend/zend_exceptions.h" #define STRING_NOT_NULL(s) (NULL == (s)?"":s) #define MIN_ACCEL_FILES 200 #define MAX_ACCEL_FILES 1000000 #define MAX_INTERNED_STRINGS_BUFFER_SIZE ((zend_long)((UINT32_MAX-PLATFORM_ALIGNMENT-sizeof(zend_accel_shared_globals))/(1024*1024))) #define TOKENTOSTR(X) #X static zif_handler orig_file_exists = NULL; static zif_handler orig_is_file = NULL; static zif_handler orig_is_readable = NULL; static ZEND_INI_MH(OnUpdateMemoryConsumption) { zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); zend_long memsize = atoi(ZSTR_VAL(new_value)); /* sanity check we must use at least 8 MB */ if (memsize < 8) { zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption is set below the required 8MB.\n"); return FAILURE; } if (UNEXPECTED(memsize > ZEND_LONG_MAX / (1024 * 1024))) { *p = ZEND_LONG_MAX & ~(1024 * 1024 - 1); } else { *p = memsize * (1024 * 1024); } return SUCCESS; } static ZEND_INI_MH(OnUpdateInternedStringsBuffer) { zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); zend_long size = zend_ini_parse_quantity_warn(new_value, entry->name); if (size < 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache.interned_strings_buffer must be greater than or equal to 0, " ZEND_LONG_FMT " given.\n", size); return FAILURE; } if (size > MAX_INTERNED_STRINGS_BUFFER_SIZE) { zend_accel_error(ACCEL_LOG_WARNING, "opcache.interned_strings_buffer must be less than or equal to " ZEND_LONG_FMT ", " ZEND_LONG_FMT " given.\n", MAX_INTERNED_STRINGS_BUFFER_SIZE, size); return FAILURE; } *p = size; return SUCCESS; } static ZEND_INI_MH(OnUpdateMaxAcceleratedFiles) { zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); zend_long size = atoi(ZSTR_VAL(new_value)); /* sanity check we must use a value between MIN_ACCEL_FILES and MAX_ACCEL_FILES */ if (size < MIN_ACCEL_FILES) { zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_accelerated_files is set below the required minimum (%d).\n", MIN_ACCEL_FILES); return FAILURE; } if (size > MAX_ACCEL_FILES) { zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_accelerated_files is set above the limit (%d).\n", MAX_ACCEL_FILES); return FAILURE; } *p = size; return SUCCESS; } static ZEND_INI_MH(OnUpdateMaxWastedPercentage) { double *p = (double *) ZEND_INI_GET_ADDR(); zend_long percentage = atoi(ZSTR_VAL(new_value)); if (percentage <= 0 || percentage > 50) { zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_wasted_percentage must be set between 1 and 50.\n"); return FAILURE; } *p = (double)percentage / 100.0; return SUCCESS; } static ZEND_INI_MH(OnEnable) { if (stage == ZEND_INI_STAGE_STARTUP || stage == ZEND_INI_STAGE_SHUTDOWN || stage == ZEND_INI_STAGE_DEACTIVATE) { return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } else { /* It may be only temporary disabled */ bool *p = (bool *) ZEND_INI_GET_ADDR(); if (zend_ini_parse_bool(new_value)) { zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " can't be temporary enabled (it may be only disabled till the end of request)"); return FAILURE; } else { *p = 0; ZCG(accelerator_enabled) = 0; return SUCCESS; } } } static ZEND_INI_MH(OnUpdateFileCache) { if (new_value) { if (!ZSTR_LEN(new_value)) { new_value = NULL; } else { zend_stat_t buf = {0}; if (!IS_ABSOLUTE_PATH(ZSTR_VAL(new_value), ZSTR_LEN(new_value)) || zend_stat(ZSTR_VAL(new_value), &buf) != 0 || !S_ISDIR(buf.st_mode) || #ifndef ZEND_WIN32 access(ZSTR_VAL(new_value), R_OK | W_OK | X_OK) != 0) { #else _access(ZSTR_VAL(new_value), 06) != 0) { #endif zend_accel_error(ACCEL_LOG_WARNING, "opcache.file_cache must be a full path of accessible directory.\n"); new_value = NULL; } } } OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); return SUCCESS; } ZEND_INI_BEGIN() STD_PHP_INI_BOOLEAN("opcache.enable" , "1", PHP_INI_ALL, OnEnable, enabled , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.use_cwd" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.use_cwd , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.validate_timestamps", "1", PHP_INI_ALL , OnUpdateBool, accel_directives.validate_timestamps, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.validate_permission", "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_permission, zend_accel_globals, accel_globals) #ifndef ZEND_WIN32 STD_PHP_INI_BOOLEAN("opcache.validate_root" , "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_root , zend_accel_globals, accel_globals) #endif STD_PHP_INI_BOOLEAN("opcache.dups_fix" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.ignore_dups , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.revalidate_path" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.revalidate_path , zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.log_verbosity_level" , "1" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.log_verbosity_level, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.memory_consumption" , "128" , PHP_INI_SYSTEM, OnUpdateMemoryConsumption, accel_directives.memory_consumption, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.interned_strings_buffer", "8" , PHP_INI_SYSTEM, OnUpdateInternedStringsBuffer, accel_directives.interned_strings_buffer, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.max_accelerated_files" , "10000", PHP_INI_SYSTEM, OnUpdateMaxAcceleratedFiles, accel_directives.max_accelerated_files, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.max_wasted_percentage" , "5" , PHP_INI_SYSTEM, OnUpdateMaxWastedPercentage, accel_directives.max_wasted_percentage, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.force_restart_timeout" , "180" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.force_restart_timeout, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.revalidate_freq" , "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.revalidate_freq, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.file_update_protection", "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.file_update_protection, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.blacklist_filename" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.user_blacklist_filename, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.max_file_size" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.max_file_size, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.protect_memory" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.protect_memory, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.save_comments" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.save_comments, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.record_warnings" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.record_warnings, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.optimization_level" , DEFAULT_OPTIMIZATION_LEVEL , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.optimization_level, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.opt_debug_level" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.opt_debug_level, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.enable_file_override" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_override_enabled, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals) #ifndef ZEND_WIN32 STD_PHP_INI_ENTRY("opcache.lockfile_path" , "/tmp" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.lockfile_path, zend_accel_globals, accel_globals) #else STD_PHP_INI_ENTRY("opcache.mmap_base", NULL, PHP_INI_SYSTEM, OnUpdateString, accel_directives.mmap_base, zend_accel_globals, accel_globals) #endif STD_PHP_INI_ENTRY("opcache.file_cache" , NULL , PHP_INI_SYSTEM, OnUpdateFileCache, accel_directives.file_cache, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.file_cache_only" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_only, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.file_cache_consistency_checks" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_consistency_checks, zend_accel_globals, accel_globals) #if ENABLE_FILE_CACHE_FALLBACK STD_PHP_INI_BOOLEAN("opcache.file_cache_fallback" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_fallback, zend_accel_globals, accel_globals) #endif #ifdef HAVE_HUGE_CODE_PAGES STD_PHP_INI_BOOLEAN("opcache.huge_code_pages" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.huge_code_pages, zend_accel_globals, accel_globals) #endif STD_PHP_INI_ENTRY("opcache.preload" , "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.preload, zend_accel_globals, accel_globals) #ifndef ZEND_WIN32 STD_PHP_INI_ENTRY("opcache.preload_user" , "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.preload_user, zend_accel_globals, accel_globals) #endif #if ZEND_WIN32 STD_PHP_INI_ENTRY("opcache.cache_id" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.cache_id, zend_accel_globals, accel_globals) #endif ZEND_INI_END() static int filename_is_in_cache(zend_string *filename) { zend_string *key; key = accel_make_persistent_key(filename); if (key != NULL) { zend_persistent_script *persistent_script = zend_accel_hash_find(&ZCSG(hash), key); if (persistent_script && !persistent_script->corrupted) { if (ZCG(accel_directives).validate_timestamps) { zend_file_handle handle; int ret; zend_stream_init_filename_ex(&handle, filename); ret = validate_timestamp_and_record_ex(persistent_script, &handle) == SUCCESS ? 1 : 0; zend_destroy_file_handle(&handle); return ret; } return 1; } } return 0; } static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) { if (ZEND_NUM_ARGS() == 1) { zval *zv = ZEND_CALL_ARG(execute_data , 1); if (Z_TYPE_P(zv) == IS_STRING && Z_STRLEN_P(zv) != 0) { return filename_is_in_cache(Z_STR_P(zv)); } } return 0; } static ZEND_NAMED_FUNCTION(accel_file_exists) { if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) { RETURN_TRUE; } else { orig_file_exists(INTERNAL_FUNCTION_PARAM_PASSTHRU); } } static ZEND_NAMED_FUNCTION(accel_is_file) { if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) { RETURN_TRUE; } else { orig_is_file(INTERNAL_FUNCTION_PARAM_PASSTHRU); } } static ZEND_NAMED_FUNCTION(accel_is_readable) { if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) { RETURN_TRUE; } else { orig_is_readable(INTERNAL_FUNCTION_PARAM_PASSTHRU); } } static ZEND_MINIT_FUNCTION(zend_accelerator) { (void)type; /* keep the compiler happy */ REGISTER_INI_ENTRIES(); return SUCCESS; } void zend_accel_override_file_functions(void) { zend_function *old_function; if (ZCG(enabled) && accel_startup_ok && ZCG(accel_directives).file_override_enabled) { if (file_cache_only) { zend_accel_error(ACCEL_LOG_WARNING, "file_override_enabled has no effect when file_cache_only is set"); return; } /* override file_exists */ if ((old_function = zend_hash_str_find_ptr(CG(function_table), "file_exists", sizeof("file_exists")-1)) != NULL) { orig_file_exists = old_function->internal_function.handler; old_function->internal_function.handler = accel_file_exists; } if ((old_function = zend_hash_str_find_ptr(CG(function_table), "is_file", sizeof("is_file")-1)) != NULL) { orig_is_file = old_function->internal_function.handler; old_function->internal_function.handler = accel_is_file; } if ((old_function = zend_hash_str_find_ptr(CG(function_table), "is_readable", sizeof("is_readable")-1)) != NULL) { orig_is_readable = old_function->internal_function.handler; old_function->internal_function.handler = accel_is_readable; } } } static ZEND_MSHUTDOWN_FUNCTION(zend_accelerator) { (void)type; /* keep the compiler happy */ UNREGISTER_INI_ENTRIES(); accel_shutdown(); return SUCCESS; } void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS) { php_info_print_table_start(); if (ZCG(accelerator_enabled) || file_cache_only) { php_info_print_table_row(2, "Opcode Caching", "Up and Running"); } else { php_info_print_table_row(2, "Opcode Caching", "Disabled"); } if (ZCG(enabled) && accel_startup_ok && ZCG(accel_directives).optimization_level) { php_info_print_table_row(2, "Optimization", "Enabled"); } else { php_info_print_table_row(2, "Optimization", "Disabled"); } if (!file_cache_only) { php_info_print_table_row(2, "SHM Cache", "Enabled"); } else { php_info_print_table_row(2, "SHM Cache", "Disabled"); } if (ZCG(accel_directives).file_cache) { php_info_print_table_row(2, "File Cache", "Enabled"); } else { php_info_print_table_row(2, "File Cache", "Disabled"); } php_info_print_table_row(2, "JIT", "Not Available"); if (file_cache_only) { if (!accel_startup_ok || zps_api_failure_reason) { php_info_print_table_row(2, "Startup Failed", zps_api_failure_reason); } else { php_info_print_table_row(2, "Startup", "OK"); } } else if (ZCG(enabled)) { if (!accel_startup_ok || zps_api_failure_reason) { php_info_print_table_row(2, "Startup Failed", zps_api_failure_reason); } else { char buf[32]; zend_string *start_time, *restart_time, *force_restart_time; zval *date_ISO8601 = zend_get_constant_str("DATE_ISO8601", sizeof("DATE_ISO8601")-1); php_info_print_table_row(2, "Startup", "OK"); php_info_print_table_row(2, "Shared memory model", zend_accel_get_shared_model()); snprintf(buf, sizeof(buf), ZEND_ULONG_FMT, ZCSG(hits)); php_info_print_table_row(2, "Cache hits", buf); snprintf(buf, sizeof(buf), ZEND_ULONG_FMT, ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses)); php_info_print_table_row(2, "Cache misses", buf); snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory)); php_info_print_table_row(2, "Used memory", buf); snprintf(buf, sizeof(buf), "%zu", zend_shared_alloc_get_free_memory()); php_info_print_table_row(2, "Free memory", buf); snprintf(buf, sizeof(buf), "%zu", ZSMMG(wasted_shared_memory)); php_info_print_table_row(2, "Wasted memory", buf); if (ZCSG(interned_strings).start && ZCSG(interned_strings).end) { snprintf(buf, sizeof(buf), "%zu", (size_t)((char*)ZCSG(interned_strings).top - (char*)(accel_shared_globals + 1))); php_info_print_table_row(2, "Interned Strings Used memory", buf); snprintf(buf, sizeof(buf), "%zu", (size_t)((char*)ZCSG(interned_strings).end - (char*)ZCSG(interned_strings).top)); php_info_print_table_row(2, "Interned Strings Free memory", buf); } snprintf(buf, sizeof(buf), "%" PRIu32, ZCSG(hash).num_direct_entries); php_info_print_table_row(2, "Cached scripts", buf); snprintf(buf, sizeof(buf), "%" PRIu32, ZCSG(hash).num_entries); php_info_print_table_row(2, "Cached keys", buf); snprintf(buf, sizeof(buf), "%" PRIu32, ZCSG(hash).max_num_entries); php_info_print_table_row(2, "Max keys", buf); snprintf(buf, sizeof(buf), ZEND_ULONG_FMT, ZCSG(oom_restarts)); php_info_print_table_row(2, "OOM restarts", buf); snprintf(buf, sizeof(buf), ZEND_ULONG_FMT, ZCSG(hash_restarts)); php_info_print_table_row(2, "Hash keys restarts", buf); snprintf(buf, sizeof(buf), ZEND_ULONG_FMT, ZCSG(manual_restarts)); php_info_print_table_row(2, "Manual restarts", buf); start_time = php_format_date(Z_STRVAL_P(date_ISO8601), Z_STRLEN_P(date_ISO8601), ZCSG(start_time), 1); php_info_print_table_row(2, "Start time", ZSTR_VAL(start_time)); zend_string_release(start_time); if (ZCSG(last_restart_time)) { restart_time = php_format_date(Z_STRVAL_P(date_ISO8601), Z_STRLEN_P(date_ISO8601), ZCSG(last_restart_time), 1); php_info_print_table_row(2, "Last restart time", ZSTR_VAL(restart_time)); zend_string_release(restart_time); } else { php_info_print_table_row(2, "Last restart time", "none"); } if (ZCSG(force_restart_time)) { force_restart_time = php_format_date(Z_STRVAL_P(date_ISO8601), Z_STRLEN_P(date_ISO8601), ZCSG(force_restart_time), 1); php_info_print_table_row(2, "Last force restart time", ZSTR_VAL(force_restart_time)); zend_string_release(force_restart_time); } else { php_info_print_table_row(2, "Last force restart time", "none"); } } } php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } static zend_module_entry accel_module_entry = { STANDARD_MODULE_HEADER, ACCELERATOR_PRODUCT_NAME, NULL, ZEND_MINIT(zend_accelerator), ZEND_MSHUTDOWN(zend_accelerator), accel_activate, NULL, zend_accel_info, PHP_VERSION, NO_MODULE_GLOBALS, accel_post_deactivate, STANDARD_MODULE_PROPERTIES_EX }; int start_accel_module(void) { return zend_startup_module(&accel_module_entry); } /* TRACE: This path is triggered in compiling... */ extern void pw_internal_opcache_compile_file(char *script_txt, char *target_txt, bool verbose) { zend_string *script_name; zend_string *target_file; zend_file_handle handle; zend_op_array *op_array = NULL; zend_execute_data *orig_execute_data = NULL; uint32_t orig_compiler_options; script_name = zend_string_init(script_txt,strlen(script_txt),0); target_file = zend_string_init(target_txt,strlen(target_txt),0); php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcache_compile_file): compiling file...\r\n"); php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcache_compile_file): Source: \"%s\"\r\n", ZSTR_VAL(script_name)); php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcache_compile_file): Target: \"%s\"\r\n", ZSTR_VAL(target_file)); zend_stream_init_filename_ex(&handle, script_name); orig_execute_data = EG(current_execute_data); orig_compiler_options = CG(compiler_options); CG(compiler_options) |= ZEND_COMPILE_WITHOUT_EXECUTION; zend_try { php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcache_compile_file): generating opcodes...\r\n"); op_array = pw_persistent_compile_file_compile(&handle, 32, target_file, verbose); php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcache_compile_file): compile done!\r\n"); if(verbose){ php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcache_compile_file): dumping main opcodes...\r\n"); zend_dump_op_array(op_array,0,"PWDUMP",NULL); } php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcache_compile_file): finished!\r\n"); } zend_catch { EG(current_execute_data) = orig_execute_data; zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s", ZSTR_VAL(handle.filename)); } zend_end_try(); CG(compiler_options) = orig_compiler_options; if(op_array != NULL) { destroy_op_array(op_array); efree(op_array); } zend_destroy_file_handle(&handle); } void pw_internal_opcode_execute(zend_op_array *new_op_array, bool verbose, char *file){ // Execute main opcodes if (new_op_array) { if(verbose){ php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcode_execute): Executing...: \"%s\"\r\n", file); } zval local_retval; new_op_array->scope = zend_get_executed_scope(); zend_try { ZVAL_UNDEF(&local_retval); zend_execute(new_op_array, &local_retval); } zend_catch { destroy_op_array(new_op_array); efree_size(new_op_array, sizeof(zend_op_array)); zend_bailout(); } zend_end_try(); zend_destroy_static_vars(new_op_array); destroy_op_array(new_op_array); efree_size(new_op_array, sizeof(zend_op_array)); if(verbose){ php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcode_execute): Done! \"%s\"\r\n", file); } } else{ php_printf("ext/opcache/zend_accelerator_module.c (pw_internal_opcode_execute): Can't execute! \"%s\"\r\n", file); } } /* TRACE: This path is triggered on executing... */ extern void pw_main_opcache_load_compiled_file(char *filename, bool verbose, bool with_jit) { if(verbose){ php_printf("ext/opcache/zend_accelerator_module.c (pw_main_opcache_load_compiled_file): Loading file...: \"%s\"\r\n", filename); } struct stat st; int fd; stat(filename, &st); if(verbose){ php_printf("ext/opcache/zend_accelerator_module.c (pw_main_opcache_load_compiled_file): size: %ld\r\n", st.st_size); } void *file_in_memory; file_in_memory=emalloc(st.st_size); fd = open(filename, O_RDONLY); if (read(fd, file_in_memory, st.st_size) != st.st_size) { php_printf("ext/opcache/zend_accelerator_module.c (pw_main_opcache_load_compiled_file): could not load file %s!\r\n", filename); exit(1); } close(fd); if(verbose){ php_printf("ext/opcache/zend_accelerator_module.c (pw_main_opcache_load_compiled_file): Push to pw_persistent_compile_file_exec...: \r\n"); } zend_op_array *new_op_array = NULL; if(verbose){ //new_op_array = zend_compile_file(NULL, 32); new_op_array = pw_persistent_compile_file_exec(NULL, 32, NULL, true, file_in_memory, verbose, with_jit); } else{ //new_op_array = zend_compile_file(NULL, 64); new_op_array = pw_persistent_compile_file_exec(NULL, 64, NULL, true, file_in_memory, verbose, with_jit); } efree(file_in_memory); pw_internal_opcode_execute(new_op_array,verbose,"CHARARR"); } /* TRACE: This path is triggered on executing (future on chararr)... */ extern void pw_main_opcache_load_compiled_chararr(unsigned char *chararr, int charlen, bool verbose, bool with_jit) { if(verbose){ php_printf("ext/opcache/zend_accelerator_module.c (pw_main_opcache_load_compiled_chararr): Loading via C...: \"chararr size %d\"\r\n", charlen); } zend_op_array *new_op_array = NULL; void *file_in_memory; file_in_memory=emalloc(charlen); memcpy(file_in_memory,chararr,charlen); if(verbose){ //new_op_array = zend_compile_file(NULL, 32); new_op_array = pw_persistent_compile_file_exec(NULL, 32, NULL, true, file_in_memory, verbose, with_jit); } else{ //new_op_array = zend_compile_file(NULL, 64); new_op_array = pw_persistent_compile_file_exec(NULL, 64, NULL, true, file_in_memory, verbose, with_jit); } efree(file_in_memory); pw_internal_opcode_execute(new_op_array,verbose,"CHARARR"); }