summaryrefslogtreecommitdiff
path: root/ext/opcache
diff options
context:
space:
mode:
authorLior Kaplan <kaplanlior@gmail.com>2013-10-18 22:57:51 +0300
committerLior Kaplan <kaplanlior@gmail.com>2013-10-19 15:52:26 +0300
commit3f2474550cbf299d8a7df34988ece052a0401414 (patch)
treec31805aa899ff4bd51981781b1d1d79a6540e245 /ext/opcache
parent1fd24dd3e14010b82febd3e300599f8d8f9c592c (diff)
downloadphp-3f2474550cbf299d8a7df34988ece052a0401414.tar.gz
Imported Upstream version 5.5.5+dfsg
Diffstat (limited to 'ext/opcache')
-rw-r--r--ext/opcache/Optimizer/pass1_5.c130
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c131
-rw-r--r--ext/opcache/ZendAccelerator.c16
-rw-r--r--ext/opcache/ZendAccelerator.h12
-rw-r--r--ext/opcache/config.m470
-rw-r--r--ext/opcache/tests/bug65845.phpt14
-rw-r--r--ext/opcache/zend_accelerator_blacklist.c1
-rw-r--r--ext/opcache/zend_accelerator_module.c47
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.c10
9 files changed, 263 insertions, 168 deletions
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index 795b95417..70ec6d5e2 100644
--- a/ext/opcache/Optimizer/pass1_5.c
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -37,7 +37,6 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC) = get_binary_op(opline->opcode);
zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */
zval result;
- zend_op *tmp_opline;
int er;
if (opline->opcode == ZEND_DIV &&
@@ -61,95 +60,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
- /* substitute the following TMP_VAR usage with constant */
- for (tmp_opline = opline + 1; tmp_opline < end; tmp_opline++) {
- if (ZEND_OP1_TYPE(tmp_opline) == IS_TMP_VAR &&
- ZEND_OP1(tmp_opline).var == tv) {
- if (tmp_opline->opcode == ZEND_FREE) {
- MAKE_NOP(tmp_opline);
- zval_dtor(&result);
- } else {
- ZEND_OP1_TYPE(tmp_opline) = IS_CONST;
-#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
- tmp_opline->op1.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC);
- if (Z_TYPE(result) == IS_STRING) {
- Z_HASH_P(&ZEND_OP1_LITERAL(tmp_opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(tmp_opline)), Z_STRLEN(ZEND_OP1_LITERAL(tmp_opline)) + 1);
- if (tmp_opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
- tmp_opline->opcode == ZEND_DO_FCALL ||
- tmp_opline->opcode == ZEND_CATCH ||
- tmp_opline->opcode == ZEND_FETCH_CONSTANT) {
- op_array->literals[tmp_opline->op1.constant].cache_slot = op_array->last_cache_slot++;
- }
- }
-#else
- ZEND_OP1_LITERAL(tmp_opline) = result;
-#endif
- }
- /* TMP_VAR my be used only once */
- break;
- }
- if (ZEND_OP2_TYPE(tmp_opline) == IS_TMP_VAR &&
- ZEND_OP2(tmp_opline).var == tv) {
- ZEND_OP2_TYPE(tmp_opline) = IS_CONST;
-#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
- tmp_opline->op2.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC);
- if (Z_TYPE(result) == IS_STRING) {
- Z_HASH_P(&ZEND_OP2_LITERAL(tmp_opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(tmp_opline)), Z_STRLEN(ZEND_OP2_LITERAL(tmp_opline)) + 1);
- if (tmp_opline->opcode == ZEND_FETCH_R ||
- tmp_opline->opcode == ZEND_FETCH_W ||
- tmp_opline->opcode == ZEND_FETCH_RW ||
- tmp_opline->opcode == ZEND_FETCH_IS ||
- tmp_opline->opcode == ZEND_FETCH_UNSET ||
- tmp_opline->opcode == ZEND_FETCH_FUNC_ARG ||
- tmp_opline->opcode == ZEND_FETCH_CLASS ||
- tmp_opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
- tmp_opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
- tmp_opline->opcode == ZEND_UNSET_VAR ||
- tmp_opline->opcode == ZEND_ISSET_ISEMPTY_VAR ||
- tmp_opline->opcode == ZEND_ADD_INTERFACE ||
- tmp_opline->opcode == ZEND_ADD_TRAIT) {
- op_array->literals[tmp_opline->op2.constant].cache_slot = op_array->last_cache_slot++;
- } else if (tmp_opline->opcode == ZEND_INIT_METHOD_CALL ||
- tmp_opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
- tmp_opline->opcode == ZEND_FETCH_CONSTANT ||
- tmp_opline->opcode == ZEND_ASSIGN_OBJ ||
- tmp_opline->opcode == ZEND_FETCH_OBJ_R ||
- tmp_opline->opcode == ZEND_FETCH_OBJ_W ||
- tmp_opline->opcode == ZEND_FETCH_OBJ_RW ||
- tmp_opline->opcode == ZEND_FETCH_OBJ_IS ||
- tmp_opline->opcode == ZEND_FETCH_OBJ_UNSET ||
- tmp_opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG ||
- tmp_opline->opcode == ZEND_UNSET_OBJ ||
- tmp_opline->opcode == ZEND_PRE_INC_OBJ ||
- tmp_opline->opcode == ZEND_PRE_DEC_OBJ ||
- tmp_opline->opcode == ZEND_POST_INC_OBJ ||
- tmp_opline->opcode == ZEND_POST_DEC_OBJ ||
- tmp_opline->opcode == ZEND_ISSET_ISEMPTY_PROP_OBJ) {
- op_array->literals[tmp_opline->op2.constant].cache_slot = op_array->last_cache_slot;
- op_array->last_cache_slot += 2;
- } else if (tmp_opline->opcode == ZEND_ASSIGN_ADD ||
- tmp_opline->opcode == ZEND_ASSIGN_SUB ||
- tmp_opline->opcode == ZEND_ASSIGN_MUL ||
- tmp_opline->opcode == ZEND_ASSIGN_DIV ||
- tmp_opline->opcode == ZEND_ASSIGN_MOD ||
- tmp_opline->opcode == ZEND_ASSIGN_SL ||
- tmp_opline->opcode == ZEND_ASSIGN_SR ||
- tmp_opline->opcode == ZEND_ASSIGN_CONCAT ||
- tmp_opline->opcode == ZEND_ASSIGN_BW_OR ||
- tmp_opline->opcode == ZEND_ASSIGN_BW_AND ||
- tmp_opline->opcode == ZEND_ASSIGN_BW_XOR) {
- if (tmp_opline->extended_value == ZEND_ASSIGN_OBJ) {
- op_array->literals[tmp_opline->op2.constant].cache_slot = op_array->last_cache_slot;
- op_array->last_cache_slot += 2;
- }
- }
- }
-#else
- ZEND_OP2_LITERAL(tmp_opline) = result;
-#endif
- break;
- }
- }
+ replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
}
break;
@@ -159,6 +70,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
opline->extended_value != IS_OBJECT &&
opline->extended_value != IS_RESOURCE) {
/* cast of constant operand */
+ zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */
zval res;
res = ZEND_OP1_LITERAL(opline);
zval_copy_ctor(&res);
@@ -179,11 +91,11 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
convert_to_string(&res);
break;
}
+
literal_dtor(&ZEND_OP1_LITERAL(opline));
- opline->opcode = ZEND_QM_ASSIGN;
- opline->extended_value = 0;
- ZEND_OP1_LITERAL(opline) = res;
- SET_UNUSED(opline->op2);
+ MAKE_NOP(opline);
+
+ replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
} else if (opline->extended_value == IS_BOOL) {
/* T = CAST(X, IS_BOOL) => T = BOOL(X) */
opline->opcode = ZEND_BOOL;
@@ -197,7 +109,6 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
/* unary operation on constant operand */
unary_op_type unary_op = get_unary_op(opline->opcode);
zval result;
- zend_op *tmp_opline;
zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */
int er;
@@ -218,34 +129,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
literal_dtor(&ZEND_OP1_LITERAL(opline));
MAKE_NOP(opline);
- /* substitute the following TMP_VAR usage with constant */
- for (tmp_opline = opline + 1; tmp_opline < end; tmp_opline++) {
- if (ZEND_OP1_TYPE(tmp_opline) == IS_TMP_VAR &&
- ZEND_OP1(tmp_opline).var == tv) {
- if (tmp_opline->opcode == ZEND_FREE) {
- MAKE_NOP(tmp_opline);
- zval_dtor(&result);
- } else {
- ZEND_OP1_TYPE(tmp_opline) = IS_CONST;
-#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
- tmp_opline->op1.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC);
-#else
- ZEND_OP1_LITERAL(tmp_opline) = result;
-#endif
- }
- break;
- }
- if (ZEND_OP2_TYPE(tmp_opline) == IS_TMP_VAR &&
- ZEND_OP2(tmp_opline).var == tv) {
- ZEND_OP2_TYPE(tmp_opline) = IS_CONST;
-#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
- tmp_opline->op2.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC);
-#else
- ZEND_OP2_LITERAL(tmp_opline) = result;
-#endif
- break;
- }
- }
+ replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
}
break;
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 1f411d5da..28085cb44 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -110,6 +110,137 @@ int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC
#endif
+static void replace_tmp_by_const(zend_op_array *op_array,
+ zend_op *opline,
+ zend_uint var,
+ zval *val
+ TSRMLS_DC)
+{
+ zend_op *end = op_array->opcodes + op_array->last;
+
+ while (opline < end) {
+ if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_OP1(opline).var == var) {
+
+ if (opline->opcode == ZEND_FREE) {
+ MAKE_NOP(opline);
+ zval_dtor(val);
+ } else {
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (Z_TYPE_P(val) == IS_STRING) {
+ switch (opline->opcode) {
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ case ZEND_CATCH:
+ case ZEND_FETCH_CONSTANT:
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
+ op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1);
+ break;
+ case ZEND_DO_FCALL:
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
+ op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
+ break;
+ default:
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
+ break;
+ }
+ } else {
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ }
+#else
+ ZEND_OP1_LITERAL(opline) = *val;
+#endif
+ }
+ /* TMP_VAR my be used only once */
+ break;
+ }
+
+ if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_OP2(opline).var == var) {
+
+ ZEND_OP2_TYPE(opline) = IS_CONST;
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ opline->op2.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ if (Z_TYPE_P(val) == IS_STRING) {
+ Z_HASH_P(&ZEND_OP2_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1);
+ switch (opline->opcode) {
+ case ZEND_FETCH_R:
+ case ZEND_FETCH_W:
+ case ZEND_FETCH_RW:
+ case ZEND_FETCH_IS:
+ case ZEND_FETCH_UNSET:
+ case ZEND_FETCH_FUNC_ARG:
+ case ZEND_FETCH_CLASS:
+ case ZEND_INIT_FCALL_BY_NAME:
+ /*case ZEND_INIT_NS_FCALL_BY_NAME:*/
+ case ZEND_UNSET_VAR:
+ case ZEND_ISSET_ISEMPTY_VAR:
+ case ZEND_ADD_INTERFACE:
+ case ZEND_ADD_TRAIT:
+ op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++;
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
+ break;
+ case ZEND_INIT_METHOD_CALL:
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
+ /* break missing intentionally */
+ /*case ZEND_FETCH_CONSTANT:*/
+ case ZEND_ASSIGN_OBJ:
+ case ZEND_FETCH_OBJ_R:
+ case ZEND_FETCH_OBJ_W:
+ case ZEND_FETCH_OBJ_RW:
+ case ZEND_FETCH_OBJ_IS:
+ case ZEND_FETCH_OBJ_UNSET:
+ case ZEND_FETCH_OBJ_FUNC_ARG:
+ case ZEND_UNSET_OBJ:
+ case ZEND_PRE_INC_OBJ:
+ case ZEND_PRE_DEC_OBJ:
+ case ZEND_POST_INC_OBJ:
+ case ZEND_POST_DEC_OBJ:
+ case ZEND_ISSET_ISEMPTY_PROP_OBJ:
+ op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
+ op_array->last_cache_slot += 2;
+ break;
+ case ZEND_ASSIGN_ADD:
+ case ZEND_ASSIGN_SUB:
+ case ZEND_ASSIGN_MUL:
+ case ZEND_ASSIGN_DIV:
+ case ZEND_ASSIGN_MOD:
+ case ZEND_ASSIGN_SL:
+ case ZEND_ASSIGN_SR:
+ case ZEND_ASSIGN_CONCAT:
+ case ZEND_ASSIGN_BW_OR:
+ case ZEND_ASSIGN_BW_AND:
+ case ZEND_ASSIGN_BW_XOR:
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
+ op_array->last_cache_slot += 2;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+#else
+ ZEND_OP2_LITERAL(opline) = *val;
+#endif
+ break;
+ }
+ opline++;
+ }
+}
+
#include "Optimizer/nop_removal.c"
#include "Optimizer/block_pass.c"
#include "Optimizer/optimize_temp_vars_5.c"
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 827f047cd..72b5a1b9f 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -1446,7 +1446,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han
}
/* zend_compile() replacement */
-static zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
+zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
{
zend_persistent_script *persistent_script = NULL;
char *key = NULL;
@@ -2407,14 +2407,14 @@ static inline int accel_find_sapi(TSRMLS_D)
return FAILURE;
}
-static void zend_accel_init_shm(TSRMLS_D)
+static int zend_accel_init_shm(TSRMLS_D)
{
zend_shared_alloc_lock(TSRMLS_C);
accel_shared_globals = zend_shared_alloc(sizeof(zend_accel_shared_globals));
if (!accel_shared_globals) {
zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
- return;
+ return FAILURE;
}
ZSMMG(app_shared_globals) = accel_shared_globals;
@@ -2429,7 +2429,8 @@ static void zend_accel_init_shm(TSRMLS_D)
ZCSG(interned_strings).arBuckets = zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
ZCSG(interned_strings_start) = zend_shared_alloc((ZCG(accel_directives).interned_strings_buffer * 1024 * 1024));
if (!ZCSG(interned_strings).arBuckets || !ZCSG(interned_strings_start)) {
- zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings");
+ zend_accel_error(ACCEL_LOG_FATAL, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings");
+ return FAILURE;
}
ZCSG(interned_strings_end) = ZCSG(interned_strings_start) + (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024);
ZCSG(interned_strings_top) = ZCSG(interned_strings_start);
@@ -2468,6 +2469,8 @@ static void zend_accel_init_shm(TSRMLS_D)
ZCSG(restart_in_progress) = 0;
zend_shared_alloc_unlock(TSRMLS_C);
+
+ return SUCCESS;
}
static void accel_globals_ctor(zend_accel_globals *accel_globals TSRMLS_DC)
@@ -2525,7 +2528,10 @@ static int accel_startup(zend_extension *extension)
/********************************************/
switch (zend_shared_alloc_startup(ZCG(accel_directives).memory_consumption)) {
case ALLOC_SUCCESS:
- zend_accel_init_shm(TSRMLS_C);
+ if (zend_accel_init_shm(TSRMLS_C) == FAILURE) {
+ accel_startup_ok = 0;
+ return FAILURE;
+ }
break;
case ALLOC_FAILURE:
accel_startup_ok = 0;
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index 361b60b08..b9d7ef347 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -80,6 +80,9 @@
# endif
# include <direct.h>
#else
+# ifndef MAXPATHLEN
+# define MAXPATHLEN 4096
+# endif
# include <sys/param.h>
#endif
@@ -100,7 +103,7 @@ extern int lock_file;
# elif defined(__svr4__)
# define FLOCK_STRUCTURE(name, type, whence, start, len) \
struct flock name = {type, whence, start, len}
-# elif defined(__linux__) || defined(__hpux)
+# elif defined(__linux__) || defined(__hpux) || defined(__GNU__)
# define FLOCK_STRUCTURE(name, type, whence, start, len) \
struct flock name = {type, whence, start, len, 0}
# elif defined(_AIX)
@@ -111,6 +114,12 @@ extern int lock_file;
# define FLOCK_STRUCTURE(name, type, whence, start, len) \
struct flock name = {type, whence, start, len}
# endif
+# elif defined(HAVE_FLOCK_BSD)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {start, len, -1, type, whence}
+# elif defined(HAVE_FLOCK_LINUX)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {type, whence, start, len}
# else
# error "Don't know how to define struct flock"
# endif
@@ -325,6 +334,7 @@ int accelerator_shm_read_lock(TSRMLS_D);
void accelerator_shm_read_unlock(TSRMLS_D);
char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC);
+zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
#if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED)
# define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145
diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4
index 1798fe13f..60edeed96 100644
--- a/ext/opcache/config.m4
+++ b/ext/opcache/config.m4
@@ -326,40 +326,42 @@ int main() {
msg=yes,msg=no,msg=no)
AC_MSG_RESULT([$msg])
- AC_MSG_CHECKING(for known struct flock definition)
- dnl Copied from ZendAccelerator.h
- AC_TRY_RUN([
-#include <fcntl.h>
-#include <stdlib.h>
-
-#ifndef ZEND_WIN32
-extern int lock_file;
-
-# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || (defined(__APPLE__) && defined(__MACH__)/* Darwin */) || defined(__OpenBSD__) || defined(__NetBSD__)
-# define FLOCK_STRUCTURE(name, type, whence, start, len) \
- struct flock name = {start, len, -1, type, whence}
-# elif defined(__svr4__)
-# define FLOCK_STRUCTURE(name, type, whence, start, len) \
- struct flock name = {type, whence, start, len}
-# elif defined(__linux__) || defined(__hpux)
-# define FLOCK_STRUCTURE(name, type, whence, start, len) \
- struct flock name = {type, whence, start, len, 0}
-# elif defined(_AIX)
-# if defined(_LARGE_FILES) || defined(__64BIT__)
-# define FLOCK_STRUCTURE(name, type, whence, start, len) \
- struct flock name = {type, whence, 0, 0, 0, start, len }
-# else
-# define FLOCK_STRUCTURE(name, type, whence, start, len) \
- struct flock name = {type, whence, start, len}
-# endif
-# else
-# error "Don't know how to define struct flock"
-# endif
-#endif
-int main() { return 0; }
-],
-[AC_MSG_RESULT([done])],
-[AC_MSG_ERROR([Don't know how to define struct flock on this system[,] set --enable-opcache=no])], [])
+flock_type=unknown
+AC_MSG_CHECKING("whether flock struct is linux ordered")
+AC_TRY_RUN([
+ #include <fcntl.h>
+ struct flock lock = { 1, 2, 3, 4, 5 };
+ int main() {
+ if(lock.l_type == 1 && lock.l_whence == 2 && lock.l_start == 3 && lock.l_len == 4) {
+ return 0;
+ }
+ return 1;
+ }
+], [
+ flock_type=linux
+ AC_DEFINE([HAVE_FLOCK_LINUX], [], [Struct flock is Linux-type])
+ AC_MSG_RESULT("yes")
+], AC_MSG_RESULT("no") )
+
+AC_MSG_CHECKING("whether flock struct is BSD ordered")
+AC_TRY_RUN([
+ #include <fcntl.h>
+ struct flock lock = { 1, 2, 3, 4, 5 };
+ int main() {
+ if(lock.l_start == 1 && lock.l_len == 2 && lock.l_type == 4 && lock.l_whence == 5) {
+ return 0;
+ }
+ return 1;
+ }
+], [
+ flock_type=bsd
+ AC_DEFINE([HAVE_FLOCK_BSD], [], [Struct flock is BSD-type])
+ AC_MSG_RESULT("yes")
+], AC_MSG_RESULT("no") )
+
+if test "$flock_type" == "unknown"; then
+ AC_MSG_ERROR([Don't know how to define struct flock on this system[,] set --enable-opcache=no])
+fi
PHP_NEW_EXTENSION(opcache,
ZendAccelerator.c \
diff --git a/ext/opcache/tests/bug65845.phpt b/ext/opcache/tests/bug65845.phpt
new file mode 100644
index 000000000..2ae5f3974
--- /dev/null
+++ b/ext/opcache/tests/bug65845.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #65845 (Error when Zend Opcache Optimizer is fully enabled)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$Pile['vars'][(string)'toto'] = 'tutu';
+var_dump($Pile['vars']['toto']);
+?>
+--EXPECT--
+string(4) "tutu"
diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c
index da83cfd31..eb0bc2146 100644
--- a/ext/opcache/zend_accelerator_blacklist.c
+++ b/ext/opcache/zend_accelerator_blacklist.c
@@ -314,6 +314,7 @@ void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
blacklist->entries[blacklist->pos].path = (char *)malloc(path_length + 1);
if (!blacklist->entries[blacklist->pos].path) {
zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
+ fclose(fp);
return;
}
blacklist->entries[blacklist->pos].id = blacklist->pos;
diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c
index f9ddaa98b..dedb7215c 100644
--- a/ext/opcache/zend_accelerator_module.c
+++ b/ext/opcache/zend_accelerator_module.c
@@ -48,6 +48,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_get_status, 0, 0, 0)
ZEND_ARG_INFO(0, fetch_scripts)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_compile_file, 0, 0, 1)
+ ZEND_ARG_INFO(0, file)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_invalidate, 0, 0, 1)
ZEND_ARG_INFO(0, script)
ZEND_ARG_INFO(0, force)
@@ -59,12 +63,14 @@ static ZEND_FUNCTION(opcache_invalidate);
/* Private functions */
static ZEND_FUNCTION(opcache_get_status);
+static ZEND_FUNCTION(opcache_compile_file);
static ZEND_FUNCTION(opcache_get_configuration);
static zend_function_entry accel_functions[] = {
/* User functions */
ZEND_FE(opcache_reset, arginfo_opcache_none)
ZEND_FE(opcache_invalidate, arginfo_opcache_invalidate)
+ ZEND_FE(opcache_compile_file, arginfo_opcache_compile_file)
/* Private functions */
ZEND_FE(opcache_get_configuration, arginfo_opcache_none)
ZEND_FE(opcache_get_status, arginfo_opcache_get_status)
@@ -709,3 +715,44 @@ static ZEND_FUNCTION(opcache_invalidate)
RETURN_FALSE;
}
}
+
+static ZEND_FUNCTION(opcache_compile_file)
+{
+ char *script_name;
+ int script_name_len;
+ zend_file_handle handle;
+ zend_op_array *op_array = NULL;
+ zend_execute_data *orig_execute_data = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &script_name, &script_name_len) == FAILURE) {
+ return;
+ }
+
+ if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled)) {
+ zend_error(E_NOTICE, ACCELERATOR_PRODUCT_NAME " seems to be disabled, can't compile file");
+ RETURN_FALSE;
+ }
+
+ handle.filename = script_name;
+ handle.free_filename = 0;
+ handle.opened_path = NULL;
+ handle.type = ZEND_HANDLE_FILENAME;
+
+ orig_execute_data = EG(current_execute_data);
+
+ zend_try {
+ op_array = persistent_compile_file(&handle, ZEND_INCLUDE TSRMLS_CC);
+ } zend_catch {
+ EG(current_execute_data) = orig_execute_data;
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s" TSRMLS_CC, handle.filename);
+ } zend_end_try();
+
+ if(op_array != NULL) {
+ destroy_op_array(op_array TSRMLS_CC);
+ efree(op_array);
+ RETVAL_TRUE;
+ } else {
+ RETVAL_FALSE;
+ }
+ zend_destroy_file_handle(&handle TSRMLS_CC);
+}
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c
index 39b4c1fc2..894da63aa 100644
--- a/ext/opcache/zend_accelerator_util_funcs.c
+++ b/ext/opcache/zend_accelerator_util_funcs.c
@@ -478,7 +478,7 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
if (accel_xlat_get(new_entry->scope, new_ce) == SUCCESS) {
new_entry->scope = *new_ce;
} else {
- zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s. Please call Zend Support", ce->name, new_entry->function_name);
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name);
}
}
@@ -487,7 +487,7 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
if (accel_xlat_get(new_entry->prototype, new_prototype) == SUCCESS) {
new_entry->prototype = *new_prototype;
} else {
- zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s. Please call Zend Support", ce->name, new_entry->function_name);
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name);
}
}
@@ -589,7 +589,7 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
} else if (accel_xlat_get(prop_info->ce, new_ce) == SUCCESS) {
prop_info->ce = *new_ce;
} else {
- zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s. Please call Zend Support", ce->name, prop_info->name);
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name, prop_info->name);
}
p = p->pListNext;
@@ -621,7 +621,7 @@ static int zend_prepare_function_for_execution(zend_op_array *op_array)
if (accel_xlat_get(ce->handler, new_func) == SUCCESS) { \
ce->handler = *new_func; \
} else { \
- zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s. Please call Zend Support", ce->name); \
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name); \
} \
} \
}
@@ -710,7 +710,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
if (accel_xlat_get(ce->parent, new_ce) == SUCCESS) {
ce->parent = *new_ce;
} else {
- zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s. Please call Zend Support", ce->name);
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name);
}
}