diff --git a/processor/processor.m4 b/processor/processor.m4 index d8bf6d1..16134f5 100644 --- a/processor/processor.m4 +++ b/processor/processor.m4 @@ -707,6 +707,18 @@ DEF_STRUCT_P_FUNC(`xc_classinfo_t', , `dnl {{{ DISPATCH(int, oplineno) ') dnl }}} +#ifdef ZEND_ENGINE_2_1 +DEF_STRUCT_P_FUNC(`xc_autoglobal_t', , `dnl {{{ + DISPATCH(zend_uint, key_len) +#ifdef IS_UNICODE + DISPATCH(zend_uchar, type) +#endif + IFRESTORE(`COPY(key)', ` + PROC_ZSTRING_L(type, key, key_len) + ') +') +dnl }}} +#endif DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{ zend_uint i; @@ -735,6 +747,10 @@ DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{ ') ') STRUCT_ARRAY(classinfo_cnt, xc_classinfo_t, classinfos) +#ifdef ZEND_ENGINE_2_1 + DISPATCH(zend_uint, autoglobal_cnt) + STRUCT_ARRAY(autoglobal_cnt, xc_autoglobal_t, autoglobals) +#endif DISPATCH(zend_bool, have_early_binding) popdef(`BEFORE_LOOP') ') diff --git a/utils.c b/utils.c index 7822ff7..57e729c 100644 --- a/utils.c +++ b/utils.c @@ -510,6 +510,29 @@ ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, int op #define TG(x) (sandbox->tmp_##x) #define OG(x) (sandbox->orig_##x) /* }}} */ +#ifdef ZEND_ENGINE_2_1 +static zend_bool xc_auto_global_callback(char *name, uint name_len TSRMLS_DC) /* {{{ */ +{ + zend_auto_global *auto_global; + if (zend_u_hash_find(CG(auto_globals), UG(unicode) ? IS_UNICODE : IS_STRING, ZSTR(name), name_len + 1, (void **) &auto_global) == FAILURE) { + return 1; + } + return 0; +} +/* }}} */ +static int xc_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */ +{ + if (auto_global->auto_global_callback) { + auto_global->armed = 1; + auto_global->auto_global_callback = xc_auto_global_callback; + } + else { + auto_global->armed = 0; + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ +#endif xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) /* {{{ */ { if (sandbox) { @@ -534,6 +557,11 @@ xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) / CG(class_table) = &TG(class_table); EG(class_table) = CG(class_table); +#ifdef ZEND_ENGINE_2_1 + OG(auto_globals) = CG(auto_globals); + CG(auto_globals) = &TG(auto_globals); +#endif + TG(included_files) = &EG(included_files); zend_hash_init_ex(TG(included_files), 5, NULL, NULL, 0, 1); @@ -542,6 +570,15 @@ xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) / #endif zend_hash_init_ex(&TG(function_table), 128, NULL, OG(function_table)->pDestructor, 0, 0); zend_hash_init_ex(&TG(class_table), 16, NULL, OG(class_table)->pDestructor, 0, 0); +#ifdef ZEND_ENGINE_2_1 + zend_hash_init_ex(&TG(auto_globals), 8, NULL, OG(auto_globals)->pDestructor, 0, 0); + { + zend_auto_global tmp_autoglobal; + + zend_hash_copy(&TG(auto_globals), OG(auto_globals), NULL, (void *) &tmp_autoglobal, sizeof(tmp_autoglobal)); + zend_hash_apply(&TG(auto_globals), (apply_func_t) xc_auto_global_arm TSRMLS_CC); + } +#endif sandbox->filename = filename; @@ -591,6 +628,18 @@ static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */ BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength TSRMLS_CC); b = b->pListNext; } + +#ifdef ZEND_ENGINE_2_1 + /* trigger auto_globals jit */ + for (b = TG(auto_globals).pListHead; b != NULL; b = b->pListNext) { + zend_auto_global *auto_global = (zend_auto_global *) b->pData; + /* check if actived */ + if (auto_global->auto_global_callback && !auto_global->armed) { + zend_u_is_auto_global(BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), auto_global->name_len TSRMLS_CC); + } + } +#endif + xc_undo_pass_two(CG(active_op_array) TSRMLS_CC); xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC); xc_redo_pass_two(CG(active_op_array) TSRMLS_CC); @@ -608,6 +657,9 @@ void xc_sandbox_free(xc_sandbox_t *sandbox, int install TSRMLS_DC) /* {{{ */ CG(function_table) = OG(function_table); CG(class_table) = OG(class_table); EG(class_table) = CG(class_table); +#ifdef ZEND_ENGINE_2_1 + CG(auto_globals) = OG(auto_globals); +#endif if (install) { CG(in_compilation) = 1; @@ -623,6 +675,9 @@ void xc_sandbox_free(xc_sandbox_t *sandbox, int install TSRMLS_DC) /* {{{ */ #endif TG(function_table).pDestructor = NULL; TG(class_table).pDestructor = NULL; +#ifdef ZEND_ENGINE_2_1 + TG(auto_globals).pDestructor = NULL; +#endif } /* destroy all the tmp */ @@ -631,6 +686,9 @@ void xc_sandbox_free(xc_sandbox_t *sandbox, int install TSRMLS_DC) /* {{{ */ #endif zend_hash_destroy(&TG(function_table)); zend_hash_destroy(&TG(class_table)); +#ifdef ZEND_ENGINE_2_1 + zend_hash_destroy(&TG(auto_globals)); +#endif zend_hash_destroy(TG(included_files)); /* restore orig here, as EG/CG holded tmp before */ diff --git a/utils.h b/utils.h index 04d6379..88b013b 100644 --- a/utils.h +++ b/utils.h @@ -48,8 +48,10 @@ typedef struct { #endif HashTable *orig_function_table; HashTable *orig_class_table; + HashTable *orig_auto_globals; HashTable tmp_function_table; HashTable tmp_class_table; + HashTable tmp_auto_globals; } xc_sandbox_t; xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC); diff --git a/xcache-zh-gb2312.ini b/xcache-zh-gb2312.ini index b3a6307..6c5d84b 100644 --- a/xcache-zh-gb2312.ini +++ b/xcache-zh-gb2312.ini @@ -9,9 +9,6 @@ zend_extension_ts = c:/php/extensions/php_xcache.dll ;; 或者 Win32 系统: ; extension = php_xcache.dll -; 如果您在 php5.1 或者以上版本启用 XCache, 则必须使用以下设置 -auto_globals_jit = Off - [xcache.admin] xcache.admin.user = "mOo" ; xcache.admin.pass = md5($您的密码) diff --git a/xcache.c b/xcache.c index 1b1090d..edd2b3e 100644 --- a/xcache.c +++ b/xcache.c @@ -499,6 +499,9 @@ static void xc_fillentry_dmz(xc_entry_t *entry, int del, zval *list TSRMLS_DC) / #endif add_assoc_long_ex(ei, ZEND_STRS("function_cnt"), php->funcinfo_cnt); add_assoc_long_ex(ei, ZEND_STRS("class_cnt"), php->classinfo_cnt); +#ifdef ZEND_ENGINE_2_1 + add_assoc_long_ex(ei, ZEND_STRS("autoglobal_cnt"),php->autoglobal_cnt); +#endif break; case XC_TYPE_VAR: var = entry->data.var; @@ -580,6 +583,22 @@ static zend_op_array *xc_entry_install(xc_entry_t *xce, zend_file_handle *h TSRM UNISW(0, ci->type), ci->key, ci->key_size TSRMLS_CC); } +#ifdef ZEND_ENGINE_2_1 + /* trigger auto_globals jit */ + for (i = 0; i < p->autoglobal_cnt; i ++) { + xc_autoglobal_t *aginfo = &p->autoglobals[i]; + /* + zend_auto_global *auto_global; + if (zend_u_hash_find(CG(auto_globals), aginfo->type, aginfo->key, aginfo->key_len+1, (void **) &auto_global)==SUCCESS) { + if (auto_global->armed) { + auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC); + } + } + */ + zend_u_is_auto_global(aginfo->type, aginfo->key, aginfo->key_len TSRMLS_CC); + } +#endif + i = 1; zend_hash_add(&EG(included_files), xce->name.str.val, xce->name.str.len+1, (void *)&i, sizeof(int), NULL); if (h) { @@ -948,10 +967,25 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) / php.op_array = op_array; #ifdef HAVE_XCACHE_CONSTANT - php.constinfo_cnt = zend_hash_num_elements(EG(zend_constants)) - old_constinfo_cnt; + php.constinfo_cnt = zend_hash_num_elements(EG(zend_constants)) - old_constinfo_cnt; +#endif + php.funcinfo_cnt = zend_hash_num_elements(CG(function_table)) - old_funcinfo_cnt; + php.classinfo_cnt = zend_hash_num_elements(CG(class_table)) - old_classinfo_cnt; +#ifdef ZEND_ENGINE_2_1 + /* {{{ count php.autoglobal_cnt */ { + Bucket *b; + + php.autoglobal_cnt = 0; + for (b = CG(auto_globals)->pListHead; b != NULL; b = b->pListNext) { + zend_auto_global *auto_global = (zend_auto_global *) b->pData; + /* check if actived */ + if (auto_global->auto_global_callback && !auto_global->armed) { + php.autoglobal_cnt ++; + } + } + } + /* }}} */ #endif - php.funcinfo_cnt = zend_hash_num_elements(CG(function_table)) - old_funcinfo_cnt; - php.classinfo_cnt = zend_hash_num_elements(CG(class_table)) - old_classinfo_cnt; #define X_ALLOC_N(var, cnt) do { \ if (php.cnt) { \ @@ -966,10 +1000,13 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) / } while (0) #ifdef HAVE_XCACHE_CONSTANT - X_ALLOC_N(constinfos, constinfo_cnt); + X_ALLOC_N(constinfos, constinfo_cnt); +#endif + X_ALLOC_N(funcinfos, funcinfo_cnt); + X_ALLOC_N(classinfos, classinfo_cnt); +#ifdef ZEND_ENGINE_2_1 + X_ALLOC_N(autoglobals, autoglobal_cnt); #endif - X_ALLOC_N(funcinfos, funcinfo_cnt); - X_ALLOC_N(classinfos, classinfo_cnt); #undef X_ALLOC /* }}} */ /* {{{ shallow copy, pointers only */ { @@ -1005,7 +1042,30 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) / b = CG(class_table)->pListHead; COPY_H(xc_classinfo_t, classinfos, classinfo_cnt, cest, xc_cest_t); #undef COPY_H - /* for ZE1, cest need to fix inside store */ + + /* for ZE1, cest need to be fixed inside store */ + +#ifdef ZEND_ENGINE_2_1 + /* scan for acatived auto globals */ + i = 0; + for (b = CG(auto_globals)->pListHead; b != NULL; b = b->pListNext) { + zend_auto_global *auto_global = (zend_auto_global *) b->pData; + /* check if actived */ + if (auto_global->auto_global_callback && !auto_global->armed) { + xc_autoglobal_t *data = &php.autoglobals[i ++]; + + assert(i < php.autoglobal_cnt); + UNISW(NOTHING, data->type = b->key.type;) + if (UNISW(1, b->key.type == IS_STRING)) { + ZSTR_S(data->key) = BUCKET_KEY_S(b); + } + else { + ZSTR_U(data->key) = BUCKET_KEY_U(b); + } + data->key_len = b->nKeyLength - 1; + } + } +#endif } /* }}} */ /* {{{ find inherited classes that should be early-binding */ @@ -1035,6 +1095,9 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) / } \ err_##var: +#ifdef ZEND_ENGINE_2_1 + X_FREE(autoglobals) +#endif X_FREE(classinfos) X_FREE(funcinfos) #ifdef HAVE_XCACHE_CONSTANT @@ -1099,6 +1162,9 @@ restore: if (xce.data.php->var) { \ efree(xce.data.php->var); \ } +#ifdef ZEND_ENGINE_2_1 + X_FREE(autoglobals) +#endif X_FREE(classinfos) X_FREE(funcinfos) #ifdef HAVE_XCACHE_CONSTANT diff --git a/xcache.h b/xcache.h index 0df49e9..6a56a1e 100644 --- a/xcache.h +++ b/xcache.h @@ -127,6 +127,8 @@ typedef char *zstr; # define add_u_assoc_zval_ex(arg, type, key, key_len, value) \ add_assoc_zval_ex(arg, key, key_len, value) +# define zend_u_is_auto_global(type, name, name_len) \ + zend_is_auto_global(name, name_len) #endif /* }}} */ @@ -220,6 +222,17 @@ typedef struct { zend_function func; } xc_funcinfo_t; /* }}} */ +#ifdef ZEND_ENGINE_2_1 +/* {{{ xc_autoglobal_t */ +typedef struct { +#ifdef IS_UNICODE + zend_uchar type; +#endif + zstr key; + zend_uint key_len; +} xc_autoglobal_t; +/* }}} */ +#endif typedef enum { XC_TYPE_PHP, XC_TYPE_VAR } xc_entry_type_t; /* {{{ xc_entry_data_php_t */ typedef struct { @@ -243,6 +256,11 @@ typedef struct { zend_uint classinfo_cnt; xc_classinfo_t *classinfos; zend_bool have_early_binding; + +#ifdef ZEND_ENGINE_2_1 + zend_uint autoglobal_cnt; + xc_autoglobal_t *autoglobals; +#endif } xc_entry_data_php_t; /* }}} */ /* {{{ xc_entry_data_var_t */ diff --git a/xcache.ini b/xcache.ini index 79b1949..3aec72f 100644 --- a/xcache.ini +++ b/xcache.ini @@ -9,9 +9,6 @@ zend_extension_ts = c:/php/extensions/php_xcache.dll ;; or win32: ; extension = php_xcache.dll -; required for >=php5.1 if you turn XCache on -auto_globals_jit = Off - [xcache.admin] xcache.admin.user = "mOo" ; xcache.admin.pass = md5($your_password)