Browse Source

Decompiler: handle closure use()

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@781 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
3.0
Xuefer 11 years ago
parent
commit
90ccdadc54
  1. 47
      Decompiler.class.php
  2. 6
      decompilesample.php
  3. 29
      xcache.c

47
Decompiler.class.php

@ -1140,15 +1140,22 @@ class Decompiler
unset($dim);
break;
}
$resvar = "$lvalue = " . str($rvalue, $EX);
if (0) {
if ($op2['op_type'] == XC_IS_VAR) {
$resvar .= ' /* isvar */';
}
else if ($op2['op_type'] == XC_IS_TMP_VAR) {
$resvar .= ' /* istmp */';
}
if (is_a($rvalue, 'Decompiler_Fetch')) {
$src = str($rvalue->src, $EX);
if ('$' . unquoteName($src) == $lvalue) {
switch ($rvalue->fetchType) {
case ZEND_FETCH_STATIC:
$statics = &$EX['op_array']['static_variables'];
if ((xcache_get_type($statics[$name]) & IS_LEXICAL_VAR)) {
$EX['uses'][] = str($lvalue);
unset($statics);
break 2;
}
unset($statics);
}
}
}
$resvar = "$lvalue = " . str($rvalue, $EX);
break;
// }}}
case XC_ASSIGN_REF: // {{{
@ -1164,6 +1171,12 @@ class Decompiler
break 2;
case ZEND_FETCH_STATIC:
$statics = &$EX['op_array']['static_variables'];
if ((xcache_get_type($statics[$name]) & IS_LEXICAL_REF)) {
$EX['uses'][] = '&' . str($lvalue);
unset($statics);
break 2;
}
$resvar = 'static ' . $lvalue;
$name = unquoteName($src);
if (isset($statics[$name])) {
@ -1853,15 +1866,9 @@ class Decompiler
// }}}
function duses(&$EX, $indent) // {{{
{
if (!$EX['uses']) {
return;
}
$uses = array();
foreach ($EX['uses'] as $name => $value) {
$uses = '$' . $name;
if ($EX['uses']) {
echo ' use(', implode(', ', $EX['uses']), ')';
}
echo ' use(', implode(', ', $uses), ')';
}
// }}}
function dfunction($func, $indent = '', $nobody = false) // {{{
@ -1885,7 +1892,7 @@ class Decompiler
if ($functionName == '{closure}') {
$functionName = '';
}
echo 'function ', $functionName, '(';
echo 'function', $functionName ? ' ' . $functionName : '', '(';
$this->dargs($EX, $indent);
echo ")";
$this->duses($EX, $indent);
@ -2256,6 +2263,12 @@ define('IS_STRING', ZEND_ENGINE_2 ? 6 : 3);
define('IS_RESOURCE', 7);
define('IS_CONSTANT', 8);
define('IS_CONSTANT_ARRAY', 9);
/* Ugly hack to support constants as static array indices */
define('IS_CONSTANT_TYPE_MASK', 0x0f);
define('IS_CONSTANT_UNQUALIFIED', 0x10);
define('IS_CONSTANT_INDEX', 0x80);
define('IS_LEXICAL_VAR', 0x20);
define('IS_LEXICAL_REF', 0x40);
@define('XC_IS_CV', 16);

6
decompilesample.php

@ -359,8 +359,10 @@ $greet('World');
$greet('PHP');
$total = 0;
$tax = 1;
$callback = function ($quantity, $product) use ($tax, &$total) {
static $static = array(1);
$callback = function($quantity, $product) use($tax, &$total) {
$tax = 'tax';
static $static1 = array(1);
static $static2;
$tax = 'tax';
$tax = --$tax;
$pricePerItem = constant('PRICE_' . strtoupper($product));

29
xcache.c

@ -2875,7 +2875,7 @@ PHP_FUNCTION(xcache_dec)
}
/* }}} */
/* {{{ proto int xcache_get_refcount(mixed variable)
Get reference count of variable */
XCache internal uses only: Get reference count of variable */
PHP_FUNCTION(xcache_get_refcount)
{
zval *variable;
@ -2887,7 +2887,11 @@ PHP_FUNCTION(xcache_get_refcount)
}
/* }}} */
/* {{{ proto bool xcache_get_isref(mixed variable)
check if variable data is marked referenced */
XCache internal uses only: Check if variable data is marked referenced */
ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_get_isref, 0, 0, 1)
ZEND_ARG_INFO(1, variable)
ZEND_END_ARG_INFO()
PHP_FUNCTION(xcache_get_isref)
{
zval *variable;
@ -2895,7 +2899,7 @@ PHP_FUNCTION(xcache_get_isref)
RETURN_NULL();
}
RETURN_BOOL(Z_ISREF_P(variable));
RETURN_BOOL(Z_ISREF_P(variable) && Z_REFCOUNT_P(variable) >= 3);
}
/* }}} */
#ifdef HAVE_XCACHE_DPRINT
@ -3046,7 +3050,8 @@ PHP_FUNCTION(xcache_get_opcode_spec)
}
/* }}} */
#endif
/* {{{ proto mixed xcache_get_special_value(zval value) */
/* {{{ proto mixed xcache_get_special_value(zval value)
XCache internal use only: For decompiler to get static value with type fixed */
PHP_FUNCTION(xcache_get_special_value)
{
zval *value;
@ -3073,6 +3078,19 @@ PHP_FUNCTION(xcache_get_special_value)
}
}
/* }}} */
/* {{{ proto int xcache_get_type(zval value)
XCache internal use only for disassembler to get variable type in engine level */
PHP_FUNCTION(xcache_get_type)
{
zval *value;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
return;
}
RETURN_LONG(Z_TYPE_P(value));
}
/* }}} */
/* {{{ proto string xcache_coredump(int op_type) */
PHP_FUNCTION(xcache_coredump)
{
@ -3125,6 +3143,7 @@ static zend_function_entry xcache_functions[] = /* {{{ */
PHP_FE(xcache_coverager_get, NULL)
#endif
PHP_FE(xcache_get_special_value, NULL)
PHP_FE(xcache_get_type, NULL)
PHP_FE(xcache_get_op_type, NULL)
PHP_FE(xcache_get_data_type, NULL)
PHP_FE(xcache_get_opcode, NULL)
@ -3140,7 +3159,7 @@ static zend_function_entry xcache_functions[] = /* {{{ */
PHP_FE(xcache_unset, NULL)
PHP_FE(xcache_unset_by_prefix, NULL)
PHP_FE(xcache_get_refcount, NULL)
PHP_FE(xcache_get_isref, NULL)
PHP_FE(xcache_get_isref, arginfo_xcache_get_isref)
#ifdef HAVE_XCACHE_DPRINT
PHP_FE(xcache_dprint, NULL)
#endif

Loading…
Cancel
Save