|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
#if 1 |
|
|
|
|
#define XCACHE_DEBUG |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -944,8 +944,26 @@ static inline xc_hash_value_t xc_entry_hash_php_basename(xc_entry_t *xce TSRMLS_
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static int xc_entry_init_key_php(xc_entry_t *xce, char *filename, char *opened_path_buffer TSRMLS_DC) /* {{{ */ |
|
|
|
|
static void xc_entry_free_key_php(xc_entry_t *xce TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
#define X_FREE(var) do {\ |
|
|
|
|
if (xce->var) { \
|
|
|
|
|
efree(xce->var); \
|
|
|
|
|
} \
|
|
|
|
|
} while (0) |
|
|
|
|
X_FREE(dirpath); |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
X_FREE(ufilepath); |
|
|
|
|
X_FREE(udirpath); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#undef X_FREE |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
static int xc_entry_init_key_php(xc_entry_t *xce, char *filename TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
char opened_path_buffer[MAXPATHLEN]; |
|
|
|
|
struct stat buf, *pbuf; |
|
|
|
|
xc_hash_value_t hv; |
|
|
|
|
int cacheid; |
|
|
|
@ -1107,6 +1125,18 @@ static int xc_entry_init_key_php_md5(xc_entry_data_php_t *php, xc_entry_t *xce T
|
|
|
|
|
return SUCCESS; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_entry_init_key_php_entry(xc_entry_t *xce, char *filepath TSRMLS_DC) /* {{{*/ |
|
|
|
|
{ |
|
|
|
|
xce->filepath = filepath; |
|
|
|
|
xce->filepath_len = strlen(xce->filepath); |
|
|
|
|
xce->dirpath = estrndup(xce->filepath, xce->filepath_len); |
|
|
|
|
xce->dirpath_len = zend_dirname(xce->dirpath, xce->filepath_len); |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &xce->ufilepath, &xce->ufilepath_len, xce->filepath, xce->filepath_len TSRMLS_CC); |
|
|
|
|
zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &xce->udirpath, &xce->udirpath_len, xce->dirpath, xce->dirpath_len TSRMLS_CC); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
#ifndef ZEND_COMPILE_DELAYED_BINDING |
|
|
|
|
static void xc_cache_early_binding_class_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
@ -1149,7 +1179,7 @@ typedef struct {
|
|
|
|
|
zend_bool udirpath_used; |
|
|
|
|
} xc_const_usage_t; |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_collect_op_array_info(xc_entry_data_php_t *php, xc_const_usage_t *usage, xc_op_array_info_t *op_array_info, zend_op_array *op_array TSRMLS_DC) /* {{{ */ |
|
|
|
|
static void xc_collect_op_array_info(xc_entry_t *xce, xc_entry_data_php_t *php, xc_const_usage_t *usage, xc_op_array_info_t *op_array_info, zend_op_array *op_array TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
int oplineno; |
|
|
|
|
xc_vector_t vector_int; |
|
|
|
@ -1157,13 +1187,13 @@ static void xc_collect_op_array_info(xc_entry_data_php_t *php, xc_const_usage_t
|
|
|
|
|
xc_vector_init(int, &vector_int); |
|
|
|
|
|
|
|
|
|
#define XCACHE_CHECK_OP(type, op) \ |
|
|
|
|
if (zend_binary_strcmp(Z_STRVAL(opline->op.u.constant), Z_STRLEN(opline->op.u.constant), php->type##path, php->type##path_len) == 0) { \
|
|
|
|
|
if (zend_binary_strcmp(Z_STRVAL(opline->op.u.constant), Z_STRLEN(opline->op.u.constant), xce->type##path, xce->type##path_len) == 0) { \
|
|
|
|
|
usage->type##path_used = 1; \
|
|
|
|
|
oplineinfo |= xcache_##op##_is_##type; \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define XCACHE_U_CHECK_OP(type, op) \ |
|
|
|
|
if (zend_u_##binary_strcmp(Z_USTRVAL(opline->op.u.constant), Z_USTRLEN(opline->op.u.constant), php->u##type##path, php->u##type##path_len) == 0) { \
|
|
|
|
|
if (zend_u_##binary_strcmp(Z_USTRVAL(opline->op.u.constant), Z_USTRLEN(opline->op.u.constant), xce->u##type##path, xce->u##type##path_len) == 0) { \
|
|
|
|
|
usage->u##type##path_used = 1; \
|
|
|
|
|
oplineinfo |= xcache_##op##_is_##type; \
|
|
|
|
|
} |
|
|
|
@ -1208,7 +1238,7 @@ static void xc_collect_op_array_info(xc_entry_data_php_t *php, xc_const_usage_t
|
|
|
|
|
xc_vector_free(int, &vector_int); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
void xc_fix_op_array_info(const xc_entry_data_php_t *php, zend_op_array *op_array, int copy, const xc_op_array_info_t *op_array_info TSRMLS_DC) /* {{{ */ |
|
|
|
|
void xc_fix_op_array_info(const xc_entry_t *xce, const xc_entry_data_php_t *php, zend_op_array *op_array, int copy, const xc_op_array_info_t *op_array_info TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
if (!op_array_info->oplineinfo_cnt) { |
|
|
|
@ -1225,13 +1255,14 @@ void xc_fix_op_array_info(const xc_entry_data_php_t *php, zend_op_array *op_arra
|
|
|
|
|
efree(Z_STRVAL(opline->op1.u.constant)); |
|
|
|
|
} |
|
|
|
|
if (Z_TYPE(opline->op1.u.constant) == IS_STRING) { |
|
|
|
|
assert(php->filepath); |
|
|
|
|
ZVAL_STRINGL(&opline->op1.u.constant, php->filepath, php->filepath_len, copy); |
|
|
|
|
assert(xce->filepath); |
|
|
|
|
ZVAL_STRINGL(&opline->op1.u.constant, xce->filepath, xce->filepath_len, copy); |
|
|
|
|
TRACE("fixing op1 to %s", xce->filepath); |
|
|
|
|
} |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
else if (Z_TYPE(opline->op1.u.constant) == IS_UNICODE) { |
|
|
|
|
assert(php->ufilepath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op1.u.constant, php->ufilepath, php->ufilepath_len, copy); |
|
|
|
|
assert(xce->ufilepath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op1.u.constant, xce->ufilepath, xce->ufilepath_len, copy); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
else { |
|
|
|
@ -1244,13 +1275,14 @@ void xc_fix_op_array_info(const xc_entry_data_php_t *php, zend_op_array *op_arra
|
|
|
|
|
efree(Z_STRVAL(opline->op1.u.constant)); |
|
|
|
|
} |
|
|
|
|
if (Z_TYPE(opline->op1.u.constant) == IS_STRING) { |
|
|
|
|
assert(php->dirpath); |
|
|
|
|
ZVAL_STRINGL(&opline->op1.u.constant, php->dirpath, php->dirpath_len, copy); |
|
|
|
|
assert(xce->dirpath); |
|
|
|
|
TRACE("fixing op1 to %s", xce->dirpath); |
|
|
|
|
ZVAL_STRINGL(&opline->op1.u.constant, xce->dirpath, xce->dirpath_len, copy); |
|
|
|
|
} |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
else if (Z_TYPE(opline->op1.u.constant) == IS_UNICODE) { |
|
|
|
|
assert(!php->udirpath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op1.u.constant, php->udirpath, php->udirpath_len, copy); |
|
|
|
|
assert(!xce->udirpath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op1.u.constant, xce->udirpath, xce->udirpath_len, copy); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
else { |
|
|
|
@ -1264,13 +1296,14 @@ void xc_fix_op_array_info(const xc_entry_data_php_t *php, zend_op_array *op_arra
|
|
|
|
|
efree(Z_STRVAL(opline->op2.u.constant)); |
|
|
|
|
} |
|
|
|
|
if (Z_TYPE(opline->op2.u.constant) == IS_STRING) { |
|
|
|
|
assert(php->filepath); |
|
|
|
|
ZVAL_STRINGL(&opline->op2.u.constant, php->filepath, php->filepath_len, copy); |
|
|
|
|
assert(xce->filepath); |
|
|
|
|
TRACE("fixing op2 to %s", xce->filepath); |
|
|
|
|
ZVAL_STRINGL(&opline->op2.u.constant, xce->filepath, xce->filepath_len, copy); |
|
|
|
|
} |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
else if (Z_TYPE(opline->op2.u.constant) == IS_UNICODE) { |
|
|
|
|
assert(php->ufilepath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op2.u.constant, php->ufilepath, php->ufilepath_len, copy); |
|
|
|
|
assert(xce->ufilepath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op2.u.constant, xce->ufilepath, xce->ufilepath_len, copy); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
else { |
|
|
|
@ -1283,13 +1316,14 @@ void xc_fix_op_array_info(const xc_entry_data_php_t *php, zend_op_array *op_arra
|
|
|
|
|
efree(Z_STRVAL(opline->op2.u.constant)); |
|
|
|
|
} |
|
|
|
|
if (Z_TYPE(opline->op2.u.constant) == IS_STRING) { |
|
|
|
|
assert(!php->dirpath); |
|
|
|
|
ZVAL_STRINGL(&opline->op2.u.constant, php->dirpath, php->dirpath_len, copy); |
|
|
|
|
assert(!xce->dirpath); |
|
|
|
|
TRACE("fixing op2 to %s", xce->dirpath); |
|
|
|
|
ZVAL_STRINGL(&opline->op2.u.constant, xce->dirpath, xce->dirpath_len, copy); |
|
|
|
|
} |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
else if (Z_TYPE(opline->op2.u.constant) == IS_UNICODE) { |
|
|
|
|
assert(!php->udirpath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op2.u.constant, php->udirpath, php->udirpath_len, copy); |
|
|
|
|
assert(!xce->udirpath); |
|
|
|
|
ZVAL_UNICODEL(&opline->op2.u.constant, xce->udirpath, xce->udirpath_len, copy); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
else { |
|
|
|
@ -1335,12 +1369,6 @@ static void xc_free_php(xc_entry_data_php_t *php TSRMLS_DC) /* {{{ */
|
|
|
|
|
} \
|
|
|
|
|
} while (0) |
|
|
|
|
|
|
|
|
|
X_FREE(dirpath); |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
X_FREE(ufilepath); |
|
|
|
|
X_FREE(udirpath); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef ZEND_ENGINE_2_1 |
|
|
|
|
X_FREE(autoglobals); |
|
|
|
|
#endif |
|
|
|
@ -1352,12 +1380,11 @@ static void xc_free_php(xc_entry_data_php_t *php TSRMLS_DC) /* {{{ */
|
|
|
|
|
#undef X_FREE |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ |
|
|
|
|
static zend_op_array *xc_compile_php(xc_entry_t *xce, xc_entry_data_php_t *php, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
zend_op_array *op_array; |
|
|
|
|
int old_constinfo_cnt, old_funcinfo_cnt, old_classinfo_cnt; |
|
|
|
|
zend_bool catched = 0; |
|
|
|
|
xc_const_usage_t const_usage; |
|
|
|
|
|
|
|
|
|
/* {{{ compile */ |
|
|
|
|
TRACE("compiling %s", h->opened_path ? h->opened_path : h->filename); |
|
|
|
@ -1435,17 +1462,6 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
|
|
|
|
|
#undef X_ALLOC |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* {{{ file/dir path init */ |
|
|
|
|
memset(&const_usage, 0, sizeof(const_usage)); |
|
|
|
|
php->filepath = zend_get_compiled_filename(TSRMLS_C); |
|
|
|
|
php->filepath_len = strlen(php->filepath); |
|
|
|
|
php->dirpath = estrndup(php->filepath, php->filepath_len); |
|
|
|
|
php->dirpath_len = zend_dirname(php->dirpath, php->filepath_len); |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &php->ufilepath, &php->ufilepath_len, php->filepath, php->filepath_len TSRMLS_CC); |
|
|
|
|
zend_string_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &php->udirpath, &php->udirpath_len, php->dirpath, php->dirpath_len TSRMLS_CC); |
|
|
|
|
#endif |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ shallow copy, pointers only */ { |
|
|
|
|
Bucket *b; |
|
|
|
|
unsigned int i; |
|
|
|
@ -1481,33 +1497,6 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
|
|
|
|
|
b = CG(function_table)->pListHead; COPY_H(xc_funcinfo_t, funcinfos, funcinfo_cnt, func, zend_function); |
|
|
|
|
b = CG(class_table)->pListHead; COPY_H(xc_classinfo_t, classinfos, classinfo_cnt, cest, xc_cest_t); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < php->classinfo_cnt; i ++) { |
|
|
|
|
xc_classinfo_t *classinfo = &php->classinfos[i]; |
|
|
|
|
zend_class_entry *ce = CestToCePtr(classinfo->cest); |
|
|
|
|
classinfo->methodinfo_cnt = ce->function_table.nTableSize; |
|
|
|
|
if (classinfo->methodinfo_cnt) { |
|
|
|
|
int j; |
|
|
|
|
|
|
|
|
|
ECALLOC_N(classinfo->methodinfos, classinfo->methodinfo_cnt); |
|
|
|
|
if (!classinfo->methodinfos) { |
|
|
|
|
goto err_alloc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (j = 0, b = ce->function_table.pListHead; b; j ++, b = b->pListNext) { |
|
|
|
|
xc_collect_op_array_info(php, &const_usage, &classinfo->methodinfos[j], (zend_op_array *) b->pData TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
classinfo->methodinfos = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (i = 0; i < php->funcinfo_cnt; i ++) { |
|
|
|
|
xc_collect_op_array_info(php, &const_usage, &php->funcinfos[i].op_array_info, (zend_op_array *) &php->funcinfos[i].func TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xc_collect_op_array_info(php, &const_usage, &php->op_array_info, php->op_array TSRMLS_CC); |
|
|
|
|
|
|
|
|
|
#undef COPY_H |
|
|
|
|
|
|
|
|
|
/* for ZE1, cest need to be fixed inside store */ |
|
|
|
@ -1537,23 +1526,60 @@ static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle
|
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ file/dir path free unused */ |
|
|
|
|
|
|
|
|
|
/* {{{ collect info for file/dir path */ { |
|
|
|
|
Bucket *b; |
|
|
|
|
xc_const_usage_t const_usage; |
|
|
|
|
unsigned int i; |
|
|
|
|
|
|
|
|
|
xc_entry_init_key_php_entry(xce, zend_get_compiled_filename(TSRMLS_C) TSRMLS_CC); |
|
|
|
|
memset(&const_usage, 0, sizeof(const_usage)); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < php->classinfo_cnt; i ++) { |
|
|
|
|
xc_classinfo_t *classinfo = &php->classinfos[i]; |
|
|
|
|
zend_class_entry *ce = CestToCePtr(classinfo->cest); |
|
|
|
|
classinfo->methodinfo_cnt = ce->function_table.nTableSize; |
|
|
|
|
if (classinfo->methodinfo_cnt) { |
|
|
|
|
int j; |
|
|
|
|
|
|
|
|
|
ECALLOC_N(classinfo->methodinfos, classinfo->methodinfo_cnt); |
|
|
|
|
if (!classinfo->methodinfos) { |
|
|
|
|
goto err_alloc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (j = 0, b = ce->function_table.pListHead; b; j ++, b = b->pListNext) { |
|
|
|
|
xc_collect_op_array_info(xce, php, &const_usage, &classinfo->methodinfos[j], (zend_op_array *) b->pData TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
classinfo->methodinfos = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (i = 0; i < php->funcinfo_cnt; i ++) { |
|
|
|
|
xc_collect_op_array_info(xce, php, &const_usage, &php->funcinfos[i].op_array_info, (zend_op_array *) &php->funcinfos[i].func TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xc_collect_op_array_info(xce, php, &const_usage, &php->op_array_info, php->op_array TSRMLS_CC); |
|
|
|
|
|
|
|
|
|
/* file/dir path free unused */ |
|
|
|
|
#define X_FREE_UNUSED(var) \ |
|
|
|
|
if (!const_usage.var##path_used) { \
|
|
|
|
|
efree(php->var##path); \
|
|
|
|
|
php->var##path = NULL; \
|
|
|
|
|
php->var##path_len = 0; \
|
|
|
|
|
} |
|
|
|
|
if (!const_usage.filepath_used) { |
|
|
|
|
php->filepath = NULL; |
|
|
|
|
php->filepath_len = 0; |
|
|
|
|
} |
|
|
|
|
X_FREE_UNUSED(dir) |
|
|
|
|
if (!const_usage.var##path_used) { \
|
|
|
|
|
efree(xce->var##path); \
|
|
|
|
|
xce->var##path = NULL; \
|
|
|
|
|
xce->var##path_len = 0; \
|
|
|
|
|
} |
|
|
|
|
if (!const_usage.filepath_used) { |
|
|
|
|
xce->filepath = NULL; |
|
|
|
|
xce->filepath_len = 0; |
|
|
|
|
} |
|
|
|
|
X_FREE_UNUSED(dir) |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
X_FREE_UNUSED(ufile) |
|
|
|
|
X_FREE_UNUSED(udir) |
|
|
|
|
X_FREE_UNUSED(ufile) |
|
|
|
|
X_FREE_UNUSED(udir) |
|
|
|
|
#endif |
|
|
|
|
#undef X_FREE_UNUSED |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
#ifdef XCACHE_ERROR_CACHING |
|
|
|
|
php->compilererrors = ((xc_sandbox_t *) XG(sandbox))->compilererrors; |
|
|
|
@ -1602,7 +1628,7 @@ static zend_op_array *xc_compile_restore(xc_entry_t *stored_xce, zend_file_handl
|
|
|
|
|
CG(zend_lineno) = 0; |
|
|
|
|
TRACE("restoring %s", stored_xce->name.str.val); |
|
|
|
|
xc_processor_restore_xc_entry_t(&xce, stored_xce TSRMLS_CC); |
|
|
|
|
xc_processor_restore_xc_entry_data_php_t(&php, xce.data.php, xc_readonly_protection TSRMLS_CC); |
|
|
|
|
xc_processor_restore_xc_entry_data_php_t(stored_xce, &php, xce.data.php, xc_readonly_protection TSRMLS_CC); |
|
|
|
|
xce.data.php = &php; |
|
|
|
|
#ifdef SHOW_DPRINT |
|
|
|
|
xc_dprint(&xce, 0 TSRMLS_CC); |
|
|
|
@ -1640,37 +1666,17 @@ static zend_op_array *xc_check_initial_compile_file(zend_file_handle *h, int typ
|
|
|
|
|
return origin_compile_file(h, type TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ |
|
|
|
|
static zend_op_array *xc_compile_file_ex(xc_entry_t *xce, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
zend_op_array *op_array; |
|
|
|
|
xc_entry_t xce, *stored_xce; |
|
|
|
|
xc_entry_data_php_t php, *stored_php; |
|
|
|
|
xc_cache_t *cache; |
|
|
|
|
xc_entry_t *stored_xce; |
|
|
|
|
xc_entry_data_php_t *stored_php; |
|
|
|
|
xc_cache_t *cache = xce->cache; |
|
|
|
|
zend_bool gaveup = 0; |
|
|
|
|
zend_bool catched = 0; |
|
|
|
|
zend_bool newlycompiled; |
|
|
|
|
char *filename; |
|
|
|
|
char opened_path_buffer[MAXPATHLEN]; |
|
|
|
|
xc_sandbox_t sandbox; |
|
|
|
|
|
|
|
|
|
assert(xc_initized); |
|
|
|
|
|
|
|
|
|
TRACE("type = %d\n", h->type); |
|
|
|
|
if (!XG(cacher)) { |
|
|
|
|
op_array = old_compile_file(h, type TSRMLS_CC); |
|
|
|
|
return op_array; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* {{{ entry_init_key */ |
|
|
|
|
filename = h->opened_path ? h->opened_path : h->filename; |
|
|
|
|
xce.data.php = &php; |
|
|
|
|
if (xc_entry_init_key_php(&xce, filename, opened_path_buffer TSRMLS_CC) != SUCCESS) { |
|
|
|
|
TRACE("failed to init key for %s", filename); |
|
|
|
|
return old_compile_file(h, type TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
cache = xce.cache; |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* stale clogs precheck */ |
|
|
|
|
if (cache->compiling) { |
|
|
|
|
cache->clogs ++; |
|
|
|
@ -1680,7 +1686,7 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
stored_xce = NULL; |
|
|
|
|
stored_php = NULL; |
|
|
|
|
ENTER_LOCK_EX(cache) { |
|
|
|
|
stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC); |
|
|
|
|
stored_xce = xc_entry_find_dmz(xce TSRMLS_CC); |
|
|
|
|
if (stored_xce) { |
|
|
|
|
xc_cache_hit_dmz(cache TSRMLS_CC); |
|
|
|
|
|
|
|
|
@ -1689,14 +1695,14 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
cache->misses ++; |
|
|
|
|
TRACE("miss %s", xce.name.str.val); |
|
|
|
|
TRACE("miss %s", xce->name.str.val); |
|
|
|
|
|
|
|
|
|
if (xc_entry_init_key_php_md5(&php, &xce TSRMLS_CC) != SUCCESS) { |
|
|
|
|
if (xc_entry_init_key_php_md5(xce->data.php, xce TSRMLS_CC) != SUCCESS) { |
|
|
|
|
gaveup = 1; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
stored_php = xc_php_find_dmz(&php TSRMLS_CC); |
|
|
|
|
stored_php = xc_php_find_dmz(xce->data.php TSRMLS_CC); |
|
|
|
|
|
|
|
|
|
/* miss but compiling */ |
|
|
|
|
if (!stored_php) { |
|
|
|
@ -1735,33 +1741,28 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
/* {{{ compile */ |
|
|
|
|
if (stored_php) { |
|
|
|
|
newlycompiled = 0; |
|
|
|
|
xce.data.php = stored_php; |
|
|
|
|
xc_entry_init_key_php_entry(xce, h->opened_path ? h->opened_path : h->filename TSRMLS_CC); |
|
|
|
|
xce->data.php = stored_php; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
newlycompiled = 1; |
|
|
|
|
|
|
|
|
|
/* make compile inside sandbox */ |
|
|
|
|
xc_sandbox_init(&sandbox, filename TSRMLS_CC); |
|
|
|
|
xc_sandbox_init(&sandbox, h->opened_path ? h->opened_path : h->filename TSRMLS_CC); |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_XCACHE_CONSTANT |
|
|
|
|
php.constinfos = NULL; |
|
|
|
|
xce->data.php->constinfos = NULL; |
|
|
|
|
#endif |
|
|
|
|
php.funcinfos = NULL; |
|
|
|
|
php.classinfos = NULL; |
|
|
|
|
xce->data.php->funcinfos = NULL; |
|
|
|
|
xce->data.php->classinfos = NULL; |
|
|
|
|
#ifdef ZEND_ENGINE_2_1 |
|
|
|
|
php.autoglobals = NULL; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
php.udirpath = NULL; |
|
|
|
|
php.ufilepath = NULL; |
|
|
|
|
xce->data.php->autoglobals = NULL; |
|
|
|
|
#endif |
|
|
|
|
php.dirpath = NULL; |
|
|
|
|
|
|
|
|
|
memset(&php.op_array_info, 0, sizeof(php.op_array_info)); |
|
|
|
|
memset(&xce->data.php->op_array_info, 0, sizeof(xce->data.php->op_array_info)); |
|
|
|
|
|
|
|
|
|
zend_try { |
|
|
|
|
op_array = xc_compile_php(&php, h, type TSRMLS_CC); |
|
|
|
|
op_array = xc_compile_php(xce, xce->data.php, h, type TSRMLS_CC); |
|
|
|
|
} zend_catch { |
|
|
|
|
catched = 1; |
|
|
|
|
} zend_end_try(); |
|
|
|
@ -1771,15 +1772,13 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* not cachable */ |
|
|
|
|
if (!php.op_array) { |
|
|
|
|
if (!xce->data.php->op_array) { |
|
|
|
|
cache->compiling = 0; |
|
|
|
|
/* it's not cachable, but don't scare the users with high misses */ |
|
|
|
|
cache->misses --; |
|
|
|
|
xc_sandbox_free(&sandbox, XC_InstallNoBinding TSRMLS_CC); |
|
|
|
|
return op_array; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xce.data.php = &php; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
#ifdef HAVE_INODE |
|
|
|
@ -1788,23 +1787,23 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
* do not update to its name to real pathname |
|
|
|
|
* WARNING: this code is required to be after compile |
|
|
|
|
*/ |
|
|
|
|
if (xce.inode) { |
|
|
|
|
filename = h->opened_path ? h->opened_path : h->filename; |
|
|
|
|
if (xce.name.str.val != filename) { |
|
|
|
|
xce.name.str.val = filename; |
|
|
|
|
xce.name.str.len = strlen(filename); |
|
|
|
|
if (xce->inode) { |
|
|
|
|
char *filename = h->opened_path ? h->opened_path : h->filename; |
|
|
|
|
if (xce->name.str.val != filename) { |
|
|
|
|
xce->name.str.val = filename; |
|
|
|
|
xce->name.str.len = strlen(filename); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
#endif |
|
|
|
|
#ifdef SHOW_DPRINT |
|
|
|
|
xc_dprint(&xce, 0 TSRMLS_CC); |
|
|
|
|
xc_dprint(xce, 0 TSRMLS_CC); |
|
|
|
|
#endif |
|
|
|
|
stored_xce = NULL; |
|
|
|
|
ENTER_LOCK_EX(cache) { /* {{{ php_store/entry_store */ |
|
|
|
|
/* php_store */ |
|
|
|
|
if (newlycompiled) { |
|
|
|
|
stored_php = xc_php_store_dmz(&php TSRMLS_CC); |
|
|
|
|
stored_php = xc_php_store_dmz(xce->data.php TSRMLS_CC); |
|
|
|
|
if (!stored_php) { |
|
|
|
|
/* error */ |
|
|
|
|
break; |
|
|
|
@ -1812,7 +1811,7 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
} |
|
|
|
|
/* entry_store */ |
|
|
|
|
xc_php_addref_dmz(stored_php); |
|
|
|
|
stored_xce = xc_entry_store_dmz(&xce TSRMLS_CC); |
|
|
|
|
stored_xce = xc_entry_store_dmz(xce TSRMLS_CC); |
|
|
|
|
if (stored_xce) { |
|
|
|
|
stored_xce->data.php = stored_php; |
|
|
|
|
} |
|
|
|
@ -1830,7 +1829,7 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (newlycompiled) { |
|
|
|
|
xc_free_php(&php TSRMLS_CC); |
|
|
|
|
xc_free_php(xce->data.php TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (stored_xce) { |
|
|
|
@ -1861,7 +1860,7 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|
|
|
|
|
|
|
|
|
err_aftersandbox: |
|
|
|
|
if (newlycompiled) { |
|
|
|
|
xc_free_php(&php TSRMLS_CC); |
|
|
|
|
xc_free_php(xce->data.php TSRMLS_CC); |
|
|
|
|
xc_sandbox_free(&sandbox, XC_NoInstall TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1873,6 +1872,37 @@ err_aftersandbox:
|
|
|
|
|
return op_array; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
zend_op_array *op_array; |
|
|
|
|
xc_entry_t xce; |
|
|
|
|
xc_entry_data_php_t php; |
|
|
|
|
char *filename; |
|
|
|
|
|
|
|
|
|
assert(xc_initized); |
|
|
|
|
|
|
|
|
|
TRACE("type = %d\n", h->type); |
|
|
|
|
if (!XG(cacher)) { |
|
|
|
|
op_array = old_compile_file(h, type TSRMLS_CC); |
|
|
|
|
return op_array; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* {{{ entry_init_key */ |
|
|
|
|
filename = h->opened_path ? h->opened_path : h->filename; |
|
|
|
|
xce.data.php = &php; |
|
|
|
|
if (xc_entry_init_key_php(&xce, filename TSRMLS_CC) != SUCCESS) { |
|
|
|
|
TRACE("failed to init key for %s", filename); |
|
|
|
|
return old_compile_file(h, type TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
op_array = xc_compile_file_ex(&xce, h, type TSRMLS_CC); |
|
|
|
|
|
|
|
|
|
xc_entry_free_key_php(&xce TSRMLS_CC); |
|
|
|
|
|
|
|
|
|
return op_array; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* gdb helper functions, but N/A for coredump */ |
|
|
|
|
int xc_is_rw(const void *p) /* {{{ */ |
|
|
|
|