Browse Source

Decompiler PHP_5_6: updated support for zend_ast

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1488 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
master
Xuefer 8 years ago
parent
commit
5f8c3d0ee3
  1. 6
      devel/sample.cpp.php
  2. 71
      lib/Decompiler.class.php
  3. 32
      mod_disassembler/xc_disassembler.c
  4. 1
      processor/main.m4
  5. 4
      processor/processor.m4
  6. 6
      processor/struct.m4

6
devel/sample.cpp.php

@ -44,6 +44,12 @@ abstract class ClassName
static public $static_const10 = array(CONST_VALUE => CONST_VALUE);
static public $static_const11 = array(self::CONST_VALUE => self::CONST_VALUE);
static public $static_const12 = array(ClassName::CONST_VALUE => ClassName::CONST_VALUE);
static public $ast_binop = ClassName::CONST_VALUE + ClassName::CONST_VALUE;
static public $ast_and = ClassName::CONST_VALUE && 1;
static public $ast_or = ClassName::CONST_VALUE || 2;
static public $ast_select = ClassName::CONST_VALUE ? a : b;
static public $ast_unaryPlus = +ClassName::CONST_VALUE;
static public $ast_unaryMinus = -ClassName::CONST_VALUE;
/** doc */
static public $public_static = array(2, 'str');
/** doc */

71
lib/Decompiler.class.php

