|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patch auto_filter_on_missing_lambdas.patch for APC Bug #52144Patch version 2012-11-02 12:18 UTC Return to Bug #52144 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:Developer: gopalv@php.net
Index: apc_compile.c
===================================================================
--- apc_compile.c (revision 328140)
+++ apc_compile.c (working copy)
@@ -1323,6 +1323,11 @@
}
}
break;
+#ifdef ZEND_ENGINE_2_4
+ case ZEND_DECLARE_LAMBDA_FUNCTION:
+ flags->lambdas = 1;
+ break;
+#endif
default:
#ifdef ZEND_ENGINE_2_4
if((zo->op1_type == IS_CONST &&
@@ -1485,7 +1490,6 @@
NULL);
zend_hash_get_current_data(CG(function_table), (void**) &fun);
-
CHECK(array[i].name = apc_pmemcpy(key, (int) key_size, pool TSRMLS_CC));
array[i].name_len = (int) key_size-1;
CHECK(array[i].function = my_copy_function(NULL, fun, ctxt TSRMLS_CC));
@@ -1597,6 +1601,11 @@
}
#endif
+#ifdef ZEND_ENGINE_2_4
+# define APC_CHECK_MISSING_LAMBDA(op1, tmp) \
+ (zend_hash_find(CG(function_table), Z_STRVAL_P(op1.zv), Z_STRLEN_P(op1.zv), (void *) &tmp) == FAILURE)
+#endif
+
/* {{{ my_prepare_op_array_for_execution */
static int my_prepare_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC)
{
@@ -1613,6 +1622,7 @@
int needcopy = flags ? flags->deep_copy : 1;
/* auto_globals_jit was not in php4 */
int do_prepare_fetch_global = PG(auto_globals_jit) && (flags == NULL || flags->unknown_global);
+ int has_lambdas = flags->lambdas;
#define FETCH_AUTOGLOBAL(member) do { \
if(flags && flags->member == 1) { \
@@ -1724,6 +1734,16 @@
APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
}
break;
+#ifdef ZEND_ENGINE_2_4
+ case ZEND_DECLARE_LAMBDA_FUNCTION:
+ if(has_lambdas) {
+ zend_op_array *tmp = NULL;
+ if(APC_CHECK_MISSING_LAMBDA(zo->op1, tmp)) {
+ return 0;
+ }
+ }
+ break;
+#endif
default:
break;
}
@@ -1732,18 +1752,27 @@
dzo++;
}
} else { /* !needcopy */
- /* The fetch is only required if auto_globals_jit=1 */
- if(do_prepare_fetch_global)
+ if(do_prepare_fetch_global || has_lambdas)
{
zo = src->opcodes;
while(i > 0) {
- if(zo->opcode == ZEND_FETCH_R ||
+ /* The fetch is only required if auto_globals_jit=1 */
+ if(do_prepare_fetch_global
+ && (zo->opcode == ZEND_FETCH_R ||
zo->opcode == ZEND_FETCH_W ||
zo->opcode == ZEND_FETCH_IS ||
zo->opcode == ZEND_FETCH_FUNC_ARG
- ) {
+ )) {
APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
+ #ifdef ZEND_ENGINE_2_4
+ } else if(has_lambdas
+ && zo->opcode == ZEND_DECLARE_LAMBDA_FUNCTION) {
+ void *tmp;
+ if(APC_CHECK_MISSING_LAMBDA(zo->op1, tmp)) {
+ return 0;
+ }
+ #endif
}
i--;
@@ -1768,7 +1797,9 @@
sizeof(src->refcount[0]),
ctxt->pool TSRMLS_CC);
- my_prepare_op_array_for_execution(dst,src, ctxt TSRMLS_CC);
+ if(!my_prepare_op_array_for_execution(dst,src, ctxt TSRMLS_CC)) {
+ return NULL;
+ }
return dst;
}
@@ -1790,8 +1821,10 @@
dst = (zend_function*) emalloc(sizeof(src[0]));
memcpy(dst, src, sizeof(src[0]));
- apc_copy_op_array_for_execution(&(dst->op_array), &(src->op_array), ctxt TSRMLS_CC);
- return dst;
+ if(apc_copy_op_array_for_execution(&(dst->op_array), &(src->op_array), ctxt TSRMLS_CC)) {
+ return dst;
+ }
+ return NULL;
}
/* }}} */
Index: apc_compile.h
===================================================================
--- apc_compile.h (revision 328139)
+++ apc_compile.h (working copy)
@@ -67,6 +67,7 @@
struct apc_opflags_t {
unsigned int has_jumps : 1; /* has jump offsets */
unsigned int deep_copy : 1; /* needs deep copy */
+ unsigned int lambdas : 1; /* declares lambdas */
/* autoglobal bits */
unsigned int _POST : 1;
Index: apc_main.c
===================================================================
--- apc_main.c (revision 328143)
+++ apc_main.c (working copy)
@@ -74,6 +74,11 @@
int status;
zend_function *func = apc_copy_function_for_execution(fn.function, ctxt TSRMLS_CC);
+ if(func == NULL) {
+ return (FAILURE-1); // massive failure
+ }
+
+
status = zend_hash_add(EG(function_table), fn.name, fn.name_len+1, func, sizeof(zend_function), NULL);
efree(func);
@@ -85,6 +90,21 @@
}
/* }}} */
+/* {{{ uninstall_function */
+static int uninstall_function(apc_function_t fn TSRMLS_DC)
+{
+ int status;
+
+ status = zend_hash_del(EG(function_table),
+ fn.name,
+ fn.name_len+1);
+ if (status == FAILURE) {
+ apc_error("Cannot delete function %s" TSRMLS_CC, fn.name);
+ }
+ return status;
+}
+/* }}} */
+
/* {{{ apc_lookup_function_hook */
int apc_lookup_function_hook(char *name, int len, ulong hash, zend_function **fe) {
apc_function_t *fn;
@@ -315,8 +335,10 @@
int type,
apc_context_t* ctxt TSRMLS_DC)
{
+ zend_op_array *op_array;
apc_cache_entry_t* cache_entry;
- int i, ii;
+ int i=0, ii;
+ int j=0, jj;
cache_entry = (apc_cache_entry_t*) apc_stack_top(APCG(cache_stack));
assert(cache_entry != NULL);
@@ -332,19 +354,29 @@
if (cache_entry->data.file.functions) {
int lazy_functions = APCG(lazy_functions);
- for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
- install_function(cache_entry->data.file.functions[i], ctxt, lazy_functions TSRMLS_CC);
+ for (j = 0; cache_entry->data.file.functions[j].function != NULL; j++) {
+ if(install_function(cache_entry->data.file.functions[j], ctxt, lazy_functions TSRMLS_CC) < FAILURE) {
+ goto default_compile;
+ }
}
}
- apc_do_halt_compiler_register(cache_entry->data.file.filename, cache_entry->data.file.halt_offset TSRMLS_CC);
+ op_array = apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array, ctxt TSRMLS_CC);
+ if(op_array) {
+ apc_do_halt_compiler_register(cache_entry->data.file.filename, cache_entry->data.file.halt_offset TSRMLS_CC);
+ return op_array;
+ }
+ /* fall through to default_compile */
- return apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array, ctxt TSRMLS_CC);
-
default_compile:
- /* XXX more cleanup in uninstall class, and uninstall_function() should be here too */
+ if(cache_entry->data.file.functions) {
+ for(jj = 0; jj < j ; jj++) {
+ uninstall_function(cache_entry->data.file.functions[jj] TSRMLS_CC);
+ }
+ }
+ /* XXX more cleanup in uninstall class */
if(cache_entry->data.file.classes) {
for(ii = 0; ii < i ; ii++) {
uninstall_class(cache_entry->data.file.classes[ii] TSRMLS_CC);
@@ -421,7 +453,6 @@
if(!(alloc_op_array = apc_copy_op_array(NULL, *op_array, &ctxt TSRMLS_CC))) {
goto freepool;
}
-
if(!(alloc_functions = apc_copy_new_functions(num_functions, &ctxt TSRMLS_CC))) {
goto freepool;
}
@@ -438,7 +469,7 @@
if(!(*cache_entry = apc_cache_make_file_entry(path, alloc_op_array, alloc_functions, alloc_classes, &ctxt TSRMLS_CC))) {
goto freepool;
}
-
+
return SUCCESS;
freepool:
@@ -520,6 +551,7 @@
(void *)&dummy, sizeof(int), NULL);
apc_stack_push(APCG(cache_stack), cache_entry TSRMLS_CC);
+ int num_functions = zend_hash_num_elements(CG(function_table));
op_array = cached_compile(h, type, &ctxt TSRMLS_CC);
if(op_array) {
@@ -544,6 +576,7 @@
apc_warning("Autofiltering %s" TSRMLS_CC,
(h->opened_path ? h->opened_path : h->filename));
apc_warning("Recompiling %s" TSRMLS_CC, cache_entry->data.file.filename);
+ ctxt.force_update = 1;
}
/* TODO: check what happens with EG(included_files) */
}
|
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 22 04:00:01 2025 UTC |