Index: unk/Decompiler.class.php
===================================================================
--- /trunk/Decompiler.class.php	(revision 981)
+++ 	(revision )
@@ -1,2817 +1,0 @@
-<?php
-
-define('INDENT', "\t");
-ini_set('error_reporting', E_ALL);
-
-function color($str, $color = 33)
-{
-	return "\x1B[{$color}m$str\x1B[0m";
-}
-
-function str($code, $indent = '') // {{{
-{
-	if (is_array($code)) {
-		$array = array();
-		foreach ($code as $key => $value) {
-			$array[$key] = str($value, $indent);
-		}
-		return $array;
-	}
-	if (is_object($code)) {
-		$code = foldToCode($code, $indent);
-		return $code->toCode($indent);
-	}
-
-	return (string) $code;
-}
-// }}}
-function foldToCode($src, $indent = '') // {{{ wrap or rewrap anything to Decompiler_Code
-{
-	if (is_array($indent)) {
-		$indent = $indent['indent'];
-	}
-
-	if (!is_object($src)) {
-		return new Decompiler_Code($src);
-	}
-
-	if (!method_exists($src, 'toCode')) {
-		var_dump($src);
-		exit('no toCode');
-	}
-	if (get_class($src) != 'Decompiler_Code') {
-		// rewrap it
-		$src = new Decompiler_Code($src->toCode($indent));
-	}
-
-	return $src;
-}
-// }}}
-function value($value) // {{{
-{
-	$spec = xcache_get_special_value($value);
-	if (isset($spec)) {
-		$value = $spec;
-		if (!is_array($value)) {
-			// constant
-			return $value;
-		}
-	}
-
-	if (is_a($value, 'Decompiler_Object')) {
-		// use as is
-	}
-	else if (is_array($value)) {
-		$value = new Decompiler_ConstArray($value);
-	}
-	else {
-		$value = new Decompiler_Value($value);
-	}
-	return $value;
-}
-// }}}
-function unquoteName_($str, $asVariableName, $indent = '') // {{{
-{
-	$str = str($str, $indent);
-	if (preg_match("!^'[\\w_][\\w\\d_\\\\]*'\$!", $str)) {
-		return str_replace('\\\\', '\\', substr($str, 1, -1));
-	}
-	else if ($asVariableName) {
-		return "{" . $str . "}";
-	}
-	else {
-		return $str;
-	}
-}
-// }}}
-function unquoteVariableName($str, $indent = '') // {{{
-{
-	return unquoteName_($str, true, $indent);
-}
-// }}}
-function unquoteName($str, $indent = '') // {{{
-{
-	return unquoteName_($str, false, $indent);
-}
-// }}}
-class Decompiler_Object // {{{
-{
-}
-// }}}
-class Decompiler_Value extends Decompiler_Object // {{{
-{
-	var $value;
-
-	function Decompiler_Value($value = null)
-	{
-		$this->value = $value;
-	}
-
-	function toCode($indent)
-	{
-		$code = var_export($this->value, true);
-		if (gettype($this->value) == 'string') {
-			switch ($this->value) {
-			case "\r":
-				return '"\\r"';
-			case "\n":
-				return '"\\n"';
-			case "\r\n":
-				return '"\\r\\n"';
-			}
-			$code = str_replace("\r\n", '\' . "\\r\\n" . \'', $code);
-			$code = str_replace("\r", '\' . "\\r" . \'', $code);
-			$code = str_replace("\n", '\' . "\\n" . \'', $code);
-		}
-		return $code;
-	}
-}
-// }}}
-class Decompiler_Code extends Decompiler_Object // {{{
-{
-	var $src;
-
-	function Decompiler_Code($src)
-	{
-		assert('isset($src)');
-		$this->src = $src;
-	}
-
-	function toCode($indent)
-	{
-		return $this->src;
-	}
-}
-// }}}
-class Decompiler_Binop extends Decompiler_Code // {{{
-{
-	var $opc;
-	var $op1;
-	var $op2;
-	var $parent;
-
-	function Decompiler_Binop($parent, $op1, $opc, $op2)
-	{
-		$this->parent = &$parent;
-		$this->opc = $opc;
-		$this->op1 = $op1;
-		$this->op2 = $op2;
-	}
-
-	function toCode($indent)
-	{
-		$opstr = $this->parent->binops[$this->opc];
-
-		if (is_a($this->op1, 'Decompiler_TriOp') || is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) {
-			$op1 = "(" . str($this->op1, $indent) . ")";
-		}
-		else {
-			$op1 = $this->op1;
-		}
-
-		if (is_a($this->op2, 'Decompiler_TriOp') || is_a($this->op2, 'Decompiler_Binop') && $this->op2->opc != $this->opc && substr($opstr, -1) != '=') {
-			$op2 = "(" . str($this->op2, $indent) . ")";
-		}
-		else {
-			$op2 = $this->op2;
-		}
-
-		if (str($op1) == '0' && ($this->opc == XC_ADD || $this->opc == XC_SUB)) {
-			return $opstr . str($op2, $indent);
-		}
-
-		return str($op1, $indent) . ' ' . $opstr . ($this->opc == XC_ASSIGN_REF ? '' : ' ') . str($op2, $indent);
-	}
-}
-// }}}
-class Decompiler_TriOp extends Decompiler_Code // {{{
-{
-	var $condition;
-	var $trueValue;
-	var $falseValue;
-
-	function Decompiler_TriOp($condition, $trueValue, $falseValue)
-	{
-		$this->condition = $condition;
-		$this->trueValue = $trueValue;
-		$this->falseValue = $falseValue;
-	}
-
-	function toCode($indent)
-	{
-		$trueValue = $this->trueValue;
-		if (is_a($this->trueValue, 'Decompiler_TriOp')) {
-			$trueValue = "(" . str($trueValue, $indent) . ")";
-		}
-		$falseValue = $this->falseValue;
-		if (is_a($this->falseValue, 'Decompiler_TriOp')) {
-			$falseValue = "(" . str($falseValue, $indent) . ")";
-		}
-
-		return str($this->condition) . ' ? ' . str($trueValue) . ' : ' . str($falseValue);
-	}
-}
-// }}}
-class Decompiler_Fetch extends Decompiler_Code // {{{
-{
-	var $src;
-	var $fetchType;
-
-	function Decompiler_Fetch($src, $type, $globalsrc)
-	{
-		$this->src = $src;
-		$this->fetchType = $type;
-		$this->globalsrc = $globalsrc;
-	}
-
-	function toCode($indent)
-	{
-		switch ($this->fetchType) {
-		case ZEND_FETCH_LOCAL:
-			return '$' . substr($this->src, 1, -1);
-		case ZEND_FETCH_STATIC:
-			if (ZEND_ENGINE_2_3) {
-				// closure local variable?
-				return str($this->src);
-			}
-			die('static fetch cant to string');
-		case ZEND_FETCH_GLOBAL:
-		case ZEND_FETCH_GLOBAL_LOCK:
-			return $this->globalsrc;
-		default:
-			var_dump($this->fetchType);
-			assert(0);
-		}
-	}
-}
-// }}}
-class Decompiler_Box // {{{
-{
-	var $obj;
-
-	function Decompiler_Box(&$obj)
-	{
-		$this->obj = &$obj;
-	}
-
-	function toCode($indent)
-	{
-		return $this->obj->toCode($indent);
-	}
-}
-// }}}
-class Decompiler_Dim extends Decompiler_Value // {{{
-{
-	var $offsets = array();
-	var $isLast = false;
-	var $isObject = false;
-	var $assign = null;
-
-	function toCode($indent)
-	{
-		if (is_a($this->value, 'Decompiler_ListBox')) {
-			$exp = str($this->value->obj->src, $indent);
-		}
-		else {
-			$exp = str($this->value, $indent);
-		}
-		$last = count($this->offsets) - 1;
-		foreach ($this->offsets as $i => $dim) {
-			if ($this->isObject && $i == $last) {
-				$exp .= '->' . unquoteVariableName($dim, $indent);
-			}
-			else {
-				$exp .= '[' . str($dim, $indent) . ']';
-			}
-		}
-		return $exp;
-	}
-}
-// }}}
-class Decompiler_DimBox extends Decompiler_Box // {{{
-{
-}
-// }}}
-class Decompiler_List extends Decompiler_Code // {{{
-{
-	var $src;
-	var $dims = array();
-	var $everLocked = false;
-
-	function toCode($indent)
-	{
-		if (count($this->dims) == 1 && !$this->everLocked) {
-			$dim = $this->dims[0];
-			unset($dim->value);
-			$dim->value = $this->src;
-			if (!isset($dim->assign)) {
-				return str($dim, $indent);
-			}
-			return str($this->dims[0]->assign, $indent) . ' = ' . str($dim, $indent);
-		}
-		/* flatten dims */
-		$assigns = array();
-		foreach ($this->dims as $dim) {
-			$assign = &$assigns;
-			foreach ($dim->offsets as $offset) {
-				$assign = &$assign[$offset];
-			}
-			$assign = foldToCode($dim->assign, $indent);
-		}
-		return str($this->toList($assigns)) . ' = ' . str($this->src, $indent);
-	}
-
-	function toList($assigns)
-	{
-		$keys = array_keys($assigns);
-		if (count($keys) < 2) {
-			$keys[] = 0;
-		}
-		$max = call_user_func_array('max', $keys);
-		$list = 'list(';
-		for ($i = 0; $i <= $max; $i ++) {
-			if ($i) {
-				$list .= ', ';
-			}
-			if (!isset($assigns[$i])) {
-				continue;
-			}
-			if (is_array($assigns[$i])) {
-				$list .= $this->toList($assigns[$i]);
-			}
-			else {
-				$list .= $assigns[$i];
-			}
-		}
-		return $list . ')';
-	}
-}
-// }}}
-class Decompiler_ListBox extends Decompiler_Box // {{{
-{
-}
-// }}}
-class Decompiler_Array extends Decompiler_Value // {{{
-{
-	// emenets
-	function Decompiler_Array()
-	{
-		$this->value = array();
-	}
-
-	function toCode($indent)
-	{
-		$subindent = $indent . INDENT;
-
-		$elementsCode = array();
-		$index = 0;
-		foreach ($this->value as $element) {
-			list($key, $value) = $element;
-			if (!isset($key)) {
-				$key = $index++;
-			}
-			$elementsCode[] = array(str($key, $subindent), str($value, $subindent), $key, $value);
-		}
-
-		$exp = "array(";
-		$indent = $indent . INDENT;
-		$assocWidth = 0;
-		$multiline = 0;
-		$i = 0;
-		foreach ($elementsCode as $element) {
-			list($keyCode, $valueCode) = $element;
-			if ((string) $i !== $keyCode) {
-				$assocWidth = 1;
-				break;
-			}
-			++$i;
-		}
-		foreach ($elementsCode as $element) {
-			list($keyCode, $valueCode, $key, $value) = $element;
-			if ($assocWidth) {
-				$len = strlen($keyCode);
-				if ($assocWidth < $len) {
-					$assocWidth = $len;
-				}
-			}
-			if (is_array($value) || is_a($value, 'Decompiler_Array')) {
-				$multiline ++;
-			}
-		}
-
-		$i = 0;
-		foreach ($elementsCode as $element) {
-			list($keyCode, $value) = $element;
-			if ($multiline) {
-				if ($i) {
-					$exp .= ",";
-				}
-				$exp .= "\n";
-				$exp .= $indent;
-			}
-			else {
-				if ($i) {
-					$exp .= ", ";
-				}
-			}
-
-			if ($assocWidth) {
-				if ($multiline) {
-					$exp .= sprintf("%-{$assocWidth}s => ", $keyCode);
-				}
-				else {
-					$exp .= $keyCode . ' => ';
-				}
-			}
-
-			$exp .= $value;
-
-			$i ++;
-		}
-		if ($multiline) {
-			$exp .= "\n$indent)";
-		}
-		else {
-			$exp .= ")";
-		}
-		return $exp;
-	}
-}
-// }}}
-class Decompiler_ConstArray extends Decompiler_Array // {{{
-{
-	function Decompiler_ConstArray($array)
-	{
-		$elements = array();
-		foreach ($array as $key => $value) {
-			$elements[] = array(value($key), value($value));
-		}
-		$this->value = $elements;
-	}
-}
-// }}}
-class Decompiler_ForeachBox extends Decompiler_Box // {{{
-{
-	var $iskey;
-
-	function toCode($indent)
-	{
-		return 'foreach (' . '';
-	}
-}
-// }}}
-
-class Decompiler
-{
-	var $namespace;
-	var $namespaceDecided;
-
-	function Decompiler()
-	{
-		// {{{ testing
-		// XC_UNDEF XC_OP_DATA
-		$this->test = !empty($_ENV['XCACHE_DECOMPILER_TEST']);
-		$this->usedOps = array();
-
-		if ($this->test) {
-			$content = file_get_contents(__FILE__);
-			for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
-				if (!preg_match("/\\bXC_" . $opname . "\\b(?!')/", $content)) {
-					echo "not recognized opcode ", $opname, "\n";
-				}
-			}
-		}
-		// }}}
-		// {{{ opinfo
-		$this->unaryops = array(
-				XC_BW_NOT   => '~',
-				XC_BOOL_NOT => '!',
-				);
-		$this->binops = array(
-				XC_ADD                 => "+",
-				XC_ASSIGN_ADD          => "+=",
-				XC_SUB                 => "-",
-				XC_ASSIGN_SUB          => "-=",
-				XC_MUL                 => "*",
-				XC_ASSIGN_MUL          => "*=",
-				XC_DIV                 => "/",
-				XC_ASSIGN_DIV          => "/=",
-				XC_MOD                 => "%",
-				XC_ASSIGN_MOD          => "%=",
-				XC_SL                  => "<<",
-				XC_ASSIGN_SL           => "<<=",
-				XC_SR                  => ">>",
-				XC_ASSIGN_SR           => ">>=",
-				XC_CONCAT              => ".",
-				XC_ASSIGN_CONCAT       => ".=",
-				XC_IS_IDENTICAL        => "===",
-				XC_IS_NOT_IDENTICAL    => "!==",
-				XC_IS_EQUAL            => "==",
-				XC_IS_NOT_EQUAL        => "!=",
-				XC_IS_SMALLER          => "<",
-				XC_IS_SMALLER_OR_EQUAL => "<=",
-				XC_BW_OR               => "|",
-				XC_ASSIGN_BW_OR        => "|=",
-				XC_BW_AND              => "&",
-				XC_ASSIGN_BW_AND       => "&=",
-				XC_BW_XOR              => "^",
-				XC_ASSIGN_BW_XOR       => "^=",
-				XC_BOOL_XOR            => "xor",
-				XC_ASSIGN              => "=",
-				XC_ASSIGN_REF          => "= &",
-				XC_JMP_SET             => "?:",
-				XC_JMPZ_EX             => "&&",
-				XC_JMPNZ_EX            => "||",
-				);
-		// }}}
-		$this->includeTypes = array( // {{{
-				ZEND_EVAL         => 'eval',
-				ZEND_INCLUDE      => 'include',
-				ZEND_INCLUDE_ONCE => 'include_once',
-				ZEND_REQUIRE      => 'require',
-				ZEND_REQUIRE_ONCE => 'require_once',
-				);
-				// }}}
-	}
-	function detectNamespace($name) // {{{
-	{
-		if ($this->namespaceDecided) {
-			return;
-		}
-
-		if (strpos($name, '\\') !== false) {
-			$this->namespace = strtok($name, '\\');
-			echo 'namespace ', $this->namespace, ";\n\n";
-		}
-
-		$this->namespaceDecided = true;
-	}
-	// }}}
-	function stripNamespace($name) // {{{
-	{
-		$len = strlen($this->namespace) + 1;
-		if (substr($name, 0, $len) == $this->namespace . '\\') {
-			return substr($name, $len);
-		}
-		else {
-			return $name;
-		}
-	}
-	// }}}
-	function outputPhp(&$EX, $range) // {{{
-	{
-		$needBlankline = isset($EX['lastBlock']);
-		$indent = $EX['indent'];
-		$curticks = 0;
-		for ($i = $range[0]; $i <= $range[1]; $i ++) {
-			$op = $EX['opcodes'][$i];
-			if (isset($op['gofrom'])) {
-				if ($needBlankline) {
-					$needBlankline = false;
-					echo PHP_EOL;
-				}
-				echo 'label' . $i, ":\n";
-			}
-			if (isset($op['php'])) {
-				$toticks = isset($op['ticks']) ? (int) str($op['ticks']) : 0;
-				if ($curticks != $toticks) {
-					$oldticks = $curticks;
-					$curticks = $toticks;
-					if (!$curticks) {
-						echo $EX['indent'], "}\n\n";
-						$indent = $EX['indent'];
-					}
-					else {
-						if ($oldticks) {
-							echo $EX['indent'], "}\n\n";
-						}
-						else if (!$oldticks) {
-							$indent .= INDENT;
-						}
-						if ($needBlankline) {
-							$needBlankline = false;
-							echo PHP_EOL;
-						}
-						echo $EX['indent'], "declare (ticks=$curticks) {\n";
-					}
-				}
-				if ($needBlankline) {
-					$needBlankline = false;
-					echo PHP_EOL;
-				}
-				echo $indent, str($op['php'], $indent), ";\n";
-				$EX['lastBlock'] = 'basic';
-			}
-		}
-		if ($curticks) {
-			echo $EX['indent'], "}\n";
-		}
-	}
-	// }}}
-	function getOpVal($op, &$EX, $free = false) // {{{
-	{
-		switch ($op['op_type']) {
-		case XC_IS_CONST:
-			return value($op['constant']);
-
-		case XC_IS_VAR:
-		case XC_IS_TMP_VAR:
-			$T = &$EX['Ts'];
-			$ret = $T[$op['var']];
-			if ($free && empty($this->keepTs)) {
-				unset($T[$op['var']]);
-			}
-			return $ret;
-
-		case XC_IS_CV:
-			$var = $op['var'];
-			$var = $EX['op_array']['vars'][$var];
-			return '$' . $var['name'];
-
-		case XC_IS_UNUSED:
-			return null;
-		}
-	}
-	// }}}
-	function removeKeyPrefix($array, $prefix) // {{{
-	{
-		$prefixLen = strlen($prefix);
-		$ret = array();
-		foreach ($array as $key => $value) {
-			if (substr($key, 0, $prefixLen) == $prefix) {
-				$key = substr($key, $prefixLen);
-			}
-			$ret[$key] = $value;
-		}
-		return $ret;
-	}
-	// }}}
-	function &fixOpcode($opcodes, $removeTailing = false, $defaultReturnValue = null) // {{{
-	{
-		$last = count($opcodes) - 1;
-		for ($i = 0; $i <= $last; $i ++) {
-			if (function_exists('xcache_get_fixed_opcode')) {
-				$opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i);
-			}
-			if (isset($opcodes[$i]['op1'])) {
-				$opcodes[$i]['op1'] = $this->removeKeyPrefix($opcodes[$i]['op1'], 'u.');
-				$opcodes[$i]['op2'] = $this->removeKeyPrefix($opcodes[$i]['op2'], 'u.');
-				$opcodes[$i]['result'] = $this->removeKeyPrefix($opcodes[$i]['result'], 'u.');
-			}
-			else {
-				$op = array(
-					'op1' => array(),
-					'op2' => array(),
-					'op3' => array(),
-				);
-				foreach ($opcodes[$i] as $name => $value) {
-					if (preg_match('!^(op1|op2|result)\\.(.*)!', $name, $m)) {
-						list(, $which, $field) = $m;
-						$op[$which][$field] = $value;
-					}
-					else if (preg_match('!^(op1|op2|result)_type$!', $name, $m)) {
-						list(, $which) = $m;
-						$op[$which]['op_type'] = $value;
-					}
-					else {
-						$op[$name] = $value;
-					}
-				}
-				$opcodes[$i] = $op;
-			}
-		}
-
-		if ($removeTailing) {
-			$last = count($opcodes) - 1;
-			if ($opcodes[$last]['opcode'] == XC_HANDLE_EXCEPTION) {
-				$this->usedOps[XC_HANDLE_EXCEPTION] = true;
-				$opcodes[$last]['opcode'] = XC_NOP;
-				--$last;
-			}
-			if ($opcodes[$last]['opcode'] == XC_RETURN) {
-				$op1 = $opcodes[$last]['op1'];
-				if ($op1['op_type'] == XC_IS_CONST && array_key_exists('constant', $op1) && $op1['constant'] === $defaultReturnValue) {
-					$opcodes[$last]['opcode'] = XC_NOP;
-					--$last;
-				}
-			}
-		}
-		return $opcodes;
-	}
-	// }}}
-	function decompileBasicBlock(&$EX, $range, $unhandled = false) // {{{
-	{
-		$this->dasmBasicBlock($EX, $range);
-		if ($unhandled) {
-			$this->dumpRange($EX, $range);
-		}
-		$this->outputPhp($EX, $range);
-	}
-	// }}}
-	function isIfCondition(&$EX, $range) // {{{
-	{
-		$opcodes = &$EX['opcodes'];
-		$firstOp = &$opcodes[$range[0]];
-		return $firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP
-		 && !empty($opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'])
-		 && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1;
-	}
-	// }}}
-	function removeJmpInfo(&$EX, $line) // {{{
-	{
-		$opcodes = &$EX['opcodes'];
-		foreach ($opcodes[$line]['jmpouts'] as $jmpTo) {
-			$jmpins = &$opcodes[$jmpTo]['jmpins'];
-			$jmpins = array_flip($jmpins);
-			unset($jmpins[$line]);
-			$jmpins = array_keys($jmpins);
-		}
-		// $opcodes[$line]['opcode'] = XC_NOP;
-		unset($opcodes[$line]['jmpouts']);
-	}
-	// }}}
-	function beginScope(&$EX, $doIndent = true) // {{{
-	{
-		array_push($EX['scopeStack'], array($EX['lastBlock'], $EX['indent']));
-		if ($doIndent) {
-			$EX['indent'] .= INDENT;
-		}
-		$EX['lastBlock'] = null;
-	}
-	// }}}
-	function endScope(&$EX) // {{{
-	{
-		list($EX['lastBlock'], $EX['indent']) = array_pop($EX['scopeStack']);
-	}
-	// }}}
-	function beginComplexBlock(&$EX) // {{{
-	{
-		if (isset($EX['lastBlock'])) {
-			echo PHP_EOL;
-			$EX['lastBlock'] = null;
-		}
-	}
-	// }}}
-	function endComplexBlock(&$EX) // {{{
-	{
-		$EX['lastBlock'] = 'complex';
-	}
-	// }}}
-	function decompileComplexBlock(&$EX, $range) // {{{
-	{
-		$T = &$EX['Ts'];
-		$opcodes = &$EX['opcodes'];
-		$indent = $EX['indent'];
-
-		$firstOp = &$opcodes[$range[0]];
-		$lastOp = &$opcodes[$range[1]];
-
-		// {{{ && || and or
-		if (($firstOp['opcode'] == XC_JMPZ_EX || $firstOp['opcode'] == XC_JMPNZ_EX) && !empty($firstOp['jmpouts'])
-		 && $firstOp['jmpouts'][0] == $range[1] + 1
-		 && $lastOp['opcode'] == XC_BOOL
-		 && $firstOp['opcode']['result']['var'] == $lastOp['opcode']['result']['var']
-		) {
-			$this->removeJmpInfo($EX, $range[0]);
-
-			$this->recognizeAndDecompileClosedBlocks($EX, array($range[0], $range[0]));
-			$op1 = $this->getOpVal($firstOp['result'], $EX, true);
-
-			$this->recognizeAndDecompileClosedBlocks($EX, array($range[0] + 1, $range[1]));
-			$op2 = $this->getOpVal($lastOp['result'], $EX, true);
-
-			$T[$firstOp['result']['var']] = new Decompiler_Binop($this, $op1, $firstOp['opcode'], $op2);
-			return false;
-		}
-		// }}}
-		// {{{ ?: excluding JMP_SET
-		if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts'])
-		 && $range[1] >= $range[0] + 3
-		 && $opcodes[$firstOp['jmpouts'][0] - 2]['opcode'] == XC_QM_ASSIGN
-		 && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1
-		 && $lastOp['opcode'] == XC_QM_ASSIGN
-		) {
-			$trueRange = array($range[0] + 1, $firstOp['jmpouts'][0] - 2);
-			$falseRange = array($firstOp['jmpouts'][0], $range[1]);
-			$this->removeJmpInfo($EX, $range[0]);
-
-			$condition = $this->getOpVal($firstOp['op1'], $EX);
-			$this->recognizeAndDecompileClosedBlocks($EX, $trueRange);
-			$trueValue = $this->getOpVal($opcodes[$trueRange[1]]['result'], $EX, true);
-			$this->recognizeAndDecompileClosedBlocks($EX, $falseRange);
-			$falseValue = $this->getOpVal($opcodes[$falseRange[1]]['result'], $EX, true);
-			$T[$opcodes[$trueRange[1]]['result']['var']] = new Decompiler_TriOp($condition, $trueValue, $falseValue);
-			return false;
-		}
-		// }}}
-		// {{{ goto
-		if ($firstOp['opcode'] == XC_JMP && !empty($firstOp['jmpouts']) && $firstOp['jmpouts'][0] == $range[1] + 1) {
-			$this->removeJmpInfo($EX, $range[0]);
-			$firstOp['opcode'] = XC_GOTO;
-			$target = $firstOp['op1']['var'];
-			$firstOp['goto'] = $target;
-			$opcodes[$target]['gofrom'][] = $range[0];
-
-			$this->recognizeAndDecompileClosedBlocks($EX, $range);
-			return false;
-		}
-		// }}}
-		// {{{ for
-		if (!empty($firstOp['jmpins']) && $opcodes[$firstOp['jmpins'][0]]['opcode'] == XC_JMP
-		 && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts']) && $lastOp['jmpouts'][0] <= $firstOp['jmpins'][0]
-		 && !empty($opcodes[$range[1] + 1]['jmpins']) && $opcodes[$opcodes[$range[1] + 1]['jmpins'][0]]['opcode'] == XC_JMPZNZ
-		) {
-			$nextRange = array($lastOp['jmpouts'][0], $firstOp['jmpins'][0]);
-			$conditionRange = array($range[0], $nextRange[0] - 1);
-			$this->removeJmpInfo($EX, $conditionRange[1]);
-			$bodyRange = array($nextRange[1], $range[1]);
-			$this->removeJmpInfo($EX, $bodyRange[1]);
-
-			$initial = '';
-			$this->beginScope($EX);
-			$this->dasmBasicBlock($EX, $conditionRange);
-			$conditionCodes = array();
-			for ($i = $conditionRange[0]; $i <= $conditionRange[1]; ++$i) {
-				if (isset($opcodes[$i]['php'])) {
-					$conditionCodes[] = str($opcodes[$i]['php'], $EX);
-				}
-			}
-			$conditionCodes[] = str($this->getOpVal($opcodes[$conditionRange[1]]['op1'], $EX), $EX);
-			if (implode(',', $conditionCodes) == 'true') {
-				$conditionCodes = array();
-			}
-			$this->endScope($EX);
-
-			$this->beginScope($EX);
-			$this->dasmBasicBlock($EX, $nextRange);
-			$nextCodes = array();
-			for ($i = $nextRange[0]; $i <= $nextRange[1]; ++$i) {
-				if (isset($opcodes[$i]['php'])) {
-					$nextCodes[] = str($opcodes[$i]['php'], $EX);
-				}
-			}
-			$this->endScope($EX);
-
-			$this->beginComplexBlock($EX);
-			echo $indent, 'for (', str($initial, $EX), '; ', implode(', ', $conditionCodes), '; ', implode(', ', $nextCodes), ') ', '{', PHP_EOL;
-			$this->beginScope($EX);
-			$this->recognizeAndDecompileClosedBlocks($EX, $bodyRange);
-			$this->endScope($EX);
-			echo $indent, '}', PHP_EOL;
-			$this->endComplexBlock($EX);
-			return;
-		}
-		// }}}
-		// {{{ if/elseif/else
-		if ($this->isIfCondition($EX, $range)) {
-			$this->beginComplexBlock($EX);
-			$isElseIf = false;
-			do {
-				$ifRange = array($range[0], $opcodes[$range[0]]['jmpouts'][0] - 1);
-				$this->removeJmpInfo($EX, $ifRange[0]);
-				$this->removeJmpInfo($EX, $ifRange[1]);
-				$condition = $this->getOpVal($opcodes[$ifRange[0]]['op1'], $EX);
-
-				echo $indent, $isElseIf ? 'else if' : 'if', ' (', str($condition, $EX), ') ', '{', PHP_EOL;
-				$this->beginScope($EX);
-				$this->recognizeAndDecompileClosedBlocks($EX, $ifRange);
-				$this->endScope($EX);
-				$EX['lastBlock'] = null;
-				echo $indent, '}', PHP_EOL;
-
-				$isElseIf = true;
-				// search for else if
-				$range[0] = $ifRange[1] + 1;
-				for ($i = $ifRange[1] + 1; $i <= $range[1]; ++$i) {
-					// find first jmpout
-					if (!empty($opcodes[$i]['jmpouts'])) {
-						if ($this->isIfCondition($EX, array($i, $range[1]))) {
-							$this->dasmBasicBlock($EX, array($range[0], $i));
-							$range[0] = $i;
-						}
-						break;
-					}
-				}
-			} while ($this->isIfCondition($EX, $range));
-			if ($ifRange[1] < $range[1]) {
-				$elseRange = array($ifRange[1], $range[1]);
-				echo $indent, 'else ', '{', PHP_EOL;
-				$this->beginScope($EX);
-				$this->recognizeAndDecompileClosedBlocks($EX, $elseRange);
-				$this->endScope($EX);
-				$EX['lastBlock'] = null;
-				echo $indent, '}', PHP_EOL;
-			}
-			$this->endComplexBlock($EX);
-			return;
-		}
-		if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts'])
-		 && $firstOp['jmpouts'][0] - 1 == $range[1] && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_RETURN) {
-			$this->beginComplexBlock($EX);
-			$this->removeJmpInfo($EX, $range[0]);
-			$condition = $this->getOpVal($opcodes[$range[0]]['op1'], $EX);
-
-			echo $indent, 'if (', str($condition, $EX), ') ', '{', PHP_EOL;
-			$this->beginScope($EX);
-			$this->recognizeAndDecompileClosedBlocks($EX, $range);
-			$this->endScope($EX);
-			echo $indent, '}', PHP_EOL;
-			$this->endComplexBlock($EX);
-			return;
-		}
-		// }}}
-		// {{{ try/catch
-		if (!empty($firstOp['jmpins']) && !empty($opcodes[$firstOp['jmpins'][0]]['isCatchBegin'])) {
-			$catchBlocks = array();
-			$catchFirst = $firstOp['jmpins'][0];
-
-			$tryRange = array($range[0], $catchFirst - 1);
-
-			// search for XC_CATCH
-			$this->removeJmpInfo($EX, $catchFirst);
-			for ($i = $catchFirst; $i <= $range[1]; ) {
-				if ($opcodes[$i]['opcode'] == XC_CATCH) {
-					$catchOpLine = $i;
-					$this->removeJmpInfo($EX, $catchOpLine);
-
-					$catchNext = $opcodes[$catchOpLine]['extended_value'];
-					$catchBodyLast = $catchNext - 1;
-					if ($opcodes[$catchBodyLast]['opcode'] == XC_JMP) {
-						--$catchBodyLast;
-					}
-
-					$catchBlocks[$catchFirst] = array($catchOpLine, $catchBodyLast);
-
-					$i = $catchFirst = $catchNext;
-				}
-				else {
-					++$i;
-				}
-			}
-
-			if ($opcodes[$tryRange[1]]['opcode'] == XC_JMP) {
-				--$tryRange[1];
-			}
-
-			$this->beginComplexBlock($EX);
-			echo $indent, "try {", PHP_EOL;
-			$this->beginScope($EX);
-			$this->recognizeAndDecompileClosedBlocks($EX, $tryRange);
-			$this->endScope($EX);
-			echo $indent, '}', PHP_EOL;
-			foreach ($catchBlocks as $catchFirst => $catchInfo) {
-				list($catchOpLine, $catchBodyLast) = $catchInfo;
-				$catchBodyFirst = $catchOpLine + 1;
-				$this->dasmBasicBlock($EX, array($catchFirst, $catchOpLine));
-				$catchOp = &$opcodes[$catchOpLine];
-				echo $indent, 'catch (', str($this->getOpVal($catchOp['op1'], $EX)), ' ', str($this->getOpVal($catchOp['op2'], $EX)), ") {", PHP_EOL;
-				unset($catchOp);
-
-				$EX['lastBlock'] = null;
-				$this->beginScope($EX);
-				$this->recognizeAndDecompileClosedBlocks($EX, array($catchBodyFirst, $catchBodyLast));
-				$this->endScope($EX);
-				echo $indent, '}', PHP_EOL;
-			}
-			$this->endComplexBlock($EX);
-			return;
-		}
-		// }}}
-		// {{{ switch/case
-		if ($firstOp['opcode'] == XC_SWITCH_FREE && isset($T[$firstOp['op1']['var']])) {
-			// TODO: merge this code to CASE code. use SWITCH_FREE to detect begin of switch by using $Ts if possible
-			$this->beginComplexBlock($EX);
-			echo $indent, 'switch (', str($this->getOpVal($firstOp['op1'], $EX)), ") {", PHP_EOL;
-			echo $indent, '}', PHP_EOL;
-			$this->endComplexBlock($EX);
-			return;
-		}
-
-		if (
-			($firstOp['opcode'] == XC_CASE
-			|| $firstOp['opcode'] == XC_JMP && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0]]['opcode'] == XC_CASE
-			)
-		 	 && !empty($lastOp['jmpouts'])
-		) {
-			$cases = array();
-			$caseDefault = null;
-			$caseOp = null;
-			for ($i = $range[0]; $i <= $range[1]; ) {
-				$op = $opcodes[$i];
-				if ($op['opcode'] == XC_CASE) {
-					if (!isset($caseOp)) {
-						$caseOp = $op;
-					}
-					$jmpz = $opcodes[$i + 1];
-					assert('$jmpz["opcode"] == XC_JMPZ');
-					$caseNext = $jmpz['jmpouts'][0];
-					$cases[$i] = $caseNext - 1;
-					$i = $caseNext;
-				}
-				else if ($op['opcode'] == XC_JMP && $op['jmpouts'][0] >= $i) {
-					// default
-					$caseNext = $op['jmpouts'][0];
-					$caseDefault = $i;
-					$cases[$i] = $caseNext - 1;
-					$i = $caseNext;
-				}
-				else {
-					++$i;
-				}
-			}
-
-			$this->beginComplexBlock($EX);
-
-			echo $indent, 'switch (', str($this->getOpVal($caseOp['op1'], $EX), $EX), ") {", PHP_EOL;
-			$caseIsOut = false;
-			foreach ($cases as $caseFirst => $caseLast) {
-				if ($caseIsOut && empty($lastCaseFall)) {
-					echo PHP_EOL;
-				}
-
-				$caseOp = $opcodes[$caseFirst];
-
-				echo $indent;
-				if ($caseOp['opcode'] == XC_CASE) {
-					echo 'case ';
-					echo str($this->getOpVal($caseOp['op2'], $EX), $EX);
-					echo ':', PHP_EOL;
-
-					$this->removeJmpInfo($EX, $caseFirst);
-					++$caseFirst;
-
-					assert('$opcodes[$caseFirst]["opcode"] == XC_JMPZ');
-					$this->removeJmpInfo($EX, $caseFirst);
-					++$caseFirst;
-				}
-				else {
-					echo 'default';
-					echo ':', PHP_EOL;
-
-					assert('$opcodes[$caseFirst]["opcode"] == XC_JMP');
-					$this->removeJmpInfo($EX, $caseFirst);
-					++$caseFirst;
-				}
-
-				assert('$opcodes[$caseLast]["opcode"] == XC_JMP');
-				$this->removeJmpInfo($EX, $caseLast);
-				--$caseLast;
-				switch ($opcodes[$caseLast]['opcode']) {
-				case XC_BRK:
-				case XC_CONT:
-				case XC_GOTO:
-					$lastCaseFall = false;
-					break;
-
-				default:
-					$lastCaseFall = true;
-				}
-
-				$this->beginScope($EX);
-				$this->recognizeAndDecompileClosedBlocks($EX, array($caseFirst, $caseLast));
-				$this->endScope($EX);
-				$caseIsOut = true;
-			}
-			echo $indent, '}', PHP_EOL;
-
-			$this->endComplexBlock($EX);
-			return;
-		}
-		// }}}
-		// {{{ do/while
-		if ($lastOp['opcode'] == XC_JMPNZ && !empty($lastOp['jmpouts'])
-		 && $lastOp['jmpouts'][0] == $range[0]) {
-			$this->removeJmpInfo($EX, $range[1]);
-			$this->beginComplexBlock($EX);
-
-			echo $indent, "do {", PHP_EOL;
-			$this->beginScope($EX);
-			$this->recognizeAndDecompileClosedBlocks($EX, $range);
-			$this->endScope($EX);
-			echo $indent, "} while (", str($this->getOpVal($lastOp['op1'], $EX)), ');', PHP_EOL;
-
-			$this->endComplexBlock($EX);
-			return;
-		}
-		// }}}
-
-		// {{{ search firstJmpOp
-		$firstJmp = null;
-		$firstJmpOp = null;
-		for ($i = $range[0]; $i <= $range[1]; ++$i) {
-			if (!empty($opcodes[$i]['jmpouts'])) {
-				$firstJmp = $i;
-				$firstJmpOp = &$opcodes[$firstJmp];
-				break;
-			}
-		}
-		// }}}
-
-		// {{{ while
-		if (isset($firstJmpOp)
-		 && $firstJmpOp['opcode'] == XC_JMPZ
-		 && $firstJmpOp['jmpouts'][0] > $range[1]
-		 && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts'])
-		 && $lastOp['jmpouts'][0] == $range[0]) {
-			$this->removeJmpInfo($EX, $firstJmp);
-			$this->removeJmpInfo($EX, $range[1]);
-			$this->beginComplexBlock($EX);
-
-			ob_start();
-			$this->beginScope($EX);
-			$this->recognizeAndDecompileClosedBlocks($EX, $range);
-			$this->endScope($EX);
-			$body = ob_get_clean();
-
-			echo $indent, 'while (', str($this->getOpVal($firstJmpOp['op1'], $EX)), ") {", PHP_EOL;
-			echo $body;
-			echo $indent, '}', PHP_EOL;
-
-			$this->endComplexBlock($EX);
-			return;
-		}
-		// }}}
-		// {{{ foreach
-		if (isset($firstJmpOp)
-		 && $firstJmpOp['opcode'] == XC_FE_FETCH
-		 && $firstJmpOp['jmpouts'][0] > $range[1]
-		 && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts'])
-		 && $lastOp['jmpouts'][0] == $firstJmp) {
-			$this->removeJmpInfo($EX, $firstJmp);
-			$this->removeJmpInfo($EX, $range[1]);
-			$this->beginComplexBlock($EX);
-
-			ob_start();
-			$this->beginScope($EX);
-			$this->recognizeAndDecompileClosedBlocks($EX, $range);
-			$this->endScope($EX);
-			$body = ob_get_clean();
-
-			$as = foldToCode($firstJmpOp['fe_as'], $EX);
-			if (isset($firstJmpOp['fe_key'])) {
-				$as = str($firstJmpOp['fe_key'], $EX) . ' => ' . str($as);
-			}
-
-			echo $indent, 'foreach (', str($firstJmpOp['fe_src'], $EX), " as $as) {", PHP_EOL;
-			echo $body;
-			echo $indent, '}', PHP_EOL;
-
-			$this->endComplexBlock($EX);
-			if ($opcodes[$range[1] + 1]['opcode'] == XC_SWITCH_FREE) {
-				$this->removeJmpInfo($EX, $range[1] + 1);
-			}
-			return;
-		}
-		// }}}
-
-		$this->decompileBasicBlock($EX, $range, true);
-	}
-	// }}}
-	function recognizeAndDecompileClosedBlocks(&$EX, $range) // {{{ decompile in a tree way
-	{
-		$opcodes = &$EX['opcodes'];
-
-		$starti = $range[0];
-		for ($i = $starti; $i <= $range[1]; ) {
-			if (!empty($opcodes[$i]['jmpins']) || !empty($opcodes[$i]['jmpouts'])) {
-				$blockFirst = $i;
-				$blockLast = -1;
-				$j = $blockFirst;
-				do {
-					$op = $opcodes[$j];
-					if (!empty($op['jmpins'])) {
-						// care about jumping from blocks behind, not before
-						foreach ($op['jmpins'] as $oplineNumber) {
-							if ($oplineNumber <= $range[1] && $blockLast < $oplineNumber) {
-								$blockLast = $oplineNumber;
-							}
-						}
-					}
-					if (!empty($op['jmpouts'])) {
-						$blockLast = max($blockLast, max($op['jmpouts']) - 1);
-					}
-					++$j;
-				} while ($j <= $blockLast);
-				if (!assert('$blockLast <= $range[1]')) {
-					var_dump($blockLast, $range[1]);
-				}
-
-				if ($blockLast >= $blockFirst) {
-					if ($blockFirst > $starti) {
-						$this->decompileBasicBlock($EX, array($starti, $blockFirst - 1));
-					}
-					if ($this->decompileComplexBlock($EX, array($blockFirst, $blockLast)) === false) {
-						if ($EX['lastBlock'] == 'complex') {
-							echo PHP_EOL;
-						}
-						$EX['lastBlock'] = null;
-					}
-					$starti = $blockLast + 1;
-					$i = $starti;
-				}
-				else {
-					++$i;
-				}
-			}
-			else {
-				++$i;
-			}
-		}
-		if ($starti <= $range[1]) {
-			$this->decompileBasicBlock($EX, array($starti, $range[1]));
-		}
-	}
-	// }}}
-	function &dop_array($op_array, $indent = '') // {{{
-	{
-		$op_array['opcodes'] = $this->fixOpcode($op_array['opcodes'], true, $indent == '' ? 1 : null);
-		$opcodes = &$op_array['opcodes'];
-		$last = count($opcodes) - 1;
-		// {{{ build jmpins/jmpouts to op_array
-		for ($i = 0; $i <= $last; $i ++) {
-			$op = &$opcodes[$i];
-			$op['line'] = $i;
-			switch ($op['opcode']) {
-			case XC_CONT:
-			case XC_BRK:
-				$op['jmpouts'] = array();
-				break;
-
-			case XC_GOTO:
-				$target = $op['op1']['var'];
-				$op['goto'] = $target;
-				$opcodes[$target]['gofrom'][] = $i;
-				break;
-
-			case XC_JMP:
-				$target = $op['op1']['var'];
-				$op['jmpouts'] = array($target);
-				$opcodes[$target]['jmpins'][] = $i;
-				break;
-
-			case XC_JMPZNZ:
-				$jmpz = $op['op2']['opline_num'];
-				$jmpnz = $op['extended_value'];
-				$op['jmpouts'] = array($jmpz, $jmpnz);
-				$opcodes[$jmpz]['jmpins'][] = $i;
-				$opcodes[$jmpnz]['jmpins'][] = $i;
-				break;
-
-			case XC_JMPZ:
-			case XC_JMPNZ:
-			case XC_JMPZ_EX:
-			case XC_JMPNZ_EX:
-			// case XC_JMP_SET:
-			// case XC_FE_RESET:
-			case XC_FE_FETCH:
-			// case XC_JMP_NO_CTOR:
-				$target = $op['op2']['opline_num'];
-				//if (!isset($target)) {
-				//	$this->dumpop($op, $EX);
-				//	var_dump($op); exit;
-				//}
-				$op['jmpouts'] = array($target);
-				$opcodes[$target]['jmpins'][] = $i;
-				break;
-
-			/*
-			case XC_RETURN:
-				$op['jmpouts'] = array();
-				break;
-			*/
-
-			case XC_SWITCH_FREE:
-				$op['jmpouts'] = array($i + 1);
-				$opcodes[$i + 1]['jmpins'][] = $i;
-				break;
-
-			case XC_CASE:
-				// just to link together
-				$op['jmpouts'] = array($i + 2);
-				$opcodes[$i + 2]['jmpins'][] = $i;
-				break;
-
-			case XC_CATCH:
-				$catchNext = $op['extended_value'];
-				$op['jmpouts'] = array($catchNext);
-				$opcodes[$catchNext]['jmpins'][] = $i;
-				break;
-			}
-			/*
-			if (!empty($op['jmpouts']) || !empty($op['jmpins'])) {
-				echo $i, "\t", xcache_get_opcode($op['opcode']), PHP_EOL;
-			}
-			// */
-		}
-		unset($op);
-		if ($op_array['try_catch_array']) {
-			foreach ($op_array['try_catch_array'] as $try_catch_element) {
-				$catch_op = $try_catch_element['catch_op'];
-				$try_op = $try_catch_element['try_op'];
-				$opcodes[$try_op]['jmpins'][] = $catch_op;
-				$opcodes[$catch_op]['jmpouts'][] = $try_op;
-				$opcodes[$catch_op]['isCatchBegin'] = true;
-			}
-		}
-		// }}}
-		// build semi-basic blocks
-		$nextbbs = array();
-		$starti = 0;
-		for ($i = 1; $i <= $last; $i ++) {
-			if (isset($opcodes[$i]['jmpins'])
-			 || isset($opcodes[$i - 1]['jmpouts'])) {
-				$nextbbs[$starti] = $i;
-				$starti = $i;
-			}
-		}
-		$nextbbs[$starti] = $last + 1;
-
-		$EX = array();
-		$EX['Ts'] = array();
-		$EX['indent'] = $indent;
-		$EX['nextbbs'] = $nextbbs;
-		$EX['op_array'] = &$op_array;
-		$EX['opcodes'] = &$opcodes;
-		$EX['range'] = array(0, count($opcodes) - 1);
-		// func call
-		$EX['object'] = null;
-		$EX['called_scope'] = null;
-		$EX['fbc'] = null;
-		$EX['argstack'] = array();
-		$EX['arg_types_stack'] = array();
-		$EX['scopeStack'] = array();
-		$EX['silence'] = 0;
-		$EX['recvs'] = array();
-		$EX['uses'] = array();
-		$EX['lastBlock'] = null;
-
-		/* dump whole array
-		$this->keepTs = true;
-		$this->dasmBasicBlock($EX, $range);
-		for ($i = $range[0]; $i <= $range[1]; ++$i) {
-			echo $i, "\t", $this->dumpop($opcodes[$i], $EX);
-		}
-		// */
-		// decompile in a tree way
-		$this->recognizeAndDecompileClosedBlocks($EX, $EX['range'], $EX['indent']);
-		return $EX;
-	}
-	// }}}
-	function dasmBasicBlock(&$EX, $range) // {{{
-	{
-		$T = &$EX['Ts'];
-		$opcodes = &$EX['opcodes'];
-		$lastphpop = null;
-
-		for ($i = $range[0]; $i <= $range[1]; $i ++) {
-			// {{{ prepair
-			$op = &$opcodes[$i];
-			$opc = $op['opcode'];
-			if ($opc == XC_NOP) {
-				$this->usedOps[$opc] = true;
-				continue;
-			}
-
-			$op1 = $op['op1'];
-			$op2 = $op['op2'];
-			$res = $op['result'];
-			$ext = $op['extended_value'];
-
-			$opname = xcache_get_opcode($opc);
-
-			if ($opname == 'UNDEF' || !isset($opname)) {
-				echo 'UNDEF OP:';
-				$this->dumpop($op, $EX);
-				continue;
-			}
-			// echo $i, ' '; $this->dumpop($op, $EX); //var_dump($op);
-
-			$resvar = null;
-			unset($curResVar);
-			if (array_key_exists($res['var'], $T)) {
-				$curResVar = &$T[$res['var']];
-			}
-			if ((ZEND_ENGINE_2_4 ? ($res['op_type'] & EXT_TYPE_UNUSED) : ($res['EA.type'] & EXT_TYPE_UNUSED)) || $res['op_type'] == XC_IS_UNUSED) {
-				$istmpres = false;
-			}
-			else {
-				$istmpres = true;
-			}
-			// }}}
-			// echo $opname, "\n";
-
-			$notHandled = false;
-			switch ($opc) {
-			case XC_NEW: // {{{
-				array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope']));
-				$EX['object'] = (int) $res['var'];
-				$EX['called_scope'] = null;
-				$EX['fbc'] = 'new ' . unquoteName($this->getOpVal($op1, $EX), $EX);
-				if (!ZEND_ENGINE_2) {
-					$resvar = '$new object$';
-				}
-				break;
-				// }}}
-			case XC_THROW: // {{{
-				$resvar = 'throw ' . str($this->getOpVal($op1, $EX));
-				break;
-				// }}}
-			case XC_CLONE: // {{{
-				$resvar = 'clone ' . str($this->getOpVal($op1, $EX));
-				break;
-				// }}}
-			case XC_CATCH: // {{{
-				break;
-				// }}}
-			case XC_INSTANCEOF: // {{{
-				$resvar = str($this->getOpVal($op1, $EX)) . ' instanceof ' . str($this->getOpVal($op2, $EX));
-				break;
-				// }}}
-			case XC_FETCH_CLASS: // {{{
-				if ($op2['op_type'] == XC_IS_UNUSED) {
-					switch (($ext & (defined('ZEND_FETCH_CLASS_MASK') ? ZEND_FETCH_CLASS_MASK : 0xFF))) {
-					case ZEND_FETCH_CLASS_SELF:
-						$class = 'self';
-						break;
-					case ZEND_FETCH_CLASS_PARENT:
-						$class = 'parent';
-						break;
-					case ZEND_FETCH_CLASS_STATIC:
-						$class = 'static';
-						break;
-					}
-					$istmpres = true;
-				}
-				else {
-					$class = $this->getOpVal($op2, $EX);
-					if (isset($op2['constant'])) {
-						$class = $this->stripNamespace(unquoteName($class));
-					}
-				}
-				$resvar = $class;
-				break;
-				// }}}
-			case XC_FETCH_CONSTANT: // {{{
-				if ($op1['op_type'] == XC_IS_UNUSED) {
-					$resvar = $this->stripNamespace($op2['constant']);
-					break;
-				}
-
-				if ($op1['op_type'] == XC_IS_CONST) {
-					$resvar = $this->stripNamespace($op1['constant']);
-				}
-				else {
-					$resvar = $this->getOpVal($op1, $EX);
-				}
-
-				$resvar = str($resvar) . '::' . unquoteName($this->getOpVal($op2, $EX));
-				break;
-				// }}}
-				// {{{ case XC_FETCH_*
-			case XC_FETCH_R:
-			case XC_FETCH_W:
-			case XC_FETCH_RW:
-			case XC_FETCH_FUNC_ARG:
-			case XC_FETCH_UNSET:
-			case XC_FETCH_IS:
-			case XC_UNSET_VAR:
-				$rvalue = $this->getOpVal($op1, $EX);
-				if (defined('ZEND_FETCH_TYPE_MASK')) {
-					$fetchtype = ($ext & ZEND_FETCH_TYPE_MASK);
-				}
-				else {
-					$fetchtype = $op2[!ZEND_ENGINE_2 ? 'fetch_type' : 'EA.type'];
-				}
-				switch ($fetchtype) {
-				case ZEND_FETCH_STATIC_MEMBER:
-					$class = $this->getOpVal($op2, $EX);
-					$rvalue = str($class) . '::$' . unquoteName($rvalue, $EX);
-					break;
-				default:
-					$name = unquoteName($rvalue, $EX);
-					$globalname = xcache_is_autoglobal($name) ? "\$$name" : "\$GLOBALS[" . str($rvalue) . "]";
-					$rvalue = new Decompiler_Fetch($rvalue, $fetchtype, $globalname);
-					break;
-				}
-				if ($opc == XC_UNSET_VAR) {
-					$op['php'] = "unset(" . str($rvalue, $EX) . ")";
-					$lastphpop = &$op;
-				}
-				else if ($res['op_type'] != XC_IS_UNUSED) {
-					$resvar = $rvalue;
-				}
-				break;
-				// }}}
-				// {{{ case XC_FETCH_DIM_*
-			case XC_FETCH_DIM_TMP_VAR:
-			case XC_FETCH_DIM_R:
-			case XC_FETCH_DIM_W:
-			case XC_FETCH_DIM_RW:
-			case XC_FETCH_DIM_FUNC_ARG:
-			case XC_FETCH_DIM_UNSET:
-			case XC_FETCH_DIM_IS:
-			case XC_ASSIGN_DIM:
-			case XC_UNSET_DIM_OBJ: // PHP 4 only
-			case XC_UNSET_DIM:
-			case XC_UNSET_OBJ:
-				$src = $this->getOpVal($op1, $EX);
-				if (is_a($src, "Decompiler_ForeachBox")) {
-					$src->iskey = $this->getOpVal($op2, $EX);
-					$resvar = $src;
-					break;
-				}
-
-				if (is_a($src, "Decompiler_DimBox")) {
-					$dimbox = $src;
-				}
-				else {
-					if (!is_a($src, "Decompiler_ListBox")) {
-						$op1val = $this->getOpVal($op1, $EX);
-						$list = new Decompiler_List(isset($op1val) ? $op1val : '$this');
-
-						$src = new Decompiler_ListBox($list);
-						if (!isset($op1['var'])) {
-							$this->dumpop($op, $EX);
-							var_dump($op);
-							die('missing var');
-						}
-						$T[$op1['var']] = $src;
-						unset($list);
-					}
-					$dim = new Decompiler_Dim($src);
-					$src->obj->dims[] = &$dim;
-
-					$dimbox = new Decompiler_DimBox($dim);
-				}
-				$dim = &$dimbox->obj;
-				$dim->offsets[] = $this->getOpVal($op2, $EX);
-				if ($ext == ZEND_FETCH_ADD_LOCK) {
-					$src->obj->everLocked = true;
-				}
-				else if ($ext == ZEND_FETCH_STANDARD) {
-					$dim->isLast = true;
-				}
-				if ($opc == XC_UNSET_OBJ) {
-					$dim->isObject = true;
-				}
-				unset($dim);
-				$rvalue = $dimbox;
-				unset($dimbox);
-
-				if ($opc == XC_ASSIGN_DIM) {
-					$lvalue = $rvalue;
-					++ $i;
-					$rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX);
-					$resvar = str($lvalue, $EX) . ' = ' . str($rvalue);
-				}
-				else if ($opc == XC_UNSET_DIM || $opc == XC_UNSET_OBJ) {
-					$op['php'] = "unset(" . str($rvalue, $EX) . ")";
-					$lastphpop = &$op;
-				}
-				else if ($res['op_type'] != XC_IS_UNUSED) {
-					$resvar = $rvalue;
-				}
-				break;
-				// }}}
-			case XC_ASSIGN: // {{{
-				$lvalue = $this->getOpVal($op1, $EX);
-				$rvalue = $this->getOpVal($op2, $EX);
-				if (is_a($rvalue, 'Decompiler_ForeachBox')) {
-					$type = $rvalue->iskey ? 'fe_key' : 'fe_as';
-					$rvalue->obj[$type] = $lvalue;
-					unset($T[$op2['var']]);
-					break;
-				}
-				if (is_a($rvalue, "Decompiler_DimBox")) {
-					$dim = &$rvalue->obj;
-					$dim->assign = $lvalue;
-					if ($dim->isLast) {
-						$resvar = foldToCode($dim->value, $EX);
-					}
-					unset($dim);
-					break;
-				}
-				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 = new Decompiler_Binop($this, $lvalue, XC_ASSIGN, $rvalue);
-				break;
-				// }}}
-			case XC_ASSIGN_REF: // {{{
-				$lvalue = $this->getOpVal($op1, $EX);
-				$rvalue = $this->getOpVal($op2, $EX);
-				if (is_a($rvalue, 'Decompiler_Fetch')) {
-					$src = str($rvalue->src, $EX);
-					if ('$' . unquoteName($src) == $lvalue) {
-						switch ($rvalue->fetchType) {
-						case ZEND_FETCH_GLOBAL:
-						case ZEND_FETCH_GLOBAL_LOCK:
-							$resvar = 'global ' . $lvalue;
-							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])) {
-								$var = $statics[$name];
-								$resvar .= ' = ';
-								$resvar .= str(value($var), $EX);
-							}
-							unset($statics);
-							break 2;
-						default:
-						}
-					}
-				}
-				// TODO: PHP_6 global
-				$resvar = new Decompiler_Binop($this, $lvalue, XC_ASSIGN_REF, $rvalue);
-				break;
-				// }}}
-			// {{{ case XC_FETCH_OBJ_*
-			case XC_FETCH_OBJ_R:
-			case XC_FETCH_OBJ_W:
-			case XC_FETCH_OBJ_RW:
-			case XC_FETCH_OBJ_FUNC_ARG:
-			case XC_FETCH_OBJ_UNSET:
-			case XC_FETCH_OBJ_IS:
-			case XC_ASSIGN_OBJ:
-				$obj = $this->getOpVal($op1, $EX);
-				if (!isset($obj)) {
-					$obj = '$this';
-				}
-				$rvalue = str($obj) . "->" . unquoteVariableName($this->getOpVal($op2, $EX), $EX);
-				if ($res['op_type'] != XC_IS_UNUSED) {
-					$resvar = $rvalue;
-				}
-				if ($opc == XC_ASSIGN_OBJ) {
-					++ $i;
-					$lvalue = $rvalue;
-					$rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX);
-					$resvar = "$lvalue = " . str($rvalue);
-				}
-				break;
-				// }}}
-			case XC_ISSET_ISEMPTY_DIM_OBJ:
-			case XC_ISSET_ISEMPTY_PROP_OBJ:
-			case XC_ISSET_ISEMPTY:
-			case XC_ISSET_ISEMPTY_VAR: // {{{
-				if ($opc == XC_ISSET_ISEMPTY_VAR) {
-					$rvalue = $this->getOpVal($op1, $EX);
-					// for < PHP_5_3
-					if ($op1['op_type'] == XC_IS_CONST) {
-						$rvalue = '$' . unquoteVariableName($this->getOpVal($op1, $EX));
-					}
-					if ($op2['EA.type'] == ZEND_FETCH_STATIC_MEMBER) {
-						$class = $this->getOpVal($op2, $EX);
-						$rvalue = $class . '::' . $rvalue;
-					}
-				}
-				else if ($opc == XC_ISSET_ISEMPTY) {
-					$rvalue = $this->getOpVal($op1, $EX);
-				}
-				else {
-					$container = $this->getOpVal($op1, $EX);
-					$dim = $this->getOpVal($op2, $EX);
-					if ($opc == XC_ISSET_ISEMPTY_PROP_OBJ) {
-						if (!isset($container)) {
-							$container = '$this';
-						}
-						$rvalue = $container . "->" . unquoteVariableName($dim);
-					}
-					else {
-						$rvalue = $container . '[' . str($dim) .']';
-					}
-				}
-
-				switch ((!ZEND_ENGINE_2 ? $op['op2']['var'] /* constant */ : $ext) & (ZEND_ISSET|ZEND_ISEMPTY)) {
-				case ZEND_ISSET:
-					$rvalue = "isset(" . str($rvalue) . ")";
-					break;
-				case ZEND_ISEMPTY:
-					$rvalue = "empty(" . str($rvalue) . ")";
-					break;
-				}
-				$resvar = $rvalue;
-				break;
-				// }}}
-			case XC_SEND_VAR_NO_REF:
-			case XC_SEND_VAL:
-			case XC_SEND_REF:
-			case XC_SEND_VAR: // {{{
-				$ref = ($opc == XC_SEND_REF ? '&' : '');
-				$EX['argstack'][] = $ref . str($this->getOpVal($op1, $EX));
-				break;
-				// }}}
-			case XC_INIT_STATIC_METHOD_CALL:
-			case XC_INIT_METHOD_CALL: // {{{
-				array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope']));
-				if ($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL || $op1['op_type'] != XC_IS_UNUSED) {
-					$obj = $this->getOpVal($op1, $EX);
-					if (!isset($obj)) {
-						$obj = '$this';
-					}
-					if ($opc == XC_INIT_STATIC_METHOD_CALL || /* PHP4 */ isset($op1['constant'])) {
-						$EX['object'] = null;
-						$EX['called_scope'] = $this->stripNamespace(unquoteName($obj, $EX));
-					}
-					else {
-						$EX['object'] = $obj;
-						$EX['called_scope'] = null;
-					}
-					if ($res['op_type'] != XC_IS_UNUSED) {
-						$resvar = '$obj call$';
-					}
-				}
-				else {
-					$EX['object'] = null;
-					$EX['called_scope'] = null;
-				}
-
-				$EX['fbc'] = $this->getOpVal($op2, $EX);
-				if (($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL) && !isset($EX['fbc'])) {
-					$EX['fbc'] = '__construct';
-				}
-				break;
-				// }}}
-			case XC_INIT_NS_FCALL_BY_NAME:
-			case XC_INIT_FCALL_BY_NAME: // {{{
-				array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope']));
-				if (!ZEND_ENGINE_2 && ($ext & ZEND_CTOR_CALL)) {
-					break;
-				}
-				$EX['object'] = null;
-				$EX['called_scope'] = null;
-				$EX['fbc'] = $this->getOpVal($op2, $EX);
-				break;
-				// }}}
-			case XC_INIT_FCALL_BY_FUNC: // {{{ deprecated even in PHP 4?
-				$EX['object'] = null;
-				$EX['called_scope'] = null;
-				$which = $op1['var'];
-				$EX['fbc'] = $EX['op_array']['funcs'][$which]['name'];
-				break;
-				// }}}
-			case XC_DO_FCALL_BY_FUNC:
-				$which = $op1['var'];
-				$fname = $EX['op_array']['funcs'][$which]['name'];
-				$args = $this->popargs($EX, $ext);
-				$resvar = $fname . "($args)";
-				break;
-			case XC_DO_FCALL:
-				$fname = unquoteName($this->getOpVal($op1, $EX), $EX);
-				$args = $this->popargs($EX, $ext);
-				$resvar = $fname . "($args)";
-				break;
-			case XC_DO_FCALL_BY_NAME: // {{{
-				$object = null;
-
-				$fname = unquoteName($EX['fbc'], $EX);
-				if (!is_int($EX['object'])) {
-					$object = $EX['object'];
-				}
-
-				$args = $this->popargs($EX, $ext);
-
-				$prefix = (isset($object) ? $object . '->' : '' )
-					. (isset($EX['called_scope']) ? $EX['called_scope'] . '::' : '' );
-				$resvar = $prefix
-					. (!$prefix ? $this->stripNamespace($fname) : $fname)
-					. "($args)";
-				unset($args);
-
-				if (is_int($EX['object'])) {
-					$T[$EX['object']] = $resvar;
-					$resvar = null;
-				}
-				list($EX['fbc'], $EX['object'], $EX['called_scope']) = array_pop($EX['arg_types_stack']);
-				break;
-				// }}}
-			case XC_VERIFY_ABSTRACT_CLASS: // {{{
-				//unset($T[$op1['var']]);
-				break;
-				// }}}
-			case XC_DECLARE_CLASS: 
-			case XC_DECLARE_INHERITED_CLASS:
-			case XC_DECLARE_INHERITED_CLASS_DELAYED: // {{{
-				$key = $op1['constant'];
-				if (!isset($this->dc['class_table'][$key])) {
-					echo 'class not found: ', $key, 'existing classes are:', "\n";
-					var_dump(array_keys($this->dc['class_table']));
-					exit;
-				}
-				$class = &$this->dc['class_table'][$key];
-				if (!isset($class['name'])) {
-					$class['name'] = unquoteName($this->getOpVal($op2, $EX), $EX);
-				}
-				if ($opc == XC_DECLARE_INHERITED_CLASS || $opc == XC_DECLARE_INHERITED_CLASS_DELAYED) {
-					$ext /= XC_SIZEOF_TEMP_VARIABLE;
-					$class['parent'] = $T[$ext];
-					unset($T[$ext]);
-				}
-				else {
-					$class['parent'] = null;
-				}
-
-				for (;;) {
-					if ($i + 1 <= $range[1]
-					 && $opcodes[$i + 1]['opcode'] == XC_ADD_INTERFACE
-					 && $opcodes[$i + 1]['op1']['var'] == $res['var']) {
-						// continue
-					}
-					else if ($i + 2 <= $range[1]
-					 && $opcodes[$i + 2]['opcode'] == XC_ADD_INTERFACE
-					 && $opcodes[$i + 2]['op1']['var'] == $res['var']
-					 && $opcodes[$i + 1]['opcode'] == XC_FETCH_CLASS) {
-						// continue
-					}
-					else {
-						break;
-					}
-					$this->usedOps[XC_ADD_INTERFACE] = true;
-
-					$fetchop = &$opcodes[$i + 1];
-					$interface = $this->stripNamespace(unquoteName($this->getOpVal($fetchop['op2'], $EX), $EX));
-					$addop = &$opcodes[$i + 2];
-					$class['interfaces'][$addop['extended_value']] = $interface;
-					unset($fetchop, $addop);
-					$i += 2;
-				}
-				$this->dclass($class, $EX['indent']);
-				echo "\n";
-				unset($class);
-				break;
-				// }}}
-			case XC_INIT_STRING: // {{{
-				$resvar = "''";
-				break;
-				// }}}
-			case XC_ADD_CHAR:
-			case XC_ADD_STRING:
-			case XC_ADD_VAR: // {{{
-				$op1val = $this->getOpVal($op1, $EX);
-				$op2val = $this->getOpVal($op2, $EX);
-				switch ($opc) {
-				case XC_ADD_CHAR:
-					$op2val = value(chr(str($op2val)));
-					break;
-				case XC_ADD_STRING:
-					break;
-				case XC_ADD_VAR:
-					break;
-				}
-				if (str($op1val) == "''") {
-					$rvalue = $op2val;
-				}
-				else if (str($op2val) == "''") {
-					$rvalue = $op1val;
-				}
-				else {
-					$rvalue = str($op1val) . ' . ' . str($op2val);
-				}
-				$resvar = $rvalue;
-				// }}}
-				break;
-			case XC_PRINT: // {{{
-				$op1val = $this->getOpVal($op1, $EX);
-				$resvar = "print(" . str($op1val) . ")";
-				break;
-				// }}}
-			case XC_ECHO: // {{{
-				$op1val = $this->getOpVal($op1, $EX);
-				$resvar = "echo " . str($op1val);
-				break;
-				// }}}
-			case XC_EXIT: // {{{
-				$op1val = $this->getOpVal($op1, $EX);
-				$resvar = "exit($op1val)";
-				break;
-				// }}}
-			case XC_INIT_ARRAY:
-			case XC_ADD_ARRAY_ELEMENT: // {{{
-				$rvalue = $this->getOpVal($op1, $EX, true);
-
-				if ($opc == XC_ADD_ARRAY_ELEMENT) {
-					$assoc = $this->getOpVal($op2, $EX);
-					if (isset($assoc)) {
-						$curResVar->value[] = array($assoc, $rvalue);
-					}
-					else {
-						$curResVar->value[] = array(null, $rvalue);
-					}
-				}
-				else {
-					if ($opc == XC_INIT_ARRAY) {
-						$resvar = new Decompiler_Array();
-						if (!isset($rvalue)) {
-							continue;
-						}
-					}
-
-					$assoc = $this->getOpVal($op2, $EX);
-					if (isset($assoc)) {
-						$resvar->value[] = array($assoc, $rvalue);
-					}
-					else {
-						$resvar->value[] = array(null, $rvalue);
-					}
-				}
-				break;
-				// }}}
-			case XC_QM_ASSIGN: // {{{
-				if (isset($curResVar) && is_a($curResVar, 'Decompiler_Binop')) {
-					$curResVar->op2 = $this->getOpVal($op1, $EX);
-				}
-				else {
-					$resvar = $this->getOpVal($op1, $EX);
-				}
-				break;
-				// }}}
-			case XC_BOOL: // {{{
-				$resvar = /*'(bool) ' .*/ $this->getOpVal($op1, $EX);
-				break;
-				// }}}
-			case XC_RETURN: // {{{
-				$resvar = "return " . str($this->getOpVal($op1, $EX));
-				break;
-				// }}}
-			case XC_INCLUDE_OR_EVAL: // {{{
-				$type = $op2['var']; // hack
-				$keyword = $this->includeTypes[$type];
-				$resvar = "$keyword " . str($this->getOpVal($op1, $EX));
-				break;
-				// }}}
-			case XC_FE_RESET: // {{{
-				$resvar = $this->getOpVal($op1, $EX);
-				break;
-				// }}}
-			case XC_FE_FETCH: // {{{
-				$op['fe_src'] = $this->getOpVal($op1, $EX, true);
-				$fe = new Decompiler_ForeachBox($op);
-				$fe->iskey = false;
-				$T[$res['var']] = $fe;
-
-				++ $i;
-				if (($ext & ZEND_FE_FETCH_WITH_KEY)) {
-					$fe = new Decompiler_ForeachBox($op);
-					$fe->iskey = true;
-
-					$res = $opcodes[$i]['result'];
-					$T[$res['var']] = $fe;
-				}
-				break;
-				// }}}
-			case XC_SWITCH_FREE: // {{{
-				break;
-				// }}}
-			case XC_FREE: // {{{
-				$free = $T[$op1['var']];
-				if (!is_a($free, 'Decompiler_Array') && !is_a($free, 'Decompiler_Box')) {
-					$op['php'] = is_object($free) ? $free : $this->unquote($free, '(', ')');
-					$lastphpop = &$op;
-				}
-				unset($T[$op1['var']], $free);
-				break;
-				// }}}
-			case XC_JMP_NO_CTOR:
-				break;
-			case XC_JMP_SET: // ?:
-				$resvar = new Decompiler_Binop($this, $this->getOpVal($op1, $EX), XC_JMP_SET, null);
-				break;
-			case XC_JMPZ_EX: // and
-			case XC_JMPNZ_EX: // or
-				$resvar = $this->getOpVal($op1, $EX);
-				break;
-
-			case XC_JMPNZ: // while
-			case XC_JMPZNZ: // for
-			case XC_JMPZ: // {{{
-				break;
-				// }}}
-			case XC_CONT:
-			case XC_BRK:
-				$resvar = $opc == XC_CONT ? 'continue' : 'break';
-				$count = str($this->getOpVal($op2, $EX));
-				if ($count != '1') {
-					$resvar .= ' ' . $count;
-				}
-				break;
-			case XC_GOTO:
-				$resvar = 'goto label' . $op['op1']['var'];
-				$istmpres = false;
-				break;
-
-			case XC_JMP: // {{{
-				break;
-				// }}}
-			case XC_CASE:
-				// $switchValue = $this->getOpVal($op1, $EX);
-				$caseValue = $this->getOpVal($op2, $EX);
-				$resvar = $caseValue;
-				break;
-			case XC_RECV_INIT:
-			case XC_RECV:
-				$offset = $this->getOpVal($op1, $EX);
-				$lvalue = $this->getOpVal($op['result'], $EX);
-				if ($opc == XC_RECV_INIT) {
-					$default = value($op['op2']['constant']);
-				}
-				else {
-					$default = null;
-				}
-				$EX['recvs'][str($offset)] = array($lvalue, $default);
-				break;
-			case XC_POST_DEC:
-			case XC_POST_INC:
-			case XC_POST_DEC_OBJ:
-			case XC_POST_INC_OBJ:
-			case XC_PRE_DEC:
-			case XC_PRE_INC:
-			case XC_PRE_DEC_OBJ:
-			case XC_PRE_INC_OBJ: // {{{
-				$flags = array_flip(explode('_', $opname));
-				if (isset($flags['OBJ'])) {
-					$resvar = $this->getOpVal($op1, $EX) . '->' . unquoteVariableName($this->getOpVal($op2, $EX), $EX);
-				}
-				else {
-					$resvar = $this->getOpVal($op1, $EX);
-				}
-				$opstr = isset($flags['DEC']) ? '--' : '++';
-				if (isset($flags['POST'])) {
-					$resvar .= $opstr;
-				}
-				else {
-					$resvar = "$opstr$resvar";
-				}
-				break;
-				// }}}
-
-			case XC_BEGIN_SILENCE: // {{{
-				$EX['silence'] ++;
-				break;
-				// }}}
-			case XC_END_SILENCE: // {{{
-				$EX['silence'] --;
-				$lastresvar = '@' . str($lastresvar, $EX);
-				break;
-				// }}}
-			case XC_CAST: // {{{
-				$type = $ext;
-				static $type2cast = array(
-						IS_LONG   => '(int)',
-						IS_DOUBLE => '(double)',
-						IS_STRING => '(string)',
-						IS_ARRAY  => '(array)',
-						IS_OBJECT => '(object)',
-						IS_BOOL   => '(bool)',
-						IS_NULL   => '(unset)',
-						);
-				assert(isset($type2cast[$type]));
-				$cast = $type2cast[$type];
-				$resvar = $cast . ' ' . $this->getOpVal($op1, $EX);
-				break;
-				// }}}
-			case XC_EXT_STMT:
-			case XC_EXT_FCALL_BEGIN:
-			case XC_EXT_FCALL_END:
-			case XC_EXT_NOP:
-				break;
-			case XC_DECLARE_FUNCTION:
-				$this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']);
-				break;
-			case XC_DECLARE_LAMBDA_FUNCTION: // {{{
-				ob_start();
-				$this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']);
-				$resvar = ob_get_clean();
-				$istmpres = true;
-				break;
-				// }}}
-			case XC_DECLARE_CONST:
-				$name = $this->stripNamespace(unquoteName($this->getOpVal($op1, $EX), $EX));
-				$value = str($this->getOpVal($op2, $EX));
-				$resvar = 'const ' . $name . ' = ' . $value;
-				break;
-			case XC_DECLARE_FUNCTION_OR_CLASS:
-				/* always removed by compiler */
-				break;
-			case XC_TICKS:
-				$lastphpop['ticks'] = $this->getOpVal($op1, $EX);
-				// $EX['tickschanged'] = true;
-				break;
-			case XC_RAISE_ABSTRACT_ERROR:
-				// abstract function body is empty, don't need this code
-				break;
-			case XC_USER_OPCODE:
-				echo '// ZEND_USER_OPCODE, impossible to decompile';
-				break;
-			case XC_OP_DATA:
-				break;
-			default: // {{{
-				$call = array(&$this, $opname);
-				if (is_callable($call)) {
-					$this->usedOps[$opc] = true;
-					$this->{$opname}($op, $EX);
-				}
-				else if (isset($this->binops[$opc])) { // {{{
-					$this->usedOps[$opc] = true;
-					$op1val = $this->getOpVal($op1, $EX);
-					$op2val = $this->getOpVal($op2, $EX);
-					$rvalue = new Decompiler_Binop($this, $op1val, $opc, $op2val);
-					$resvar = $rvalue;
-					// }}}
-				}
-				else if (isset($this->unaryops[$opc])) { // {{{
-					$this->usedOps[$opc] = true;
-					$op1val = $this->getOpVal($op1, $EX);
-					$myop = $this->unaryops[$opc];
-					$rvalue = $myop . str($op1val);
-					$resvar = $rvalue;
-					// }}}
-				}
-				else {
-					$notHandled = true;
-				}
-				// }}}
-			}
-			if ($notHandled) {
-				echo "\x1B[31m * TODO ", $opname, "\x1B[0m\n";
-			}
-			else {
-				$this->usedOps[$opc] = true;
-			}
-
-			if (isset($resvar)) {
-				if ($istmpres) {
-					$T[$res['var']] = $resvar;
-					$lastresvar = &$T[$res['var']];
-				}
-				else {
-					$op['php'] = $resvar;
-					$lastphpop = &$op;
-					$lastresvar = &$op['php'];
-				}
-			}
-		}
-		return $T;
-	}
-	// }}}
-	function unquote($str, $st, $ed) // {{{
-	{
-		$l1 = strlen($st);
-		$l2 = strlen($ed);
-		if (substr($str, 0, $l1) === $st && substr($str, -$l2) === $ed) {
-			$str = substr($str, $l1, -$l2);
-		}
-		return $str;
-	}
-	// }}}
-	function popargs(&$EX, $n) // {{{
-	{
-		$args = array();
-		for ($i = 0; $i < $n; $i ++) {
-			$a = array_pop($EX['argstack']);
-			if (is_array($a)) {
-				array_unshift($args, foldToCode($a, $EX));
-			}
-			else {
-				array_unshift($args, $a);
-			}
-		}
-		return implode(', ', $args);
-	}
-	// }}}
-	function dumpop($op, &$EX) // {{{
-	{
-		assert('isset($op)');
-		$op1 = $op['op1'];
-		$op2 = $op['op2'];
-		$d = array(xcache_get_opcode($op['opcode']), $op['opcode']);
-
-		foreach (array('op1' => '1:', 'op2' => '2:', 'result' => '>') as $k => $kk) {
-			switch ($op[$k]['op_type']) {
-			case XC_IS_UNUSED:
-				$d[$kk] = 'U:' . $op[$k]['opline_num'];
-				break;
-
-			case XC_IS_VAR:
-				$d[$kk] = '$' . $op[$k]['var'];
-				if ($k != 'result') {
-					$d[$kk] .= ':' . str($this->getOpVal($op[$k], $EX));
-				}
-				break;
-
-			case XC_IS_TMP_VAR:
-				$d[$kk] = '#' . $op[$k]['var'];
-				if ($k != 'result') {
-					$d[$kk] .= ':' . str($this->getOpVal($op[$k], $EX));
-				}
-				break;
-
-			case XC_IS_CV:
-				$d[$kk] = $this->getOpVal($op[$k], $EX);
-				break;
-
-			default:
-				if ($k == 'result') {
-					var_dump($op);
-					assert(0);
-					exit;
-				}
-				else {
-					$d[$kk] = $this->getOpVal($op[$k], $EX);
-				}
-			}
-		}
-		$d[';'] = $op['extended_value'];
-		if (!empty($op['jmpouts'])) {
-			$d['>>'] = implode(',', $op['jmpouts']);
-		}
-		if (!empty($op['jmpins'])) {
-			$d['<<'] = implode(',', $op['jmpins']);
-		}
-
-		foreach ($d as $k => $v) {
-			echo is_int($k) ? '' : $k, str($v), "\t";
-		}
-		echo PHP_EOL;
-	}
-	// }}}
-	function dumpRange(&$EX, $range) // {{{
-	{
-		for ($i = $range[0]; $i <= $range[1]; ++$i) {
-			echo $EX['indent'], $i, "\t"; $this->dumpop($EX['opcodes'][$i], $EX);
-		}
-		echo $EX['indent'], "==", PHP_EOL;
-	}
-	// }}}
-	function dargs(&$EX) // {{{
-	{
-		$op_array = &$EX['op_array'];
-
-		if (isset($op_array['num_args'])) {
-			$c = $op_array['num_args'];
-		}
-		else if (!empty($op_array['arg_types'])) {
-			$c = count($op_array['arg_types']);
-		}
-		else {
-			// php4
-			$c = count($EX['recvs']);
-		}
-
-		$refrest = false;
-		for ($i = 0; $i < $c; $i ++) {
-			if ($i) {
-				echo ', ';
-			}
-			$arg = $EX['recvs'][$i + 1];
-			if (isset($op_array['arg_info'])) {
-				$ai = $op_array['arg_info'][$i];
-				if (!empty($ai['class_name'])) {
-					echo $this->stripNamespace($ai['class_name']), ' ';
-					if (!ZEND_ENGINE_2_2 && $ai['allow_null']) {
-						echo 'or NULL ';
-					}
-				}
-				else if (!empty($ai['array_type_hint'])) {
-					echo 'array ';
-					if (!ZEND_ENGINE_2_2 && $ai['allow_null']) {
-						echo 'or NULL ';
-					}
-				}
-				if ($ai['pass_by_reference']) {
-					echo '&';
-				}
-				printf("\$%s", $ai['name']);
-			}
-			else {
-				if ($refrest) {
-					echo '&';
-				}
-				else if (!empty($op_array['arg_types']) && isset($op_array['arg_types'][$i])) {
-					switch ($op_array['arg_types'][$i]) {
-					case BYREF_FORCE_REST:
-						$refrest = true;
-						/* fall */
-					case BYREF_FORCE:
-						echo '&';
-						break;
-
-					case BYREF_NONE:
-					case BYREF_ALLOW:
-						break;
-					default:
-						assert(0);
-					}
-				}
-				echo str($arg[0], $EX);
-			}
-			if (isset($arg[1])) {
-				echo ' = ', str($arg[1], $EX);
-			}
-		}
-	}
-	// }}}
-	function duses(&$EX) // {{{
-	{
-		if ($EX['uses']) {
-			echo ' use(', implode(', ', $EX['uses']), ')';
-		}
-	}
-	// }}}
-	function dfunction($func, $indent = '', $decorations = array(), $nobody = false) // {{{
-	{
-		$this->detectNamespace($func['op_array']['function_name']);
-
-		if ($nobody) {
-			$EX = array();
-			$EX['op_array'] = &$func['op_array'];
-			$EX['recvs'] = array();
-			$EX['uses'] = array();
-		}
-		else {
-			ob_start();
-			$EX = &$this->dop_array($func['op_array'], $indent . INDENT);
-			$body = ob_get_clean();
-		}
-
-		$functionName = $this->stripNamespace($func['op_array']['function_name']);
-		$isExpression = false;
-		if ($functionName == '{closure}') {
-			$functionName = '';
-			$isExpression = true;
-		}
-		echo $isExpression ? '' : $indent;
-		if ($decorations) {
-			echo implode(' ', $decorations), ' ';
-		}
-		echo 'function', $functionName ? ' ' . $functionName : '', '(';
-		$this->dargs($EX);
-		echo ")";
-		$this->duses($EX);
-		if ($nobody) {
-			echo ";\n";
-		}
-		else {
-			if (!$isExpression) {
-				echo "\n";
-				echo $indent, "{\n";
-			}
-			else {
-				echo " {\n";
-			}
-
-			echo $body;
-			echo "$indent}";
-			if (!$isExpression) {
-				echo "\n";
-			}
-		}
-	}
-	// }}}
-	function dclass($class, $indent = '') // {{{
-	{
-		$this->detectNamespace($class['name']);
-
-		// {{{ class decl
-		if (!empty($class['doc_comment'])) {
-			echo $indent;
-			echo $class['doc_comment'];
-			echo "\n";
-		}
-		$isInterface = false;
-		$decorations = array();
-		if (!empty($class['ce_flags'])) {
-			if ($class['ce_flags'] & ZEND_ACC_INTERFACE) {
-				$isInterface = true;
-			}
-			else {
-				if ($class['ce_flags'] & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
-					$decorations[] = "abstract";
-				}
-				if ($class['ce_flags'] & ZEND_ACC_FINAL_CLASS) {
-					$decorations[] = "final";
-				}
-			}
-		}
-
-		echo $indent;
-		if ($decorations) {
-			echo implode(' ', $decorations), ' ';
-		}
-		echo $isInterface ? 'interface ' : 'class ', $this->stripNamespace($class['name']);
-		if ($class['parent']) {
-			echo ' extends ', $class['parent'];
-		}
-		/* TODO */
-		if (!empty($class['interfaces'])) {
-			echo ' implements ';
-			echo implode(', ', $class['interfaces']);
-		}
-		echo "\n";
-		echo $indent, "{";
-		// }}}
-		$newindent = INDENT . $indent;
-		// {{{ const, static
-		foreach (array('constants_table' => 'const '
-					, 'static_members' => 'static $') as $type => $prefix) {
-			if (!empty($class[$type])) {
-				echo "\n";
-				// TODO: skip shadow?
-				foreach ($class[$type] as $name => $v) {
-					echo $newindent;
-					echo $prefix, $name, ' = ';
-					echo str(value($v), $newindent);
-					echo ";\n";
-				}
-			}
-		}
-		// }}}
-		// {{{ properties
-		$member_variables = isset($class['properties_info']) ? $class['properties_info'] : ($class['default_static_members'] + $class['default_properties']);
-		if ($member_variables) {
-			echo "\n";
-			$infos = !empty($class['properties_info']) ? $class['properties_info'] : null;
-			foreach ($member_variables as $name => $dummy) {
-				$info = (isset($infos) && isset($infos[$name])) ? $infos[$name] : null;
-				if (isset($info)) {
-					if (!empty($info['doc_comment'])) {
-						echo $newindent;
-						echo $info['doc_comment'];
-						echo "\n";
-					}
-				}
-
-				echo $newindent;
-				$static = false;
-				if (isset($info)) {
-					if ($info['flags'] & ZEND_ACC_STATIC) {
-						$static = true;
-					}
-				}
-				else if (isset($class['default_static_members'][$name])) {
-					$static = true;
-				}
-
-				if ($static) {
-					echo "static ";
-				}
-
-				$mangled = false;
-				if (!ZEND_ENGINE_2) {
-					echo 'var ';
-				}
-				else if (!isset($info)) {
-					echo 'public ';
-				}
-				else {
-					if ($info['flags'] & ZEND_ACC_SHADOW) {
-						continue;
-					}
-					switch ($info['flags'] & ZEND_ACC_PPP_MASK) {
-					case ZEND_ACC_PUBLIC:
-						echo "public ";
-						break;
-					case ZEND_ACC_PRIVATE:
-						echo "private ";
-						$mangled = true;
-						break;
-					case ZEND_ACC_PROTECTED:
-						echo "protected ";
-						$mangled = true;
-						break;
-					}
-				}
-
-				echo '$', $name;
-
-				if (isset($info['offset'])) {
-					$value = $class[$static ? 'default_static_members_table' : 'default_properties_table'][$info['offset']];
-				}
-				else {
-					$key = isset($info) ? $info['name'] . ($mangled ? "\000" : "") : $name;
-
-					$value = $class[$static ? 'default_static_members' : 'default_properties'][$key];
-				}
-				if (isset($value)) {
-					echo ' = ';
-					echo str(value($value), $newindent);
-				}
-				echo ";\n";
-			}
-		}
-		// }}}
-		// {{{ function_table
-		if (isset($class['function_table'])) {
-			foreach ($class['function_table'] as $func) {
-				if (!isset($func['scope']) || $func['scope'] == $class['name']) {
-					// TODO: skip shadow here
-					echo "\n";
-					$opa = $func['op_array'];
-					if (!empty($opa['doc_comment'])) {
-						echo $newindent;
-						echo $opa['doc_comment'];
-						echo "\n";
-					}
-					$isAbstractMethod = false;
-					$decorations = array();
-					if (isset($opa['fn_flags'])) {
-						if (($opa['fn_flags'] & ZEND_ACC_ABSTRACT) && !$isInterface) {
-							$decorations[] = "abstract";
-							$isAbstractMethod = true;
-						}
-						if ($opa['fn_flags'] & ZEND_ACC_FINAL) {
-							$decorations[] = "final";
-						}
-						if ($opa['fn_flags'] & ZEND_ACC_STATIC) {
-							$decorations[] = "static";
-						}
-
-						switch ($opa['fn_flags'] & ZEND_ACC_PPP_MASK) {
-							case ZEND_ACC_PUBLIC:
-								$decorations[] = "public";
-								break;
-							case ZEND_ACC_PRIVATE:
-								$decorations[] = "private";
-								break;
-							case ZEND_ACC_PROTECTED:
-								$decorations[] = "protected";
-								break;
-							default:
-								$decorations[] = "<visibility error>";
-								break;
-						}
-					}
-					$this->dfunction($func, $newindent, $decorations, $isInterface || $isAbstractMethod);
-					if ($opa['function_name'] == 'Decompiler') {
-						//exit;
-					}
-				}
-			}
-		}
-		// }}}
-		echo $indent, "}\n";
-	}
-	// }}}
-	function decompileString($string) // {{{
-	{
-		$this->dc = xcache_dasm_string($string);
-		if ($this->dc === false) {
-			echo "error compling string\n";
-			return false;
-		}
-	}
-	// }}}
-	function decompileFile($file) // {{{
-	{
-		$this->dc = xcache_dasm_file($file);
-		if ($this->dc === false) {
-			echo "error compling $file\n";
-			return false;
-		}
-	}
-	// }}}
-	function decompileDasm($content) // {{{
-	{
-		$this->dc = $content;
-	}
-	// }}}
-	function output() // {{{
-	{
-		echo "<?". "php\n\n";
-		foreach ($this->dc['class_table'] as $key => $class) {
-			if ($key{0} != "\0") {
-				$this->dclass($class);
-				echo "\n";
-			}
-		}
-
-		foreach ($this->dc['function_table'] as $key => $func) {
-			if ($key{0} != "\0") {
-				$this->dfunction($func);
-				echo "\n";
-			}
-		}
-
-		$this->dop_array($this->dc['op_array']);
-		echo "\n?" . ">\n";
-
-		if (!empty($this->test)) {
-			$this->outputUnusedOp();
-		}
-		return true;
-	}
-	// }}}
-	function outputUnusedOp() // {{{
-	{
-		for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
-			if ($opname == 'UNDEF')  {
-				continue;
-			}
-
-			if (!isset($this->usedOps[$i])) {
-				echo "not covered opcode ", $opname, "\n";
-			}
-		}
-	}
-	// }}}
-}
-
-// {{{ defines
-define('ZEND_ENGINE_2_4', PHP_VERSION >= "5.3.99");
-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.");
-define('ZEND_ENGINE_2',   ZEND_ENGINE_2_1 || PHP_VERSION >= "5.0.");
-
-define('ZEND_ACC_STATIC',         0x01);
-define('ZEND_ACC_ABSTRACT',       0x02);
-define('ZEND_ACC_FINAL',          0x04);
-define('ZEND_ACC_IMPLEMENTED_ABSTRACT',       0x08);
-
-define('ZEND_ACC_IMPLICIT_ABSTRACT_CLASS',    0x10);
-define('ZEND_ACC_EXPLICIT_ABSTRACT_CLASS',    0x20);
-define('ZEND_ACC_FINAL_CLASS',                0x40);
-define('ZEND_ACC_INTERFACE',                  0x80);
-if (ZEND_ENGINE_2_4) {
-	define('ZEND_ACC_TRAIT',                  0x120);
-}
-define('ZEND_ACC_PUBLIC',     0x100);
-define('ZEND_ACC_PROTECTED',  0x200);
-define('ZEND_ACC_PRIVATE',    0x400);
-define('ZEND_ACC_PPP_MASK',  (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE));
-
-define('ZEND_ACC_CHANGED',    0x800);
-define('ZEND_ACC_IMPLICIT_PUBLIC',    0x1000);
-
-define('ZEND_ACC_CTOR',       0x2000);
-define('ZEND_ACC_DTOR',       0x4000);
-define('ZEND_ACC_CLONE',      0x8000);
-
-define('ZEND_ACC_ALLOW_STATIC',   0x10000);
-
-define('ZEND_ACC_SHADOW', 0x2000);
-
-if (ZEND_ENGINE_2_4) {
-	define('ZEND_FETCH_GLOBAL',           0x00000000);
-	define('ZEND_FETCH_LOCAL',            0x10000000);
-	define('ZEND_FETCH_STATIC',           0x20000000);
-	define('ZEND_FETCH_STATIC_MEMBER',    0x30000000);
-	define('ZEND_FETCH_GLOBAL_LOCK',      0x40000000);
-	define('ZEND_FETCH_LEXICAL',          0x50000000);
-
-	define('ZEND_FETCH_TYPE_MASK',        0x70000000);
-}
-else {
-	define('ZEND_FETCH_GLOBAL',           0);
-	define('ZEND_FETCH_LOCAL',            1);
-	define('ZEND_FETCH_STATIC',           2);
-	define('ZEND_FETCH_STATIC_MEMBER',    3);
-	define('ZEND_FETCH_GLOBAL_LOCK',      4);
-}
-
-define('ZEND_FETCH_CLASS_DEFAULT',    0);
-define('ZEND_FETCH_CLASS_SELF',       1);
-define('ZEND_FETCH_CLASS_PARENT',     2);
-define('ZEND_FETCH_CLASS_MAIN',       3);
-define('ZEND_FETCH_CLASS_GLOBAL',     4);
-define('ZEND_FETCH_CLASS_AUTO',       5);
-define('ZEND_FETCH_CLASS_INTERFACE',  6);
-define('ZEND_FETCH_CLASS_STATIC',     7);
-if (ZEND_ENGINE_2_4) {
-	define('ZEND_FETCH_CLASS_TRAIT',     14);
-}
-if (ZEND_ENGINE_2_3) {
-	define('ZEND_FETCH_CLASS_MASK',     0xF);
-}
-
-define('ZEND_EVAL',               (1<<0));
-define('ZEND_INCLUDE',            (1<<1));
-define('ZEND_INCLUDE_ONCE',       (1<<2));
-define('ZEND_REQUIRE',            (1<<3));
-define('ZEND_REQUIRE_ONCE',       (1<<4));
-
-define('ZEND_ISSET',              (1<<0));
-define('ZEND_ISEMPTY',            (1<<1));
-if (ZEND_ENGINE_2_4) {
-	define('EXT_TYPE_UNUSED',     (1<<5));
-}
-else {
-	define('EXT_TYPE_UNUSED',     (1<<0));
-}
-
-define('ZEND_FETCH_STANDARD',     0);
-define('ZEND_FETCH_ADD_LOCK',     1);
-
-define('ZEND_FE_FETCH_BYREF',     1);
-define('ZEND_FE_FETCH_WITH_KEY',  2);
-
-define('ZEND_MEMBER_FUNC_CALL',   1<<0);
-define('ZEND_CTOR_CALL',          1<<1);
-
-define('ZEND_ARG_SEND_BY_REF',        (1<<0));
-define('ZEND_ARG_COMPILE_TIME_BOUND', (1<<1));
-define('ZEND_ARG_SEND_FUNCTION',      (1<<2));
-
-define('BYREF_NONE',       0);
-define('BYREF_FORCE',      1);
-define('BYREF_ALLOW',      2);
-define('BYREF_FORCE_REST', 3);
-define('IS_NULL',     0);
-define('IS_LONG',     1);
-define('IS_DOUBLE',   2);
-define('IS_BOOL',     ZEND_ENGINE_2 ? 3 : 6);
-define('IS_ARRAY',    4);
-define('IS_OBJECT',   5);
-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);
-
-/*
-if (preg_match_all('!XC_[A-Z_]+!', file_get_contents(__FILE__), $ms)) {
-	$verdiff = array();
-	foreach ($ms[0] as $k) {
-		if (!defined($k)) {
-			$verdiff[$k] = -1;
-			define($k, -1);
-		}
-	}
-	var_export($verdiff);
-}
-/*/
-foreach (array (
-	'XC_HANDLE_EXCEPTION' => -1,
-	'XC_FETCH_CLASS' => -1,
-	'XC_FETCH_' => -1,
-	'XC_FETCH_DIM_' => -1,
-	'XC_ASSIGN_DIM' => -1,
-	'XC_UNSET_DIM' => -1,
-	'XC_UNSET_OBJ' => -1,
-	'XC_ASSIGN_OBJ' => -1,
-	'XC_ISSET_ISEMPTY_DIM_OBJ' => -1,
-	'XC_ISSET_ISEMPTY_PROP_OBJ' => -1,
-	'XC_ISSET_ISEMPTY_VAR' => -1,
-	'XC_INIT_STATIC_METHOD_CALL' => -1,
-	'XC_INIT_METHOD_CALL' => -1,
-	'XC_VERIFY_ABSTRACT_CLASS' => -1,
-	'XC_DECLARE_CLASS' => -1,
-	'XC_DECLARE_INHERITED_CLASS' => -1,
-	'XC_DECLARE_INHERITED_CLASS_DELAYED' => -1,
-	'XC_ADD_INTERFACE' => -1,
-	'XC_POST_DEC_OBJ' => -1,
-	'XC_POST_INC_OBJ' => -1,
-	'XC_PRE_DEC_OBJ' => -1,
-	'XC_PRE_INC_OBJ' => -1,
-	'XC_UNSET_OBJ' => -1,
-	'XC_JMP_NO_CTOR' => -1,
-	'XC_FETCH_' => -1,
-	'XC_FETCH_DIM_' => -1,
-	'XC_UNSET_DIM_OBJ' => -1,
-	'XC_ISSET_ISEMPTY' => -1,
-	'XC_INIT_FCALL_BY_FUNC' => -1,
-	'XC_DO_FCALL_BY_FUNC' => -1,
-	'XC_DECLARE_FUNCTION_OR_CLASS' => -1,
-	'XC_INIT_NS_FCALL_BY_NAME' => -1,
-	'XC_GOTO' => -1,
-	'XC_CATCH' => -1,
-	'XC_THROW' => -1,
-	'XC_INSTANCEOF' => -1,
-	'XC_DECLARE_FUNCTION' => -1,
-	'XC_RAISE_ABSTRACT_ERROR' => -1,
-	'XC_DECLARE_CONST' => -1,
-	'XC_USER_OPCODE' => -1,
-	'XC_JMP_SET' => -1,
-	'XC_DECLARE_LAMBDA_FUNCTION' => -1,
-) as $k => $v) {
-	if (!defined($k)) {
-		define($k, $v);
-	}
-}
-// }}}
-
Index: /trunk/Makefile.frag
===================================================================
--- /trunk/Makefile.frag	(revision 981)
+++ /trunk/Makefile.frag	(revision 982)
@@ -1,6 +1,6 @@
 XCACHE_PROC_SRC=$(srcdir)/processor/main.m4
 XCACHE_PROC_OUT=$(builddir)/processor.out
-XCACHE_PROC_C=$(builddir)/processor_real.c
-XCACHE_PROC_H=$(builddir)/processor.h
+XCACHE_PROC_C=$(builddir)/main/xc_processor_real.c
+XCACHE_PROC_H=$(builddir)/main/xc_processor.h
 XCACHE_INCLUDES_SRC=$(srcdir)/includes.c
 XCACHE_INCLUDES_I=$(builddir)/includes.i
@@ -10,7 +10,7 @@
 	$(CC) -I. -I$(srcdir) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -E $(XCACHE_INCLUDES_SRC) -o $(XCACHE_INCLUDES_I)
 
-$(XCACHE_STRUCTINFO_OUT): $(XCACHE_INCLUDES_I) $(srcdir)/mkstructinfo.awk
+$(XCACHE_STRUCTINFO_OUT): $(XCACHE_INCLUDES_I) $(srcdir)/gen_structinfo.awk
 	@echo $(XCACHE_STRUCTINFO_OUT) is optional if XCache test is not enabled, feel free if it awk failed to produce it
-	-$(XCACHE_AWK) -f $(srcdir)/mkstructinfo.awk < $(XCACHE_INCLUDES_I) > $(XCACHE_STRUCTINFO_OUT).tmp && mv $(XCACHE_STRUCTINFO_OUT).tmp $(XCACHE_STRUCTINFO_OUT)
+	-$(XCACHE_AWK) -f $(srcdir)/gen_structinfo.awk < $(XCACHE_INCLUDES_I) > $(XCACHE_STRUCTINFO_OUT).tmp && mv $(XCACHE_STRUCTINFO_OUT).tmp $(XCACHE_STRUCTINFO_OUT)
 
 $(XCACHE_PROC_OUT): $(XCACHE_PROC_SRC) $(XCACHE_STRUCTINFO_OUT) $(XCACHE_PROC_SOURCES)
@@ -26,11 +26,11 @@
 	-$(XCACHE_INDENT) < $(XCACHE_PROC_OUT) > $(XCACHE_PROC_C).tmp && mv $(XCACHE_PROC_C).tmp $(XCACHE_PROC_C)
 
-$(builddir)/processor.lo: $(XCACHE_PROC_C) $(XCACHE_PROC_H) $(srcdir)/processor.c
+$(builddir)/main/xc_processor.lo: $(XCACHE_PROC_C) $(XCACHE_PROC_H) $(srcdir)/main/xc_processor.c
 
-$(builddir)/disassembler.lo: $(XCACHE_PROC_H) $(srcdir)/processor.c
+$(builddir)/submodules/xc_disassembler.lo: $(XCACHE_PROC_H) $(srcdir)/main/xc_processor.c
 
-$(builddir)/opcode_spec.lo: $(srcdir)/xcache.h $(srcdir)/opcode_spec.c $(srcdir)/opcode_spec_def.h $(srcdir)/const_string.h
+$(builddir)/xc_opcode_spec.lo: $(srcdir)/xcache.h $(srcdir)/xc_opcode_spec.c $(srcdir)/xc_opcode_spec_def.h $(srcdir)/xc_const_string.h
 
-$(builddir)/xcache.lo: $(XCACHE_PROC_H) $(srcdir)/xc_shm.h $(srcdir)/stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.c $(srcdir)/foreachcoresig.h $(srcdir)/utils.h
+$(builddir)/xcache.lo: $(XCACHE_PROC_H) $(srcdir)/main/xc_shm.h $(srcdir)/util/xc_stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.c $(srcdir)/util/xc_foreachcoresig.h $(srcdir)/main/xc_utils.h
 
 xcachesvnclean: clean
Index: unk/align.h
===================================================================
--- /trunk/align.h	(revision 981)
+++ 	(revision )
@@ -1,19 +1,0 @@
-#ifndef __ALIGN_H
-#define __ALIGN_H
-#ifndef ALIGN
-typedef union align_union {
-	double d;
-	void *v;
-	int (*func)(int);
-	long l;
-} align_union;
-
-#if (defined (__GNUC__) && __GNUC__ >= 2)
-#define XCACHE_PLATFORM_ALIGNMENT (__alignof__ (align_union))
-#else
-#define XCACHE_PLATFORM_ALIGNMENT (sizeof(align_union))
-#endif
-
-#define ALIGN(n) ((((size_t)(n)-1) & ~(XCACHE_PLATFORM_ALIGNMENT-1)) + XCACHE_PLATFORM_ALIGNMENT)
-#endif
-#endif /* __ALIGN_H */
Index: /trunk/bin/phpdc.phpr
===================================================================
--- /trunk/bin/phpdc.phpr	(revision 982)
+++ /trunk/bin/phpdc.phpr	(revision 982)
@@ -0,0 +1,33 @@
+#! /usr/bin/php -dopen_basedir=
+<?php
+
+$srcdir = dirname(__FILE__);
+require_once("$srcdir/../lib/Decompiler.class.php");
+if (file_exists("$srcdir/phpdc.debug.php")) {
+	include("$srcdir/phpdc.debug.php");
+}
+
+if (!isset($argv)) {
+	$argv = $_SERVER['argv'];
+	$argc = $_SERVER['argc'];
+}
+
+$dc = new Decompiler();
+if (isset($argv[2])) {
+	eval('$dc->dc = ' . file_get_contents($argv[2]) . ';');
+}
+else if (isset($argv[1])) {
+	$dc->decompileFile($argv[1]);
+}
+else {
+	$phpcode = '';
+	if (!defined('stdin')) {
+		define('stdin', fopen('php://stdin', 'rb'));
+	}
+	while (!feof(stdin)) {
+		$phpcode .= fgets(stdin);
+	}
+	$dc->decompileString($phpcode);
+}
+$dc->output();
+
Index: /trunk/bin/phpdop.phpr
===================================================================
--- /trunk/bin/phpdop.phpr	(revision 982)
+++ /trunk/bin/phpdop.phpr	(revision 982)
@@ -0,0 +1,130 @@
+#! /usr/bin/php
+<?php
+
+$srcdir = dirname(__FILE__);
+require_once("$srcdir/../lib/Decompiler.class.php");
+if (file_exists("$srcdir/phpdc.debug.php")) {
+	include("$srcdir/phpdc.debug.php");
+}
+
+function get_op($op)
+{
+	switch ($op['op_type']) {
+	case 1: // CONST
+		return var_export($op['constant'], true);
+
+	case 2: // IS_TMP_VAR
+		return 't@' . $op['var'];
+
+	case 4:
+		return 'v$' . $op['var'];
+
+	case 8: // UNUSED
+		if (isset($op['opline_num'])) {
+			return 'l#' . $op['opline_num'];
+		}
+		else {
+			return '-';
+		}
+
+	default:
+		return $op['op_type'] . $op['var'];
+	}
+}
+
+function dump_opcodes($opcodes, $indent = '')
+{
+	global $decompiler;
+
+	$types = array('result' => 5, 'op1' => 20, 'op2' => 20);
+	foreach ($decompiler->fixOpcode($opcodes) as $line => $op) {
+		echo $indent;
+		echo sprintf("%3d ", $op['lineno']);
+		echo sprintf("%3x ", $line);
+		$name = xcache_get_opcode($op['opcode']);
+
+		if (substr($name, 0, 5) == 'ZEND_') {
+			$name = substr($name, 5);
+		}
+		echo str_pad($name, 25);
+
+		foreach ($types as $t => $len) {
+			echo str_pad(isset($op[$t]) ? get_op($op[$t]) : "", $len);
+		}
+		printf("%5s", isset($op['extended_value']) ?  $op['extended_value'] : "");
+
+		echo "\n";
+	}
+}
+
+function dump_function($name, $func, $indent = '')
+{
+	if (isset($func['op_array'])) {
+		$op_array = $func['op_array'];
+		unset($func['op_array']);
+	}
+	else {
+		$op_array = null;
+	}
+	var_dump($func);
+	echo $indent, 'function ', $name, "\n";
+	if (isset($op_array)) {
+		dump_opcodes($op_array['opcodes'], "  " . $indent);
+	}
+}
+
+function dump_class($name, $class, $indent = '')
+{
+	if (isset($class['function_table'])) {
+		$funcs = $class['function_table'];
+		unset($class['function_table']);
+	}
+	else {
+		$funcs = null;
+	}
+	echo $indent, 'class ', $name, "\n";
+	if (isset($funcs)) {
+		foreach ($funcs as $name => $func) {
+			dump_function($name, $func, "  " . $indent);
+		}
+	}
+}
+
+if (!isset($argv[1])) {
+	die("Usage: $argv[0] <file>\n");
+}
+$decompiler = new Decompiler();
+if (isset($argv[2])) {
+	eval('$pk = ' . file_get_contents($argv[2]) . ';');
+}
+else {
+	$pk = xcache_dasm_file($argv[1]);
+}
+$op_array = $funcs = $classes = null;
+if (isset($pk['op_array'])) {
+	$op_array = $pk['op_array'];
+	unset($pk['op_array']);
+}
+if (isset($pk['function_table'])) {
+	$funcs = $pk['function_table'];
+	unset($pk['function_table']);
+}
+if (isset($pk['class_table'])) {
+	$classes = $pk['class_table'];
+	unset($pk['class_table']);
+}
+var_dump($pk);
+if (isset($classes)) {
+	foreach ($classes as $name => $class) {
+		dump_class($name, $class);
+	}
+}
+if (isset($funcs)) {
+	foreach ($funcs as $name => $func) {
+		dump_function($name, $func);
+	}
+}
+if (isset($op_array)) {
+	dump_opcodes($op_array['opcodes']);
+}
+
Index: /trunk/config.m4
===================================================================
--- /trunk/config.m4	(revision 981)
+++ /trunk/config.m4	(revision 982)
@@ -1,9 +1,9 @@
 dnl vim:ts=2:sw=2:expandtab
 
-AC_DEFUN([XCACHE_OPTION], [
+AC_DEFUN([XCACHE_MODULE], [
   PHP_ARG_ENABLE(xcache-$1, for XCache $1,
   [  --enable-xcache-$2    XCache: $4], no, no)
   if test "$PHP_$3" != "no"; then
-    xcache_sources="$xcache_sources $1.c"
+    xcache_sources="$xcache_sources submodules/xc_$1.c"
     XCACHE_MODULES="$XCACHE_MODULES $1"
     HAVE_$3=1
@@ -18,28 +18,29 @@
 
 if test "$PHP_XCACHE" != "no"; then
-	PHP_ARG_ENABLE(xcache-constant, for XCache handle of compile time constant,
+  PHP_ARG_ENABLE(xcache-constant, for XCache handle of compile time constant,
   [  --enable-xcache-constant        XCache: Handle new constants made by php compiler (e.g.: for __halt_compiler)], yes, no)
-	if test "$PHP_XCACHE_CONSTANT" != "no"; then
-		AC_DEFINE([HAVE_XCACHE_CONSTANT], 1, [Define to enable XCache handling of compile time constants])
-	fi
+  if test "$PHP_XCACHE_CONSTANT" != "no"; then
+    AC_DEFINE([HAVE_XCACHE_CONSTANT], 1, [Define to enable XCache handling of compile time constants])
+  fi
 
-  xcache_sources="processor.c \
+  xcache_sources="
+                  main/xc_const_string.c \
+                  main/xc_lock.c \
+                  main/xc_mem.c \
+                  main/xc_opcode_spec.c \
+                  main/xc_processor.c \
+                  main/xc_shm.c \
+                  main/xc_shm_mmap.c \
+                  main/xc_utils.c \
+                  util/xc_stack.c \
                   xcache.c \
-                  mmap.c \
-                  mem.c \
-                  xc_shm.c \
-                  const_string.c \
-                  opcode_spec.c \
-                  stack.c \
-                  utils.c \
-                  lock.c \
                   "
   XCACHE_MODULES="cacher"
-  XCACHE_OPTION([optimizer],    [optimizer   ], [XCACHE_OPTIMIZER],    [(N/A)])
-  XCACHE_OPTION([coverager],    [coverager   ], [XCACHE_COVERAGER],    [Enable code coverage dumper, useful for testing php scripts])
-  XCACHE_OPTION([assembler],    [assembler   ], [XCACHE_ASSEMBLER],    [(N/A)])
-  XCACHE_OPTION([disassembler], [disassembler], [XCACHE_DISASSEMBLER], [Enable opcode to php variable dumper, NOT for production server])
-  XCACHE_OPTION([encoder],      [encoder     ], [XCACHE_ENCODER],      [(N/A)])
-  XCACHE_OPTION([decoder],      [decoder     ], [XCACHE_DECODER],      [(N/A)])
+  XCACHE_MODULE([optimizer],    [optimizer   ], [XCACHE_OPTIMIZER],    [(N/A)])
+  XCACHE_MODULE([coverager],    [coverager   ], [XCACHE_COVERAGER],    [Enable code coverage dumper, useful for testing php scripts])
+  XCACHE_MODULE([assembler],    [assembler   ], [XCACHE_ASSEMBLER],    [(N/A)])
+  XCACHE_MODULE([disassembler], [disassembler], [XCACHE_DISASSEMBLER], [Enable opcode to php variable dumper, NOT for production server])
+  XCACHE_MODULE([encoder],      [encoder     ], [XCACHE_ENCODER],      [(N/A)])
+  XCACHE_MODULE([decoder],      [decoder     ], [XCACHE_DECODER],      [(N/A)])
   AC_DEFINE_UNQUOTED([XCACHE_MODULES], "$XCACHE_MODULES", [Define what modules is built with XCache])
 
@@ -48,5 +49,5 @@
   if test "$PHP_XCACHE_TEST" != "no"; then
     XCACHE_ENABLE_TEST=-DXCACHE_ENABLE_TEST
-    xcache_sources="$xcache_sources xc_malloc.c"
+    xcache_sources="$xcache_sources main/xc_malloc.c"
     AC_DEFINE([HAVE_XCACHE_TEST], 1, [Define to enable XCache self test])
   else
@@ -116,19 +117,3 @@
   XCACHE_PROC_SOURCES=`ls $ac_srcdir/processor/*.m4`
   PHP_SUBST([XCACHE_PROC_SOURCES])
-
-  AC_MSG_CHECKING(if you have opcode_spec_def.h for XCache)
-  if test -e "$ac_srcdir/opcode_spec_def.h" ; then
-    AC_DEFINE([HAVE_XCACHE_OPCODE_SPEC_DEF], 1, [Define if you have opcode_spec_def.h for XCache])
-    AC_MSG_RESULT(yes)
-  else
-    dnl check for features depend on opcode_spec_def.h
-    AC_MSG_RESULT(no)
-    define([ERROR], [
-      AC_MSG_ERROR([cannot build with $1, $ac_srcdir/opcode_spec_def.h required])
-    ])
-    if test "$PHP_XCACHE_DISASSEMBLER" != "no" ; then
-      ERROR(disassembler)
-    fi
-    undefine([ERROR])
-  fi
 fi
Index: /trunk/config.w32
===================================================================
--- /trunk/config.w32	(revision 981)
+++ /trunk/config.w32	(revision 982)
@@ -12,14 +12,15 @@
 	// }}}
 
-	var xcache_sources = "processor.c \
+	var xcache_sources = "
+	                      main/xc_processor.c \
+	                      main/xc_const_string.c \
+	                      main/xc_lock.c \
+	                      main/xc_mem.c \
+	                      main/xc_opcode_spec.c \
+	                      main/xc_shm.c \
+	                      main/xc_shm_mmap.c \
+	                      main/xc_utils.c \
+	                      util/xc_stack.c \
 	                      xcache.c \
-	                      mmap.c \
-	                      mem.c \
-	                      xc_shm.c \
-	                      const_string.c \
-	                      opcode_spec.c \
-	                      stack.c \
-	                      utils.c \
-	                      lock.c \
 	                      ";
 	// {{{ add sources on enabled
@@ -41,5 +42,5 @@
 		var withval = eval("PHP_XCACHE_" + uname);
 		if (withval != "no") {
-			xcache_sources += " " + name + ".c";
+			xcache_sources += " submodules/xc_" + name + ".c";
 			XCACHE_MODULES += " " + name;
 			STDOUT.WriteLine("Enabling XCache Module: " + name);
@@ -76,5 +77,5 @@
 	if (PHP_XCACHE_TEST != "no") {
 		ADD_FLAG("XCACHE_ENABLE_TEST", "-DXCACHE_ENABLE_TEST");
-		xcache_sources += " xc_malloc.c";
+		xcache_sources += " main/xc_malloc.c";
 		AC_DEFINE("HAVE_XCACHE_TEST", 1, "Define to enable XCache self test");
 	}
@@ -130,22 +131,3 @@
 	XCACHE_PROC_SOURCES=glob(srcdir + "\\processor\\*.m4").join(' ');
 	ADD_FLAG("XCACHE_PROC_SOURCES", XCACHE_PROC_SOURCES);
-	// {{{ check for opcode_spec_def.h
-	STDOUT.Write("Checking if you have opcode_spec_def.h for XCache ... ");
-	var file = srcdir + "\\opcode_spec_def.h";
-	if (FSO.FileExists(file)) {
-		STDOUT.WriteLine("yes");
-		AC_DEFINE("HAVE_XCACHE_OPCODE_SPEC_DEF", 1, "Define if you have opcode_spec_def.h for XCache");
-	}
-	else {
-		STDOUT.WriteLine("no");
-
-		// check for features depend on opcode_spec_def.h
-		var xcache_require_opcode_spec_def = function(withval, name) {
-			if (withval != "no") {
-				ERROR(file + " is required to enable XCache " + name);
-			}
-		}
-		xcache_require_opcode_spec_def(PHP_XCACHE_DISASSEMBLER, "disassembler");
-	}
-	// }}}
 }
Index: unk/const_string.c
===================================================================
--- /trunk/const_string.c	(revision 981)
+++ 	(revision )
@@ -1,86 +1,0 @@
-#include "xcache.h"
-#include "const_string.h"
-
-/* {{{ xc_get_op_type */
-static const char *const op_type_names[] = {
-	/* 0 */ "NULL?",
-	/* 1 */ "IS_CONST",
-	/* 2 */ "IS_TMP_VAR",
-	/* 3 */ NULL,
-	/* 4 */ "IS_VAR",
-	/* 5 */ NULL,
-	/* 6 */ NULL,
-	/* 7 */ NULL,
-	/* 8 */ "IS_UNUSED",
-#ifdef IS_CV
-	/* 9  */ NULL,
-	/* 10 */ NULL,
-	/* 11 */ NULL,
-	/* 12 */ NULL,
-	/* 13 */ NULL,
-	/* 14 */ NULL,
-	/* 15 */ NULL,
-	/* 16 */ "IS_CV"
-#endif
-};
-
-zend_uchar xc_get_op_type_count()
-{
-	return sizeof(op_type_names) / sizeof(op_type_names[0]);
-}
-
-const char *xc_get_op_type(zend_uchar op_type)
-{
-	assert(op_type < xc_get_op_type_count());
-	return op_type_names[op_type];
-}
-/* }}} */
-/* {{{ xc_get_data_type */
-static const char *const data_type_names[] = {
-	/* 0 */ "IS_NULL",
-	/* 1 */ "IS_LONG",
-	/* 2 */ "IS_DOUBLE",
-	/* 3 */ "IS_BOOL",
-	/* 4 */ "IS_ARRAY",
-	/* 5 */ "IS_OBJECT",
-	/* 6 */ "IS_STRING",
-	/* 7 */ "IS_RESOURCE",
-	/* 8 */ "IS_CONSTANT",
-	/* 9 */ "IS_CONSTANT_ARRAY",
-	/* 10 */ "IS_UNICODE"
-};
-
-zend_uchar xc_get_data_type_count()
-{
-	return sizeof(data_type_names) / sizeof(data_type_names[0]);
-}
-
-const char *xc_get_data_type(zend_uchar data_type)
-{
-	return data_type_names[(data_type & IS_CONSTANT_TYPE_MASK)];
-}
-/* }}} */
-/* {{{ xc_get_opcode */
-#if PHP_MAJOR_VERSION >= 6
-#	include "const_string_opcodes_php6.x.h"
-#elif defined(ZEND_ENGINE_2_4)
-#	include "const_string_opcodes_php5.4.h"
-#elif defined(ZEND_ENGINE_2_1)
-#	include "const_string_opcodes_php5.1.h"
-#elif defined(ZEND_ENGINE_2)
-#	include "const_string_opcodes_php5.0.h"
-#else
-#	include "const_string_opcodes_php4.x.h"
-#endif
-
-zend_uchar xc_get_opcode_count()
-{
-	return sizeof(xc_opcode_names) / sizeof(xc_opcode_names[0]);
-}
-
-const char *xc_get_opcode(zend_uchar opcode)
-{
-	assert(opcode < xc_get_opcode_count());
-	return xc_opcode_names[opcode];
-}
-/* }}} */
Index: unk/const_string.h
===================================================================
--- /trunk/const_string.h	(revision 981)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include "php.h"
-
-zend_uchar xc_get_op_type_count();
-const char *xc_get_op_type(zend_uchar op_type);
-zend_uchar xc_get_data_type_count();
-const char *xc_get_data_type(zend_uchar data_type);
-zend_uchar xc_get_opcode_count();
-const char *xc_get_opcode(zend_uchar opcode);
Index: unk/const_string_opcodes_php4.x.h
===================================================================
--- /trunk/const_string_opcodes_php4.x.h	(revision 981)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/* size = 113 */
-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 */	"JMP_NO_CTOR",
-/* 70 */	"FREE",
-/* 71 */	"INIT_ARRAY",
-/* 72 */	"ADD_ARRAY_ELEMENT",
-/* 73 */	"INCLUDE_OR_EVAL",
-/* 74 */	"UNSET_VAR",
-/* 75 */	"UNSET_DIM_OBJ",
-/* 76 */	"ISSET_ISEMPTY",
-/* 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 */	"DECLARE_FUNCTION_OR_CLASS",
-/* 101 */	"EXT_STMT",
-/* 102 */	"EXT_FCALL_BEGIN",
-/* 103 */	"EXT_FCALL_END",
-/* 104 */	"EXT_NOP",
-/* 105 */	"TICKS",
-/* 106 */	"SEND_VAR_NO_REF",
-/* 107 */	"UNDEF",
-/* 108 */	"UNDEF",
-/* 109 */	"UNDEF",
-/* 110 */	"DO_FCALL_BY_FUNC",
-/* 111 */	"INIT_FCALL_BY_FUNC",
-/* 112 */	"UNDEF"
-};
Index: unk/const_string_opcodes_php5.0.h
===================================================================
--- /trunk/const_string_opcodes_php5.0.h	(revision 981)
+++ 	(revision )
@@ -1,153 +1,0 @@
-/* size = 149 */
-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 */	"JMP_NO_CTOR",
-/* 70 */	"FREE",
-/* 71 */	"INIT_ARRAY",
-/* 72 */	"ADD_ARRAY_ELEMENT",
-/* 73 */	"INCLUDE_OR_EVAL",
-/* 74 */	"UNSET_VAR",
-/* 75 */	"UNSET_DIM_OBJ",
-/* 76 */	"UNDEF",
-/* 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 */	"UNDEF",
-/* 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 */	"INIT_CTOR_CALL",
-/* 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 */	"UNDEF",
-/* 144 */	"ADD_INTERFACE",
-/* 145 */	"UNDEF",
-/* 146 */	"VERIFY_ABSTRACT_CLASS",
-/* 147 */	"ASSIGN_DIM",
-/* 148 */	"ISSET_ISEMPTY_PROP_OBJ",
-/* 149 */	"HANDLE_EXCEPTION"
-};
Index: unk/const_string_opcodes_php5.1.h
===================================================================
--- /trunk/const_string_opcodes_php5.1.h	(revision 981)
+++ 	(revision )
@@ -1,157 +1,0 @@
-/* size = 154 */
-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 */	"UNDEF",
-/* 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"
-};
Index: unk/const_string_opcodes_php5.4.h
===================================================================
--- /trunk/const_string_opcodes_php5.4.h	(revision 981)
+++ 	(revision )
@@ -1,162 +1,0 @@
-/* size = 159 */
-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"
-};
Index: unk/const_string_opcodes_php6.x.h
===================================================================
--- /trunk/const_string_opcodes_php6.x.h	(revision 981)
+++ 	(revision )
@@ -1,162 +1,0 @@
-/* size = 159 */
-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"
-};
Index: unk/coverager.c
===================================================================
--- /trunk/coverager.c	(revision 981)
+++ 	(revision )
@@ -1,593 +1,0 @@
-#if 0
-#define XCACHE_DEBUG
-#endif
-
-#include <stdio.h>
-#include "xcache.h"
-#include "ext/standard/flock_compat.h"
-#ifdef HAVE_SYS_FILE_H
-#	include <sys/file.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "stack.h"
-#include "xcache_globals.h"
-#include "coverager.h"
-#include "utils.h"
-typedef HashTable *coverager_t;
-#define PCOV_HEADER_MAGIC 0x564f4350
-
-static char *xc_coveragedump_dir = NULL;
-static zend_compile_file_t *old_compile_file = NULL;
-
-/* dumper */
-static void xc_destroy_coverage(void *pDest) /* {{{ */
-{
-	coverager_t cov = *(coverager_t*) pDest;
-	TRACE("destroy %p", cov);
-	zend_hash_destroy(cov);
-	efree(cov);
-}
-/* }}} */
-void xcache_mkdirs_ex(char *root, int rootlen, char *path, int pathlen TSRMLS_DC) /* {{{ */
-{
-	char *fullpath;
-	struct stat st;
-	ALLOCA_FLAG(use_heap)
-
-	TRACE("mkdirs %s %d %s %d", root, rootlen, path, pathlen);
-	fullpath = my_do_alloca(rootlen + pathlen + 1, use_heap);
-	memcpy(fullpath, root, rootlen);
-	memcpy(fullpath + rootlen, path, pathlen);
-	fullpath[rootlen + pathlen] = '\0';
-
-	if (stat(fullpath, &st) != 0) {
-		char *chr;
-
-		chr = strrchr(path, PHP_DIR_SEPARATOR);
-		if (chr && chr != path) {
-			*chr = '\0';
-			xcache_mkdirs_ex(root, rootlen, path, chr - path TSRMLS_CC);
-			*chr = PHP_DIR_SEPARATOR;
-		}
-		TRACE("mkdir %s", fullpath);
-#if PHP_MAJOR_VERSION > 5
-		php_stream_mkdir(fullpath, 0700, REPORT_ERRORS, NULL);
-#else
-		mkdir(fullpath, 0700);
-#endif
-	}
-	my_free_alloca(fullpath, use_heap);
-}
-/* }}} */
-static void xc_coverager_save_cov(char *srcfile, char *outfilename, coverager_t cov TSRMLS_DC) /* {{{ */
-{
-	long *buf = NULL, *p;
-	long covlines, *phits;
-	int fd = -1;
-	int size;
-	int newfile;
-	struct stat srcstat, outstat;
-	HashPosition pos;
-	char *contents = NULL;
-	long len;
-
-	if (stat(srcfile, &srcstat) != 0) {
-		return;
-	}
-
-	newfile = 0;
-	if (stat(outfilename, &outstat) != 0) {
-		newfile = 1;
-	}
-	else {
-		if (srcstat.st_mtime > outstat.st_mtime) {
-			newfile = 1;
-		}
-	}
-
-	fd = open(outfilename, O_RDWR | O_CREAT, 0600);
-	if (fd < 0) {
-		char *chr;
-		chr = strrchr(srcfile, PHP_DIR_SEPARATOR);
-		if (chr) {
-			*chr = '\0';
-			xcache_mkdirs_ex(xc_coveragedump_dir, strlen(xc_coveragedump_dir), srcfile, chr - srcfile TSRMLS_CC);
-			*chr = PHP_DIR_SEPARATOR;
-		}
-		fd = open(outfilename, O_RDWR | O_CREAT, 0600);
-		if (fd < 0) {
-			goto bailout;
-		}
-	}
-	if (flock(fd, LOCK_EX) != SUCCESS) {
-		goto bailout;
-	}
-
-	if (newfile) {
-		TRACE("%s", "new file");
-	}
-	else if (outstat.st_size) {
-		len = outstat.st_size;
-		contents = emalloc(len);
-		if (read(fd, (void *) contents, len) != len) {
-			goto bailout;
-		}
-		TRACE("oldsize %d", (int) len);
-		do {
-			p = (long *) contents;
-			len -= sizeof(long);
-			if (len < 0) {
-				break;
-			}
-			if (*p++ != PCOV_HEADER_MAGIC) {
-				TRACE("wrong magic in file %s", outfilename);
-				break;
-			}
-
-			p += 2; /* skip covliens */
-			len -= sizeof(long) * 2;
-			if (len < 0) {
-				break;
-			}
-
-			for (; len >= sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
-				if (zend_hash_index_find(cov, p[0], (void**)&phits) == SUCCESS) {
-					if (p[1] == -1) {
-						/* OPTIMIZE: already marked */
-						continue;
-					}
-					if (*phits != -1) {
-						p[1] += *phits;
-					}
-				}
-				zend_hash_index_update(cov, p[0], &p[1], sizeof(p[1]), NULL);
-			}
-		} while (0);
-		efree(contents);
-		contents = NULL;
-	}
-
-
-	/* serialize */
-	size = (zend_hash_num_elements(cov) + 1) * sizeof(long) * 2 + sizeof(long);
-	p = buf = emalloc(size);
-	*p++ = PCOV_HEADER_MAGIC;
-	p += 2; /* for covlines */
-	covlines = 0;
-
-	zend_hash_internal_pointer_reset_ex(cov, &pos);
-	while (zend_hash_get_current_data_ex(cov, (void**)&phits, &pos) == SUCCESS) {
-		*p++ = pos->h;
-		*p++ = *phits;
-		if (*phits > 0) {
-			covlines ++;
-		}
-		zend_hash_move_forward_ex(cov, &pos);
-	}
-	p = buf + 1;
-	p[0] = 0;
-	p[1] = covlines;
-
-	if (ftruncate(fd, 0) != 0) {
-		goto bailout;
-	}
-	lseek(fd, 0, SEEK_SET);
-	if (write(fd, (char *) buf, size) != size) {
-		goto bailout;
-	}
-
-bailout:
-	if (contents) efree(contents);
-	if (fd >= 0) close(fd);
-	if (buf) efree(buf);
-}
-/* }}} */
-
-static void xc_coverager_initenv(TSRMLS_D) /* {{{ */
-{
-	if (!XG(coverages)) {
-		XG(coverages) = emalloc(sizeof(HashTable));
-		zend_hash_init(XG(coverages), 0, NULL, xc_destroy_coverage, 0);
-	}
-}
-/* }}} */
-static void xc_coverager_clean(TSRMLS_D) /* {{{ */
-{
-	if (XG(coverages)) {
-		HashPosition pos;
-		coverager_t *pcov;
-
-		zend_hash_internal_pointer_reset_ex(XG(coverages), &pos);
-		while (zend_hash_get_current_data_ex(XG(coverages), (void **) &pcov, &pos) == SUCCESS) {
-			long *phits;
-			coverager_t cov;
-			HashPosition pos2;
-
-			cov = *pcov;
-
-			zend_hash_internal_pointer_reset_ex(cov, &pos2);
-			while (zend_hash_get_current_data_ex(cov, (void**)&phits, &pos2) == SUCCESS) {
-				long hits = *phits;
-
-				if (hits != -1) {
-					hits = -1;
-					zend_hash_index_update(cov, pos2->h, &hits, sizeof(hits), NULL);
-				}
-				zend_hash_move_forward_ex(cov, &pos2);
-			}
-
-			zend_hash_move_forward_ex(XG(coverages), &pos);
-		}
-	}
-}
-/* }}} */
-static void xc_coverager_cleanup(TSRMLS_D) /* {{{ */
-{
-	if (XG(coverages)) {
-		zend_hash_destroy(XG(coverages));
-		efree(XG(coverages));
-		XG(coverages) = NULL;
-	}
-}
-/* }}} */
-
-static void xc_coverager_enable(TSRMLS_D) /* {{{ */
-{
-	XG(coverage_enabled) = 1;
-}
-/* }}} */
-static void xc_coverager_disable(TSRMLS_D) /* {{{ */
-{
-	XG(coverage_enabled) = 0;
-}
-/* }}} */
-
-void xc_coverager_request_init(TSRMLS_D) /* {{{ */
-{
-	if (XG(coverager)) {
-		xc_coverager_enable(TSRMLS_C);
-#ifdef ZEND_COMPILE_EXTENDED_INFO
-		CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
-#else
-		CG(extended_info) = 1;
-#endif
-	}
-	else {
-		XG(coverage_enabled) = 0;
-	}
-}
-/* }}} */
-static void xc_coverager_autodump(TSRMLS_D) /* {{{ */
-{
-	coverager_t *pcov;
-	zstr s;
-	char *outfilename;
-	int dumpdir_len, outfilelen, alloc_len = 0;
-	uint size;
-	HashPosition pos;
-
-	if (XG(coverages) && xc_coveragedump_dir) {	
-		dumpdir_len = strlen(xc_coveragedump_dir);
-		alloc_len = dumpdir_len + 1 + 128;
-		outfilename = emalloc(alloc_len);
-		strcpy(outfilename, xc_coveragedump_dir);
-
-		zend_hash_internal_pointer_reset_ex(XG(coverages), &pos);
-		while (zend_hash_get_current_data_ex(XG(coverages), (void **) &pcov, &pos) == SUCCESS) {
-			zend_hash_get_current_key_ex(XG(coverages), &s, &size, NULL, 0, &pos);
-			outfilelen = dumpdir_len + size + 5;
-			if (alloc_len < outfilelen) {
-				alloc_len = outfilelen + 128;
-				outfilename = erealloc(outfilename, alloc_len);
-			}
-			strcpy(outfilename + dumpdir_len, ZSTR_S(s));
-			strcpy(outfilename + dumpdir_len + size - 1, ".pcov");
-
-			TRACE("outfilename %s", outfilename);
-			xc_coverager_save_cov(ZSTR_S(s), outfilename, *pcov TSRMLS_CC);
-			zend_hash_move_forward_ex(XG(coverages), &pos);
-		}
-		efree(outfilename);
-	}
-}
-/* }}} */
-static void xc_coverager_dump(zval *return_value TSRMLS_DC) /* {{{ */
-{
-	coverager_t *pcov;
-	HashPosition pos;
-
-	if (XG(coverages)) {
-		array_init(return_value);
-
-		zend_hash_internal_pointer_reset_ex(XG(coverages), &pos);
-		while (zend_hash_get_current_data_ex(XG(coverages), (void **) &pcov, &pos) == SUCCESS) {
-			zval *lines;
-			long *phits;
-			coverager_t cov;
-			HashPosition pos2;
-			zstr filename;
-			uint size;
-
-			cov = *pcov;
-			zend_hash_get_current_key_ex(XG(coverages), &filename, &size, NULL, 0, &pos);
-
-			MAKE_STD_ZVAL(lines);
-			array_init(lines);
-			zend_hash_internal_pointer_reset_ex(cov, &pos2);
-			while (zend_hash_get_current_data_ex(cov, (void**)&phits, &pos2) == SUCCESS) {
-				long hits = *phits;
-				add_index_long(lines, pos2->h, hits >= 0 ? hits : 0);
-				zend_hash_move_forward_ex(cov, &pos2);
-			}
-			add_assoc_zval_ex(return_value, ZSTR_S(filename), strlen(ZSTR_S(filename)) + 1, lines);
-
-			zend_hash_move_forward_ex(XG(coverages), &pos);
-		}
-	}
-	else {
-		RETVAL_NULL();
-	}
-}
-/* }}} */
-void xc_coverager_request_shutdown(TSRMLS_D) /* {{{ */
-{
-	if (XG(coverager)) {
-		xc_coverager_autodump(TSRMLS_C);
-		xc_coverager_cleanup(TSRMLS_C);
-	}
-}
-/* }}} */
-
-/* helper func to store hits into coverages */
-static coverager_t xc_coverager_get(const char *filename TSRMLS_DC) /* {{{ */
-{
-	int len = strlen(filename) + 1;
-	coverager_t cov, *pcov;
-
-	if (zend_u_hash_find(XG(coverages), IS_STRING, filename, len, (void **) &pcov) == SUCCESS) {
-		TRACE("got coverage %s %p", filename, *pcov);
-		return *pcov;
-	}
-	else {
-		cov = emalloc(sizeof(HashTable));
-		zend_hash_init(cov, 0, NULL, NULL, 0);
-		zend_u_hash_add(XG(coverages), IS_STRING, filename, len, (void **) &cov, sizeof(cov), NULL);
-		TRACE("new coverage %s %p", filename, cov);
-		return cov;
-	}
-}
-/* }}} */
-static void xc_coverager_add_hits(HashTable *cov, long line, long hits TSRMLS_DC) /* {{{ */
-{
-	long *poldhits;
-
-	if (line == 0) {
-		return;
-	}
-	if (zend_hash_index_find(cov, line, (void**)&poldhits) == SUCCESS) {
-		if (hits == -1) {
-			/* OPTIMIZE: -1 == init-ing, but it's already initized */
-			return;
-		}
-		if (*poldhits != -1) {
-			hits += *poldhits;
-		}
-	}
-	zend_hash_index_update(cov, line, &hits, sizeof(hits), NULL);
-}
-/* }}} */
-
-static int xc_coverager_get_op_array_size_no_tail(zend_op_array *op_array) /* {{{ */
-{
-	zend_uint last = op_array->last;
-	do {
-next_op:
-		if (last == 0) {
-			break;
-		}
-		switch (op_array->opcodes[last - 1].opcode) {
-#ifdef ZEND_HANDLE_EXCEPTION
-			case ZEND_HANDLE_EXCEPTION:
-#endif
-			case ZEND_RETURN:
-			case ZEND_EXT_STMT:
-				--last;
-				goto next_op;
-		}
-	} while (0);
-	return last;
-}
-/* }}} */
-
-/* prefill */
-static int xc_coverager_init_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	zend_uint size;
-	coverager_t cov;
-	zend_uint i;
-
-	if (op_array->type != ZEND_USER_FUNCTION) {
-		return 0;
-	}
-
-	size = xc_coverager_get_op_array_size_no_tail(op_array);
-	cov = xc_coverager_get(op_array->filename TSRMLS_CC);
-	for (i = 0; i < size; i ++) {
-		switch (op_array->opcodes[i].opcode) {
-			case ZEND_EXT_STMT:
-#if 0
-			case ZEND_EXT_FCALL_BEGIN:
-			case ZEND_EXT_FCALL_END:
-#endif
-				xc_coverager_add_hits(cov, op_array->opcodes[i].lineno, -1 TSRMLS_CC);
-				break;
-		}
-	}
-	return 0;
-}
-/* }}} */
-static void xc_coverager_init_compile_result(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	xc_compile_result_t cr;
-
-	xc_compile_result_init_cur(&cr, op_array TSRMLS_CC);
-	xc_apply_op_array(&cr, (apply_func_t) xc_coverager_init_op_array TSRMLS_CC);
-	xc_compile_result_free(&cr);
-}
-/* }}} */
-static zend_op_array *xc_compile_file_for_coverage(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */
-{
-	zend_op_array *op_array;
-
-	op_array = old_compile_file(h, type TSRMLS_CC);
-	if (op_array) {
-		if (XG(coverager)) {
-			xc_coverager_initenv(TSRMLS_C);
-			xc_coverager_init_compile_result(op_array TSRMLS_CC);
-		}
-	}
-	return op_array;
-}
-/* }}} */
-
-/* hits */
-void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op) /* {{{ */
-{
-	TSRMLS_FETCH();
-
-	if (XG(coverages) && XG(coverage_enabled)) {
-		int size = xc_coverager_get_op_array_size_no_tail(op_array);
-		int oplineno = (*EG(opline_ptr)) - op_array->opcodes;
-		if (oplineno < size) {
-			xc_coverager_add_hits(xc_coverager_get(op_array->filename TSRMLS_CC), (*EG(opline_ptr))->lineno, 1 TSRMLS_CC);
-		}
-	}
-}
-/* }}} */
-
-/* init/destroy */
-int xc_coverager_init(int module_number TSRMLS_DC) /* {{{ */
-{
-	old_compile_file = zend_compile_file;
-	zend_compile_file = xc_compile_file_for_coverage;
-
-	if (cfg_get_string("xcache.coveragedump_directory", &xc_coveragedump_dir) == SUCCESS && xc_coveragedump_dir) {
-		int len;
-		xc_coveragedump_dir = pestrdup(xc_coveragedump_dir, 1);
-		len = strlen(xc_coveragedump_dir);
-		if (len) {
-			if (xc_coveragedump_dir[len - 1] == '/') {
-				xc_coveragedump_dir[len - 1] = '\0';
-			}
-		}
-		if (!strlen(xc_coveragedump_dir)) {
-			pefree(xc_coveragedump_dir, 1);
-			xc_coveragedump_dir = NULL;
-		}
-	}
-
-	return SUCCESS;
-}
-/* }}} */
-void xc_coverager_destroy() /* {{{ */
-{
-	if (old_compile_file == xc_compile_file_for_coverage) {
-		zend_compile_file = old_compile_file;
-	}
-	if (xc_coveragedump_dir) {
-		pefree(xc_coveragedump_dir, 1);
-		xc_coveragedump_dir = NULL;
-	}
-}
-/* }}} */
-
-/* user api */
-/* {{{ proto array xcache_coverager_decode(string data)
- * decode specified data which is saved by auto dumper to array
- */
-PHP_FUNCTION(xcache_coverager_decode)
-{
-	char *str;
-	int len;
-	long *p;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) {
-		return;
-	}
-
-	array_init(return_value);
-
-	p = (long*) str;
-	len -= sizeof(long);
-	if (len < 0) {
-		return;
-	}
-	if (*p++ != PCOV_HEADER_MAGIC) {
-		TRACE("%s", "wrong magic in xcache_coverager_decode");
-		return;
-	}
-
-	for (; len >= sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
-		add_index_long(return_value, p[0], p[1] < 0 ? 0 : p[1]);
-	}
-}
-/* }}} */
-/* {{{ proto void xcache_coverager_start([bool clean = true])
- * starts coverager data collecting
- */
-PHP_FUNCTION(xcache_coverager_start)
-{
-	zend_bool clean = 1;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
-		return;
-	}
-
-	if (clean) {
-		xc_coverager_clean(TSRMLS_C);
-	}
-
-	if (XG(coverager)) {
-		xc_coverager_enable(TSRMLS_C);
-	}
-	else {
-		php_error(E_WARNING, "You can only start coverager after you set 'xcache.coverager' to 'On' in ini");
-	}
-}
-/* }}} */
-/* {{{ proto void xcache_coverager_stop([bool clean = false])
- * stop coverager data collecting
- */
-PHP_FUNCTION(xcache_coverager_stop)
-{
-	zend_bool clean = 0;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
-		return;
-	}
-
-	xc_coverager_disable(TSRMLS_C);
-	if (clean) {
-		xc_coverager_clean(TSRMLS_C);
-	}
-}
-/* }}} */
-/* {{{ proto array xcache_coverager_get([bool clean = false])
- * get coverager data collected
- */
-PHP_FUNCTION(xcache_coverager_get)
-{
-	zend_bool clean = 0;
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
-		return;
-	}
-
-	xc_coverager_dump(return_value TSRMLS_CC);
-	if (clean) {
-		xc_coverager_clean(TSRMLS_C);
-	}
-}
-/* }}} */
Index: unk/coverager.h
===================================================================
--- /trunk/coverager.h	(revision 981)
+++ 	(revision )
@@ -1,12 +1,0 @@
-#include "php.h"
-#include "xcache.h"
-
-void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op);
-int xc_coverager_init(int module_number TSRMLS_DC);
-void xc_coverager_destroy();
-void xc_coverager_request_init(TSRMLS_D);
-void xc_coverager_request_shutdown(TSRMLS_D);
-PHP_FUNCTION(xcache_coverager_decode);
-PHP_FUNCTION(xcache_coverager_start);
-PHP_FUNCTION(xcache_coverager_stop);
-PHP_FUNCTION(xcache_coverager_get);
Index: /trunk/devel/gen_const_string_opcodes.awk
===================================================================
--- /trunk/devel/gen_const_string_opcodes.awk	(revision 982)
+++ /trunk/devel/gen_const_string_opcodes.awk	(revision 982)
@@ -0,0 +1,77 @@
+#! /usr/bin/awk -f
+# vim:ts=4:sw=4
+# process zend_vm_def.h or zend_compile.h
+BEGIN {
+	FS=" "
+	max = 0;
+}
+
+/^ZEND_VM_HANDLER\(/ {
+	# regex from php5.1+/Zend/zend_vm_gen.php
+	gsub(/ +/, "");
+	if (!match($0, /^ZEND_VM_HANDLER\(([0-9]+),([A-Z_]+),([A-Z|]+),([A-Z|]+)\)/)) {
+		print "error unmatch $0";
+		exit;
+	}
+	# life is hard without 3rd argument of match()
+	sub(/^ZEND_VM_HANDLER\(/, "");
+	id = $0;
+	sub(/,.*/, "", id); # chop
+	id = 0 + id;
+	sub(/^([0-9]+),/, "");
+	sub(/,.*/, ""); # chop
+	name = $0;
+	if (max < id) {
+		max = id;
+	}
+	opcodes[id] = name;
+	next;
+}
+
+/^#define +ZEND_[A-Z_]+[\t ]+[[:digit:]]+$/ {
+	id = 0 + $3;
+	name = $2;
+	if (max < id) {
+		max = id;
+	}
+	opcodes[id] = name;
+	next;
+}
+
+/end of block/ {
+	exit;
+}
+
+END {
+	mymax = 112;
+	if (max < mymax) {
+		for (i = max + 1; i <= mymax; i ++) {
+			opcodes[i] = "UNDEF";
+		}
+		max = mymax;
+		opcodes[110] = "ZEND_DO_FCALL_BY_FUNC";
+		opcodes[111] = "ZEND_INIT_FCALL_BY_FUNC";
+		opcodes[112] = "UNDEF";
+	}
+	printf "/* size = %d */\n", max + 1;
+	print "static const char *const xc_opcode_names[] = {";
+	for (i = 0; i <= max; i ++) {
+		if (i != 0) {
+			print ",";
+		}
+		printf "/* %d */\t", i
+		if (i in opcodes) {
+			name = opcodes[i];
+			sub(/^ZEND_/, "", name);
+			printf "\"%s\"", name;
+		}
+		else if (i == 137) {
+			printf "\"%s\"", "OP_DATA";
+		}
+		else {
+			printf "\"UNDEF\"";
+		}
+	}
+	print "";
+	print "};";
+}
Index: /trunk/devel/gen_xc_opcode_spec.awk
===================================================================
--- /trunk/devel/gen_xc_opcode_spec.awk	(revision 982)
+++ /trunk/devel/gen_xc_opcode_spec.awk	(revision 982)
@@ -0,0 +1,46 @@
+#! /usr/bin/awk -f
+# vim:ts=4:sw=4
+# process eaccelerator/opcodes.c
+BEGIN {
+	FS=" "
+	max = 0;
+	started = 0
+}
+
+/OPDEF/ {
+	if (started) {
+		name = "";
+		if (match($0, /"([^"]+)"/, m)) { 
+			name = m[1]; 
+		} 
+		sub(/"[^"]*"/, "");
+		if (!match($0, /EXT_([^ |]+).*OP[1S]_([^ |]+).*OP2_([^ |]+).*RES_([^ |)]+).*/, array)) {
+			print "error" $0
+			exit
+		}
+		id = "";
+		if (match($0, /\/\* *([0-9]+) *\*\//, comments)) {
+			id = comments[1];
+		}
+		printf "\tOPSPEC(%10s, %10s, %10s, %10s) /* %s %-30s */\n", array[1], array[2], array[3], array[4], id, name;
+		next
+	}
+}
+/^}/ {
+	print $0
+	exit;
+}
+/^[ ]*,[ ]*$/ {
+	next
+}
+{
+	if (started) {
+		print $0
+		next
+	}
+}
+
+/^static/ {
+	started = 1;
+	print "static const xc_opcode_spec_t xc_opcode_spec[] = {"
+}
Index: /trunk/devel/graph/cached_compile.dot
===================================================================
--- /trunk/devel/graph/cached_compile.dot	(revision 982)
+++ /trunk/devel/graph/cached_compile.dot	(revision 982)
@@ -0,0 +1,31 @@
+digraph tree {
+	subgraph cluster_compiling {
+		label="compiling";
+		php_compile;
+		php_store;
+		entry_store;
+	}
+	error [color=red];
+	origin_compile [color=red]
+
+	begin -> origin_compile [label="compiling", color=red];
+
+	begin -> entry_init_key -> entry_lookup;
+	edge [label=hit, color=blue]
+	entry_lookup -> restore;
+	php_lookup -> entry_store;
+	edge [label=miss, color=green]
+	entry_lookup -> md5_init;
+	md5_init -> php_lookup;
+	php_lookup -> php_compile;
+
+	edge [label="", color=""]
+	php_lookup -> origin_compile [label="miss but compiling", color=red];
+	php_compile -> php_store -> entry_store -> restore;
+
+	edge [color=red];
+	md5_init -> error;
+	php_compile -> error;
+	php_store -> error;
+	entry_store -> error;
+}
Index: /trunk/devel/prepare.devel
===================================================================
--- /trunk/devel/prepare.devel	(revision 982)
+++ /trunk/devel/prepare.devel	(revision 982)
@@ -0,0 +1,105 @@
+#! /bin/bash
+SELF="$0"
+
+if test -e prepare.devel.inc ; then
+	. prepare.devel.inc
+else
+	echo prepare.devel.inc is required, see prepare.devel.inc.example >&2
+	exit
+fi
+
+CTAGS=`which ctags 2>/dev/null || which exuberant-ctags 2>/dev/null `
+AWK=`which gawk 2>/dev/null || which awk 2>/dev/null `
+
+make_all() {
+	make_xc_opcode_spec_def.h
+	make_xc_const_string
+	test -e tags && echo tags exists, skipping. use \""$0" tags\" to rebuild || make_tags
+}
+
+make_clean() {
+ 	make_clean_xc_const_string
+	echo "*" rm -f tags xc_opcode_spec_def.h
+	rm -f tags xc_opcode_spec_def.h
+}
+
+make_xc_const_string() {
+	make_xc_const_string_opcodes_php4.x.h
+	make_xc_const_string_opcodes_php5.0.h
+	make_xc_const_string_opcodes_php5.1.h
+	make_xc_const_string_opcodes_php5.4.h
+	make_xc_const_string_opcodes_php6.x.h
+}
+
+make_clean_xc_const_string() {
+	echo "*" rm -f main/xc_const_string_opcodes_php*.h{,.tmp}
+	rm -f main/xc_const_string_opcodes_php*.h
+}
+
+make_xc_const_string_opcodes_php4.x.h() {
+	precheck main/xc_const_string_opcodes_php4.x.h "${PHP4_x_DIR}/Zend/zend_compile.h" && "$AWK" -f ./devel/gen_const_string_opcodes.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
+}
+
+make_xc_const_string_opcodes_php5.0.h() {
+	precheck main/xc_const_string_opcodes_php5.0.h "${PHP5_0_DIR}/Zend/zend_compile.h" && "$AWK" -f ./devel/gen_const_string_opcodes.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
+}
+
+make_xc_const_string_opcodes_php5.1.h() {
+	precheck main/xc_const_string_opcodes_php5.1.h "${PHP5_1_DIR}/Zend/zend_vm_def.h"  && "$AWK" -f ./devel/gen_const_string_opcodes.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
+}
+
+make_xc_const_string_opcodes_php5.4.h() {
+	precheck main/xc_const_string_opcodes_php5.4.h "${PHP5_4_DIR}/Zend/zend_vm_def.h"  && "$AWK" -f ./devel/gen_const_string_opcodes.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
+}
+
+make_xc_const_string_opcodes_php6.x.h() {
+	precheck main/xc_const_string_opcodes_php6.x.h "${PHP6_x_DIR}/Zend/zend_vm_def.h"  && "$AWK" -f ./devel/gen_const_string_opcodes.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
+}
+
+make_xc_opcode_spec_def.h() {
+	precheck main/xc_opcode_spec_def.h "${EA_DIR}/opcodes.c" && "$AWK" -f ./devel/gen_xc_opcode_spec.awk < "$I" > "$O"
+}
+
+make_tags() {
+	if test -z "$CTAGS" ; then
+		echo tool ctags not found, skip building tags >&2
+		return
+	fi
+
+	if test -d "${PHP_DEVEL_DIR}" ; then
+		echo "* Making tags with ${PHP_DEVEL_DIR}"
+		"$CTAGS" -R . "${PHP_DEVEL_DIR}/main" "${PHP_DEVEL_DIR}/Zend" "${PHP_DEVEL_DIR}/TSRM" "${PHP_DEVEL_DIR}/ext/standard"
+	else
+		echo "* Making tags without php source files"
+		"$CTAGS" -R .
+	fi
+}
+
+error() {
+	echo "$@" >&2
+}
+
+precheck() {
+	if test -e "$2" ; then :; else
+		error X skipping "$1" because "$2" not found
+		return 1
+	fi
+	if test "$1" -ot "$2" ; then :; else
+		echo O "$1" is up to date.
+		return 1
+	fi
+	O="$1"
+	I="$2"
+	echo "* Making $1 from $2"
+	return 0
+}
+
+if test -z "$1" ; then
+	make_all
+else
+	while ! test -z "$1" ; do
+		eval "make_$1"
+		shift
+	done
+fi
+
Index: /trunk/devel/prepare.devel.inc.example
===================================================================
--- /trunk/devel/prepare.devel.inc.example	(revision 982)
+++ /trunk/devel/prepare.devel.inc.example	(revision 982)
@@ -0,0 +1,11 @@
+# copy this file as ../devel.prepare.inc before modifying
+PHP4_x_DIR=
+PHP5_0_DIR=
+PHP5_1_DIR=
+PHP5_3_DIR=
+PHP6_x_DIR=
+
+PHP_DEVEL_DIR=
+
+# path to eaccelerator source dir
+EA_DIR=
Index: /trunk/devel/run
===================================================================
--- /trunk/devel/run	(revision 982)
+++ /trunk/devel/run	(revision 982)
@@ -0,0 +1,137 @@
+#!/bin/bash
+# this script is for developers only
+
+. run.cfg
+
+basename=$(basename $(pwd))
+if echo $basename | grep -- - >/dev/null; then :; else
+	dirs=${dirs:-php5-debug}
+
+	for dir in $dirs; do
+		cd ../${basename}-${dir} || exit
+
+		rm -f php-src
+		find -L . -type l | xargs rm -f
+		lndir ../$basename >/dev/null
+		find . -iname .\*.swp | xargs rm -f
+		ln -sf ~/src/php/$dir php-src
+		for i in ~/src/php/$dir/sapi/cgi/php{,-cgi}; do
+			[[ -r $i ]] && ln -sf "$i" php-cgi
+		done
+		ln -sf ~/src/php/$dir/sapi/cli/php php-cli
+
+		pwd
+		$0 "$@"
+	done
+	exit
+fi
+phpbasename=${basename#*-}
+xcachebasename=${basename%%-*}
+
+if [[ ! -z $1 ]]; then
+	type=$1
+	shift
+
+	if [[ ! -z $1 ]]; then
+		args=("$@")
+	elif [[ -z $args ]]; then
+		args=(test.php)
+	fi
+fi
+
+case $type in
+prepare)
+	exec ./devel/prepare.devel
+	;;
+tags)
+	exec ./devel/prepare.devel tags
+	;;
+rebuild)
+	PHPDIRS=${PHPDIRS:-$HOME/test}
+	if [[ ! -x $PHPDIRS/$phpbasename/bin/phpize ]]; then
+		echo $PHPDIRS/$phpbasename/bin/phpize not found
+		exit
+	fi
+	export PATH=$PHPDIRS/$phpbasename/bin:$PATH
+	phpize --clean \
+	&& phpize \
+	&& CFLAGS="-Wall -Wno-unused -W -Wshadow -std=gnu99" ./configure --enable-xcache-disassembler --enable-xcache-test --enable-xcache-constant \
+	&& make
+	exit
+	;;
+make)
+	MAKEARGS=("$@")
+	;;
+esac
+
+LANG=C /usr/bin/make $MAKEOPTS "${MAKEARGS[@]}" 2>&1 | hi error implicit warn FAIL
+ret=${PIPESTATUS[0]}
+if [[ $ret -ne 0 || $type = make ]]; then
+	exit $ret
+fi
+
+cmd=()
+tracer=()
+case "$basename" in
+*-apache1*)
+	cmd=($HOME/apache1/bin/httpd -X)
+	;;
+*-apache*)
+	exit 1
+	;;
+*)
+	cmd=(./php-cgi -q -c php.ini)
+	"${cmd[@]}" -v
+	;;
+esac
+
+case "${args[0]}" in
+fcgi)
+	args=(-b 1026)
+	shift
+	;;
+esac
+
+case "$type" in
+ltr*)
+	export USE_ZEND_ALLOC=0
+	tracer=(ltrace -s1024 -e malloc,realloc,free,write)
+	;;
+str*)
+	tracer=(strace -s1024 -T ./php-cgi)
+	;;
+gdb)
+	#USE_ZEND_ALLOC=0
+	tracer=(gdb --args)
+	;;
+val*)
+	export USE_ZEND_ALLOC=0
+	tracer=(valgrind --gen-suppressions=all)
+	;;
+dc)
+	exec ./php-cli -c php.ini ./bin/phpdc.phpr "${args[@]}" | tee decompiled.php
+	;;
+dop)
+	exec ./php-cli -c php.ini ./bin/phpdop.phpr "${args[@]}"
+	;;
+retest)
+	exec make xcachetest "$@" TESTS="`grep '^/.*\.phpt$' php_test_results_*.txt | uniq | xargs`"
+	;;
+test)
+	case "${args[0]}" in
+	*.phpt)
+		exec make xcachetest TEST_ARGS=-v TESTS="${args[*]}"
+		;;
+	*/)
+		exec make xcachetest TESTS="${args[@]}"
+		;;
+	*)
+		exec make xcachetest
+		;;
+	esac
+	;;
+esac
+
+export XCACHE_SKIP_FCGI_WARNING=1
+echo "${tracer[@]}" "${cmd[@]}" "${args[@]}"
+exec "${tracer[@]}" "${cmd[@]}" "${args[@]}"
Index: /trunk/devel/test.mak
===================================================================
--- /trunk/devel/test.mak	(revision 982)
+++ /trunk/devel/test.mak	(revision 982)
@@ -0,0 +1,21 @@
+#! /usr/bin/make -f
+
+EXES=mem_test
+OBJS=mem.o
+CC=gcc
+CFLAGS=-g -O0 -D TEST -Wall
+TEST=valgrind
+
+all: mem
+
+mem_test: mem.c
+	$(CC) $(CFLAGS) -o mem_test mem.c
+	
+mem: mem_test
+	$(TEST) ./mem_test
+
+clean:
+	rm -f $(OBJS) $(EXES)
+
+leakcheck:
+	valgrind php -c test.ini test.ini
Index: unk/disassembler.c
===================================================================
--- /trunk/disassembler.c	(revision 981)
+++ 	(revision )
@@ -1,192 +1,0 @@
-#include "disassembler.h"
-#include "xcache.h"
-#include "utils.h"
-#include "processor.h"
-
-#ifndef HAVE_XCACHE_OPCODE_SPEC_DEF
-#error disassembler cannot be built without xcache/opcode_spec_def.h
-#endif
-static void xc_dasm(zval *output, zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	const Bucket *b;
-	zval *zv, *list;
-	xc_compile_result_t cr;
-	int bufsize = 2;
-	char *buf;
-	xc_dasm_t dasm;
-
-	xc_compile_result_init_cur(&cr, op_array TSRMLS_CC);
-
-	xc_apply_op_array(&cr, (apply_func_t) xc_undo_pass_two TSRMLS_CC);
-	xc_apply_op_array(&cr, (apply_func_t) xc_fix_opcode TSRMLS_CC);
-
-	/* go */
-	array_init(output);
-
-	ALLOC_INIT_ZVAL(zv);
-	array_init(zv);
-	xc_dasm_zend_op_array(&dasm, zv, op_array TSRMLS_CC);
-	add_assoc_zval_ex(output, ZEND_STRS("op_array"), zv);
-
-	buf = emalloc(bufsize);
-
-	ALLOC_INIT_ZVAL(list);
-	array_init(list);
-	for (b = xc_sandbox_user_function_begin(TSRMLS_C); b; b = b->pListNext) {
-		int keysize, keyLength;
-
-		ALLOC_INIT_ZVAL(zv);
-		array_init(zv);
-		xc_dasm_zend_function(&dasm, zv, b->pData TSRMLS_CC);
-
-		keysize = BUCKET_KEY_SIZE(b) + 2;
-		if (keysize > bufsize) {
-			do {
-				bufsize *= 2;
-			} while (keysize > bufsize);
-			buf = erealloc(buf, bufsize);
-		}
-		memcpy(buf, BUCKET_KEY_S(b), keysize);
-		buf[keysize - 2] = buf[keysize - 1] = ""[0];
-		keyLength = b->nKeyLength;
-#ifdef IS_UNICODE
-		if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
-			if (buf[0] == ""[0] && buf[1] == ""[0]) {
-				keyLength ++;
-			}
-		} else
-#endif
-		{
-			if (buf[0] == ""[0]) {
-				keyLength ++;
-			}
-		}
-
-		add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
-	}
-	add_assoc_zval_ex(output, ZEND_STRS("function_table"), list);
-	
-	ALLOC_INIT_ZVAL(list);
-	array_init(list);
-	for (b = xc_sandbox_user_class_begin(TSRMLS_C); b; b = b->pListNext) {
-		int keysize, keyLength;
-
-		ALLOC_INIT_ZVAL(zv);
-		array_init(zv);
-		xc_dasm_zend_class_entry(&dasm, zv, CestToCePtr(*(xc_cest_t *)b->pData) TSRMLS_CC);
-
-		keysize = BUCKET_KEY_SIZE(b) + 2;
-		if (keysize > bufsize) {
-			do {
-				bufsize *= 2;
-			} while (keysize > bufsize);
-			buf = erealloc(buf, bufsize);
-		}
-		memcpy(buf, BUCKET_KEY_S(b), keysize);
-		buf[keysize - 2] = buf[keysize - 1] = ""[0];
-		keyLength = b->nKeyLength;
-#ifdef IS_UNICODE
-		if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
-			if (buf[0] == ""[0] && buf[1] == ""[0]) {
-				keyLength ++;
-			}
-		} else
-#endif
-		{
-			if (buf[0] == ""[0]) {
-				keyLength ++;
-			}
-		}
-		add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
-	}
-	efree(buf);
-	add_assoc_zval_ex(output, ZEND_STRS("class_table"), list);
-
-	/*xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);*/
-	xc_compile_result_free(&cr);
-}
-/* }}} */
-typedef struct xc_dasm_sandboxed_t { /* {{{ */
-	enum Type {
-		xc_dasm_file_t
-		, xc_dasm_string_t
-	} type;
-	union {
-		zval *zfilename;
-		struct {
-			zval *source;
-			char *eval_name;
-		} compile_string;
-	} input;
-
-	zval *output;
-} xc_dasm_sandboxed_t; /* {{{ */
-
-zend_op_array *xc_dasm_sandboxed(void *data TSRMLS_DC)
-{
-	zend_bool catched = 0;
-	zend_op_array *op_array = NULL;
-	xc_dasm_sandboxed_t *sandboxed_dasm = (xc_dasm_sandboxed_t *) data;
-
-	zend_try {
-		if (sandboxed_dasm->type == xc_dasm_file_t) {
-			op_array = compile_filename(ZEND_REQUIRE, sandboxed_dasm->input.zfilename TSRMLS_CC);
-		}
-		else {
-			op_array = compile_string(sandboxed_dasm->input.compile_string.source, sandboxed_dasm->input.compile_string.eval_name TSRMLS_CC);
-		}
-	} zend_catch {
-		catched = 1;
-	} zend_end_try();
-
-	if (catched || !op_array) {
-#define return_value sandboxed_dasm->output
-		RETVAL_FALSE;
-#undef return_value
-		return NULL;
-	}
-
-	xc_dasm(sandboxed_dasm->output, op_array TSRMLS_CC);
-
-	/* free */
-#ifdef ZEND_ENGINE_2
-	destroy_op_array(op_array TSRMLS_CC);
-#else
-	destroy_op_array(op_array);
-#endif
-	efree(op_array);
-
-	return NULL;
-} /* }}} */
-void xc_dasm_string(zval *output, zval *source TSRMLS_DC) /* {{{ */
-{
-	xc_dasm_sandboxed_t sandboxed_dasm;
-	char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
-
-	sandboxed_dasm.output = output;
-	sandboxed_dasm.type = xc_dasm_string_t;
-	sandboxed_dasm.input.compile_string.source = source;
-	sandboxed_dasm.input.compile_string.eval_name = eval_name;
-	xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, eval_name TSRMLS_CC);
-	efree(eval_name);
-}
-/* }}} */
-void xc_dasm_file(zval *output, const char *filename TSRMLS_DC) /* {{{ */
-{
-	zval *zfilename;
-	xc_dasm_sandboxed_t sandboxed_dasm;
-
-	MAKE_STD_ZVAL(zfilename);
-	zfilename->value.str.val = estrdup(filename);
-	zfilename->value.str.len = strlen(filename);
-	zfilename->type = IS_STRING;
-
-	sandboxed_dasm.output = output;
-	sandboxed_dasm.type = xc_dasm_file_t;
-	sandboxed_dasm.input.zfilename = zfilename;
-	xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, zfilename->value.str.val TSRMLS_CC);
-
-	zval_dtor(zfilename);
-	FREE_ZVAL(zfilename);
-}
-/* }}} */
Index: unk/disassembler.h
===================================================================
--- /trunk/disassembler.h	(revision 981)
+++ 	(revision )
@@ -1,4 +1,0 @@
-#include "php.h"
-
-void xc_dasm_string(zval *return_value, zval *code TSRMLS_DC);
-void xc_dasm_file(zval *return_value, const char *filename TSRMLS_DC);
Index: unk/foreachcoresig.h
===================================================================
--- /trunk/foreachcoresig.h	(revision 981)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/* all signals generate coredump by default is list here */
-
-#ifdef SIGABRT
-FOREACH_SIG(SIGABRT);
-#endif
-
-#ifdef SIGBUS
-FOREACH_SIG(SIGBUS);
-#endif
-
-#ifdef SIGEMT
-FOREACH_SIG(SIGEMT);
-#endif
-
-#ifdef SIGFPE
-FOREACH_SIG(SIGFPE);
-#endif
-
-#ifdef SIGILL
-FOREACH_SIG(SIGILL);
-#endif
-
-#ifdef SIGIOT
-FOREACH_SIG(SIGIOT);
-#endif
-
-#ifdef SIGQUIT
-FOREACH_SIG(SIGQUIT);
-#endif
-
-#ifdef SIGSEGV
-FOREACH_SIG(SIGSEGV);
-#endif
-
-#ifdef SIGSYS
-FOREACH_SIG(SIGSYS);
-#endif
-
-#ifdef SIGTRAP
-FOREACH_SIG(SIGTRAP);
-#endif
-
-#ifdef SIGXCPU
-FOREACH_SIG(SIGXCPU);
-#endif
-
-#ifdef SIGXFSZ
-FOREACH_SIG(SIGXFSZ);
-#endif
-
Index: /trunk/gen_structinfo.awk
===================================================================
--- /trunk/gen_structinfo.awk	(revision 982)
+++ /trunk/gen_structinfo.awk	(revision 982)
@@ -0,0 +1,212 @@
+#! /usr/bin/awk -f
+# vim:ts=4:sw=4
+BEGIN {
+	brace = 0;
+	incomment = 0;
+	buffer_len = 0;
+}
+function printstruct(structname) {
+	printf "define(`ELEMENTSOF_%s', `%s')\n", structname, ELEMENTSOF[structname];
+	printf "define(`COUNTOF_%s', `%s')\n", structname, COUNTOF[structname];
+	printf "define(`SIZEOF_%s', `(  %s  )')\n", structname, SIZEOF[structname];
+}
+function countBrace(text,  len, i, char, braceCount) {
+	len = length(text);
+	braceCount = 0;
+	for (i = 1; i <= len; ++i) {
+		char = substr(text, i, 1);
+		if (char == "{") {
+			braceCount = braceCount + 1;
+		}
+		else if (char == "}") {
+			braceCount = braceCount - 1;
+		}
+	}
+	return braceCount;
+}
+
+# multiline comment handling
+{
+	# removes one line comment
+	gsub(/\/\*(.+?)\*\//, " ");
+}
+/\*\// {
+	if (incomment) {
+		sub(/.*\*\//, "");
+		incomment = 0;
+	}
+}
+incomment {
+	next;
+}
+/\/\*/ {
+	sub(/\/\*.*/, "");
+	incomment = 1;
+	# fall through
+}
+
+# skip file/line mark here to be faster
+/^#/ {
+	next;
+}
+
+/^}.*;/ {
+	if (instruct) {
+		sub(";", "");
+		structname = instruct;
+		if (structname == 1 && $2) {
+			structname = $2;
+		}
+		if (structname in typedefs) {
+			structname = typedefs[structname];
+		}
+		sizeinfo = "";
+		elms = "";
+		for (i = 0; i in buffer; i ++) {
+			if (i) {
+				sizeinfo = sizeinfo " + ";
+			}
+			sizeinfo = sizeinfo "sizeof(((" structname "*)NULL)->" buffer[i] ")";
+
+			if (i == 0) {
+				elms = "\"" buffer[i] "\"";
+			}
+			else {
+				elms = elms "," "\"" buffer[i] "\"";
+			}
+		}
+		ELEMENTSOF[structname] = elms;
+		COUNTOF[structname]    = i;
+		SIZEOF[structname]     = sizeinfo;
+		printstruct(structname);
+		print "\n";
+		for (i in buffer) {
+			delete buffer[i];
+		}
+		buffer_len = 0;
+		instruct = 0;
+	}
+	next;
+}
+
+/.[{}]/ {
+	brace += countBrace($0);
+}
+
+{
+	if (brace == 1 && instruct) {
+		gsub(/(^[\t ]+|[\t ]+$)/, ""); # trim whitespaces
+		sub(/.*[{}]/, "");
+		gsub(/\[[^\]]+\]/, ""); # ignore [...]
+		gsub(/:[0-9]+/, ""); # ignore struct bit
+		if (match($0, /^[^(]*\([ ]*\*([^)]+)\)/)) {
+			sub(/ +/, "")
+			sub(/^[^(]*\(\*/, "");
+			sub(/\).*/, "");
+			# function pointer
+			buffer[buffer_len] = $0;
+			buffer_len ++;
+		}
+		else {
+			# process normal variables
+
+			# ignore any ()s
+			while (gsub(/(\([^)]*\))/, "")) {
+			}
+			if (match($0, /[()]/)) {
+				next;
+			}
+			# unsigned int *a,  b; int c;
+			gsub(/[*]/, " ");
+			# unsigned int a,  b; int c;
+			gsub(/ +/, " ");
+			# unsigned int a, b; int c;
+			gsub(/ *[,;]/, ";");
+			# unsigned int a; b; int c;
+			if (!match($0, /;/)) {
+				next;
+			}
+			# print "=DEBUG=" $0 "==";
+			split($0, chunks, ";");
+			# [unsigned int a, b, c]
+
+			for (i = 1; i in chunks; i ++) {
+				if (chunks[i] == "") {
+					delete chunks[i];
+					continue;
+				}
+				split(chunks[i], pieces, " ");
+				# [unsigned, int, a]
+				# [b]
+				# [c]
+
+				last_piece = "";
+				for (j = 1; j in pieces; j ++) {
+					last_piece = pieces[j];
+					delete pieces[j];
+				}
+				if (last_piece == "") {
+					# print "=ERROR=" chunks[i] "==";
+					delete chunks[i];
+					continue;
+				}
+				# a
+				# b
+				# c
+
+				buffer[buffer_len] = last_piece;
+				buffer_len ++;
+				delete chunks[i]
+			}
+			last_piece = "";
+		}
+		next;
+	}
+}
+
+/^typedef struct [^{]*;/ {
+	sub(";", "");
+	typename=$3;
+	newtypename=$4;
+	typedefs[typename] = newtypename;
+	if (ELEMENTSOF[typename]) {
+		ELEMENTSOF[newtypename] = ELEMENTSOF[typename];
+		COUNTOF[newtypename]    = COUNTOF[typename];
+		sub(/.*/, SIZEOF[typename]);
+		gsub(typename, newtypename);
+		SIZEOF[newtypename]     = $0;
+		printstruct(newtypename);
+	}
+	next;
+}
+/^typedef struct .*\{[^}]*$/ {
+	brace = countBrace($0);
+	if (brace > 0) {
+		instruct = 1;
+	}
+	else {
+		brace = 0;
+		instruct = 0;
+	}
+
+	for (i in buffer) {
+		delete buffer[i];
+	}
+	next;
+}
+
+/^struct .*\{.*/ {
+	brace = countBrace($0);
+	if (brace > 0) {
+		instruct = $2;
+	}
+	else {
+		brace = 0;
+		instruct = 0;
+	}
+
+	for (i in buffer) {
+		delete buffer[i];
+	}
+	next;
+}
Index: /trunk/lib/Decompiler.class.php
===================================================================
--- /trunk/lib/Decompiler.class.php	(revision 982)
+++ /trunk/lib/Decompiler.class.php	(revision 982)
@@ -0,0 +1,2817 @@
+<?php
+
+define('INDENT', "\t");
+ini_set('error_reporting', E_ALL);
+
+function color($str, $color = 33)
+{
+	return "\x1B[{$color}m$str\x1B[0m";
+}
+
+function str($code, $indent = '') // {{{
+{
+	if (is_array($code)) {
+		$array = array();
+		foreach ($code as $key => $value) {
+			$array[$key] = str($value, $indent);
+		}
+		return $array;
+	}
+	if (is_object($code)) {
+		$code = foldToCode($code, $indent);
+		return $code->toCode($indent);
+	}
+
+	return (string) $code;
+}
+// }}}
+function foldToCode($src, $indent = '') // {{{ wrap or rewrap anything to Decompiler_Code
+{
+	if (is_array($indent)) {
+		$indent = $indent['indent'];
+	}
+
+	if (!is_object($src)) {
+		return new Decompiler_Code($src);
+	}
+
+	if (!method_exists($src, 'toCode')) {
+		var_dump($src);
+		exit('no toCode');
+	}
+	if (get_class($src) != 'Decompiler_Code') {
+		// rewrap it
+		$src = new Decompiler_Code($src->toCode($indent));
+	}
+
+	return $src;
+}
+// }}}
+function value($value) // {{{
+{
+	$spec = xcache_get_special_value($value);
+	if (isset($spec)) {
+		$value = $spec;
+		if (!is_array($value)) {
+			// constant
+			return $value;
+		}
+	}
+
+	if (is_a($value, 'Decompiler_Object')) {
+		// use as is
+	}
+	else if (is_array($value)) {
+		$value = new Decompiler_ConstArray($value);
+	}
+	else {
+		$value = new Decompiler_Value($value);
+	}
+	return $value;
+}
+// }}}
+function unquoteName_($str, $asVariableName, $indent = '') // {{{
+{
+	$str = str($str, $indent);
+	if (preg_match("!^'[\\w_][\\w\\d_\\\\]*'\$!", $str)) {
+		return str_replace('\\\\', '\\', substr($str, 1, -1));
+	}
+	else if ($asVariableName) {
+		return "{" . $str . "}";
+	}
+	else {
+		return $str;
+	}
+}
+// }}}
+function unquoteVariableName($str, $indent = '') // {{{
+{
+	return unquoteName_($str, true, $indent);
+}
+// }}}
+function unquoteName($str, $indent = '') // {{{
+{
+	return unquoteName_($str, false, $indent);
+}
+// }}}
+class Decompiler_Object // {{{
+{
+}
+// }}}
+class Decompiler_Value extends Decompiler_Object // {{{
+{
+	var $value;
+
+	function Decompiler_Value($value = null)
+	{
+		$this->value = $value;
+	}
+
+	function toCode($indent)
+	{
+		$code = var_export($this->value, true);
+		if (gettype($this->value) == 'string') {
+			switch ($this->value) {
+			case "\r":
+				return '"\\r"';
+			case "\n":
+				return '"\\n"';
+			case "\r\n":
+				return '"\\r\\n"';
+			}
+			$code = str_replace("\r\n", '\' . "\\r\\n" . \'', $code);
+			$code = str_replace("\r", '\' . "\\r" . \'', $code);
+			$code = str_replace("\n", '\' . "\\n" . \'', $code);
+		}
+		return $code;
+	}
+}
+// }}}
+class Decompiler_Code extends Decompiler_Object // {{{
+{
+	var $src;
+
+	function Decompiler_Code($src)
+	{
+		assert('isset($src)');
+		$this->src = $src;
+	}
+
+	function toCode($indent)
+	{
+		return $this->src;
+	}
+}
+// }}}
+class Decompiler_Binop extends Decompiler_Code // {{{
+{
+	var $opc;
+	var $op1;
+	var $op2;
+	var $parent;
+
+	function Decompiler_Binop($parent, $op1, $opc, $op2)
+	{
+		$this->parent = &$parent;
+		$this->opc = $opc;
+		$this->op1 = $op1;
+		$this->op2 = $op2;
+	}
+
+	function toCode($indent)
+	{
+		$opstr = $this->parent->binops[$this->opc];
+
+		if (is_a($this->op1, 'Decompiler_TriOp') || is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) {
+			$op1 = "(" . str($this->op1, $indent) . ")";
+		}
+		else {
+			$op1 = $this->op1;
+		}
+
+		if (is_a($this->op2, 'Decompiler_TriOp') || is_a($this->op2, 'Decompiler_Binop') && $this->op2->opc != $this->opc && substr($opstr, -1) != '=') {
+			$op2 = "(" . str($this->op2, $indent) . ")";
+		}
+		else {
+			$op2 = $this->op2;
+		}
+
+		if (str($op1) == '0' && ($this->opc == XC_ADD || $this->opc == XC_SUB)) {
+			return $opstr . str($op2, $indent);
+		}
+
+		return str($op1, $indent) . ' ' . $opstr . ($this->opc == XC_ASSIGN_REF ? '' : ' ') . str($op2, $indent);
+	}
+}
+// }}}
+class Decompiler_TriOp extends Decompiler_Code // {{{
+{
+	var $condition;
+	var $trueValue;
+	var $falseValue;
+
+	function Decompiler_TriOp($condition, $trueValue, $falseValue)
+	{
+		$this->condition = $condition;
+		$this->trueValue = $trueValue;
+		$this->falseValue = $falseValue;
+	}
+
+	function toCode($indent)
+	{
+		$trueValue = $this->trueValue;
+		if (is_a($this->trueValue, 'Decompiler_TriOp')) {
+			$trueValue = "(" . str($trueValue, $indent) . ")";
+		}
+		$falseValue = $this->falseValue;
+		if (is_a($this->falseValue, 'Decompiler_TriOp')) {
+			$falseValue = "(" . str($falseValue, $indent) . ")";
+		}
+
+		return str($this->condition) . ' ? ' . str($trueValue) . ' : ' . str($falseValue);
+	}
+}
+// }}}
+class Decompiler_Fetch extends Decompiler_Code // {{{
+{
+	var $src;
+	var $fetchType;
+
+	function Decompiler_Fetch($src, $type, $globalsrc)
+	{
+		$this->src = $src;
+		$this->fetchType = $type;
+		$this->globalsrc = $globalsrc;
+	}
+
+	function toCode($indent)
+	{
+		switch ($this->fetchType) {
+		case ZEND_FETCH_LOCAL:
+			return '$' . substr($this->src, 1, -1);
+		case ZEND_FETCH_STATIC:
+			if (ZEND_ENGINE_2_3) {
+				// closure local variable?
+				return str($this->src);
+			}
+			die('static fetch cant to string');
+		case ZEND_FETCH_GLOBAL:
+		case ZEND_FETCH_GLOBAL_LOCK:
+			return $this->globalsrc;
+		default:
+			var_dump($this->fetchType);
+			assert(0);
+		}
+	}
+}
+// }}}
+class Decompiler_Box // {{{
+{
+	var $obj;
+
+	function Decompiler_Box(&$obj)
+	{
+		$this->obj = &$obj;
+	}
+
+	function toCode($indent)
+	{
+		return $this->obj->toCode($indent);
+	}
+}
+// }}}
+class Decompiler_Dim extends Decompiler_Value // {{{
+{
+	var $offsets = array();
+	var $isLast = false;
+	var $isObject = false;
+	var $assign = null;
+
+	function toCode($indent)
+	{
+		if (is_a($this->value, 'Decompiler_ListBox')) {
+			$exp = str($this->value->obj->src, $indent);
+		}
+		else {
+			$exp = str($this->value, $indent);
+		}
+		$last = count($this->offsets) - 1;
+		foreach ($this->offsets as $i => $dim) {
+			if ($this->isObject && $i == $last) {
+				$exp .= '->' . unquoteVariableName($dim, $indent);
+			}
+			else {
+				$exp .= '[' . str($dim, $indent) . ']';
+			}
+		}
+		return $exp;
+	}
+}
+// }}}
+class Decompiler_DimBox extends Decompiler_Box // {{{
+{
+}
+// }}}
+class Decompiler_List extends Decompiler_Code // {{{
+{
+	var $src;
+	var $dims = array();
+	var $everLocked = false;
+
+	function toCode($indent)
+	{
+		if (count($this->dims) == 1 && !$this->everLocked) {
+			$dim = $this->dims[0];
+			unset($dim->value);
+			$dim->value = $this->src;
+			if (!isset($dim->assign)) {
+				return str($dim, $indent);
+			}
+			return str($this->dims[0]->assign, $indent) . ' = ' . str($dim, $indent);
+		}
+		/* flatten dims */
+		$assigns = array();
+		foreach ($this->dims as $dim) {
+			$assign = &$assigns;
+			foreach ($dim->offsets as $offset) {
+				$assign = &$assign[$offset];
+			}
+			$assign = foldToCode($dim->assign, $indent);
+		}
+		return str($this->toList($assigns)) . ' = ' . str($this->src, $indent);
+	}
+
+	function toList($assigns)
+	{
+		$keys = array_keys($assigns);
+		if (count($keys) < 2) {
+			$keys[] = 0;
+		}
+		$max = call_user_func_array('max', $keys);
+		$list = 'list(';
+		for ($i = 0; $i <= $max; $i ++) {
+			if ($i) {
+				$list .= ', ';
+			}
+			if (!isset($assigns[$i])) {
+				continue;
+			}
+			if (is_array($assigns[$i])) {
+				$list .= $this->toList($assigns[$i]);
+			}
+			else {
+				$list .= $assigns[$i];
+			}
+		}
+		return $list . ')';
+	}
+}
+// }}}
+class Decompiler_ListBox extends Decompiler_Box // {{{
+{
+}
+// }}}
+class Decompiler_Array extends Decompiler_Value // {{{
+{
+	// emenets
+	function Decompiler_Array()
+	{
+		$this->value = array();
+	}
+
+	function toCode($indent)
+	{
+		$subindent = $indent . INDENT;
+
+		$elementsCode = array();
+		$index = 0;
+		foreach ($this->value as $element) {
+			list($key, $value) = $element;
+			if (!isset($key)) {
+				$key = $index++;
+			}
+			$elementsCode[] = array(str($key, $subindent), str($value, $subindent), $key, $value);
+		}
+
+		$exp = "array(";
+		$indent = $indent . INDENT;
+		$assocWidth = 0;
+		$multiline = 0;
+		$i = 0;
+		foreach ($elementsCode as $element) {
+			list($keyCode, $valueCode) = $element;
+			if ((string) $i !== $keyCode) {
+				$assocWidth = 1;
+				break;
+			}
+			++$i;
+		}
+		foreach ($elementsCode as $element) {
+			list($keyCode, $valueCode, $key, $value) = $element;
+			if ($assocWidth) {
+				$len = strlen($keyCode);
+				if ($assocWidth < $len) {
+					$assocWidth = $len;
+				}
+			}
+			if (is_array($value) || is_a($value, 'Decompiler_Array')) {
+				$multiline ++;
+			}
+		}
+
+		$i = 0;
+		foreach ($elementsCode as $element) {
+			list($keyCode, $value) = $element;
+			if ($multiline) {
+				if ($i) {
+					$exp .= ",";
+				}
+				$exp .= "\n";
+				$exp .= $indent;
+			}
+			else {
+				if ($i) {
+					$exp .= ", ";
+				}
+			}
+
+			if ($assocWidth) {
+				if ($multiline) {
+					$exp .= sprintf("%-{$assocWidth}s => ", $keyCode);
+				}
+				else {
+					$exp .= $keyCode . ' => ';
+				}
+			}
+
+			$exp .= $value;
+
+			$i ++;
+		}
+		if ($multiline) {
+			$exp .= "\n$indent)";
+		}
+		else {
+			$exp .= ")";
+		}
+		return $exp;
+	}
+}
+// }}}
+class Decompiler_ConstArray extends Decompiler_Array // {{{
+{
+	function Decompiler_ConstArray($array)
+	{
+		$elements = array();
+		foreach ($array as $key => $value) {
+			$elements[] = array(value($key), value($value));
+		}
+		$this->value = $elements;
+	}
+}
+// }}}
+class Decompiler_ForeachBox extends Decompiler_Box // {{{
+{
+	var $iskey;
+
+	function toCode($indent)
+	{
+		return 'foreach (' . '';
+	}
+}
+// }}}
+
+class Decompiler
+{
+	var $namespace;
+	var $namespaceDecided;
+
+	function Decompiler()
+	{
+		// {{{ testing
+		// XC_UNDEF XC_OP_DATA
+		$this->test = !empty($_ENV['XCACHE_DECOMPILER_TEST']);
+		$this->usedOps = array();
+
+		if ($this->test) {
+			$content = file_get_contents(__FILE__);
+			for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
+				if (!preg_match("/\\bXC_" . $opname . "\\b(?!')/", $content)) {
+					echo "not recognized opcode ", $opname, "\n";
+				}
+			}
+		}
+		// }}}
+		// {{{ opinfo
+		$this->unaryops = array(
+				XC_BW_NOT   => '~',
+				XC_BOOL_NOT => '!',
+				);
+		$this->binops = array(
+				XC_ADD                 => "+",
+				XC_ASSIGN_ADD          => "+=",
+				XC_SUB                 => "-",
+				XC_ASSIGN_SUB          => "-=",
+				XC_MUL                 => "*",
+				XC_ASSIGN_MUL          => "*=",
+				XC_DIV                 => "/",
+				XC_ASSIGN_DIV          => "/=",
+				XC_MOD                 => "%",
+				XC_ASSIGN_MOD          => "%=",
+				XC_SL                  => "<<",
+				XC_ASSIGN_SL           => "<<=",
+				XC_SR                  => ">>",
+				XC_ASSIGN_SR           => ">>=",
+				XC_CONCAT              => ".",
+				XC_ASSIGN_CONCAT       => ".=",
+				XC_IS_IDENTICAL        => "===",
+				XC_IS_NOT_IDENTICAL    => "!==",
+				XC_IS_EQUAL            => "==",
+				XC_IS_NOT_EQUAL        => "!=",
+				XC_IS_SMALLER          => "<",
+				XC_IS_SMALLER_OR_EQUAL => "<=",
+				XC_BW_OR               => "|",
+				XC_ASSIGN_BW_OR        => "|=",
+				XC_BW_AND              => "&",
+				XC_ASSIGN_BW_AND       => "&=",
+				XC_BW_XOR              => "^",
+				XC_ASSIGN_BW_XOR       => "^=",
+				XC_BOOL_XOR            => "xor",
+				XC_ASSIGN              => "=",
+				XC_ASSIGN_REF          => "= &",
+				XC_JMP_SET             => "?:",
+				XC_JMPZ_EX             => "&&",
+				XC_JMPNZ_EX            => "||",
+				);
+		// }}}
+		$this->includeTypes = array( // {{{
+				ZEND_EVAL         => 'eval',
+				ZEND_INCLUDE      => 'include',
+				ZEND_INCLUDE_ONCE => 'include_once',
+				ZEND_REQUIRE      => 'require',
+				ZEND_REQUIRE_ONCE => 'require_once',
+				);
+				// }}}
+	}
+	function detectNamespace($name) // {{{
+	{
+		if ($this->namespaceDecided) {
+			return;
+		}
+
+		if (strpos($name, '\\') !== false) {
+			$this->namespace = strtok($name, '\\');
+			echo 'namespace ', $this->namespace, ";\n\n";
+		}
+
+		$this->namespaceDecided = true;
+	}
+	// }}}
+	function stripNamespace($name) // {{{
+	{
+		$len = strlen($this->namespace) + 1;
+		if (substr($name, 0, $len) == $this->namespace . '\\') {
+			return substr($name, $len);
+		}
+		else {
+			return $name;
+		}
+	}
+	// }}}
+	function outputPhp(&$EX, $range) // {{{
+	{
+		$needBlankline = isset($EX['lastBlock']);
+		$indent = $EX['indent'];
+		$curticks = 0;
+		for ($i = $range[0]; $i <= $range[1]; $i ++) {
+			$op = $EX['opcodes'][$i];
+			if (isset($op['gofrom'])) {
+				if ($needBlankline) {
+					$needBlankline = false;
+					echo PHP_EOL;
+				}
+				echo 'label' . $i, ":\n";
+			}
+			if (isset($op['php'])) {
+				$toticks = isset($op['ticks']) ? (int) str($op['ticks']) : 0;
+				if ($curticks != $toticks) {
+					$oldticks = $curticks;
+					$curticks = $toticks;
+					if (!$curticks) {
+						echo $EX['indent'], "}\n\n";
+						$indent = $EX['indent'];
+					}
+					else {
+						if ($oldticks) {
+							echo $EX['indent'], "}\n\n";
+						}
+						else if (!$oldticks) {
+							$indent .= INDENT;
+						}
+						if ($needBlankline) {
+							$needBlankline = false;
+							echo PHP_EOL;
+						}
+						echo $EX['indent'], "declare (ticks=$curticks) {\n";
+					}
+				}
+				if ($needBlankline) {
+					$needBlankline = false;
+					echo PHP_EOL;
+				}
+				echo $indent, str($op['php'], $indent), ";\n";
+				$EX['lastBlock'] = 'basic';
+			}
+		}
+		if ($curticks) {
+			echo $EX['indent'], "}\n";
+		}
+	}
+	// }}}
+	function getOpVal($op, &$EX, $free = false) // {{{
+	{
+		switch ($op['op_type']) {
+		case XC_IS_CONST:
+			return value($op['constant']);
+
+		case XC_IS_VAR:
+		case XC_IS_TMP_VAR:
+			$T = &$EX['Ts'];
+			$ret = $T[$op['var']];
+			if ($free && empty($this->keepTs)) {
+				unset($T[$op['var']]);
+			}
+			return $ret;
+
+		case XC_IS_CV:
+			$var = $op['var'];
+			$var = $EX['op_array']['vars'][$var];
+			return '$' . $var['name'];
+
+		case XC_IS_UNUSED:
+			return null;
+		}
+	}
+	// }}}
+	function removeKeyPrefix($array, $prefix) // {{{
+	{
+		$prefixLen = strlen($prefix);
+		$ret = array();
+		foreach ($array as $key => $value) {
+			if (substr($key, 0, $prefixLen) == $prefix) {
+				$key = substr($key, $prefixLen);
+			}
+			$ret[$key] = $value;
+		}
+		return $ret;
+	}
+	// }}}
+	function &fixOpcode($opcodes, $removeTailing = false, $defaultReturnValue = null) // {{{
+	{
+		$last = count($opcodes) - 1;
+		for ($i = 0; $i <= $last; $i ++) {
+			if (function_exists('xcache_get_fixed_opcode')) {
+				$opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i);
+			}
+			if (isset($opcodes[$i]['op1'])) {
+				$opcodes[$i]['op1'] = $this->removeKeyPrefix($opcodes[$i]['op1'], 'u.');
+				$opcodes[$i]['op2'] = $this->removeKeyPrefix($opcodes[$i]['op2'], 'u.');
+				$opcodes[$i]['result'] = $this->removeKeyPrefix($opcodes[$i]['result'], 'u.');
+			}
+			else {
+				$op = array(
+					'op1' => array(),
+					'op2' => array(),
+					'op3' => array(),
+				);
+				foreach ($opcodes[$i] as $name => $value) {
+					if (preg_match('!^(op1|op2|result)\\.(.*)!', $name, $m)) {
+						list(, $which, $field) = $m;
+						$op[$which][$field] = $value;
+					}
+					else if (preg_match('!^(op1|op2|result)_type$!', $name, $m)) {
+						list(, $which) = $m;
+						$op[$which]['op_type'] = $value;
+					}
+					else {
+						$op[$name] = $value;
+					}
+				}
+				$opcodes[$i] = $op;
+			}
+		}
+
+		if ($removeTailing) {
+			$last = count($opcodes) - 1;
+			if ($opcodes[$last]['opcode'] == XC_HANDLE_EXCEPTION) {
+				$this->usedOps[XC_HANDLE_EXCEPTION] = true;
+				$opcodes[$last]['opcode'] = XC_NOP;
+				--$last;
+			}
+			if ($opcodes[$last]['opcode'] == XC_RETURN) {
+				$op1 = $opcodes[$last]['op1'];
+				if ($op1['op_type'] == XC_IS_CONST && array_key_exists('constant', $op1) && $op1['constant'] === $defaultReturnValue) {
+					$opcodes[$last]['opcode'] = XC_NOP;
+					--$last;
+				}
+			}
+		}
+		return $opcodes;
+	}
+	// }}}
+	function decompileBasicBlock(&$EX, $range, $unhandled = false) // {{{
+	{
+		$this->dasmBasicBlock($EX, $range);
+		if ($unhandled) {
+			$this->dumpRange($EX, $range);
+		}
+		$this->outputPhp($EX, $range);
+	}
+	// }}}
+	function isIfCondition(&$EX, $range) // {{{
+	{
+		$opcodes = &$EX['opcodes'];
+		$firstOp = &$opcodes[$range[0]];
+		return $firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP
+		 && !empty($opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'])
+		 && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1;
+	}
+	// }}}
+	function removeJmpInfo(&$EX, $line) // {{{
+	{
+		$opcodes = &$EX['opcodes'];
+		foreach ($opcodes[$line]['jmpouts'] as $jmpTo) {
+			$jmpins = &$opcodes[$jmpTo]['jmpins'];
+			$jmpins = array_flip($jmpins);
+			unset($jmpins[$line]);
+			$jmpins = array_keys($jmpins);
+		}
+		// $opcodes[$line]['opcode'] = XC_NOP;
+		unset($opcodes[$line]['jmpouts']);
+	}
+	// }}}
+	function beginScope(&$EX, $doIndent = true) // {{{
+	{
+		array_push($EX['scopeStack'], array($EX['lastBlock'], $EX['indent']));
+		if ($doIndent) {
+			$EX['indent'] .= INDENT;
+		}
+		$EX['lastBlock'] = null;
+	}
+	// }}}
+	function endScope(&$EX) // {{{
+	{
+		list($EX['lastBlock'], $EX['indent']) = array_pop($EX['scopeStack']);
+	}
+	// }}}
+	function beginComplexBlock(&$EX) // {{{
+	{
+		if (isset($EX['lastBlock'])) {
+			echo PHP_EOL;
+			$EX['lastBlock'] = null;
+		}
+	}
+	// }}}
+	function endComplexBlock(&$EX) // {{{
+	{
+		$EX['lastBlock'] = 'complex';
+	}
+	// }}}
+	function decompileComplexBlock(&$EX, $range) // {{{
+	{
+		$T = &$EX['Ts'];
+		$opcodes = &$EX['opcodes'];
+		$indent = $EX['indent'];
+
+		$firstOp = &$opcodes[$range[0]];
+		$lastOp = &$opcodes[$range[1]];
+
+		// {{{ && || and or
+		if (($firstOp['opcode'] == XC_JMPZ_EX || $firstOp['opcode'] == XC_JMPNZ_EX) && !empty($firstOp['jmpouts'])
+		 && $firstOp['jmpouts'][0] == $range[1] + 1
+		 && $lastOp['opcode'] == XC_BOOL
+		 && $firstOp['opcode']['result']['var'] == $lastOp['opcode']['result']['var']
+		) {
+			$this->removeJmpInfo($EX, $range[0]);
+
+			$this->recognizeAndDecompileClosedBlocks($EX, array($range[0], $range[0]));
+			$op1 = $this->getOpVal($firstOp['result'], $EX, true);
+
+			$this->recognizeAndDecompileClosedBlocks($EX, array($range[0] + 1, $range[1]));
+			$op2 = $this->getOpVal($lastOp['result'], $EX, true);
+
+			$T[$firstOp['result']['var']] = new Decompiler_Binop($this, $op1, $firstOp['opcode'], $op2);
+			return false;
+		}
+		// }}}
+		// {{{ ?: excluding JMP_SET
+		if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts'])
+		 && $range[1] >= $range[0] + 3
+		 && $opcodes[$firstOp['jmpouts'][0] - 2]['opcode'] == XC_QM_ASSIGN
+		 && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1
+		 && $lastOp['opcode'] == XC_QM_ASSIGN
+		) {
+			$trueRange = array($range[0] + 1, $firstOp['jmpouts'][0] - 2);
+			$falseRange = array($firstOp['jmpouts'][0], $range[1]);
+			$this->removeJmpInfo($EX, $range[0]);
+
+			$condition = $this->getOpVal($firstOp['op1'], $EX);
+			$this->recognizeAndDecompileClosedBlocks($EX, $trueRange);
+			$trueValue = $this->getOpVal($opcodes[$trueRange[1]]['result'], $EX, true);
+			$this->recognizeAndDecompileClosedBlocks($EX, $falseRange);
+			$falseValue = $this->getOpVal($opcodes[$falseRange[1]]['result'], $EX, true);
+			$T[$opcodes[$trueRange[1]]['result']['var']] = new Decompiler_TriOp($condition, $trueValue, $falseValue);
+			return false;
+		}
+		// }}}
+		// {{{ goto
+		if ($firstOp['opcode'] == XC_JMP && !empty($firstOp['jmpouts']) && $firstOp['jmpouts'][0] == $range[1] + 1) {
+			$this->removeJmpInfo($EX, $range[0]);
+			$firstOp['opcode'] = XC_GOTO;
+			$target = $firstOp['op1']['var'];
+			$firstOp['goto'] = $target;
+			$opcodes[$target]['gofrom'][] = $range[0];
+
+			$this->recognizeAndDecompileClosedBlocks($EX, $range);
+			return false;
+		}
+		// }}}
+		// {{{ for
+		if (!empty($firstOp['jmpins']) && $opcodes[$firstOp['jmpins'][0]]['opcode'] == XC_JMP
+		 && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts']) && $lastOp['jmpouts'][0] <= $firstOp['jmpins'][0]
+		 && !empty($opcodes[$range[1] + 1]['jmpins']) && $opcodes[$opcodes[$range[1] + 1]['jmpins'][0]]['opcode'] == XC_JMPZNZ
+		) {
+			$nextRange = array($lastOp['jmpouts'][0], $firstOp['jmpins'][0]);
+			$conditionRange = array($range[0], $nextRange[0] - 1);
+			$this->removeJmpInfo($EX, $conditionRange[1]);
+			$bodyRange = array($nextRange[1], $range[1]);
+			$this->removeJmpInfo($EX, $bodyRange[1]);
+
+			$initial = '';
+			$this->beginScope($EX);
+			$this->dasmBasicBlock($EX, $conditionRange);
+			$conditionCodes = array();
+			for ($i = $conditionRange[0]; $i <= $conditionRange[1]; ++$i) {
+				if (isset($opcodes[$i]['php'])) {
+					$conditionCodes[] = str($opcodes[$i]['php'], $EX);
+				}
+			}
+			$conditionCodes[] = str($this->getOpVal($opcodes[$conditionRange[1]]['op1'], $EX), $EX);
+			if (implode(',', $conditionCodes) == 'true') {
+				$conditionCodes = array();
+			}
+			$this->endScope($EX);
+
+			$this->beginScope($EX);
+			$this->dasmBasicBlock($EX, $nextRange);
+			$nextCodes = array();
+			for ($i = $nextRange[0]; $i <= $nextRange[1]; ++$i) {
+				if (isset($opcodes[$i]['php'])) {
+					$nextCodes[] = str($opcodes[$i]['php'], $EX);
+				}
+			}
+			$this->endScope($EX);
+
+			$this->beginComplexBlock($EX);
+			echo $indent, 'for (', str($initial, $EX), '; ', implode(', ', $conditionCodes), '; ', implode(', ', $nextCodes), ') ', '{', PHP_EOL;
+			$this->beginScope($EX);
+			$this->recognizeAndDecompileClosedBlocks($EX, $bodyRange);
+			$this->endScope($EX);
+			echo $indent, '}', PHP_EOL;
+			$this->endComplexBlock($EX);
+			return;
+		}
+		// }}}
+		// {{{ if/elseif/else
+		if ($this->isIfCondition($EX, $range)) {
+			$this->beginComplexBlock($EX);
+			$isElseIf = false;
+			do {
+				$ifRange = array($range[0], $opcodes[$range[0]]['jmpouts'][0] - 1);
+				$this->removeJmpInfo($EX, $ifRange[0]);
+				$this->removeJmpInfo($EX, $ifRange[1]);
+				$condition = $this->getOpVal($opcodes[$ifRange[0]]['op1'], $EX);
+
+				echo $indent, $isElseIf ? 'else if' : 'if', ' (', str($condition, $EX), ') ', '{', PHP_EOL;
+				$this->beginScope($EX);
+				$this->recognizeAndDecompileClosedBlocks($EX, $ifRange);
+				$this->endScope($EX);
+				$EX['lastBlock'] = null;
+				echo $indent, '}', PHP_EOL;
+
+				$isElseIf = true;
+				// search for else if
+				$range[0] = $ifRange[1] + 1;
+				for ($i = $ifRange[1] + 1; $i <= $range[1]; ++$i) {
+					// find first jmpout
+					if (!empty($opcodes[$i]['jmpouts'])) {
+						if ($this->isIfCondition($EX, array($i, $range[1]))) {
+							$this->dasmBasicBlock($EX, array($range[0], $i));
+							$range[0] = $i;
+						}
+						break;
+					}
+				}
+			} while ($this->isIfCondition($EX, $range));
+			if ($ifRange[1] < $range[1]) {
+				$elseRange = array($ifRange[1], $range[1]);
+				echo $indent, 'else ', '{', PHP_EOL;
+				$this->beginScope($EX);
+				$this->recognizeAndDecompileClosedBlocks($EX, $elseRange);
+				$this->endScope($EX);
+				$EX['lastBlock'] = null;
+				echo $indent, '}', PHP_EOL;
+			}
+			$this->endComplexBlock($EX);
+			return;
+		}
+		if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts'])
+		 && $firstOp['jmpouts'][0] - 1 == $range[1] && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_RETURN) {
+			$this->beginComplexBlock($EX);
+			$this->removeJmpInfo($EX, $range[0]);
+			$condition = $this->getOpVal($opcodes[$range[0]]['op1'], $EX);
+
+			echo $indent, 'if (', str($condition, $EX), ') ', '{', PHP_EOL;
+			$this->beginScope($EX);
+			$this->recognizeAndDecompileClosedBlocks($EX, $range);
+			$this->endScope($EX);
+			echo $indent, '}', PHP_EOL;
+			$this->endComplexBlock($EX);
+			return;
+		}
+		// }}}
+		// {{{ try/catch
+		if (!empty($firstOp['jmpins']) && !empty($opcodes[$firstOp['jmpins'][0]]['isCatchBegin'])) {
+			$catchBlocks = array();
+			$catchFirst = $firstOp['jmpins'][0];
+
+			$tryRange = array($range[0], $catchFirst - 1);
+
+			// search for XC_CATCH
+			$this->removeJmpInfo($EX, $catchFirst);
+			for ($i = $catchFirst; $i <= $range[1]; ) {
+				if ($opcodes[$i]['opcode'] == XC_CATCH) {
+					$catchOpLine = $i;
+					$this->removeJmpInfo($EX, $catchOpLine);
+
+					$catchNext = $opcodes[$catchOpLine]['extended_value'];
+					$catchBodyLast = $catchNext - 1;
+					if ($opcodes[$catchBodyLast]['opcode'] == XC_JMP) {
+						--$catchBodyLast;
+					}
+
+					$catchBlocks[$catchFirst] = array($catchOpLine, $catchBodyLast);
+
+					$i = $catchFirst = $catchNext;
+				}
+				else {
+					++$i;
+				}
+			}
+
+			if ($opcodes[$tryRange[1]]['opcode'] == XC_JMP) {
+				--$tryRange[1];
+			}
+
+			$this->beginComplexBlock($EX);
+			echo $indent, "try {", PHP_EOL;
+			$this->beginScope($EX);
+			$this->recognizeAndDecompileClosedBlocks($EX, $tryRange);
+			$this->endScope($EX);
+			echo $indent, '}', PHP_EOL;
+			foreach ($catchBlocks as $catchFirst => $catchInfo) {
+				list($catchOpLine, $catchBodyLast) = $catchInfo;
+				$catchBodyFirst = $catchOpLine + 1;
+				$this->dasmBasicBlock($EX, array($catchFirst, $catchOpLine));
+				$catchOp = &$opcodes[$catchOpLine];
+				echo $indent, 'catch (', str($this->getOpVal($catchOp['op1'], $EX)), ' ', str($this->getOpVal($catchOp['op2'], $EX)), ") {", PHP_EOL;
+				unset($catchOp);
+
+				$EX['lastBlock'] = null;
+				$this->beginScope($EX);
+				$this->recognizeAndDecompileClosedBlocks($EX, array($catchBodyFirst, $catchBodyLast));
+				$this->endScope($EX);
+				echo $indent, '}', PHP_EOL;
+			}
+			$this->endComplexBlock($EX);
+			return;
+		}
+		// }}}
+		// {{{ switch/case
+		if ($firstOp['opcode'] == XC_SWITCH_FREE && isset($T[$firstOp['op1']['var']])) {
+			// TODO: merge this code to CASE code. use SWITCH_FREE to detect begin of switch by using $Ts if possible
+			$this->beginComplexBlock($EX);
+			echo $indent, 'switch (', str($this->getOpVal($firstOp['op1'], $EX)), ") {", PHP_EOL;
+			echo $indent, '}', PHP_EOL;
+			$this->endComplexBlock($EX);
+			return;
+		}
+
+		if (
+			($firstOp['opcode'] == XC_CASE
+			|| $firstOp['opcode'] == XC_JMP && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0]]['opcode'] == XC_CASE
+			)
+		 	 && !empty($lastOp['jmpouts'])
+		) {
+			$cases = array();
+			$caseDefault = null;
+			$caseOp = null;
+			for ($i = $range[0]; $i <= $range[1]; ) {
+				$op = $opcodes[$i];
+				if ($op['opcode'] == XC_CASE) {
+					if (!isset($caseOp)) {
+						$caseOp = $op;
+					}
+					$jmpz = $opcodes[$i + 1];
+					assert('$jmpz["opcode"] == XC_JMPZ');
+					$caseNext = $jmpz['jmpouts'][0];
+					$cases[$i] = $caseNext - 1;
+					$i = $caseNext;
+				}
+				else if ($op['opcode'] == XC_JMP && $op['jmpouts'][0] >= $i) {
+					// default
+					$caseNext = $op['jmpouts'][0];
+					$caseDefault = $i;
+					$cases[$i] = $caseNext - 1;
+					$i = $caseNext;
+				}
+				else {
+					++$i;
+				}
+			}
+
+			$this->beginComplexBlock($EX);
+
+			echo $indent, 'switch (', str($this->getOpVal($caseOp['op1'], $EX), $EX), ") {", PHP_EOL;
+			$caseIsOut = false;
+			foreach ($cases as $caseFirst => $caseLast) {
+				if ($caseIsOut && empty($lastCaseFall)) {
+					echo PHP_EOL;
+				}
+
+				$caseOp = $opcodes[$caseFirst];
+
+				echo $indent;
+				if ($caseOp['opcode'] == XC_CASE) {
+					echo 'case ';
+					echo str($this->getOpVal($caseOp['op2'], $EX), $EX);
+					echo ':', PHP_EOL;
+
+					$this->removeJmpInfo($EX, $caseFirst);
+					++$caseFirst;
+
+					assert('$opcodes[$caseFirst]["opcode"] == XC_JMPZ');
+					$this->removeJmpInfo($EX, $caseFirst);
+					++$caseFirst;
+				}
+				else {
+					echo 'default';
+					echo ':', PHP_EOL;
+
+					assert('$opcodes[$caseFirst]["opcode"] == XC_JMP');
+					$this->removeJmpInfo($EX, $caseFirst);
+					++$caseFirst;
+				}
+
+				assert('$opcodes[$caseLast]["opcode"] == XC_JMP');
+				$this->removeJmpInfo($EX, $caseLast);
+				--$caseLast;
+				switch ($opcodes[$caseLast]['opcode']) {
+				case XC_BRK:
+				case XC_CONT:
+				case XC_GOTO:
+					$lastCaseFall = false;
+					break;
+
+				default:
+					$lastCaseFall = true;
+				}
+
+				$this->beginScope($EX);
+				$this->recognizeAndDecompileClosedBlocks($EX, array($caseFirst, $caseLast));
+				$this->endScope($EX);
+				$caseIsOut = true;
+			}
+			echo $indent, '}', PHP_EOL;
+
+			$this->endComplexBlock($EX);
+			return;
+		}
+		// }}}
+		// {{{ do/while
+		if ($lastOp['opcode'] == XC_JMPNZ && !empty($lastOp['jmpouts'])
+		 && $lastOp['jmpouts'][0] == $range[0]) {
+			$this->removeJmpInfo($EX, $range[1]);
+			$this->beginComplexBlock($EX);
+
+			echo $indent, "do {", PHP_EOL;
+			$this->beginScope($EX);
+			$this->recognizeAndDecompileClosedBlocks($EX, $range);
+			$this->endScope($EX);
+			echo $indent, "} while (", str($this->getOpVal($lastOp['op1'], $EX)), ');', PHP_EOL;
+
+			$this->endComplexBlock($EX);
+			return;
+		}
+		// }}}
+
+		// {{{ search firstJmpOp
+		$firstJmp = null;
+		$firstJmpOp = null;
+		for ($i = $range[0]; $i <= $range[1]; ++$i) {
+			if (!empty($opcodes[$i]['jmpouts'])) {
+				$firstJmp = $i;
+				$firstJmpOp = &$opcodes[$firstJmp];
+				break;
+			}
+		}
+		// }}}
+
+		// {{{ while
+		if (isset($firstJmpOp)
+		 && $firstJmpOp['opcode'] == XC_JMPZ
+		 && $firstJmpOp['jmpouts'][0] > $range[1]
+		 && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts'])
+		 && $lastOp['jmpouts'][0] == $range[0]) {
+			$this->removeJmpInfo($EX, $firstJmp);
+			$this->removeJmpInfo($EX, $range[1]);
+			$this->beginComplexBlock($EX);
+
+			ob_start();
+			$this->beginScope($EX);
+			$this->recognizeAndDecompileClosedBlocks($EX, $range);
+			$this->endScope($EX);
+			$body = ob_get_clean();
+
+			echo $indent, 'while (', str($this->getOpVal($firstJmpOp['op1'], $EX)), ") {", PHP_EOL;
+			echo $body;
+			echo $indent, '}', PHP_EOL;
+
+			$this->endComplexBlock($EX);
+			return;
+		}
+		// }}}
+		// {{{ foreach
+		if (isset($firstJmpOp)
+		 && $firstJmpOp['opcode'] == XC_FE_FETCH
+		 && $firstJmpOp['jmpouts'][0] > $range[1]
+		 && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts'])
+		 && $lastOp['jmpouts'][0] == $firstJmp) {
+			$this->removeJmpInfo($EX, $firstJmp);
+			$this->removeJmpInfo($EX, $range[1]);
+			$this->beginComplexBlock($EX);
+
+			ob_start();
+			$this->beginScope($EX);
+			$this->recognizeAndDecompileClosedBlocks($EX, $range);
+			$this->endScope($EX);
+			$body = ob_get_clean();
+
+			$as = foldToCode($firstJmpOp['fe_as'], $EX);
+			if (isset($firstJmpOp['fe_key'])) {
+				$as = str($firstJmpOp['fe_key'], $EX) . ' => ' . str($as);
+			}
+
+			echo $indent, 'foreach (', str($firstJmpOp['fe_src'], $EX), " as $as) {", PHP_EOL;
+			echo $body;
+			echo $indent, '}', PHP_EOL;
+
+			$this->endComplexBlock($EX);
+			if ($opcodes[$range[1] + 1]['opcode'] == XC_SWITCH_FREE) {
+				$this->removeJmpInfo($EX, $range[1] + 1);
+			}
+			return;
+		}
+		// }}}
+
+		$this->decompileBasicBlock($EX, $range, true);
+	}
+	// }}}
+	function recognizeAndDecompileClosedBlocks(&$EX, $range) // {{{ decompile in a tree way
+	{
+		$opcodes = &$EX['opcodes'];
+
+		$starti = $range[0];
+		for ($i = $starti; $i <= $range[1]; ) {
+			if (!empty($opcodes[$i]['jmpins']) || !empty($opcodes[$i]['jmpouts'])) {
+				$blockFirst = $i;
+				$blockLast = -1;
+				$j = $blockFirst;
+				do {
+					$op = $opcodes[$j];
+					if (!empty($op['jmpins'])) {
+						// care about jumping from blocks behind, not before
+						foreach ($op['jmpins'] as $oplineNumber) {
+							if ($oplineNumber <= $range[1] && $blockLast < $oplineNumber) {
+								$blockLast = $oplineNumber;
+							}
+						}
+					}
+					if (!empty($op['jmpouts'])) {
+						$blockLast = max($blockLast, max($op['jmpouts']) - 1);
+					}
+					++$j;
+				} while ($j <= $blockLast);
+				if (!assert('$blockLast <= $range[1]')) {
+					var_dump($blockLast, $range[1]);
+				}
+
+				if ($blockLast >= $blockFirst) {
+					if ($blockFirst > $starti) {
+						$this->decompileBasicBlock($EX, array($starti, $blockFirst - 1));
+					}
+					if ($this->decompileComplexBlock($EX, array($blockFirst, $blockLast)) === false) {
+						if ($EX['lastBlock'] == 'complex') {
+							echo PHP_EOL;
+						}
+						$EX['lastBlock'] = null;
+					}
+					$starti = $blockLast + 1;
+					$i = $starti;
+				}
+				else {
+					++$i;
+				}
+			}
+			else {
+				++$i;
+			}
+		}
+		if ($starti <= $range[1]) {
+			$this->decompileBasicBlock($EX, array($starti, $range[1]));
+		}
+	}
+	// }}}
+	function &dop_array($op_array, $indent = '') // {{{
+	{
+		$op_array['opcodes'] = $this->fixOpcode($op_array['opcodes'], true, $indent == '' ? 1 : null);
+		$opcodes = &$op_array['opcodes'];
+		$last = count($opcodes) - 1;
+		// {{{ build jmpins/jmpouts to op_array
+		for ($i = 0; $i <= $last; $i ++) {
+			$op = &$opcodes[$i];
+			$op['line'] = $i;
+			switch ($op['opcode']) {
+			case XC_CONT:
+			case XC_BRK:
+				$op['jmpouts'] = array();
+				break;
+
+			case XC_GOTO:
+				$target = $op['op1']['var'];
+				$op['goto'] = $target;
+				$opcodes[$target]['gofrom'][] = $i;
+				break;
+
+			case XC_JMP:
+				$target = $op['op1']['var'];
+				$op['jmpouts'] = array($target);
+				$opcodes[$target]['jmpins'][] = $i;
+				break;
+
+			case XC_JMPZNZ:
+				$jmpz = $op['op2']['opline_num'];
+				$jmpnz = $op['extended_value'];
+				$op['jmpouts'] = array($jmpz, $jmpnz);
+				$opcodes[$jmpz]['jmpins'][] = $i;
+				$opcodes[$jmpnz]['jmpins'][] = $i;
+				break;
+
+			case XC_JMPZ:
+			case XC_JMPNZ:
+			case XC_JMPZ_EX:
+			case XC_JMPNZ_EX:
+			// case XC_JMP_SET:
+			// case XC_FE_RESET:
+			case XC_FE_FETCH:
+			// case XC_JMP_NO_CTOR:
+				$target = $op['op2']['opline_num'];
+				//if (!isset($target)) {
+				//	$this->dumpop($op, $EX);
+				//	var_dump($op); exit;
+				//}
+				$op['jmpouts'] = array($target);
+				$opcodes[$target]['jmpins'][] = $i;
+				break;
+
+			/*
+			case XC_RETURN:
+				$op['jmpouts'] = array();
+				break;
+			*/
+
+			case XC_SWITCH_FREE:
+				$op['jmpouts'] = array($i + 1);
+				$opcodes[$i + 1]['jmpins'][] = $i;
+				break;
+
+			case XC_CASE:
+				// just to link together
+				$op['jmpouts'] = array($i + 2);
+				$opcodes[$i + 2]['jmpins'][] = $i;
+				break;
+
+			case XC_CATCH:
+				$catchNext = $op['extended_value'];
+				$op['jmpouts'] = array($catchNext);
+				$opcodes[$catchNext]['jmpins'][] = $i;
+				break;
+			}
+			/*
+			if (!empty($op['jmpouts']) || !empty($op['jmpins'])) {
+				echo $i, "\t", xcache_get_opcode($op['opcode']), PHP_EOL;
+			}
+			// */
+		}
+		unset($op);
+		if ($op_array['try_catch_array']) {
+			foreach ($op_array['try_catch_array'] as $try_catch_element) {
+				$catch_op = $try_catch_element['catch_op'];
+				$try_op = $try_catch_element['try_op'];
+				$opcodes[$try_op]['jmpins'][] = $catch_op;
+				$opcodes[$catch_op]['jmpouts'][] = $try_op;
+				$opcodes[$catch_op]['isCatchBegin'] = true;
+			}
+		}
+		// }}}
+		// build semi-basic blocks
+		$nextbbs = array();
+		$starti = 0;
+		for ($i = 1; $i <= $last; $i ++) {
+			if (isset($opcodes[$i]['jmpins'])
+			 || isset($opcodes[$i - 1]['jmpouts'])) {
+				$nextbbs[$starti] = $i;
+				$starti = $i;
+			}
+		}
+		$nextbbs[$starti] = $last + 1;
+
+		$EX = array();
+		$EX['Ts'] = array();
+		$EX['indent'] = $indent;
+		$EX['nextbbs'] = $nextbbs;
+		$EX['op_array'] = &$op_array;
+		$EX['opcodes'] = &$opcodes;
+		$EX['range'] = array(0, count($opcodes) - 1);
+		// func call
+		$EX['object'] = null;
+		$EX['called_scope'] = null;
+		$EX['fbc'] = null;
+		$EX['argstack'] = array();
+		$EX['arg_types_stack'] = array();
+		$EX['scopeStack'] = array();
+		$EX['silence'] = 0;
+		$EX['recvs'] = array();
+		$EX['uses'] = array();
+		$EX['lastBlock'] = null;
+
+		/* dump whole array
+		$this->keepTs = true;
+		$this->dasmBasicBlock($EX, $range);
+		for ($i = $range[0]; $i <= $range[1]; ++$i) {
+			echo $i, "\t", $this->dumpop($opcodes[$i], $EX);
+		}
+		// */
+		// decompile in a tree way
+		$this->recognizeAndDecompileClosedBlocks($EX, $EX['range'], $EX['indent']);
+		return $EX;
+	}
+	// }}}
+	function dasmBasicBlock(&$EX, $range) // {{{
+	{
+		$T = &$EX['Ts'];
+		$opcodes = &$EX['opcodes'];
+		$lastphpop = null;
+
+		for ($i = $range[0]; $i <= $range[1]; $i ++) {
+			// {{{ prepair
+			$op = &$opcodes[$i];
+			$opc = $op['opcode'];
+			if ($opc == XC_NOP) {
+				$this->usedOps[$opc] = true;
+				continue;
+			}
+
+			$op1 = $op['op1'];
+			$op2 = $op['op2'];
+			$res = $op['result'];
+			$ext = $op['extended_value'];
+
+			$opname = xcache_get_opcode($opc);
+
+			if ($opname == 'UNDEF' || !isset($opname)) {
+				echo 'UNDEF OP:';
+				$this->dumpop($op, $EX);
+				continue;
+			}
+			// echo $i, ' '; $this->dumpop($op, $EX); //var_dump($op);
+
+			$resvar = null;
+			unset($curResVar);
+			if (array_key_exists($res['var'], $T)) {
+				$curResVar = &$T[$res['var']];
+			}
+			if ((ZEND_ENGINE_2_4 ? ($res['op_type'] & EXT_TYPE_UNUSED) : ($res['EA.type'] & EXT_TYPE_UNUSED)) || $res['op_type'] == XC_IS_UNUSED) {
+				$istmpres = false;
+			}
+			else {
+				$istmpres = true;
+			}
+			// }}}
+			// echo $opname, "\n";
+
+			$notHandled = false;
+			switch ($opc) {
+			case XC_NEW: // {{{
+				array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope']));
+				$EX['object'] = (int) $res['var'];
+				$EX['called_scope'] = null;
+				$EX['fbc'] = 'new ' . unquoteName($this->getOpVal($op1, $EX), $EX);
+				if (!ZEND_ENGINE_2) {
+					$resvar = '$new object$';
+				}
+				break;
+				// }}}
+			case XC_THROW: // {{{
+				$resvar = 'throw ' . str($this->getOpVal($op1, $EX));
+				break;
+				// }}}
+			case XC_CLONE: // {{{
+				$resvar = 'clone ' . str($this->getOpVal($op1, $EX));
+				break;
+				// }}}
+			case XC_CATCH: // {{{
+				break;
+				// }}}
+			case XC_INSTANCEOF: // {{{
+				$resvar = str($this->getOpVal($op1, $EX)) . ' instanceof ' . str($this->getOpVal($op2, $EX));
+				break;
+				// }}}
+			case XC_FETCH_CLASS: // {{{
+				if ($op2['op_type'] == XC_IS_UNUSED) {
+					switch (($ext & (defined('ZEND_FETCH_CLASS_MASK') ? ZEND_FETCH_CLASS_MASK : 0xFF))) {
+					case ZEND_FETCH_CLASS_SELF:
+						$class = 'self';
+						break;
+					case ZEND_FETCH_CLASS_PARENT:
+						$class = 'parent';
+						break;
+					case ZEND_FETCH_CLASS_STATIC:
+						$class = 'static';
+						break;
+					}
+					$istmpres = true;
+				}
+				else {
+					$class = $this->getOpVal($op2, $EX);
+					if (isset($op2['constant'])) {
+						$class = $this->stripNamespace(unquoteName($class));
+					}
+				}
+				$resvar = $class;
+				break;
+				// }}}
+			case XC_FETCH_CONSTANT: // {{{
+				if ($op1['op_type'] == XC_IS_UNUSED) {
+					$resvar = $this->stripNamespace($op2['constant']);
+					break;
+				}
+
+				if ($op1['op_type'] == XC_IS_CONST) {
+					$resvar = $this->stripNamespace($op1['constant']);
+				}
+				else {
+					$resvar = $this->getOpVal($op1, $EX);
+				}
+
+				$resvar = str($resvar) . '::' . unquoteName($this->getOpVal($op2, $EX));
+				break;
+				// }}}
+				// {{{ case XC_FETCH_*
+			case XC_FETCH_R:
+			case XC_FETCH_W:
+			case XC_FETCH_RW:
+			case XC_FETCH_FUNC_ARG:
+			case XC_FETCH_UNSET:
+			case XC_FETCH_IS:
+			case XC_UNSET_VAR:
+				$rvalue = $this->getOpVal($op1, $EX);
+				if (defined('ZEND_FETCH_TYPE_MASK')) {
+					$fetchtype = ($ext & ZEND_FETCH_TYPE_MASK);
+				}
+				else {
+					$fetchtype = $op2[!ZEND_ENGINE_2 ? 'fetch_type' : 'EA.type'];
+				}
+				switch ($fetchtype) {
+				case ZEND_FETCH_STATIC_MEMBER:
+					$class = $this->getOpVal($op2, $EX);
+					$rvalue = str($class) . '::$' . unquoteName($rvalue, $EX);
+					break;
+				default:
+					$name = unquoteName($rvalue, $EX);
+					$globalname = xcache_is_autoglobal($name) ? "\$$name" : "\$GLOBALS[" . str($rvalue) . "]";
+					$rvalue = new Decompiler_Fetch($rvalue, $fetchtype, $globalname);
+					break;
+				}
+				if ($opc == XC_UNSET_VAR) {
+					$op['php'] = "unset(" . str($rvalue, $EX) . ")";
+					$lastphpop = &$op;
+				}
+				else if ($res['op_type'] != XC_IS_UNUSED) {
+					$resvar = $rvalue;
+				}
+				break;
+				// }}}
+				// {{{ case XC_FETCH_DIM_*
+			case XC_FETCH_DIM_TMP_VAR:
+			case XC_FETCH_DIM_R:
+			case XC_FETCH_DIM_W:
+			case XC_FETCH_DIM_RW:
+			case XC_FETCH_DIM_FUNC_ARG:
+			case XC_FETCH_DIM_UNSET:
+			case XC_FETCH_DIM_IS:
+			case XC_ASSIGN_DIM:
+			case XC_UNSET_DIM_OBJ: // PHP 4 only
+			case XC_UNSET_DIM:
+			case XC_UNSET_OBJ:
+				$src = $this->getOpVal($op1, $EX);
+				if (is_a($src, "Decompiler_ForeachBox")) {
+					$src->iskey = $this->getOpVal($op2, $EX);
+					$resvar = $src;
+					break;
+				}
+
+				if (is_a($src, "Decompiler_DimBox")) {
+					$dimbox = $src;
+				}
+				else {
+					if (!is_a($src, "Decompiler_ListBox")) {
+						$op1val = $this->getOpVal($op1, $EX);
+						$list = new Decompiler_List(isset($op1val) ? $op1val : '$this');
+
+						$src = new Decompiler_ListBox($list);
+						if (!isset($op1['var'])) {
+							$this->dumpop($op, $EX);
+							var_dump($op);
+							die('missing var');
+						}
+						$T[$op1['var']] = $src;
+						unset($list);
+					}
+					$dim = new Decompiler_Dim($src);
+					$src->obj->dims[] = &$dim;
+
+					$dimbox = new Decompiler_DimBox($dim);
+				}
+				$dim = &$dimbox->obj;
+				$dim->offsets[] = $this->getOpVal($op2, $EX);
+				if ($ext == ZEND_FETCH_ADD_LOCK) {
+					$src->obj->everLocked = true;
+				}
+				else if ($ext == ZEND_FETCH_STANDARD) {
+					$dim->isLast = true;
+				}
+				if ($opc == XC_UNSET_OBJ) {
+					$dim->isObject = true;
+				}
+				unset($dim);
+				$rvalue = $dimbox;
+				unset($dimbox);
+
+				if ($opc == XC_ASSIGN_DIM) {
+					$lvalue = $rvalue;
+					++ $i;
+					$rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX);
+					$resvar = str($lvalue, $EX) . ' = ' . str($rvalue);
+				}
+				else if ($opc == XC_UNSET_DIM || $opc == XC_UNSET_OBJ) {
+					$op['php'] = "unset(" . str($rvalue, $EX) . ")";
+					$lastphpop = &$op;
+				}
+				else if ($res['op_type'] != XC_IS_UNUSED) {
+					$resvar = $rvalue;
+				}
+				break;
+				// }}}
+			case XC_ASSIGN: // {{{
+				$lvalue = $this->getOpVal($op1, $EX);
+				$rvalue = $this->getOpVal($op2, $EX);
+				if (is_a($rvalue, 'Decompiler_ForeachBox')) {
+					$type = $rvalue->iskey ? 'fe_key' : 'fe_as';
+					$rvalue->obj[$type] = $lvalue;
+					unset($T[$op2['var']]);
+					break;
+				}
+				if (is_a($rvalue, "Decompiler_DimBox")) {
+					$dim = &$rvalue->obj;
+					$dim->assign = $lvalue;
+					if ($dim->isLast) {
+						$resvar = foldToCode($dim->value, $EX);
+					}
+					unset($dim);
+					break;
+				}
+				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 = new Decompiler_Binop($this, $lvalue, XC_ASSIGN, $rvalue);
+				break;
+				// }}}
+			case XC_ASSIGN_REF: // {{{
+				$lvalue = $this->getOpVal($op1, $EX);
+				$rvalue = $this->getOpVal($op2, $EX);
+				if (is_a($rvalue, 'Decompiler_Fetch')) {
+					$src = str($rvalue->src, $EX);
+					if ('$' . unquoteName($src) == $lvalue) {
+						switch ($rvalue->fetchType) {
+						case ZEND_FETCH_GLOBAL:
+						case ZEND_FETCH_GLOBAL_LOCK:
+							$resvar = 'global ' . $lvalue;
+							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])) {
+								$var = $statics[$name];
+								$resvar .= ' = ';
+								$resvar .= str(value($var), $EX);
+							}
+							unset($statics);
+							break 2;
+						default:
+						}
+					}
+				}
+				// TODO: PHP_6 global
+				$resvar = new Decompiler_Binop($this, $lvalue, XC_ASSIGN_REF, $rvalue);
+				break;
+				// }}}
+			// {{{ case XC_FETCH_OBJ_*
+			case XC_FETCH_OBJ_R:
+			case XC_FETCH_OBJ_W:
+			case XC_FETCH_OBJ_RW:
+			case XC_FETCH_OBJ_FUNC_ARG:
+			case XC_FETCH_OBJ_UNSET:
+			case XC_FETCH_OBJ_IS:
+			case XC_ASSIGN_OBJ:
+				$obj = $this->getOpVal($op1, $EX);
+				if (!isset($obj)) {
+					$obj = '$this';
+				}
+				$rvalue = str($obj) . "->" . unquoteVariableName($this->getOpVal($op2, $EX), $EX);
+				if ($res['op_type'] != XC_IS_UNUSED) {
+					$resvar = $rvalue;
+				}
+				if ($opc == XC_ASSIGN_OBJ) {
+					++ $i;
+					$lvalue = $rvalue;
+					$rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX);
+					$resvar = "$lvalue = " . str($rvalue);
+				}
+				break;
+				// }}}
+			case XC_ISSET_ISEMPTY_DIM_OBJ:
+			case XC_ISSET_ISEMPTY_PROP_OBJ:
+			case XC_ISSET_ISEMPTY:
+			case XC_ISSET_ISEMPTY_VAR: // {{{
+				if ($opc == XC_ISSET_ISEMPTY_VAR) {
+					$rvalue = $this->getOpVal($op1, $EX);
+					// for < PHP_5_3
+					if ($op1['op_type'] == XC_IS_CONST) {
+						$rvalue = '$' . unquoteVariableName($this->getOpVal($op1, $EX));
+					}
+					if ($op2['EA.type'] == ZEND_FETCH_STATIC_MEMBER) {
+						$class = $this->getOpVal($op2, $EX);
+						$rvalue = $class . '::' . $rvalue;
+					}
+				}
+				else if ($opc == XC_ISSET_ISEMPTY) {
+					$rvalue = $this->getOpVal($op1, $EX);
+				}
+				else {
+					$container = $this->getOpVal($op1, $EX);
+					$dim = $this->getOpVal($op2, $EX);
+					if ($opc == XC_ISSET_ISEMPTY_PROP_OBJ) {
+						if (!isset($container)) {
+							$container = '$this';
+						}
+						$rvalue = $container . "->" . unquoteVariableName($dim);
+					}
+					else {
+						$rvalue = $container . '[' . str($dim) .']';
+					}
+				}
+
+				switch ((!ZEND_ENGINE_2 ? $op['op2']['var'] /* constant */ : $ext) & (ZEND_ISSET|ZEND_ISEMPTY)) {
+				case ZEND_ISSET:
+					$rvalue = "isset(" . str($rvalue) . ")";
+					break;
+				case ZEND_ISEMPTY:
+					$rvalue = "empty(" . str($rvalue) . ")";
+					break;
+				}
+				$resvar = $rvalue;
+				break;
+				// }}}
+			case XC_SEND_VAR_NO_REF:
+			case XC_SEND_VAL:
+			case XC_SEND_REF:
+			case XC_SEND_VAR: // {{{
+				$ref = ($opc == XC_SEND_REF ? '&' : '');
+				$EX['argstack'][] = $ref . str($this->getOpVal($op1, $EX));
+				break;
+				// }}}
+			case XC_INIT_STATIC_METHOD_CALL:
+			case XC_INIT_METHOD_CALL: // {{{
+				array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope']));
+				if ($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL || $op1['op_type'] != XC_IS_UNUSED) {
+					$obj = $this->getOpVal($op1, $EX);
+					if (!isset($obj)) {
+						$obj = '$this';
+					}
+					if ($opc == XC_INIT_STATIC_METHOD_CALL || /* PHP4 */ isset($op1['constant'])) {
+						$EX['object'] = null;
+						$EX['called_scope'] = $this->stripNamespace(unquoteName($obj, $EX));
+					}
+					else {
+						$EX['object'] = $obj;
+						$EX['called_scope'] = null;
+					}
+					if ($res['op_type'] != XC_IS_UNUSED) {
+						$resvar = '$obj call$';
+					}
+				}
+				else {
+					$EX['object'] = null;
+					$EX['called_scope'] = null;
+				}
+
+				$EX['fbc'] = $this->getOpVal($op2, $EX);
+				if (($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL) && !isset($EX['fbc'])) {
+					$EX['fbc'] = '__construct';
+				}
+				break;
+				// }}}
+			case XC_INIT_NS_FCALL_BY_NAME:
+			case XC_INIT_FCALL_BY_NAME: // {{{
+				array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope']));
+				if (!ZEND_ENGINE_2 && ($ext & ZEND_CTOR_CALL)) {
+					break;
+				}
+				$EX['object'] = null;
+				$EX['called_scope'] = null;
+				$EX['fbc'] = $this->getOpVal($op2, $EX);
+				break;
+				// }}}
+			case XC_INIT_FCALL_BY_FUNC: // {{{ deprecated even in PHP 4?
+				$EX['object'] = null;
+				$EX['called_scope'] = null;
+				$which = $op1['var'];
+				$EX['fbc'] = $EX['op_array']['funcs'][$which]['name'];
+				break;
+				// }}}
+			case XC_DO_FCALL_BY_FUNC:
+				$which = $op1['var'];
+				$fname = $EX['op_array']['funcs'][$which]['name'];
+				$args = $this->popargs($EX, $ext);
+				$resvar = $fname . "($args)";
+				break;
+			case XC_DO_FCALL:
+				$fname = unquoteName($this->getOpVal($op1, $EX), $EX);
+				$args = $this->popargs($EX, $ext);
+				$resvar = $fname . "($args)";
+				break;
+			case XC_DO_FCALL_BY_NAME: // {{{
+				$object = null;
+
+				$fname = unquoteName($EX['fbc'], $EX);
+				if (!is_int($EX['object'])) {
+					$object = $EX['object'];
+				}
+
+				$args = $this->popargs($EX, $ext);
+
+				$prefix = (isset($object) ? $object . '->' : '' )
+					. (isset($EX['called_scope']) ? $EX['called_scope'] . '::' : '' );
+				$resvar = $prefix
+					. (!$prefix ? $this->stripNamespace($fname) : $fname)
+					. "($args)";
+				unset($args);
+
+				if (is_int($EX['object'])) {
+					$T[$EX['object']] = $resvar;
+					$resvar = null;
+				}
+				list($EX['fbc'], $EX['object'], $EX['called_scope']) = array_pop($EX['arg_types_stack']);
+				break;
+				// }}}
+			case XC_VERIFY_ABSTRACT_CLASS: // {{{
+				//unset($T[$op1['var']]);
+				break;
+				// }}}
+			case XC_DECLARE_CLASS: 
+			case XC_DECLARE_INHERITED_CLASS:
+			case XC_DECLARE_INHERITED_CLASS_DELAYED: // {{{
+				$key = $op1['constant'];
+				if (!isset($this->dc['class_table'][$key])) {
+					echo 'class not found: ', $key, 'existing classes are:', "\n";
+					var_dump(array_keys($this->dc['class_table']));
+					exit;
+				}
+				$class = &$this->dc['class_table'][$key];
+				if (!isset($class['name'])) {
+					$class['name'] = unquoteName($this->getOpVal($op2, $EX), $EX);
+				}
+				if ($opc == XC_DECLARE_INHERITED_CLASS || $opc == XC_DECLARE_INHERITED_CLASS_DELAYED) {
+					$ext /= XC_SIZEOF_TEMP_VARIABLE;
+					$class['parent'] = $T[$ext];
+					unset($T[$ext]);
+				}
+				else {
+					$class['parent'] = null;
+				}
+
+				for (;;) {
+					if ($i + 1 <= $range[1]
+					 && $opcodes[$i + 1]['opcode'] == XC_ADD_INTERFACE
+					 && $opcodes[$i + 1]['op1']['var'] == $res['var']) {
+						// continue
+					}
+					else if ($i + 2 <= $range[1]
+					 && $opcodes[$i + 2]['opcode'] == XC_ADD_INTERFACE
+					 && $opcodes[$i + 2]['op1']['var'] == $res['var']
+					 && $opcodes[$i + 1]['opcode'] == XC_FETCH_CLASS) {
+						// continue
+					}
+					else {
+						break;
+					}
+					$this->usedOps[XC_ADD_INTERFACE] = true;
+
+					$fetchop = &$opcodes[$i + 1];
+					$interface = $this->stripNamespace(unquoteName($this->getOpVal($fetchop['op2'], $EX), $EX));
+					$addop = &$opcodes[$i + 2];
+					$class['interfaces'][$addop['extended_value']] = $interface;
+					unset($fetchop, $addop);
+					$i += 2;
+				}
+				$this->dclass($class, $EX['indent']);
+				echo "\n";
+				unset($class);
+				break;
+				// }}}
+			case XC_INIT_STRING: // {{{
+				$resvar = "''";
+				break;
+				// }}}
+			case XC_ADD_CHAR:
+			case XC_ADD_STRING:
+			case XC_ADD_VAR: // {{{
+				$op1val = $this->getOpVal($op1, $EX);
+				$op2val = $this->getOpVal($op2, $EX);
+				switch ($opc) {
+				case XC_ADD_CHAR:
+					$op2val = value(chr(str($op2val)));
+					break;
+				case XC_ADD_STRING:
+					break;
+				case XC_ADD_VAR:
+					break;
+				}
+				if (str($op1val) == "''") {
+					$rvalue = $op2val;
+				}
+				else if (str($op2val) == "''") {
+					$rvalue = $op1val;
+				}
+				else {
+					$rvalue = str($op1val) . ' . ' . str($op2val);
+				}
+				$resvar = $rvalue;
+				// }}}
+				break;
+			case XC_PRINT: // {{{
+				$op1val = $this->getOpVal($op1, $EX);
+				$resvar = "print(" . str($op1val) . ")";
+				break;
+				// }}}
+			case XC_ECHO: // {{{
+				$op1val = $this->getOpVal($op1, $EX);
+				$resvar = "echo " . str($op1val);
+				break;
+				// }}}
+			case XC_EXIT: // {{{
+				$op1val = $this->getOpVal($op1, $EX);
+				$resvar = "exit($op1val)";
+				break;
+				// }}}
+			case XC_INIT_ARRAY:
+			case XC_ADD_ARRAY_ELEMENT: // {{{
+				$rvalue = $this->getOpVal($op1, $EX, true);
+
+				if ($opc == XC_ADD_ARRAY_ELEMENT) {
+					$assoc = $this->getOpVal($op2, $EX);
+					if (isset($assoc)) {
+						$curResVar->value[] = array($assoc, $rvalue);
+					}
+					else {
+						$curResVar->value[] = array(null, $rvalue);
+					}
+				}
+				else {
+					if ($opc == XC_INIT_ARRAY) {
+						$resvar = new Decompiler_Array();
+						if (!isset($rvalue)) {
+							continue;
+						}
+					}
+
+					$assoc = $this->getOpVal($op2, $EX);
+					if (isset($assoc)) {
+						$resvar->value[] = array($assoc, $rvalue);
+					}
+					else {
+						$resvar->value[] = array(null, $rvalue);
+					}
+				}
+				break;
+				// }}}
+			case XC_QM_ASSIGN: // {{{
+				if (isset($curResVar) && is_a($curResVar, 'Decompiler_Binop')) {
+					$curResVar->op2 = $this->getOpVal($op1, $EX);
+				}
+				else {
+					$resvar = $this->getOpVal($op1, $EX);
+				}
+				break;
+				// }}}
+			case XC_BOOL: // {{{
+				$resvar = /*'(bool) ' .*/ $this->getOpVal($op1, $EX);
+				break;
+				// }}}
+			case XC_RETURN: // {{{
+				$resvar = "return " . str($this->getOpVal($op1, $EX));
+				break;
+				// }}}
+			case XC_INCLUDE_OR_EVAL: // {{{
+				$type = $op2['var']; // hack
+				$keyword = $this->includeTypes[$type];
+				$resvar = "$keyword " . str($this->getOpVal($op1, $EX));
+				break;
+				// }}}
+			case XC_FE_RESET: // {{{
+				$resvar = $this->getOpVal($op1, $EX);
+				break;
+				// }}}
+			case XC_FE_FETCH: // {{{
+				$op['fe_src'] = $this->getOpVal($op1, $EX, true);
+				$fe = new Decompiler_ForeachBox($op);
+				$fe->iskey = false;
+				$T[$res['var']] = $fe;
+
+				++ $i;
+				if (($ext & ZEND_FE_FETCH_WITH_KEY)) {
+					$fe = new Decompiler_ForeachBox($op);
+					$fe->iskey = true;
+
+					$res = $opcodes[$i]['result'];
+					$T[$res['var']] = $fe;
+				}
+				break;
+				// }}}
+			case XC_SWITCH_FREE: // {{{
+				break;
+				// }}}
+			case XC_FREE: // {{{
+				$free = $T[$op1['var']];
+				if (!is_a($free, 'Decompiler_Array') && !is_a($free, 'Decompiler_Box')) {
+					$op['php'] = is_object($free) ? $free : $this->unquote($free, '(', ')');
+					$lastphpop = &$op;
+				}
+				unset($T[$op1['var']], $free);
+				break;
+				// }}}
+			case XC_JMP_NO_CTOR:
+				break;
+			case XC_JMP_SET: // ?:
+				$resvar = new Decompiler_Binop($this, $this->getOpVal($op1, $EX), XC_JMP_SET, null);
+				break;
+			case XC_JMPZ_EX: // and
+			case XC_JMPNZ_EX: // or
+				$resvar = $this->getOpVal($op1, $EX);
+				break;
+
+			case XC_JMPNZ: // while
+			case XC_JMPZNZ: // for
+			case XC_JMPZ: // {{{
+				break;
+				// }}}
+			case XC_CONT:
+			case XC_BRK:
+				$resvar = $opc == XC_CONT ? 'continue' : 'break';
+				$count = str($this->getOpVal($op2, $EX));
+				if ($count != '1') {
+					$resvar .= ' ' . $count;
+				}
+				break;
+			case XC_GOTO:
+				$resvar = 'goto label' . $op['op1']['var'];
+				$istmpres = false;
+				break;
+
+			case XC_JMP: // {{{
+				break;
+				// }}}
+			case XC_CASE:
+				// $switchValue = $this->getOpVal($op1, $EX);
+				$caseValue = $this->getOpVal($op2, $EX);
+				$resvar = $caseValue;
+				break;
+			case XC_RECV_INIT:
+			case XC_RECV:
+				$offset = $this->getOpVal($op1, $EX);
+				$lvalue = $this->getOpVal($op['result'], $EX);
+				if ($opc == XC_RECV_INIT) {
+					$default = value($op['op2']['constant']);
+				}
+				else {
+					$default = null;
+				}
+				$EX['recvs'][str($offset)] = array($lvalue, $default);
+				break;
+			case XC_POST_DEC:
+			case XC_POST_INC:
+			case XC_POST_DEC_OBJ:
+			case XC_POST_INC_OBJ:
+			case XC_PRE_DEC:
+			case XC_PRE_INC:
+			case XC_PRE_DEC_OBJ:
+			case XC_PRE_INC_OBJ: // {{{
+				$flags = array_flip(explode('_', $opname));
+				if (isset($flags['OBJ'])) {
+					$resvar = $this->getOpVal($op1, $EX) . '->' . unquoteVariableName($this->getOpVal($op2, $EX), $EX);
+				}
+				else {
+					$resvar = $this->getOpVal($op1, $EX);
+				}
+				$opstr = isset($flags['DEC']) ? '--' : '++';
+				if (isset($flags['POST'])) {
+					$resvar .= $opstr;
+				}
+				else {
+					$resvar = "$opstr$resvar";
+				}
+				break;
+				// }}}
+
+			case XC_BEGIN_SILENCE: // {{{
+				$EX['silence'] ++;
+				break;
+				// }}}
+			case XC_END_SILENCE: // {{{
+				$EX['silence'] --;
+				$lastresvar = '@' . str($lastresvar, $EX);
+				break;
+				// }}}
+			case XC_CAST: // {{{
+				$type = $ext;
+				static $type2cast = array(
+						IS_LONG   => '(int)',
+						IS_DOUBLE => '(double)',
+						IS_STRING => '(string)',
+						IS_ARRAY  => '(array)',
+						IS_OBJECT => '(object)',
+						IS_BOOL   => '(bool)',
+						IS_NULL   => '(unset)',
+						);
+				assert(isset($type2cast[$type]));
+				$cast = $type2cast[$type];
+				$resvar = $cast . ' ' . $this->getOpVal($op1, $EX);
+				break;
+				// }}}
+			case XC_EXT_STMT:
+			case XC_EXT_FCALL_BEGIN:
+			case XC_EXT_FCALL_END:
+			case XC_EXT_NOP:
+				break;
+			case XC_DECLARE_FUNCTION:
+				$this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']);
+				break;
+			case XC_DECLARE_LAMBDA_FUNCTION: // {{{
+				ob_start();
+				$this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']);
+				$resvar = ob_get_clean();
+				$istmpres = true;
+				break;
+				// }}}
+			case XC_DECLARE_CONST:
+				$name = $this->stripNamespace(unquoteName($this->getOpVal($op1, $EX), $EX));
+				$value = str($this->getOpVal($op2, $EX));
+				$resvar = 'const ' . $name . ' = ' . $value;
+				break;
+			case XC_DECLARE_FUNCTION_OR_CLASS:
+				/* always removed by compiler */
+				break;
+			case XC_TICKS:
+				$lastphpop['ticks'] = $this->getOpVal($op1, $EX);
+				// $EX['tickschanged'] = true;
+				break;
+			case XC_RAISE_ABSTRACT_ERROR:
+				// abstract function body is empty, don't need this code
+				break;
+			case XC_USER_OPCODE:
+				echo '// ZEND_USER_OPCODE, impossible to decompile';
+				break;
+			case XC_OP_DATA:
+				break;
+			default: // {{{
+				$call = array(&$this, $opname);
+				if (is_callable($call)) {
+					$this->usedOps[$opc] = true;
+					$this->{$opname}($op, $EX);
+				}
+				else if (isset($this->binops[$opc])) { // {{{
+					$this->usedOps[$opc] = true;
+					$op1val = $this->getOpVal($op1, $EX);
+					$op2val = $this->getOpVal($op2, $EX);
+					$rvalue = new Decompiler_Binop($this, $op1val, $opc, $op2val);
+					$resvar = $rvalue;
+					// }}}
+				}
+				else if (isset($this->unaryops[$opc])) { // {{{
+					$this->usedOps[$opc] = true;
+					$op1val = $this->getOpVal($op1, $EX);
+					$myop = $this->unaryops[$opc];
+					$rvalue = $myop . str($op1val);
+					$resvar = $rvalue;
+					// }}}
+				}
+				else {
+					$notHandled = true;
+				}
+				// }}}
+			}
+			if ($notHandled) {
+				echo "\x1B[31m * TODO ", $opname, "\x1B[0m\n";
+			}
+			else {
+				$this->usedOps[$opc] = true;
+			}
+
+			if (isset($resvar)) {
+				if ($istmpres) {
+					$T[$res['var']] = $resvar;
+					$lastresvar = &$T[$res['var']];
+				}
+				else {
+					$op['php'] = $resvar;
+					$lastphpop = &$op;
+					$lastresvar = &$op['php'];
+				}
+			}
+		}
+		return $T;
+	}
+	// }}}
+	function unquote($str, $st, $ed) // {{{
+	{
+		$l1 = strlen($st);
+		$l2 = strlen($ed);
+		if (substr($str, 0, $l1) === $st && substr($str, -$l2) === $ed) {
+			$str = substr($str, $l1, -$l2);
+		}
+		return $str;
+	}
+	// }}}
+	function popargs(&$EX, $n) // {{{
+	{
+		$args = array();
+		for ($i = 0; $i < $n; $i ++) {
+			$a = array_pop($EX['argstack']);
+			if (is_array($a)) {
+				array_unshift($args, foldToCode($a, $EX));
+			}
+			else {
+				array_unshift($args, $a);
+			}
+		}
+		return implode(', ', $args);
+	}
+	// }}}
+	function dumpop($op, &$EX) // {{{
+	{
+		assert('isset($op)');
+		$op1 = $op['op1'];
+		$op2 = $op['op2'];
+		$d = array(xcache_get_opcode($op['opcode']), $op['opcode']);
+
+		foreach (array('op1' => '1:', 'op2' => '2:', 'result' => '>') as $k => $kk) {
+			switch ($op[$k]['op_type']) {
+			case XC_IS_UNUSED:
+				$d[$kk] = 'U:' . $op[$k]['opline_num'];
+				break;
+
+			case XC_IS_VAR:
+				$d[$kk] = '$' . $op[$k]['var'];
+				if ($k != 'result') {
+					$d[$kk] .= ':' . str($this->getOpVal($op[$k], $EX));
+				}
+				break;
+
+			case XC_IS_TMP_VAR:
+				$d[$kk] = '#' . $op[$k]['var'];
+				if ($k != 'result') {
+					$d[$kk] .= ':' . str($this->getOpVal($op[$k], $EX));
+				}
+				break;
+
+			case XC_IS_CV:
+				$d[$kk] = $this->getOpVal($op[$k], $EX);
+				break;
+
+			default:
+				if ($k == 'result') {
+					var_dump($op);
+					assert(0);
+					exit;
+				}
+				else {
+					$d[$kk] = $this->getOpVal($op[$k], $EX);
+				}
+			}
+		}
+		$d[';'] = $op['extended_value'];
+		if (!empty($op['jmpouts'])) {
+			$d['>>'] = implode(',', $op['jmpouts']);
+		}
+		if (!empty($op['jmpins'])) {
+			$d['<<'] = implode(',', $op['jmpins']);
+		}
+
+		foreach ($d as $k => $v) {
+			echo is_int($k) ? '' : $k, str($v), "\t";
+		}
+		echo PHP_EOL;
+	}
+	// }}}
+	function dumpRange(&$EX, $range) // {{{
+	{
+		for ($i = $range[0]; $i <= $range[1]; ++$i) {
+			echo $EX['indent'], $i, "\t"; $this->dumpop($EX['opcodes'][$i], $EX);
+		}
+		echo $EX['indent'], "==", PHP_EOL;
+	}
+	// }}}
+	function dargs(&$EX) // {{{
+	{
+		$op_array = &$EX['op_array'];
+
+		if (isset($op_array['num_args'])) {
+			$c = $op_array['num_args'];
+		}
+		else if (!empty($op_array['arg_types'])) {
+			$c = count($op_array['arg_types']);
+		}
+		else {
+			// php4
+			$c = count($EX['recvs']);
+		}
+
+		$refrest = false;
+		for ($i = 0; $i < $c; $i ++) {
+			if ($i) {
+				echo ', ';
+			}
+			$arg = $EX['recvs'][$i + 1];
+			if (isset($op_array['arg_info'])) {
+				$ai = $op_array['arg_info'][$i];
+				if (!empty($ai['class_name'])) {
+					echo $this->stripNamespace($ai['class_name']), ' ';
+					if (!ZEND_ENGINE_2_2 && $ai['allow_null']) {
+						echo 'or NULL ';
+					}
+				}
+				else if (!empty($ai['array_type_hint'])) {
+					echo 'array ';
+					if (!ZEND_ENGINE_2_2 && $ai['allow_null']) {
+						echo 'or NULL ';
+					}
+				}
+				if ($ai['pass_by_reference']) {
+					echo '&';
+				}
+				printf("\$%s", $ai['name']);
+			}
+			else {
+				if ($refrest) {
+					echo '&';
+				}
+				else if (!empty($op_array['arg_types']) && isset($op_array['arg_types'][$i])) {
+					switch ($op_array['arg_types'][$i]) {
+					case BYREF_FORCE_REST:
+						$refrest = true;
+						/* fall */
+					case BYREF_FORCE:
+						echo '&';
+						break;
+
+					case BYREF_NONE:
+					case BYREF_ALLOW:
+						break;
+					default:
+						assert(0);
+					}
+				}
+				echo str($arg[0], $EX);
+			}
+			if (isset($arg[1])) {
+				echo ' = ', str($arg[1], $EX);
+			}
+		}
+	}
+	// }}}
+	function duses(&$EX) // {{{
+	{
+		if ($EX['uses']) {
+			echo ' use(', implode(', ', $EX['uses']), ')';
+		}
+	}
+	// }}}
+	function dfunction($func, $indent = '', $decorations = array(), $nobody = false) // {{{
+	{
+		$this->detectNamespace($func['op_array']['function_name']);
+
+		if ($nobody) {
+			$EX = array();
+			$EX['op_array'] = &$func['op_array'];
+			$EX['recvs'] = array();
+			$EX['uses'] = array();
+		}
+		else {
+			ob_start();
+			$EX = &$this->dop_array($func['op_array'], $indent . INDENT);
+			$body = ob_get_clean();
+		}
+
+		$functionName = $this->stripNamespace($func['op_array']['function_name']);
+		$isExpression = false;
+		if ($functionName == '{closure}') {
+			$functionName = '';
+			$isExpression = true;
+		}
+		echo $isExpression ? '' : $indent;
+		if ($decorations) {
+			echo implode(' ', $decorations), ' ';
+		}
+		echo 'function', $functionName ? ' ' . $functionName : '', '(';
+		$this->dargs($EX);
+		echo ")";
+		$this->duses($EX);
+		if ($nobody) {
+			echo ";\n";
+		}
+		else {
+			if (!$isExpression) {
+				echo "\n";
+				echo $indent, "{\n";
+			}
+			else {
+				echo " {\n";
+			}
+
+			echo $body;
+			echo "$indent}";
+			if (!$isExpression) {
+				echo "\n";
+			}
+		}
+	}
+	// }}}
+	function dclass($class, $indent = '') // {{{
+	{
+		$this->detectNamespace($class['name']);
+
+		// {{{ class decl
+		if (!empty($class['doc_comment'])) {
+			echo $indent;
+			echo $class['doc_comment'];
+			echo "\n";
+		}
+		$isInterface = false;
+		$decorations = array();
+		if (!empty($class['ce_flags'])) {
+			if ($class['ce_flags'] & ZEND_ACC_INTERFACE) {
+				$isInterface = true;
+			}
+			else {
+				if ($class['ce_flags'] & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
+					$decorations[] = "abstract";
+				}
+				if ($class['ce_flags'] & ZEND_ACC_FINAL_CLASS) {
+					$decorations[] = "final";
+				}
+			}
+		}
+
+		echo $indent;
+		if ($decorations) {
+			echo implode(' ', $decorations), ' ';
+		}
+		echo $isInterface ? 'interface ' : 'class ', $this->stripNamespace($class['name']);
+		if ($class['parent']) {
+			echo ' extends ', $class['parent'];
+		}
+		/* TODO */
+		if (!empty($class['interfaces'])) {
+			echo ' implements ';
+			echo implode(', ', $class['interfaces']);
+		}
+		echo "\n";
+		echo $indent, "{";
+		// }}}
+		$newindent = INDENT . $indent;
+		// {{{ const, static
+		foreach (array('constants_table' => 'const '
+					, 'static_members' => 'static $') as $type => $prefix) {
+			if (!empty($class[$type])) {
+				echo "\n";
+				// TODO: skip shadow?
+				foreach ($class[$type] as $name => $v) {
+					echo $newindent;
+					echo $prefix, $name, ' = ';
+					echo str(value($v), $newindent);
+					echo ";\n";
+				}
+			}
+		}
+		// }}}
+		// {{{ properties
+		$member_variables = isset($class['properties_info']) ? $class['properties_info'] : ($class['default_static_members'] + $class['default_properties']);
+		if ($member_variables) {
+			echo "\n";
+			$infos = !empty($class['properties_info']) ? $class['properties_info'] : null;
+			foreach ($member_variables as $name => $dummy) {
+				$info = (isset($infos) && isset($infos[$name])) ? $infos[$name] : null;
+				if (isset($info)) {
+					if (!empty($info['doc_comment'])) {
+						echo $newindent;
+						echo $info['doc_comment'];
+						echo "\n";
+					}
+				}
+
+				echo $newindent;
+				$static = false;
+				if (isset($info)) {
+					if ($info['flags'] & ZEND_ACC_STATIC) {
+						$static = true;
+					}
+				}
+				else if (isset($class['default_static_members'][$name])) {
+					$static = true;
+				}
+
+				if ($static) {
+					echo "static ";
+				}
+
+				$mangled = false;
+				if (!ZEND_ENGINE_2) {
+					echo 'var ';
+				}
+				else if (!isset($info)) {
+					echo 'public ';
+				}
+				else {
+					if ($info['flags'] & ZEND_ACC_SHADOW) {
+						continue;
+					}
+					switch ($info['flags'] & ZEND_ACC_PPP_MASK) {
+					case ZEND_ACC_PUBLIC:
+						echo "public ";
+						break;
+					case ZEND_ACC_PRIVATE:
+						echo "private ";
+						$mangled = true;
+						break;
+					case ZEND_ACC_PROTECTED:
+						echo "protected ";
+						$mangled = true;
+						break;
+					}
+				}
+
+				echo '$', $name;
+
+				if (isset($info['offset'])) {
+					$value = $class[$static ? 'default_static_members_table' : 'default_properties_table'][$info['offset']];
+				}
+				else {
+					$key = isset($info) ? $info['name'] . ($mangled ? "\000" : "") : $name;
+
+					$value = $class[$static ? 'default_static_members' : 'default_properties'][$key];
+				}
+				if (isset($value)) {
+					echo ' = ';
+					echo str(value($value), $newindent);
+				}
+				echo ";\n";
+			}
+		}
+		// }}}
+		// {{{ function_table
+		if (isset($class['function_table'])) {
+			foreach ($class['function_table'] as $func) {
+				if (!isset($func['scope']) || $func['scope'] == $class['name']) {
+					// TODO: skip shadow here
+					echo "\n";
+					$opa = $func['op_array'];
+					if (!empty($opa['doc_comment'])) {
+						echo $newindent;
+						echo $opa['doc_comment'];
+						echo "\n";
+					}
+					$isAbstractMethod = false;
+					$decorations = array();
+					if (isset($opa['fn_flags'])) {
+						if (($opa['fn_flags'] & ZEND_ACC_ABSTRACT) && !$isInterface) {
+							$decorations[] = "abstract";
+							$isAbstractMethod = true;
+						}
+						if ($opa['fn_flags'] & ZEND_ACC_FINAL) {
+							$decorations[] = "final";
+						}
+						if ($opa['fn_flags'] & ZEND_ACC_STATIC) {
+							$decorations[] = "static";
+						}
+
+						switch ($opa['fn_flags'] & ZEND_ACC_PPP_MASK) {
+							case ZEND_ACC_PUBLIC:
+								$decorations[] = "public";
+								break;
+							case ZEND_ACC_PRIVATE:
+								$decorations[] = "private";
+								break;
+							case ZEND_ACC_PROTECTED:
+								$decorations[] = "protected";
+								break;
+							default:
+								$decorations[] = "<visibility error>";
+								break;
+						}
+					}
+					$this->dfunction($func, $newindent, $decorations, $isInterface || $isAbstractMethod);
+					if ($opa['function_name'] == 'Decompiler') {
+						//exit;
+					}
+				}
+			}
+		}
+		// }}}
+		echo $indent, "}\n";
+	}
+	// }}}
+	function decompileString($string) // {{{
+	{
+		$this->dc = xcache_dasm_string($string);
+		if ($this->dc === false) {
+			echo "error compling string\n";
+			return false;
+		}
+	}
+	// }}}
+	function decompileFile($file) // {{{
+	{
+		$this->dc = xcache_dasm_file($file);
+		if ($this->dc === false) {
+			echo "error compling $file\n";
+			return false;
+		}
+	}
+	// }}}
+	function decompileDasm($content) // {{{
+	{
+		$this->dc = $content;
+	}
+	// }}}
+	function output() // {{{
+	{
+		echo "<?". "php\n\n";
+		foreach ($this->dc['class_table'] as $key => $class) {
+			if ($key{0} != "\0") {
+				$this->dclass($class);
+				echo "\n";
+			}
+		}
+
+		foreach ($this->dc['function_table'] as $key => $func) {
+			if ($key{0} != "\0") {
+				$this->dfunction($func);
+				echo "\n";
+			}
+		}
+
+		$this->dop_array($this->dc['op_array']);
+		echo "\n?" . ">\n";
+
+		if (!empty($this->test)) {
+			$this->outputUnusedOp();
+		}
+		return true;
+	}
+	// }}}
+	function outputUnusedOp() // {{{
+	{
+		for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
+			if ($opname == 'UNDEF')  {
+				continue;
+			}
+
+			if (!isset($this->usedOps[$i])) {
+				echo "not covered opcode ", $opname, "\n";
+			}
+		}
+	}
+	// }}}
+}
+
+// {{{ defines
+define('ZEND_ENGINE_2_4', PHP_VERSION >= "5.3.99");
+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.");
+define('ZEND_ENGINE_2',   ZEND_ENGINE_2_1 || PHP_VERSION >= "5.0.");
+
+define('ZEND_ACC_STATIC',         0x01);
+define('ZEND_ACC_ABSTRACT',       0x02);
+define('ZEND_ACC_FINAL',          0x04);
+define('ZEND_ACC_IMPLEMENTED_ABSTRACT',       0x08);
+
+define('ZEND_ACC_IMPLICIT_ABSTRACT_CLASS',    0x10);
+define('ZEND_ACC_EXPLICIT_ABSTRACT_CLASS',    0x20);
+define('ZEND_ACC_FINAL_CLASS',                0x40);
+define('ZEND_ACC_INTERFACE',                  0x80);
+if (ZEND_ENGINE_2_4) {
+	define('ZEND_ACC_TRAIT',                  0x120);
+}
+define('ZEND_ACC_PUBLIC',     0x100);
+define('ZEND_ACC_PROTECTED',  0x200);
+define('ZEND_ACC_PRIVATE',    0x400);
+define('ZEND_ACC_PPP_MASK',  (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE));
+
+define('ZEND_ACC_CHANGED',    0x800);
+define('ZEND_ACC_IMPLICIT_PUBLIC',    0x1000);
+
+define('ZEND_ACC_CTOR',       0x2000);
+define('ZEND_ACC_DTOR',       0x4000);
+define('ZEND_ACC_CLONE',      0x8000);
+
+define('ZEND_ACC_ALLOW_STATIC',   0x10000);
+
+define('ZEND_ACC_SHADOW', 0x2000);
+
+if (ZEND_ENGINE_2_4) {
+	define('ZEND_FETCH_GLOBAL',           0x00000000);
+	define('ZEND_FETCH_LOCAL',            0x10000000);
+	define('ZEND_FETCH_STATIC',           0x20000000);
+	define('ZEND_FETCH_STATIC_MEMBER',    0x30000000);
+	define('ZEND_FETCH_GLOBAL_LOCK',      0x40000000);
+	define('ZEND_FETCH_LEXICAL',          0x50000000);
+
+	define('ZEND_FETCH_TYPE_MASK',        0x70000000);
+}
+else {
+	define('ZEND_FETCH_GLOBAL',           0);
+	define('ZEND_FETCH_LOCAL',            1);
+	define('ZEND_FETCH_STATIC',           2);
+	define('ZEND_FETCH_STATIC_MEMBER',    3);
+	define('ZEND_FETCH_GLOBAL_LOCK',      4);
+}
+
+define('ZEND_FETCH_CLASS_DEFAULT',    0);
+define('ZEND_FETCH_CLASS_SELF',       1);
+define('ZEND_FETCH_CLASS_PARENT',     2);
+define('ZEND_FETCH_CLASS_MAIN',       3);
+define('ZEND_FETCH_CLASS_GLOBAL',     4);
+define('ZEND_FETCH_CLASS_AUTO',       5);
+define('ZEND_FETCH_CLASS_INTERFACE',  6);
+define('ZEND_FETCH_CLASS_STATIC',     7);
+if (ZEND_ENGINE_2_4) {
+	define('ZEND_FETCH_CLASS_TRAIT',     14);
+}
+if (ZEND_ENGINE_2_3) {
+	define('ZEND_FETCH_CLASS_MASK',     0xF);
+}
+
+define('ZEND_EVAL',               (1<<0));
+define('ZEND_INCLUDE',            (1<<1));
+define('ZEND_INCLUDE_ONCE',       (1<<2));
+define('ZEND_REQUIRE',            (1<<3));
+define('ZEND_REQUIRE_ONCE',       (1<<4));
+
+define('ZEND_ISSET',              (1<<0));
+define('ZEND_ISEMPTY',            (1<<1));
+if (ZEND_ENGINE_2_4) {
+	define('EXT_TYPE_UNUSED',     (1<<5));
+}
+else {
+	define('EXT_TYPE_UNUSED',     (1<<0));
+}
+
+define('ZEND_FETCH_STANDARD',     0);
+define('ZEND_FETCH_ADD_LOCK',     1);
+
+define('ZEND_FE_FETCH_BYREF',     1);
+define('ZEND_FE_FETCH_WITH_KEY',  2);
+
+define('ZEND_MEMBER_FUNC_CALL',   1<<0);
+define('ZEND_CTOR_CALL',          1<<1);
+
+define('ZEND_ARG_SEND_BY_REF',        (1<<0));
+define('ZEND_ARG_COMPILE_TIME_BOUND', (1<<1));
+define('ZEND_ARG_SEND_FUNCTION',      (1<<2));
+
+define('BYREF_NONE',       0);
+define('BYREF_FORCE',      1);
+define('BYREF_ALLOW',      2);
+define('BYREF_FORCE_REST', 3);
+define('IS_NULL',     0);
+define('IS_LONG',     1);
+define('IS_DOUBLE',   2);
+define('IS_BOOL',     ZEND_ENGINE_2 ? 3 : 6);
+define('IS_ARRAY',    4);
+define('IS_OBJECT',   5);
+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);
+
+/*
+if (preg_match_all('!XC_[A-Z_]+!', file_get_contents(__FILE__), $ms)) {
+	$verdiff = array();
+	foreach ($ms[0] as $k) {
+		if (!defined($k)) {
+			$verdiff[$k] = -1;
+			define($k, -1);
+		}
+	}
+	var_export($verdiff);
+}
+/*/
+foreach (array (
+	'XC_HANDLE_EXCEPTION' => -1,
+	'XC_FETCH_CLASS' => -1,
+	'XC_FETCH_' => -1,
+	'XC_FETCH_DIM_' => -1,
+	'XC_ASSIGN_DIM' => -1,
+	'XC_UNSET_DIM' => -1,
+	'XC_UNSET_OBJ' => -1,
+	'XC_ASSIGN_OBJ' => -1,
+	'XC_ISSET_ISEMPTY_DIM_OBJ' => -1,
+	'XC_ISSET_ISEMPTY_PROP_OBJ' => -1,
+	'XC_ISSET_ISEMPTY_VAR' => -1,
+	'XC_INIT_STATIC_METHOD_CALL' => -1,
+	'XC_INIT_METHOD_CALL' => -1,
+	'XC_VERIFY_ABSTRACT_CLASS' => -1,
+	'XC_DECLARE_CLASS' => -1,
+	'XC_DECLARE_INHERITED_CLASS' => -1,
+	'XC_DECLARE_INHERITED_CLASS_DELAYED' => -1,
+	'XC_ADD_INTERFACE' => -1,
+	'XC_POST_DEC_OBJ' => -1,
+	'XC_POST_INC_OBJ' => -1,
+	'XC_PRE_DEC_OBJ' => -1,
+	'XC_PRE_INC_OBJ' => -1,
+	'XC_UNSET_OBJ' => -1,
+	'XC_JMP_NO_CTOR' => -1,
+	'XC_FETCH_' => -1,
+	'XC_FETCH_DIM_' => -1,
+	'XC_UNSET_DIM_OBJ' => -1,
+	'XC_ISSET_ISEMPTY' => -1,
+	'XC_INIT_FCALL_BY_FUNC' => -1,
+	'XC_DO_FCALL_BY_FUNC' => -1,
+	'XC_DECLARE_FUNCTION_OR_CLASS' => -1,
+	'XC_INIT_NS_FCALL_BY_NAME' => -1,
+	'XC_GOTO' => -1,
+	'XC_CATCH' => -1,
+	'XC_THROW' => -1,
+	'XC_INSTANCEOF' => -1,
+	'XC_DECLARE_FUNCTION' => -1,
+	'XC_RAISE_ABSTRACT_ERROR' => -1,
+	'XC_DECLARE_CONST' => -1,
+	'XC_USER_OPCODE' => -1,
+	'XC_JMP_SET' => -1,
+	'XC_DECLARE_LAMBDA_FUNCTION' => -1,
+) as $k => $v) {
+	if (!defined($k)) {
+		define($k, $v);
+	}
+}
+// }}}
+
Index: unk/lock.c
===================================================================
--- /trunk/lock.c	(revision 981)
+++ 	(revision )
@@ -1,164 +1,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <php.h>
-#ifndef ZEND_WIN32
-typedef int HANDLE;
-#	ifndef INVALID_HANDLE_VALUE
-#		define INVALID_HANDLE_VALUE -1
-#	endif
-#else
-#	define close(h) CloseHandle(h)
-#	define open(filename, mode, permission) CreateFile(filename, \
-		GENERIC_READ | GENERIC_WRITE, \
-		FILE_SHARE_READ | FILE_SHARE_WRITE, \
-		NULL, \
-		OPEN_ALWAYS, \
-		FILE_ATTRIBUTE_NORMAL, \
-		NULL)
-#endif
-#include "lock.h"
-
-struct _xc_lock_t {
-	HANDLE fd;
-	char *pathname;
-};
-
-#ifndef ZEND_WIN32
-#	include <unistd.h>
-#	include <fcntl.h>
-#	include <errno.h>
-#	define LCK_WR F_WRLCK
-#	define LCK_RD F_RDLCK
-#	define LCK_UN F_UNLCK
-#	define LCK_NB 0
-static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
-{ 
-	int ret;
-	struct flock lock;
-
-	lock.l_type = type;
-	lock.l_start = 0;
-	lock.l_whence = SEEK_SET;
-	lock.l_len = 1;
-	lock.l_pid = 0;
-
-	do {
-		ret = fcntl(lck->fd, F_SETLKW, &lock);
-	} while (ret < 0 && errno == EINTR);
-	return ret;
-}
-/* }}} */
-#else
-
-#	include <win32/flock.h>
-#	include <io.h>
-#	include <fcntl.h>
-#	include <sys/types.h>
-#	include <sys/stat.h>
-#	undef errno
-#	define errno GetLastError()
-#	define getuid() 0
-#	define LCK_WR LOCKFILE_EXCLUSIVE_LOCK
-#	define LCK_RD 0
-#	define LCK_UN 0
-#	define LCK_NB LOCKFILE_FAIL_IMMEDIATELY
-static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
-{ 
-	static OVERLAPPED offset = {0, 0, 0, 0, NULL};
-
-	if (type == LCK_UN) {
-		return UnlockFileEx((HANDLE)lck->fd, 0, 1, 0, &offset);
-	}
-	else {
-		return LockFileEx((HANDLE)lck->fd, type, 0, 1, 0, &offset);
-	}
-}
-/* }}} */
-#endif
-
-xc_lock_t *xc_fcntl_init(const char *pathname) /* {{{ */
-{
-	HANDLE fd;
-	xc_lock_t *lck;
-	int size;
-	char *myname;
-
-	if (pathname == NULL) {
-		static int i = 0;
-		const char default_tmpdir[] = { DEFAULT_SLASH, 't', 'm', 'p', '\0' };
-		const char *tmpdir;
-
-		tmpdir = getenv("TEMP");
-		if (!tmpdir) {
-			tmpdir = getenv("TMP");
-			if (!tmpdir) {
-				tmpdir = default_tmpdir;
-			}
-		}
-		size = strlen(tmpdir) + sizeof("/.xcache.lock") - 1 + 3 * 10 + 100;
-		myname = malloc(size);
-		snprintf(myname, size - 1, "%s%c.xcache.%d.%d.%d.lock", tmpdir, DEFAULT_SLASH, (int) getuid(), i ++, rand());
-		pathname = myname;
-	}
-	else {
-		myname = NULL;
-	}
-
-	fd = open(pathname, O_RDWR|O_CREAT, 0666);
-
-	if (fd != INVALID_HANDLE_VALUE) {
-		lck = malloc(sizeof(lck[0]));
-
-#ifndef __CYGWIN__
-		unlink(pathname);
-#endif
-		lck->fd = fd;
-		size = strlen(pathname) + 1;
-		lck->pathname = malloc(size);
-		memcpy(lck->pathname, pathname, size);
-	}
-	else {
-		zend_error(E_ERROR, "xc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
-		lck = NULL;
-	}
-
-	if (myname) {
-		free(myname);
-	}
-
-	return lck;
-}
-/* }}} */
-void xc_fcntl_destroy(xc_lock_t *lck) /* {{{ */
-{   
-	close(lck->fd);
-#ifdef __CYGWIN__
-	unlink(lck->pathname);
-#endif
-	free(lck->pathname);
-	free(lck);
-}
-/* }}} */
-void xc_fcntl_lock(xc_lock_t *lck) /* {{{ */
-{   
-	if (dolock(lck, LCK_WR) < 0) {
-		zend_error(E_ERROR, "xc_fcntl_lock failed errno:%d", errno);
-	}
-}
-/* }}} */
-void xc_fcntl_rdlock(xc_lock_t *lck) /* {{{ */
-{   
-	if (dolock(lck, LCK_RD) < 0) {
-		zend_error(E_ERROR, "xc_fcntl_lock failed errno:%d", errno);
-	}
-}
-/* }}} */
-void xc_fcntl_unlock(xc_lock_t *lck) /* {{{ */
-{   
-	if (dolock(lck, LCK_UN) < 0) {
-		zend_error(E_ERROR, "xc_fcntl_unlock failed errno:%d", errno);
-	}
-}
-/* }}} */
Index: unk/lock.h
===================================================================
--- /trunk/lock.h	(revision 981)
+++ 	(revision )
@@ -1,11 +1,0 @@
-typedef struct _xc_lock_t xc_lock_t;
-
-xc_lock_t *xc_fcntl_init(const char *pathname);
-void xc_fcntl_destroy(xc_lock_t *lck);
-void xc_fcntl_lock(xc_lock_t *lck);
-void xc_fcntl_unlock(xc_lock_t *lck);
-
-#define xc_lock_init(name)  xc_fcntl_init(name)
-#define xc_lock_destroy(fd) xc_fcntl_destroy(fd)
-#define xc_lock(fd)         xc_fcntl_lock(fd)
-#define xc_unlock(fd)       xc_fcntl_unlock(fd)
Index: /trunk/main/README
===================================================================
--- /trunk/main/README	(revision 982)
+++ /trunk/main/README	(revision 982)
@@ -0,0 +1,1 @@
+understructure
Index: /trunk/main/xc_const_string.c
===================================================================
--- /trunk/main/xc_const_string.c	(revision 982)
+++ /trunk/main/xc_const_string.c	(revision 982)
@@ -0,0 +1,86 @@
+#include "xcache.h"
+#include "xc_const_string.h"
+
+/* {{{ xc_get_op_type */
+static const char *const op_type_names[] = {
+	/* 0 */ "NULL?",
+	/* 1 */ "IS_CONST",
+	/* 2 */ "IS_TMP_VAR",
+	/* 3 */ NULL,
+	/* 4 */ "IS_VAR",
+	/* 5 */ NULL,
+	/* 6 */ NULL,
+	/* 7 */ NULL,
+	/* 8 */ "IS_UNUSED",
+#ifdef IS_CV
+	/* 9  */ NULL,
+	/* 10 */ NULL,
+	/* 11 */ NULL,
+	/* 12 */ NULL,
+	/* 13 */ NULL,
+	/* 14 */ NULL,
+	/* 15 */ NULL,
+	/* 16 */ "IS_CV"
+#endif
+};
+
+zend_uchar xc_get_op_type_count()
+{
+	return sizeof(op_type_names) / sizeof(op_type_names[0]);
+}
+
+const char *xc_get_op_type(zend_uchar op_type)
+{
+	assert(op_type < xc_get_op_type_count());
+	return op_type_names[op_type];
+}
+/* }}} */
+/* {{{ xc_get_data_type */
+static const char *const data_type_names[] = {
+	/* 0 */ "IS_NULL",
+	/* 1 */ "IS_LONG",
+	/* 2 */ "IS_DOUBLE",
+	/* 3 */ "IS_BOOL",
+	/* 4 */ "IS_ARRAY",
+	/* 5 */ "IS_OBJECT",
+	/* 6 */ "IS_STRING",
+	/* 7 */ "IS_RESOURCE",
+	/* 8 */ "IS_CONSTANT",
+	/* 9 */ "IS_CONSTANT_ARRAY",
+	/* 10 */ "IS_UNICODE"
+};
+
+zend_uchar xc_get_data_type_count()
+{
+	return sizeof(data_type_names) / sizeof(data_type_names[0]);
+}
+
+const char *xc_get_data_type(zend_uchar data_type)
+{
+	return data_type_names[(data_type & IS_CONSTANT_TYPE_MASK)];
+}
+/* }}} */
+/* {{{ xc_get_opcode */
+#if PHP_MAJOR_VERSION >= 6
+#	include "xc_const_string_opcodes_php6.x.h"
+#elif defined(ZEND_ENGINE_2_4)
+#	include "xc_const_string_opcodes_php5.4.h"
+#elif defined(ZEND_ENGINE_2_1)
+#	include "xc_const_string_opcodes_php5.1.h"
+#elif defined(ZEND_ENGINE_2)
+#	include "xc_const_string_opcodes_php5.0.h"
+#else
+#	include "xc_const_string_opcodes_php4.x.h"
+#endif
+
+zend_uchar xc_get_opcode_count()
+{
+	return sizeof(xc_opcode_names) / sizeof(xc_opcode_names[0]);
+}
+
+const char *xc_get_opcode(zend_uchar opcode)
+{
+	assert(opcode < xc_get_opcode_count());
+	return xc_opcode_names[opcode];
+}
+/* }}} */
Index: /trunk/main/xc_const_string.h
===================================================================
--- /trunk/main/xc_const_string.h	(revision 982)
+++ /trunk/main/xc_const_string.h	(revision 982)
@@ -0,0 +1,8 @@
+#include "php.h"
+
+zend_uchar xc_get_op_type_count();
+const char *xc_get_op_type(zend_uchar op_type);
+zend_uchar xc_get_data_type_count();
+const char *xc_get_data_type(zend_uchar data_type);
+zend_uchar xc_get_opcode_count();
+const char *xc_get_opcode(zend_uchar opcode);
Index: /trunk/main/xc_const_string_opcodes_php4.x.h
===================================================================
--- /trunk/main/xc_const_string_opcodes_php4.x.h	(revision 982)
+++ /trunk/main/xc_const_string_opcodes_php4.x.h	(revision 982)
@@ -0,0 +1,116 @@
+/* size = 113 */
+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 */	"JMP_NO_CTOR",
+/* 70 */	"FREE",
+/* 71 */	"INIT_ARRAY",
+/* 72 */	"ADD_ARRAY_ELEMENT",
+/* 73 */	"INCLUDE_OR_EVAL",
+/* 74 */	"UNSET_VAR",
+/* 75 */	"UNSET_DIM_OBJ",
+/* 76 */	"ISSET_ISEMPTY",
+/* 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 */	"DECLARE_FUNCTION_OR_CLASS",
+/* 101 */	"EXT_STMT",
+/* 102 */	"EXT_FCALL_BEGIN",
+/* 103 */	"EXT_FCALL_END",
+/* 104 */	"EXT_NOP",
+/* 105 */	"TICKS",
+/* 106 */	"SEND_VAR_NO_REF",
+/* 107 */	"UNDEF",
+/* 108 */	"UNDEF",
+/* 109 */	"UNDEF",
+/* 110 */	"DO_FCALL_BY_FUNC",
+/* 111 */	"INIT_FCALL_BY_FUNC",
+/* 112 */	"UNDEF"
+};
Index: /trunk/main/xc_const_string_opcodes_php5.0.h
===================================================================
--- /trunk/main/xc_const_string_opcodes_php5.0.h	(revision 982)
+++ /trunk/main/xc_const_string_opcodes_php5.0.h	(revision 982)
@@ -0,0 +1,153 @@
+/* size = 149 */
+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 */	"JMP_NO_CTOR",
+/* 70 */	"FREE",
+/* 71 */	"INIT_ARRAY",
+/* 72 */	"ADD_ARRAY_ELEMENT",
+/* 73 */	"INCLUDE_OR_EVAL",
+/* 74 */	"UNSET_VAR",
+/* 75 */	"UNSET_DIM_OBJ",
+/* 76 */	"UNDEF",
+/* 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 */	"UNDEF",
+/* 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 */	"INIT_CTOR_CALL",
+/* 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 */	"UNDEF",
+/* 144 */	"ADD_INTERFACE",
+/* 145 */	"UNDEF",
+/* 146 */	"VERIFY_ABSTRACT_CLASS",
+/* 147 */	"ASSIGN_DIM",
+/* 148 */	"ISSET_ISEMPTY_PROP_OBJ",
+/* 149 */	"HANDLE_EXCEPTION"
+};
Index: /trunk/main/xc_const_string_opcodes_php5.1.h
===================================================================
--- /trunk/main/xc_const_string_opcodes_php5.1.h	(revision 982)
+++ /trunk/main/xc_const_string_opcodes_php5.1.h	(revision 982)
@@ -0,0 +1,157 @@
+/* size = 154 */
+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 */	"UNDEF",
+/* 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"
+};
Index: /trunk/main/xc_const_string_opcodes_php5.4.h
===================================================================
--- /trunk/main/xc_const_string_opcodes_php5.4.h	(revision 982)
+++ /trunk/main/xc_const_string_opcodes_php5.4.h	(revision 982)
@@ -0,0 +1,162 @@
+/* size = 159 */
+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"
+};
Index: /trunk/main/xc_const_string_opcodes_php6.x.h
===================================================================
--- /trunk/main/xc_const_string_opcodes_php6.x.h	(revision 982)
+++ /trunk/main/xc_const_string_opcodes_php6.x.h	(revision 982)
@@ -0,0 +1,162 @@
+/* size = 159 */
+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"
+};
Index: /trunk/main/xc_lock.c
===================================================================
--- /trunk/main/xc_lock.c	(revision 982)
+++ /trunk/main/xc_lock.c	(revision 982)
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <php.h>
+#ifndef ZEND_WIN32
+typedef int HANDLE;
+#	ifndef INVALID_HANDLE_VALUE
+#		define INVALID_HANDLE_VALUE -1
+#	endif
+#else
+#	define close(h) CloseHandle(h)
+#	define open(filename, mode, permission) CreateFile(filename, \
+		GENERIC_READ | GENERIC_WRITE, \
+		FILE_SHARE_READ | FILE_SHARE_WRITE, \
+		NULL, \
+		OPEN_ALWAYS, \
+		FILE_ATTRIBUTE_NORMAL, \
+		NULL)
+#endif
+#include "xc_lock.h"
+
+struct _xc_lock_t {
+	HANDLE fd;
+	char *pathname;
+};
+
+#ifndef ZEND_WIN32
+#	include <unistd.h>
+#	include <fcntl.h>
+#	include <errno.h>
+#	define LCK_WR F_WRLCK
+#	define LCK_RD F_RDLCK
+#	define LCK_UN F_UNLCK
+#	define LCK_NB 0
+static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
+{ 
+	int ret;
+	struct flock lock;
+
+	lock.l_type = type;
+	lock.l_start = 0;
+	lock.l_whence = SEEK_SET;
+	lock.l_len = 1;
+	lock.l_pid = 0;
+
+	do {
+		ret = fcntl(lck->fd, F_SETLKW, &lock);
+	} while (ret < 0 && errno == EINTR);
+	return ret;
+}
+/* }}} */
+#else
+
+#	include <win32/flock.h>
+#	include <io.h>
+#	include <fcntl.h>
+#	include <sys/types.h>
+#	include <sys/stat.h>
+#	undef errno
+#	define errno GetLastError()
+#	define getuid() 0
+#	define LCK_WR LOCKFILE_EXCLUSIVE_LOCK
+#	define LCK_RD 0
+#	define LCK_UN 0
+#	define LCK_NB LOCKFILE_FAIL_IMMEDIATELY
+static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
+{ 
+	static OVERLAPPED offset = {0, 0, 0, 0, NULL};
+
+	if (type == LCK_UN) {
+		return UnlockFileEx((HANDLE)lck->fd, 0, 1, 0, &offset);
+	}
+	else {
+		return LockFileEx((HANDLE)lck->fd, type, 0, 1, 0, &offset);
+	}
+}
+/* }}} */
+#endif
+
+xc_lock_t *xc_fcntl_init(const char *pathname) /* {{{ */
+{
+	HANDLE fd;
+	xc_lock_t *lck;
+	int size;
+	char *myname;
+
+	if (pathname == NULL) {
+		static int i = 0;
+		const char default_tmpdir[] = { DEFAULT_SLASH, 't', 'm', 'p', '\0' };
+		const char *tmpdir;
+
+		tmpdir = getenv("TEMP");
+		if (!tmpdir) {
+			tmpdir = getenv("TMP");
+			if (!tmpdir) {
+				tmpdir = default_tmpdir;
+			}
+		}
+		size = strlen(tmpdir) + sizeof("/.xcache.lock") - 1 + 3 * 10 + 100;
+		myname = malloc(size);
+		snprintf(myname, size - 1, "%s%c.xcache.%d.%d.%d.lock", tmpdir, DEFAULT_SLASH, (int) getuid(), i ++, rand());
+		pathname = myname;
+	}
+	else {
+		myname = NULL;
+	}
+
+	fd = open(pathname, O_RDWR|O_CREAT, 0666);
+
+	if (fd != INVALID_HANDLE_VALUE) {
+		lck = malloc(sizeof(lck[0]));
+
+#ifndef __CYGWIN__
+		unlink(pathname);
+#endif
+		lck->fd = fd;
+		size = strlen(pathname) + 1;
+		lck->pathname = malloc(size);
+		memcpy(lck->pathname, pathname, size);
+	}
+	else {
+		zend_error(E_ERROR, "xc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
+		lck = NULL;
+	}
+
+	if (myname) {
+		free(myname);
+	}
+
+	return lck;
+}
+/* }}} */
+void xc_fcntl_destroy(xc_lock_t *lck) /* {{{ */
+{   
+	close(lck->fd);
+#ifdef __CYGWIN__
+	unlink(lck->pathname);
+#endif
+	free(lck->pathname);
+	free(lck);
+}
+/* }}} */
+void xc_fcntl_lock(xc_lock_t *lck) /* {{{ */
+{   
+	if (dolock(lck, LCK_WR) < 0) {
+		zend_error(E_ERROR, "xc_fcntl_lock failed errno:%d", errno);
+	}
+}
+/* }}} */
+void xc_fcntl_rdlock(xc_lock_t *lck) /* {{{ */
+{   
+	if (dolock(lck, LCK_RD) < 0) {
+		zend_error(E_ERROR, "xc_fcntl_lock failed errno:%d", errno);
+	}
+}
+/* }}} */
+void xc_fcntl_unlock(xc_lock_t *lck) /* {{{ */
+{   
+	if (dolock(lck, LCK_UN) < 0) {
+		zend_error(E_ERROR, "xc_fcntl_unlock failed errno:%d", errno);
+	}
+}
+/* }}} */
Index: /trunk/main/xc_lock.h
===================================================================
--- /trunk/main/xc_lock.h	(revision 982)
+++ /trunk/main/xc_lock.h	(revision 982)
@@ -0,0 +1,11 @@
+typedef struct _xc_lock_t xc_lock_t;
+
+xc_lock_t *xc_fcntl_init(const char *pathname);
+void xc_fcntl_destroy(xc_lock_t *lck);
+void xc_fcntl_lock(xc_lock_t *lck);
+void xc_fcntl_unlock(xc_lock_t *lck);
+
+#define xc_lock_init(name)  xc_fcntl_init(name)
+#define xc_lock_destroy(fd) xc_fcntl_destroy(fd)
+#define xc_lock(fd)         xc_fcntl_lock(fd)
+#define xc_unlock(fd)       xc_fcntl_unlock(fd)
Index: /trunk/main/xc_malloc.c
===================================================================
--- /trunk/main/xc_malloc.c	(revision 982)
+++ /trunk/main/xc_malloc.c	(revision 982)
@@ -0,0 +1,250 @@
+#define XC_SHM_IMPL _xc_malloc_shm_t
+#define XC_MEM_IMPL _xc_malloc_mem_t
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xc_shm.h"
+#include "php.h"
+#include "xc_utils.h"
+#include "util/xc_align.h"
+
+struct _xc_malloc_mem_t {
+	const xc_mem_handlers_t *handlers;
+	xc_shm_t                *shm;
+	xc_memsize_t size;
+	xc_memsize_t avail;       /* total free */
+};
+
+/* {{{ _xc_malloc_shm_t */
+struct _xc_malloc_shm_t {
+	xc_shm_handlers_t *handlers;
+	xc_shmsize_t       size;
+	xc_shmsize_t       memoffset;
+#ifdef HAVE_XCACHE_TEST
+	HashTable blocks;
+#endif
+};
+/* }}} */
+
+#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
+
+static void *xc_add_to_blocks(xc_mem_t *mem, void *p, size_t size) /* {{{ */
+{
+#ifdef HAVE_XCACHE_TEST
+	if (p) {
+		zend_hash_add(&mem->shm->blocks, (void *) &p, sizeof(p), (void *) &size, sizeof(size), NULL);
+	}
+#endif
+	return p;
+}
+/* }}} */
+static void xc_del_from_blocks(xc_mem_t *mem, void *p) /* {{{ */
+{
+#ifdef HAVE_XCACHE_TEST
+	zend_hash_del(&mem->shm->blocks, (void *) &p, sizeof(p));
+#endif
+}
+/* }}} */
+
+static XC_MEM_MALLOC(xc_malloc_malloc) /* {{{ */
+{
+	return xc_add_to_blocks(mem, malloc(size), size);
+}
+/* }}} */
+static XC_MEM_FREE(xc_malloc_free) /* {{{ return block size freed */
+{
+	xc_del_from_blocks(mem, (void *) p);
+	free((void *) p);
+	return 0;
+}
+/* }}} */
+static XC_MEM_CALLOC(xc_malloc_calloc) /* {{{ */
+{
+	return xc_add_to_blocks(mem, calloc(memb, size), size);
+}
+/* }}} */
+static XC_MEM_REALLOC(xc_malloc_realloc) /* {{{ */
+{
+	return xc_add_to_blocks(mem, realloc((void *) p, size), size);
+}
+/* }}} */
+static XC_MEM_STRNDUP(xc_malloc_strndup) /* {{{ */
+{
+	char *p = xc_add_to_blocks(mem, malloc(len), len);
+	if (!p) {
+		return NULL;
+	}
+	return memcpy(p, str, len);
+}
+/* }}} */
+static XC_MEM_STRDUP(xc_malloc_strdup) /* {{{ */
+{
+	return xc_malloc_strndup(mem, str, strlen(str) + 1);
+}
+/* }}} */
+
+static XC_MEM_AVAIL(xc_malloc_avail) /* {{{ */
+{
+	return mem->avail;
+}
+/* }}} */
+static XC_MEM_SIZE(xc_malloc_size) /* {{{ */
+{
+	return mem->size;
+}
+/* }}} */
+
+static XC_MEM_FREEBLOCK_FIRST(xc_malloc_freeblock_first) /* {{{ */
+{
+	return (void *) -1;
+}
+/* }}} */
+XC_MEM_FREEBLOCK_NEXT(xc_malloc_freeblock_next) /* {{{ */
+{
+	return NULL;
+}
+/* }}} */
+XC_MEM_BLOCK_SIZE(xc_malloc_block_size) /* {{{ */
+{
+	return 0;
+}
+/* }}} */
+XC_MEM_BLOCK_OFFSET(xc_malloc_block_offset) /* {{{ */
+{
+	return 0;
+}
+/* }}} */
+
+static XC_MEM_INIT(xc_mem_malloc_init) /* {{{ */
+{
+#define MINSIZE (ALIGN(sizeof(xc_mem_t)))
+	/* requires at least the header and 1 tail block */
+	if (size < MINSIZE) {
+		fprintf(stderr, "xc_mem_malloc_init requires %lu bytes at least\n", (unsigned long) MINSIZE);
+		return NULL;
+	}
+	mem->shm = shm;
+	mem->size = size;
+	mem->avail = size - MINSIZE;
+#undef MINSIZE
+
+	return mem;
+}
+/* }}} */
+static XC_MEM_DESTROY(xc_mem_malloc_destroy) /* {{{ */
+{
+}
+/* }}} */
+
+static XC_SHM_CAN_READONLY(xc_malloc_can_readonly) /* {{{ */
+{
+	return 0;
+}
+/* }}} */
+static XC_SHM_IS_READWRITE(xc_malloc_is_readwrite) /* {{{ */
+{
+#ifdef HAVE_XCACHE_TEST
+	HashPosition pos;
+	size_t *psize;
+	char **ptr;
+
+	zend_hash_internal_pointer_reset_ex(&shm->blocks, &pos);
+	while (zend_hash_get_current_data_ex(&shm->blocks, (void **) &psize, &pos) == SUCCESS) {
+		zend_hash_get_current_key_ex(&shm->blocks, (void *) &ptr, NULL, NULL, 0, &pos);
+		if ((char *) p >= *ptr && (char *) p < *ptr + *psize) {
+			return 1;
+		}
+		zend_hash_move_forward_ex(&shm->blocks, &pos);
+	}
+#endif
+
+	return 0;
+}
+/* }}} */
+static XC_SHM_IS_READONLY(xc_malloc_is_readonly) /* {{{ */
+{
+	return 0;
+}
+/* }}} */
+static XC_SHM_TO_READWRITE(xc_malloc_to_readwrite) /* {{{ */
+{
+	return p;
+}
+/* }}} */
+static XC_SHM_TO_READONLY(xc_malloc_to_readonly) /* {{{ */
+{
+	return p;
+}
+/* }}} */
+
+static XC_SHM_DESTROY(xc_malloc_destroy) /* {{{ */
+{
+#ifdef HAVE_XCACHE_TEST
+	zend_hash_destroy(&shm->blocks);
+#endif
+	free(shm);
+	return;
+}
+/* }}} */
+static XC_SHM_INIT(xc_malloc_init) /* {{{ */
+{
+	xc_shm_t *shm;
+	CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM");
+	shm->size = size;
+
+#ifdef HAVE_XCACHE_TEST
+	zend_hash_init(&shm->blocks, 64, NULL, NULL, 1);
+#endif
+	return shm;
+err:
+	return NULL;
+}
+/* }}} */
+
+static XC_SHM_MEMINIT(xc_malloc_meminit) /* {{{ */
+{
+	xc_mem_t *mem;
+	if (shm->memoffset + size > shm->size) {
+		zend_error(E_ERROR, "XCache: internal error at %s#%d", __FILE__, __LINE__);
+		return NULL;
+	}
+	shm->memoffset += size;
+	CHECK(mem = calloc(1, sizeof(xc_mem_t)), "mem OOM");
+	mem->handlers = shm->handlers->memhandlers;
+	mem->handlers->init(shm, mem, size);
+	return mem;
+err:
+	return NULL;
+}
+/* }}} */
+static XC_SHM_MEMDESTROY(xc_malloc_memdestroy) /* {{{ */
+{
+	mem->handlers->destroy(mem);
+	free(mem);
+}
+/* }}} */
+
+#define xc_malloc_destroy xc_mem_malloc_destroy
+#define xc_malloc_init xc_mem_malloc_init
+static xc_mem_handlers_t xc_mem_malloc_handlers = XC_MEM_HANDLERS(malloc);
+#undef xc_malloc_init
+#undef xc_malloc_destroy
+static xc_shm_handlers_t xc_shm_malloc_handlers = XC_SHM_HANDLERS(malloc);
+void xc_shm_malloc_register() /* {{{ */
+{
+	if (xc_mem_scheme_register("malloc", &xc_mem_malloc_handlers) == 0) {
+		zend_error(E_ERROR, "XCache: failed to register malloc mem_scheme");
+	}
+
+	CHECK(xc_shm_malloc_handlers.memhandlers = xc_mem_scheme_find("malloc"), "cannot find malloc handlers");
+	if (xc_shm_scheme_register("malloc", &xc_shm_malloc_handlers) == 0) {
+		zend_error(E_ERROR, "XCache: failed to register malloc shm_scheme");
+	}
+err:
+	return;
+}
+/* }}} */
Index: /trunk/main/xc_mem.c
===================================================================
--- /trunk/main/xc_mem.c	(revision 982)
+++ /trunk/main/xc_mem.c	(revision 982)
@@ -0,0 +1,407 @@
+#ifdef TEST
+#include <limits.h>
+#include <stdio.h>
+#	define XCACHE_DEBUG
+#else
+#include <php.h>
+#endif
+
+#ifdef XCACHE_DEBUG
+#	define ALLOC_DEBUG_BLOCK_CHECK
+#endif
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#define XC_MEMBLOCK_IMPL _xc_mem_block_t
+#define XC_MEM_IMPL _xc_mem_mem_t
+#include "xc_shm.h"
+#include "xc_utils.h"
+#include "util/xc_align.h"
+#include "util/xc_trace.h"
+
+#if 0
+#undef ALLOC_DEBUG_BLOCK_CHECK
+#endif
+
+#define CHAR_PTR(p) ((char *) (p))
+#define PADD(p, a) (CHAR_PTR(p) + a)
+#define PSUB(p1, p2) (CHAR_PTR(p1) - CHAR_PTR(p2))
+
+/* {{{ mem */
+struct _xc_mem_block_t {
+#ifdef ALLOC_DEBUG_BLOCK_CHECK
+	unsigned int magic;
+#endif
+	xc_memsize_t size; /* reserved even after alloc */
+	xc_block_t *next;  /* not used after alloc */
+};
+
+struct _xc_mem_mem_t {
+	const xc_mem_handlers_t *handlers;
+	xc_shm_t                *shm;
+	xc_memsize_t size;
+	xc_memsize_t avail;       /* total free */
+	xc_block_t headblock[1];  /* just as a pointer to first block*/
+};
+
+#ifndef XtOffsetOf
+#	include <linux/stddef.h>
+#	define XtOffsetOf(s_type, field) offsetof(s_type, field)
+#endif
+
+#define SizeOf(type, field) sizeof( ((type *) 0)->field )
+#define BLOCK_HEADER_SIZE() (ALIGN( XtOffsetOf(xc_block_t, size) + SizeOf(xc_block_t, size) ))
+
+#define BLOCK_MAGIC ((unsigned int) 0x87655678)
+
+/* }}} */
+static inline void xc_block_setup(xc_block_t *b, xc_memsize_t size, xc_block_t *next) /* {{{ */
+{
+#ifdef ALLOC_DEBUG_BLOCK_CHECK
+	b->magic = BLOCK_MAGIC;
+#endif
+	b->size = size;
+	b->next = next;
+}
+/* }}} */
+#ifdef ALLOC_DEBUG_BLOCK_CHECK
+static void xc_block_check(xc_block_t *b) /* {{{ */
+{
+	if (b->magic != BLOCK_MAGIC) {
+		fprintf(stderr, "0x%X != 0x%X magic wrong \n", b->magic, BLOCK_MAGIC);
+	}
+}
+/* }}} */
+#else
+#	define xc_block_check(b) do { } while(0)
+#endif
+
+
+static XC_MEM_MALLOC(xc_mem_malloc) /* {{{ */
+{
+	xc_block_t *prev, *cur;
+	xc_block_t *newb, *b;
+	xc_memsize_t realsize;
+	xc_memsize_t minsize;
+	void *p;
+	/* [xc_block_t:size|size] */
+	realsize = BLOCK_HEADER_SIZE() + size;
+	/* realsize is ALIGNed so next block start at ALIGNed address */
+	realsize = ALIGN(realsize);
+
+	TRACE("avail: %lu (%luKB). Allocate size: %lu realsize: %lu (%luKB)"
+			, mem->avail, mem->avail / 1024
+			, size
+			, realsize, realsize / 1024
+			);
+	do {
+		p = NULL;
+		if (mem->avail < realsize) {
+			TRACE("%s", " oom");
+			break;
+		}
+
+		b = NULL;
+		minsize = ULONG_MAX;
+
+		/* prev|cur */
+
+		for (prev = mem->headblock; prev->next; prev = cur) {
+			/* while (prev->next != 0) { */
+			cur = prev->next;
+			xc_block_check(cur);
+			if (cur->size == realsize) {
+				/* found a perfect fit, stop searching */
+				b = prev;
+				break;
+			}
+			/* make sure we can split on the block */
+			else if (cur->size > (sizeof(xc_block_t) + realsize) &&
+					cur->size < minsize) {
+				/* cur is acceptable and memller */
+				b = prev;
+				minsize = cur->size;
+			}
+			prev = cur;
+		}
+
+		if (b == NULL) {
+			TRACE("%s", " no fit chunk");
+			break;
+		}
+
+		prev = b;
+
+		cur = prev->next;
+		p = PADD(cur, BLOCK_HEADER_SIZE());
+
+		/* update the block header */
+		mem->avail -= realsize;
+
+		/* perfect fit, just unlink */
+		if (cur->size == realsize) {
+			prev->next = cur->next;
+			TRACE(" perfect fit. Got: %p", p);
+			break;
+		}
+
+		/* make new free block after alloced space */
+
+		/* save, as it might be overwrited by newb (cur->size is ok) */
+		b = cur->next;
+
+		/* prev|cur     |next=b */
+
+		newb = (xc_block_t *)PADD(cur, realsize);
+		xc_block_setup(newb, cur->size - realsize, b);
+		cur->size = realsize;
+		/* prev|cur|newb|next
+		 *            `--^
+		 */
+
+		TRACE(" -> avail: %lu (%luKB). new next: %p offset: %lu %luKB. Got: %p"
+				, mem->avail, mem->avail / 1024
+				, newb
+				, PSUB(newb, mem), PSUB(newb, mem) / 1024
+				, p
+				);
+		prev->next = newb;
+		/* prev|cur|newb|next
+		 *    `-----^
+		 */
+
+	} while (0);
+
+	return p;
+}
+/* }}} */
+static XC_MEM_FREE(xc_mem_free) /* {{{ return block size freed */
+{
+	xc_block_t *cur, *b;
+	int size;
+
+	cur = (xc_block_t *) (CHAR_PTR(p) - BLOCK_HEADER_SIZE());
+	TRACE("freeing: %p, size=%lu", p, cur->size);
+	xc_block_check(cur);
+	assert((char*)mem < (char*)cur && (char*)cur < (char*)mem + mem->size);
+
+	/* find free block right before the p */
+	b = mem->headblock;
+	while (b->next != 0 && b->next < cur) {
+		b = b->next;
+	}
+
+	/* restore block */
+	cur->next = b->next;
+	b->next = cur;
+	size = cur->size;
+
+	TRACE(" avail %lu (%luKB)", mem->avail, mem->avail / 1024);
+	mem->avail += size;
+
+	/* combine prev|cur */
+	if (PADD(b, b->size) == (char *)cur) {
+		b->size += cur->size;
+		b->next = cur->next;
+		cur = b;
+		TRACE("%s", " combine prev");
+	}
+
+	/* combine cur|next */
+	b = cur->next;
+	if (PADD(cur, cur->size) == (char *)b) {
+		cur->size += b->size;
+		cur->next = b->next;
+		TRACE("%s", " combine next");
+	}
+	TRACE(" -> avail %lu (%luKB)", mem->avail, mem->avail / 1024);
+	return size;
+}
+/* }}} */
+static XC_MEM_CALLOC(xc_mem_calloc) /* {{{ */
+{
+	xc_memsize_t realsize = memb * size;
+	void *p = xc_mem_malloc(mem, realsize);
+
+	if (p) {
+		memset(p, 0, realsize);
+	}
+	return p;
+}
+/* }}} */
+static XC_MEM_REALLOC(xc_mem_realloc) /* {{{ */
+{
+	void *newp = xc_mem_malloc(mem, size);
+	if (p && newp) {
+		memcpy(newp, p, size);
+		xc_mem_free(mem, p);
+	}
+	return newp;
+}
+/* }}} */
+static XC_MEM_STRNDUP(xc_mem_strndup) /* {{{ */
+{
+	void *p = xc_mem_malloc(mem, len + 1);
+	if (p) {
+		memcpy(p, str, len + 1);
+	}
+	return p;
+}
+/* }}} */
+static XC_MEM_STRDUP(xc_mem_strdup) /* {{{ */
+{
+	return xc_mem_strndup(mem, str, strlen(str));
+}
+/* }}} */
+
+static XC_MEM_AVAIL(xc_mem_avail) /* {{{ */
+{
+	return mem->avail;
+}
+/* }}} */
+static XC_MEM_SIZE(xc_mem_size) /* {{{ */
+{
+	return mem->size;
+}
+/* }}} */
+
+static XC_MEM_FREEBLOCK_FIRST(xc_mem_freeblock_first) /* {{{ */
+{
+	return mem->headblock->next;
+}
+/* }}} */
+XC_MEM_FREEBLOCK_NEXT(xc_mem_freeblock_next) /* {{{ */
+{
+	return block->next;
+}
+/* }}} */
+XC_MEM_BLOCK_SIZE(xc_mem_block_size) /* {{{ */
+{
+	return block->size;
+}
+/* }}} */
+XC_MEM_BLOCK_OFFSET(xc_mem_block_offset) /* {{{ */
+{
+	return ((char *) block) - ((char *) mem);
+}
+/* }}} */
+
+static XC_MEM_INIT(xc_mem_init) /* {{{ */
+{
+	xc_block_t *b;
+#define MINSIZE (ALIGN(sizeof(xc_mem_t)) + sizeof(xc_block_t))
+	/* requires at least the header and 1 tail block */
+	if (size < MINSIZE) {
+		fprintf(stderr, "xc_mem_init requires %lu bytes at least\n", (unsigned long) MINSIZE);
+		return NULL;
+	}
+	TRACE("size=%lu", size);
+	mem->shm = shm;
+	mem->size = size;
+	mem->avail = size - MINSIZE;
+
+	/* pointer to first block, right after ALIGNed header */
+	b = mem->headblock;
+	xc_block_setup(b, 0, (xc_block_t *) PADD(mem, ALIGN(sizeof(xc_mem_t))));
+
+	/* first block*/
+	b = b->next;
+	xc_block_setup(b, mem->avail, 0);
+#undef MINSIZE
+
+	return mem;
+}
+/* }}} */
+static XC_MEM_DESTROY(xc_mem_destroy) /* {{{ */
+{
+}
+/* }}} */
+
+#ifdef TEST
+/* {{{ */
+#undef CHECK
+#define CHECK(a, msg) do { if ((a) == NULL) { puts(msg); return -1; } } while (0)
+#include <time.h>
+
+int main()
+{
+	int count = 0;
+	void *p;
+	void *memory;
+	xc_mem_t *mem;
+	void **ptrs;
+	int size, i;
+
+#if 0
+	fprintf(stderr, "%s", "Input test size: ");
+	scanf("%d", &size);
+#else
+	size = 100;
+#endif
+	CHECK(memory = malloc(size), "OOM");
+	CHECK(ptrs   = malloc(size * sizeof(void*)), "OOM");
+	CHECK(mem    = xc_mem_init(memory, size), "Failed init memory allocator");
+
+	while ((p = xc_mem_malloc(mem, 1))) {
+		ptrs[count ++] = p;
+	}
+	fprintf(stderr, "count=%d, random freeing\n", count);
+	srandom(time(NULL));
+	while (count) {
+		i = (random() % count);
+		fprintf(stderr, "freeing %d: ", i);
+		xc_mem_free(mem, ptrs[i]);
+		ptrs[i] = ptrs[count - 1];
+		count --;
+	}
+
+	free(ptrs);
+	free(memory);
+	return 0;
+}
+/* }}} */
+#endif
+
+typedef struct {
+	const char              *name;
+	const xc_mem_handlers_t *handlers;
+} xc_mem_scheme_t;
+static xc_mem_scheme_t xc_mem_schemes[10];
+
+int xc_mem_scheme_register(const char *name, const xc_mem_handlers_t *handlers) /* {{{ */
+{
+	int i;
+	for (i = 0; i < 10; i ++) {
+		if (!xc_mem_schemes[i].name) {
+			xc_mem_schemes[i].name = name;
+			xc_mem_schemes[i].handlers = handlers;
+			return 1;
+		}
+	}
+	return 0;
+}
+/* }}} */
+const xc_mem_handlers_t *xc_mem_scheme_find(const char *name) /* {{{ */
+{
+	int i;
+	for (i = 0; i < 10 && xc_mem_schemes[i].name; i ++) {
+		if (strcmp(xc_mem_schemes[i].name, name) == 0) {
+			return xc_mem_schemes[i].handlers;
+		}
+	}
+	return NULL;
+}
+/* }}} */
+
+static xc_mem_handlers_t xc_mem_mem_handlers = XC_MEM_HANDLERS(mem);
+void xc_shm_mem_init() /* {{{ */
+{
+	memset(xc_mem_schemes, 0, sizeof(xc_mem_schemes));
+
+	if (xc_mem_scheme_register("mem", &xc_mem_mem_handlers) == 0) {
+		zend_error(E_ERROR, "XCache: failed to register mem mem_scheme");
+	}
+}
+/* }}} */
Index: /trunk/main/xc_mem.h
===================================================================
--- /trunk/main/xc_mem.h	(revision 982)
+++ /trunk/main/xc_mem.h	(revision 982)
@@ -0,0 +1,74 @@
+#include "xc_shm.h"
+
+typedef struct _xc_mem_handlers_t xc_mem_handlers_t;
+
+#ifndef XC_MEM_IMPL
+struct _xc_mem_t {
+	const xc_mem_handlers_t *handlers;
+	xc_shm_t                *shm;
+};
+#   define XC_MEM_IMPL _xc_mem_t
+#endif
+
+#ifndef XC_MEMBLOCK_IMPL
+#   define XC_MEMBLOCK_IMPL _xc_block_t
+#endif
+typedef struct XC_MEM_IMPL xc_mem_t;
+typedef struct XC_MEMBLOCK_IMPL xc_block_t;
+typedef xc_shmsize_t xc_memsize_t;
+
+/* shm::mem */
+#define XC_MEM_MALLOC(func)          void *func(xc_mem_t *mem, xc_memsize_t size)
+#define XC_MEM_FREE(func)            xc_memsize_t  func(xc_mem_t *mem, const void *p)
+#define XC_MEM_CALLOC(func)          void *func(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size)
+#define XC_MEM_REALLOC(func)         void *func(xc_mem_t *mem, const void *p, xc_memsize_t size)
+#define XC_MEM_STRNDUP(func)         char *func(xc_mem_t *mem, const char *str, xc_memsize_t len)
+#define XC_MEM_STRDUP(func)          char *func(xc_mem_t *mem, const char *str)
+#define XC_MEM_AVAIL(func)           xc_memsize_t      func(xc_mem_t *mem)
+#define XC_MEM_SIZE(func)            xc_memsize_t      func(xc_mem_t *mem)
+#define XC_MEM_FREEBLOCK_FIRST(func) const xc_block_t *func(xc_mem_t *mem)
+#define XC_MEM_FREEBLOCK_NEXT(func)  const xc_block_t *func(const xc_block_t *block)
+#define XC_MEM_BLOCK_SIZE(func)      xc_memsize_t      func(const xc_block_t *block)
+#define XC_MEM_BLOCK_OFFSET(func)    xc_memsize_t      func(const xc_mem_t *mem, const xc_block_t *block)
+
+#define XC_MEM_INIT(func)            xc_mem_t *func(xc_shm_t *shm, xc_mem_t *mem, xc_memsize_t size)
+#define XC_MEM_DESTROY(func)         void func(xc_mem_t *mem)
+
+#define XC_MEM_HANDLERS(name)   {  \
+	xc_##name##_malloc             \
+	, xc_##name##_free             \
+	, xc_##name##_calloc           \
+	, xc_##name##_realloc          \
+	, xc_##name##_strndup          \
+	, xc_##name##_strdup           \
+	, xc_##name##_avail            \
+	, xc_##name##_size             \
+	, xc_##name##_freeblock_first  \
+	, xc_##name##_freeblock_next   \
+	, xc_##name##_block_size       \
+	, xc_##name##_block_offset     \
+\
+	, xc_##name##_init             \
+	, xc_##name##_destroy          \
+}
+
+struct _xc_mem_handlers_t {
+	XC_MEM_MALLOC((*malloc));
+	XC_MEM_FREE((*free));
+	XC_MEM_CALLOC((*calloc));
+	XC_MEM_REALLOC((*realloc));
+	XC_MEM_STRNDUP((*strndup));
+	XC_MEM_STRDUP((*strdup));
+	XC_MEM_AVAIL((*avail));
+	XC_MEM_SIZE((*size));
+	XC_MEM_FREEBLOCK_FIRST((*freeblock_first));
+	XC_MEM_FREEBLOCK_NEXT((*freeblock_next));
+	XC_MEM_BLOCK_SIZE((*block_size));
+	XC_MEM_BLOCK_OFFSET((*block_offset));
+
+	XC_MEM_INIT((*init));
+	XC_MEM_DESTROY((*destroy));
+};
+
+int xc_mem_scheme_register(const char *name, const xc_mem_handlers_t *handlers);
+const xc_mem_handlers_t *xc_mem_scheme_find(const char *name);
Index: /trunk/main/xc_opcode_spec.c
===================================================================
--- /trunk/main/xc_opcode_spec.c	(revision 982)
+++ /trunk/main/xc_opcode_spec.c	(revision 982)
@@ -0,0 +1,46 @@
+#include "xcache.h"
+#include "xc_opcode_spec.h"
+#include "xc_const_string.h"
+
+/* {{{ opcode_spec */
+#define OPSPEC(ext, op1, op2, res) { OPSPEC_##ext, OPSPEC_##op1, OPSPEC_##op2, OPSPEC_##res },
+#ifdef ZEND_ENGINE_2
+#	define OPSPEC_VAR_2 OPSPEC_STD
+#else
+#	define OPSPEC_VAR_2 OPSPEC_VAR
+#endif
+#include "xc_opcode_spec_def.h"
+
+zend_uchar xc_get_opcode_spec_count()
+{
+	return sizeof(xc_opcode_spec) / sizeof(xc_opcode_spec[0]);
+}
+
+const xc_opcode_spec_t *xc_get_opcode_spec(zend_uchar opcode)
+{
+#ifndef NDEBUG
+	if (xc_get_opcode_count() != xc_get_opcode_spec_count()) {
+		fprintf(stderr, "count mismatch: xc_get_opcode_count=%d, xc_get_opcode_spec_count=%d\n", xc_get_opcode_count(), xc_get_opcode_spec_count());
+	}
+#endif
+	assert(xc_get_opcode_count() == xc_get_opcode_spec_count());
+	assert(opcode < xc_get_opcode_spec_count());
+	return &xc_opcode_spec[opcode];
+}
+/* }}} */
+/* {{{ op_spec */
+
+#define OPSPECS_DEF_NAME(name) #name,
+static const char *xc_op_spec[] = { OPSPECS(OPSPECS_DEF_NAME) };
+
+zend_uchar xc_get_op_spec_count()
+{
+	return sizeof(xc_op_spec) / sizeof(xc_op_spec[0]);
+}
+
+const char *xc_get_op_spec(zend_uchar spec)
+{
+	assert(spec < xc_get_op_spec_count());
+	return xc_op_spec[spec];
+}
+/* }}} */
Index: /trunk/main/xc_opcode_spec.h
===================================================================
--- /trunk/main/xc_opcode_spec.h	(revision 982)
+++ /trunk/main/xc_opcode_spec.h	(revision 982)
@@ -0,0 +1,43 @@
+#include "php.h"
+
+#define OPSPECS(OPSPEC) \
+	OPSPEC(STD) \
+	OPSPEC(UNUSED) \
+	OPSPEC(OPLINE) \
+	OPSPEC(FCALL) \
+	OPSPEC(INIT_FCALL) \
+	OPSPEC(ARG) \
+	OPSPEC(CAST) \
+	OPSPEC(FETCH) \
+	OPSPEC(DECLARE) \
+	OPSPEC(SEND) \
+	OPSPEC(SEND_NOREF) \
+	OPSPEC(FCLASS) \
+	OPSPEC(UCLASS) \
+	OPSPEC(CLASS) \
+	OPSPEC(FE) \
+	OPSPEC(IFACE) \
+	OPSPEC(ISSET) \
+	OPSPEC(BIT) \
+	OPSPEC(VAR) \
+	OPSPEC(TMP) \
+	OPSPEC(JMPADDR) \
+	OPSPEC(BRK) \
+	OPSPEC(CONT) \
+	OPSPEC(INCLUDE) \
+	OPSPEC(ASSIGN)
+
+#define OPSPECS_DEF_ENUM(name) OPSPEC_##name,
+typedef enum { OPSPECS(OPSPECS_DEF_ENUM) OPSPEC_DUMMY } xc_op_spec_t;
+
+typedef struct {
+	xc_op_spec_t ext;
+	xc_op_spec_t op1;
+	xc_op_spec_t op2;
+	xc_op_spec_t res;
+} xc_opcode_spec_t;
+
+const xc_opcode_spec_t *xc_get_opcode_spec(zend_uchar opcode);
+zend_uchar xc_get_opcode_spec_count();
+zend_uchar xc_get_op_spec_count();
+const char *xc_get_op_spec(zend_uchar spec);
Index: /trunk/main/xc_opcode_spec_def.h
===================================================================
--- /trunk/main/xc_opcode_spec_def.h	(revision 982)
+++ /trunk/main/xc_opcode_spec_def.h	(revision 982)
@@ -0,0 +1,260 @@
+static const xc_opcode_spec_t xc_opcode_spec[] = {
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 0 NOP                            */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 1 ADD                            */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 2 SUB                            */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 3 MUL                            */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 4 DIV                            */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 5 MOD                            */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 6 SL                             */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 7 SR                             */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 8 CONCAT                         */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 9 BW_OR                          */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 10 BW_AND                         */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 11 BW_XOR                         */
+	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 12 BW_NOT                         */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 13 BOOL_NOT                       */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 14 BOOL_XOR                       */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 15 IS_IDENTICAL                   */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 16 IS_NOT_IDENTICAL               */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 17 IS_EQUAL                       */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 18 IS_NOT_EQUAL                   */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 19 IS_SMALLER                     */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 20 IS_SMALLER_OR_EQUAL            */
+	OPSPEC(      CAST,        STD,     UNUSED,        TMP) /* 21 CAST                           */
+	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 22 QM_ASSIGN                      */
+#ifdef ZEND_ENGINE_2
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 23 ASSIGN_ADD                     */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 24 ASSIGN_SUB                     */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 25 ASSIGN_MUL                     */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 26 ASSIGN_DIV                     */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 27 ASSIGN_MOD                     */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 28 ASSIGN_SL                      */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 29 ASSIGN_SR                      */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 30 ASSIGN_CONCAT                  */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 31 ASSIGN_BW_OR                   */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 32 ASSIGN_BW_AND                  */
+	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 33 ASSIGN_BW_XOR                  */
+#else
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
+#endif
+	OPSPEC(    UNUSED,        VAR,     UNUSED,        VAR) /* 34 PRE_INC                        */
+	OPSPEC(    UNUSED,        VAR,     UNUSED,        VAR) /* 35 PRE_DEC                        */
+	OPSPEC(    UNUSED,        VAR,     UNUSED,        TMP) /* 36 POST_INC                       */
+	OPSPEC(    UNUSED,        VAR,     UNUSED,        TMP) /* 37 POST_DEC                       */
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 38 ASSIGN                         */
+	OPSPEC(    UNUSED,        VAR,        VAR,        VAR) /* 39 ASSIGN_REF                     */
+	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 40 ECHO                           */
+	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 41 PRINT                          */
+#ifdef ZEND_ENGINE_2
+	OPSPEC(    UNUSED,    JMPADDR,     UNUSED,     UNUSED) /* 42 JMP                            */
+	OPSPEC(    UNUSED,        STD,    JMPADDR,     UNUSED) /* 43 JMPZ                           */
+	OPSPEC(    UNUSED,        STD,    JMPADDR,     UNUSED) /* 44 JMPNZ                          */
+#else
+	OPSPEC(    UNUSED,     OPLINE,     UNUSED,     UNUSED)
+	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED)
+	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED)
+#endif
+	OPSPEC(    OPLINE,        STD,     OPLINE,     UNUSED) /* 45 JMPZNZ                         */
+#ifdef ZEND_ENGINE_2
+	OPSPEC(    UNUSED,        STD,    JMPADDR,        TMP) /* 46 JMPZ_EX                        */
+	OPSPEC(    UNUSED,        STD,    JMPADDR,        TMP) /* 47 JMPNZ_EX                       */
+#else
+	OPSPEC(    UNUSED,        STD,     OPLINE,        TMP)
+	OPSPEC(    UNUSED,        STD,     OPLINE,        TMP)
+#endif
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 48 CASE                           */
+	OPSPEC(       BIT,        STD,     UNUSED,     UNUSED) /* 49 SWITCH_FREE                    */
+	OPSPEC(    UNUSED,        BRK,        STD,     UNUSED) /* 50 BRK                            */
+	OPSPEC(    UNUSED,       CONT,        STD,     UNUSED) /* 51 CONT                           */
+	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 52 BOOL                           */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,        TMP) /* 53 INIT_STRING                    */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 54 ADD_CHAR                       */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 55 ADD_STRING                     */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 56 ADD_VAR                        */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,        TMP) /* 57 BEGIN_SILENCE                  */
+	OPSPEC(    UNUSED,        TMP,     UNUSED,     UNUSED) /* 58 END_SILENCE                    */
+	OPSPEC(INIT_FCALL,        STD,        STD,     UNUSED) /* 59 INIT_FCALL_BY_NAME             */
+#ifdef ZEND_ENGINE_2
+	OPSPEC(     FCALL,        STD,     OPLINE,        VAR) /* 60 DO_FCALL                       */
+	OPSPEC(     FCALL,        STD,     OPLINE,        VAR) /* 61 DO_FCALL_BY_NAME               */
+#else
+	OPSPEC(     FCALL,        STD,     UNUSED,        VAR)
+	OPSPEC(     FCALL,        STD,     UNUSED,        VAR)
+#endif
+	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 62 RETURN                         */
+	OPSPEC(    UNUSED,        ARG,     UNUSED,        VAR) /* 63 RECV                           */
+	OPSPEC(    UNUSED,        ARG,        STD,        VAR) /* 64 RECV_INIT                      */
+	OPSPEC(      SEND,        STD,        ARG,     UNUSED) /* 65 SEND_VAL                       */
+	OPSPEC(      SEND,        VAR,        ARG,     UNUSED) /* 66 SEND_VAR                       */
+	OPSPEC(      SEND,        VAR,        ARG,     UNUSED) /* 67 SEND_REF                       */
+#ifdef ZEND_ENGINE_2
+	OPSPEC(    UNUSED,      CLASS,     UNUSED,        VAR) /* 68 NEW                            */
+#else
+	OPSPEC(    UNUSED,        STD,     UNUSED,        VAR)
+#endif
+#ifdef ZEND_ENGINE_2_3
+	OPSPEC(       STD,        STD,        STD,     UNUSED) /* 69 INIT_NS_FCALL_BY_NAME          */
+#else
+	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED) /* 69 JMP_NO_CTOR                    */
+#endif
+	OPSPEC(    UNUSED,        TMP,     UNUSED,     UNUSED) /* 70 FREE                           */
+	OPSPEC(       BIT,        STD,        STD,        TMP) /* 71 INIT_ARRAY                     */
+	OPSPEC(       BIT,        STD,        STD,        TMP) /* 72 ADD_ARRAY_ELEMENT              */
+	OPSPEC(    UNUSED,        STD,    INCLUDE,        VAR) /* 73 INCLUDE_OR_EVAL                */
+#ifdef ZEND_ENGINE_2_1
+  /* php 5.1 and up */
+	OPSPEC(    UNUSED,        STD,      FETCH,     UNUSED) /* 74 UNSET_VAR                      */
+	OPSPEC(       STD,        STD,        STD,     UNUSED) /* 75 UNSET_DIM                      */
+	OPSPEC(       STD,        STD,        STD,     UNUSED) /* 76 UNSET_OBJ                      */
+	OPSPEC(       BIT,        STD,     OPLINE,        VAR) /* 77 FE_RESET                       */
+#else
+  /* <= php 5.0 */
+  /* though there is no ISSET_ISEMPTY in php 5.0 it's better to leave it here i guess */
+	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED)
+	OPSPEC(    UNUSED,        VAR,        STD,     UNUSED)
+	OPSPEC(    UNUSED,        VAR,      ISSET,        TMP)
+	OPSPEC(       BIT,        STD,     UNUSED,        VAR)
+#endif
+	OPSPEC(        FE,        STD,     OPLINE,        TMP) /* 78 FE_FETCH                       */
+	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 79 EXIT                           */
+	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 80 FETCH_R                        */
+	OPSPEC(     FETCH,        VAR,        STD,        VAR) /* 81 FETCH_DIM_R                    */
+	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 82 FETCH_OBJ_R                    */
+	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 83 FETCH_W                        */
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 84 FETCH_DIM_W                    */
+	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 85 FETCH_OBJ_W                    */
+	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 86 FETCH_RW                       */
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 87 FETCH_DIM_RW                   */
+	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 88 FETCH_OBJ_RW                   */
+	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 89 FETCH_IS                       */
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 90 FETCH_DIM_IS                   */
+	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 91 FETCH_OBJ_IS                   */
+	OPSPEC(       ARG,        STD,      FETCH,        VAR) /* 92 FETCH_FUNC_ARG                 */
+	OPSPEC(       ARG,        VAR,        STD,        VAR) /* 93 FETCH_DIM_FUNC_ARG             */
+	OPSPEC(       ARG,      VAR_2,        STD,        VAR) /* 94 FETCH_OBJ_FUNC_ARG             */
+	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 95 FETCH_UNSET                    */
+	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 96 FETCH_DIM_UNSET                */
+	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 97 FETCH_OBJ_UNSET                */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 98 FETCH_DIM_TMP_VAR              */
+#ifdef ZEND_ENGINE_2_3
+	OPSPEC(    UNUSED,      VAR_2,        STD,        TMP) /* 99 FETCH_CONSTANT                 */
+#elif defined(ZEND_ENGINE_2)
+	OPSPEC(    UNUSED,     UCLASS,        STD,        TMP) /* 99 FETCH_CONSTANT                 */
+#else
+	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 99 FETCH_CONSTANT                 */
+#endif
+#ifdef ZEND_ENGINE_2_3
+	OPSPEC(       STD,    JMPADDR,        STD,     UNUSED) /* 100 GOTO                           */
+#else
+	OPSPEC(   DECLARE,        STD,        STD,     UNUSED) /* 100 DECLARE_FUNCTION_OR_CLASS      */
+#endif
+	OPSPEC(       STD,        STD,        STD,        STD) /* 101 EXT_STMT                       */
+	OPSPEC(       STD,        STD,        STD,        STD) /* 102 EXT_FCALL_BEGIN                */
+	OPSPEC(       STD,        STD,        STD,        STD) /* 103 EXT_FCALL_END                  */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 104 EXT_NOP                        */
+	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 105 TICKS                          */
+	OPSPEC(SEND_NOREF,        VAR,        ARG,     UNUSED) /* 106 SEND_VAR_NO_REF                */
+#ifdef ZEND_ENGINE_2
+	OPSPEC(    OPLINE,      CLASS,        STD,     UNUSED) /* 107 CATCH                          */
+	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED) /* 108 THROW                          */
+	OPSPEC(    FCLASS,        STD,        STD,      CLASS) /* 109 FETCH_CLASS                    */
+	OPSPEC(    UNUSED,        STD,     UNUSED,        VAR) /* 110 CLONE                          */
+
+#ifdef ZEND_ENGINE_2_4
+	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 111 RETURN_BY_REF                  */
+#else
+	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 111 INIT_CTOR_CALL                 */
+#endif
+
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 112 INIT_METHOD_CALL               */
+#	ifdef ZEND_ENGINE_2_3
+	OPSPEC(    UNUSED,        STD,        STD,     UNUSED) /* 113 INIT_STATIC_METHOD_CALL        */
+#	else
+	OPSPEC(    UNUSED,     UCLASS,        STD,     UNUSED) /* 113 INIT_STATIC_METHOD_CALL        */
+#	endif
+	OPSPEC(     ISSET,        STD,      FETCH,        TMP) /* 114 ISSET_ISEMPTY_VAR              */
+	OPSPEC(     ISSET,        STD,        STD,        TMP) /* 115 ISSET_ISEMPTY_DIM_OBJ          */
+
+	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 116 IMPORT_FUNCTION                */
+	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 117 IMPORT_CLASS                   */
+	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 118 IMPORT_CONST                   */
+	OPSPEC(       STD,        STD,        STD,        STD) /* 119 OP_119                         */
+	OPSPEC(       STD,        STD,        STD,        STD) /* 120 OP_120                         */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 121 ASSIGN_ADD_OBJ                 */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 122 ASSIGN_SUB_OBJ                 */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 123 ASSIGN_MUL_OBJ                 */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 124 ASSIGN_DIV_OBJ                 */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 125 ASSIGN_MOD_OBJ                 */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 126 ASSIGN_SL_OBJ                  */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 127 ASSIGN_SR_OBJ                  */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 128 ASSIGN_CONCAT_OBJ              */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 129 ASSIGN_BW_OR_OBJ               */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 130 ASSIGN_BW_AND_OBJ              */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 131 ASSIGN_BW_XOR_OBJ              */
+
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 132 PRE_INC_OBJ                    */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 133 PRE_DEC_OBJ                    */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 134 POST_INC_OBJ                   */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 135 POST_DEC_OBJ                   */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 136 ASSIGN_OBJ                     */
+	OPSPEC(    UNUSED,        STD,        STD,        STD) /* 137 OP_DATA                        */
+	OPSPEC(    UNUSED,        STD,      CLASS,        TMP) /* 138 INSTANCEOF                     */
+	OPSPEC(    UNUSED,        STD,        STD,      CLASS) /* 139 DECLARE_CLASS                  */
+	OPSPEC(     CLASS,        STD,        STD,      CLASS) /* 140 DECLARE_INHERITED_CLASS        */
+	OPSPEC(    UNUSED,        STD,        STD,     UNUSED) /* 141 DECLARE_FUNCTION               */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 142 RAISE_ABSTRACT_ERROR           */
+#ifdef ZEND_ENGINE_2_3
+	OPSPEC(   DECLARE,        STD,        STD,     UNUSED) /* 143 DECLARE_CONST                  */
+#else
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 143 UNDEF-143                      */
+#endif
+#ifdef ZEND_ENGINE_2_3
+	OPSPEC(     IFACE,      CLASS,        STD,     UNUSED) /* 144 ADD_INTERFACE                  */
+#else
+	OPSPEC(     IFACE,      CLASS,      CLASS,     UNUSED) /* 144 ADD_INTERFACE                  */
+#endif
+#ifdef ZEND_ENGINE_2_3
+	OPSPEC(     CLASS,        STD,        STD,     OPLINE) /* 145 DECLARE_INHERITED_CLASS_DELAYED */
+#else
+	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 145 VERIFY_INSTANCEOF              */
+#endif
+	OPSPEC(    UNUSED,      CLASS,     UNUSED,     UNUSED) /* 146 VERIFY_ABSTRACT_CLASS          */
+	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 147 ASSIGN_DIM                     */
+	OPSPEC(     ISSET,        STD,        STD,        TMP) /* 148 ISSET_ISEMPTY_PROP_OBJ         */
+	OPSPEC(       STD,     UNUSED,     UNUSED,        STD) /* 149 HANDLE_EXCEPTION               */
+	OPSPEC(       STD,     UNUSED,     UNUSED,        STD) /* 150 USER_OPCODE                    */
+# ifdef ZEND_ENGINE_2_3
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 151 UNDEF                          */
+	OPSPEC(    UNUSED,        STD,    JMPADDR,        TMP) /* 152 JMP_SET                        */
+	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 153 DECLARE_LAMBDA_FUNCTION        */
+#  ifdef ZEND_ENGINE_2_4
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 154 ADD_TRAIT                      */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 155 BIND_TRAITS                    */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 156 SEPARATE                       */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 157 QM_ASSIGN_VAR                  */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 158 JMP_SET_VAR                    */
+#  endif
+# else
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 151 UNDEF                          */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 152 UNDEF                          */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 153 UNDEF                          */
+# endif
+#else
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 107 UNDEF                          */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 108 UNDEF                          */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 109 UNDEF                          */
+	OPSPEC(     FCALL,        STD,     OPLINE,        VAR) /* 61 DO_FCALL_BY_FUNC                */
+	OPSPEC(INIT_FCALL,        STD,        STD,     UNUSED) /* 111 INIT_FCALL_BY_FUNC             */
+	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 112 UNDEF                          */
+#endif
+};
Index: /trunk/main/xc_processor.c
===================================================================
--- /trunk/main/xc_processor.c	(revision 982)
+++ /trunk/main/xc_processor.c	(revision 982)
@@ -0,0 +1,1 @@
+#include "xc_processor_real.c"
Index: /trunk/main/xc_shm.c
===================================================================
--- /trunk/main/xc_shm.c	(revision 982)
+++ /trunk/main/xc_shm.c	(revision 982)
@@ -0,0 +1,99 @@
+#ifdef TEST
+#include <limits.h>
+#include <stdio.h>
+#else
+#include <php.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xc_shm.h"
+
+struct _xc_shm_scheme_t {
+	const char              *name;
+	const xc_shm_handlers_t *handlers;
+};
+static xc_shm_scheme_t xc_shm_schemes[10];
+
+void xc_shm_init_modules() /* {{{ */
+{
+	extern void xc_shm_mem_init();
+#ifdef HAVE_XCACHE_TEST
+	extern void xc_shm_malloc_register();
+#endif
+	extern void xc_shm_mmap_register();
+
+	memset(xc_shm_schemes, 0, sizeof(xc_shm_schemes));
+	xc_shm_mem_init();
+#ifdef HAVE_XCACHE_TEST
+	xc_shm_malloc_register();
+#endif
+	xc_shm_mmap_register();
+}
+/* }}} */
+int xc_shm_scheme_register(const char *name, const xc_shm_handlers_t *handlers) /* {{{ */
+{
+	int i;
+	for (i = 0; i < 10; i ++) {
+		if (!xc_shm_schemes[i].name) {
+			xc_shm_schemes[i].name = name;
+			xc_shm_schemes[i].handlers = handlers;
+			return 1;
+		}
+	}
+	return 0;
+}
+/* }}} */
+const xc_shm_handlers_t *xc_shm_scheme_find(const char *name) /* {{{ */
+{
+	int i;
+	for (i = 0; i < 10 && xc_shm_schemes[i].name; i ++) {
+		if (strcmp(xc_shm_schemes[i].name, name) == 0) {
+			return xc_shm_schemes[i].handlers;
+		}
+	}
+	return NULL;
+}
+/* }}} */
+xc_shm_scheme_t *xc_shm_scheme_first() /* {{{ */
+{
+	return xc_shm_schemes;
+}
+/* }}} */
+xc_shm_scheme_t *xc_shm_scheme_next(xc_shm_scheme_t *scheme) /* {{{ */
+{
+	scheme ++;
+	return scheme->name ? scheme : NULL;
+}
+/* }}} */
+const char *xc_shm_scheme_name(xc_shm_scheme_t *scheme) /* {{{ */
+{
+	assert(scheme);
+	return scheme->name;
+}
+/* }}} */
+xc_shm_t *xc_shm_init(const char *type, xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2) /* {{{ */
+{
+	const xc_shm_handlers_t *handlers = xc_shm_scheme_find(type);
+
+	if (handlers) {
+		xc_shm_t *shm = handlers->init(size, readonly_protection, arg1, arg2);
+		if (shm) {
+			shm->handlers = handlers;
+		}
+		return shm;
+	}
+
+	return NULL;
+}
+/* }}} */
+void xc_shm_destroy(xc_shm_t *shm) /* {{{ */
+{
+	shm->handlers->destroy(shm);
+}
+/* }}} */
Index: /trunk/main/xc_shm.h
===================================================================
--- /trunk/main/xc_shm.h	(revision 982)
+++ /trunk/main/xc_shm.h	(revision 982)
@@ -0,0 +1,71 @@
+#ifndef XC_SHM_H
+#define XC_SHM_H
+typedef struct _xc_shm_handlers_t xc_shm_handlers_t;
+
+#ifndef XC_SHM_IMPL
+struct _xc_shm_t {
+	const xc_shm_handlers_t *handlers;
+	zend_bool disabled;
+};
+#define XC_SHM_IMPL _xc_shm_t
+#endif
+
+typedef struct XC_SHM_IMPL xc_shm_t;
+typedef size_t xc_shmsize_t;
+
+#include "xc_mem.h"
+
+/* shm */
+#define XC_SHM_CAN_READONLY(func) int   func(xc_shm_t *shm)
+#define XC_SHM_IS_READWRITE(func) int   func(xc_shm_t *shm, const void *p)
+#define XC_SHM_IS_READONLY(func)  int   func(xc_shm_t *shm, const void *p)
+#define XC_SHM_TO_READWRITE(func) void *func(xc_shm_t *shm, void *p)
+#define XC_SHM_TO_READONLY(func)  void *func(xc_shm_t *shm, void *p)
+
+#define XC_SHM_INIT(func)         xc_shm_t *func(xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2)
+#define XC_SHM_DESTROY(func)      void func(xc_shm_t *shm)
+
+#define XC_SHM_MEMINIT(func)      xc_mem_t *func(xc_shm_t *shm, xc_memsize_t size)
+#define XC_SHM_MEMDESTROY(func)   void func(xc_mem_t *mem)
+
+#define XC_SHM_HANDLERS(name)    { \
+	NULL                           \
+	, xc_##name##_can_readonly     \
+	, xc_##name##_is_readwrite     \
+	, xc_##name##_is_readonly      \
+	, xc_##name##_to_readwrite     \
+	, xc_##name##_to_readonly      \
+\
+	, xc_##name##_init             \
+	, xc_##name##_destroy          \
+\
+	, xc_##name##_meminit          \
+	, xc_##name##_memdestroy       \
+}
+
+struct _xc_shm_handlers_t {
+	const xc_mem_handlers_t *memhandlers;
+	XC_SHM_CAN_READONLY((*can_readonly));
+	XC_SHM_IS_READWRITE((*is_readwrite));
+	XC_SHM_IS_READONLY((*is_readonly));
+	XC_SHM_TO_READWRITE((*to_readwrite));
+	XC_SHM_TO_READONLY((*to_readonly));
+	XC_SHM_INIT((*init));
+	XC_SHM_DESTROY((*destroy));
+
+	XC_SHM_MEMINIT((*meminit));
+	XC_SHM_MEMDESTROY((*memdestroy));
+};
+
+typedef struct _xc_shm_scheme_t xc_shm_scheme_t;
+
+void xc_shm_init_modules();
+int xc_shm_scheme_register(const char *name, const xc_shm_handlers_t *handlers);
+const xc_shm_handlers_t *xc_shm_scheme_find(const char *name);
+xc_shm_scheme_t *xc_shm_scheme_first();
+xc_shm_scheme_t *xc_shm_scheme_next(xc_shm_scheme_t *scheme);
+const char *xc_shm_scheme_name(xc_shm_scheme_t *scheme);
+
+xc_shm_t *xc_shm_init(const char *type, xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2);
+void xc_shm_destroy(xc_shm_t *shm);
+#endif
Index: /trunk/main/xc_shm_mmap.c
===================================================================
--- /trunk/main/xc_shm_mmap.c	(revision 982)
+++ /trunk/main/xc_shm_mmap.c	(revision 982)
@@ -0,0 +1,324 @@
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* mmap */
+#ifdef ZEND_WIN32
+#	define ftruncate chsize
+#	define getuid() 0
+#	include <process.h>
+#	define XCacheCreateFileMapping(size, perm, name) \
+		CreateFileMapping(INVALID_HANDLE_VALUE, NULL, perm, (sizeof(xc_shmsize_t) > 4) ? size >> 32 : 0, size & 0xffffffff, name)
+#	define XCACHE_MAP_FAILED NULL
+#	define munmap(p, s) UnmapViewOfFile(p)
+#else
+#	include <unistd.h>
+/* make sure to mark(change) it to NULL to keep consistent */
+#	define XCACHE_MAP_FAILED MAP_FAILED
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef ZEND_WIN32
+#include <sys/mman.h>
+#endif
+
+#include "php.h"
+#define XC_SHM_IMPL _xc_mmap_shm_t
+#include "xc_shm.h"
+#include "xc_utils.h"
+
+#ifndef max
+#define max(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+/* {{{ xc_shm_t */
+struct _xc_mmap_shm_t {
+	xc_shm_handlers_t *handlers;
+	zend_bool disabled;
+	void *ptr;
+	void *ptr_ro;
+	long  diff;
+	xc_shmsize_t size;
+	xc_shmsize_t memoffset;
+	char *name;
+#ifdef ZEND_WIN32
+	HANDLE hmap;
+	HANDLE hmap_ro;
+#else
+	int newfile;
+#endif
+};
+
+/* }}} */
+#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
+#define PTR_ADD(ptr, v) (((char *) (ptr)) + (v))
+#define PTR_SUB(ptr, v) (((char *) (ptr)) - (v))
+
+static XC_SHM_CAN_READONLY(xc_mmap_can_readonly) /* {{{ */
+{
+	return shm->ptr_ro != NULL;
+}
+/* }}} */
+static XC_SHM_IS_READWRITE(xc_mmap_is_readwrite) /* {{{ */
+{
+	return p >= shm->ptr && (char *)p < (char *)shm->ptr + shm->size;
+}
+/* }}} */
+static XC_SHM_IS_READONLY(xc_mmap_is_readonly) /* {{{ */
+{
+	return xc_mmap_can_readonly(shm) && p >= shm->ptr_ro && (char *)p < (char *)shm->ptr_ro + shm->size;
+}
+/* }}} */
+static XC_SHM_TO_READWRITE(xc_mmap_to_readwrite) /* {{{ */
+{
+	if (shm->diff) {
+		assert(xc_mmap_is_readonly(shm, p));
+		p = PTR_SUB(p, shm->diff);
+	}
+	assert(xc_mmap_is_readwrite(shm, p));
+	return p;
+}
+/* }}} */
+static XC_SHM_TO_READONLY(xc_mmap_to_readonly) /* {{{ */
+{
+	assert(xc_mmap_is_readwrite(shm, p));
+	if (shm->diff) {
+		p = PTR_ADD(p, shm->diff);
+		assert(xc_mmap_is_readonly(shm, p));
+	}
+	return p;
+}
+/* }}} */
+
+static XC_SHM_DESTROY(xc_mmap_destroy) /* {{{ */
+{
+	if (shm->ptr_ro) {
+		munmap(shm->ptr_ro, shm->size);
+		/*
+		shm->ptr_ro = NULL;
+		*/
+	}
+	if (shm->ptr) {
+		/* shm->size depends on shm->ptr */
+		munmap(shm->ptr, shm->size);
+		/*
+		shm->ptr = NULL;
+		*/
+	}
+#ifdef ZEND_WIN32
+	if (shm->hmap) {
+		CloseHandle(shm->hmap);
+	}
+	if (shm->hmap_ro) {
+		CloseHandle(shm->hmap_ro);
+	}
+#endif
+
+	if (shm->name) {
+#ifndef ZEND_WIN32
+#	ifdef __CYGWIN__
+		if (shm->newfile) {
+			unlink(shm->name);
+		}
+#	endif
+#endif
+		free(shm->name);
+	}
+	/*
+	shm->size = NULL;
+	shm->diff = 0;
+	*/
+
+	free(shm);
+	return;
+}
+/* }}} */
+static XC_SHM_INIT(xc_mmap_init) /* {{{ */
+{
+#ifdef ZEND_WIN32
+#	define TMP_PATH "XCache"
+#else
+#	define TMP_PATH "/tmp/XCache"
+	int fd = -1;
+#endif
+	xc_shm_t *shm = NULL;
+	int ro_ok;
+	volatile void *romem;
+	char tmpname[sizeof(TMP_PATH) - 1 + 100];
+	const char *errstr = NULL;
+	const char *path = (const char *) arg1;
+
+	CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM");
+	shm->size = size;
+
+	if (path == NULL || !path[0]) {
+		static int inc = 0;
+		snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d.%d", TMP_PATH, (int) getuid(), (int) getpid(), inc ++, rand());
+		path = tmpname;
+	}
+#ifdef ZEND_WIN32
+	else {
+		static int inc2 = 0;
+		snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d.%d", path, (int) getuid(), (int) getpid(), inc2 ++, rand());
+		path = tmpname;
+	}
+#endif
+
+	shm->name = strdup(path);
+
+#ifndef ZEND_WIN32
+#	define XCACHE_MMAP_PERMISSION (S_IRUSR | S_IWUSR)
+	fd = open(shm->name, O_RDWR, XCACHE_MMAP_PERMISSION);
+	if (fd == -1) {
+		/* do not create file in /dev */
+		if (strncmp(shm->name, "/dev", 4) == 0) {
+			perror(shm->name);
+			errstr = "Cannot open file set by xcache.mmap_path, check the xcache.size/var_size against system limitation";
+			goto err;
+		}
+		fd = open(shm->name, O_CREAT | O_RDWR, XCACHE_MMAP_PERMISSION);
+		shm->newfile = 1;
+		if (fd == -1) {
+			perror(shm->name);
+			errstr = "Cannot open or create file set by xcache.mmap_path, check the path permission or check xcache.size/var_size against system limitation";
+			goto err;
+		}
+	}
+
+	if (ftruncate(fd, size) != 0 && errno != EINVAL) {
+		perror(shm->name);
+		errstr = "Failed to ftruncate the file";
+		goto err;
+	}
+#endif
+
+#ifdef ZEND_WIN32
+	shm->hmap = XCacheCreateFileMapping(size, PAGE_READWRITE, shm->name);
+	shm->ptr = (LPSTR) MapViewOfFile(shm->hmap, FILE_MAP_WRITE, 0, 0, 0);
+#else
+	shm->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+#endif
+
+	if (shm->ptr == XCACHE_MAP_FAILED) {
+		perror(shm->name);
+		errstr = "Failed creating file mapping";
+		shm->ptr = NULL;
+		goto err;
+	}
+
+	/* {{{ readonly protection, mmap it readonly and check if ptr_ro works */
+	if (readonly_protection) {
+		ro_ok = 0;
+
+#ifdef ZEND_WIN32
+		shm->hmap_ro = XCacheCreateFileMapping(size, PAGE_READONLY, shm->name);
+		shm->ptr_ro = (LPSTR) MapViewOfFile(shm->hmap_ro, FILE_MAP_READ, 0, 0, 0);
+#else
+		shm->ptr_ro = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+#endif
+		if (shm->ptr_ro == XCACHE_MAP_FAILED) {
+			shm->ptr_ro = NULL;
+		}
+		romem = shm->ptr_ro;
+
+		do {
+			if (romem == NULL || romem == shm->ptr) {
+				break;
+			}
+			*(char *)shm->ptr = 1;
+			if (*(char *)romem != 1) {
+				break;
+			}
+			*(char *)shm->ptr = 2;
+			if (*(char *)romem != 2) {
+				break;
+			}
+			ro_ok = 1;
+		} while (0);
+
+		if (ro_ok) {
+			shm->diff = PTR_SUB(shm->ptr_ro, (char *) shm->ptr);
+			/* no overlap */
+			assert(abs(shm->diff) >= size);
+		}
+		else {
+			if (shm->ptr_ro) {
+				munmap(shm->ptr_ro, size);
+			}
+#ifdef ZEND_WIN32
+			if (shm->hmap_ro) {
+				CloseHandle(shm->hmap_ro);
+			}
+#endif
+			shm->ptr_ro = NULL;
+			shm->diff = 0;
+		}
+	}
+
+	/* }}} */
+
+#ifndef ZEND_WIN32
+	close(fd);
+
+#	ifndef __CYGWIN__
+	if (shm->newfile) {
+		unlink(shm->name);
+	}
+#	endif
+#endif
+
+	return shm;
+
+err:
+#ifndef ZEND_WIN32
+	if (fd != -1) {
+		close(fd);
+	}
+#endif
+	if (shm) {
+		xc_mmap_destroy(shm);
+	}
+	if (errstr) {
+		fprintf(stderr, "%s\n", errstr);
+		zend_error(E_ERROR, "%s", errstr);
+	}
+	return NULL;
+}
+/* }}} */
+
+static XC_SHM_MEMINIT(xc_mmap_meminit) /* {{{ */
+{
+	xc_mem_t *mem;
+	if (shm->memoffset + size > shm->size) {
+		zend_error(E_ERROR, "XCache: internal error at %s#%d", __FILE__, __LINE__);
+		return NULL;
+	}
+	mem = (xc_mem_t *) PTR_ADD(shm->ptr, shm->memoffset);
+	shm->memoffset += size;
+	mem->handlers = shm->handlers->memhandlers;
+	mem->handlers->init(shm, mem, size);
+	return mem;
+}
+/* }}} */
+static XC_SHM_MEMDESTROY(xc_mmap_memdestroy) /* {{{ */
+{
+}
+/* }}} */
+
+static xc_shm_handlers_t xc_shm_mmap_handlers = XC_SHM_HANDLERS(mmap);
+void xc_shm_mmap_register() /* {{{ */
+{
+	CHECK(xc_shm_mmap_handlers.memhandlers = xc_mem_scheme_find("mem"), "cannot find mem handlers");
+	if (xc_shm_scheme_register("mmap", &xc_shm_mmap_handlers) == 0) {
+		zend_error(E_ERROR, "XCache: failed to register mmap shm_scheme");
+	}
+err:
+	return;
+}
+/* }}} */
Index: /trunk/main/xc_utils.c
===================================================================
--- /trunk/main/xc_utils.c	(revision 982)
+++ /trunk/main/xc_utils.c	(revision 982)
@@ -0,0 +1,1132 @@
+
+#include "xcache.h"
+#include "xcache_globals.h"
+#include "xc_utils.h"
+#ifdef ZEND_ENGINE_2_1
+#include "zend_vm.h"
+#endif
+#include "xc_opcode_spec.h"
+#undef NDEBUG
+#include "assert.h"
+
+#ifndef max
+#define max(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+#ifndef ZEND_VM_SET_OPCODE_HANDLER
+#	define ZEND_VM_SET_OPCODE_HANDLER(opline) do { } while (0)
+#endif
+
+#ifdef ZEND_ENGINE_2_4
+#	define OP_ZVAL_DTOR(op) do { } while(0)
+#else
+#	define OP_ZVAL_DTOR(op) do { \
+		Z_UNSET_ISREF(Z_OP_CONSTANT(op)); \
+		zval_dtor(&Z_OP_CONSTANT(op)); \
+	} while(0)
+#endif
+
+static void (*old_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) = NULL;
+static void call_old_zend_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, ...) /* {{{ */
+{
+	va_list args;
+	va_start(args, format);
+	old_zend_error_cb(type, error_filename, error_lineno, format, args);
+}
+/* }}} */
+
+xc_compile_result_t *xc_compile_result_init(xc_compile_result_t *cr, /* {{{ */
+		zend_op_array *op_array,
+		HashTable *function_table,
+		HashTable *class_table)
+{
+	assert(cr);
+	cr->op_array       = op_array;
+	cr->function_table = function_table;
+	cr->class_table    = class_table;
+	return cr;
+}
+/* }}} */
+xc_compile_result_t *xc_compile_result_init_cur(xc_compile_result_t *cr, zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	assert(cr);
+	return xc_compile_result_init(cr, op_array, CG(function_table), CG(class_table));
+}
+/* }}} */
+void xc_compile_result_free(xc_compile_result_t *cr) /* {{{ */
+{
+}
+/* }}} */
+
+int xc_apply_function(zend_function *zf, apply_func_t applyer TSRMLS_DC) /* {{{ */
+{
+	switch (zf->type) {
+	case ZEND_USER_FUNCTION:
+	case ZEND_EVAL_CODE:
+		return applyer(&zf->op_array TSRMLS_CC);
+		break;
+
+	case ZEND_INTERNAL_FUNCTION:
+	case ZEND_OVERLOADED_FUNCTION:
+		break;
+
+	EMPTY_SWITCH_DEFAULT_CASE();
+	}
+	return 0;
+}
+/* }}} */
+typedef struct {
+	apply_func_t applyer;
+	zend_class_entry *ce;
+} xc_apply_method_info;
+int xc_apply_method(zend_function *zf, xc_apply_method_info *mi TSRMLS_DC) /* {{{ */
+{
+	/* avoid duplicate apply for shadowed method */
+#ifdef ZEND_ENGINE_2
+	if (mi->ce != zf->common.scope) {
+		/* fprintf(stderr, "avoided duplicate %s\n", zf->common.function_name); */
+		return 0;
+	}
+#else
+	char *name = zf->common.function_name;
+	int name_s = strlen(name) + 1;
+	zend_class_entry *ce;
+	zend_function *ptr;
+
+	for (ce = mi->ce->parent; ce; ce = ce->parent) {
+		if (zend_hash_find(&ce->function_table, name, name_s, (void **) &ptr) == SUCCESS) {
+			if (ptr->op_array.refcount == zf->op_array.refcount) {
+				return 0;
+			}
+		}
+	}
+#endif
+	return xc_apply_function(zf, mi->applyer TSRMLS_CC);
+}
+/* }}} */
+#if 0
+int xc_apply_class(zend_class_entry *ce, apply_func_t applyer TSRMLS_DC) /* {{{ */
+{
+	xc_apply_method_info mi;
+
+	mi.applyer = applyer;
+	mi.ce      = ce;
+	zend_hash_apply_with_argument(&(ce->function_table), (apply_func_arg_t) xc_apply_method, &mi TSRMLS_CC);
+	return 0;
+}
+/* }}} */
+#endif
+static int xc_apply_cest(xc_cest_t *cest, apply_func_t applyer TSRMLS_DC) /* {{{ */
+{
+	xc_apply_method_info mi;
+
+	mi.applyer = applyer;
+	mi.ce      = CestToCePtr(*cest);
+	zend_hash_apply_with_argument(&(CestToCePtr(*cest)->function_table), (apply_func_arg_t) xc_apply_method, &mi TSRMLS_CC);
+	return 0;
+}
+/* }}} */
+int xc_apply_op_array(xc_compile_result_t *cr, apply_func_t applyer TSRMLS_DC) /* {{{ */
+{
+	zend_hash_apply_with_argument(cr->function_table, (apply_func_arg_t) xc_apply_function, (void *) applyer TSRMLS_CC);
+	zend_hash_apply_with_argument(cr->class_table, (apply_func_arg_t) xc_apply_cest, (void *) applyer TSRMLS_CC);
+
+	return applyer(cr->op_array TSRMLS_CC);
+}
+/* }}} */
+int xc_undo_pass_two(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline, *end;
+
+#ifdef ZEND_ENGINE_2_4
+	if (!(op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO)) {
+		return 0;
+	}
+#else
+	if (!op_array->done_pass_two) {
+		return 0;
+	}
+#endif
+
+	opline = op_array->opcodes;
+	end = opline + op_array->last;
+	while (opline < end) {
+#ifdef ZEND_ENGINE_2_4
+		if (opline->op1_type == IS_CONST) {
+			opline->op1.constant = opline->op1.literal - op_array->literals;
+		}
+		if (opline->op2_type == IS_CONST) {
+			opline->op2.constant = opline->op2.literal - op_array->literals;
+		}
+#endif
+
+#ifdef ZEND_ENGINE_2_1
+		switch (opline->opcode) {
+#ifdef ZEND_GOTO
+			case ZEND_GOTO:
+#endif
+			case ZEND_JMP:
+				assert(Z_OP(opline->op1).jmp_addr >= op_array->opcodes && (zend_uint) (Z_OP(opline->op1).jmp_addr - op_array->opcodes) < op_array->last);
+				Z_OP(opline->op1).opline_num = Z_OP(opline->op1).jmp_addr - op_array->opcodes;
+				break;
+			case ZEND_JMPZ:
+			case ZEND_JMPNZ:
+			case ZEND_JMPZ_EX:
+			case ZEND_JMPNZ_EX:
+#ifdef ZEND_JMP_SET
+			case ZEND_JMP_SET:
+#endif
+#ifdef ZEND_JMP_SET_VAR
+			case ZEND_JMP_SET_VAR:
+#endif
+				assert(Z_OP(opline->op2).jmp_addr >= op_array->opcodes && (zend_uint) (Z_OP(opline->op2).jmp_addr - op_array->opcodes) < op_array->last);
+				Z_OP(opline->op2).opline_num = Z_OP(opline->op2).jmp_addr - op_array->opcodes;
+				break;
+		}
+#endif
+		opline++;
+	}
+#ifdef ZEND_ENGINE_2_4
+	op_array->fn_flags &= ~ZEND_ACC_DONE_PASS_TWO;
+#else
+	op_array->done_pass_two = 0;
+#endif
+
+	return 0;
+}
+/* }}} */
+int xc_redo_pass_two(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline, *end;
+#ifdef ZEND_ENGINE_2_4
+	zend_literal *literal = op_array->literals;
+#endif
+
+#ifdef ZEND_ENGINE_2_4
+	if ((op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO)) {
+		return 0;
+	}
+#else
+	if (op_array->done_pass_two) {
+		return 0;
+	}
+#endif
+
+	/*
+	op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last);
+	op_array->size = op_array->last;
+	*/
+#ifdef ZEND_ENGINE_2_4
+	if (literal) {
+		zend_literal *end = literal + op_array->last_literal;
+		while (literal < end) {
+			Z_SET_ISREF(literal->constant);
+			Z_SET_REFCOUNT(literal->constant, 2); /* Make sure is_ref won't be reset */
+			literal++;
+		}
+	}
+#endif
+
+	opline = op_array->opcodes;
+	end = opline + op_array->last;
+	while (opline < end) {
+#ifdef ZEND_ENGINE_2_4
+		if (opline->op1_type == IS_CONST) {
+			opline->op1.literal = op_array->literals + opline->op1.constant;
+		}
+		if (opline->op2_type == IS_CONST) {
+			opline->op2.literal = op_array->literals + opline->op2.constant;
+		}
+#else
+		if (Z_OP_TYPE(opline->op1) == IS_CONST) {
+			Z_SET_ISREF(Z_OP_CONSTANT(opline->op1));
+			Z_SET_REFCOUNT(Z_OP_CONSTANT(opline->op1), 2); /* Make sure is_ref won't be reset */
+		}
+		if (Z_OP_TYPE(opline->op2) == IS_CONST) {
+			Z_SET_ISREF(Z_OP_CONSTANT(opline->op2));
+			Z_SET_REFCOUNT(Z_OP_CONSTANT(opline->op2), 2);
+		}
+#endif
+#ifdef ZEND_ENGINE_2_1
+		switch (opline->opcode) {
+#ifdef ZEND_GOTO
+			case ZEND_GOTO:
+#endif
+			case ZEND_JMP:
+				assert(Z_OP(opline->op1).opline_num < op_array->last);
+				Z_OP(opline->op1).jmp_addr = op_array->opcodes + Z_OP(opline->op1).opline_num;
+				break;
+			case ZEND_JMPZ:
+			case ZEND_JMPNZ:
+			case ZEND_JMPZ_EX:
+			case ZEND_JMPNZ_EX:
+#ifdef ZEND_JMP_SET
+			case ZEND_JMP_SET:
+#endif
+				assert(Z_OP(opline->op2).opline_num < op_array->last);
+				Z_OP(opline->op2).jmp_addr = op_array->opcodes + Z_OP(opline->op2).opline_num;
+				break;
+		}
+		ZEND_VM_SET_OPCODE_HANDLER(opline);
+#endif
+		opline++;
+	}
+
+#ifdef ZEND_ENGINE_2_4
+	op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
+#else
+	op_array->done_pass_two = 1;
+#endif
+	return 0;
+}
+/* }}} */
+
+static void xc_fix_opcode_ex_znode(int tofix, xc_op_spec_t spec, Z_OP_TYPEOF_TYPE *op_type, znode_op *op, int type TSRMLS_DC) /* {{{ */
+{
+#ifdef ZEND_ENGINE_2
+	if ((*op_type != IS_UNUSED && (spec == OPSPEC_UCLASS || spec == OPSPEC_CLASS)) ||
+			spec == OPSPEC_FETCH) {
+		if (tofix) {
+			switch (*op_type) {
+			case IS_VAR:
+			case IS_TMP_VAR:
+				break;
+
+			default:
+				/* TODO: data lost, find a way to keep it */
+				/* assert(*op_type == IS_CONST); */
+				*op_type = IS_TMP_VAR;
+			}
+		}
+	}
+	switch (*op_type) {
+	case IS_TMP_VAR:
+	case IS_VAR:
+		if (tofix) {
+			Z_OP(*op).var /= sizeof(temp_variable);
+		}
+		else {
+			Z_OP(*op).var *= sizeof(temp_variable);
+		}
+	}
+#endif
+}
+/* }}} */
+
+static void xc_fix_opcode_ex(zend_op_array *op_array, int tofix TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline;
+	zend_uint i;
+
+	opline = op_array->opcodes;
+	for (i = 0; i < op_array->last; i ++, opline ++) {
+		/* 3rd optimizer may have ... */
+		if (opline->opcode < xc_get_opcode_spec_count()) {
+			const xc_opcode_spec_t *spec;
+			spec = xc_get_opcode_spec(opline->opcode);
+
+			xc_fix_opcode_ex_znode(tofix, spec->op1, &Z_OP_TYPE(opline->op1),    &opline->op1, 0 TSRMLS_CC);
+			xc_fix_opcode_ex_znode(tofix, spec->op2, &Z_OP_TYPE(opline->op2),    &opline->op2, 1 TSRMLS_CC);
+			xc_fix_opcode_ex_znode(tofix, spec->res, &Z_OP_TYPE(opline->result), &opline->result, 2 TSRMLS_CC);
+		}
+	}
+}
+/* }}} */
+int xc_fix_opcode(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	xc_fix_opcode_ex(op_array, 1 TSRMLS_CC);
+	return 0;
+}
+/* }}} */
+int xc_undo_fix_opcode(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	xc_fix_opcode_ex(op_array, 0 TSRMLS_CC);
+
+	return 0;
+}
+/* }}} */
+
+int xc_foreach_early_binding_class(zend_op_array *op_array, void (*callback)(zend_op *opline, int oplineno, void *data TSRMLS_DC), void *data TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline, *begin, *end, *next = NULL;
+
+	opline = begin = op_array->opcodes;
+	end = opline + op_array->last;
+	while (opline < end) {
+		switch (opline->opcode) {
+#ifdef ZEND_GOTO
+			case ZEND_GOTO:
+#endif
+			case ZEND_JMP:
+				next = begin + Z_OP(opline->op1).opline_num;
+				break;
+
+			case ZEND_JMPZNZ:
+				next = begin + max(Z_OP(opline->op2).opline_num, opline->extended_value);
+				break;
+
+			case ZEND_JMPZ:
+			case ZEND_JMPNZ:
+			case ZEND_JMPZ_EX:
+			case ZEND_JMPNZ_EX:
+#ifdef ZEND_JMP_SET
+			case ZEND_JMP_SET:
+#endif
+				next = begin + Z_OP(opline->op2).opline_num;
+				break;
+
+			case ZEND_RETURN:
+				opline = end;
+				break;
+
+#ifdef ZEND_ENGINE_2
+			case ZEND_DECLARE_INHERITED_CLASS:
+				callback(opline, opline - begin, data TSRMLS_CC);
+				break;
+#else
+			case ZEND_DECLARE_FUNCTION_OR_CLASS:
+				if (opline->extended_value == ZEND_DECLARE_INHERITED_CLASS) {
+					callback(opline, opline - begin, data TSRMLS_CC);
+				}
+				break;
+#endif
+		}
+
+		if (opline < next) {
+			opline = next;
+		}
+		else {
+			opline ++;
+		}
+	}
+	return SUCCESS;
+}
+/* }}} */
+#ifndef ZEND_COMPILE_DELAYED_BINDING
+static int xc_do_early_binding(zend_op_array *op_array, HashTable *class_table, int oplineno TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline;
+
+	TRACE("binding %d", oplineno);
+	assert(oplineno >= 0);
+
+	/* do early binding */
+	opline = &(op_array->opcodes[oplineno]);
+
+	switch (opline->opcode) {
+#ifdef ZEND_ENGINE_2
+	case ZEND_DECLARE_INHERITED_CLASS:
+		{
+			zval *parent_name;
+			zend_class_entry **pce;
+
+			/* don't early-bind classes that implement interfaces */
+			if ((opline + 1)->opcode == ZEND_FETCH_CLASS && (opline + 2)->opcode == ZEND_ADD_INTERFACE) {
+				return FAILURE;
+			}
+
+			parent_name = &(Z_OP_CONSTANT((opline - 1)->op2));
+			TRACE("binding with parent %s", Z_STRVAL_P(parent_name));
+			if (zend_lookup_class(Z_STRVAL_P(parent_name), Z_STRLEN_P(parent_name), &pce TSRMLS_CC) == FAILURE) {
+				return FAILURE;
+			}
+
+			if (do_bind_inherited_class(opline, class_table, *pce, 1 TSRMLS_CC) == NULL) {
+				return FAILURE;
+			}
+		}
+
+		/* clear unnecessary ZEND_FETCH_CLASS opcode */
+		if (opline > op_array->opcodes
+		 && (opline - 1)->opcode == ZEND_FETCH_CLASS) {
+			zend_op *fetch_class_opline = opline - 1;
+
+			TRACE("%s %p", Z_STRVAL(Z_OP_CONSTANT(fetch_class_opline->op2)), Z_STRVAL(Z_OP_CONSTANT(fetch_class_opline->op2)));
+			OP_ZVAL_DTOR(fetch_class_opline->op2);
+			fetch_class_opline->opcode = ZEND_NOP;
+			ZEND_VM_SET_OPCODE_HANDLER(fetch_class_opline);
+			memset(&fetch_class_opline->op1, 0, sizeof(znode));
+			memset(&fetch_class_opline->op2, 0, sizeof(znode));
+			SET_UNUSED(fetch_class_opline->op1);
+			SET_UNUSED(fetch_class_opline->op2);
+			SET_UNUSED(fetch_class_opline->result);
+		}
+
+		/* clear unnecessary ZEND_VERIFY_ABSTRACT_CLASS opcode */
+		if ((opline + 1)->opcode == ZEND_VERIFY_ABSTRACT_CLASS) {
+			zend_op *abstract_op = opline + 1;
+			memset(abstract_op, 0, sizeof(abstract_op[0]));
+			abstract_op->lineno = 0;
+			SET_UNUSED(abstract_op->op1);
+			SET_UNUSED(abstract_op->op2);
+			SET_UNUSED(abstract_op->result);
+			abstract_op->opcode = ZEND_NOP;
+			ZEND_VM_SET_OPCODE_HANDLER(abstract_op);
+		}
+#else
+	case ZEND_DECLARE_FUNCTION_OR_CLASS:
+		if (do_bind_function_or_class(opline, NULL, class_table, 1) == FAILURE) {
+			return FAILURE;
+		}
+#endif
+		break;
+
+	default:
+		return FAILURE;
+	}
+
+	zend_hash_del(class_table, Z_OP_CONSTANT(opline->op1).value.str.val, Z_OP_CONSTANT(opline->op1).value.str.len);
+	OP_ZVAL_DTOR(opline->op1);
+	OP_ZVAL_DTOR(opline->op2);
+	opline->opcode = ZEND_NOP;
+	ZEND_VM_SET_OPCODE_HANDLER(opline);
+	memset(&opline->op1, 0, sizeof(znode));
+	memset(&opline->op2, 0, sizeof(znode));
+	SET_UNUSED(opline->op1);
+	SET_UNUSED(opline->op2);
+	return SUCCESS;
+}
+/* }}} */
+#endif
+
+#ifdef HAVE_XCACHE_CONSTANT
+void xc_install_constant(ZEND_24(NOTHING, const) char *filename, zend_constant *constant, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC) /* {{{ */
+{
+	if (zend_u_hash_add(EG(zend_constants), type, key, len,
+				constant, sizeof(zend_constant),
+				NULL
+				) == FAILURE) {
+		CG(zend_lineno) = 0;
+#ifdef IS_UNICODE
+		zend_error(E_NOTICE, "Constant %R already defined", type, key);
+#else
+		zend_error(E_NOTICE, "Constant %s already defined", key);
+#endif
+		free(ZSTR_V(constant->name));
+		if (!(constant->flags & CONST_PERSISTENT)) {
+			zval_dtor(&constant->value);
+		}
+	}
+}
+/* }}} */
+#endif
+void xc_install_function(ZEND_24(NOTHING, const) char *filename, zend_function *func, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC) /* {{{ */
+{
+	zend_bool istmpkey;
+
+	if (func->type == ZEND_USER_FUNCTION) {
+#ifdef IS_UNICODE
+		istmpkey = (type == IS_STRING && ZSTR_S(key)[0] == 0) || ZSTR_U(key)[0] == 0;
+#else
+		istmpkey = ZSTR_S(key)[0] == 0;
+#endif
+		if (istmpkey) {
+			zend_u_hash_update(CG(function_table), type, key, len,
+						func, sizeof(zend_op_array),
+						NULL
+						);
+		}
+		else if (zend_u_hash_add(CG(function_table), type, key, len,
+					func, sizeof(zend_op_array),
+					NULL
+					) == FAILURE) {
+			CG(zend_lineno) = ZESW(func->op_array.opcodes[0].lineno, func->op_array.line_start);
+#ifdef IS_UNICODE
+			zend_error(E_ERROR, "Cannot redeclare %R()", type, key);
+#else
+			zend_error(E_ERROR, "Cannot redeclare %s()", key);
+#endif
+		}
+	}
+}
+/* }}} */
+ZESW(xc_cest_t *, void) xc_install_class(ZEND_24(NOTHING, const) char *filename, xc_cest_t *cest, int oplineno, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC) /* {{{ */
+{
+	zend_bool istmpkey;
+	zend_class_entry *cep = CestToCePtr(*cest);
+	ZESW(void *stored_ce_ptr, NOTHING);
+
+#ifdef IS_UNICODE
+	istmpkey = (type == IS_STRING && ZSTR_S(key)[0] == 0) || ZSTR_U(key)[0] == 0;
+#else
+	istmpkey = ZSTR_S(key)[0] == 0;
+#endif
+	if (istmpkey) {
+		zend_u_hash_quick_update(CG(class_table), type, key, len, h,
+					cest, sizeof(xc_cest_t),
+					ZESW(&stored_ce_ptr, NULL)
+					);
+#ifndef ZEND_COMPILE_DELAYED_BINDING
+		if (oplineno != -1) {
+			xc_do_early_binding(CG(active_op_array), CG(class_table), oplineno TSRMLS_CC);
+		}
+#endif
+	}
+	else if (zend_u_hash_quick_add(CG(class_table), type, key, len, h,
+				cest, sizeof(xc_cest_t),
+				ZESW(&stored_ce_ptr, NULL)
+				) == FAILURE) {
+		CG(zend_lineno) = ZESW(0, Z_CLASS_INFO(*cep).line_start);
+#ifdef IS_UNICODE
+		zend_error(E_ERROR, "Cannot redeclare class %R", type, cep->name);
+#else
+		zend_error(E_ERROR, "Cannot redeclare class %s", cep->name);
+#endif
+		assert(oplineno == -1);
+	}
+	ZESW(return (xc_cest_t *) stored_ce_ptr, NOTHING);
+}
+/* }}} */
+
+typedef struct { /* sandbox {{{ */
+	ZEND_24(NOTHING, const) char *filename;
+
+	HashTable orig_included_files;
+	HashTable *tmp_included_files;
+
+#ifdef HAVE_XCACHE_CONSTANT
+	HashTable *orig_zend_constants;
+	HashTable tmp_zend_constants;
+#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;
+#ifdef HAVE_XCACHE_CONSTANT
+	Bucket    *tmp_internal_constant_tail;
+#endif
+	Bucket    *tmp_internal_function_tail;
+	Bucket    *tmp_internal_class_tail;
+
+#ifdef XCACHE_ERROR_CACHING
+	int orig_user_error_handler_error_reporting;
+	zend_uint compilererror_cnt;
+	zend_uint compilererror_size;
+	xc_compilererror_t *compilererrors;
+#endif
+
+#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
+	zend_uint orig_compiler_options;
+#endif
+} xc_sandbox_t;
+
+#undef TG
+#undef OG
+#define TG(x) (sandbox->tmp_##x)
+#define OG(x) (sandbox->orig_##x)
+/* }}} */
+#ifdef XCACHE_ERROR_CACHING
+static void xc_sandbox_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) /* {{{ */
+{
+	xc_compilererror_t *compilererror;
+	xc_sandbox_t *sandbox;
+	TSRMLS_FETCH();
+
+	sandbox = (xc_sandbox_t *) XG(sandbox);
+	if (!sandbox) {
+		old_zend_error_cb(type, error_filename, error_lineno, format, args);
+		return;
+	}
+
+	switch (type) {
+#ifdef E_STRICT
+	case E_STRICT:
+#endif
+#ifdef E_DEPRECATED
+	case E_DEPRECATED:
+#endif
+		if (sandbox->compilererror_cnt <= sandbox->compilererror_size) {
+			if (sandbox->compilererror_size) {
+				sandbox->compilererror_size += 16;
+				sandbox->compilererrors = erealloc(sandbox->compilererrors, sandbox->compilererror_size * sizeof(sandbox->compilererrors));
+			}
+			else {
+				sandbox->compilererror_size = 16;
+				sandbox->compilererrors = emalloc(sandbox->compilererror_size * sizeof(sandbox->compilererrors));
+			}
+		}
+		compilererror = &sandbox->compilererrors[sandbox->compilererror_cnt++];
+		compilererror->type = type;
+		compilererror->lineno = error_lineno;
+		compilererror->error_len = vspprintf(&compilererror->error, 0, format, args);
+		break;
+
+	default: {
+		/* give up, and user handler is not supported in this case */
+		zend_uint i;
+		zend_uint old_lineno = CG(zend_lineno);
+
+		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
+			compilererror = &sandbox->compilererrors[i];
+			CG(zend_lineno) = compilererror->lineno;
+			call_old_zend_error_cb(compilererror->type, error_filename, error_lineno, "%s", compilererror->error);
+			efree(compilererror->error);
+		}
+		if (sandbox->compilererrors) {
+			efree(sandbox->compilererrors);
+			sandbox->compilererrors = NULL;
+		}
+		sandbox->compilererror_cnt  = 0;
+		sandbox->compilererror_size = 0;
+
+		CG(zend_lineno) = old_lineno;
+		old_zend_error_cb(type, error_filename, error_lineno, format, args);
+		break;
+	}
+	}
+}
+/* }}} */
+#endif
+#ifdef ZEND_ENGINE_2_1
+static zend_bool xc_auto_global_callback(ZEND_24(NOTHING, const) char *name, uint name_len TSRMLS_DC) /* {{{ */
+{
+	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
+
+void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker) /* {{{ */
+{
+	Bucket *p;
+	void *new_entry;
+	zend_bool setTargetPointer;
+
+	setTargetPointer = !target->pInternalPointer;
+	p = source->pListHead;
+	while (p) {
+		if (checker(p->pData)) {
+			if (setTargetPointer && source->pInternalPointer == p) {
+				target->pInternalPointer = NULL;
+			}
+			if (p->nKeyLength) {
+				zend_u_hash_quick_update(target, p->key.type, ZSTR(BUCKET_KEY_S(p)), p->nKeyLength, p->h, p->pData, size, &new_entry);
+			} else {
+				zend_hash_index_update(target, p->h, p->pData, size, &new_entry);
+			}
+			if (pCopyConstructor) {
+				pCopyConstructor(new_entry);
+			}
+		}
+		p = p->pListNext;
+	}
+	if (!target->pInternalPointer) {
+		target->pInternalPointer = target->pListHead;
+	}
+}
+/* }}} */
+#ifdef HAVE_XCACHE_CONSTANT
+static zend_bool xc_is_internal_zend_constant(zend_constant *c) /* {{{ */
+{
+	return (c->flags & CONST_PERSISTENT) ? 1 : 0;
+}
+/* }}} */
+void xc_zend_constant_ctor(zend_constant *c) /* {{{ */
+{
+	assert((c->flags & CONST_PERSISTENT));
+	ZSTR_U(c->name) = UNISW(zend_strndup, zend_ustrndup)(ZSTR_U(c->name), c->name_len - 1);
+}
+/* }}} */
+void xc_zend_constant_dtor(zend_constant *c) /* {{{ */
+{
+	free(ZSTR_V(c->name));
+}
+/* }}} */
+static void xc_free_zend_constant(zend_constant *c) /* {{{ */
+{
+	if (!(c->flags & CONST_PERSISTENT)) {
+		zval_dtor(&c->value);
+	}
+	free(ZSTR_V(c->name));
+}
+/* }}} */
+void xc_copy_internal_zend_constants(HashTable *target, HashTable *source) /* {{{ */
+{
+	zend_constant tmp_const;
+	xc_hash_copy_if(target, source, (copy_ctor_func_t) xc_zend_constant_ctor, (void *) &tmp_const, sizeof(zend_constant), (xc_if_func_t) xc_is_internal_zend_constant);
+}
+/* }}} */
+#endif
+
+static xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
+{
+	HashTable *h;
+
+	assert(sandbox);
+	memset(sandbox, 0, sizeof(sandbox[0]));
+
+	memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files)));
+
+#ifdef HAVE_XCACHE_CONSTANT
+	OG(zend_constants) = EG(zend_constants);
+	EG(zend_constants) = &TG(zend_constants);
+#endif
+
+	OG(function_table) = CG(function_table);
+	CG(function_table) = &TG(function_table);
+
+	OG(class_table) = CG(class_table);
+	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);
+#ifdef HAVE_XCACHE_CONSTANT
+	h = OG(zend_constants);
+	zend_hash_init_ex(&TG(zend_constants),  20, NULL, (dtor_func_t) xc_free_zend_constant, h->persistent, h->bApplyProtection);
+	xc_copy_internal_zend_constants(&TG(zend_constants), &XG(internal_constant_table));
+	TG(internal_constant_tail) = TG(zend_constants).pListTail;
+#endif
+	h = OG(function_table);
+	zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, h->persistent, h->bApplyProtection);
+	{
+		zend_function tmp_func;
+		zend_hash_copy(&TG(function_table), &XG(internal_function_table), NULL, (void *) &tmp_func, sizeof(tmp_func));
+	}
+	TG(internal_function_tail) = TG(function_table).pListTail;
+
+	h = OG(class_table);
+	zend_hash_init_ex(&TG(class_table),     16, NULL, ZEND_CLASS_DTOR, h->persistent, h->bApplyProtection);
+#if 0 && TODO
+	{
+		xc_cest_t tmp_cest;
+		zend_hash_copy(&TG(class_table), &XG(internal_class_table), NULL, (void *) &tmp_cest, sizeof(tmp_cest));
+	}
+#endif
+	TG(internal_class_tail) = TG(class_table).pListTail;
+
+#ifdef ZEND_ENGINE_2_1
+	/* shallow copy, don't destruct */
+	h = OG(auto_globals);
+	zend_hash_init_ex(&TG(auto_globals),     8, NULL,           NULL, h->persistent, h->bApplyProtection);
+	{
+		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;
+
+#ifdef XCACHE_ERROR_CACHING
+	sandbox->orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting);
+	EG(user_error_handler_error_reporting) = 0;
+
+	sandbox->compilererror_cnt  = 0;
+	sandbox->compilererror_size = 0;
+#endif
+
+#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
+	sandbox->orig_compiler_options = CG(compiler_options);
+	/* Using ZEND_COMPILE_IGNORE_INTERNAL_CLASSES for ZEND_FETCH_CLASS_RT_NS_CHECK
+	 */
+	CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES | ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_DELAYED_BINDING;
+#endif
+
+	XG(sandbox) = (void *) sandbox;
+	return sandbox;
+}
+/* }}} */
+#ifndef ZEND_COMPILE_DELAYED_BINDING
+static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) data;
+	xc_do_early_binding(CG(active_op_array), OG(class_table), oplineno TSRMLS_CC);
+}
+/* }}} */
+#endif
+static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
+{
+	zend_uint i;
+	Bucket *b;
+
+#ifdef HAVE_XCACHE_CONSTANT
+	for (b = TG(zend_constants).pListHead; b != NULL && b != TG(internal_constant_tail); b = b->pListNext) {
+		zend_constant *c = (zend_constant*) b->pData;
+		xc_free_zend_constant(c);
+	}
+
+	b = TG(internal_constant_tail) ? TG(internal_constant_tail)->pListNext : TG(zend_constants).pListHead;
+	/* install constants */
+	while (b != NULL) {
+		zend_constant *c = (zend_constant*) b->pData;
+		xc_install_constant(sandbox->filename, c,
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
+		b = b->pListNext;
+	}
+#endif
+
+	b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
+	/* install function */
+	while (b != NULL) {
+		zend_function *func = (zend_function*) b->pData;
+		xc_install_function(sandbox->filename, func,
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
+		b = b->pListNext;
+	}
+
+	b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
+	/* install class */
+	while (b != NULL) {
+		xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, -1,
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h 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
+
+#ifdef ZEND_COMPILE_DELAYED_BINDING
+	zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC);
+#else
+	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);
+#endif
+
+#ifdef XCACHE_ERROR_CACHING
+	/* restore trigger errors */
+	for (i = 0; i < sandbox->compilererror_cnt; i ++) {
+		xc_compilererror_t *error = &sandbox->compilererrors[i];
+		CG(zend_lineno) = error->lineno;
+		zend_error(error->type, "%s", error->error);
+	}
+	CG(zend_lineno) = 0;
+#endif
+
+	i = 1;
+	/* still needed because in zend_language_scanner.l, require()/include() check file_handle.handle.stream.handle */
+	zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL);
+}
+/* }}} */
+static void xc_sandbox_free(xc_sandbox_t *sandbox, zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	XG(sandbox) = NULL;
+#ifdef XCACHE_ERROR_CACHING
+	EG(user_error_handler_error_reporting) = sandbox->orig_user_error_handler_error_reporting;
+#endif
+
+	/* restore first first install function/class */
+#ifdef HAVE_XCACHE_CONSTANT
+	EG(zend_constants) = OG(zend_constants);
+#endif
+	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 (op_array) {
+		zend_op_array *old_active_op_array = CG(active_op_array);
+		CG(in_compilation)    = 1;
+		CG(compiled_filename) = ZEND_24(NOTHING, (char *)) sandbox->filename;
+		CG(zend_lineno)       = 0;
+
+		CG(active_op_array) = op_array;
+		xc_sandbox_install(sandbox TSRMLS_CC);
+		CG(active_op_array) = old_active_op_array;
+
+		CG(in_compilation)    = 0;
+		CG(compiled_filename) = NULL;
+
+		/* no free as it's installed */
+#ifdef HAVE_XCACHE_CONSTANT
+		TG(zend_constants).pDestructor = NULL;
+#endif
+		TG(function_table).pDestructor = NULL;
+		TG(class_table).pDestructor = NULL;
+	}
+
+	/* destroy all the tmp */
+#ifdef HAVE_XCACHE_CONSTANT
+	zend_hash_destroy(&TG(zend_constants));
+#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 */
+	memcpy(&EG(included_files), &OG(included_files), sizeof(EG(included_files)));
+
+#ifdef XCACHE_ERROR_CACHING
+	if (sandbox->compilererrors) {
+		zend_uint i;
+		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
+			efree(sandbox->compilererrors[i].error);
+		}
+		efree(sandbox->compilererrors);
+	}
+#endif
+
+#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
+	CG(compiler_options) = sandbox->orig_compiler_options;
+#endif
+}
+/* }}} */
+zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
+{
+	xc_sandbox_t sandbox;
+	zend_op_array *op_array = NULL;
+	zend_bool catched = 0;
+
+	memset(&sandbox, 0, sizeof(sandbox));
+	zend_try {
+		xc_sandbox_init(&sandbox, filename TSRMLS_CC);
+		op_array = sandboxed_func(data TSRMLS_CC);
+	} zend_catch {
+		catched = 1;
+	} zend_end_try();
+
+	xc_sandbox_free(&sandbox, op_array TSRMLS_CC);
+	if (catched) {
+		zend_bailout();
+	}
+	return op_array;
+}
+/* {{{ */
+const Bucket *xc_sandbox_user_function_begin(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
+}
+/* {{{ */
+const Bucket *xc_sandbox_user_class_begin(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
+}
+/* {{{ */
+#ifdef XCACHE_ERROR_CACHING
+xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return sandbox->compilererrors;
+}
+/* }}} */
+zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return sandbox->compilererror_cnt;
+}
+/* }}} */
+#endif
+
+int xc_vtrace(const char *fmt, va_list args) /* {{{ */
+{
+	return vfprintf(stderr, fmt, args);
+}
+/* }}} */
+int xc_trace(const char *fmt, ...) /* {{{ */
+{
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	ret = xc_vtrace(fmt, args);
+	va_end(args);
+	return ret;
+}
+/* }}} */
+
+#ifndef ZEND_ENGINE_2_3
+#include "ext/standard/php_string.h"
+size_t xc_dirname(char *path, size_t len) /* {{{ */
+{
+#ifdef ZEND_ENGINE_2
+	return php_dirname(path, len);
+#else
+	php_dirname(path, len);
+	return strlen(path);
+#endif
+}
+/* }}} */
+
+long xc_atol(const char *str, int str_len) /* {{{ */
+{
+	long retval;
+
+	if (!str_len) {
+		str_len = strlen(str);
+	}
+
+	retval = strtol(str, NULL, 0);
+	if (str_len > 0) {
+		switch (str[str_len - 1]) {
+		case 'g':
+		case 'G':
+			retval *= 1024;
+			/* break intentionally missing */
+		case 'm':
+		case 'M':
+			retval *= 1024;
+			/* break intentionally missing */
+		case 'k':
+		case 'K':
+			retval *= 1024;
+			break;
+		}
+	}
+
+	return retval;
+}
+/* }}} */
+
+#endif
+
+/* init/destroy */
+int xc_util_init(int module_number TSRMLS_DC) /* {{{ */
+{
+#ifdef XCACHE_ERROR_CACHING
+	old_zend_error_cb = zend_error_cb;
+	zend_error_cb = xc_sandbox_error_cb;
+#endif
+
+	return SUCCESS;
+}
+/* }}} */
+void xc_util_destroy() /* {{{ */
+{
+#ifdef XCACHE_ERROR_CACHING
+	if (zend_error_cb == xc_sandbox_error_cb) {
+		zend_error_cb = old_zend_error_cb;
+	}
+#endif
+}
+/* }}} */
+
Index: /trunk/main/xc_utils.h
===================================================================
--- /trunk/main/xc_utils.h	(revision 982)
+++ /trunk/main/xc_utils.h	(revision 982)
@@ -0,0 +1,70 @@
+#include "php.h"
+#include "xcache.h"
+
+int xc_util_init(int module_number TSRMLS_DC);
+void xc_util_destroy();
+
+typedef struct {
+	zend_op_array *op_array;
+	HashTable *function_table;
+	HashTable *class_table;
+} xc_compile_result_t;
+
+xc_compile_result_t *xc_compile_result_init(xc_compile_result_t *cr,
+		zend_op_array *op_array,
+		HashTable *function_table,
+		HashTable *class_table);
+void xc_compile_result_free(xc_compile_result_t *cr);
+xc_compile_result_t *xc_compile_result_init_cur(xc_compile_result_t *cr, zend_op_array *op_array TSRMLS_DC);
+/* apply func */
+int xc_apply_function(zend_function *zf, apply_func_t applyer TSRMLS_DC);
+int xc_apply_class(zend_class_entry *ce, apply_func_t applyer TSRMLS_DC);
+int xc_apply_op_array(xc_compile_result_t *cr, apply_func_t applyer TSRMLS_DC);
+
+int xc_undo_pass_two(zend_op_array *op_array TSRMLS_DC);
+int xc_redo_pass_two(zend_op_array *op_array TSRMLS_DC);
+int xc_fix_opcode(zend_op_array *op_array TSRMLS_DC);
+int xc_undo_fix_opcode(zend_op_array *op_array TSRMLS_DC);
+zend_uchar xc_get_fixed_opcode(zend_uchar opcode, int line);
+
+int xc_foreach_early_binding_class(zend_op_array *op_array, void (*callback)(zend_op *opline, int oplineno, void *data TSRMLS_DC), void *data TSRMLS_DC);
+
+/* installer */
+#ifdef HAVE_XCACHE_CONSTANT
+void xc_install_constant(ZEND_24(NOTHING, const) char *filename, zend_constant *constant, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC);
+#endif
+void xc_install_function(ZEND_24(NOTHING, const) char *filename, zend_function *func, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC);
+ZESW(xc_cest_t *, void) xc_install_class(ZEND_24(NOTHING, const) char *filename, xc_cest_t *cest, int oplineno, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC);
+
+#if defined(E_STRICT) || defined(E_DEPRECATED)
+#define XCACHE_ERROR_CACHING
+#endif
+
+/* return op_array to install */
+typedef zend_op_array *(*xc_sandboxed_func_t)(void *data TSRMLS_DC);
+zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC);
+const Bucket *xc_sandbox_user_function_begin(TSRMLS_D);
+const Bucket *xc_sandbox_user_class_begin(TSRMLS_D);
+zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
+#ifdef XCACHE_ERROR_CACHING
+xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D);
+zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
+#endif
+
+void xc_zend_class_add_ref(zend_class_entry ZESW(*ce, **ce));
+
+typedef zend_bool (*xc_if_func_t)(void *data);
+
+void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker);
+#ifdef HAVE_XCACHE_CONSTANT
+void xc_zend_constant_ctor(zend_constant *c);
+void xc_zend_constant_dtor(zend_constant *c);
+void xc_copy_internal_zend_constants(HashTable *target, HashTable *source);
+#endif
+
+#ifndef ZEND_ENGINE_2_3
+size_t xc_dirname(char *path, size_t len);
+#define zend_dirname xc_dirname
+long xc_atol(const char *str, int len);
+#define zend_atol xc_atol
+#endif
Index: unk/mem.c
===================================================================
--- /trunk/mem.c	(revision 981)
+++ 	(revision )
@@ -1,406 +1,0 @@
-#ifdef TEST
-#include <limits.h>
-#include <stdio.h>
-#	define XCACHE_DEBUG
-#else
-#include <php.h>
-#endif
-
-#ifdef XCACHE_DEBUG
-#	define ALLOC_DEBUG_BLOCK_CHECK
-#endif
-
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#define XC_MEMBLOCK_IMPL _xc_mem_block_t
-#define XC_MEM_IMPL _xc_mem_mem_t
-#include "xc_shm.h"
-#include "align.h"
-#include "utils.h"
-
-#if 0
-#undef ALLOC_DEBUG_BLOCK_CHECK
-#endif
-
-#define CHAR_PTR(p) ((char *) (p))
-#define PADD(p, a) (CHAR_PTR(p) + a)
-#define PSUB(p1, p2) (CHAR_PTR(p1) - CHAR_PTR(p2))
-
-/* {{{ mem */
-struct _xc_mem_block_t {
-#ifdef ALLOC_DEBUG_BLOCK_CHECK
-	unsigned int magic;
-#endif
-	xc_memsize_t size; /* reserved even after alloc */
-	xc_block_t *next;  /* not used after alloc */
-};
-
-struct _xc_mem_mem_t {
-	const xc_mem_handlers_t *handlers;
-	xc_shm_t                *shm;
-	xc_memsize_t size;
-	xc_memsize_t avail;       /* total free */
-	xc_block_t headblock[1];  /* just as a pointer to first block*/
-};
-
-#ifndef XtOffsetOf
-#	include <linux/stddef.h>
-#	define XtOffsetOf(s_type, field) offsetof(s_type, field)
-#endif
-
-#define SizeOf(type, field) sizeof( ((type *) 0)->field )
-#define BLOCK_HEADER_SIZE() (ALIGN( XtOffsetOf(xc_block_t, size) + SizeOf(xc_block_t, size) ))
-
-#define BLOCK_MAGIC ((unsigned int) 0x87655678)
-
-/* }}} */
-static inline void xc_block_setup(xc_block_t *b, xc_memsize_t size, xc_block_t *next) /* {{{ */
-{
-#ifdef ALLOC_DEBUG_BLOCK_CHECK
-	b->magic = BLOCK_MAGIC;
-#endif
-	b->size = size;
-	b->next = next;
-}
-/* }}} */
-#ifdef ALLOC_DEBUG_BLOCK_CHECK
-static void xc_block_check(xc_block_t *b) /* {{{ */
-{
-	if (b->magic != BLOCK_MAGIC) {
-		fprintf(stderr, "0x%X != 0x%X magic wrong \n", b->magic, BLOCK_MAGIC);
-	}
-}
-/* }}} */
-#else
-#	define xc_block_check(b) do { } while(0)
-#endif
-
-
-static XC_MEM_MALLOC(xc_mem_malloc) /* {{{ */
-{
-	xc_block_t *prev, *cur;
-	xc_block_t *newb, *b;
-	xc_memsize_t realsize;
-	xc_memsize_t minsize;
-	void *p;
-	/* [xc_block_t:size|size] */
-	realsize = BLOCK_HEADER_SIZE() + size;
-	/* realsize is ALIGNed so next block start at ALIGNed address */
-	realsize = ALIGN(realsize);
-
-	TRACE("avail: %lu (%luKB). Allocate size: %lu realsize: %lu (%luKB)"
-			, mem->avail, mem->avail / 1024
-			, size
-			, realsize, realsize / 1024
-			);
-	do {
-		p = NULL;
-		if (mem->avail < realsize) {
-			TRACE("%s", " oom");
-			break;
-		}
-
-		b = NULL;
-		minsize = ULONG_MAX;
-
-		/* prev|cur */
-
-		for (prev = mem->headblock; prev->next; prev = cur) {
-			/* while (prev->next != 0) { */
-			cur = prev->next;
-			xc_block_check(cur);
-			if (cur->size == realsize) {
-				/* found a perfect fit, stop searching */
-				b = prev;
-				break;
-			}
-			/* make sure we can split on the block */
-			else if (cur->size > (sizeof(xc_block_t) + realsize) &&
-					cur->size < minsize) {
-				/* cur is acceptable and memller */
-				b = prev;
-				minsize = cur->size;
-			}
-			prev = cur;
-		}
-
-		if (b == NULL) {
-			TRACE("%s", " no fit chunk");
-			break;
-		}
-
-		prev = b;
-
-		cur = prev->next;
-		p = PADD(cur, BLOCK_HEADER_SIZE());
-
-		/* update the block header */
-		mem->avail -= realsize;
-
-		/* perfect fit, just unlink */
-		if (cur->size == realsize) {
-			prev->next = cur->next;
-			TRACE(" perfect fit. Got: %p", p);
-			break;
-		}
-
-		/* make new free block after alloced space */
-
-		/* save, as it might be overwrited by newb (cur->size is ok) */
-		b = cur->next;
-
-		/* prev|cur     |next=b */
-
-		newb = (xc_block_t *)PADD(cur, realsize);
-		xc_block_setup(newb, cur->size - realsize, b);
-		cur->size = realsize;
-		/* prev|cur|newb|next
-		 *            `--^
-		 */
-
-		TRACE(" -> avail: %lu (%luKB). new next: %p offset: %lu %luKB. Got: %p"
-				, mem->avail, mem->avail / 1024
-				, newb
-				, PSUB(newb, mem), PSUB(newb, mem) / 1024
-				, p
-				);
-		prev->next = newb;
-		/* prev|cur|newb|next
-		 *    `-----^
-		 */
-
-	} while (0);
-
-	return p;
-}
-/* }}} */
-static XC_MEM_FREE(xc_mem_free) /* {{{ return block size freed */
-{
-	xc_block_t *cur, *b;
-	int size;
-
-	cur = (xc_block_t *) (CHAR_PTR(p) - BLOCK_HEADER_SIZE());
-	TRACE("freeing: %p, size=%lu", p, cur->size);
-	xc_block_check(cur);
-	assert((char*)mem < (char*)cur && (char*)cur < (char*)mem + mem->size);
-
-	/* find free block right before the p */
-	b = mem->headblock;
-	while (b->next != 0 && b->next < cur) {
-		b = b->next;
-	}
-
-	/* restore block */
-	cur->next = b->next;
-	b->next = cur;
-	size = cur->size;
-
-	TRACE(" avail %lu (%luKB)", mem->avail, mem->avail / 1024);
-	mem->avail += size;
-
-	/* combine prev|cur */
-	if (PADD(b, b->size) == (char *)cur) {
-		b->size += cur->size;
-		b->next = cur->next;
-		cur = b;
-		TRACE("%s", " combine prev");
-	}
-
-	/* combine cur|next */
-	b = cur->next;
-	if (PADD(cur, cur->size) == (char *)b) {
-		cur->size += b->size;
-		cur->next = b->next;
-		TRACE("%s", " combine next");
-	}
-	TRACE(" -> avail %lu (%luKB)", mem->avail, mem->avail / 1024);
-	return size;
-}
-/* }}} */
-static XC_MEM_CALLOC(xc_mem_calloc) /* {{{ */
-{
-	xc_memsize_t realsize = memb * size;
-	void *p = xc_mem_malloc(mem, realsize);
-
-	if (p) {
-		memset(p, 0, realsize);
-	}
-	return p;
-}
-/* }}} */
-static XC_MEM_REALLOC(xc_mem_realloc) /* {{{ */
-{
-	void *newp = xc_mem_malloc(mem, size);
-	if (p && newp) {
-		memcpy(newp, p, size);
-		xc_mem_free(mem, p);
-	}
-	return newp;
-}
-/* }}} */
-static XC_MEM_STRNDUP(xc_mem_strndup) /* {{{ */
-{
-	void *p = xc_mem_malloc(mem, len + 1);
-	if (p) {
-		memcpy(p, str, len + 1);
-	}
-	return p;
-}
-/* }}} */
-static XC_MEM_STRDUP(xc_mem_strdup) /* {{{ */
-{
-	return xc_mem_strndup(mem, str, strlen(str));
-}
-/* }}} */
-
-static XC_MEM_AVAIL(xc_mem_avail) /* {{{ */
-{
-	return mem->avail;
-}
-/* }}} */
-static XC_MEM_SIZE(xc_mem_size) /* {{{ */
-{
-	return mem->size;
-}
-/* }}} */
-
-static XC_MEM_FREEBLOCK_FIRST(xc_mem_freeblock_first) /* {{{ */
-{
-	return mem->headblock->next;
-}
-/* }}} */
-XC_MEM_FREEBLOCK_NEXT(xc_mem_freeblock_next) /* {{{ */
-{
-	return block->next;
-}
-/* }}} */
-XC_MEM_BLOCK_SIZE(xc_mem_block_size) /* {{{ */
-{
-	return block->size;
-}
-/* }}} */
-XC_MEM_BLOCK_OFFSET(xc_mem_block_offset) /* {{{ */
-{
-	return ((char *) block) - ((char *) mem);
-}
-/* }}} */
-
-static XC_MEM_INIT(xc_mem_init) /* {{{ */
-{
-	xc_block_t *b;
-#define MINSIZE (ALIGN(sizeof(xc_mem_t)) + sizeof(xc_block_t))
-	/* requires at least the header and 1 tail block */
-	if (size < MINSIZE) {
-		fprintf(stderr, "xc_mem_init requires %lu bytes at least\n", (unsigned long) MINSIZE);
-		return NULL;
-	}
-	TRACE("size=%lu", size);
-	mem->shm = shm;
-	mem->size = size;
-	mem->avail = size - MINSIZE;
-
-	/* pointer to first block, right after ALIGNed header */
-	b = mem->headblock;
-	xc_block_setup(b, 0, (xc_block_t *) PADD(mem, ALIGN(sizeof(xc_mem_t))));
-
-	/* first block*/
-	b = b->next;
-	xc_block_setup(b, mem->avail, 0);
-#undef MINSIZE
-
-	return mem;
-}
-/* }}} */
-static XC_MEM_DESTROY(xc_mem_destroy) /* {{{ */
-{
-}
-/* }}} */
-
-#ifdef TEST
-/* {{{ */
-#undef CHECK
-#define CHECK(a, msg) do { if ((a) == NULL) { puts(msg); return -1; } } while (0)
-#include <time.h>
-
-int main()
-{
-	int count = 0;
-	void *p;
-	void *memory;
-	xc_mem_t *mem;
-	void **ptrs;
-	int size, i;
-
-#if 0
-	fprintf(stderr, "%s", "Input test size: ");
-	scanf("%d", &size);
-#else
-	size = 100;
-#endif
-	CHECK(memory = malloc(size), "OOM");
-	CHECK(ptrs   = malloc(size * sizeof(void*)), "OOM");
-	CHECK(mem    = xc_mem_init(memory, size), "Failed init memory allocator");
-
-	while ((p = xc_mem_malloc(mem, 1))) {
-		ptrs[count ++] = p;
-	}
-	fprintf(stderr, "count=%d, random freeing\n", count);
-	srandom(time(NULL));
-	while (count) {
-		i = (random() % count);
-		fprintf(stderr, "freeing %d: ", i);
-		xc_mem_free(mem, ptrs[i]);
-		ptrs[i] = ptrs[count - 1];
-		count --;
-	}
-
-	free(ptrs);
-	free(memory);
-	return 0;
-}
-/* }}} */
-#endif
-
-typedef struct {
-	const char              *name;
-	const xc_mem_handlers_t *handlers;
-} xc_mem_scheme_t;
-static xc_mem_scheme_t xc_mem_schemes[10];
-
-int xc_mem_scheme_register(const char *name, const xc_mem_handlers_t *handlers) /* {{{ */
-{
-	int i;
-	for (i = 0; i < 10; i ++) {
-		if (!xc_mem_schemes[i].name) {
-			xc_mem_schemes[i].name = name;
-			xc_mem_schemes[i].handlers = handlers;
-			return 1;
-		}
-	}
-	return 0;
-}
-/* }}} */
-const xc_mem_handlers_t *xc_mem_scheme_find(const char *name) /* {{{ */
-{
-	int i;
-	for (i = 0; i < 10 && xc_mem_schemes[i].name; i ++) {
-		if (strcmp(xc_mem_schemes[i].name, name) == 0) {
-			return xc_mem_schemes[i].handlers;
-		}
-	}
-	return NULL;
-}
-/* }}} */
-
-static xc_mem_handlers_t xc_mem_mem_handlers = XC_MEM_HANDLERS(mem);
-void xc_shm_mem_init() /* {{{ */
-{
-	memset(xc_mem_schemes, 0, sizeof(xc_mem_schemes));
-
-	if (xc_mem_scheme_register("mem", &xc_mem_mem_handlers) == 0) {
-		zend_error(E_ERROR, "XCache: failed to register mem mem_scheme");
-	}
-}
-/* }}} */
Index: unk/mem.h
===================================================================
--- /trunk/mem.h	(revision 981)
+++ 	(revision )
@@ -1,74 +1,0 @@
-#include "xc_shm.h"
-
-typedef struct _xc_mem_handlers_t xc_mem_handlers_t;
-
-#ifndef XC_MEM_IMPL
-struct _xc_mem_t {
-	const xc_mem_handlers_t *handlers;
-	xc_shm_t                *shm;
-};
-#   define XC_MEM_IMPL _xc_mem_t
-#endif
-
-#ifndef XC_MEMBLOCK_IMPL
-#   define XC_MEMBLOCK_IMPL _xc_block_t
-#endif
-typedef struct XC_MEM_IMPL xc_mem_t;
-typedef struct XC_MEMBLOCK_IMPL xc_block_t;
-typedef xc_shmsize_t xc_memsize_t;
-
-/* shm::mem */
-#define XC_MEM_MALLOC(func)          void *func(xc_mem_t *mem, xc_memsize_t size)
-#define XC_MEM_FREE(func)            xc_memsize_t  func(xc_mem_t *mem, const void *p)
-#define XC_MEM_CALLOC(func)          void *func(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size)
-#define XC_MEM_REALLOC(func)         void *func(xc_mem_t *mem, const void *p, xc_memsize_t size)
-#define XC_MEM_STRNDUP(func)         char *func(xc_mem_t *mem, const char *str, xc_memsize_t len)
-#define XC_MEM_STRDUP(func)          char *func(xc_mem_t *mem, const char *str)
-#define XC_MEM_AVAIL(func)           xc_memsize_t      func(xc_mem_t *mem)
-#define XC_MEM_SIZE(func)            xc_memsize_t      func(xc_mem_t *mem)
-#define XC_MEM_FREEBLOCK_FIRST(func) const xc_block_t *func(xc_mem_t *mem)
-#define XC_MEM_FREEBLOCK_NEXT(func)  const xc_block_t *func(const xc_block_t *block)
-#define XC_MEM_BLOCK_SIZE(func)      xc_memsize_t      func(const xc_block_t *block)
-#define XC_MEM_BLOCK_OFFSET(func)    xc_memsize_t      func(const xc_mem_t *mem, const xc_block_t *block)
-
-#define XC_MEM_INIT(func)            xc_mem_t *func(xc_shm_t *shm, xc_mem_t *mem, xc_memsize_t size)
-#define XC_MEM_DESTROY(func)         void func(xc_mem_t *mem)
-
-#define XC_MEM_HANDLERS(name)   {  \
-	xc_##name##_malloc             \
-	, xc_##name##_free             \
-	, xc_##name##_calloc           \
-	, xc_##name##_realloc          \
-	, xc_##name##_strndup          \
-	, xc_##name##_strdup           \
-	, xc_##name##_avail            \
-	, xc_##name##_size             \
-	, xc_##name##_freeblock_first  \
-	, xc_##name##_freeblock_next   \
-	, xc_##name##_block_size       \
-	, xc_##name##_block_offset     \
-\
-	, xc_##name##_init             \
-	, xc_##name##_destroy          \
-}
-
-struct _xc_mem_handlers_t {
-	XC_MEM_MALLOC((*malloc));
-	XC_MEM_FREE((*free));
-	XC_MEM_CALLOC((*calloc));
-	XC_MEM_REALLOC((*realloc));
-	XC_MEM_STRNDUP((*strndup));
-	XC_MEM_STRDUP((*strdup));
-	XC_MEM_AVAIL((*avail));
-	XC_MEM_SIZE((*size));
-	XC_MEM_FREEBLOCK_FIRST((*freeblock_first));
-	XC_MEM_FREEBLOCK_NEXT((*freeblock_next));
-	XC_MEM_BLOCK_SIZE((*block_size));
-	XC_MEM_BLOCK_OFFSET((*block_offset));
-
-	XC_MEM_INIT((*init));
-	XC_MEM_DESTROY((*destroy));
-};
-
-int xc_mem_scheme_register(const char *name, const xc_mem_handlers_t *handlers);
-const xc_mem_handlers_t *xc_mem_scheme_find(const char *name);
Index: unk/mkopcode.awk
===================================================================
--- /trunk/mkopcode.awk	(revision 981)
+++ 	(revision )
@@ -1,77 +1,0 @@
-#! /usr/bin/awk -f
-# vim:ts=4:sw=4
-# process zend_vm_def.h or zend_compile.h
-BEGIN {
-	FS=" "
-	max = 0;
-}
-
-/^ZEND_VM_HANDLER\(/ {
-	# regex from php5.1+/Zend/zend_vm_gen.php
-	gsub(/ +/, "");
-	if (!match($0, /^ZEND_VM_HANDLER\(([0-9]+),([A-Z_]+),([A-Z|]+),([A-Z|]+)\)/)) {
-		print "error unmatch $0";
-		exit;
-	}
-	# life is hard without 3rd argument of match()
-	sub(/^ZEND_VM_HANDLER\(/, "");
-	id = $0;
-	sub(/,.*/, "", id); # chop
-	id = 0 + id;
-	sub(/^([0-9]+),/, "");
-	sub(/,.*/, ""); # chop
-	name = $0;
-	if (max < id) {
-		max = id;
-	}
-	opcodes[id] = name;
-	next;
-}
-
-/^#define +ZEND_[A-Z_]+[\t ]+[[:digit:]]+$/ {
-	id = 0 + $3;
-	name = $2;
-	if (max < id) {
-		max = id;
-	}
-	opcodes[id] = name;
-	next;
-}
-
-/end of block/ {
-	exit;
-}
-
-END {
-	mymax = 112;
-	if (max < mymax) {
-		for (i = max + 1; i <= mymax; i ++) {
-			opcodes[i] = "UNDEF";
-		}
-		max = mymax;
-		opcodes[110] = "ZEND_DO_FCALL_BY_FUNC";
-		opcodes[111] = "ZEND_INIT_FCALL_BY_FUNC";
-		opcodes[112] = "UNDEF";
-	}
-	printf "/* size = %d */\n", max + 1;
-	print "static const char *const xc_opcode_names[] = {";
-	for (i = 0; i <= max; i ++) {
-		if (i != 0) {
-			print ",";
-		}
-		printf "/* %d */\t", i
-		if (i in opcodes) {
-			name = opcodes[i];
-			sub(/^ZEND_/, "", name);
-			printf "\"%s\"", name;
-		}
-		else if (i == 137) {
-			printf "\"%s\"", "OP_DATA";
-		}
-		else {
-			printf "\"UNDEF\"";
-		}
-	}
-	print "";
-	print "};";
-}
Index: unk/mkopcode_spec.awk
===================================================================
--- /trunk/mkopcode_spec.awk	(revision 981)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#! /usr/bin/awk -f
-# vim:ts=4:sw=4
-# process eaccelerator/opcodes.c
-BEGIN {
-	FS=" "
-	max = 0;
-	started = 0
-}
-
-/OPDEF/ {
-	if (started) {
-		name = "";
-		if (match($0, /"([^"]+)"/, m)) { 
-			name = m[1]; 
-		} 
-		sub(/"[^"]*"/, "");
-		if (!match($0, /EXT_([^ |]+).*OP[1S]_([^ |]+).*OP2_([^ |]+).*RES_([^ |)]+).*/, array)) {
-			print "error" $0
-			exit
-		}
-		id = "";
-		if (match($0, /\/\* *([0-9]+) *\*\//, comments)) {
-			id = comments[1];
-		}
-		printf "\tOPSPEC(%10s, %10s, %10s, %10s) /* %s %-30s */\n", array[1], array[2], array[3], array[4], id, name;
-		next
-	}
-}
-/^}/ {
-	print $0
-	exit;
-}
-/^[ ]*,[ ]*$/ {
-	next
-}
-{
-	if (started) {
-		print $0
-		next
-	}
-}
-
-/^static/ {
-	started = 1;
-	print "static const xc_opcode_spec_t xc_opcode_spec[] = {"
-}
Index: unk/mkstructinfo.awk
===================================================================
--- /trunk/mkstructinfo.awk	(revision 981)
+++ 	(revision )
@@ -1,212 +1,0 @@
-#! /usr/bin/awk -f
-# vim:ts=4:sw=4
-BEGIN {
-	brace = 0;
-	incomment = 0;
-	buffer_len = 0;
-}
-function printstruct(structname) {
-	printf "define(`ELEMENTSOF_%s', `%s')\n", structname, ELEMENTSOF[structname];
-	printf "define(`COUNTOF_%s', `%s')\n", structname, COUNTOF[structname];
-	printf "define(`SIZEOF_%s', `(  %s  )')\n", structname, SIZEOF[structname];
-}
-function countBrace(text,  len, i, char, braceCount) {
-	len = length(text);
-	braceCount = 0;
-	for (i = 1; i <= len; ++i) {
-		char = substr(text, i, 1);
-		if (char == "{") {
-			braceCount = braceCount + 1;
-		}
-		else if (char == "}") {
-			braceCount = braceCount - 1;
-		}
-	}
-	return braceCount;
-}
-
-# multiline comment handling
-{
-	# removes one line comment
-	gsub(/\/\*(.+?)\*\//, " ");
-}
-/\*\// {
-	if (incomment) {
-		sub(/.*\*\//, "");
-		incomment = 0;
-	}
-}
-incomment {
-	next;
-}
-/\/\*/ {
-	sub(/\/\*.*/, "");
-	incomment = 1;
-	# fall through
-}
-
-# skip file/line mark here to be faster
-/^#/ {
-	next;
-}
-
-/^}.*;/ {
-	if (instruct) {
-		sub(";", "");
-		structname = instruct;
-		if (structname == 1 && $2) {
-			structname = $2;
-		}
-		if (structname in typedefs) {
-			structname = typedefs[structname];
-		}
-		sizeinfo = "";
-		elms = "";
-		for (i = 0; i in buffer; i ++) {
-			if (i) {
-				sizeinfo = sizeinfo " + ";
-			}
-			sizeinfo = sizeinfo "sizeof(((" structname "*)NULL)->" buffer[i] ")";
-
-			if (i == 0) {
-				elms = "\"" buffer[i] "\"";
-			}
-			else {
-				elms = elms "," "\"" buffer[i] "\"";
-			}
-		}
-		ELEMENTSOF[structname] = elms;
-		COUNTOF[structname]    = i;
-		SIZEOF[structname]     = sizeinfo;
-		printstruct(structname);
-		print "\n";
-		for (i in buffer) {
-			delete buffer[i];
-		}
-		buffer_len = 0;
-		instruct = 0;
-	}
-	next;
-}
-
-/.[{}]/ {
-	brace += countBrace($0);
-}
-
-{
-	if (brace == 1 && instruct) {
-		gsub(/(^[\t ]+|[\t ]+$)/, ""); # trim whitespaces
-		sub(/.*[{}]/, "");
-		gsub(/\[[^\]]+\]/, ""); # ignore [...]
-		gsub(/:[0-9]+/, ""); # ignore struct bit
-		if (match($0, /^[^(]*\([ ]*\*([^)]+)\)/)) {
-			sub(/ +/, "")
-			sub(/^[^(]*\(\*/, "");
-			sub(/\).*/, "");
-			# function pointer
-			buffer[buffer_len] = $0;
-			buffer_len ++;
-		}
-		else {
-			# process normal variables
-
-			# ignore any ()s
-			while (gsub(/(\([^)]*\))/, "")) {
-			}
-			if (match($0, /[()]/)) {
-				next;
-			}
-			# unsigned int *a,  b; int c;
-			gsub(/[*]/, " ");
-			# unsigned int a,  b; int c;
-			gsub(/ +/, " ");
-			# unsigned int a, b; int c;
-			gsub(/ *[,;]/, ";");
-			# unsigned int a; b; int c;
-			if (!match($0, /;/)) {
-				next;
-			}
-			# print "=DEBUG=" $0 "==";
-			split($0, chunks, ";");
-			# [unsigned int a, b, c]
-
-			for (i = 1; i in chunks; i ++) {
-				if (chunks[i] == "") {
-					delete chunks[i];
-					continue;
-				}
-				split(chunks[i], pieces, " ");
-				# [unsigned, int, a]
-				# [b]
-				# [c]
-
-				last_piece = "";
-				for (j = 1; j in pieces; j ++) {
-					last_piece = pieces[j];
-					delete pieces[j];
-				}
-				if (last_piece == "") {
-					# print "=ERROR=" chunks[i] "==";
-					delete chunks[i];
-					continue;
-				}
-				# a
-				# b
-				# c
-
-				buffer[buffer_len] = last_piece;
-				buffer_len ++;
-				delete chunks[i]
-			}
-			last_piece = "";
-		}
-		next;
-	}
-}
-
-/^typedef struct [^{]*;/ {
-	sub(";", "");
-	typename=$3;
-	newtypename=$4;
-	typedefs[typename] = newtypename;
-	if (ELEMENTSOF[typename]) {
-		ELEMENTSOF[newtypename] = ELEMENTSOF[typename];
-		COUNTOF[newtypename]    = COUNTOF[typename];
-		sub(/.*/, SIZEOF[typename]);
-		gsub(typename, newtypename);
-		SIZEOF[newtypename]     = $0;
-		printstruct(newtypename);
-	}
-	next;
-}
-/^typedef struct .*\{[^}]*$/ {
-	brace = countBrace($0);
-	if (brace > 0) {
-		instruct = 1;
-	}
-	else {
-		brace = 0;
-		instruct = 0;
-	}
-
-	for (i in buffer) {
-		delete buffer[i];
-	}
-	next;
-}
-
-/^struct .*\{.*/ {
-	brace = countBrace($0);
-	if (brace > 0) {
-		instruct = $2;
-	}
-	else {
-		brace = 0;
-		instruct = 0;
-	}
-
-	for (i in buffer) {
-		delete buffer[i];
-	}
-	next;
-}
Index: unk/mmap.c
===================================================================
--- /trunk/mmap.c	(revision 981)
+++ 	(revision )
@@ -1,324 +1,0 @@
-
-#include <stdio.h>
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* mmap */
-#ifdef ZEND_WIN32
-#	define ftruncate chsize
-#	define getuid() 0
-#	include <process.h>
-#	define XCacheCreateFileMapping(size, perm, name) \
-		CreateFileMapping(INVALID_HANDLE_VALUE, NULL, perm, (sizeof(xc_shmsize_t) > 4) ? size >> 32 : 0, size & 0xffffffff, name)
-#	define XCACHE_MAP_FAILED NULL
-#	define munmap(p, s) UnmapViewOfFile(p)
-#else
-#	include <unistd.h>
-/* make sure to mark(change) it to NULL to keep consistent */
-#	define XCACHE_MAP_FAILED MAP_FAILED
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#ifndef ZEND_WIN32
-#include <sys/mman.h>
-#endif
-
-#include "php.h"
-#define XC_SHM_IMPL _xc_mmap_shm_t
-#include "xc_shm.h"
-#include "utils.h"
-
-#ifndef max
-#define max(a, b) ((a) < (b) ? (b) : (a))
-#endif
-
-/* {{{ xc_shm_t */
-struct _xc_mmap_shm_t {
-	xc_shm_handlers_t *handlers;
-	zend_bool disabled;
-	void *ptr;
-	void *ptr_ro;
-	long  diff;
-	xc_shmsize_t size;
-	xc_shmsize_t memoffset;
-	char *name;
-#ifdef ZEND_WIN32
-	HANDLE hmap;
-	HANDLE hmap_ro;
-#else
-	int newfile;
-#endif
-};
-
-/* }}} */
-#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
-#define PTR_ADD(ptr, v) (((char *) (ptr)) + (v))
-#define PTR_SUB(ptr, v) (((char *) (ptr)) - (v))
-
-static XC_SHM_CAN_READONLY(xc_mmap_can_readonly) /* {{{ */
-{
-	return shm->ptr_ro != NULL;
-}
-/* }}} */
-static XC_SHM_IS_READWRITE(xc_mmap_is_readwrite) /* {{{ */
-{
-	return p >= shm->ptr && (char *)p < (char *)shm->ptr + shm->size;
-}
-/* }}} */
-static XC_SHM_IS_READONLY(xc_mmap_is_readonly) /* {{{ */
-{
-	return xc_mmap_can_readonly(shm) && p >= shm->ptr_ro && (char *)p < (char *)shm->ptr_ro + shm->size;
-}
-/* }}} */
-static XC_SHM_TO_READWRITE(xc_mmap_to_readwrite) /* {{{ */
-{
-	if (shm->diff) {
-		assert(xc_mmap_is_readonly(shm, p));
-		p = PTR_SUB(p, shm->diff);
-	}
-	assert(xc_mmap_is_readwrite(shm, p));
-	return p;
-}
-/* }}} */
-static XC_SHM_TO_READONLY(xc_mmap_to_readonly) /* {{{ */
-{
-	assert(xc_mmap_is_readwrite(shm, p));
-	if (shm->diff) {
-		p = PTR_ADD(p, shm->diff);
-		assert(xc_mmap_is_readonly(shm, p));
-	}
-	return p;
-}
-/* }}} */
-
-static XC_SHM_DESTROY(xc_mmap_destroy) /* {{{ */
-{
-	if (shm->ptr_ro) {
-		munmap(shm->ptr_ro, shm->size);
-		/*
-		shm->ptr_ro = NULL;
-		*/
-	}
-	if (shm->ptr) {
-		/* shm->size depends on shm->ptr */
-		munmap(shm->ptr, shm->size);
-		/*
-		shm->ptr = NULL;
-		*/
-	}
-#ifdef ZEND_WIN32
-	if (shm->hmap) {
-		CloseHandle(shm->hmap);
-	}
-	if (shm->hmap_ro) {
-		CloseHandle(shm->hmap_ro);
-	}
-#endif
-
-	if (shm->name) {
-#ifndef ZEND_WIN32
-#	ifdef __CYGWIN__
-		if (shm->newfile) {
-			unlink(shm->name);
-		}
-#	endif
-#endif
-		free(shm->name);
-	}
-	/*
-	shm->size = NULL;
-	shm->diff = 0;
-	*/
-
-	free(shm);
-	return;
-}
-/* }}} */
-static XC_SHM_INIT(xc_mmap_init) /* {{{ */
-{
-#ifdef ZEND_WIN32
-#	define TMP_PATH "XCache"
-#else
-#	define TMP_PATH "/tmp/XCache"
-	int fd = -1;
-#endif
-	xc_shm_t *shm = NULL;
-	int ro_ok;
-	volatile void *romem;
-	char tmpname[sizeof(TMP_PATH) - 1 + 100];
-	const char *errstr = NULL;
-	const char *path = (const char *) arg1;
-
-	CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM");
-	shm->size = size;
-
-	if (path == NULL || !path[0]) {
-		static int inc = 0;
-		snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d.%d", TMP_PATH, (int) getuid(), (int) getpid(), inc ++, rand());
-		path = tmpname;
-	}
-#ifdef ZEND_WIN32
-	else {
-		static int inc2 = 0;
-		snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d.%d", path, (int) getuid(), (int) getpid(), inc2 ++, rand());
-		path = tmpname;
-	}
-#endif
-
-	shm->name = strdup(path);
-
-#ifndef ZEND_WIN32
-#	define XCACHE_MMAP_PERMISSION (S_IRUSR | S_IWUSR)
-	fd = open(shm->name, O_RDWR, XCACHE_MMAP_PERMISSION);
-	if (fd == -1) {
-		/* do not create file in /dev */
-		if (strncmp(shm->name, "/dev", 4) == 0) {
-			perror(shm->name);
-			errstr = "Cannot open file set by xcache.mmap_path, check the xcache.size/var_size against system limitation";
-			goto err;
-		}
-		fd = open(shm->name, O_CREAT | O_RDWR, XCACHE_MMAP_PERMISSION);
-		shm->newfile = 1;
-		if (fd == -1) {
-			perror(shm->name);
-			errstr = "Cannot open or create file set by xcache.mmap_path, check the path permission or check xcache.size/var_size against system limitation";
-			goto err;
-		}
-	}
-
-	if (ftruncate(fd, size) != 0 && errno != EINVAL) {
-		perror(shm->name);
-		errstr = "Failed to ftruncate the file";
-		goto err;
-	}
-#endif
-
-#ifdef ZEND_WIN32
-	shm->hmap = XCacheCreateFileMapping(size, PAGE_READWRITE, shm->name);
-	shm->ptr = (LPSTR) MapViewOfFile(shm->hmap, FILE_MAP_WRITE, 0, 0, 0);
-#else
-	shm->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-#endif
-
-	if (shm->ptr == XCACHE_MAP_FAILED) {
-		perror(shm->name);
-		errstr = "Failed creating file mapping";
-		shm->ptr = NULL;
-		goto err;
-	}
-
-	/* {{{ readonly protection, mmap it readonly and check if ptr_ro works */
-	if (readonly_protection) {
-		ro_ok = 0;
-
-#ifdef ZEND_WIN32
-		shm->hmap_ro = XCacheCreateFileMapping(size, PAGE_READONLY, shm->name);
-		shm->ptr_ro = (LPSTR) MapViewOfFile(shm->hmap_ro, FILE_MAP_READ, 0, 0, 0);
-#else
-		shm->ptr_ro = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
-#endif
-		if (shm->ptr_ro == XCACHE_MAP_FAILED) {
-			shm->ptr_ro = NULL;
-		}
-		romem = shm->ptr_ro;
-
-		do {
-			if (romem == NULL || romem == shm->ptr) {
-				break;
-			}
-			*(char *)shm->ptr = 1;
-			if (*(char *)romem != 1) {
-				break;
-			}
-			*(char *)shm->ptr = 2;
-			if (*(char *)romem != 2) {
-				break;
-			}
-			ro_ok = 1;
-		} while (0);
-
-		if (ro_ok) {
-			shm->diff = PTR_SUB(shm->ptr_ro, (char *) shm->ptr);
-			/* no overlap */
-			assert(abs(shm->diff) >= size);
-		}
-		else {
-			if (shm->ptr_ro) {
-				munmap(shm->ptr_ro, size);
-			}
-#ifdef ZEND_WIN32
-			if (shm->hmap_ro) {
-				CloseHandle(shm->hmap_ro);
-			}
-#endif
-			shm->ptr_ro = NULL;
-			shm->diff = 0;
-		}
-	}
-
-	/* }}} */
-
-#ifndef ZEND_WIN32
-	close(fd);
-
-#	ifndef __CYGWIN__
-	if (shm->newfile) {
-		unlink(shm->name);
-	}
-#	endif
-#endif
-
-	return shm;
-
-err:
-#ifndef ZEND_WIN32
-	if (fd != -1) {
-		close(fd);
-	}
-#endif
-	if (shm) {
-		xc_mmap_destroy(shm);
-	}
-	if (errstr) {
-		fprintf(stderr, "%s\n", errstr);
-		zend_error(E_ERROR, "%s", errstr);
-	}
-	return NULL;
-}
-/* }}} */
-
-static XC_SHM_MEMINIT(xc_mmap_meminit) /* {{{ */
-{
-	xc_mem_t *mem;
-	if (shm->memoffset + size > shm->size) {
-		zend_error(E_ERROR, "XCache: internal error at %s#%d", __FILE__, __LINE__);
-		return NULL;
-	}
-	mem = (xc_mem_t *) PTR_ADD(shm->ptr, shm->memoffset);
-	shm->memoffset += size;
-	mem->handlers = shm->handlers->memhandlers;
-	mem->handlers->init(shm, mem, size);
-	return mem;
-}
-/* }}} */
-static XC_SHM_MEMDESTROY(xc_mmap_memdestroy) /* {{{ */
-{
-}
-/* }}} */
-
-static xc_shm_handlers_t xc_shm_mmap_handlers = XC_SHM_HANDLERS(mmap);
-void xc_shm_mmap_register() /* {{{ */
-{
-	CHECK(xc_shm_mmap_handlers.memhandlers = xc_mem_scheme_find("mem"), "cannot find mem handlers");
-	if (xc_shm_scheme_register("mmap", &xc_shm_mmap_handlers) == 0) {
-		zend_error(E_ERROR, "XCache: failed to register mmap shm_scheme");
-	}
-err:
-	return;
-}
-/* }}} */
Index: unk/opcode_spec.c
===================================================================
--- /trunk/opcode_spec.c	(revision 981)
+++ 	(revision )
@@ -1,48 +1,0 @@
-#include "xcache.h"
-#include "opcode_spec.h"
-#include "const_string.h"
-
-#ifdef HAVE_XCACHE_OPCODE_SPEC_DEF
-/* {{{ opcode_spec */
-#define OPSPEC(ext, op1, op2, res) { OPSPEC_##ext, OPSPEC_##op1, OPSPEC_##op2, OPSPEC_##res },
-#ifdef ZEND_ENGINE_2
-#	define OPSPEC_VAR_2 OPSPEC_STD
-#else
-#	define OPSPEC_VAR_2 OPSPEC_VAR
-#endif
-#include "opcode_spec_def.h"
-
-zend_uchar xc_get_opcode_spec_count()
-{
-	return sizeof(xc_opcode_spec) / sizeof(xc_opcode_spec[0]);
-}
-
-const xc_opcode_spec_t *xc_get_opcode_spec(zend_uchar opcode)
-{
-#ifndef NDEBUG
-	if (xc_get_opcode_count() != xc_get_opcode_spec_count()) {
-		fprintf(stderr, "count mismatch: xc_get_opcode_count=%d, xc_get_opcode_spec_count=%d\n", xc_get_opcode_count(), xc_get_opcode_spec_count());
-	}
-#endif
-	assert(xc_get_opcode_count() == xc_get_opcode_spec_count());
-	assert(opcode < xc_get_opcode_spec_count());
-	return &xc_opcode_spec[opcode];
-}
-/* }}} */
-#endif
-/* {{{ op_spec */
-
-#define OPSPECS_DEF_NAME(name) #name,
-static const char *xc_op_spec[] = { OPSPECS(OPSPECS_DEF_NAME) };
-
-zend_uchar xc_get_op_spec_count()
-{
-	return sizeof(xc_op_spec) / sizeof(xc_op_spec[0]);
-}
-
-const char *xc_get_op_spec(zend_uchar spec)
-{
-	assert(spec < xc_get_op_spec_count());
-	return xc_op_spec[spec];
-}
-/* }}} */
Index: unk/opcode_spec.h
===================================================================
--- /trunk/opcode_spec.h	(revision 981)
+++ 	(revision )
@@ -1,43 +1,0 @@
-#include "php.h"
-
-#define OPSPECS(OPSPEC) \
-	OPSPEC(STD) \
-	OPSPEC(UNUSED) \
-	OPSPEC(OPLINE) \
-	OPSPEC(FCALL) \
-	OPSPEC(INIT_FCALL) \
-	OPSPEC(ARG) \
-	OPSPEC(CAST) \
-	OPSPEC(FETCH) \
-	OPSPEC(DECLARE) \
-	OPSPEC(SEND) \
-	OPSPEC(SEND_NOREF) \
-	OPSPEC(FCLASS) \
-	OPSPEC(UCLASS) \
-	OPSPEC(CLASS) \
-	OPSPEC(FE) \
-	OPSPEC(IFACE) \
-	OPSPEC(ISSET) \
-	OPSPEC(BIT) \
-	OPSPEC(VAR) \
-	OPSPEC(TMP) \
-	OPSPEC(JMPADDR) \
-	OPSPEC(BRK) \
-	OPSPEC(CONT) \
-	OPSPEC(INCLUDE) \
-	OPSPEC(ASSIGN)
-
-#define OPSPECS_DEF_ENUM(name) OPSPEC_##name,
-typedef enum { OPSPECS(OPSPECS_DEF_ENUM) OPSPEC_DUMMY } xc_op_spec_t;
-
-typedef struct {
-	xc_op_spec_t ext;
-	xc_op_spec_t op1;
-	xc_op_spec_t op2;
-	xc_op_spec_t res;
-} xc_opcode_spec_t;
-
-const xc_opcode_spec_t *xc_get_opcode_spec(zend_uchar opcode);
-zend_uchar xc_get_opcode_spec_count();
-zend_uchar xc_get_op_spec_count();
-const char *xc_get_op_spec(zend_uchar spec);
Index: unk/opcode_spec_def.h
===================================================================
--- /trunk/opcode_spec_def.h	(revision 981)
+++ 	(revision )
@@ -1,260 +1,0 @@
-static const xc_opcode_spec_t xc_opcode_spec[] = {
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 0 NOP                            */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 1 ADD                            */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 2 SUB                            */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 3 MUL                            */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 4 DIV                            */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 5 MOD                            */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 6 SL                             */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 7 SR                             */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 8 CONCAT                         */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 9 BW_OR                          */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 10 BW_AND                         */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 11 BW_XOR                         */
-	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 12 BW_NOT                         */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 13 BOOL_NOT                       */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 14 BOOL_XOR                       */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 15 IS_IDENTICAL                   */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 16 IS_NOT_IDENTICAL               */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 17 IS_EQUAL                       */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 18 IS_NOT_EQUAL                   */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 19 IS_SMALLER                     */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 20 IS_SMALLER_OR_EQUAL            */
-	OPSPEC(      CAST,        STD,     UNUSED,        TMP) /* 21 CAST                           */
-	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 22 QM_ASSIGN                      */
-#ifdef ZEND_ENGINE_2
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 23 ASSIGN_ADD                     */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 24 ASSIGN_SUB                     */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 25 ASSIGN_MUL                     */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 26 ASSIGN_DIV                     */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 27 ASSIGN_MOD                     */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 28 ASSIGN_SL                      */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 29 ASSIGN_SR                      */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 30 ASSIGN_CONCAT                  */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 31 ASSIGN_BW_OR                   */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 32 ASSIGN_BW_AND                  */
-	OPSPEC(    ASSIGN,        STD,        STD,        VAR) /* 33 ASSIGN_BW_XOR                  */
-#else
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR)
-#endif
-	OPSPEC(    UNUSED,        VAR,     UNUSED,        VAR) /* 34 PRE_INC                        */
-	OPSPEC(    UNUSED,        VAR,     UNUSED,        VAR) /* 35 PRE_DEC                        */
-	OPSPEC(    UNUSED,        VAR,     UNUSED,        TMP) /* 36 POST_INC                       */
-	OPSPEC(    UNUSED,        VAR,     UNUSED,        TMP) /* 37 POST_DEC                       */
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 38 ASSIGN                         */
-	OPSPEC(    UNUSED,        VAR,        VAR,        VAR) /* 39 ASSIGN_REF                     */
-	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 40 ECHO                           */
-	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 41 PRINT                          */
-#ifdef ZEND_ENGINE_2
-	OPSPEC(    UNUSED,    JMPADDR,     UNUSED,     UNUSED) /* 42 JMP                            */
-	OPSPEC(    UNUSED,        STD,    JMPADDR,     UNUSED) /* 43 JMPZ                           */
-	OPSPEC(    UNUSED,        STD,    JMPADDR,     UNUSED) /* 44 JMPNZ                          */
-#else
-	OPSPEC(    UNUSED,     OPLINE,     UNUSED,     UNUSED)
-	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED)
-	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED)
-#endif
-	OPSPEC(    OPLINE,        STD,     OPLINE,     UNUSED) /* 45 JMPZNZ                         */
-#ifdef ZEND_ENGINE_2
-	OPSPEC(    UNUSED,        STD,    JMPADDR,        TMP) /* 46 JMPZ_EX                        */
-	OPSPEC(    UNUSED,        STD,    JMPADDR,        TMP) /* 47 JMPNZ_EX                       */
-#else
-	OPSPEC(    UNUSED,        STD,     OPLINE,        TMP)
-	OPSPEC(    UNUSED,        STD,     OPLINE,        TMP)
-#endif
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 48 CASE                           */
-	OPSPEC(       BIT,        STD,     UNUSED,     UNUSED) /* 49 SWITCH_FREE                    */
-	OPSPEC(    UNUSED,        BRK,        STD,     UNUSED) /* 50 BRK                            */
-	OPSPEC(    UNUSED,       CONT,        STD,     UNUSED) /* 51 CONT                           */
-	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 52 BOOL                           */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,        TMP) /* 53 INIT_STRING                    */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 54 ADD_CHAR                       */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 55 ADD_STRING                     */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 56 ADD_VAR                        */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,        TMP) /* 57 BEGIN_SILENCE                  */
-	OPSPEC(    UNUSED,        TMP,     UNUSED,     UNUSED) /* 58 END_SILENCE                    */
-	OPSPEC(INIT_FCALL,        STD,        STD,     UNUSED) /* 59 INIT_FCALL_BY_NAME             */
-#ifdef ZEND_ENGINE_2
-	OPSPEC(     FCALL,        STD,     OPLINE,        VAR) /* 60 DO_FCALL                       */
-	OPSPEC(     FCALL,        STD,     OPLINE,        VAR) /* 61 DO_FCALL_BY_NAME               */
-#else
-	OPSPEC(     FCALL,        STD,     UNUSED,        VAR)
-	OPSPEC(     FCALL,        STD,     UNUSED,        VAR)
-#endif
-	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 62 RETURN                         */
-	OPSPEC(    UNUSED,        ARG,     UNUSED,        VAR) /* 63 RECV                           */
-	OPSPEC(    UNUSED,        ARG,        STD,        VAR) /* 64 RECV_INIT                      */
-	OPSPEC(      SEND,        STD,        ARG,     UNUSED) /* 65 SEND_VAL                       */
-	OPSPEC(      SEND,        VAR,        ARG,     UNUSED) /* 66 SEND_VAR                       */
-	OPSPEC(      SEND,        VAR,        ARG,     UNUSED) /* 67 SEND_REF                       */
-#ifdef ZEND_ENGINE_2
-	OPSPEC(    UNUSED,      CLASS,     UNUSED,        VAR) /* 68 NEW                            */
-#else
-	OPSPEC(    UNUSED,        STD,     UNUSED,        VAR)
-#endif
-#ifdef ZEND_ENGINE_2_3
-	OPSPEC(       STD,        STD,        STD,     UNUSED) /* 69 INIT_NS_FCALL_BY_NAME          */
-#else
-	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED) /* 69 JMP_NO_CTOR                    */
-#endif
-	OPSPEC(    UNUSED,        TMP,     UNUSED,     UNUSED) /* 70 FREE                           */
-	OPSPEC(       BIT,        STD,        STD,        TMP) /* 71 INIT_ARRAY                     */
-	OPSPEC(       BIT,        STD,        STD,        TMP) /* 72 ADD_ARRAY_ELEMENT              */
-	OPSPEC(    UNUSED,        STD,    INCLUDE,        VAR) /* 73 INCLUDE_OR_EVAL                */
-#ifdef ZEND_ENGINE_2_1
-  /* php 5.1 and up */
-	OPSPEC(    UNUSED,        STD,      FETCH,     UNUSED) /* 74 UNSET_VAR                      */
-	OPSPEC(       STD,        STD,        STD,     UNUSED) /* 75 UNSET_DIM                      */
-	OPSPEC(       STD,        STD,        STD,     UNUSED) /* 76 UNSET_OBJ                      */
-	OPSPEC(       BIT,        STD,     OPLINE,        VAR) /* 77 FE_RESET                       */
-#else
-  /* <= php 5.0 */
-  /* though there is no ISSET_ISEMPTY in php 5.0 it's better to leave it here i guess */
-	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED)
-	OPSPEC(    UNUSED,        VAR,        STD,     UNUSED)
-	OPSPEC(    UNUSED,        VAR,      ISSET,        TMP)
-	OPSPEC(       BIT,        STD,     UNUSED,        VAR)
-#endif
-	OPSPEC(        FE,        STD,     OPLINE,        TMP) /* 78 FE_FETCH                       */
-	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 79 EXIT                           */
-	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 80 FETCH_R                        */
-	OPSPEC(     FETCH,        VAR,        STD,        VAR) /* 81 FETCH_DIM_R                    */
-	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 82 FETCH_OBJ_R                    */
-	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 83 FETCH_W                        */
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 84 FETCH_DIM_W                    */
-	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 85 FETCH_OBJ_W                    */
-	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 86 FETCH_RW                       */
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 87 FETCH_DIM_RW                   */
-	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 88 FETCH_OBJ_RW                   */
-	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 89 FETCH_IS                       */
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 90 FETCH_DIM_IS                   */
-	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 91 FETCH_OBJ_IS                   */
-	OPSPEC(       ARG,        STD,      FETCH,        VAR) /* 92 FETCH_FUNC_ARG                 */
-	OPSPEC(       ARG,        VAR,        STD,        VAR) /* 93 FETCH_DIM_FUNC_ARG             */
-	OPSPEC(       ARG,      VAR_2,        STD,        VAR) /* 94 FETCH_OBJ_FUNC_ARG             */
-	OPSPEC(    UNUSED,        STD,      FETCH,        VAR) /* 95 FETCH_UNSET                    */
-	OPSPEC(    UNUSED,        VAR,        STD,        VAR) /* 96 FETCH_DIM_UNSET                */
-	OPSPEC(    UNUSED,      VAR_2,        STD,        VAR) /* 97 FETCH_OBJ_UNSET                */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 98 FETCH_DIM_TMP_VAR              */
-#ifdef ZEND_ENGINE_2_3
-	OPSPEC(    UNUSED,      VAR_2,        STD,        TMP) /* 99 FETCH_CONSTANT                 */
-#elif defined(ZEND_ENGINE_2)
-	OPSPEC(    UNUSED,     UCLASS,        STD,        TMP) /* 99 FETCH_CONSTANT                 */
-#else
-	OPSPEC(    UNUSED,        STD,     UNUSED,        TMP) /* 99 FETCH_CONSTANT                 */
-#endif
-#ifdef ZEND_ENGINE_2_3
-	OPSPEC(       STD,    JMPADDR,        STD,     UNUSED) /* 100 GOTO                           */
-#else
-	OPSPEC(   DECLARE,        STD,        STD,     UNUSED) /* 100 DECLARE_FUNCTION_OR_CLASS      */
-#endif
-	OPSPEC(       STD,        STD,        STD,        STD) /* 101 EXT_STMT                       */
-	OPSPEC(       STD,        STD,        STD,        STD) /* 102 EXT_FCALL_BEGIN                */
-	OPSPEC(       STD,        STD,        STD,        STD) /* 103 EXT_FCALL_END                  */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 104 EXT_NOP                        */
-	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 105 TICKS                          */
-	OPSPEC(SEND_NOREF,        VAR,        ARG,     UNUSED) /* 106 SEND_VAR_NO_REF                */
-#ifdef ZEND_ENGINE_2
-	OPSPEC(    OPLINE,      CLASS,        STD,     UNUSED) /* 107 CATCH                          */
-	OPSPEC(    UNUSED,        STD,     OPLINE,     UNUSED) /* 108 THROW                          */
-	OPSPEC(    FCLASS,        STD,        STD,      CLASS) /* 109 FETCH_CLASS                    */
-	OPSPEC(    UNUSED,        STD,     UNUSED,        VAR) /* 110 CLONE                          */
-
-#ifdef ZEND_ENGINE_2_4
-	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 111 RETURN_BY_REF                  */
-#else
-	OPSPEC(    UNUSED,        STD,     UNUSED,     UNUSED) /* 111 INIT_CTOR_CALL                 */
-#endif
-
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 112 INIT_METHOD_CALL               */
-#	ifdef ZEND_ENGINE_2_3
-	OPSPEC(    UNUSED,        STD,        STD,     UNUSED) /* 113 INIT_STATIC_METHOD_CALL        */
-#	else
-	OPSPEC(    UNUSED,     UCLASS,        STD,     UNUSED) /* 113 INIT_STATIC_METHOD_CALL        */
-#	endif
-	OPSPEC(     ISSET,        STD,      FETCH,        TMP) /* 114 ISSET_ISEMPTY_VAR              */
-	OPSPEC(     ISSET,        STD,        STD,        TMP) /* 115 ISSET_ISEMPTY_DIM_OBJ          */
-
-	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 116 IMPORT_FUNCTION                */
-	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 117 IMPORT_CLASS                   */
-	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 118 IMPORT_CONST                   */
-	OPSPEC(       STD,        STD,        STD,        STD) /* 119 OP_119                         */
-	OPSPEC(       STD,        STD,        STD,        STD) /* 120 OP_120                         */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 121 ASSIGN_ADD_OBJ                 */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 122 ASSIGN_SUB_OBJ                 */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 123 ASSIGN_MUL_OBJ                 */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 124 ASSIGN_DIV_OBJ                 */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 125 ASSIGN_MOD_OBJ                 */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 126 ASSIGN_SL_OBJ                  */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 127 ASSIGN_SR_OBJ                  */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 128 ASSIGN_CONCAT_OBJ              */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 129 ASSIGN_BW_OR_OBJ               */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 130 ASSIGN_BW_AND_OBJ              */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 131 ASSIGN_BW_XOR_OBJ              */
-
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 132 PRE_INC_OBJ                    */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 133 PRE_DEC_OBJ                    */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 134 POST_INC_OBJ                   */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 135 POST_DEC_OBJ                   */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 136 ASSIGN_OBJ                     */
-	OPSPEC(    UNUSED,        STD,        STD,        STD) /* 137 OP_DATA                        */
-	OPSPEC(    UNUSED,        STD,      CLASS,        TMP) /* 138 INSTANCEOF                     */
-	OPSPEC(    UNUSED,        STD,        STD,      CLASS) /* 139 DECLARE_CLASS                  */
-	OPSPEC(     CLASS,        STD,        STD,      CLASS) /* 140 DECLARE_INHERITED_CLASS        */
-	OPSPEC(    UNUSED,        STD,        STD,     UNUSED) /* 141 DECLARE_FUNCTION               */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 142 RAISE_ABSTRACT_ERROR           */
-#ifdef ZEND_ENGINE_2_3
-	OPSPEC(   DECLARE,        STD,        STD,     UNUSED) /* 143 DECLARE_CONST                  */
-#else
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 143 UNDEF-143                      */
-#endif
-#ifdef ZEND_ENGINE_2_3
-	OPSPEC(     IFACE,      CLASS,        STD,     UNUSED) /* 144 ADD_INTERFACE                  */
-#else
-	OPSPEC(     IFACE,      CLASS,      CLASS,     UNUSED) /* 144 ADD_INTERFACE                  */
-#endif
-#ifdef ZEND_ENGINE_2_3
-	OPSPEC(     CLASS,        STD,        STD,     OPLINE) /* 145 DECLARE_INHERITED_CLASS_DELAYED */
-#else
-	OPSPEC(    UNUSED,      CLASS,        STD,     UNUSED) /* 145 VERIFY_INSTANCEOF              */
-#endif
-	OPSPEC(    UNUSED,      CLASS,     UNUSED,     UNUSED) /* 146 VERIFY_ABSTRACT_CLASS          */
-	OPSPEC(    UNUSED,        STD,        STD,        VAR) /* 147 ASSIGN_DIM                     */
-	OPSPEC(     ISSET,        STD,        STD,        TMP) /* 148 ISSET_ISEMPTY_PROP_OBJ         */
-	OPSPEC(       STD,     UNUSED,     UNUSED,        STD) /* 149 HANDLE_EXCEPTION               */
-	OPSPEC(       STD,     UNUSED,     UNUSED,        STD) /* 150 USER_OPCODE                    */
-# ifdef ZEND_ENGINE_2_3
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 151 UNDEF                          */
-	OPSPEC(    UNUSED,        STD,    JMPADDR,        TMP) /* 152 JMP_SET                        */
-	OPSPEC(    UNUSED,        STD,        STD,        TMP) /* 153 DECLARE_LAMBDA_FUNCTION        */
-#  ifdef ZEND_ENGINE_2_4
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 154 ADD_TRAIT                      */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 155 BIND_TRAITS                    */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 156 SEPARATE                       */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 157 QM_ASSIGN_VAR                  */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 158 JMP_SET_VAR                    */
-#  endif
-# else
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 151 UNDEF                          */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 152 UNDEF                          */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 153 UNDEF                          */
-# endif
-#else
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 107 UNDEF                          */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 108 UNDEF                          */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 109 UNDEF                          */
-	OPSPEC(     FCALL,        STD,     OPLINE,        VAR) /* 61 DO_FCALL_BY_FUNC                */
-	OPSPEC(INIT_FCALL,        STD,        STD,     UNUSED) /* 111 INIT_FCALL_BY_FUNC             */
-	OPSPEC(    UNUSED,     UNUSED,     UNUSED,     UNUSED) /* 112 UNDEF                          */
-#endif
-};
Index: unk/optimizer.c
===================================================================
--- /trunk/optimizer.c	(revision 981)
+++ 	(revision )
@@ -1,616 +1,0 @@
-#if 0
-#	define XCACHE_DEBUG
-#endif
-
-#include "utils.h"
-#include "optimizer.h"
-/* the "vector" stack */
-#include "stack.h"
-#include "xcache_globals.h"
-
-#ifdef XCACHE_DEBUG
-#	include "processor.h"
-#	include "const_string.h"
-#	include "ext/standard/php_var.h"
-#endif
-
-#ifdef IS_CV
-#	define XCACHE_IS_CV IS_CV
-#else
-#	define XCACHE_IS_CV 16
-#endif
-
-#ifdef ZEND_ENGINE_2_4
-#	undef Z_OP_CONSTANT
-/* Z_OP_CONSTANT is used before pass_two is applied */
-#	define Z_OP_CONSTANT(op) op_array->literals[op.constant].constant
-#endif
-
-typedef int bbid_t;
-enum {
-	BBID_INVALID = -1
-};
-/* {{{ basic block */
-typedef struct _bb_t {
-	bbid_t     id;
-	zend_bool  used;
-
-	zend_bool  alloc;
-	zend_op   *opcodes;
-	int        count;
-	int        size;
-
-	bbid_t     fall;
-#ifdef ZEND_ENGINE_2
-	bbid_t     catch;
-#endif
-
-	int        opnum; /* opnum after joining basic block */
-} bb_t;
-/* }}} */
-
-/* basic blocks */
-typedef xc_stack_t bbs_t;
-
-/* op array helper functions */
-static int op_array_convert_switch(zend_op_array *op_array) /* {{{ */
-{
-	int i;
-
-	if (op_array->brk_cont_array == NULL) {
-		return SUCCESS;
-	}
-
-	for (i = 0; i < op_array->last; i ++) {
-		zend_op *opline = &op_array->opcodes[i];
-		zend_brk_cont_element *jmp_to;
-		zend_bool can_convert = 1;
-		int array_offset, nest_levels, original_nest_levels;
-
-		switch (opline->opcode) {
-		case ZEND_BRK:
-		case ZEND_CONT:
-			break;
-
-#ifdef ZEND_GOTO
-		case ZEND_GOTO:
-#endif
-			continue;
-
-		default:
-			continue;
-		}
-
-		if (Z_OP_TYPE(opline->op2) != IS_CONST
-		 || Z_OP_CONSTANT(opline->op2).type != IS_LONG) {
-			return FAILURE;
-		}
-
-		nest_levels = Z_OP_CONSTANT(opline->op2).value.lval;
-		original_nest_levels = nest_levels;
-
-		array_offset = Z_OP(opline->op1).opline_num;
-		do {
-			if (array_offset == -1) {
-				/* this is a runtime error in ZE
-				zend_error(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
-				*/
-				return FAILURE;
-			}
-			jmp_to = &op_array->brk_cont_array[array_offset];
-			if (nest_levels > 1) {
-				zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
-
-				switch (brk_opline->opcode) {
-				case ZEND_SWITCH_FREE:
-				case ZEND_FREE:
-#ifdef EXT_TYPE_FREE_ON_RETURN
-					if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN))
-#endif
-					{
-						can_convert = 0;
-					}
-					break;
-				}
-			}
-			array_offset = jmp_to->parent;
-		} while (--nest_levels > 0);
-
-		if (can_convert) {
-			/* rewrite to jmp */
-			switch (opline->opcode) {
-			case ZEND_BRK:
-				Z_OP(opline->op1).opline_num = jmp_to->brk;
-				break;
-
-			case ZEND_CONT:
-				Z_OP(opline->op1).opline_num = jmp_to->cont;
-				break;
-			}
-			Z_OP_TYPE(opline->op2) = IS_UNUSED;
-			opline->opcode = ZEND_JMP;
-		}
-	}
-
-	return SUCCESS;
-}
-/* }}} */
-/* {{{ op_flowinfo helper func */
-enum {
-	XC_OPNUM_INVALID = -1,
-};
-typedef struct {
-	int       jmpout_op1;
-	int       jmpout_op2;
-	int       jmpout_ext;
-	zend_bool fall;
-} op_flowinfo_t;
-static void op_flowinfo_init(op_flowinfo_t *fi)
-{
-	fi->jmpout_op1 = fi->jmpout_op2 = fi->jmpout_ext = XC_OPNUM_INVALID;
-	fi->fall = 0;
-}
-/* }}} */
-static int op_get_flowinfo(op_flowinfo_t *fi, zend_op *opline) /* {{{ */
-{
-	op_flowinfo_init(fi);
-
-	/* break=will fall */
-	switch (opline->opcode) {
-#ifdef ZEND_HANDLE_EXCEPTION
-	case ZEND_HANDLE_EXCEPTION:
-#endif
-	case ZEND_RETURN:
-	case ZEND_EXIT:
-		return SUCCESS; /* no fall */
-
-	case ZEND_JMP:
-		fi->jmpout_op1 = Z_OP(opline->op1).opline_num;
-		return SUCCESS; /* no fall */
-
-	case ZEND_JMPZNZ:
-		fi->jmpout_op2 = Z_OP(opline->op2).opline_num;
-		fi->jmpout_ext = (int) opline->extended_value;
-		return SUCCESS; /* no fall */
-
-	case ZEND_JMPZ:
-	case ZEND_JMPNZ:
-	case ZEND_JMPZ_EX:
-	case ZEND_JMPNZ_EX:
-#ifdef ZEND_JMP_SET
-	case ZEND_JMP_SET:
-#endif
-#ifdef ZEND_JMP_NO_CTOR
-	case ZEND_JMP_NO_CTOR:
-#endif
-#ifdef ZEND_NEW
-	case ZEND_NEW:
-#endif
-#ifdef ZEND_FE_RESET
-	case ZEND_FE_RESET:
-#endif      
-	case ZEND_FE_FETCH:
-		fi->jmpout_op2 = Z_OP(opline->op2).opline_num;
-		break;
-
-#ifdef ZEND_CATCH
-	case ZEND_CATCH:
-		fi->jmpout_ext = (int) opline->extended_value;
-		break;
-#endif
-
-	default:
-		return FAILURE;
-	}
-
-	fi->fall = 1;
-	return SUCCESS;
-}
-/* }}} */
-#ifdef XCACHE_DEBUG
-static void op_snprint(char *buf, int size, zend_uchar op_type, znode_op *op) /* {{{ */
-{
-	switch (op_type) {
-	case IS_CONST:
-		{
-			zval result;
-			zval *zv = &Z_OP_CONSTANT(*op);
-			TSRMLS_FETCH();
-
-			/* TODO: update for PHP 6 */
-			php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
-			php_var_export(&zv, 1 TSRMLS_CC);
-
-			php_ob_get_buffer(&result TSRMLS_CC); 
-			php_end_ob_buffer(0, 0 TSRMLS_CC);
-			snprintf(buf, size, Z_STRVAL(result));
-			zval_dtor(&result);
-		}
-		break;
-
-	case IS_TMP_VAR:
-		snprintf(buf, size, "t@%d", Z_OP(*op).var);
-		break;
-
-	case XCACHE_IS_CV:
-	case IS_VAR:
-		snprintf(buf, size, "v@%d", Z_OP(*op).var);
-		break;
-
-	case IS_UNUSED:
-		if (Z_OP(*op).opline_num) {
-			snprintf(buf, size, "u#%d", Z_OP(op).opline_num);
-		}
-		else {
-			snprintf(buf, size, "-");
-		}
-		break;
-
-	default:
-		snprintf(buf, size, "%d %d", op->op_type, Z_OP(op).var);
-	}
-}
-/* }}} */
-static void op_print(int line, zend_op *first, zend_op *end) /* {{{ */
-{
-	zend_op *opline;
-	for (opline = first; opline < end; opline ++) {
-		char buf_r[20];
-		char buf_1[20];
-		char buf_2[20];
-		op_snprint(buf_r, sizeof(buf_r), Z_OP_TYPE(opline->result), &opline->result);
-		op_snprint(buf_1, sizeof(buf_1), Z_OP_TYPE(opline->op1),    &opline->op1);
-		op_snprint(buf_2, sizeof(buf_2), Z_OP_TYPE(opline->op2),    &opline->op2);
-		fprintf(stderr,
-				"%3d %3d"
-				" %-25s%-5s%-20s%-20s%5lu\r\n"
-				, opline->lineno, opline - first + line
-				, xc_get_opcode(opline->opcode), buf_r, buf_1, buf_2, opline->extended_value);
-	}
-}
-/* }}} */
-#endif
-
-/*
- * basic block functions
- */
-
-static bb_t *bb_new_ex(zend_op *opcodes, int count) /* {{{ */
-{
-	bb_t *bb = (bb_t *) ecalloc(sizeof(bb_t), 1);
-
-	bb->fall       = BBID_INVALID;
-#ifdef ZEND_ENGINE_2
-	bb->catch      = BBID_INVALID;
-#endif
-
-	if (opcodes) {
-		bb->alloc   = 0;
-		bb->size    = bb->count = count;
-		bb->opcodes = opcodes;
-	}
-	else {
-		bb->alloc   = 1;
-		bb->size    = bb->count = 8;
-		bb->opcodes = ecalloc(sizeof(zend_op), bb->size);
-	}
-
-	return bb;
-}
-/* }}} */
-#define bb_new() bb_new_ex(NULL, 0)
-static void bb_destroy(bb_t *bb) /* {{{ */
-{
-	if (bb->alloc) {
-		efree(bb->opcodes);
-	}
-	efree(bb);
-}
-/* }}} */
-#ifdef XCACHE_DEBUG
-static void bb_print(bb_t *bb, zend_op *opcodes) /* {{{ */
-{
-	int line = bb->opcodes - opcodes;
-	op_flowinfo_t fi;
-	zend_op *last = bb->opcodes + bb->count - 1;
-	bbid_t catchbbid;
-#ifdef ZEND_ENGINE_2
-	catchbbid = BBID_INVALID;
-#else
-	catchbbid = bb->catch;
-#endif
-
-	op_get_flowinfo(&fi, last);
-
-	fprintf(stderr,
-			"\r\n==== #%-3d cnt:%-3d lno:%-3d"
-			" %c%c"
-			" op1:%-3d op2:%-3d ext:%-3d fal:%-3d cat:%-3d %s ====\r\n"
-			, bb->id, bb->count, bb->alloc ? -1 : line
-			, bb->used ? 'U' : ' ', bb->alloc ? 'A' : ' '
-			, fi.jmpout_op1, fi.jmpout_op2, fi.jmpout_ext, bb->fall, catchbbid, xc_get_opcode(last->opcode)
-			);
-	op_print(line, bb->opcodes, last + 1);
-}
-/* }}} */
-#endif
-
-static bb_t *bbs_get(bbs_t *bbs, int n) /* {{{ */
-{
-	return (bb_t *) xc_stack_get(bbs, n);
-}
-/* }}} */
-static int bbs_count(bbs_t *bbs) /* {{{ */
-{
-	return xc_stack_count(bbs);
-}
-/* }}} */
-static void bbs_destroy(bbs_t *bbs) /* {{{ */
-{
-	bb_t *bb;
-	while (bbs_count(bbs)) {
-		bb = (bb_t *) xc_stack_pop(bbs);
-		bb_destroy(bb);
-	}
-	xc_stack_destroy(bbs);
-}
-/* }}} */
-#ifdef XCACHE_DEBUG
-static void bbs_print(bbs_t *bbs, zend_op *opcodes) /* {{{ */
-{
-	int i;
-	for (i = 0; i < xc_stack_count(bbs); i ++) {
-		bb_print(bbs_get(bbs, i), opcodes);
-	}
-}
-/* }}} */
-#endif
-#define bbs_init(bbs) xc_stack_init_ex(bbs, 16)
-static bb_t *bbs_add_bb(bbs_t *bbs, bb_t *bb) /* {{{ */
-{
-	bb->id = (bbid_t) xc_stack_count(bbs);
-	xc_stack_push(bbs, (void *) bb);
-	return bb;
-}
-/* }}} */
-static bb_t *bbs_new_bb_ex(bbs_t *bbs, zend_op *opcodes, int count) /* {{{ */
-{
-	return bbs_add_bb(bbs, bb_new_ex(opcodes, count));
-}
-/* }}} */
-static int bbs_build_from(bbs_t *bbs, zend_op_array *op_array, int count) /* {{{ */
-{
-	int i, start;
-	bb_t *pbb;
-	bbid_t id;
-	op_flowinfo_t fi;
-	zend_op *opline;
-	ALLOCA_FLAG(use_heap_bbids)
-	ALLOCA_FLAG(use_heap_catchbbids)
-	ALLOCA_FLAG(use_heap_markbbhead)
-	bbid_t *bbids          = my_do_alloca(count * sizeof(bbid_t),    use_heap_bbids);
-#ifdef ZEND_ENGINE_2
-	bbid_t *catchbbids     = my_do_alloca(count * sizeof(bbid_t),    use_heap_catchbbids);
-#endif
-	zend_bool *markbbhead  = my_do_alloca(count * sizeof(zend_bool), use_heap_markbbhead);
-
-	/* {{{ mark jmpin/jumpout */
-	memset(markbbhead,  0, count * sizeof(zend_bool));
-
-	markbbhead[0] = 1;
-	for (i = 0; i < count; i ++) {
-		if (op_get_flowinfo(&fi, &op_array->opcodes[i]) == SUCCESS) {
-			if (fi.jmpout_op1 != XC_OPNUM_INVALID) {
-				markbbhead[fi.jmpout_op1] = 1;
-			}
-			if (fi.jmpout_op2 != XC_OPNUM_INVALID) {
-				markbbhead[fi.jmpout_op2] = 1;
-			}
-			if (fi.jmpout_ext != XC_OPNUM_INVALID) {
-				markbbhead[fi.jmpout_ext] = 1;
-			}
-			if (i + 1 < count) {
-				markbbhead[i + 1] = 1;
-			}
-		}
-	}
-#ifdef ZEND_ENGINE_2
-	/* mark try start */
-	for (i = 0; i < op_array->last_try_catch; i ++) {
-		markbbhead[op_array->try_catch_array[i].try_op] = 1;
-	}
-#endif
-	/* }}} */
-	/* {{{ fill op lines with newly allocated id */
-	for (i = 0; i < count; i ++) {
-		bbids[i] = BBID_INVALID;
-	}
-
-	id = -1;
-	for (i = 0; i < count; i ++) {
-		if (markbbhead[i]) {
-			id ++;
-		}
-		bbids[i] = id;
-		TRACE("bbids[%d] = %d", i, id);
-	}
-	/* }}} */
-#ifdef ZEND_ENGINE_2
-	/* {{{ fill op lines with catch id */
-	for (i = 0; i < count; i ++) {
-		catchbbids[i] = BBID_INVALID;
-	}
-
-	for (i = 0; i < op_array->last_try_catch; i ++) {
-		int j;
-		zend_try_catch_element *e = &op_array->try_catch_array[i];
-		for (j = e->try_op; j < e->catch_op; j ++) {
-			catchbbids[j] = bbids[e->catch_op];
-		}
-	}
-#ifdef XCACHE_DEBUG
-	for (i = 0; i < count; i ++) {
-		TRACE("catchbbids[%d] = %d", i, catchbbids[i]);
-	}
-#endif
-	/* }}} */
-#endif
-	/* {{{ create basic blocks */
-	start = 0;
-	id = 0;
-	/* loop over to deal with the last block */
-	for (i = 1; i <= count; i ++) {
-		if (i < count && id == bbids[i]) {
-			continue;
-		}
-
-		opline = op_array->opcodes + start;
-		pbb = bbs_new_bb_ex(bbs, opline, i - start);
-#ifdef ZEND_ENGINE_2
-		pbb->catch = catchbbids[start];
-#endif
-
-		/* last */
-		opline = pbb->opcodes + pbb->count - 1;
-		if (op_get_flowinfo(&fi, opline) == SUCCESS) {
-			if (fi.jmpout_op1 != XC_OPNUM_INVALID) {
-				Z_OP(opline->op1).opline_num = bbids[fi.jmpout_op1];
-				assert(Z_OP(opline->op1).opline_num != BBID_INVALID);
-			}
-			if (fi.jmpout_op2 != XC_OPNUM_INVALID) {
-				Z_OP(opline->op2).opline_num = bbids[fi.jmpout_op2];
-				assert(Z_OP(opline->op2).opline_num != BBID_INVALID);
-			}
-			if (fi.jmpout_ext != XC_OPNUM_INVALID) {
-				opline->extended_value = bbids[fi.jmpout_ext];
-				assert(opline->extended_value != BBID_INVALID);
-			}
-			if (fi.fall && i + 1 < count) {
-				pbb->fall = bbids[i + 1];
-				TRACE("fall %d", pbb->fall);
-				assert(pbb->fall != BBID_INVALID);
-			}
-		}
-		if (i >= count) {
-			break;
-		}
-		start = i;
-		id = bbids[i];
-	}
-	/* }}} */
-
-	my_free_alloca(markbbhead, use_heap_markbbhead);
-#ifdef ZEND_ENGINE_2
-	my_free_alloca(catchbbids, use_heap_catchbbids);
-#endif
-	my_free_alloca(bbids,      use_heap_bbids);
-	return SUCCESS;
-}
-/* }}} */
-static void bbs_restore_opnum(bbs_t *bbs, zend_op_array *op_array) /* {{{ */
-{
-	int i;
-#ifdef ZEND_ENGINE_2
-	bbid_t lasttrybbid;
-	bbid_t lastcatchbbid;
-#endif
-
-	for (i = 0; i < bbs_count(bbs); i ++) {
-		op_flowinfo_t fi;
-		bb_t *bb = bbs_get(bbs, i);
-		zend_op *last = bb->opcodes + bb->count - 1;
-
-		if (op_get_flowinfo(&fi, last) == SUCCESS) {
-			if (fi.jmpout_op1 != XC_OPNUM_INVALID) {
-				Z_OP(last->op1).opline_num = bbs_get(bbs, fi.jmpout_op1)->opnum;
-				assert(Z_OP(last->op1).opline_num != BBID_INVALID);
-			}
-			if (fi.jmpout_op2 != XC_OPNUM_INVALID) {
-				Z_OP(last->op2).opline_num = bbs_get(bbs, fi.jmpout_op2)->opnum;
-				assert(Z_OP(last->op2).opline_num != BBID_INVALID);
-			}
-			if (fi.jmpout_ext != XC_OPNUM_INVALID) {
-				last->extended_value = bbs_get(bbs, fi.jmpout_ext)->opnum;
-				assert(last->extended_value != BBID_INVALID);
-			}
-		}
-	}
-
-#ifdef ZEND_ENGINE_2
-	lasttrybbid   = BBID_INVALID;
-	lastcatchbbid = BBID_INVALID;
-	op_array->last_try_catch = 0;
-	for (i = 0; i < bbs_count(bbs); i ++) {
-		bb_t *bb = bbs_get(bbs, i);
-
-		if (lastcatchbbid != bb->catch) {
-			if (lasttrybbid != BBID_INVALID && lastcatchbbid != BBID_INVALID) {
-				int try_catch_offset = op_array->last_try_catch ++;
-
-				op_array->try_catch_array = erealloc(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch);
-				op_array->try_catch_array[try_catch_offset].try_op = bbs_get(bbs, lasttrybbid)->opnum;
-				op_array->try_catch_array[try_catch_offset].catch_op = bbs_get(bbs, lastcatchbbid)->opnum;
-			}
-			lasttrybbid   = i;
-			lastcatchbbid = bb->catch;
-		}
-	}
-	/* it is impossible to have last bb catched */
-#endif
-}
-/* }}} */
-
-/*
- * optimize
- */
-static int xc_optimize_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	bbs_t bbs;
-
-	if (op_array->type != ZEND_USER_FUNCTION) {
-		return 0;
-	}
-
-#ifdef XCACHE_DEBUG
-#	if 0
-	TRACE("optimize file: %s", op_array->filename);
-	xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC);
-#	endif
-	op_print(0, op_array->opcodes, op_array->opcodes + op_array->last);
-#endif
-
-	if (op_array_convert_switch(op_array) == SUCCESS) {
-		bbs_init(&bbs);
-		if (bbs_build_from(&bbs, op_array, op_array->last) == SUCCESS) {
-			int i;
-#ifdef XCACHE_DEBUG
-			bbs_print(&bbs, op_array->opcodes);
-#endif
-			/* TODO: calc opnum after basic block move */
-			for (i = 0; i < bbs_count(&bbs); i ++) {
-				bb_t *bb = bbs_get(&bbs, i);
-				bb->opnum = bb->opcodes - op_array->opcodes;
-			}
-			bbs_restore_opnum(&bbs, op_array);
-		}
-		bbs_destroy(&bbs);
-	}
-
-#ifdef XCACHE_DEBUG
-#	if 0
-	TRACE("%s", "after compiles");
-	xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC);
-#	endif
-	op_print(0, op_array->opcodes, op_array->opcodes + op_array->last);
-#endif
-	return 0;
-}
-/* }}} */
-void xc_optimizer_op_array_handler(zend_op_array *op_array) /* {{{ */
-{
-	TSRMLS_FETCH();
-	if (XG(optimizer)) {
-		xc_optimize_op_array(op_array TSRMLS_CC);
-	}
-}
-/* }}} */
Index: unk/optimizer.h
===================================================================
--- /trunk/optimizer.h	(revision 981)
+++ 	(revision )
@@ -1,4 +1,0 @@
-#include "php.h"
-#include "xcache.h"
-
-void xc_optimizer_op_array_handler(zend_op_array *op_array);
Index: unk/phpdc.phpr
===================================================================
--- /trunk/phpdc.phpr	(revision 981)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#! /usr/bin/php -dopen_basedir=
-<?php
-
-$srcdir = dirname(__FILE__);
-require_once("$srcdir/Decompiler.class.php");
-if (file_exists("$srcdir/phpdc.debug.php")) {
-	include("$srcdir/phpdc.debug.php");
-}
-
-if (!isset($argv)) {
-	$argv = $_SERVER['argv'];
-	$argc = $_SERVER['argc'];
-}
-
-$dc = new Decompiler();
-if (isset($argv[2])) {
-	eval('$dc->dc = ' . file_get_contents($argv[2]) . ';');
-}
-else if (isset($argv[1])) {
-	$dc->decompileFile($argv[1]);
-}
-else {
-	$phpcode = '';
-	if (!defined('stdin')) {
-		define('stdin', fopen('php://stdin', 'rb'));
-	}
-	while (!feof(stdin)) {
-		$phpcode .= fgets(stdin);
-	}
-	$dc->decompileString($phpcode);
-}
-$dc->output();
-
Index: unk/phpdop.phpr
===================================================================
--- /trunk/phpdop.phpr	(revision 981)
+++ 	(revision )
@@ -1,130 +1,0 @@
-#! /usr/bin/php
-<?php
-
-$srcdir = dirname(__FILE__);
-require_once("$srcdir/Decompiler.class.php");
-if (file_exists("$srcdir/phpdc.debug.php")) {
-	include("$srcdir/phpdc.debug.php");
-}
-
-function get_op($op)
-{
-	switch ($op['op_type']) {
-	case 1: // CONST
-		return var_export($op['constant'], true);
-
-	case 2: // IS_TMP_VAR
-		return 't@' . $op['var'];
-
-	case 4:
-		return 'v$' . $op['var'];
-
-	case 8: // UNUSED
-		if (isset($op['opline_num'])) {
-			return 'l#' . $op['opline_num'];
-		}
-		else {
-			return '-';
-		}
-
-	default:
-		return $op['op_type'] . $op['var'];
-	}
-}
-
-function dump_opcodes($opcodes, $indent = '')
-{
-	global $decompiler;
-
-	$types = array('result' => 5, 'op1' => 20, 'op2' => 20);
-	foreach ($decompiler->fixOpcode($opcodes) as $line => $op) {
-		echo $indent;
-		echo sprintf("%3d ", $op['lineno']);
-		echo sprintf("%3x ", $line);
-		$name = xcache_get_opcode($op['opcode']);
-
-		if (substr($name, 0, 5) == 'ZEND_') {
-			$name = substr($name, 5);
-		}
-		echo str_pad($name, 25);
-
-		foreach ($types as $t => $len) {
-			echo str_pad(isset($op[$t]) ? get_op($op[$t]) : "", $len);
-		}
-		printf("%5s", isset($op['extended_value']) ?  $op['extended_value'] : "");
-
-		echo "\n";
-	}
-}
-
-function dump_function($name, $func, $indent = '')
-{
-	if (isset($func['op_array'])) {
-		$op_array = $func['op_array'];
-		unset($func['op_array']);
-	}
-	else {
-		$op_array = null;
-	}
-	var_dump($func);
-	echo $indent, 'function ', $name, "\n";
-	if (isset($op_array)) {
-		dump_opcodes($op_array['opcodes'], "  " . $indent);
-	}
-}
-
-function dump_class($name, $class, $indent = '')
-{
-	if (isset($class['function_table'])) {
-		$funcs = $class['function_table'];
-		unset($class['function_table']);
-	}
-	else {
-		$funcs = null;
-	}
-	echo $indent, 'class ', $name, "\n";
-	if (isset($funcs)) {
-		foreach ($funcs as $name => $func) {
-			dump_function($name, $func, "  " . $indent);
-		}
-	}
-}
-
-if (!isset($argv[1])) {
-	die("Usage: $argv[0] <file>\n");
-}
-$decompiler = new Decompiler();
-if (isset($argv[2])) {
-	eval('$pk = ' . file_get_contents($argv[2]) . ';');
-}
-else {
-	$pk = xcache_dasm_file($argv[1]);
-}
-$op_array = $funcs = $classes = null;
-if (isset($pk['op_array'])) {
-	$op_array = $pk['op_array'];
-	unset($pk['op_array']);
-}
-if (isset($pk['function_table'])) {
-	$funcs = $pk['function_table'];
-	unset($pk['function_table']);
-}
-if (isset($pk['class_table'])) {
-	$classes = $pk['class_table'];
-	unset($pk['class_table']);
-}
-var_dump($pk);
-if (isset($classes)) {
-	foreach ($classes as $name => $class) {
-		dump_class($name, $class);
-	}
-}
-if (isset($funcs)) {
-	foreach ($funcs as $name => $func) {
-		dump_function($name, $func);
-	}
-}
-if (isset($op_array)) {
-	dump_opcodes($op_array['opcodes']);
-}
-
Index: unk/prepare.devel
===================================================================
--- /trunk/prepare.devel	(revision 981)
+++ 	(revision )
@@ -1,105 +1,0 @@
-#! /bin/bash
-SELF="$0"
-
-if test -e prepare.devel.inc ; then
-	. prepare.devel.inc
-else
-	echo prepare.devel.inc is required, see prepare.devel.inc.example >&2
-	exit
-fi
-
-CTAGS=`which ctags 2>/dev/null || which exuberant-ctags 2>/dev/null `
-AWK=`which gawk 2>/dev/null || which awk 2>/dev/null `
-
-make_all() {
-	make_opcode_spec_def.h
-	make_const_string
-	test -e tags && echo tags exists, skipping. use \""$0" tags\" to rebuild || make_tags
-}
-
-make_clean() {
- 	make_clean_const_string
-	echo "*" rm -f tags opcode_spec_def.h
-	rm -f tags opcode_spec_def.h
-}
-
-make_const_string() {
-	make_const_string_opcodes_php4.x.h
-	make_const_string_opcodes_php5.0.h
-	make_const_string_opcodes_php5.1.h
-	make_const_string_opcodes_php5.4.h
-	make_const_string_opcodes_php6.x.h
-}
-
-make_clean_const_string() {
-	echo "*" rm -f const_string_opcodes_php*.h{,.tmp}
-	rm -f const_string_opcodes_php*.h
-}
-
-make_const_string_opcodes_php4.x.h() {
-	precheck const_string_opcodes_php4.x.h "${PHP4_x_DIR}/Zend/zend_compile.h" && "$AWK" -f ./mkopcode.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
-}
-
-make_const_string_opcodes_php5.0.h() {
-	precheck const_string_opcodes_php5.0.h "${PHP5_0_DIR}/Zend/zend_compile.h" && "$AWK" -f ./mkopcode.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
-}
-
-make_const_string_opcodes_php5.1.h() {
-	precheck const_string_opcodes_php5.1.h "${PHP5_1_DIR}/Zend/zend_vm_def.h"  && "$AWK" -f ./mkopcode.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
-}
-
-make_const_string_opcodes_php5.4.h() {
-	precheck const_string_opcodes_php5.4.h "${PHP5_4_DIR}/Zend/zend_vm_def.h"  && "$AWK" -f ./mkopcode.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
-}
-
-make_const_string_opcodes_php6.x.h() {
-	precheck const_string_opcodes_php6.x.h "${PHP6_x_DIR}/Zend/zend_vm_def.h"  && "$AWK" -f ./mkopcode.awk < "$I" > "$O.tmp" && mv "$O.tmp" "$O"
-}
-
-make_opcode_spec_def.h() {
-	precheck "opcode_spec_def.h" "${EA_DIR}/opcodes.c" && "$AWK" -f ./mkopcode_spec.awk < "$I" > "$O"
-}
-
-make_tags() {
-	if test -z "$CTAGS" ; then
-		echo tool ctags not found, skip building tags >&2
-		return
-	fi
-
-	if test -d "${PHP_DEVEL_DIR}" ; then
-		echo "* Making tags with ${PHP_DEVEL_DIR}"
-		"$CTAGS" -R . "${PHP_DEVEL_DIR}/main" "${PHP_DEVEL_DIR}/Zend" "${PHP_DEVEL_DIR}/TSRM" "${PHP_DEVEL_DIR}/ext/standard"
-	else
-		echo "* Making tags without php source files"
-		"$CTAGS" -R .
-	fi
-}
-
-error() {
-	echo "$@" >&2
-}
-
-precheck() {
-	if test -e "$2" ; then :; else
-		error X skipping "$1" because "$2" not found
-		return 1
-	fi
-	if test "$1" -ot "$2" ; then :; else
-		echo O "$1" is up to date.
-		return 1
-	fi
-	O="$1"
-	I="$2"
-	echo "* Making $1 from $2"
-	return 0
-}
-
-if test -z "$1" ; then
-	make_all
-else
-	while ! test -z "$1" ; do
-		eval "make_$1"
-		shift
-	done
-fi
-
Index: unk/prepare.devel.inc.example
===================================================================
--- /trunk/prepare.devel.inc.example	(revision 981)
+++ 	(revision )
@@ -1,11 +1,0 @@
-# copy this file as devel.prepare.inc before modifying
-PHP4_x_DIR=
-PHP5_0_DIR=
-PHP5_1_DIR=
-PHP5_3_DIR=
-PHP6_x_DIR=
-
-PHP_DEVEL_DIR=
-
-# path to eaccelerator source dir
-EA_DIR=
Index: unk/processor.c
===================================================================
--- /trunk/processor.c	(revision 981)
+++ 	(revision )
@@ -1,1 +1,0 @@
-#include "processor_real.c"
Index: /trunk/processor/head.m4
===================================================================
--- /trunk/processor/head.m4	(revision 981)
+++ /trunk/processor/head.m4	(revision 982)
@@ -11,8 +11,7 @@
 
 #include "xcache.h"
-#include "align.h"
-#include "const_string.h"
-#include "processor.h"
-#include "stack.h"
+#include "util/xc_align.h"
+#include "xc_const_string.h"
+#include "xc_processor.h"
 #include "xcache_globals.h"
 
Index: /trunk/run
===================================================================
--- /trunk/run	(revision 981)
+++ /trunk/run	(revision 982)
@@ -1,102 +1,2 @@
-#!/bin/bash
-# this script is for developers only
-
-. run.cfg
-
-basename=$(basename $(pwd))
-if echo $basename | grep -- - >/dev/null; then :; else
-	dirs=${dirs:-php5-debug}
-	for dir in $dirs; do
-		cd ../${basename}-${dir} || exit
-		pwd
-		$0 "$@"
-	done
-	exit
-fi
-
-if [[ ! -z $1 ]]; then
-	type=$1
-	shift
-
-	if [[ ! -z $1 ]]; then
-		args=("$@")
-	elif [[ -z $args ]]; then
-		args=(test.php)
-	fi
-fi
-
-if [[ $type = make ]]; then
-	MAKEARGS=("$@")
-fi
-
-LANG=C /usr/bin/make $MAKEOPTS "${MAKEARGS[@]}" 2>&1 | hi error warn FAIL
-ret=${PIPESTATUS[0]}
-if [[ $ret -ne 0 || $type = make ]]; then
-	exit $ret
-fi
-
-cmd=()
-tracer=()
-case "$basename" in
-*-apache1*)
-	cmd=($HOME/apache1/bin/httpd -X)
-	;;
-*-apache*)
-	exit 1
-	;;
-*)
-	cmd=(./php-cgi -q -c php.ini)
-	"${cmd[@]}" -v
-	;;
-esac
-
-case "${args[0]}" in
-fcgi)
-	args=(-b 1026)
-	shift
-	;;
-esac
-
-case "$type" in
-ltr*)
-	export USE_ZEND_ALLOC=0
-	tracer=(ltrace -s1024 -e malloc,realloc,free,write)
-	;;
-str*)
-	tracer=(strace -s1024 -T ./php-cgi)
-	;;
-gdb)
-	#USE_ZEND_ALLOC=0
-	tracer=(gdb --args)
-	;;
-val*)
-	export USE_ZEND_ALLOC=0
-	tracer=(valgrind --gen-suppressions=all)
-	;;
-dc)
-	exec ./php-cli -c php.ini ./phpdc.phpr "${args[@]}" | tee decompiled.php
-	;;
-dop)
-	exec ./php-cgi -q -c php.ini ./phpdop.phpr "${args[@]}"
-	;;
-retest)
-	exec make xcachetest "$@" TESTS="`grep '^/.*\.phpt$' php_test_results_*.txt | uniq | xargs`"
-	;;
-test)
-	case "${args[0]}" in
-	*.phpt)
-		exec make xcachetest TEST_ARGS=-v TESTS="${args[*]}"
-		;;
-	*/)
-		exec make xcachetest TESTS="${args[@]}"
-		;;
-	*)
-		exec make xcachetest
-		;;
-	esac
-	;;
-esac
-
-export XCACHE_SKIP_FCGI_WARNING=1
-echo "${tracer[@]}" "${cmd[@]}" "${args[@]}"
-exec "${tracer[@]}" "${cmd[@]}" "${args[@]}"
+#!/bin/sh
+exec devel/run "$@"
Index: unk/stack.c
===================================================================
--- /trunk/stack.c	(revision 981)
+++ 	(revision )
@@ -1,62 +1,0 @@
-#include <stdlib.h>
-#include <assert.h>
-#include "stack.h"
-typedef xc_stack_t* S;
-
-void xc_stack_init_ex(S stack, int initsize)
-{
-	stack->cnt = 0;
-	stack->size = initsize;
-	stack->data = malloc(sizeof(void *) * stack->size);
-}
-
-void xc_stack_destroy(S stack)
-{
-	free(stack->data);
-}
-
-void xc_stack_push(S stack, void *item)
-{
-	if (stack->cnt == stack->size) {
-		stack->size <<= 1;
-		stack->data = realloc(stack->data, sizeof(void *) * stack->size);
-	}
-	stack->data[stack->cnt++] = item;
-}
-
-void* xc_stack_pop(S stack)
-{
-	assert(stack != NULL && stack->size > 0);
-	return stack->data[--stack->cnt];
-}
-
-void* xc_stack_top(S stack)
-{
-	assert(stack != NULL && stack->cnt > 0);
-	return stack->data[stack->cnt-1];
-}
-
-void* xc_stack_get(S stack, int n)
-{
-	assert(stack != NULL && stack->cnt > 0);
-	return stack->data[n];
-}
-
-int xc_stack_count(S stack)
-{
-	assert(stack != NULL);
-	return stack->cnt;
-}
-
-void xc_stack_reverse(S stack)
-{
-	int i, j;
-	void *tmp;
-
-	assert(stack != NULL);
-	for (i = 0, j = stack->cnt - 1; i < j; i ++, j --) {
-		tmp = stack->data[i];
-		stack->data[i] = stack->data[j];
-		stack->data[j] = tmp;
-	}
-}
Index: unk/stack.h
===================================================================
--- /trunk/stack.h	(revision 981)
+++ 	(revision )
@@ -1,18 +1,0 @@
-
-typedef struct {
-	void **data;
-	int cnt;
-	int size;
-} xc_stack_t;
-
-#define S xc_stack_t*
-void xc_stack_init_ex(S stack, int initsize);
-#define xc_stack_init(stack) xc_stack_init_ex(stack, 8)
-void xc_stack_destroy(S stack);
-void xc_stack_push(S stack, void *item);
-void *xc_stack_pop(S stack);
-void *xc_stack_top(S stack);
-void *xc_stack_get(S stack, int n);
-int xc_stack_count(S stack);
-void xc_stack_reverse(S stack);
-#undef S
Index: /trunk/submodules/xc_coverager.c
===================================================================
--- /trunk/submodules/xc_coverager.c	(revision 982)
+++ /trunk/submodules/xc_coverager.c	(revision 982)
@@ -0,0 +1,593 @@
+#if 0
+#define XCACHE_DEBUG
+#endif
+
+#include <stdio.h>
+#include "xcache.h"
+#include "ext/standard/flock_compat.h"
+#ifdef HAVE_SYS_FILE_H
+#	include <sys/file.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "stack.h"
+#include "xcache_globals.h"
+#include "coverager.h"
+#include "utils.h"
+typedef HashTable *coverager_t;
+#define PCOV_HEADER_MAGIC 0x564f4350
+
+static char *xc_coveragedump_dir = NULL;
+static zend_compile_file_t *old_compile_file = NULL;
+
+/* dumper */
+static void xc_destroy_coverage(void *pDest) /* {{{ */
+{
+	coverager_t cov = *(coverager_t*) pDest;
+	TRACE("destroy %p", cov);
+	zend_hash_destroy(cov);
+	efree(cov);
+}
+/* }}} */
+void xcache_mkdirs_ex(char *root, int rootlen, char *path, int pathlen TSRMLS_DC) /* {{{ */
+{
+	char *fullpath;
+	struct stat st;
+	ALLOCA_FLAG(use_heap)
+
+	TRACE("mkdirs %s %d %s %d", root, rootlen, path, pathlen);
+	fullpath = my_do_alloca(rootlen + pathlen + 1, use_heap);
+	memcpy(fullpath, root, rootlen);
+	memcpy(fullpath + rootlen, path, pathlen);
+	fullpath[rootlen + pathlen] = '\0';
+
+	if (stat(fullpath, &st) != 0) {
+		char *chr;
+
+		chr = strrchr(path, PHP_DIR_SEPARATOR);
+		if (chr && chr != path) {
+			*chr = '\0';
+			xcache_mkdirs_ex(root, rootlen, path, chr - path TSRMLS_CC);
+			*chr = PHP_DIR_SEPARATOR;
+		}
+		TRACE("mkdir %s", fullpath);
+#if PHP_MAJOR_VERSION > 5
+		php_stream_mkdir(fullpath, 0700, REPORT_ERRORS, NULL);
+#else
+		mkdir(fullpath, 0700);
+#endif
+	}
+	my_free_alloca(fullpath, use_heap);
+}
+/* }}} */
+static void xc_coverager_save_cov(char *srcfile, char *outfilename, coverager_t cov TSRMLS_DC) /* {{{ */
+{
+	long *buf = NULL, *p;
+	long covlines, *phits;
+	int fd = -1;
+	int size;
+	int newfile;
+	struct stat srcstat, outstat;
+	HashPosition pos;
+	char *contents = NULL;
+	long len;
+
+	if (stat(srcfile, &srcstat) != 0) {
+		return;
+	}
+
+	newfile = 0;
+	if (stat(outfilename, &outstat) != 0) {
+		newfile = 1;
+	}
+	else {
+		if (srcstat.st_mtime > outstat.st_mtime) {
+			newfile = 1;
+		}
+	}
+
+	fd = open(outfilename, O_RDWR | O_CREAT, 0600);
+	if (fd < 0) {
+		char *chr;
+		chr = strrchr(srcfile, PHP_DIR_SEPARATOR);
+		if (chr) {
+			*chr = '\0';
+			xcache_mkdirs_ex(xc_coveragedump_dir, strlen(xc_coveragedump_dir), srcfile, chr - srcfile TSRMLS_CC);
+			*chr = PHP_DIR_SEPARATOR;
+		}
+		fd = open(outfilename, O_RDWR | O_CREAT, 0600);
+		if (fd < 0) {
+			goto bailout;
+		}
+	}
+	if (flock(fd, LOCK_EX) != SUCCESS) {
+		goto bailout;
+	}
+
+	if (newfile) {
+		TRACE("%s", "new file");
+	}
+	else if (outstat.st_size) {
+		len = outstat.st_size;
+		contents = emalloc(len);
+		if (read(fd, (void *) contents, len) != len) {
+			goto bailout;
+		}
+		TRACE("oldsize %d", (int) len);
+		do {
+			p = (long *) contents;
+			len -= sizeof(long);
+			if (len < 0) {
+				break;
+			}
+			if (*p++ != PCOV_HEADER_MAGIC) {
+				TRACE("wrong magic in file %s", outfilename);
+				break;
+			}
+
+			p += 2; /* skip covliens */
+			len -= sizeof(long) * 2;
+			if (len < 0) {
+				break;
+			}
+
+			for (; len >= sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
+				if (zend_hash_index_find(cov, p[0], (void**)&phits) == SUCCESS) {
+					if (p[1] == -1) {
+						/* OPTIMIZE: already marked */
+						continue;
+					}
+					if (*phits != -1) {
+						p[1] += *phits;
+					}
+				}
+				zend_hash_index_update(cov, p[0], &p[1], sizeof(p[1]), NULL);
+			}
+		} while (0);
+		efree(contents);
+		contents = NULL;
+	}
+
+
+	/* serialize */
+	size = (zend_hash_num_elements(cov) + 1) * sizeof(long) * 2 + sizeof(long);
+	p = buf = emalloc(size);
+	*p++ = PCOV_HEADER_MAGIC;
+	p += 2; /* for covlines */
+	covlines = 0;
+
+	zend_hash_internal_pointer_reset_ex(cov, &pos);
+	while (zend_hash_get_current_data_ex(cov, (void**)&phits, &pos) == SUCCESS) {
+		*p++ = pos->h;
+		*p++ = *phits;
+		if (*phits > 0) {
+			covlines ++;
+		}
+		zend_hash_move_forward_ex(cov, &pos);
+	}
+	p = buf + 1;
+	p[0] = 0;
+	p[1] = covlines;
+
+	if (ftruncate(fd, 0) != 0) {
+		goto bailout;
+	}
+	lseek(fd, 0, SEEK_SET);
+	if (write(fd, (char *) buf, size) != size) {
+		goto bailout;
+	}
+
+bailout:
+	if (contents) efree(contents);
+	if (fd >= 0) close(fd);
+	if (buf) efree(buf);
+}
+/* }}} */
+
+static void xc_coverager_initenv(TSRMLS_D) /* {{{ */
+{
+	if (!XG(coverages)) {
+		XG(coverages) = emalloc(sizeof(HashTable));
+		zend_hash_init(XG(coverages), 0, NULL, xc_destroy_coverage, 0);
+	}
+}
+/* }}} */
+static void xc_coverager_clean(TSRMLS_D) /* {{{ */
+{
+	if (XG(coverages)) {
+		HashPosition pos;
+		coverager_t *pcov;
+
+		zend_hash_internal_pointer_reset_ex(XG(coverages), &pos);
+		while (zend_hash_get_current_data_ex(XG(coverages), (void **) &pcov, &pos) == SUCCESS) {
+			long *phits;
+			coverager_t cov;
+			HashPosition pos2;
+
+			cov = *pcov;
+
+			zend_hash_internal_pointer_reset_ex(cov, &pos2);
+			while (zend_hash_get_current_data_ex(cov, (void**)&phits, &pos2) == SUCCESS) {
+				long hits = *phits;
+
+				if (hits != -1) {
+					hits = -1;
+					zend_hash_index_update(cov, pos2->h, &hits, sizeof(hits), NULL);
+				}
+				zend_hash_move_forward_ex(cov, &pos2);
+			}
+
+			zend_hash_move_forward_ex(XG(coverages), &pos);
+		}
+	}
+}
+/* }}} */
+static void xc_coverager_cleanup(TSRMLS_D) /* {{{ */
+{
+	if (XG(coverages)) {
+		zend_hash_destroy(XG(coverages));
+		efree(XG(coverages));
+		XG(coverages) = NULL;
+	}
+}
+/* }}} */
+
+static void xc_coverager_enable(TSRMLS_D) /* {{{ */
+{
+	XG(coverage_enabled) = 1;
+}
+/* }}} */
+static void xc_coverager_disable(TSRMLS_D) /* {{{ */
+{
+	XG(coverage_enabled) = 0;
+}
+/* }}} */
+
+void xc_coverager_request_init(TSRMLS_D) /* {{{ */
+{
+	if (XG(coverager)) {
+		xc_coverager_enable(TSRMLS_C);
+#ifdef ZEND_COMPILE_EXTENDED_INFO
+		CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
+#else
+		CG(extended_info) = 1;
+#endif
+	}
+	else {
+		XG(coverage_enabled) = 0;
+	}
+}
+/* }}} */
+static void xc_coverager_autodump(TSRMLS_D) /* {{{ */
+{
+	coverager_t *pcov;
+	zstr s;
+	char *outfilename;
+	int dumpdir_len, outfilelen, alloc_len = 0;
+	uint size;
+	HashPosition pos;
+
+	if (XG(coverages) && xc_coveragedump_dir) {	
+		dumpdir_len = strlen(xc_coveragedump_dir);
+		alloc_len = dumpdir_len + 1 + 128;
+		outfilename = emalloc(alloc_len);
+		strcpy(outfilename, xc_coveragedump_dir);
+
+		zend_hash_internal_pointer_reset_ex(XG(coverages), &pos);
+		while (zend_hash_get_current_data_ex(XG(coverages), (void **) &pcov, &pos) == SUCCESS) {
+			zend_hash_get_current_key_ex(XG(coverages), &s, &size, NULL, 0, &pos);
+			outfilelen = dumpdir_len + size + 5;
+			if (alloc_len < outfilelen) {
+				alloc_len = outfilelen + 128;
+				outfilename = erealloc(outfilename, alloc_len);
+			}
+			strcpy(outfilename + dumpdir_len, ZSTR_S(s));
+			strcpy(outfilename + dumpdir_len + size - 1, ".pcov");
+
+			TRACE("outfilename %s", outfilename);
+			xc_coverager_save_cov(ZSTR_S(s), outfilename, *pcov TSRMLS_CC);
+			zend_hash_move_forward_ex(XG(coverages), &pos);
+		}
+		efree(outfilename);
+	}
+}
+/* }}} */
+static void xc_coverager_dump(zval *return_value TSRMLS_DC) /* {{{ */
+{
+	coverager_t *pcov;
+	HashPosition pos;
+
+	if (XG(coverages)) {
+		array_init(return_value);
+
+		zend_hash_internal_pointer_reset_ex(XG(coverages), &pos);
+		while (zend_hash_get_current_data_ex(XG(coverages), (void **) &pcov, &pos) == SUCCESS) {
+			zval *lines;
+			long *phits;
+			coverager_t cov;
+			HashPosition pos2;
+			zstr filename;
+			uint size;
+
+			cov = *pcov;
+			zend_hash_get_current_key_ex(XG(coverages), &filename, &size, NULL, 0, &pos);
+
+			MAKE_STD_ZVAL(lines);
+			array_init(lines);
+			zend_hash_internal_pointer_reset_ex(cov, &pos2);
+			while (zend_hash_get_current_data_ex(cov, (void**)&phits, &pos2) == SUCCESS) {
+				long hits = *phits;
+				add_index_long(lines, pos2->h, hits >= 0 ? hits : 0);
+				zend_hash_move_forward_ex(cov, &pos2);
+			}
+			add_assoc_zval_ex(return_value, ZSTR_S(filename), strlen(ZSTR_S(filename)) + 1, lines);
+
+			zend_hash_move_forward_ex(XG(coverages), &pos);
+		}
+	}
+	else {
+		RETVAL_NULL();
+	}
+}
+/* }}} */
+void xc_coverager_request_shutdown(TSRMLS_D) /* {{{ */
+{
+	if (XG(coverager)) {
+		xc_coverager_autodump(TSRMLS_C);
+		xc_coverager_cleanup(TSRMLS_C);
+	}
+}
+/* }}} */
+
+/* helper func to store hits into coverages */
+static coverager_t xc_coverager_get(const char *filename TSRMLS_DC) /* {{{ */
+{
+	int len = strlen(filename) + 1;
+	coverager_t cov, *pcov;
+
+	if (zend_u_hash_find(XG(coverages), IS_STRING, filename, len, (void **) &pcov) == SUCCESS) {
+		TRACE("got coverage %s %p", filename, *pcov);
+		return *pcov;
+	}
+	else {
+		cov = emalloc(sizeof(HashTable));
+		zend_hash_init(cov, 0, NULL, NULL, 0);
+		zend_u_hash_add(XG(coverages), IS_STRING, filename, len, (void **) &cov, sizeof(cov), NULL);
+		TRACE("new coverage %s %p", filename, cov);
+		return cov;
+	}
+}
+/* }}} */
+static void xc_coverager_add_hits(HashTable *cov, long line, long hits TSRMLS_DC) /* {{{ */
+{
+	long *poldhits;
+
+	if (line == 0) {
+		return;
+	}
+	if (zend_hash_index_find(cov, line, (void**)&poldhits) == SUCCESS) {
+		if (hits == -1) {
+			/* OPTIMIZE: -1 == init-ing, but it's already initized */
+			return;
+		}
+		if (*poldhits != -1) {
+			hits += *poldhits;
+		}
+	}
+	zend_hash_index_update(cov, line, &hits, sizeof(hits), NULL);
+}
+/* }}} */
+
+static int xc_coverager_get_op_array_size_no_tail(zend_op_array *op_array) /* {{{ */
+{
+	zend_uint last = op_array->last;
+	do {
+next_op:
+		if (last == 0) {
+			break;
+		}
+		switch (op_array->opcodes[last - 1].opcode) {
+#ifdef ZEND_HANDLE_EXCEPTION
+			case ZEND_HANDLE_EXCEPTION:
+#endif
+			case ZEND_RETURN:
+			case ZEND_EXT_STMT:
+				--last;
+				goto next_op;
+		}
+	} while (0);
+	return last;
+}
+/* }}} */
+
+/* prefill */
+static int xc_coverager_init_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	zend_uint size;
+	coverager_t cov;
+	zend_uint i;
+
+	if (op_array->type != ZEND_USER_FUNCTION) {
+		return 0;
+	}
+
+	size = xc_coverager_get_op_array_size_no_tail(op_array);
+	cov = xc_coverager_get(op_array->filename TSRMLS_CC);
+	for (i = 0; i < size; i ++) {
+		switch (op_array->opcodes[i].opcode) {
+			case ZEND_EXT_STMT:
+#if 0
+			case ZEND_EXT_FCALL_BEGIN:
+			case ZEND_EXT_FCALL_END:
+#endif
+				xc_coverager_add_hits(cov, op_array->opcodes[i].lineno, -1 TSRMLS_CC);
+				break;
+		}
+	}
+	return 0;
+}
+/* }}} */
+static void xc_coverager_init_compile_result(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	xc_compile_result_t cr;
+
+	xc_compile_result_init_cur(&cr, op_array TSRMLS_CC);
+	xc_apply_op_array(&cr, (apply_func_t) xc_coverager_init_op_array TSRMLS_CC);
+	xc_compile_result_free(&cr);
+}
+/* }}} */
+static zend_op_array *xc_compile_file_for_coverage(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */
+{
+	zend_op_array *op_array;
+
+	op_array = old_compile_file(h, type TSRMLS_CC);
+	if (op_array) {
+		if (XG(coverager)) {
+			xc_coverager_initenv(TSRMLS_C);
+			xc_coverager_init_compile_result(op_array TSRMLS_CC);
+		}
+	}
+	return op_array;
+}
+/* }}} */
+
+/* hits */
+void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op) /* {{{ */
+{
+	TSRMLS_FETCH();
+
+	if (XG(coverages) && XG(coverage_enabled)) {
+		int size = xc_coverager_get_op_array_size_no_tail(op_array);
+		int oplineno = (*EG(opline_ptr)) - op_array->opcodes;
+		if (oplineno < size) {
+			xc_coverager_add_hits(xc_coverager_get(op_array->filename TSRMLS_CC), (*EG(opline_ptr))->lineno, 1 TSRMLS_CC);
+		}
+	}
+}
+/* }}} */
+
+/* init/destroy */
+int xc_coverager_init(int module_number TSRMLS_DC) /* {{{ */
+{
+	old_compile_file = zend_compile_file;
+	zend_compile_file = xc_compile_file_for_coverage;
+
+	if (cfg_get_string("xcache.coveragedump_directory", &xc_coveragedump_dir) == SUCCESS && xc_coveragedump_dir) {
+		int len;
+		xc_coveragedump_dir = pestrdup(xc_coveragedump_dir, 1);
+		len = strlen(xc_coveragedump_dir);
+		if (len) {
+			if (xc_coveragedump_dir[len - 1] == '/') {
+				xc_coveragedump_dir[len - 1] = '\0';
+			}
+		}
+		if (!strlen(xc_coveragedump_dir)) {
+			pefree(xc_coveragedump_dir, 1);
+			xc_coveragedump_dir = NULL;
+		}
+	}
+
+	return SUCCESS;
+}
+/* }}} */
+void xc_coverager_destroy() /* {{{ */
+{
+	if (old_compile_file == xc_compile_file_for_coverage) {
+		zend_compile_file = old_compile_file;
+	}
+	if (xc_coveragedump_dir) {
+		pefree(xc_coveragedump_dir, 1);
+		xc_coveragedump_dir = NULL;
+	}
+}
+/* }}} */
+
+/* user api */
+/* {{{ proto array xcache_coverager_decode(string data)
+ * decode specified data which is saved by auto dumper to array
+ */
+PHP_FUNCTION(xcache_coverager_decode)
+{
+	char *str;
+	int len;
+	long *p;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) {
+		return;
+	}
+
+	array_init(return_value);
+
+	p = (long*) str;
+	len -= sizeof(long);
+	if (len < 0) {
+		return;
+	}
+	if (*p++ != PCOV_HEADER_MAGIC) {
+		TRACE("%s", "wrong magic in xcache_coverager_decode");
+		return;
+	}
+
+	for (; len >= sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
+		add_index_long(return_value, p[0], p[1] < 0 ? 0 : p[1]);
+	}
+}
+/* }}} */
+/* {{{ proto void xcache_coverager_start([bool clean = true])
+ * starts coverager data collecting
+ */
+PHP_FUNCTION(xcache_coverager_start)
+{
+	zend_bool clean = 1;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
+		return;
+	}
+
+	if (clean) {
+		xc_coverager_clean(TSRMLS_C);
+	}
+
+	if (XG(coverager)) {
+		xc_coverager_enable(TSRMLS_C);
+	}
+	else {
+		php_error(E_WARNING, "You can only start coverager after you set 'xcache.coverager' to 'On' in ini");
+	}
+}
+/* }}} */
+/* {{{ proto void xcache_coverager_stop([bool clean = false])
+ * stop coverager data collecting
+ */
+PHP_FUNCTION(xcache_coverager_stop)
+{
+	zend_bool clean = 0;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
+		return;
+	}
+
+	xc_coverager_disable(TSRMLS_C);
+	if (clean) {
+		xc_coverager_clean(TSRMLS_C);
+	}
+}
+/* }}} */
+/* {{{ proto array xcache_coverager_get([bool clean = false])
+ * get coverager data collected
+ */
+PHP_FUNCTION(xcache_coverager_get)
+{
+	zend_bool clean = 0;
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
+		return;
+	}
+
+	xc_coverager_dump(return_value TSRMLS_CC);
+	if (clean) {
+		xc_coverager_clean(TSRMLS_C);
+	}
+}
+/* }}} */
Index: /trunk/submodules/xc_coverager.h
===================================================================
--- /trunk/submodules/xc_coverager.h	(revision 982)
+++ /trunk/submodules/xc_coverager.h	(revision 982)
@@ -0,0 +1,12 @@
+#include "php.h"
+#include "xcache.h"
+
+void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op);
+int xc_coverager_init(int module_number TSRMLS_DC);
+void xc_coverager_destroy();
+void xc_coverager_request_init(TSRMLS_D);
+void xc_coverager_request_shutdown(TSRMLS_D);
+PHP_FUNCTION(xcache_coverager_decode);
+PHP_FUNCTION(xcache_coverager_start);
+PHP_FUNCTION(xcache_coverager_stop);
+PHP_FUNCTION(xcache_coverager_get);
Index: /trunk/submodules/xc_disassembler.c
===================================================================
--- /trunk/submodules/xc_disassembler.c	(revision 982)
+++ /trunk/submodules/xc_disassembler.c	(revision 982)
@@ -0,0 +1,189 @@
+#include "xc_disassembler.h"
+#include "xcache.h"
+#include "xc_utils.h"
+#include "xc_processor.h"
+
+static void xc_dasm(zval *output, zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	const Bucket *b;
+	zval *zv, *list;
+	xc_compile_result_t cr;
+	int bufsize = 2;
+	char *buf;
+	xc_dasm_t dasm;
+
+	xc_compile_result_init_cur(&cr, op_array TSRMLS_CC);
+
+	xc_apply_op_array(&cr, (apply_func_t) xc_undo_pass_two TSRMLS_CC);
+	xc_apply_op_array(&cr, (apply_func_t) xc_fix_opcode TSRMLS_CC);
+
+	/* go */
+	array_init(output);
+
+	ALLOC_INIT_ZVAL(zv);
+	array_init(zv);
+	xc_dasm_zend_op_array(&dasm, zv, op_array TSRMLS_CC);
+	add_assoc_zval_ex(output, ZEND_STRS("op_array"), zv);
+
+	buf = emalloc(bufsize);
+
+	ALLOC_INIT_ZVAL(list);
+	array_init(list);
+	for (b = xc_sandbox_user_function_begin(TSRMLS_C); b; b = b->pListNext) {
+		int keysize, keyLength;
+
+		ALLOC_INIT_ZVAL(zv);
+		array_init(zv);
+		xc_dasm_zend_function(&dasm, zv, b->pData TSRMLS_CC);
+
+		keysize = BUCKET_KEY_SIZE(b) + 2;
+		if (keysize > bufsize) {
+			do {
+				bufsize *= 2;
+			} while (keysize > bufsize);
+			buf = erealloc(buf, bufsize);
+		}
+		memcpy(buf, BUCKET_KEY_S(b), keysize);
+		buf[keysize - 2] = buf[keysize - 1] = ""[0];
+		keyLength = b->nKeyLength;
+#ifdef IS_UNICODE
+		if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
+			if (buf[0] == ""[0] && buf[1] == ""[0]) {
+				keyLength ++;
+			}
+		} else
+#endif
+		{
+			if (buf[0] == ""[0]) {
+				keyLength ++;
+			}
+		}
+
+		add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
+	}
+	add_assoc_zval_ex(output, ZEND_STRS("function_table"), list);
+	
+	ALLOC_INIT_ZVAL(list);
+	array_init(list);
+	for (b = xc_sandbox_user_class_begin(TSRMLS_C); b; b = b->pListNext) {
+		int keysize, keyLength;
+
+		ALLOC_INIT_ZVAL(zv);
+		array_init(zv);
+		xc_dasm_zend_class_entry(&dasm, zv, CestToCePtr(*(xc_cest_t *)b->pData) TSRMLS_CC);
+
+		keysize = BUCKET_KEY_SIZE(b) + 2;
+		if (keysize > bufsize) {
+			do {
+				bufsize *= 2;
+			} while (keysize > bufsize);
+			buf = erealloc(buf, bufsize);
+		}
+		memcpy(buf, BUCKET_KEY_S(b), keysize);
+		buf[keysize - 2] = buf[keysize - 1] = ""[0];
+		keyLength = b->nKeyLength;
+#ifdef IS_UNICODE
+		if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
+			if (buf[0] == ""[0] && buf[1] == ""[0]) {
+				keyLength ++;
+			}
+		} else
+#endif
+		{
+			if (buf[0] == ""[0]) {
+				keyLength ++;
+			}
+		}
+		add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
+	}
+	efree(buf);
+	add_assoc_zval_ex(output, ZEND_STRS("class_table"), list);
+
+	/*xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);*/
+	xc_compile_result_free(&cr);
+}
+/* }}} */
+typedef struct xc_dasm_sandboxed_t { /* {{{ */
+	enum Type {
+		xc_dasm_file_t
+		, xc_dasm_string_t
+	} type;
+	union {
+		zval *zfilename;
+		struct {
+			zval *source;
+			char *eval_name;
+		} compile_string;
+	} input;
+
+	zval *output;
+} xc_dasm_sandboxed_t; /* {{{ */
+
+zend_op_array *xc_dasm_sandboxed(void *data TSRMLS_DC)
+{
+	zend_bool catched = 0;
+	zend_op_array *op_array = NULL;
+	xc_dasm_sandboxed_t *sandboxed_dasm = (xc_dasm_sandboxed_t *) data;
+
+	zend_try {
+		if (sandboxed_dasm->type == xc_dasm_file_t) {
+			op_array = compile_filename(ZEND_REQUIRE, sandboxed_dasm->input.zfilename TSRMLS_CC);
+		}
+		else {
+			op_array = compile_string(sandboxed_dasm->input.compile_string.source, sandboxed_dasm->input.compile_string.eval_name TSRMLS_CC);
+		}
+	} zend_catch {
+		catched = 1;
+	} zend_end_try();
+
+	if (catched || !op_array) {
+#define return_value sandboxed_dasm->output
+		RETVAL_FALSE;
+#undef return_value
+		return NULL;
+	}
+
+	xc_dasm(sandboxed_dasm->output, op_array TSRMLS_CC);
+
+	/* free */
+#ifdef ZEND_ENGINE_2
+	destroy_op_array(op_array TSRMLS_CC);
+#else
+	destroy_op_array(op_array);
+#endif
+	efree(op_array);
+
+	return NULL;
+} /* }}} */
+void xc_dasm_string(zval *output, zval *source TSRMLS_DC) /* {{{ */
+{
+	xc_dasm_sandboxed_t sandboxed_dasm;
+	char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
+
+	sandboxed_dasm.output = output;
+	sandboxed_dasm.type = xc_dasm_string_t;
+	sandboxed_dasm.input.compile_string.source = source;
+	sandboxed_dasm.input.compile_string.eval_name = eval_name;
+	xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, eval_name TSRMLS_CC);
+	efree(eval_name);
+}
+/* }}} */
+void xc_dasm_file(zval *output, const char *filename TSRMLS_DC) /* {{{ */
+{
+	zval *zfilename;
+	xc_dasm_sandboxed_t sandboxed_dasm;
+
+	MAKE_STD_ZVAL(zfilename);
+	zfilename->value.str.val = estrdup(filename);
+	zfilename->value.str.len = strlen(filename);
+	zfilename->type = IS_STRING;
+
+	sandboxed_dasm.output = output;
+	sandboxed_dasm.type = xc_dasm_file_t;
+	sandboxed_dasm.input.zfilename = zfilename;
+	xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, zfilename->value.str.val TSRMLS_CC);
+
+	zval_dtor(zfilename);
+	FREE_ZVAL(zfilename);
+}
+/* }}} */
Index: /trunk/submodules/xc_disassembler.h
===================================================================
--- /trunk/submodules/xc_disassembler.h	(revision 982)
+++ /trunk/submodules/xc_disassembler.h	(revision 982)
@@ -0,0 +1,4 @@
+#include "php.h"
+
+void xc_dasm_string(zval *return_value, zval *code TSRMLS_DC);
+void xc_dasm_file(zval *return_value, const char *filename TSRMLS_DC);
Index: /trunk/submodules/xc_optimizer.c
===================================================================
--- /trunk/submodules/xc_optimizer.c	(revision 982)
+++ /trunk/submodules/xc_optimizer.c	(revision 982)
@@ -0,0 +1,616 @@
+#if 0
+#	define XCACHE_DEBUG
+#endif
+
+#include "utils.h"
+#include "optimizer.h"
+/* the "vector" stack */
+#include "stack.h"
+#include "xcache_globals.h"
+
+#ifdef XCACHE_DEBUG
+#	include "processor.h"
+#	include "const_string.h"
+#	include "ext/standard/php_var.h"
+#endif
+
+#ifdef IS_CV
+#	define XCACHE_IS_CV IS_CV
+#else
+#	define XCACHE_IS_CV 16
+#endif
+
+#ifdef ZEND_ENGINE_2_4
+#	undef Z_OP_CONSTANT
+/* Z_OP_CONSTANT is used before pass_two is applied */
+#	define Z_OP_CONSTANT(op) op_array->literals[op.constant].constant
+#endif
+
+typedef int bbid_t;
+enum {
+	BBID_INVALID = -1
+};
+/* {{{ basic block */
+typedef struct _bb_t {
+	bbid_t     id;
+	zend_bool  used;
+
+	zend_bool  alloc;
+	zend_op   *opcodes;
+	int        count;
+	int        size;
+
+	bbid_t     fall;
+#ifdef ZEND_ENGINE_2
+	bbid_t     catch;
+#endif
+
+	int        opnum; /* opnum after joining basic block */
+} bb_t;
+/* }}} */
+
+/* basic blocks */
+typedef xc_stack_t bbs_t;
+
+/* op array helper functions */
+static int op_array_convert_switch(zend_op_array *op_array) /* {{{ */
+{
+	int i;
+
+	if (op_array->brk_cont_array == NULL) {
+		return SUCCESS;
+	}
+
+	for (i = 0; i < op_array->last; i ++) {
+		zend_op *opline = &op_array->opcodes[i];
+		zend_brk_cont_element *jmp_to;
+		zend_bool can_convert = 1;
+		int array_offset, nest_levels, original_nest_levels;
+
+		switch (opline->opcode) {
+		case ZEND_BRK:
+		case ZEND_CONT:
+			break;
+
+#ifdef ZEND_GOTO
+		case ZEND_GOTO:
+#endif
+			continue;
+
+		default:
+			continue;
+		}
+
+		if (Z_OP_TYPE(opline->op2) != IS_CONST
+		 || Z_OP_CONSTANT(opline->op2).type != IS_LONG) {
+			return FAILURE;
+		}
+
+		nest_levels = Z_OP_CONSTANT(opline->op2).value.lval;
+		original_nest_levels = nest_levels;
+
+		array_offset = Z_OP(opline->op1).opline_num;
+		do {
+			if (array_offset == -1) {
+				/* this is a runtime error in ZE
+				zend_error(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
+				*/
+				return FAILURE;
+			}
+			jmp_to = &op_array->brk_cont_array[array_offset];
+			if (nest_levels > 1) {
+				zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
+
+				switch (brk_opline->opcode) {
+				case ZEND_SWITCH_FREE:
+				case ZEND_FREE:
+#ifdef EXT_TYPE_FREE_ON_RETURN
+					if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN))
+#endif
+					{
+						can_convert = 0;
+					}
+					break;
+				}
+			}
+			array_offset = jmp_to->parent;
+		} while (--nest_levels > 0);
+
+		if (can_convert) {
+			/* rewrite to jmp */
+			switch (opline->opcode) {
+			case ZEND_BRK:
+				Z_OP(opline->op1).opline_num = jmp_to->brk;
+				break;
+
+			case ZEND_CONT:
+				Z_OP(opline->op1).opline_num = jmp_to->cont;
+				break;
+			}
+			Z_OP_TYPE(opline->op2) = IS_UNUSED;
+			opline->opcode = ZEND_JMP;
+		}
+	}
+
+	return SUCCESS;
+}
+/* }}} */
+/* {{{ op_flowinfo helper func */
+enum {
+	XC_OPNUM_INVALID = -1,
+};
+typedef struct {
+	int       jmpout_op1;
+	int       jmpout_op2;
+	int       jmpout_ext;
+	zend_bool fall;
+} op_flowinfo_t;
+static void op_flowinfo_init(op_flowinfo_t *fi)
+{
+	fi->jmpout_op1 = fi->jmpout_op2 = fi->jmpout_ext = XC_OPNUM_INVALID;
+	fi->fall = 0;
+}
+/* }}} */
+static int op_get_flowinfo(op_flowinfo_t *fi, zend_op *opline) /* {{{ */
+{
+	op_flowinfo_init(fi);
+
+	/* break=will fall */
+	switch (opline->opcode) {
+#ifdef ZEND_HANDLE_EXCEPTION
+	case ZEND_HANDLE_EXCEPTION:
+#endif
+	case ZEND_RETURN:
+	case ZEND_EXIT:
+		return SUCCESS; /* no fall */
+
+	case ZEND_JMP:
+		fi->jmpout_op1 = Z_OP(opline->op1).opline_num;
+		return SUCCESS; /* no fall */
+
+	case ZEND_JMPZNZ:
+		fi->jmpout_op2 = Z_OP(opline->op2).opline_num;
+		fi->jmpout_ext = (int) opline->extended_value;
+		return SUCCESS; /* no fall */
+
+	case ZEND_JMPZ:
+	case ZEND_JMPNZ:
+	case ZEND_JMPZ_EX:
+	case ZEND_JMPNZ_EX:
+#ifdef ZEND_JMP_SET
+	case ZEND_JMP_SET:
+#endif
+#ifdef ZEND_JMP_NO_CTOR
+	case ZEND_JMP_NO_CTOR:
+#endif
+#ifdef ZEND_NEW
+	case ZEND_NEW:
+#endif
+#ifdef ZEND_FE_RESET
+	case ZEND_FE_RESET:
+#endif      
+	case ZEND_FE_FETCH:
+		fi->jmpout_op2 = Z_OP(opline->op2).opline_num;
+		break;
+
+#ifdef ZEND_CATCH
+	case ZEND_CATCH:
+		fi->jmpout_ext = (int) opline->extended_value;
+		break;
+#endif
+
+	default:
+		return FAILURE;
+	}
+
+	fi->fall = 1;
+	return SUCCESS;
+}
+/* }}} */
+#ifdef XCACHE_DEBUG
+static void op_snprint(char *buf, int size, zend_uchar op_type, znode_op *op) /* {{{ */
+{
+	switch (op_type) {
+	case IS_CONST:
+		{
+			zval result;
+			zval *zv = &Z_OP_CONSTANT(*op);
+			TSRMLS_FETCH();
+
+			/* TODO: update for PHP 6 */
+			php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
+			php_var_export(&zv, 1 TSRMLS_CC);
+
+			php_ob_get_buffer(&result TSRMLS_CC); 
+			php_end_ob_buffer(0, 0 TSRMLS_CC);
+			snprintf(buf, size, Z_STRVAL(result));
+			zval_dtor(&result);
+		}
+		break;
+
+	case IS_TMP_VAR:
+		snprintf(buf, size, "t@%d", Z_OP(*op).var);
+		break;
+
+	case XCACHE_IS_CV:
+	case IS_VAR:
+		snprintf(buf, size, "v@%d", Z_OP(*op).var);
+		break;
+
+	case IS_UNUSED:
+		if (Z_OP(*op).opline_num) {
+			snprintf(buf, size, "u#%d", Z_OP(op).opline_num);
+		}
+		else {
+			snprintf(buf, size, "-");
+		}
+		break;
+
+	default:
+		snprintf(buf, size, "%d %d", op->op_type, Z_OP(op).var);
+	}
+}
+/* }}} */
+static void op_print(int line, zend_op *first, zend_op *end) /* {{{ */
+{
+	zend_op *opline;
+	for (opline = first; opline < end; opline ++) {
+		char buf_r[20];
+		char buf_1[20];
+		char buf_2[20];
+		op_snprint(buf_r, sizeof(buf_r), Z_OP_TYPE(opline->result), &opline->result);
+		op_snprint(buf_1, sizeof(buf_1), Z_OP_TYPE(opline->op1),    &opline->op1);
+		op_snprint(buf_2, sizeof(buf_2), Z_OP_TYPE(opline->op2),    &opline->op2);
+		fprintf(stderr,
+				"%3d %3d"
+				" %-25s%-5s%-20s%-20s%5lu\r\n"
+				, opline->lineno, opline - first + line
+				, xc_get_opcode(opline->opcode), buf_r, buf_1, buf_2, opline->extended_value);
+	}
+}
+/* }}} */
+#endif
+
+/*
+ * basic block functions
+ */
+
+static bb_t *bb_new_ex(zend_op *opcodes, int count) /* {{{ */
+{
+	bb_t *bb = (bb_t *) ecalloc(sizeof(bb_t), 1);
+
+	bb->fall       = BBID_INVALID;
+#ifdef ZEND_ENGINE_2
+	bb->catch      = BBID_INVALID;
+#endif
+
+	if (opcodes) {
+		bb->alloc   = 0;
+		bb->size    = bb->count = count;
+		bb->opcodes = opcodes;
+	}
+	else {
+		bb->alloc   = 1;
+		bb->size    = bb->count = 8;
+		bb->opcodes = ecalloc(sizeof(zend_op), bb->size);
+	}
+
+	return bb;
+}
+/* }}} */
+#define bb_new() bb_new_ex(NULL, 0)
+static void bb_destroy(bb_t *bb) /* {{{ */
+{
+	if (bb->alloc) {
+		efree(bb->opcodes);
+	}
+	efree(bb);
+}
+/* }}} */
+#ifdef XCACHE_DEBUG
+static void bb_print(bb_t *bb, zend_op *opcodes) /* {{{ */
+{
+	int line = bb->opcodes - opcodes;
+	op_flowinfo_t fi;
+	zend_op *last = bb->opcodes + bb->count - 1;
+	bbid_t catchbbid;
+#ifdef ZEND_ENGINE_2
+	catchbbid = BBID_INVALID;
+#else
+	catchbbid = bb->catch;
+#endif
+
+	op_get_flowinfo(&fi, last);
+
+	fprintf(stderr,
+			"\r\n==== #%-3d cnt:%-3d lno:%-3d"
+			" %c%c"
+			" op1:%-3d op2:%-3d ext:%-3d fal:%-3d cat:%-3d %s ====\r\n"
+			, bb->id, bb->count, bb->alloc ? -1 : line
+			, bb->used ? 'U' : ' ', bb->alloc ? 'A' : ' '
+			, fi.jmpout_op1, fi.jmpout_op2, fi.jmpout_ext, bb->fall, catchbbid, xc_get_opcode(last->opcode)
+			);
+	op_print(line, bb->opcodes, last + 1);
+}
+/* }}} */
+#endif
+
+static bb_t *bbs_get(bbs_t *bbs, int n) /* {{{ */
+{
+	return (bb_t *) xc_stack_get(bbs, n);
+}
+/* }}} */
+static int bbs_count(bbs_t *bbs) /* {{{ */
+{
+	return xc_stack_count(bbs);
+}
+/* }}} */
+static void bbs_destroy(bbs_t *bbs) /* {{{ */
+{
+	bb_t *bb;
+	while (bbs_count(bbs)) {
+		bb = (bb_t *) xc_stack_pop(bbs);
+		bb_destroy(bb);
+	}
+	xc_stack_destroy(bbs);
+}
+/* }}} */
+#ifdef XCACHE_DEBUG
+static void bbs_print(bbs_t *bbs, zend_op *opcodes) /* {{{ */
+{
+	int i;
+	for (i = 0; i < xc_stack_count(bbs); i ++) {
+		bb_print(bbs_get(bbs, i), opcodes);
+	}
+}
+/* }}} */
+#endif
+#define bbs_init(bbs) xc_stack_init_ex(bbs, 16)
+static bb_t *bbs_add_bb(bbs_t *bbs, bb_t *bb) /* {{{ */
+{
+	bb->id = (bbid_t) xc_stack_count(bbs);
+	xc_stack_push(bbs, (void *) bb);
+	return bb;
+}
+/* }}} */
+static bb_t *bbs_new_bb_ex(bbs_t *bbs, zend_op *opcodes, int count) /* {{{ */
+{
+	return bbs_add_bb(bbs, bb_new_ex(opcodes, count));
+}
+/* }}} */
+static int bbs_build_from(bbs_t *bbs, zend_op_array *op_array, int count) /* {{{ */
+{
+	int i, start;
+	bb_t *pbb;
+	bbid_t id;
+	op_flowinfo_t fi;
+	zend_op *opline;
+	ALLOCA_FLAG(use_heap_bbids)
+	ALLOCA_FLAG(use_heap_catchbbids)
+	ALLOCA_FLAG(use_heap_markbbhead)
+	bbid_t *bbids          = my_do_alloca(count * sizeof(bbid_t),    use_heap_bbids);
+#ifdef ZEND_ENGINE_2
+	bbid_t *catchbbids     = my_do_alloca(count * sizeof(bbid_t),    use_heap_catchbbids);
+#endif
+	zend_bool *markbbhead  = my_do_alloca(count * sizeof(zend_bool), use_heap_markbbhead);
+
+	/* {{{ mark jmpin/jumpout */
+	memset(markbbhead,  0, count * sizeof(zend_bool));
+
+	markbbhead[0] = 1;
+	for (i = 0; i < count; i ++) {
+		if (op_get_flowinfo(&fi, &op_array->opcodes[i]) == SUCCESS) {
+			if (fi.jmpout_op1 != XC_OPNUM_INVALID) {
+				markbbhead[fi.jmpout_op1] = 1;
+			}
+			if (fi.jmpout_op2 != XC_OPNUM_INVALID) {
+				markbbhead[fi.jmpout_op2] = 1;
+			}
+			if (fi.jmpout_ext != XC_OPNUM_INVALID) {
+				markbbhead[fi.jmpout_ext] = 1;
+			}
+			if (i + 1 < count) {
+				markbbhead[i + 1] = 1;
+			}
+		}
+	}
+#ifdef ZEND_ENGINE_2
+	/* mark try start */
+	for (i = 0; i < op_array->last_try_catch; i ++) {
+		markbbhead[op_array->try_catch_array[i].try_op] = 1;
+	}
+#endif
+	/* }}} */
+	/* {{{ fill op lines with newly allocated id */
+	for (i = 0; i < count; i ++) {
+		bbids[i] = BBID_INVALID;
+	}
+
+	id = -1;
+	for (i = 0; i < count; i ++) {
+		if (markbbhead[i]) {
+			id ++;
+		}
+		bbids[i] = id;
+		TRACE("bbids[%d] = %d", i, id);
+	}
+	/* }}} */
+#ifdef ZEND_ENGINE_2
+	/* {{{ fill op lines with catch id */
+	for (i = 0; i < count; i ++) {
+		catchbbids[i] = BBID_INVALID;
+	}
+
+	for (i = 0; i < op_array->last_try_catch; i ++) {
+		int j;
+		zend_try_catch_element *e = &op_array->try_catch_array[i];
+		for (j = e->try_op; j < e->catch_op; j ++) {
+			catchbbids[j] = bbids[e->catch_op];
+		}
+	}
+#ifdef XCACHE_DEBUG
+	for (i = 0; i < count; i ++) {
+		TRACE("catchbbids[%d] = %d", i, catchbbids[i]);
+	}
+#endif
+	/* }}} */
+#endif
+	/* {{{ create basic blocks */
+	start = 0;
+	id = 0;
+	/* loop over to deal with the last block */
+	for (i = 1; i <= count; i ++) {
+		if (i < count && id == bbids[i]) {
+			continue;
+		}
+
+		opline = op_array->opcodes + start;
+		pbb = bbs_new_bb_ex(bbs, opline, i - start);
+#ifdef ZEND_ENGINE_2
+		pbb->catch = catchbbids[start];
+#endif
+
+		/* last */
+		opline = pbb->opcodes + pbb->count - 1;
+		if (op_get_flowinfo(&fi, opline) == SUCCESS) {
+			if (fi.jmpout_op1 != XC_OPNUM_INVALID) {
+				Z_OP(opline->op1).opline_num = bbids[fi.jmpout_op1];
+				assert(Z_OP(opline->op1).opline_num != BBID_INVALID);
+			}
+			if (fi.jmpout_op2 != XC_OPNUM_INVALID) {
+				Z_OP(opline->op2).opline_num = bbids[fi.jmpout_op2];
+				assert(Z_OP(opline->op2).opline_num != BBID_INVALID);
+			}
+			if (fi.jmpout_ext != XC_OPNUM_INVALID) {
+				opline->extended_value = bbids[fi.jmpout_ext];
+				assert(opline->extended_value != BBID_INVALID);
+			}
+			if (fi.fall && i + 1 < count) {
+				pbb->fall = bbids[i + 1];
+				TRACE("fall %d", pbb->fall);
+				assert(pbb->fall != BBID_INVALID);
+			}
+		}
+		if (i >= count) {
+			break;
+		}
+		start = i;
+		id = bbids[i];
+	}
+	/* }}} */
+
+	my_free_alloca(markbbhead, use_heap_markbbhead);
+#ifdef ZEND_ENGINE_2
+	my_free_alloca(catchbbids, use_heap_catchbbids);
+#endif
+	my_free_alloca(bbids,      use_heap_bbids);
+	return SUCCESS;
+}
+/* }}} */
+static void bbs_restore_opnum(bbs_t *bbs, zend_op_array *op_array) /* {{{ */
+{
+	int i;
+#ifdef ZEND_ENGINE_2
+	bbid_t lasttrybbid;
+	bbid_t lastcatchbbid;
+#endif
+
+	for (i = 0; i < bbs_count(bbs); i ++) {
+		op_flowinfo_t fi;
+		bb_t *bb = bbs_get(bbs, i);
+		zend_op *last = bb->opcodes + bb->count - 1;
+
+		if (op_get_flowinfo(&fi, last) == SUCCESS) {
+			if (fi.jmpout_op1 != XC_OPNUM_INVALID) {
+				Z_OP(last->op1).opline_num = bbs_get(bbs, fi.jmpout_op1)->opnum;
+				assert(Z_OP(last->op1).opline_num != BBID_INVALID);
+			}
+			if (fi.jmpout_op2 != XC_OPNUM_INVALID) {
+				Z_OP(last->op2).opline_num = bbs_get(bbs, fi.jmpout_op2)->opnum;
+				assert(Z_OP(last->op2).opline_num != BBID_INVALID);
+			}
+			if (fi.jmpout_ext != XC_OPNUM_INVALID) {
+				last->extended_value = bbs_get(bbs, fi.jmpout_ext)->opnum;
+				assert(last->extended_value != BBID_INVALID);
+			}
+		}
+	}
+
+#ifdef ZEND_ENGINE_2
+	lasttrybbid   = BBID_INVALID;
+	lastcatchbbid = BBID_INVALID;
+	op_array->last_try_catch = 0;
+	for (i = 0; i < bbs_count(bbs); i ++) {
+		bb_t *bb = bbs_get(bbs, i);
+
+		if (lastcatchbbid != bb->catch) {
+			if (lasttrybbid != BBID_INVALID && lastcatchbbid != BBID_INVALID) {
+				int try_catch_offset = op_array->last_try_catch ++;
+
+				op_array->try_catch_array = erealloc(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch);
+				op_array->try_catch_array[try_catch_offset].try_op = bbs_get(bbs, lasttrybbid)->opnum;
+				op_array->try_catch_array[try_catch_offset].catch_op = bbs_get(bbs, lastcatchbbid)->opnum;
+			}
+			lasttrybbid   = i;
+			lastcatchbbid = bb->catch;
+		}
+	}
+	/* it is impossible to have last bb catched */
+#endif
+}
+/* }}} */
+
+/*
+ * optimize
+ */
+static int xc_optimize_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	bbs_t bbs;
+
+	if (op_array->type != ZEND_USER_FUNCTION) {
+		return 0;
+	}
+
+#ifdef XCACHE_DEBUG
+#	if 0
+	TRACE("optimize file: %s", op_array->filename);
+	xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC);
+#	endif
+	op_print(0, op_array->opcodes, op_array->opcodes + op_array->last);
+#endif
+
+	if (op_array_convert_switch(op_array) == SUCCESS) {
+		bbs_init(&bbs);
+		if (bbs_build_from(&bbs, op_array, op_array->last) == SUCCESS) {
+			int i;
+#ifdef XCACHE_DEBUG
+			bbs_print(&bbs, op_array->opcodes);
+#endif
+			/* TODO: calc opnum after basic block move */
+			for (i = 0; i < bbs_count(&bbs); i ++) {
+				bb_t *bb = bbs_get(&bbs, i);
+				bb->opnum = bb->opcodes - op_array->opcodes;
+			}
+			bbs_restore_opnum(&bbs, op_array);
+		}
+		bbs_destroy(&bbs);
+	}
+
+#ifdef XCACHE_DEBUG
+#	if 0
+	TRACE("%s", "after compiles");
+	xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC);
+#	endif
+	op_print(0, op_array->opcodes, op_array->opcodes + op_array->last);
+#endif
+	return 0;
+}
+/* }}} */
+void xc_optimizer_op_array_handler(zend_op_array *op_array) /* {{{ */
+{
+	TSRMLS_FETCH();
+	if (XG(optimizer)) {
+		xc_optimize_op_array(op_array TSRMLS_CC);
+	}
+}
+/* }}} */
Index: /trunk/submodules/xc_optimizer.h
===================================================================
--- /trunk/submodules/xc_optimizer.h	(revision 982)
+++ /trunk/submodules/xc_optimizer.h	(revision 982)
@@ -0,0 +1,4 @@
+#include "php.h"
+#include "xcache.h"
+
+void xc_optimizer_op_array_handler(zend_op_array *op_array);
Index: unk/test.mak
===================================================================
--- /trunk/test.mak	(revision 981)
+++ 	(revision )
@@ -1,21 +1,0 @@
-#! /usr/bin/make -f
-
-EXES=mem_test
-OBJS=mem.o
-CC=gcc
-CFLAGS=-g -O0 -D TEST -Wall
-TEST=valgrind
-
-all: mem
-
-mem_test: mem.c
-	$(CC) $(CFLAGS) -o mem_test mem.c
-	
-mem: mem_test
-	$(TEST) ./mem_test
-
-clean:
-	rm -f $(OBJS) $(EXES)
-
-leakcheck:
-	valgrind php -c test.ini test.ini
Index: /trunk/util/README
===================================================================
--- /trunk/util/README	(revision 982)
+++ /trunk/util/README	(revision 982)
@@ -0,0 +1,1 @@
+generic utility stuffs unrelatived to ZendEngine
Index: /trunk/util/xc_align.h
===================================================================
--- /trunk/util/xc_align.h	(revision 982)
+++ /trunk/util/xc_align.h	(revision 982)
@@ -0,0 +1,19 @@
+#ifndef __ALIGN_H
+#define __ALIGN_H
+#ifndef ALIGN
+typedef union align_union {
+	double d;
+	void *v;
+	int (*func)(int);
+	long l;
+} align_union;
+
+#if (defined (__GNUC__) && __GNUC__ >= 2)
+#define XCACHE_PLATFORM_ALIGNMENT (__alignof__ (align_union))
+#else
+#define XCACHE_PLATFORM_ALIGNMENT (sizeof(align_union))
+#endif
+
+#define ALIGN(n) ((((size_t)(n)-1) & ~(XCACHE_PLATFORM_ALIGNMENT-1)) + XCACHE_PLATFORM_ALIGNMENT)
+#endif
+#endif /* __ALIGN_H */
Index: /trunk/util/xc_foreachcoresig.h
===================================================================
--- /trunk/util/xc_foreachcoresig.h	(revision 982)
+++ /trunk/util/xc_foreachcoresig.h	(revision 982)
@@ -0,0 +1,50 @@
+/* all signals generate coredump by default is list here */
+
+#ifdef SIGABRT
+FOREACH_SIG(SIGABRT);
+#endif
+
+#ifdef SIGBUS
+FOREACH_SIG(SIGBUS);
+#endif
+
+#ifdef SIGEMT
+FOREACH_SIG(SIGEMT);
+#endif
+
+#ifdef SIGFPE
+FOREACH_SIG(SIGFPE);
+#endif
+
+#ifdef SIGILL
+FOREACH_SIG(SIGILL);
+#endif
+
+#ifdef SIGIOT
+FOREACH_SIG(SIGIOT);
+#endif
+
+#ifdef SIGQUIT
+FOREACH_SIG(SIGQUIT);
+#endif
+
+#ifdef SIGSEGV
+FOREACH_SIG(SIGSEGV);
+#endif
+
+#ifdef SIGSYS
+FOREACH_SIG(SIGSYS);
+#endif
+
+#ifdef SIGTRAP
+FOREACH_SIG(SIGTRAP);
+#endif
+
+#ifdef SIGXCPU
+FOREACH_SIG(SIGXCPU);
+#endif
+
+#ifdef SIGXFSZ
+FOREACH_SIG(SIGXFSZ);
+#endif
+
Index: /trunk/util/xc_stack.c
===================================================================
--- /trunk/util/xc_stack.c	(revision 982)
+++ /trunk/util/xc_stack.c	(revision 982)
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <assert.h>
+#include "xc_stack.h"
+typedef xc_stack_t* S;
+
+void xc_stack_init_ex(S stack, int initsize)
+{
+	stack->cnt = 0;
+	stack->size = initsize;
+	stack->data = malloc(sizeof(void *) * stack->size);
+}
+
+void xc_stack_destroy(S stack)
+{
+	free(stack->data);
+}
+
+void xc_stack_push(S stack, void *item)
+{
+	if (stack->cnt == stack->size) {
+		stack->size <<= 1;
+		stack->data = realloc(stack->data, sizeof(void *) * stack->size);
+	}
+	stack->data[stack->cnt++] = item;
+}
+
+void* xc_stack_pop(S stack)
+{
+	assert(stack != NULL && stack->size > 0);
+	return stack->data[--stack->cnt];
+}
+
+void* xc_stack_top(S stack)
+{
+	assert(stack != NULL && stack->cnt > 0);
+	return stack->data[stack->cnt-1];
+}
+
+void* xc_stack_get(S stack, int n)
+{
+	assert(stack != NULL && stack->cnt > 0);
+	return stack->data[n];
+}
+
+int xc_stack_count(S stack)
+{
+	assert(stack != NULL);
+	return stack->cnt;
+}
+
+void xc_stack_reverse(S stack)
+{
+	int i, j;
+	void *tmp;
+
+	assert(stack != NULL);
+	for (i = 0, j = stack->cnt - 1; i < j; i ++, j --) {
+		tmp = stack->data[i];
+		stack->data[i] = stack->data[j];
+		stack->data[j] = tmp;
+	}
+}
Index: /trunk/util/xc_stack.h
===================================================================
--- /trunk/util/xc_stack.h	(revision 982)
+++ /trunk/util/xc_stack.h	(revision 982)
@@ -0,0 +1,22 @@
+#ifndef __XC_UTIL_STACK
+#define __XC_UTIL_STACK
+
+typedef struct {
+	void **data;
+	int cnt;
+	int size;
+} xc_stack_t;
+
+#define S xc_stack_t*
+void xc_stack_init_ex(S stack, int initsize);
+#define xc_stack_init(stack) xc_stack_init_ex(stack, 8)
+void xc_stack_destroy(S stack);
+void xc_stack_push(S stack, void *item);
+void *xc_stack_pop(S stack);
+void *xc_stack_top(S stack);
+void *xc_stack_get(S stack, int n);
+int xc_stack_count(S stack);
+void xc_stack_reverse(S stack);
+#undef S
+
+#endif /* __XC_UTIL_STACK */
Index: /trunk/util/xc_vector.h
===================================================================
--- /trunk/util/xc_vector.h	(revision 982)
+++ /trunk/util/xc_vector.h	(revision 982)
@@ -0,0 +1,56 @@
+#ifndef XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B
+#define XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+typedef struct {
+	zend_uint size;
+	zend_uint cnt;
+	void *data;
+} xc_vector_t;
+
+#define xc_vector_init(type, vector) do { \
+	(vector)->cnt = 0;     \
+	(vector)->size = 0;    \
+	(vector)->data = NULL; \
+} while (0)
+
+#define xc_vector_add(type, vector, value) do { \
+	if ((vector)->cnt == (vector)->size) { \
+		if ((vector)->size) { \
+			(vector)->size <<= 1; \
+			(vector)->data = erealloc((vector)->data, sizeof(type) * (vector)->size); \
+		} \
+		else { \
+			(vector)->size = 8; \
+			(vector)->data = emalloc(sizeof(type) * (vector)->size); \
+		} \
+	} \
+	((type *) (vector)->data)[(vector)->cnt++] = value; \
+} while (0)
+
+static inline void *xc_vector_detach_impl(xc_vector_t *vector)
+{
+	void *data = vector->data;
+	vector->data = NULL;
+	vector->size = 0;
+	vector->cnt = 0;
+	return data;
+}
+
+#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(vector))
+
+static inline void xc_vector_free_impl(xc_vector_t *vector TSRMLS_DC)
+{
+	if (vector->data) {
+		efree(vector->data);
+	}
+	vector->size = 0;
+	vector->cnt = 0;
+}
+
+#define xc_vector_free(type, vector) xc_vector_free_impl(vector TSRMLS_CC)
+
+#endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */
Index: unk/utils.c
===================================================================
--- /trunk/utils.c	(revision 981)
+++ 	(revision )
@@ -1,1135 +1,0 @@
-
-#include "xcache.h"
-#include "stack.h"
-#include "xcache_globals.h"
-#include "utils.h"
-#ifdef ZEND_ENGINE_2_1
-#include "zend_vm.h"
-#endif
-#include "opcode_spec.h"
-#undef NDEBUG
-#include "assert.h"
-
-#ifndef max
-#define max(a, b) ((a) < (b) ? (b) : (a))
-#endif
-
-#ifndef ZEND_VM_SET_OPCODE_HANDLER
-#	define ZEND_VM_SET_OPCODE_HANDLER(opline) do { } while (0)
-#endif
-
-#ifdef ZEND_ENGINE_2_4
-#	define OP_ZVAL_DTOR(op) do { } while(0)
-#else
-#	define OP_ZVAL_DTOR(op) do { \
-		Z_UNSET_ISREF(Z_OP_CONSTANT(op)); \
-		zval_dtor(&Z_OP_CONSTANT(op)); \
-	} while(0)
-#endif
-
-static void (*old_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) = NULL;
-static void call_old_zend_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, ...) /* {{{ */
-{
-	va_list args;
-	va_start(args, format);
-	old_zend_error_cb(type, error_filename, error_lineno, format, args);
-}
-/* }}} */
-
-xc_compile_result_t *xc_compile_result_init(xc_compile_result_t *cr, /* {{{ */
-		zend_op_array *op_array,
-		HashTable *function_table,
-		HashTable *class_table)
-{
-	assert(cr);
-	cr->op_array       = op_array;
-	cr->function_table = function_table;
-	cr->class_table    = class_table;
-	return cr;
-}
-/* }}} */
-xc_compile_result_t *xc_compile_result_init_cur(xc_compile_result_t *cr, zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	assert(cr);
-	return xc_compile_result_init(cr, op_array, CG(function_table), CG(class_table));
-}
-/* }}} */
-void xc_compile_result_free(xc_compile_result_t *cr) /* {{{ */
-{
-}
-/* }}} */
-
-int xc_apply_function(zend_function *zf, apply_func_t applyer TSRMLS_DC) /* {{{ */
-{
-	switch (zf->type) {
-	case ZEND_USER_FUNCTION:
-	case ZEND_EVAL_CODE:
-		return applyer(&zf->op_array TSRMLS_CC);
-		break;
-
-	case ZEND_INTERNAL_FUNCTION:
-	case ZEND_OVERLOADED_FUNCTION:
-		break;
-
-	EMPTY_SWITCH_DEFAULT_CASE();
-	}
-	return 0;
-}
-/* }}} */
-typedef struct {
-	apply_func_t applyer;
-	zend_class_entry *ce;
-} xc_apply_method_info;
-int xc_apply_method(zend_function *zf, xc_apply_method_info *mi TSRMLS_DC) /* {{{ */
-{
-	/* avoid duplicate apply for shadowed method */
-#ifdef ZEND_ENGINE_2
-	if (mi->ce != zf->common.scope) {
-		/* fprintf(stderr, "avoided duplicate %s\n", zf->common.function_name); */
-		return 0;
-	}
-#else
-	char *name = zf->common.function_name;
-	int name_s = strlen(name) + 1;
-	zend_class_entry *ce;
-	zend_function *ptr;
-
-	for (ce = mi->ce->parent; ce; ce = ce->parent) {
-		if (zend_hash_find(&ce->function_table, name, name_s, (void **) &ptr) == SUCCESS) {
-			if (ptr->op_array.refcount == zf->op_array.refcount) {
-				return 0;
-			}
-		}
-	}
-#endif
-	return xc_apply_function(zf, mi->applyer TSRMLS_CC);
-}
-/* }}} */
-#if 0
-int xc_apply_class(zend_class_entry *ce, apply_func_t applyer TSRMLS_DC) /* {{{ */
-{
-	xc_apply_method_info mi;
-
-	mi.applyer = applyer;
-	mi.ce      = ce;
-	zend_hash_apply_with_argument(&(ce->function_table), (apply_func_arg_t) xc_apply_method, &mi TSRMLS_CC);
-	return 0;
-}
-/* }}} */
-#endif
-static int xc_apply_cest(xc_cest_t *cest, apply_func_t applyer TSRMLS_DC) /* {{{ */
-{
-	xc_apply_method_info mi;
-
-	mi.applyer = applyer;
-	mi.ce      = CestToCePtr(*cest);
-	zend_hash_apply_with_argument(&(CestToCePtr(*cest)->function_table), (apply_func_arg_t) xc_apply_method, &mi TSRMLS_CC);
-	return 0;
-}
-/* }}} */
-int xc_apply_op_array(xc_compile_result_t *cr, apply_func_t applyer TSRMLS_DC) /* {{{ */
-{
-	zend_hash_apply_with_argument(cr->function_table, (apply_func_arg_t) xc_apply_function, (void *) applyer TSRMLS_CC);
-	zend_hash_apply_with_argument(cr->class_table, (apply_func_arg_t) xc_apply_cest, (void *) applyer TSRMLS_CC);
-
-	return applyer(cr->op_array TSRMLS_CC);
-}
-/* }}} */
-int xc_undo_pass_two(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	zend_op *opline, *end;
-
-#ifdef ZEND_ENGINE_2_4
-	if (!(op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO)) {
-		return 0;
-	}
-#else
-	if (!op_array->done_pass_two) {
-		return 0;
-	}
-#endif
-
-	opline = op_array->opcodes;
-	end = opline + op_array->last;
-	while (opline < end) {
-#ifdef ZEND_ENGINE_2_4
-		if (opline->op1_type == IS_CONST) {
-			opline->op1.constant = opline->op1.literal - op_array->literals;
-		}
-		if (opline->op2_type == IS_CONST) {
-			opline->op2.constant = opline->op2.literal - op_array->literals;
-		}
-#endif
-
-#ifdef ZEND_ENGINE_2_1
-		switch (opline->opcode) {
-#ifdef ZEND_GOTO
-			case ZEND_GOTO:
-#endif
-			case ZEND_JMP:
-				assert(Z_OP(opline->op1).jmp_addr >= op_array->opcodes && (zend_uint) (Z_OP(opline->op1).jmp_addr - op_array->opcodes) < op_array->last);
-				Z_OP(opline->op1).opline_num = Z_OP(opline->op1).jmp_addr - op_array->opcodes;
-				break;
-			case ZEND_JMPZ:
-			case ZEND_JMPNZ:
-			case ZEND_JMPZ_EX:
-			case ZEND_JMPNZ_EX:
-#ifdef ZEND_JMP_SET
-			case ZEND_JMP_SET:
-#endif
-#ifdef ZEND_JMP_SET_VAR
-			case ZEND_JMP_SET_VAR:
-#endif
-				assert(Z_OP(opline->op2).jmp_addr >= op_array->opcodes && (zend_uint) (Z_OP(opline->op2).jmp_addr - op_array->opcodes) < op_array->last);
-				Z_OP(opline->op2).opline_num = Z_OP(opline->op2).jmp_addr - op_array->opcodes;
-				break;
-		}
-#endif
-		opline++;
-	}
-#ifdef ZEND_ENGINE_2_4
-	op_array->fn_flags &= ~ZEND_ACC_DONE_PASS_TWO;
-#else
-	op_array->done_pass_two = 0;
-#endif
-
-	return 0;
-}
-/* }}} */
-int xc_redo_pass_two(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	zend_op *opline, *end;
-#ifdef ZEND_ENGINE_2_4
-	zend_literal *literal = op_array->literals;
-#endif
-
-#ifdef ZEND_ENGINE_2_4
-	if ((op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO)) {
-		return 0;
-	}
-#else
-	if (op_array->done_pass_two) {
-		return 0;
-	}
-#endif
-
-	/*
-	op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last);
-	op_array->size = op_array->last;
-	*/
-#ifdef ZEND_ENGINE_2_4
-	if (literal) {
-		zend_literal *end = literal + op_array->last_literal;
-		while (literal < end) {
-			Z_SET_ISREF(literal->constant);
-			Z_SET_REFCOUNT(literal->constant, 2); /* Make sure is_ref won't be reset */
-			literal++;
-		}
-	}
-#endif
-
-	opline = op_array->opcodes;
-	end = opline + op_array->last;
-	while (opline < end) {
-#ifdef ZEND_ENGINE_2_4
-		if (opline->op1_type == IS_CONST) {
-			opline->op1.literal = op_array->literals + opline->op1.constant;
-		}
-		if (opline->op2_type == IS_CONST) {
-			opline->op2.literal = op_array->literals + opline->op2.constant;
-		}
-#else
-		if (Z_OP_TYPE(opline->op1) == IS_CONST) {
-			Z_SET_ISREF(Z_OP_CONSTANT(opline->op1));
-			Z_SET_REFCOUNT(Z_OP_CONSTANT(opline->op1), 2); /* Make sure is_ref won't be reset */
-		}
-		if (Z_OP_TYPE(opline->op2) == IS_CONST) {
-			Z_SET_ISREF(Z_OP_CONSTANT(opline->op2));
-			Z_SET_REFCOUNT(Z_OP_CONSTANT(opline->op2), 2);
-		}
-#endif
-#ifdef ZEND_ENGINE_2_1
-		switch (opline->opcode) {
-#ifdef ZEND_GOTO
-			case ZEND_GOTO:
-#endif
-			case ZEND_JMP:
-				assert(Z_OP(opline->op1).opline_num < op_array->last);
-				Z_OP(opline->op1).jmp_addr = op_array->opcodes + Z_OP(opline->op1).opline_num;
-				break;
-			case ZEND_JMPZ:
-			case ZEND_JMPNZ:
-			case ZEND_JMPZ_EX:
-			case ZEND_JMPNZ_EX:
-#ifdef ZEND_JMP_SET
-			case ZEND_JMP_SET:
-#endif
-				assert(Z_OP(opline->op2).opline_num < op_array->last);
-				Z_OP(opline->op2).jmp_addr = op_array->opcodes + Z_OP(opline->op2).opline_num;
-				break;
-		}
-		ZEND_VM_SET_OPCODE_HANDLER(opline);
-#endif
-		opline++;
-	}
-
-#ifdef ZEND_ENGINE_2_4
-	op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
-#else
-	op_array->done_pass_two = 1;
-#endif
-	return 0;
-}
-/* }}} */
-
-#ifdef HAVE_XCACHE_OPCODE_SPEC_DEF
-static void xc_fix_opcode_ex_znode(int tofix, xc_op_spec_t spec, Z_OP_TYPEOF_TYPE *op_type, znode_op *op, int type TSRMLS_DC) /* {{{ */
-{
-#ifdef ZEND_ENGINE_2
-	if ((*op_type != IS_UNUSED && (spec == OPSPEC_UCLASS || spec == OPSPEC_CLASS)) ||
-			spec == OPSPEC_FETCH) {
-		if (tofix) {
-			switch (*op_type) {
-			case IS_VAR:
-			case IS_TMP_VAR:
-				break;
-
-			default:
-				/* TODO: data lost, find a way to keep it */
-				/* assert(*op_type == IS_CONST); */
-				*op_type = IS_TMP_VAR;
-			}
-		}
-	}
-	switch (*op_type) {
-	case IS_TMP_VAR:
-	case IS_VAR:
-		if (tofix) {
-			Z_OP(*op).var /= sizeof(temp_variable);
-		}
-		else {
-			Z_OP(*op).var *= sizeof(temp_variable);
-		}
-	}
-#endif
-}
-/* }}} */
-
-static void xc_fix_opcode_ex(zend_op_array *op_array, int tofix TSRMLS_DC) /* {{{ */
-{
-	zend_op *opline;
-	zend_uint i;
-
-	opline = op_array->opcodes;
-	for (i = 0; i < op_array->last; i ++, opline ++) {
-		/* 3rd optimizer may have ... */
-		if (opline->opcode < xc_get_opcode_spec_count()) {
-			const xc_opcode_spec_t *spec;
-			spec = xc_get_opcode_spec(opline->opcode);
-
-			xc_fix_opcode_ex_znode(tofix, spec->op1, &Z_OP_TYPE(opline->op1),    &opline->op1, 0 TSRMLS_CC);
-			xc_fix_opcode_ex_znode(tofix, spec->op2, &Z_OP_TYPE(opline->op2),    &opline->op2, 1 TSRMLS_CC);
-			xc_fix_opcode_ex_znode(tofix, spec->res, &Z_OP_TYPE(opline->result), &opline->result, 2 TSRMLS_CC);
-		}
-	}
-}
-/* }}} */
-int xc_fix_opcode(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	xc_fix_opcode_ex(op_array, 1 TSRMLS_CC);
-	return 0;
-}
-/* }}} */
-int xc_undo_fix_opcode(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	xc_fix_opcode_ex(op_array, 0 TSRMLS_CC);
-
-	return 0;
-}
-/* }}} */
-#endif
-
-int xc_foreach_early_binding_class(zend_op_array *op_array, void (*callback)(zend_op *opline, int oplineno, void *data TSRMLS_DC), void *data TSRMLS_DC) /* {{{ */
-{
-	zend_op *opline, *begin, *end, *next = NULL;
-
-	opline = begin = op_array->opcodes;
-	end = opline + op_array->last;
-	while (opline < end) {
-		switch (opline->opcode) {
-#ifdef ZEND_GOTO
-			case ZEND_GOTO:
-#endif
-			case ZEND_JMP:
-				next = begin + Z_OP(opline->op1).opline_num;
-				break;
-
-			case ZEND_JMPZNZ:
-				next = begin + max(Z_OP(opline->op2).opline_num, opline->extended_value);
-				break;
-
-			case ZEND_JMPZ:
-			case ZEND_JMPNZ:
-			case ZEND_JMPZ_EX:
-			case ZEND_JMPNZ_EX:
-#ifdef ZEND_JMP_SET
-			case ZEND_JMP_SET:
-#endif
-				next = begin + Z_OP(opline->op2).opline_num;
-				break;
-
-			case ZEND_RETURN:
-				opline = end;
-				break;
-
-#ifdef ZEND_ENGINE_2
-			case ZEND_DECLARE_INHERITED_CLASS:
-				callback(opline, opline - begin, data TSRMLS_CC);
-				break;
-#else
-			case ZEND_DECLARE_FUNCTION_OR_CLASS:
-				if (opline->extended_value == ZEND_DECLARE_INHERITED_CLASS) {
-					callback(opline, opline - begin, data TSRMLS_CC);
-				}
-				break;
-#endif
-		}
-
-		if (opline < next) {
-			opline = next;
-		}
-		else {
-			opline ++;
-		}
-	}
-	return SUCCESS;
-}
-/* }}} */
-#ifndef ZEND_COMPILE_DELAYED_BINDING
-static int xc_do_early_binding(zend_op_array *op_array, HashTable *class_table, int oplineno TSRMLS_DC) /* {{{ */
-{
-	zend_op *opline;
-
-	TRACE("binding %d", oplineno);
-	assert(oplineno >= 0);
-
-	/* do early binding */
-	opline = &(op_array->opcodes[oplineno]);
-
-	switch (opline->opcode) {
-#ifdef ZEND_ENGINE_2
-	case ZEND_DECLARE_INHERITED_CLASS:
-		{
-			zval *parent_name;
-			zend_class_entry **pce;
-
-			/* don't early-bind classes that implement interfaces */
-			if ((opline + 1)->opcode == ZEND_FETCH_CLASS && (opline + 2)->opcode == ZEND_ADD_INTERFACE) {
-				return FAILURE;
-			}
-
-			parent_name = &(Z_OP_CONSTANT((opline - 1)->op2));
-			TRACE("binding with parent %s", Z_STRVAL_P(parent_name));
-			if (zend_lookup_class(Z_STRVAL_P(parent_name), Z_STRLEN_P(parent_name), &pce TSRMLS_CC) == FAILURE) {
-				return FAILURE;
-			}
-
-			if (do_bind_inherited_class(opline, class_table, *pce, 1 TSRMLS_CC) == NULL) {
-				return FAILURE;
-			}
-		}
-
-		/* clear unnecessary ZEND_FETCH_CLASS opcode */
-		if (opline > op_array->opcodes
-		 && (opline - 1)->opcode == ZEND_FETCH_CLASS) {
-			zend_op *fetch_class_opline = opline - 1;
-
-			TRACE("%s %p", Z_STRVAL(Z_OP_CONSTANT(fetch_class_opline->op2)), Z_STRVAL(Z_OP_CONSTANT(fetch_class_opline->op2)));
-			OP_ZVAL_DTOR(fetch_class_opline->op2);
-			fetch_class_opline->opcode = ZEND_NOP;
-			ZEND_VM_SET_OPCODE_HANDLER(fetch_class_opline);
-			memset(&fetch_class_opline->op1, 0, sizeof(znode));
-			memset(&fetch_class_opline->op2, 0, sizeof(znode));
-			SET_UNUSED(fetch_class_opline->op1);
-			SET_UNUSED(fetch_class_opline->op2);
-			SET_UNUSED(fetch_class_opline->result);
-		}
-
-		/* clear unnecessary ZEND_VERIFY_ABSTRACT_CLASS opcode */
-		if ((opline + 1)->opcode == ZEND_VERIFY_ABSTRACT_CLASS) {
-			zend_op *abstract_op = opline + 1;
-			memset(abstract_op, 0, sizeof(abstract_op[0]));
-			abstract_op->lineno = 0;
-			SET_UNUSED(abstract_op->op1);
-			SET_UNUSED(abstract_op->op2);
-			SET_UNUSED(abstract_op->result);
-			abstract_op->opcode = ZEND_NOP;
-			ZEND_VM_SET_OPCODE_HANDLER(abstract_op);
-		}
-#else
-	case ZEND_DECLARE_FUNCTION_OR_CLASS:
-		if (do_bind_function_or_class(opline, NULL, class_table, 1) == FAILURE) {
-			return FAILURE;
-		}
-#endif
-		break;
-
-	default:
-		return FAILURE;
-	}
-
-	zend_hash_del(class_table, Z_OP_CONSTANT(opline->op1).value.str.val, Z_OP_CONSTANT(opline->op1).value.str.len);
-	OP_ZVAL_DTOR(opline->op1);
-	OP_ZVAL_DTOR(opline->op2);
-	opline->opcode = ZEND_NOP;
-	ZEND_VM_SET_OPCODE_HANDLER(opline);
-	memset(&opline->op1, 0, sizeof(znode));
-	memset(&opline->op2, 0, sizeof(znode));
-	SET_UNUSED(opline->op1);
-	SET_UNUSED(opline->op2);
-	return SUCCESS;
-}
-/* }}} */
-#endif
-
-#ifdef HAVE_XCACHE_CONSTANT
-void xc_install_constant(ZEND_24(NOTHING, const) char *filename, zend_constant *constant, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC) /* {{{ */
-{
-	if (zend_u_hash_add(EG(zend_constants), type, key, len,
-				constant, sizeof(zend_constant),
-				NULL
-				) == FAILURE) {
-		CG(zend_lineno) = 0;
-#ifdef IS_UNICODE
-		zend_error(E_NOTICE, "Constant %R already defined", type, key);
-#else
-		zend_error(E_NOTICE, "Constant %s already defined", key);
-#endif
-		free(ZSTR_V(constant->name));
-		if (!(constant->flags & CONST_PERSISTENT)) {
-			zval_dtor(&constant->value);
-		}
-	}
-}
-/* }}} */
-#endif
-void xc_install_function(ZEND_24(NOTHING, const) char *filename, zend_function *func, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC) /* {{{ */
-{
-	zend_bool istmpkey;
-
-	if (func->type == ZEND_USER_FUNCTION) {
-#ifdef IS_UNICODE
-		istmpkey = (type == IS_STRING && ZSTR_S(key)[0] == 0) || ZSTR_U(key)[0] == 0;
-#else
-		istmpkey = ZSTR_S(key)[0] == 0;
-#endif
-		if (istmpkey) {
-			zend_u_hash_update(CG(function_table), type, key, len,
-						func, sizeof(zend_op_array),
-						NULL
-						);
-		}
-		else if (zend_u_hash_add(CG(function_table), type, key, len,
-					func, sizeof(zend_op_array),
-					NULL
-					) == FAILURE) {
-			CG(zend_lineno) = ZESW(func->op_array.opcodes[0].lineno, func->op_array.line_start);
-#ifdef IS_UNICODE
-			zend_error(E_ERROR, "Cannot redeclare %R()", type, key);
-#else
-			zend_error(E_ERROR, "Cannot redeclare %s()", key);
-#endif
-		}
-	}
-}
-/* }}} */
-ZESW(xc_cest_t *, void) xc_install_class(ZEND_24(NOTHING, const) char *filename, xc_cest_t *cest, int oplineno, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC) /* {{{ */
-{
-	zend_bool istmpkey;
-	zend_class_entry *cep = CestToCePtr(*cest);
-	ZESW(void *stored_ce_ptr, NOTHING);
-
-#ifdef IS_UNICODE
-	istmpkey = (type == IS_STRING && ZSTR_S(key)[0] == 0) || ZSTR_U(key)[0] == 0;
-#else
-	istmpkey = ZSTR_S(key)[0] == 0;
-#endif
-	if (istmpkey) {
-		zend_u_hash_quick_update(CG(class_table), type, key, len, h,
-					cest, sizeof(xc_cest_t),
-					ZESW(&stored_ce_ptr, NULL)
-					);
-#ifndef ZEND_COMPILE_DELAYED_BINDING
-		if (oplineno != -1) {
-			xc_do_early_binding(CG(active_op_array), CG(class_table), oplineno TSRMLS_CC);
-		}
-#endif
-	}
-	else if (zend_u_hash_quick_add(CG(class_table), type, key, len, h,
-				cest, sizeof(xc_cest_t),
-				ZESW(&stored_ce_ptr, NULL)
-				) == FAILURE) {
-		CG(zend_lineno) = ZESW(0, Z_CLASS_INFO(*cep).line_start);
-#ifdef IS_UNICODE
-		zend_error(E_ERROR, "Cannot redeclare class %R", type, cep->name);
-#else
-		zend_error(E_ERROR, "Cannot redeclare class %s", cep->name);
-#endif
-		assert(oplineno == -1);
-	}
-	ZESW(return (xc_cest_t *) stored_ce_ptr, NOTHING);
-}
-/* }}} */
-
-typedef struct { /* sandbox {{{ */
-	ZEND_24(NOTHING, const) char *filename;
-
-	HashTable orig_included_files;
-	HashTable *tmp_included_files;
-
-#ifdef HAVE_XCACHE_CONSTANT
-	HashTable *orig_zend_constants;
-	HashTable tmp_zend_constants;
-#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;
-#ifdef HAVE_XCACHE_CONSTANT
-	Bucket    *tmp_internal_constant_tail;
-#endif
-	Bucket    *tmp_internal_function_tail;
-	Bucket    *tmp_internal_class_tail;
-
-#ifdef XCACHE_ERROR_CACHING
-	int orig_user_error_handler_error_reporting;
-	zend_uint compilererror_cnt;
-	zend_uint compilererror_size;
-	xc_compilererror_t *compilererrors;
-#endif
-
-#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
-	zend_uint orig_compiler_options;
-#endif
-} xc_sandbox_t;
-
-#undef TG
-#undef OG
-#define TG(x) (sandbox->tmp_##x)
-#define OG(x) (sandbox->orig_##x)
-/* }}} */
-#ifdef XCACHE_ERROR_CACHING
-static void xc_sandbox_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) /* {{{ */
-{
-	xc_compilererror_t *compilererror;
-	xc_sandbox_t *sandbox;
-	TSRMLS_FETCH();
-
-	sandbox = (xc_sandbox_t *) XG(sandbox);
-	if (!sandbox) {
-		old_zend_error_cb(type, error_filename, error_lineno, format, args);
-		return;
-	}
-
-	switch (type) {
-#ifdef E_STRICT
-	case E_STRICT:
-#endif
-#ifdef E_DEPRECATED
-	case E_DEPRECATED:
-#endif
-		if (sandbox->compilererror_cnt <= sandbox->compilererror_size) {
-			if (sandbox->compilererror_size) {
-				sandbox->compilererror_size += 16;
-				sandbox->compilererrors = erealloc(sandbox->compilererrors, sandbox->compilererror_size * sizeof(sandbox->compilererrors));
-			}
-			else {
-				sandbox->compilererror_size = 16;
-				sandbox->compilererrors = emalloc(sandbox->compilererror_size * sizeof(sandbox->compilererrors));
-			}
-		}
-		compilererror = &sandbox->compilererrors[sandbox->compilererror_cnt++];
-		compilererror->type = type;
-		compilererror->lineno = error_lineno;
-		compilererror->error_len = vspprintf(&compilererror->error, 0, format, args);
-		break;
-
-	default: {
-		/* give up, and user handler is not supported in this case */
-		zend_uint i;
-		zend_uint old_lineno = CG(zend_lineno);
-
-		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
-			compilererror = &sandbox->compilererrors[i];
-			CG(zend_lineno) = compilererror->lineno;
-			call_old_zend_error_cb(compilererror->type, error_filename, error_lineno, "%s", compilererror->error);
-			efree(compilererror->error);
-		}
-		if (sandbox->compilererrors) {
-			efree(sandbox->compilererrors);
-			sandbox->compilererrors = NULL;
-		}
-		sandbox->compilererror_cnt  = 0;
-		sandbox->compilererror_size = 0;
-
-		CG(zend_lineno) = old_lineno;
-		old_zend_error_cb(type, error_filename, error_lineno, format, args);
-		break;
-	}
-	}
-}
-/* }}} */
-#endif
-#ifdef ZEND_ENGINE_2_1
-static zend_bool xc_auto_global_callback(ZEND_24(NOTHING, const) char *name, uint name_len TSRMLS_DC) /* {{{ */
-{
-	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
-
-void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker) /* {{{ */
-{
-	Bucket *p;
-	void *new_entry;
-	zend_bool setTargetPointer;
-
-	setTargetPointer = !target->pInternalPointer;
-	p = source->pListHead;
-	while (p) {
-		if (checker(p->pData)) {
-			if (setTargetPointer && source->pInternalPointer == p) {
-				target->pInternalPointer = NULL;
-			}
-			if (p->nKeyLength) {
-				zend_u_hash_quick_update(target, p->key.type, ZSTR(BUCKET_KEY_S(p)), p->nKeyLength, p->h, p->pData, size, &new_entry);
-			} else {
-				zend_hash_index_update(target, p->h, p->pData, size, &new_entry);
-			}
-			if (pCopyConstructor) {
-				pCopyConstructor(new_entry);
-			}
-		}
-		p = p->pListNext;
-	}
-	if (!target->pInternalPointer) {
-		target->pInternalPointer = target->pListHead;
-	}
-}
-/* }}} */
-#ifdef HAVE_XCACHE_CONSTANT
-static zend_bool xc_is_internal_zend_constant(zend_constant *c) /* {{{ */
-{
-	return (c->flags & CONST_PERSISTENT) ? 1 : 0;
-}
-/* }}} */
-void xc_zend_constant_ctor(zend_constant *c) /* {{{ */
-{
-	assert((c->flags & CONST_PERSISTENT));
-	ZSTR_U(c->name) = UNISW(zend_strndup, zend_ustrndup)(ZSTR_U(c->name), c->name_len - 1);
-}
-/* }}} */
-void xc_zend_constant_dtor(zend_constant *c) /* {{{ */
-{
-	free(ZSTR_V(c->name));
-}
-/* }}} */
-static void xc_free_zend_constant(zend_constant *c) /* {{{ */
-{
-	if (!(c->flags & CONST_PERSISTENT)) {
-		zval_dtor(&c->value);
-	}
-	free(ZSTR_V(c->name));
-}
-/* }}} */
-void xc_copy_internal_zend_constants(HashTable *target, HashTable *source) /* {{{ */
-{
-	zend_constant tmp_const;
-	xc_hash_copy_if(target, source, (copy_ctor_func_t) xc_zend_constant_ctor, (void *) &tmp_const, sizeof(zend_constant), (xc_if_func_t) xc_is_internal_zend_constant);
-}
-/* }}} */
-#endif
-
-static xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
-{
-	HashTable *h;
-
-	assert(sandbox);
-	memset(sandbox, 0, sizeof(sandbox[0]));
-
-	memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files)));
-
-#ifdef HAVE_XCACHE_CONSTANT
-	OG(zend_constants) = EG(zend_constants);
-	EG(zend_constants) = &TG(zend_constants);
-#endif
-
-	OG(function_table) = CG(function_table);
-	CG(function_table) = &TG(function_table);
-
-	OG(class_table) = CG(class_table);
-	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);
-#ifdef HAVE_XCACHE_CONSTANT
-	h = OG(zend_constants);
-	zend_hash_init_ex(&TG(zend_constants),  20, NULL, (dtor_func_t) xc_free_zend_constant, h->persistent, h->bApplyProtection);
-	xc_copy_internal_zend_constants(&TG(zend_constants), &XG(internal_constant_table));
-	TG(internal_constant_tail) = TG(zend_constants).pListTail;
-#endif
-	h = OG(function_table);
-	zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, h->persistent, h->bApplyProtection);
-	{
-		zend_function tmp_func;
-		zend_hash_copy(&TG(function_table), &XG(internal_function_table), NULL, (void *) &tmp_func, sizeof(tmp_func));
-	}
-	TG(internal_function_tail) = TG(function_table).pListTail;
-
-	h = OG(class_table);
-	zend_hash_init_ex(&TG(class_table),     16, NULL, ZEND_CLASS_DTOR, h->persistent, h->bApplyProtection);
-#if 0 && TODO
-	{
-		xc_cest_t tmp_cest;
-		zend_hash_copy(&TG(class_table), &XG(internal_class_table), NULL, (void *) &tmp_cest, sizeof(tmp_cest));
-	}
-#endif
-	TG(internal_class_tail) = TG(class_table).pListTail;
-
-#ifdef ZEND_ENGINE_2_1
-	/* shallow copy, don't destruct */
-	h = OG(auto_globals);
-	zend_hash_init_ex(&TG(auto_globals),     8, NULL,           NULL, h->persistent, h->bApplyProtection);
-	{
-		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;
-
-#ifdef XCACHE_ERROR_CACHING
-	sandbox->orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting);
-	EG(user_error_handler_error_reporting) = 0;
-
-	sandbox->compilererror_cnt  = 0;
-	sandbox->compilererror_size = 0;
-#endif
-
-#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
-	sandbox->orig_compiler_options = CG(compiler_options);
-	/* Using ZEND_COMPILE_IGNORE_INTERNAL_CLASSES for ZEND_FETCH_CLASS_RT_NS_CHECK
-	 */
-	CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES | ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_DELAYED_BINDING;
-#endif
-
-	XG(sandbox) = (void *) sandbox;
-	return sandbox;
-}
-/* }}} */
-#ifndef ZEND_COMPILE_DELAYED_BINDING
-static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) data;
-	xc_do_early_binding(CG(active_op_array), OG(class_table), oplineno TSRMLS_CC);
-}
-/* }}} */
-#endif
-static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
-{
-	zend_uint i;
-	Bucket *b;
-
-#ifdef HAVE_XCACHE_CONSTANT
-	for (b = TG(zend_constants).pListHead; b != NULL && b != TG(internal_constant_tail); b = b->pListNext) {
-		zend_constant *c = (zend_constant*) b->pData;
-		xc_free_zend_constant(c);
-	}
-
-	b = TG(internal_constant_tail) ? TG(internal_constant_tail)->pListNext : TG(zend_constants).pListHead;
-	/* install constants */
-	while (b != NULL) {
-		zend_constant *c = (zend_constant*) b->pData;
-		xc_install_constant(sandbox->filename, c,
-				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
-		b = b->pListNext;
-	}
-#endif
-
-	b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
-	/* install function */
-	while (b != NULL) {
-		zend_function *func = (zend_function*) b->pData;
-		xc_install_function(sandbox->filename, func,
-				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
-		b = b->pListNext;
-	}
-
-	b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
-	/* install class */
-	while (b != NULL) {
-		xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, -1,
-				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h 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
-
-#ifdef ZEND_COMPILE_DELAYED_BINDING
-	zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC);
-#else
-	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);
-#endif
-
-#ifdef XCACHE_ERROR_CACHING
-	/* restore trigger errors */
-	for (i = 0; i < sandbox->compilererror_cnt; i ++) {
-		xc_compilererror_t *error = &sandbox->compilererrors[i];
-		CG(zend_lineno) = error->lineno;
-		zend_error(error->type, "%s", error->error);
-	}
-	CG(zend_lineno) = 0;
-#endif
-
-	i = 1;
-	/* still needed because in zend_language_scanner.l, require()/include() check file_handle.handle.stream.handle */
-	zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL);
-}
-/* }}} */
-static void xc_sandbox_free(xc_sandbox_t *sandbox, zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	XG(sandbox) = NULL;
-#ifdef XCACHE_ERROR_CACHING
-	EG(user_error_handler_error_reporting) = sandbox->orig_user_error_handler_error_reporting;
-#endif
-
-	/* restore first first install function/class */
-#ifdef HAVE_XCACHE_CONSTANT
-	EG(zend_constants) = OG(zend_constants);
-#endif
-	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 (op_array) {
-		zend_op_array *old_active_op_array = CG(active_op_array);
-		CG(in_compilation)    = 1;
-		CG(compiled_filename) = ZEND_24(NOTHING, (char *)) sandbox->filename;
-		CG(zend_lineno)       = 0;
-
-		CG(active_op_array) = op_array;
-		xc_sandbox_install(sandbox TSRMLS_CC);
-		CG(active_op_array) = old_active_op_array;
-
-		CG(in_compilation)    = 0;
-		CG(compiled_filename) = NULL;
-
-		/* no free as it's installed */
-#ifdef HAVE_XCACHE_CONSTANT
-		TG(zend_constants).pDestructor = NULL;
-#endif
-		TG(function_table).pDestructor = NULL;
-		TG(class_table).pDestructor = NULL;
-	}
-
-	/* destroy all the tmp */
-#ifdef HAVE_XCACHE_CONSTANT
-	zend_hash_destroy(&TG(zend_constants));
-#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 */
-	memcpy(&EG(included_files), &OG(included_files), sizeof(EG(included_files)));
-
-#ifdef XCACHE_ERROR_CACHING
-	if (sandbox->compilererrors) {
-		zend_uint i;
-		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
-			efree(sandbox->compilererrors[i].error);
-		}
-		efree(sandbox->compilererrors);
-	}
-#endif
-
-#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
-	CG(compiler_options) = sandbox->orig_compiler_options;
-#endif
-}
-/* }}} */
-zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
-{
-	xc_sandbox_t sandbox;
-	zend_op_array *op_array = NULL;
-	zend_bool catched = 0;
-
-	memset(&sandbox, 0, sizeof(sandbox));
-	zend_try {
-		xc_sandbox_init(&sandbox, filename TSRMLS_CC);
-		op_array = sandboxed_func(data TSRMLS_CC);
-	} zend_catch {
-		catched = 1;
-	} zend_end_try();
-
-	xc_sandbox_free(&sandbox, op_array TSRMLS_CC);
-	if (catched) {
-		zend_bailout();
-	}
-	return op_array;
-}
-/* {{{ */
-const Bucket *xc_sandbox_user_function_begin(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
-}
-/* {{{ */
-const Bucket *xc_sandbox_user_class_begin(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
-}
-/* {{{ */
-#ifdef XCACHE_ERROR_CACHING
-xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return sandbox->compilererrors;
-}
-/* }}} */
-zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return sandbox->compilererror_cnt;
-}
-/* }}} */
-#endif
-
-int xc_vtrace(const char *fmt, va_list args) /* {{{ */
-{
-	return vfprintf(stderr, fmt, args);
-}
-/* }}} */
-int xc_trace(const char *fmt, ...) /* {{{ */
-{
-	va_list args;
-	int ret;
-
-	va_start(args, fmt);
-	ret = xc_vtrace(fmt, args);
-	va_end(args);
-	return ret;
-}
-/* }}} */
-
-#ifndef ZEND_ENGINE_2_3
-#include "ext/standard/php_string.h"
-size_t xc_dirname(char *path, size_t len) /* {{{ */
-{
-#ifdef ZEND_ENGINE_2
-	return php_dirname(path, len);
-#else
-	php_dirname(path, len);
-	return strlen(path);
-#endif
-}
-/* }}} */
-
-long xc_atol(const char *str, int str_len) /* {{{ */
-{
-	long retval;
-
-	if (!str_len) {
-		str_len = strlen(str);
-	}
-
-	retval = strtol(str, NULL, 0);
-	if (str_len > 0) {
-		switch (str[str_len - 1]) {
-		case 'g':
-		case 'G':
-			retval *= 1024;
-			/* break intentionally missing */
-		case 'm':
-		case 'M':
-			retval *= 1024;
-			/* break intentionally missing */
-		case 'k':
-		case 'K':
-			retval *= 1024;
-			break;
-		}
-	}
-
-	return retval;
-}
-/* }}} */
-
-#endif
-
-/* init/destroy */
-int xc_util_init(int module_number TSRMLS_DC) /* {{{ */
-{
-#ifdef XCACHE_ERROR_CACHING
-	old_zend_error_cb = zend_error_cb;
-	zend_error_cb = xc_sandbox_error_cb;
-#endif
-
-	return SUCCESS;
-}
-/* }}} */
-void xc_util_destroy() /* {{{ */
-{
-#ifdef XCACHE_ERROR_CACHING
-	if (zend_error_cb == xc_sandbox_error_cb) {
-		zend_error_cb = old_zend_error_cb;
-	}
-#endif
-}
-/* }}} */
-
Index: unk/utils.h
===================================================================
--- /trunk/utils.h	(revision 981)
+++ 	(revision )
@@ -1,158 +1,0 @@
-#include "php.h"
-#include "xcache.h"
-
-#ifdef XCACHE_DEBUG
-#	define IFDEBUG(x) (x)
-int xc_vtrace(const char *fmt, va_list args);
-int xc_trace(const char *fmt, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
-
-#	ifdef ZEND_WIN32
-static inline int TRACE(const char *fmt, ...) 
-{
-	va_list args;
-	int ret;
-
-	va_start(args, fmt);
-	ret = xc_vtrace(fmt, args);
-	va_end(args);
-	return ret;
-}
-#	else
-#		define TRACE(fmt, ...) \
-		xc_trace("%s:%d: " fmt "\r\n", __FILE__, __LINE__, __VA_ARGS__)
-#	endif /* ZEND_WIN32 */
-#   undef NDEBUG
-#   undef inline
-#   define inline
-#else /* XCACHE_DEBUG */
-
-#	ifdef ZEND_WIN32
-static inline int TRACE_DUMMY(const char *fmt, ...)
-{
-	return 0;
-}
-#		define TRACE 1 ? 0 : TRACE_DUMMY
-#	else
-#		define TRACE(fmt, ...) do { } while (0)
-#	endif /* ZEND_WIN32 */
-
-#	define IFDEBUG(x) do { } while (0)
-#endif /* XCACHE_DEBUG */
-#include <assert.h>
-
-int xc_util_init(int module_number TSRMLS_DC);
-void xc_util_destroy();
-
-typedef struct {
-	zend_op_array *op_array;
-	HashTable *function_table;
-	HashTable *class_table;
-} xc_compile_result_t;
-
-xc_compile_result_t *xc_compile_result_init(xc_compile_result_t *cr,
-		zend_op_array *op_array,
-		HashTable *function_table,
-		HashTable *class_table);
-void xc_compile_result_free(xc_compile_result_t *cr);
-xc_compile_result_t *xc_compile_result_init_cur(xc_compile_result_t *cr, zend_op_array *op_array TSRMLS_DC);
-/* apply func */
-int xc_apply_function(zend_function *zf, apply_func_t applyer TSRMLS_DC);
-int xc_apply_class(zend_class_entry *ce, apply_func_t applyer TSRMLS_DC);
-int xc_apply_op_array(xc_compile_result_t *cr, apply_func_t applyer TSRMLS_DC);
-
-int xc_undo_pass_two(zend_op_array *op_array TSRMLS_DC);
-int xc_redo_pass_two(zend_op_array *op_array TSRMLS_DC);
-int xc_fix_opcode(zend_op_array *op_array TSRMLS_DC);
-int xc_undo_fix_opcode(zend_op_array *op_array TSRMLS_DC);
-zend_uchar xc_get_fixed_opcode(zend_uchar opcode, int line);
-
-int xc_foreach_early_binding_class(zend_op_array *op_array, void (*callback)(zend_op *opline, int oplineno, void *data TSRMLS_DC), void *data TSRMLS_DC);
-
-/* installer */
-#ifdef HAVE_XCACHE_CONSTANT
-void xc_install_constant(ZEND_24(NOTHING, const) char *filename, zend_constant *constant, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC);
-#endif
-void xc_install_function(ZEND_24(NOTHING, const) char *filename, zend_function *func, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC);
-ZESW(xc_cest_t *, void) xc_install_class(ZEND_24(NOTHING, const) char *filename, xc_cest_t *cest, int oplineno, zend_uchar type, const24_zstr key, uint len, ulong h TSRMLS_DC);
-
-#if defined(E_STRICT) || defined(E_DEPRECATED)
-#define XCACHE_ERROR_CACHING
-#endif
-
-/* return op_array to install */
-typedef zend_op_array *(*xc_sandboxed_func_t)(void *data TSRMLS_DC);
-zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC);
-const Bucket *xc_sandbox_user_function_begin(TSRMLS_D);
-const Bucket *xc_sandbox_user_class_begin(TSRMLS_D);
-zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
-#ifdef XCACHE_ERROR_CACHING
-xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D);
-zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
-#endif
-
-void xc_zend_class_add_ref(zend_class_entry ZESW(*ce, **ce));
-
-typedef zend_bool (*xc_if_func_t)(void *data);
-
-void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker);
-#ifdef HAVE_XCACHE_CONSTANT
-void xc_zend_constant_ctor(zend_constant *c);
-void xc_zend_constant_dtor(zend_constant *c);
-void xc_copy_internal_zend_constants(HashTable *target, HashTable *source);
-#endif
-
-#ifndef ZEND_ENGINE_2_3
-size_t xc_dirname(char *path, size_t len);
-#define zend_dirname xc_dirname
-long xc_atol(const char *str, int len);
-#define zend_atol xc_atol
-#endif
-
-typedef struct {
-	zend_uint size;
-	zend_uint cnt;
-	void *data;
-} xc_vector_t;
-
-#define xc_vector_init(type, vector) do { \
-	(vector)->cnt = 0;     \
-	(vector)->size = 0;    \
-	(vector)->data = NULL; \
-} while (0)
-
-#define xc_vector_add(type, vector, value) do { \
-	if ((vector)->cnt == (vector)->size) { \
-		if ((vector)->size) { \
-			(vector)->size <<= 1; \
-			(vector)->data = erealloc((vector)->data, sizeof(type) * (vector)->size); \
-		} \
-		else { \
-			(vector)->size = 8; \
-			(vector)->data = emalloc(sizeof(type) * (vector)->size); \
-		} \
-	} \
-	((type *) (vector)->data)[(vector)->cnt++] = value; \
-} while (0)
-
-static inline void *xc_vector_detach_impl(xc_vector_t *vector)
-{
-	void *data = vector->data;
-	vector->data = NULL;
-	vector->size = 0;
-	vector->cnt = 0;
-	return data;
-}
-
-#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(vector))
-
-static inline void xc_vector_free_impl(xc_vector_t *vector TSRMLS_DC)
-{
-	if (vector->data) {
-		efree(vector->data);
-	}
-	vector->size = 0;
-	vector->cnt = 0;
-}
-
-#define xc_vector_free(type, vector) xc_vector_free_impl(vector TSRMLS_CC)
-
Index: unk/xc_malloc.c
===================================================================
--- /trunk/xc_malloc.c	(revision 981)
+++ 	(revision )
@@ -1,250 +1,0 @@
-#define XC_SHM_IMPL _xc_malloc_shm_t
-#define XC_MEM_IMPL _xc_malloc_mem_t
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "xc_shm.h"
-#include "php.h"
-#include "align.h"
-#include "utils.h"
-
-struct _xc_malloc_mem_t {
-	const xc_mem_handlers_t *handlers;
-	xc_shm_t                *shm;
-	xc_memsize_t size;
-	xc_memsize_t avail;       /* total free */
-};
-
-/* {{{ _xc_malloc_shm_t */
-struct _xc_malloc_shm_t {
-	xc_shm_handlers_t *handlers;
-	xc_shmsize_t       size;
-	xc_shmsize_t       memoffset;
-#ifdef HAVE_XCACHE_TEST
-	HashTable blocks;
-#endif
-};
-/* }}} */
-
-#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
-
-static void *xc_add_to_blocks(xc_mem_t *mem, void *p, size_t size) /* {{{ */
-{
-#ifdef HAVE_XCACHE_TEST
-	if (p) {
-		zend_hash_add(&mem->shm->blocks, (void *) &p, sizeof(p), (void *) &size, sizeof(size), NULL);
-	}
-#endif
-	return p;
-}
-/* }}} */
-static void xc_del_from_blocks(xc_mem_t *mem, void *p) /* {{{ */
-{
-#ifdef HAVE_XCACHE_TEST
-	zend_hash_del(&mem->shm->blocks, (void *) &p, sizeof(p));
-#endif
-}
-/* }}} */
-
-static XC_MEM_MALLOC(xc_malloc_malloc) /* {{{ */
-{
-	return xc_add_to_blocks(mem, malloc(size), size);
-}
-/* }}} */
-static XC_MEM_FREE(xc_malloc_free) /* {{{ return block size freed */
-{
-	xc_del_from_blocks(mem, (void *) p);
-	free((void *) p);
-	return 0;
-}
-/* }}} */
-static XC_MEM_CALLOC(xc_malloc_calloc) /* {{{ */
-{
-	return xc_add_to_blocks(mem, calloc(memb, size), size);
-}
-/* }}} */
-static XC_MEM_REALLOC(xc_malloc_realloc) /* {{{ */
-{
-	return xc_add_to_blocks(mem, realloc((void *) p, size), size);
-}
-/* }}} */
-static XC_MEM_STRNDUP(xc_malloc_strndup) /* {{{ */
-{
-	char *p = xc_add_to_blocks(mem, malloc(len), len);
-	if (!p) {
-		return NULL;
-	}
-	return memcpy(p, str, len);
-}
-/* }}} */
-static XC_MEM_STRDUP(xc_malloc_strdup) /* {{{ */
-{
-	return xc_malloc_strndup(mem, str, strlen(str) + 1);
-}
-/* }}} */
-
-static XC_MEM_AVAIL(xc_malloc_avail) /* {{{ */
-{
-	return mem->avail;
-}
-/* }}} */
-static XC_MEM_SIZE(xc_malloc_size) /* {{{ */
-{
-	return mem->size;
-}
-/* }}} */
-
-static XC_MEM_FREEBLOCK_FIRST(xc_malloc_freeblock_first) /* {{{ */
-{
-	return (void *) -1;
-}
-/* }}} */
-XC_MEM_FREEBLOCK_NEXT(xc_malloc_freeblock_next) /* {{{ */
-{
-	return NULL;
-}
-/* }}} */
-XC_MEM_BLOCK_SIZE(xc_malloc_block_size) /* {{{ */
-{
-	return 0;
-}
-/* }}} */
-XC_MEM_BLOCK_OFFSET(xc_malloc_block_offset) /* {{{ */
-{
-	return 0;
-}
-/* }}} */
-
-static XC_MEM_INIT(xc_mem_malloc_init) /* {{{ */
-{
-#define MINSIZE (ALIGN(sizeof(xc_mem_t)))
-	/* requires at least the header and 1 tail block */
-	if (size < MINSIZE) {
-		fprintf(stderr, "xc_mem_malloc_init requires %lu bytes at least\n", (unsigned long) MINSIZE);
-		return NULL;
-	}
-	mem->shm = shm;
-	mem->size = size;
-	mem->avail = size - MINSIZE;
-#undef MINSIZE
-
-	return mem;
-}
-/* }}} */
-static XC_MEM_DESTROY(xc_mem_malloc_destroy) /* {{{ */
-{
-}
-/* }}} */
-
-static XC_SHM_CAN_READONLY(xc_malloc_can_readonly) /* {{{ */
-{
-	return 0;
-}
-/* }}} */
-static XC_SHM_IS_READWRITE(xc_malloc_is_readwrite) /* {{{ */
-{
-#ifdef HAVE_XCACHE_TEST
-	HashPosition pos;
-	size_t *psize;
-	char **ptr;
-
-	zend_hash_internal_pointer_reset_ex(&shm->blocks, &pos);
-	while (zend_hash_get_current_data_ex(&shm->blocks, (void **) &psize, &pos) == SUCCESS) {
-		zend_hash_get_current_key_ex(&shm->blocks, (void *) &ptr, NULL, NULL, 0, &pos);
-		if ((char *) p >= *ptr && (char *) p < *ptr + *psize) {
-			return 1;
-		}
-		zend_hash_move_forward_ex(&shm->blocks, &pos);
-	}
-#endif
-
-	return 0;
-}
-/* }}} */
-static XC_SHM_IS_READONLY(xc_malloc_is_readonly) /* {{{ */
-{
-	return 0;
-}
-/* }}} */
-static XC_SHM_TO_READWRITE(xc_malloc_to_readwrite) /* {{{ */
-{
-	return p;
-}
-/* }}} */
-static XC_SHM_TO_READONLY(xc_malloc_to_readonly) /* {{{ */
-{
-	return p;
-}
-/* }}} */
-
-static XC_SHM_DESTROY(xc_malloc_destroy) /* {{{ */
-{
-#ifdef HAVE_XCACHE_TEST
-	zend_hash_destroy(&shm->blocks);
-#endif
-	free(shm);
-	return;
-}
-/* }}} */
-static XC_SHM_INIT(xc_malloc_init) /* {{{ */
-{
-	xc_shm_t *shm;
-	CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM");
-	shm->size = size;
-
-#ifdef HAVE_XCACHE_TEST
-	zend_hash_init(&shm->blocks, 64, NULL, NULL, 1);
-#endif
-	return shm;
-err:
-	return NULL;
-}
-/* }}} */
-
-static XC_SHM_MEMINIT(xc_malloc_meminit) /* {{{ */
-{
-	xc_mem_t *mem;
-	if (shm->memoffset + size > shm->size) {
-		zend_error(E_ERROR, "XCache: internal error at %s#%d", __FILE__, __LINE__);
-		return NULL;
-	}
-	shm->memoffset += size;
-	CHECK(mem = calloc(1, sizeof(xc_mem_t)), "mem OOM");
-	mem->handlers = shm->handlers->memhandlers;
-	mem->handlers->init(shm, mem, size);
-	return mem;
-err:
-	return NULL;
-}
-/* }}} */
-static XC_SHM_MEMDESTROY(xc_malloc_memdestroy) /* {{{ */
-{
-	mem->handlers->destroy(mem);
-	free(mem);
-}
-/* }}} */
-
-#define xc_malloc_destroy xc_mem_malloc_destroy
-#define xc_malloc_init xc_mem_malloc_init
-static xc_mem_handlers_t xc_mem_malloc_handlers = XC_MEM_HANDLERS(malloc);
-#undef xc_malloc_init
-#undef xc_malloc_destroy
-static xc_shm_handlers_t xc_shm_malloc_handlers = XC_SHM_HANDLERS(malloc);
-void xc_shm_malloc_register() /* {{{ */
-{
-	if (xc_mem_scheme_register("malloc", &xc_mem_malloc_handlers) == 0) {
-		zend_error(E_ERROR, "XCache: failed to register malloc mem_scheme");
-	}
-
-	CHECK(xc_shm_malloc_handlers.memhandlers = xc_mem_scheme_find("malloc"), "cannot find malloc handlers");
-	if (xc_shm_scheme_register("malloc", &xc_shm_malloc_handlers) == 0) {
-		zend_error(E_ERROR, "XCache: failed to register malloc shm_scheme");
-	}
-err:
-	return;
-}
-/* }}} */
Index: unk/xc_shm.c
===================================================================
--- /trunk/xc_shm.c	(revision 981)
+++ 	(revision )
@@ -1,99 +1,0 @@
-#ifdef TEST
-#include <limits.h>
-#include <stdio.h>
-#else
-#include <php.h>
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "xc_shm.h"
-
-struct _xc_shm_scheme_t {
-	const char              *name;
-	const xc_shm_handlers_t *handlers;
-};
-static xc_shm_scheme_t xc_shm_schemes[10];
-
-void xc_shm_init_modules() /* {{{ */
-{
-	extern void xc_shm_mem_init();
-#ifdef HAVE_XCACHE_TEST
-	extern void xc_shm_malloc_register();
-#endif
-	extern void xc_shm_mmap_register();
-
-	memset(xc_shm_schemes, 0, sizeof(xc_shm_schemes));
-	xc_shm_mem_init();
-#ifdef HAVE_XCACHE_TEST
-	xc_shm_malloc_register();
-#endif
-	xc_shm_mmap_register();
-}
-/* }}} */
-int xc_shm_scheme_register(const char *name, const xc_shm_handlers_t *handlers) /* {{{ */
-{
-	int i;
-	for (i = 0; i < 10; i ++) {
-		if (!xc_shm_schemes[i].name) {
-			xc_shm_schemes[i].name = name;
-			xc_shm_schemes[i].handlers = handlers;
-			return 1;
-		}
-	}
-	return 0;
-}
-/* }}} */
-const xc_shm_handlers_t *xc_shm_scheme_find(const char *name) /* {{{ */
-{
-	int i;
-	for (i = 0; i < 10 && xc_shm_schemes[i].name; i ++) {
-		if (strcmp(xc_shm_schemes[i].name, name) == 0) {
-			return xc_shm_schemes[i].handlers;
-		}
-	}
-	return NULL;
-}
-/* }}} */
-xc_shm_scheme_t *xc_shm_scheme_first() /* {{{ */
-{
-	return xc_shm_schemes;
-}
-/* }}} */
-xc_shm_scheme_t *xc_shm_scheme_next(xc_shm_scheme_t *scheme) /* {{{ */
-{
-	scheme ++;
-	return scheme->name ? scheme : NULL;
-}
-/* }}} */
-const char *xc_shm_scheme_name(xc_shm_scheme_t *scheme) /* {{{ */
-{
-	assert(scheme);
-	return scheme->name;
-}
-/* }}} */
-xc_shm_t *xc_shm_init(const char *type, xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2) /* {{{ */
-{
-	const xc_shm_handlers_t *handlers = xc_shm_scheme_find(type);
-
-	if (handlers) {
-		xc_shm_t *shm = handlers->init(size, readonly_protection, arg1, arg2);
-		if (shm) {
-			shm->handlers = handlers;
-		}
-		return shm;
-	}
-
-	return NULL;
-}
-/* }}} */
-void xc_shm_destroy(xc_shm_t *shm) /* {{{ */
-{
-	shm->handlers->destroy(shm);
-}
-/* }}} */
Index: unk/xc_shm.h
===================================================================
--- /trunk/xc_shm.h	(revision 981)
+++ 	(revision )
@@ -1,71 +1,0 @@
-#ifndef XC_SHM_H
-#define XC_SHM_H
-typedef struct _xc_shm_handlers_t xc_shm_handlers_t;
-
-#ifndef XC_SHM_IMPL
-struct _xc_shm_t {
-	const xc_shm_handlers_t *handlers;
-	zend_bool disabled;
-};
-#define XC_SHM_IMPL _xc_shm_t
-#endif
-
-typedef struct XC_SHM_IMPL xc_shm_t;
-typedef size_t xc_shmsize_t;
-
-#include "mem.h"
-
-/* shm */
-#define XC_SHM_CAN_READONLY(func) int   func(xc_shm_t *shm)
-#define XC_SHM_IS_READWRITE(func) int   func(xc_shm_t *shm, const void *p)
-#define XC_SHM_IS_READONLY(func)  int   func(xc_shm_t *shm, const void *p)
-#define XC_SHM_TO_READWRITE(func) void *func(xc_shm_t *shm, void *p)
-#define XC_SHM_TO_READONLY(func)  void *func(xc_shm_t *shm, void *p)
-
-#define XC_SHM_INIT(func)         xc_shm_t *func(xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2)
-#define XC_SHM_DESTROY(func)      void func(xc_shm_t *shm)
-
-#define XC_SHM_MEMINIT(func)      xc_mem_t *func(xc_shm_t *shm, xc_memsize_t size)
-#define XC_SHM_MEMDESTROY(func)   void func(xc_mem_t *mem)
-
-#define XC_SHM_HANDLERS(name)    { \
-	NULL                           \
-	, xc_##name##_can_readonly     \
-	, xc_##name##_is_readwrite     \
-	, xc_##name##_is_readonly      \
-	, xc_##name##_to_readwrite     \
-	, xc_##name##_to_readonly      \
-\
-	, xc_##name##_init             \
-	, xc_##name##_destroy          \
-\
-	, xc_##name##_meminit          \
-	, xc_##name##_memdestroy       \
-}
-
-struct _xc_shm_handlers_t {
-	const xc_mem_handlers_t *memhandlers;
-	XC_SHM_CAN_READONLY((*can_readonly));
-	XC_SHM_IS_READWRITE((*is_readwrite));
-	XC_SHM_IS_READONLY((*is_readonly));
-	XC_SHM_TO_READWRITE((*to_readwrite));
-	XC_SHM_TO_READONLY((*to_readonly));
-	XC_SHM_INIT((*init));
-	XC_SHM_DESTROY((*destroy));
-
-	XC_SHM_MEMINIT((*meminit));
-	XC_SHM_MEMDESTROY((*memdestroy));
-};
-
-typedef struct _xc_shm_scheme_t xc_shm_scheme_t;
-
-void xc_shm_init_modules();
-int xc_shm_scheme_register(const char *name, const xc_shm_handlers_t *handlers);
-const xc_shm_handlers_t *xc_shm_scheme_find(const char *name);
-xc_shm_scheme_t *xc_shm_scheme_first();
-xc_shm_scheme_t *xc_shm_scheme_next(xc_shm_scheme_t *scheme);
-const char *xc_shm_scheme_name(xc_shm_scheme_t *scheme);
-
-xc_shm_t *xc_shm_init(const char *type, xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2);
-void xc_shm_destroy(xc_shm_t *shm);
-#endif
Index: /trunk/xcache.c
===================================================================
--- /trunk/xcache.c	(revision 981)
+++ /trunk/xcache.c	(revision 982)
@@ -27,14 +27,16 @@
 #include "ext/date/php_date.h"
 #endif
-#include "optimizer.h"
-#include "coverager.h"
-#include "disassembler.h"
-#include "align.h"
-#include "stack.h"
+#include "submodules/xc_optimizer.h"
+#include "submodules/xc_coverager.h"
+#include "submodules/xc_disassembler.h"
 #include "xcache_globals.h"
-#include "processor.h"
-#include "const_string.h"
-#include "opcode_spec.h"
-#include "utils.h"
+#include "xc_processor.h"
+#include "xc_const_string.h"
+#include "xc_opcode_spec.h"
+#include "xc_utils.h"
+#include "util/xc_align.h"
+#include "util/xc_stack.h"
+#include "util/xc_vector.h"
+#include "util/xc_trace.h"
 
 #define VAR_ENTRY_EXPIRED(pentry) ((pentry)->ttl && XG(request_time) > (pentry)->ctime + (time_t) (pentry)->ttl)
@@ -72,8 +74,8 @@
 static zend_bool xc_disable_on_crash = 0;
 
-static xc_hash_t xc_php_hcache = { 0 };
-static xc_hash_t xc_php_hentry = { 0 };
-static xc_hash_t xc_var_hcache = { 0 };
-static xc_hash_t xc_var_hentry = { 0 };
+static xc_hash_t xc_php_hcache = { 0, 0, 0 };
+static xc_hash_t xc_php_hentry = { 0, 0, 0 };
+static xc_hash_t xc_var_hcache = { 0, 0, 0 };
+static xc_hash_t xc_var_hentry = { 0, 0, 0 };
 
 static zend_ulong xc_php_ttl    = 0;
@@ -114,5 +116,5 @@
 #endif
 ZEND_DLEXPORT zend_extension zend_extension_entry;
-ZEND_DECLARE_MODULE_GLOBALS(xcache);
+ZEND_DECLARE_MODULE_GLOBALS(xcache)
 
 typedef enum { XC_TYPE_PHP, XC_TYPE_VAR } xc_entry_type_t;
@@ -3271,5 +3273,4 @@
 }
 /* }}} */
-#ifdef HAVE_XCACHE_OPCODE_SPEC_DEF
 /* {{{ proto string xcache_get_opcode_spec(int opcode) */
 PHP_FUNCTION(xcache_get_opcode_spec)
@@ -3295,5 +3296,4 @@
 }
 /* }}} */
-#endif
 /* {{{ proto mixed xcache_get_special_value(zval value)
    XCache internal use only: For decompiler to get static value with type fixed */
@@ -3398,7 +3398,5 @@
 	PHP_FE(xcache_get_data_type,     NULL)
 	PHP_FE(xcache_get_opcode,        NULL)
-#ifdef HAVE_XCACHE_OPCODE_SPEC_DEF
 	PHP_FE(xcache_get_opcode_spec,   NULL)
-#endif
 	PHP_FE(xcache_is_autoglobal,     NULL)
 	PHP_FE(xcache_inc,               NULL)
@@ -3520,5 +3518,5 @@
 typedef void (*xc_sighandler_t)(int);
 #define FOREACH_SIG(sig) static xc_sighandler_t old_##sig##_handler = NULL
-#include "foreachcoresig.h"
+#include "util/xc_foreachcoresig.h"
 #undef FOREACH_SIG
 /* }}} */
@@ -3534,5 +3532,5 @@
 	} \
 } while (0)
-#include "foreachcoresig.h"
+#include "util/xc_foreachcoresig.h"
 #undef FOREACH_SIG
 }
@@ -3542,5 +3540,5 @@
 #define FOREACH_SIG(sig) \
 	old_##sig##_handler = signal(sig, xcache_signal_handler)
-#include "foreachcoresig.h"
+#include "util/xc_foreachcoresig.h"
 #undef FOREACH_SIG
 }
Index: /trunk/xcache.h
===================================================================
--- /trunk/xcache.h	(revision 981)
+++ /trunk/xcache.h	(revision 982)
@@ -21,5 +21,5 @@
 #endif
 #include "xc_shm.h"
-#include "lock.h"
+#include "xc_lock.h"
 
 #if !defined(ZEND_ENGINE_2_4) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4 || PHP_MAJOR_VERSION > 5)
Index: /trunk/xcache_globals.h
===================================================================
--- /trunk/xcache_globals.h	(revision 981)
+++ /trunk/xcache_globals.h	(revision 982)
@@ -1,2 +1,3 @@
+#include "util/xc_stack.h"
 
 ZEND_BEGIN_MODULE_GLOBALS(xcache)