@ -87,8 +87,66 @@ function foldToCode($src, $indent = '') // {{{ wrap or rewrap anything to Decomp
return $src;
}
// }}}
function decompileAst($ast, $EX) // {{{
{
$kind = $ast['kind'];
$children = $ast['children'];
unset($ast['kind']);
unset($ast['children']);
switch ($kind) {
case ZEND_CONST:
return value($ast[0], $EX);
case XC_INIT_ARRAY:
$array = new Decompiler_Array();
for ($i = 0; $i < $children; $i += 2) {
if (isset($ast[$i + 1])) {
$key = decompileAst($ast[$i], $EX);
$value = decompileAst($ast[$i + 1], $EX);
$array->value[] = array($key, $value);
}
else {
$array->value[] = array(null, decompileAst($ast[$i], $EX));
}
}
return $array;
// ZEND_BOOL_AND: handled in binop
// ZEND_BOOL_OR: handled in binop
case ZEND_SELECT:
return new Decompiler_TriOp(
decompileAst($ast[0], $EX)
, decompileAst($ast[1], $EX)
, decompileAst($ast[2], $EX)
);
case ZEND_UNARY_PLUS:
return new Decompiler_Code('+' . str(decompileAst($ast[0], $EX)));
case ZEND_UNARY_MINUS:
return new Decompiler_Code('-' . str(decompileAst($ast[0], $EX)));
default:
$decompiler = $GLOBALS['__xcache_decompiler'];
if (isset($decompiler->binops[$kind])) {
return new Decompiler_Binop($decompiler
, decompileAst($ast[0], $EX)
, $kind
, decompileAst($ast[1], $EX)
);
}
return "un-handled kind $kind in zend_ast";
}
}
// }}}
function value($value, &$EX) // {{{
{
if (ZEND_ENGINE_2_6 && (xcache_get_type($value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_AST) {
return decompileAst(xcache_dasm_ast($value), $EX);
}
$originalValue = xcache_get_special_value($value);
if (isset($originalValue)) {
if ((xcache_get_type($value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
@ -590,6 +648,10 @@ class Decompiler
XC_JMP_SET_VAR => "?:",
XC_JMPZ_EX => "&&",
XC_JMPNZ_EX => "||",
// zend_ast
ZEND_BOOL_AND => '&&',
ZEND_BOOL_OR => '||',
);
// }}}
$this->includeTypes = array( // {{{
@ -2944,6 +3006,15 @@ define('IS_CONSTANT_INDEX', 0x80);
define('IS_LEXICAL_VAR', 0x20);
define('IS_LEXICAL_REF', 0x40);
if (ZEND_ENGINE_2_6) {
define('ZEND_CONST', 256);
define('ZEND_BOOL_AND', 256 + 1);
define('ZEND_BOOL_OR', 256 + 2);
define('ZEND_SELECT', 256 + 3);
define('ZEND_UNARY_PLUS', 256 + 4);
define('ZEND_UNARY_MINUS', 256 + 5);
}
@define('XC_IS_CV', 16);
/*

32
mod_disassembler/xc_disassembler.c

@ -236,6 +236,35 @@ PHP_FUNCTION(xcache_dasm_string)
}
/* }}} */
#ifdef IS_CONSTANT_AST
/* {{{ proto array xcache_dasm_ast(mixed ast)
Disassemble zend_ast data into array */
#ifdef ZEND_BEGIN_ARG_INFO_EX
ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_dasm_ast, 0, 0, 1)
ZEND_ARG_INFO(0, ast)
ZEND_END_ARG_INFO()
#else
static unsigned char arginfo_xcache_dasm_ast[] = { 1, BYREF_NONE };
#endif
PHP_FUNCTION(xcache_dasm_ast)
{
zval *ast;
xc_dasm_t dasm;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &ast) == FAILURE) {
return;
}
if ((Z_TYPE_P(ast) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT_AST) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Data type is not zend_ast");
return;
}
array_init(return_value);
xc_dasm_zend_ast(&dasm, return_value, ast->value.ast TSRMLS_CC);
}
/* }}} */
#endif
/* {{{ PHP_MINFO_FUNCTION(xcache_disassembler) */
static PHP_MINFO_FUNCTION(xcache_disassembler)
{
@ -250,6 +279,9 @@ static zend_function_entry xcache_disassembler_functions[] = /* {{{ */
{
PHP_FE(xcache_dasm_file, arginfo_xcache_dasm_file)
PHP_FE(xcache_dasm_string, arginfo_xcache_dasm_string)
#ifdef IS_CONSTANT_AST
PHP_FE(xcache_dasm_ast, arginfo_xcache_dasm_ast)
#endif
PHP_FE_END
};
/* }}} */

1
processor/main.m4

@ -254,6 +254,7 @@ dnl }}}
EXPORT_PROCESSOR(`dasm', `zend_op_array')
EXPORT_PROCESSOR(`dasm', `zend_function')
EXPORT_PROCESSOR(`dasm', `zend_class_entry')
EXPORT_PROCESSOR(`dasm', `zend_ast')
EXPORT_PROCESSOR(`dprint', `zval')
include(__dir__`/hashtable.m4')

4
processor/processor.m4

@ -96,7 +96,7 @@ DEF_STRUCT_P_FUNC(`zend_ast', , `dnl {{{
DST()->u.val = (zval *) (DST() + 1);
memcpy(DST()->u.val, SRC()->u.val, sizeof(zval));
')
STRUCT_P_EX(zval, DST()->u.val, SRC()->u.val, `', `', ` ')
STRUCT_P_EX(zval, DST()->u.val, SRC()->u.val, `[]', `', ` ')
RELOCATE_EX(zval, DST()->u.val)
}
else {
@ -105,7 +105,7 @@ DEF_STRUCT_P_FUNC(`zend_ast', , `dnl {{{
if (src_ast) {
ZEND_AST_HELPER(`src_ast', `
ALLOC(`(&DST()->u.child)[i]', zend_ast)
STRUCT_P_EX(zend_ast, (&DST()->u.child)[i], src_ast, `[i]', `', ` ')
STRUCT_P_EX(zend_ast, (&DST()->u.child)[i], src_ast, `[]', `', ` ')
')
RELOCATE_EX(zend_ast, (&DST()->u.child)[i])
}

6
processor/struct.m4

@ -157,7 +157,11 @@ ifdef(`DASM_STRUCT_DIRECT', `', `
);
ifdef(`DASM_STRUCT_DIRECT', `', `
IFDASM(`
add_assoc_zval_ex(DST(), XCACHE_STRS("$4"), zv);
ifelse(`$4', `[]', `
add_next_index_zval(DST(), zv);
', `
add_assoc_zval_ex(DST(), XCACHE_STRS("$4"), zv);
')
} while (0);
')
')

Loading…
Cancel
Save