diff --git a/ChangeLog b/ChangeLog index c33d5ce..52f7f10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ ChangeLog * cacher: * (WIP) defragment * (WIP) cache to disk + * (WIP) PHP_5_6 support * misc: * Reflection info added for APIs diff --git a/NEWS b/NEWS index 874eca8..5a97e38 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ 4.0.0 2014-??-?? +======== * api updates * cache defragment, cache to disk + * PHP_5_6 support 3.2.1 2013-??-?? ======== diff --git a/devel/prepare.cfg.example b/devel/prepare.cfg.example index 0968403..368543d 100644 --- a/devel/prepare.cfg.example +++ b/devel/prepare.cfg.example @@ -5,9 +5,10 @@ PHP5_1_DIR= PHP5_3_DIR= PHP5_4_DIR= PHP5_5_DIR= +PHP5_6_DIR= PHP6_x_DIR= -PHP_DEVEL_DIR= +PHP_DEVEL_DIR=$(PHP5_6_DIR) # path to eaccelerator source dir EA_DIR= diff --git a/devel/prepare.mak b/devel/prepare.mak index 141e4a0..25ab836 100644 --- a/devel/prepare.mak +++ b/devel/prepare.mak @@ -24,6 +24,7 @@ xc_const_string: \ xcache/xc_const_string_opcodes_php5.3.h \ xcache/xc_const_string_opcodes_php5.4.h \ xcache/xc_const_string_opcodes_php5.5.h \ + xcache/xc_const_string_opcodes_php5.6.h \ xcache/xc_const_string_opcodes_php6.x.h ifeq (${EA_DIR},) @@ -98,6 +99,15 @@ xcache/xc_const_string_opcodes_php5.5.h: ${PHP5_5_DIR}/Zend/zend_vm_def.h mv "$@.tmp" "$@" endif +ifeq (${PHP5_6_DIR},) +xcache/xc_const_string_opcodes_php5.6.h: dummy + @echo "Skipped $@: PHP_5_6_DIR not set" +else +xcache/xc_const_string_opcodes_php5.6.h: ${PHP5_6_DIR}/Zend/zend_vm_def.h + $(AWK) -f ./devel/gen_const_string_opcodes.awk < "$<" > "$@.tmp" + mv "$@.tmp" "$@" +endif + ifeq (${PHP6_x_DIR},) xcache/xc_const_string_opcodes_php6.x.h: dummy @echo "Skipped $@: PHP_6_x_DIR not set" diff --git a/lib/Decompiler.class.php b/lib/Decompiler.class.php index dad266c..9fcc43b 100644 --- a/lib/Decompiler.class.php +++ b/lib/Decompiler.class.php @@ -2796,7 +2796,9 @@ class Decompiler } // {{{ defines -define('ZEND_ENGINE_2_4', PHP_VERSION >= "5.4"); +define('ZEND_ENGINE_2_6', PHP_VERSION >= "5.6"); +define('ZEND_ENGINE_2_5', ZEND_ENGINE_2_6 || PHP_VERSION >= "5.5."); +define('ZEND_ENGINE_2_4', ZEND_ENGINE_2_5 || PHP_VERSION >= "5.4."); define('ZEND_ENGINE_2_3', ZEND_ENGINE_2_4 || PHP_VERSION >= "5.3."); define('ZEND_ENGINE_2_2', ZEND_ENGINE_2_3 || PHP_VERSION >= "5.2."); define('ZEND_ENGINE_2_1', ZEND_ENGINE_2_2 || PHP_VERSION >= "5.1."); @@ -2925,7 +2927,13 @@ define('IS_OBJECT', 5); define('IS_STRING', ZEND_ENGINE_2_1 ? 6 : 3); define('IS_RESOURCE', 7); define('IS_CONSTANT', 8); -define('IS_CONSTANT_ARRAY', 9); +if (ZEND_ENGINE_2_6) { + define('IS_CONSTANT_ARRAY', -1); + define('IS_CONSTANT_AST', 9); +} +else { + define('IS_CONSTANT_ARRAY', 9); +} if (ZEND_ENGINE_2_4) { define('IS_CALLABLE', 10); } diff --git a/processor/main.m4 b/processor/main.m4 index 70b22eb..4611b88 100644 --- a/processor/main.m4 +++ b/processor/main.m4 @@ -34,7 +34,11 @@ dnl }}} dnl {{{ ALLOC(1:dst, 2:type, 3:count=1, 4:clean=false, 5:realtype=$2) define(`ALLOC', ` pushdef(`COUNT', `ifelse(`$3', `', `1', `$3')') - pushdef(`SIZE', `sizeof($2)ifelse(`$3', `', `', ` * $3')') + ifdef(`ALLOC_SIZE_HELPER', ` + pushdef(`SIZE', `ALLOC_SIZE_HELPER()') + ', ` + pushdef(`SIZE', `sizeof($2)ifelse(`$3', `', `', ` * $3')') + ') pushdef(`REALTYPE', `ifelse(`$5', , `$2', `$5')') /* allocate */ IFCALC(` diff --git a/processor/processor.m4 b/processor/processor.m4 index aaae239..a41d51a 100644 --- a/processor/processor.m4 +++ b/processor/processor.m4 @@ -69,6 +69,46 @@ DEF_HASH_TABLE_FUNC(`HashTable_zend_function', `zend_function') #ifdef ZEND_ENGINE_2 DEF_HASH_TABLE_FUNC(`HashTable_zend_property_info', `zend_property_info') #endif +#ifdef IS_CONSTANT_AST +define(`ZEND_AST_HELPER', ` + { + IFCALCCOPY(` + size_t zend_ast_size = $1->kind == ZEND_CONST + ? sizeof(zend_ast) + sizeof(zval) + : sizeof(zend_ast) + sizeof(zend_ast *) * ($1->children - 1); + ') + + pushdef(`ALLOC_SIZE_HELPER', `zend_ast_size') + $2 + popdef(`ALLOC_SIZE_HELPER') + } +') +DEF_STRUCT_P_FUNC(`zend_ast', , `dnl {{{ + zend_ushort i; + PROCESS(zend_ushort, kind) + PROCESS(zend_ushort, children) + DONE(u) + DISABLECHECK(` + if (SRC()->kind == ZEND_CONST) { + assert(SRC()->u.val); + IFCOPY(` + memcpy(DST()->u.val, SRC()->u.val, sizeof(zval)); + ') + STRUCT_P_EX(zval, DST()->u.val, SRC()->u.val, `', `', ` ') + RELOCATE_EX(zval, DST()->u.val) + } + else { + for (i = 0; i < SRC()->children; ++i) { + zend_ast *src_ast = (&SRC()->u.child)[i]; + ALLOC(`(&DST()->u.child)[i]', zend_ast) + ZEND_AST_HELPER(`src_ast', `STRUCT_P_EX(zend_ast, (&DST()->u.child)[i], src_ast, `[i]', `', ` ')') + RELOCATE_EX(zend_ast, (&DST()->u.child)[i]) + } + } + ') +') +dnl }}} +#endif DEF_STRUCT_P_FUNC(`zval', , `dnl {{{ IFDASM(`do { zval_dtor(DST()); @@ -125,10 +165,20 @@ proc_unicode: #endif case IS_ARRAY: +#ifdef IS_CONSTANT_ARRAY case IS_CONSTANT_ARRAY: +#endif + assert(SRC()->value.ht); STRUCT_P(HashTable, value.ht, HashTable_zval_ptr) break; +#ifdef IS_CONSTANT_AST + case IS_CONSTANT_AST: + assert(SRC()->value.ast); + ZEND_AST_HELPER(`SRC()->value.ast', `STRUCT_P(zend_ast, value.ast)') + break; +#endif + case IS_OBJECT: IFNOTMEMCPY(`IFCOPY(`memcpy(DST(), SRC(), sizeof(SRC()[0]));')') dnl STRUCT(value.obj) @@ -236,9 +286,18 @@ DEF_STRUCT_P_FUNC(`zend_arg_info', , `dnl {{{ PROCESS(zend_uchar, type_hint) #elif defined(ZEND_ENGINE_2_1) PROCESS(zend_bool, array_type_hint) +#endif +#ifdef ZEND_ENGINE_2_6 + PROCESS(zend_uchar, pass_by_reference) #endif PROCESS(zend_bool, allow_null) + +#ifdef ZEND_ENGINE_2_6 + PROCESS(zend_bool, is_variadic) +#else PROCESS(zend_bool, pass_by_reference) +#endif + #ifndef ZEND_ENGINE_2_4 PROCESS(zend_bool, return_reference) PROCESS(int, required_num_args) @@ -480,10 +539,13 @@ DEF_STRUCT_P_FUNC(`zend_class_entry', , `dnl {{{ # ifdef ZEND_ENGINE_2_1 PROCESS_CTEXTPOINTER(__unset) PROCESS_CTEXTPOINTER(__isset) -# if defined(ZEND_ENGINE_2_2) || PHP_MAJOR_VERSION >= 6 - PROCESS_CTEXTPOINTER(__tostring) -# endif # endif +# if defined(ZEND_ENGINE_2_2) || PHP_MAJOR_VERSION >= 6 + PROCESS_CTEXTPOINTER(__tostring) +# endif +# if defined(ZEND_ENGINE_2_6) + PROCESS_CTEXTPOINTER(__debugInfo) +# endif PROCESS_CTEXTPOINTER(__call) # ifdef ZEND_CALLSTATIC_FUNC_NAME PROCESS_CTEXTPOINTER(__callstatic) diff --git a/xcache.c b/xcache.c index 0e513c2..f15662f 100644 --- a/xcache.c +++ b/xcache.c @@ -366,11 +366,19 @@ PHP_FUNCTION(xcache_get_special_value) return_value->type = UNISW(IS_STRING, UG(unicode) ? IS_UNICODE : IS_STRING); break; +#ifdef IS_CONSTANT_ARRAY case IS_CONSTANT_ARRAY: *return_value = *value; zval_copy_ctor(return_value); return_value->type = IS_ARRAY; break; +#endif + +#ifdef IS_CONSTANT_AST + case IS_CONSTANT_AST: + RETURN_NULL(); + break; +#endif default: if ((Z_TYPE_P(value) & ~IS_CONSTANT_TYPE_MASK)) { diff --git a/xcache/xc_compatibility.h b/xcache/xc_compatibility.h index e96f74f..8d522c5 100644 --- a/xcache/xc_compatibility.h +++ b/xcache/xc_compatibility.h @@ -10,7 +10,10 @@ /* Purpose: Privode stuffs for compatibility with different PHP version */ -#if !defined(ZEND_ENGINE_2_5) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 5 || PHP_MAJOR_VERSION > 6) +#if !defined(ZEND_ENGINE_2_6) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 6 || PHP_MAJOR_VERSION > 6) +# define ZEND_ENGINE_2_6 +#endif +#if !defined(ZEND_ENGINE_2_5) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 5 || defined(ZEND_ENGINE_2_6)) # define ZEND_ENGINE_2_5 #endif #if !defined(ZEND_ENGINE_2_4) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 4 || defined(ZEND_ENGINE_2_5)) diff --git a/xcache/xc_const_string.c b/xcache/xc_const_string.c index 94f48da..4de5e1e 100644 --- a/xcache/xc_const_string.c +++ b/xcache/xc_const_string.c @@ -71,6 +71,8 @@ const char *xc_get_data_type(zend_uchar data_type) /* {{{ xc_get_opcode */ #if PHP_MAJOR_VERSION >= 6 # include "xc_const_string_opcodes_php6.x.h" +#elif defined(ZEND_ENGINE_2_6) +# include "xc_const_string_opcodes_php5.6.h" #elif defined(ZEND_ENGINE_2_5) # include "xc_const_string_opcodes_php5.5.h" #elif defined(ZEND_ENGINE_2_4) diff --git a/xcache/xc_const_string_opcodes_php5.6.h b/xcache/xc_const_string_opcodes_php5.6.h new file mode 100644 index 0000000..4366d5e --- /dev/null +++ b/xcache/xc_const_string_opcodes_php5.6.h @@ -0,0 +1,171 @@ +/* size = 168 */ +static const char *const xc_opcode_names[] = { +/* 0 */ "NOP", +/* 1 */ "ADD", +/* 2 */ "SUB", +/* 3 */ "MUL", +/* 4 */ "DIV", +/* 5 */ "MOD", +/* 6 */ "SL", +/* 7 */ "SR", +/* 8 */ "CONCAT", +/* 9 */ "BW_OR", +/* 10 */ "BW_AND", +/* 11 */ "BW_XOR", +/* 12 */ "BW_NOT", +/* 13 */ "BOOL_NOT", +/* 14 */ "BOOL_XOR", +/* 15 */ "IS_IDENTICAL", +/* 16 */ "IS_NOT_IDENTICAL", +/* 17 */ "IS_EQUAL", +/* 18 */ "IS_NOT_EQUAL", +/* 19 */ "IS_SMALLER", +/* 20 */ "IS_SMALLER_OR_EQUAL", +/* 21 */ "CAST", +/* 22 */ "QM_ASSIGN", +/* 23 */ "ASSIGN_ADD", +/* 24 */ "ASSIGN_SUB", +/* 25 */ "ASSIGN_MUL", +/* 26 */ "ASSIGN_DIV", +/* 27 */ "ASSIGN_MOD", +/* 28 */ "ASSIGN_SL", +/* 29 */ "ASSIGN_SR", +/* 30 */ "ASSIGN_CONCAT", +/* 31 */ "ASSIGN_BW_OR", +/* 32 */ "ASSIGN_BW_AND", +/* 33 */ "ASSIGN_BW_XOR", +/* 34 */ "PRE_INC", +/* 35 */ "PRE_DEC", +/* 36 */ "POST_INC", +/* 37 */ "POST_DEC", +/* 38 */ "ASSIGN", +/* 39 */ "ASSIGN_REF", +/* 40 */ "ECHO", +/* 41 */ "PRINT", +/* 42 */ "JMP", +/* 43 */ "JMPZ", +/* 44 */ "JMPNZ", +/* 45 */ "JMPZNZ", +/* 46 */ "JMPZ_EX", +/* 47 */ "JMPNZ_EX", +/* 48 */ "CASE", +/* 49 */ "SWITCH_FREE", +/* 50 */ "BRK", +/* 51 */ "CONT", +/* 52 */ "BOOL", +/* 53 */ "INIT_STRING", +/* 54 */ "ADD_CHAR", +/* 55 */ "ADD_STRING", +/* 56 */ "ADD_VAR", +/* 57 */ "BEGIN_SILENCE", +/* 58 */ "END_SILENCE", +/* 59 */ "INIT_FCALL_BY_NAME", +/* 60 */ "DO_FCALL", +/* 61 */ "DO_FCALL_BY_NAME", +/* 62 */ "RETURN", +/* 63 */ "RECV", +/* 64 */ "RECV_INIT", +/* 65 */ "SEND_VAL", +/* 66 */ "SEND_VAR", +/* 67 */ "SEND_REF", +/* 68 */ "NEW", +/* 69 */ "INIT_NS_FCALL_BY_NAME", +/* 70 */ "FREE", +/* 71 */ "INIT_ARRAY", +/* 72 */ "ADD_ARRAY_ELEMENT", +/* 73 */ "INCLUDE_OR_EVAL", +/* 74 */ "UNSET_VAR", +/* 75 */ "UNSET_DIM", +/* 76 */ "UNSET_OBJ", +/* 77 */ "FE_RESET", +/* 78 */ "FE_FETCH", +/* 79 */ "EXIT", +/* 80 */ "FETCH_R", +/* 81 */ "FETCH_DIM_R", +/* 82 */ "FETCH_OBJ_R", +/* 83 */ "FETCH_W", +/* 84 */ "FETCH_DIM_W", +/* 85 */ "FETCH_OBJ_W", +/* 86 */ "FETCH_RW", +/* 87 */ "FETCH_DIM_RW", +/* 88 */ "FETCH_OBJ_RW", +/* 89 */ "FETCH_IS", +/* 90 */ "FETCH_DIM_IS", +/* 91 */ "FETCH_OBJ_IS", +/* 92 */ "FETCH_FUNC_ARG", +/* 93 */ "FETCH_DIM_FUNC_ARG", +/* 94 */ "FETCH_OBJ_FUNC_ARG", +/* 95 */ "FETCH_UNSET", +/* 96 */ "FETCH_DIM_UNSET", +/* 97 */ "FETCH_OBJ_UNSET", +/* 98 */ "FETCH_DIM_TMP_VAR", +/* 99 */ "FETCH_CONSTANT", +/* 100 */ "GOTO", +/* 101 */ "EXT_STMT", +/* 102 */ "EXT_FCALL_BEGIN", +/* 103 */ "EXT_FCALL_END", +/* 104 */ "EXT_NOP", +/* 105 */ "TICKS", +/* 106 */ "SEND_VAR_NO_REF", +/* 107 */ "CATCH", +/* 108 */ "THROW", +/* 109 */ "FETCH_CLASS", +/* 110 */ "CLONE", +/* 111 */ "RETURN_BY_REF", +/* 112 */ "INIT_METHOD_CALL", +/* 113 */ "INIT_STATIC_METHOD_CALL", +/* 114 */ "ISSET_ISEMPTY_VAR", +/* 115 */ "ISSET_ISEMPTY_DIM_OBJ", +/* 116 */ "UNDEF", +/* 117 */ "UNDEF", +/* 118 */ "UNDEF", +/* 119 */ "UNDEF", +/* 120 */ "UNDEF", +/* 121 */ "UNDEF", +/* 122 */ "UNDEF", +/* 123 */ "UNDEF", +/* 124 */ "UNDEF", +/* 125 */ "UNDEF", +/* 126 */ "UNDEF", +/* 127 */ "UNDEF", +/* 128 */ "UNDEF", +/* 129 */ "UNDEF", +/* 130 */ "UNDEF", +/* 131 */ "UNDEF", +/* 132 */ "PRE_INC_OBJ", +/* 133 */ "PRE_DEC_OBJ", +/* 134 */ "POST_INC_OBJ", +/* 135 */ "POST_DEC_OBJ", +/* 136 */ "ASSIGN_OBJ", +/* 137 */ "OP_DATA", +/* 138 */ "INSTANCEOF", +/* 139 */ "DECLARE_CLASS", +/* 140 */ "DECLARE_INHERITED_CLASS", +/* 141 */ "DECLARE_FUNCTION", +/* 142 */ "RAISE_ABSTRACT_ERROR", +/* 143 */ "DECLARE_CONST", +/* 144 */ "ADD_INTERFACE", +/* 145 */ "DECLARE_INHERITED_CLASS_DELAYED", +/* 146 */ "VERIFY_ABSTRACT_CLASS", +/* 147 */ "ASSIGN_DIM", +/* 148 */ "ISSET_ISEMPTY_PROP_OBJ", +/* 149 */ "HANDLE_EXCEPTION", +/* 150 */ "USER_OPCODE", +/* 151 */ "UNDEF", +/* 152 */ "JMP_SET", +/* 153 */ "DECLARE_LAMBDA_FUNCTION", +/* 154 */ "ADD_TRAIT", +/* 155 */ "BIND_TRAITS", +/* 156 */ "SEPARATE", +/* 157 */ "QM_ASSIGN_VAR", +/* 158 */ "JMP_SET_VAR", +/* 159 */ "DISCARD_EXCEPTION", +/* 160 */ "YIELD", +/* 161 */ "GENERATOR_RETURN", +/* 162 */ "FAST_CALL", +/* 163 */ "FAST_RET", +/* 164 */ "RECV_VARIADIC", +/* 165 */ "SEND_UNPACK", +/* 166 */ "POW", +/* 167 */ "ASSIGN_POW" +}; diff --git a/xcache/xc_opcode_spec_def.h b/xcache/xc_opcode_spec_def.h index 51b3f96..527835f 100644 --- a/xcache/xc_opcode_spec_def.h +++ b/xcache/xc_opcode_spec_def.h @@ -300,4 +300,10 @@ static const xc_opcode_spec_t xc_opcode_spec[] = { OPSPEC( UNUSED, JMPADDR, UNUSED, UNUSED) /* 162 FAST_CALL */ OPSPEC( UNUSED, UNUSED, UNUSED, UNUSED) /* 163 FAST_RET */ #endif +#ifdef ZEND_ENGINE_2_6 + OPSPEC( UNUSED, ARG, UNUSED, VAR) /* 164 RECV_VARIADIC */ + OPSPEC( SEND, STD, ARG, UNUSED) /* 165 SEND_UNPACK */ + OPSPEC( UNUSED, STD, STD, TMP) /* 166 POW */ + OPSPEC( ASSIGN, STD, STD, VAR) /* 167 ASSIGN_POW */ +#endif };