Index: /trunk/includes.c
===================================================================
--- /trunk/includes.c	(revision 1051)
+++ /trunk/includes.c	(revision 1)
@@ -1,4 +1,2 @@
 #include "xcache.h"
-#include "mod_cacher/xc_cache.h"
-#include "xcache/xc_utils.h"
 #include "zend_compile.h"
Index: /trunk/const_string.c
===================================================================
--- /trunk/const_string.c	(revision 1)
+++ /trunk/const_string.c	(revision 1)
@@ -0,0 +1,114 @@
+#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
+};
+
+int 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",
+#if 0
+	/* 11 */ "",
+	/* 12 */ "",
+	/* 13 */ "",
+	/* 14 */ "",
+	/* 15 */ "", "", "", "", "",
+
+/* IS_CONSTANT_INDEX */
+	/* 20 */ "CIDX IS_NULL",
+	/* 21 */ "CIDX IS_LONG",
+	/* 22 */ "CIDX IS_DOUBLE",
+	/* 23 */ "CIDX IS_BOOL",
+	/* 24 */ "CIDX IS_ARRAY",
+	/* 25 */ "CIDX IS_OBJECT",
+	/* 26 */ "CIDX IS_STRING",
+	/* 27 */ "CIDX IS_RESOURCE",
+	/* 28 */ "CIDX IS_CONSTANT",
+	/* 29 */ "CIDX IS_CONSTANT_ARRAY"
+	/* 20 */ "CIDX IS_UNICODE",
+#endif
+};
+
+int 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)
+{
+#if 0
+	if (data_type & IS_CONSTANT_INDEX) {
+		data_type = (data_type & ~IS_CONSTANT_INDEX) + 20;
+	}
+#endif
+	data_type &= ~IS_CONSTANT_INDEX;
+	return data_type_names[data_type];
+}
+/* }}} */
+/* {{{ xc_get_opcode */
+#if PHP_MAJAR_VERSION >= 6
+#	include     "const_string_opcodes_php6.x.h"
+#else
+#	ifdef ZEND_ENGINE_2_1
+#		include     "const_string_opcodes_php5.1.h"
+#	else
+#		ifdef ZEND_ENGINE_2
+#			include "const_string_opcodes_php5.0.h"
+#		else
+#			include "const_string_opcodes_php4.x.h"
+#		endif
+#	endif
+#endif
+
+int 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/.vimrc
===================================================================
--- /trunk/.vimrc	(revision 605)
+++ /trunk/.vimrc	(revision 1)
@@ -1,3 +1,2 @@
-set noexpandtab
-au FileType m4 setlocal ts=2 sw=2 fdm=marker noexpandtab
-au FileType c setlocal ts=4 sw=4 fdm=marker noexpandtab
+
+au FileType m4 setlocal ts=2 sw=2 fdm=marker
Index: /trunk/mem.c
===================================================================
--- /trunk/mem.c	(revision 1)
+++ /trunk/mem.c	(revision 1)
@@ -0,0 +1,268 @@
+#include <php.h>
+#include <stdlib.h>
+#include "mem.h"
+#include "align.h"
+#define PADD(p, a) (((char*)p) + a)
+
+// {{{ mem
+struct _xc_block_t {
+#ifdef ALLOC_DEBUG
+	unsigned int magic;
+#endif
+	xc_memsize_t size; /* reserved even after alloc */
+	xc_block_t *next;  /* not used after alloc */
+};
+
+struct _xc_mem_t {
+	xc_memsize_t size;
+	xc_memsize_t avail;       /* total free */
+	xc_block_t headblock[1];  /* just as a pointer to first block*/
+};
+
+#ifndef offsetof
+#	define offsetof(type, field) ((int) ((char *) &((type *) 0)->field))
+#endif
+#define SizeOf(type, field) sizeof( ((type *) 0)->field )
+#define BLOCK_HEADER_SIZE() (ALIGN( offsetof(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
+	b->magic = BLOCK_MAGIC;
+#endif
+	b->size = size;
+	b->next = next;
+}
+/* }}} */
+#ifdef ALLOC_DEBUG
+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
+
+
+void *xc_mem_malloc(xc_mem_t *mem, xc_memsize_t size) /* {{{ */
+{
+	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);
+
+	do {
+		p = NULL;
+		if (mem->avail < realsize) {
+			break;
+		}
+
+		b = NULL;
+		minsize = INT_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) {
+			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;
+			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
+		 *            `--^
+		 */
+
+#ifdef ALLOC_DEBUG
+		fprintf(stderr, "avail: %d (%dKB). size: %d %d (%dKB) new next: %p offset: %d %dKB\n"
+				, mem->avail, mem->avail/1024
+				, size
+				, realsize, realsize/1024
+				, newb
+				, ((char*)newb - mem->rw), ((char*)newb - mem->rw) / 1024
+				);
+#endif
+		prev->next = newb;
+		/* prev|cur|newb|next
+		 *    `-----^
+		 */
+
+	} while (0);
+
+	return p;
+}
+/* }}} */
+int xc_mem_free(xc_mem_t *mem, const void *p) /* {{{ return block size freed */
+{
+	xc_block_t *cur, *b;
+	int size;
+
+	cur = (xc_block_t *) (((char *) p) - BLOCK_HEADER_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;
+
+	mem->avail += size;
+
+	/* combine prev|cur */
+	if (PADD(b, b->size) == (char *)cur) {
+		b->size += cur->size;
+		b->next = cur->next;
+		cur = b;
+	}
+
+	/* combine cur|next */
+	b = cur->next;
+	if (PADD(cur, cur->size) == (char *)b) {
+		cur->size += b->size;
+		cur->next = b->next;
+	}
+	return size;
+}
+/* }}} */
+void *xc_mem_calloc(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size) /* {{{ */
+{
+	xc_memsize_t realsize = memb * size;
+	void *p = xc_mem_malloc(mem, realsize);
+
+	memset(p, 0, realsize);
+	return p;
+}
+/* }}} */
+void *xc_mem_realloc(xc_mem_t *mem, const void *p, xc_memsize_t size) /* {{{ */
+{
+	void *newp = xc_mem_malloc(mem, size);
+	memcpy(newp, p, size);
+	xc_mem_free(mem, p);
+	return newp;
+}
+/* }}} */
+char *xc_mem_strndup(xc_mem_t *mem, const char *str, xc_memsize_t len) /* {{{ */
+{
+	void *p = xc_mem_malloc(mem, len + 1);
+	memcpy(p, str, len + 1);
+	return p;
+}
+/* }}} */
+char *xc_mem_strdup(xc_mem_t *mem, const char *str) /* {{{ */
+{
+	return xc_mem_strndup(mem, str, strlen(str));
+}
+/* }}} */
+
+xc_memsize_t xc_mem_avail(xc_mem_t *mem) /* {{{ */
+{
+	return mem->avail;
+}
+/* }}} */
+xc_memsize_t xc_mem_size(xc_mem_t *mem) /* {{{ */
+{
+	return mem->size;
+}
+/* }}} */
+
+const xc_block_t *xc_mem_freeblock_first(xc_mem_t *mem) /* {{{ */
+{
+	return mem->headblock->next;
+}
+/* }}} */
+const xc_block_t *xc_mem_freeblock_next(const xc_block_t *block) /* {{{ */
+{
+	return block->next;
+}
+/* }}} */
+xc_memsize_t xc_mem_block_size(const xc_block_t *block) /* {{{ */
+{
+	return block->size;
+}
+/* }}} */
+xc_memsize_t xc_mem_block_offset(const xc_mem_t *mem, const xc_block_t *block) /* {{{ */
+{
+	return ((char *) block) - ((char *) mem);
+}
+/* }}} */
+
+xc_mem_t *xc_mem_init(void *ptr, xc_memsize_t size) /* {{{ */
+{
+	xc_mem_t *mem = (xc_mem_t *) ptr;
+	xc_block_t  *b;
+
+	mem->size = size;
+	mem->avail = size - ALIGN(sizeof(xc_mem_t));
+
+	/* pointer to first block */
+	b = mem->headblock;
+	xc_block_setup(b, 0, (xc_block_t *)(mem + ALIGN(sizeof(xc_mem_t))));
+
+	/* first block*/
+	b = b->next;
+	xc_block_setup(b, mem->avail, 0);
+
+	return mem;
+}
+/* }}} */
+void xc_mem_destroy(xc_mem_t *mem) /* {{{ */
+{
+}
+/* }}} */
Index: /trunk/phpdop.phpr
===================================================================
--- /trunk/phpdop.phpr	(revision 1)
+++ /trunk/phpdop.phpr	(revision 1)
@@ -0,0 +1,118 @@
+#!/usr/bin/php
+<?php
+
+$srcdir = dirname(__FILE__);
+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['u.constant'], true);
+
+	case 2: // IS_TMP_VAR
+		return 't@' . $op['u.var'];
+
+	case 4:
+		return 'v$' . $op['u.var'];
+
+	case 8: // UNUSED
+		if (isset($op['u.opline_num'])) {
+			return 'l#' . $op['u.opline_num'];
+		}
+		else {
+			return '-';
+		}
+
+	default:
+		return $op['op_type'] . $op['u.var'];
+	}
+}
+
+function dump_opcodes($op_array, $indent = '')
+{
+	$types = array('result' => 5, 'op1' => 20, 'op2' => 20);
+	foreach ($op_array 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);
+		}
+	}
+}
+
+$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($op_array)) {
+	dump_opcodes($op_array['opcodes']);
+}
+if (isset($funcs)) {
+	foreach ($funcs as $name => $func) {
+		dump_function($name, $func);
+	}
+}
+if (isset($classes)) {
+	foreach ($classes as $name => $class) {
+		dump_class($name, $class);
+	}
+}
+
Index: /trunk/const_string.h
===================================================================
--- /trunk/const_string.h	(revision 1)
+++ /trunk/const_string.h	(revision 1)
@@ -0,0 +1,8 @@
+#include "php.h"
+
+int xc_get_op_type_count();
+const char *xc_get_op_type(zend_uchar op_type);
+int xc_get_data_type_count();
+const char *xc_get_data_type(zend_uchar data_type);
+int xc_get_opcode_count();
+const char *xc_get_opcode(zend_uchar opcode);
Index: /trunk/mem.h
===================================================================
--- /trunk/mem.h	(revision 1)
+++ /trunk/mem.h	(revision 1)
@@ -0,0 +1,20 @@
+typedef struct _xc_mem_t xc_mem_t;
+typedef struct _xc_block_t xc_block_t;
+typedef unsigned int xc_memsize_t;
+
+void *xc_mem_malloc(xc_mem_t *mem, xc_memsize_t size);
+int xc_mem_free(xc_mem_t *mem, const void *p);
+void *xc_mem_calloc(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size);
+void *xc_mem_realloc(xc_mem_t *mem, const void *p, xc_memsize_t size);
+char *xc_mem_strndup(xc_mem_t *mem, const char *str, xc_memsize_t len);
+char *xc_mem_strdup(xc_mem_t *mem, const char *str);
+const xc_block_t *xc_mem_freeblock_first(xc_mem_t *mem);
+const xc_block_t *xc_mem_freeblock_next(const xc_block_t *block);
+xc_memsize_t xc_mem_block_size(const xc_block_t *block);
+xc_memsize_t xc_mem_block_offset(const xc_mem_t *mem, const xc_block_t *block);
+
+xc_memsize_t xc_mem_avail(xc_mem_t *mem);
+xc_memsize_t xc_mem_size(xc_mem_t *mem);
+
+xc_mem_t *xc_mem_init(void *ptr, xc_memsize_t size);
+void xc_mem_destroy(xc_mem_t *mem);
Index: /trunk/const_string_opcodes_php5.1.h
===================================================================
--- /trunk/const_string_opcodes_php5.1.h	(revision 1)
+++ /trunk/const_string_opcodes_php5.1.h	(revision 1)
@@ -0,0 +1,154 @@
+/* size = 150 */
+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 */	"UNDEF",
+/* 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 */	"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 */	"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 */	"UNDEF",
+/* 144 */	"ADD_INTERFACE",
+/* 145 */	"UNDEF",
+/* 146 */	"VERIFY_ABSTRACT_CLASS",
+/* 147 */	"ASSIGN_DIM",
+/* 148 */	"ISSET_ISEMPTY_PROP_OBJ",
+/* 149 */	"HANDLE_EXCEPTION",
+/* 150 */	"USER_OPCODE"
+};
Index: /trunk/mkstructinfo.awk
===================================================================
--- /trunk/mkstructinfo.awk	(revision 1)
+++ /trunk/mkstructinfo.awk	(revision 1)
@@ -0,0 +1,82 @@
+#!/usr/bin/gawk -f
+# vim:ts=4:sw=4
+BEGIN {
+	brace = 0;
+	delete buffer;
+	buffer_len = 0;
+}
+/^}.*;/ {
+	if (instruct) {
+		sub(";", "");
+		if (instruct == 1 && $2) {
+			instruct = $2;
+		}
+		if (instruct in typedefs) {
+			instruct = typedefs[instruct];
+		}
+		elm = "";
+		elms = "";
+		for (i = 0; i in buffer; i ++) {
+			if (i) elm = elm " + ";
+			# elm = elm "sizeof(((`" instruct "'*)NULL)->`" buffer[i] "')";
+			# elms = elms " `" buffer[i] "'";
+			elm = elm "sizeof(((" instruct "*)NULL)->" buffer[i] ")";
+			elms = elms " " buffer[i] "";
+		}
+		printf "define(`ELEMENTSOF_%s', `%s')\n", instruct, elms;
+		printf "define(`COUNTOF_%s', `%s')\n", instruct, i;
+		printf "define(`SIZEOF_%s', `(  %s  )')\n", instruct, elm;
+		print "\n";
+		delete buffer;
+		buffer_len = 0;
+		instruct = 0;
+	}
+	next;
+}
+
+/.{/ {
+	brace = brace + 1;
+}
+/.}/ {
+	brace = brace - 1;
+}
+
+{
+	if (brace == 1 && instruct) {
+		sub(/.*[{}]/, "");
+		gsub(/\[[^\]]+\]/, "");
+		gsub(/:[0-9]+/, "");
+		str = $0;
+		if (match(str, /\([ ]*\*([^)]+)\)/, a)) {
+			buffer[buffer_len] = a[1];
+			buffer_len ++;
+		}
+		else {
+			while (gsub(/(\([^)]*\))/, "", str)) {
+			}
+			while (match(str, /([^*() ]+)[ ]*[,;](.*)/, a)) {
+				buffer[buffer_len] = a[1];
+				buffer_len ++;
+				str = a[2];
+			}
+		}
+		next;
+	}
+}
+
+/^typedef struct [^{]*;/ {
+	sub(";", "");
+	typedefs[$3] = $4;
+	next;
+}
+/^typedef struct .*{/ {
+	brace = 1;
+	instruct = 1;
+	next;
+}
+
+/^struct .*{/ {
+	instruct = $2;
+	brace = 1;
+	next;
+}
Index: /trunk/xcache.ini
===================================================================
--- /trunk/xcache.ini	(revision 1182)
+++ /trunk/xcache.ini	(revision 1)
@@ -1,84 +1,36 @@
-;; this is an example, it won't work unless properly configured into php.ini
 [xcache-common]
-;; non-Windows example:
+;; install as extension, make sure your extension_dir setting is correct
 extension = xcache.so
-;; Windows example:
-; extension = php_xcache.dll
+;; or install as zend extension, normally "$extension_dir/xcache.so"
+; zend_extension = /usr/local/lib/php/extensions/non-debug-non-zts-xxx/xcache.so
 
-[xcache.admin]
-xcache.admin.enable_auth = On
-xcache.admin.user = "mOo"
-; set xcache.admin.pass = md5($your_password)
-; login use $your_password
-xcache.admin.pass = ""
+; required for >=php5.1 if you turn xcache on
+auto_globals_jit = Off
 
 [xcache]
-; ini only settings, all the values here is default unless explained
-
-; select low level shm implemenation
-xcache.shm_scheme =        "mmap"
+; ini only settings, all the values here is default
 ; to disable: xcache.size=0
-; to enable : xcache.size=64M etc (any size > 0) and your system mmap allows
-xcache.size  =               60M
-; set to cpu count (cat /proc/cpuinfo |grep -c processor)
+; to enable : xcache.size=any size > 0 and your system mmap allows
+xcache.size =                  0
+; uncomment and set to cpu count (cat /proc/cpuinfo |grep -c processor)
 xcache.count =                 1
-; just a hash hints, you can always store count(items) > slots
+; just a hash hints, you can always store count(entries) > slots
 xcache.slots =                8K
-; ttl of the cache item, 0=forever
-xcache.ttl   =                 0
-; interval of gc scanning expired items, 0=no scan, other values is in seconds
-xcache.gc_interval =           0
 
 ; same as aboves but for variable cache
-xcache.var_size  =            4M
+xcache.var_size =              0
 xcache.var_count =             1
 xcache.var_slots =            8K
-; default value for $ttl parameter of xcache_*() functions
-xcache.var_ttl   =             0
-; hard limit ttl that cannot be exceed by xcache_*() functions. 0=unlimited
-xcache.var_maxttl   =          0
-xcache.var_gc_interval =     300
 
-; mode:0, const string specified by xcache.var_namespace
-; mode:1, $_SERVER[xcache.var_namespace]
-; mode:2, uid or gid (specified by xcache.var_namespace)
-xcache.var_namespace_mode =    0
-xcache.var_namespace =        ""
-
+xcache.test =                Off
 ; N/A for /dev/zero
 xcache.readonly_protection = Off
-; for *nix, xcache.mmap_path is a file path, not directory. (auto create/overwrite)
-; Use something like "/tmp/xcache" instead of "/dev/*" if you want to turn on ReadonlyProtection
-; different process group of php won't share the same /tmp/xcache
-; for win32, xcache.mmap_path=anonymous map name, not file path
+; uncomment and change to "/tmp/xcache" for readonly protection
 xcache.mmap_path =    "/dev/zero"
+; leave it blank(disabled) or "/tmp/phpcore/"
+; make sure it's writable
+xcache.coredump_directory =   ""
 
-
-; Useful when XCache crash. leave it blank(disabled) or "/tmp/phpcore/" (writable by php)
-xcache.coredump_directory =   ""
-; Windows only. leave it as 0 (default) until you're told by XCache dev
-xcache.coredump_type =         0
-
-; disable cache after crash
-xcache.disable_on_crash =    Off
-
-; enable experimental documented features for each release if available
-xcache.experimental =        Off
-
-; per request settings. can ini_set, .htaccess etc
+; pre request settings
 xcache.cacher =               On
-xcache.stat   =               On
 xcache.optimizer =           Off
-
-[xcache.coverager]
-; enabling this feature will impact performance
-; enabled only if xcache.coverager == On && xcache.coveragedump_directory == "non-empty-value"
-
-; per request settings. can ini_set, .htaccess etc
-; enable coverage data collecting and xcache_coverager_start/stop/get/clean() functions
-xcache.coverager =           Off
-xcache.coverager_autostart =  On
-
-; set in php ini file only
-; make sure it's readable (open_basedir is checked) by coverage viewer script
-xcache.coveragedump_directory = ""
Index: /trunk/mmap.c
===================================================================
--- /trunk/mmap.c	(revision 1)
+++ /trunk/mmap.c	(revision 1)
@@ -0,0 +1,191 @@
+
+#undef ALLOC_DEBUG
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+/* mmap */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "php.h"
+#include "myshm.h"
+
+#ifndef max
+#define max(a, b) ((a) < (b) ? (b) : (a))
+#endif
+
+// {{{ xc_shm_t
+struct _xc_shm_t {
+	void *ptr;
+	void *ptr_ro;
+	long  diff;
+	xc_shmsize_t size;
+};
+
+#ifdef ALLOC_DEBUG
+#	undef NDEBUG
+#	define inline
+#else
+#	define NDEBUG
+#endif
+#include <assert.h>
+/* }}} */
+#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
+
+int xc_shm_can_readonly(xc_shm_t *shm) /* {{{ */
+{
+	return shm->ptr_ro != NULL;
+}
+/* }}} */
+int xc_shm_is_readwrite(xc_shm_t *shm, const void *p) /* {{{ */
+{
+	return p >= shm->ptr && (char *)p < (char *)shm->ptr + shm->size;
+}
+/* }}} */
+int xc_shm_is_readonly(xc_shm_t *shm, const void *p) /* {{{ */
+{
+	return xc_shm_can_readonly(shm) && p >= shm->ptr_ro && (char *)p < (char *)shm->ptr_ro + shm->size;
+}
+/* }}} */
+void *xc_shm_to_readwrite(xc_shm_t *shm, void *p) /* {{{ */
+{
+	if (shm->diff) {
+		assert(xc_shm_is_readonly(p));
+		p = p - shm->diff;
+	}
+	assert(xc_shm_is_readwrite(p));
+	return p;
+}
+/* }}} */
+void *xc_shm_to_readonly(xc_shm_t *shm, void *p) /* {{{ */
+{
+	assert(xc_shm_is_readwrite(p));
+	if (shm->diff) {
+		p = p + shm->diff;
+		assert(xc_shm_is_readonly(p));
+	}
+	return p;
+}
+/* }}} */
+
+void xc_shm_destroy(xc_shm_t *shm) /* {{{ */
+{
+	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;
+		*/
+	}
+	/*
+	shm->size = NULL;
+	shm->diff = 0;
+	*/
+
+	free(shm);
+	return;
+}
+/* }}} */
+xc_shm_t *xc_shm_init(const char *path, xc_shmsize_t size, zend_bool readonly_protection) /* {{{ */
+{
+	xc_shm_t *shm = NULL;
+	int fd;
+	int ro_ok;
+	volatile void *romem;
+	int created = 0;
+
+	CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM");
+	shm->size = size;
+	if (path == NULL || !path[0]) {
+		path = "/tmp/xcache";
+	}
+	fd = open(path, O_RDWR, S_IRUSR | S_IWUSR);
+	if (fd == -1) {
+		created = 1;
+		fd = open(path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+		if (fd == -1) {
+			if (created) {
+				unlink(path);
+			}
+			goto err;
+		}
+	}
+	ftruncate(fd, size);
+
+	shm->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	if (shm->ptr == MAP_FAILED) {
+		shm->ptr = NULL;
+		close(fd);
+		if (created) {
+			unlink(path);
+		}
+		goto err;
+	}
+
+	ro_ok = 0;
+	if (readonly_protection) {
+		shm->ptr_ro = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+		romem = shm->ptr_ro;
+
+		/* {{{ check if ptr_ro works */
+		do {
+			if (shm->ptr_ro == MAP_FAILED || shm->ptr_ro == 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 = shm->ptr_ro - shm->ptr;
+		assert(abs(shm->diff) >= size);
+	}
+	else {
+		if (shm->ptr_ro != MAP_FAILED) {
+			munmap(shm->ptr_ro, size);
+		}
+		shm->ptr_ro = NULL;
+		shm->diff = 0;
+	}
+	/* }}} */
+
+	close(fd);
+	if (created) {
+		unlink(path);
+	}
+
+	return shm;
+
+err:
+	if (shm) {
+		xc_shm_destroy(shm);
+	}
+	return NULL;
+}
+/* }}} */
+
+void *xc_shm_ptr(xc_shm_t *shm) /* {{{ */
+{
+	return shm->ptr;
+}
+/* }}} */
Index: /trunk/processor/main.m4
===================================================================
--- /trunk/processor/main.m4	(revision 1201)
+++ /trunk/processor/main.m4	(revision 1)
@@ -1,6 +1,5 @@
 divert(-1)
 dnl ================ start ======================
-dnl define(`XCACHE_ENABLE_TEST')
-dnl define(`DEBUG_SIZE')
+define(`XCACHE_ENABLE_TEST')
 define(`USEMEMCPY')
 
@@ -8,31 +7,22 @@
 
 dnl {{{ basic
-define(`REDEF', `ifdef(`$1', `undefine(`$1')') define(`$1', `$2')')
-define(`MAKE_MACRONAME', `translit(`$1', ` ():
-', `_____')')
-define(`ONCE', `ifdef(MAKE_MACRONAME(`ONCE $1'), `', `define(MAKE_MACRONAME(`ONCE $1'))$1')')
+define(`REDEF', `undefine(`$1') define(`$1', `$2')')
+define(`ONCE', `ifdef(`ONCE $1', `', `define(`ONCE $1')$1')')
 define(`m4_errprint', `ONCE(`errprint(`$1
 ')')')
-ifdef(`len', `
-define(`m4_len', defn(`len'))
-undefine(`len')
-')
-define(`ZEND_STRS', `($1), (sizeof($1))')
-define(`ZEND_STRL', `($1), (sizeof($1) - 1)')
-define(`DST', `dst->$1')
-define(`SRC', `src->$1')
 dnl ============
 define(`INDENT', `xc_dprint_indent(indent);')
 dnl }}}
-dnl {{{ ALLOC(1:dst, 2:type, 3:count=1, 4:clean=false, 5:realtype=$2)
+dnl {{{ ALLOC(1:dst, 2:type, 3:count=1, 4:clean=false, 5:forcetype=$2)
+dnl don't use typeof(dst) as we need the compiler warning
 define(`ALLOC', `
 	pushdef(`COUNT', `ifelse(`$3', `', `1', `$3')')
 	pushdef(`SIZE', `sizeof($2)ifelse(`$3', `', `', ` * $3')')
-	pushdef(`REALTYPE', `ifelse(`$5', , `$2', `$5')')
+	pushdef(`FORCETYPE', `ifelse(`$5', , `$2', `$5')')
 	/* allocate */
 	IFCALC(`
-		IFAUTOCHECK(`
-			xc_stack_push(&processor->allocsizes, (void *) (long) (SIZE));
-			xc_stack_push(&processor->allocsizes, (void *) (long) (__LINE__));
+		IFASSERT(`
+			xc_stack_push(&processor->allocsizes, (void*)(SIZE));
+			xc_stack_push(&processor->allocsizes, (void*)(__LINE__));
 		')
 		processor->size = (size_t) ALIGN(processor->size);
@@ -40,74 +30,76 @@
 	')
 	IFSTORE(`
-		IFAUTOCHECK(`{
-			if (!xc_stack_count(&processor->allocsizes)) {
+		IFASSERT(`{
+			if (!xc_stack_size(&processor->allocsizes)) {
 				fprintf(stderr, "mismatch `$@' at line %d\n", __LINE__);
 			}
 			else {
-				unsigned long expect = (unsigned long) xc_stack_pop(&processor->allocsizes);
-				unsigned long atline = (unsigned long) xc_stack_pop(&processor->allocsizes);
-				unsigned long real = SIZE;
+				int expect = (int)xc_stack_pop(&processor->allocsizes);
+				int atline = (int)xc_stack_pop(&processor->allocsizes);
+				int real = SIZE;
 				if (expect != real) {
-					fprintf(stderr, "mismatch `$@' at line %d(was %lu): real %lu - expect %lu = %lu\n", __LINE__, atline, real, expect, real - expect);
+					fprintf(stderr, "mismatch `$@' at line %d(was %d): real %d - expect %d = %d\n", __LINE__, atline, real, expect, real - expect);
 				}
 			}
 		}')
-		ifdef(`DEBUG_SIZE', ` {
-			void *oldp = processor->p;
-		')
-		$1 = (REALTYPE *) (processor->p = (char *) ALIGN(processor->p));
+		$1 = (FORCETYPE *) (processor->p = (char *) ALIGN(processor->p));
 		ifelse(`$4', `', `
-				IFAUTOCHECK(`memsetptr($1, (void *) (unsigned long) __LINE__, SIZE);')
+				IFASSERT(`memset($1, -1, SIZE);')
 			', `
 				memset($1, 0, SIZE);
 		')
 		processor->p += SIZE;
-
-		ifdef(`DEBUG_SIZE', `
-			xc_totalsize += (char *) processor->p - (char *) oldp;
-			fprintf(stderr, "%d\t%d\t`'SIZE()\n", (char *) processor->p - (char *) oldp, xc_totalsize);
-		}
-		')
 	')
 	IFRESTORE(`ifelse(`$4', `', `
 			ifelse(
-				REALTYPE*COUNT, `zval*1', `ALLOC_ZVAL($1);',
-				REALTYPE*COUNT, `HashTable*1', `ALLOC_HASHTABLE($1);',
-				`', `', `$1 = (REALTYPE *) emalloc(SIZE);')
-			IFAUTOCHECK(`memsetptr($1, (void *) __LINE__, SIZE);')
+				FORCETYPE*COUNT, `zval*1', `ALLOC_ZVAL($1);',
+				FORCETYPE*COUNT, `HashTable*1', `ALLOC_HASHTABLE($1);',
+				`', `', `$1 = (FORCETYPE *) emalloc(SIZE);')
+			IFASSERT(`memset($1, -1, SIZE);')
 		', `
-			$1 = (REALTYPE *) ecalloc(COUNT, sizeof($2));
+			$1 = (FORCETYPE *) ecalloc(COUNT, sizeof($2));
 		')
 	')
-	popdef(`REALTYPE')
 	popdef(`COUNT')
 	popdef(`SIZE')
 ')
-dnl CALLOC(1:dst, 2:type [, 3:count=1, 4:realtype=$2 ])
-define(`CALLOC', `ALLOC(`$1', `$2', `$3', `1', `$4')')
-dnl }}}
-dnl {{{ PROC_CLASS_ENTRY_P(1:elm)
-define(`PROC_CLASS_ENTRY_P', `PROC_CLASS_ENTRY_P_EX(`dst->$1', `SRC(`$1')', `$1')`'DONE(`$1')')
-dnl PROC_CLASS_ENTRY_P_EX(1:dst, 2:src, 3:elm-name)
+dnl CALLOC(1:dst, 2:type [, 3:count=1 ])
+define(`CALLOC', `ALLOC(`$1', `$2', `$3', `1')')
+dnl }}}
+dnl {{{ PROC_INT(1:elm, 2:format=%d, 3:type=, 4:spec=)
+define(`PROC_INT', `
+	IFNOTMEMCPY(`IFCOPY(`dst->$1 = src->$1;')')
+	IFDPRINT(`
+		INDENT()
+		ifelse(
+			`$3 $1', `zval_data_type type', `fprintf(stderr, "$3:$1:\t%d %s\n", src->$1, xc_get_data_type(src->$1));'
+		, `$3 $1', `int op_type', `fprintf(stderr, "$3:$1:\t%d %s\n", src->$1, xc_get_op_type(src->$1));'
+		, `$3 $1', `zend_uchar opcode', `fprintf(stderr, "$3:$1:\t%d %s\n", src->$1, xc_get_opcode(src->$1));'
+		, `', `', `fprintf(stderr, "$3:$1:\t%ifelse(`$2',`',`d',`$2')\n", src->$1);')
+	')
+	IFDASM(`
+		ifelse(
+			`$3', `zend_bool', `add_assoc_bool_ex(dst, ZEND_STRS("$1"), src->$1 ? 1 : 0);'
+		, `', `', `add_assoc_long_ex(dst, ZEND_STRS("$1"), src->$1);'
+		)
+	')
+	DONE(`$1')
+')
+dnl }}}
+dnl {{{ PROC_CLASS_ENTRY_P
+define(`PROC_CLASS_ENTRY_P', `PROC_CLASS_ENTRY_P_EX(`dst->$1', `src->$1')`'DONE(`$1')')
 define(`PROC_CLASS_ENTRY_P_EX', `
 	if ($2) {
 		IFSTORE(`$1 = (zend_class_entry *) xc_get_class_num(processor, $2);')
-		IFRESTORE(`$1 = xc_get_class(processor, (zend_ulong) $2);')
-#ifdef IS_UNICODE
-		IFDASM(`add_assoc_unicodel_ex(dst, ZEND_STRS("$3"), ZSTR_U($2->name), $2->name_length, 1);')
-#else
-		IFDASM(`add_assoc_stringl_ex(dst, ZEND_STRS("$3"), (char *) $2->name, $2->name_length, 1);')
-#endif
+		IFRESTORE(`$1 = xc_get_class(processor, (zend_uint) $2);')
+		IFDASM(`add_assoc_stringl_ex(dst, ZEND_STRS("patsubst(`$1', `dst->')"), $2->name, strlen($2->name), 1);')
 	}
 	else {
-		COPYNULL_EX(`$1', `$3')
+		COPYNULL_EX($1)
 	}
 ')
 dnl }}}
-dnl {{{ IFAUTOCHECKEX
-define(`IFAUTOCHECKEX', `ifdef(`XCACHE_ENABLE_TEST', `$1', `$2')')
-dnl }}}
-dnl {{{ IFAUTOCHECK
-define(`IFAUTOCHECK', `IFAUTOCHECKEX(`
+dnl {{{ IFASSERT
+define(`IFASSERT', `ifdef(`XCACHE_ENABLE_TEST', `
 #ifndef NDEBUG
 		$1
@@ -126,33 +118,13 @@
 define(`FIXPOINTER', `FIXPOINTER_EX(`$1', `dst->$2')')
 define(`FIXPOINTER_EX', `IFSTORE(`
-	$2 = ($1 *) processor->shm->handlers->to_readonly(processor->shm, (char *)$2);
+	$2 = ($1 *) xc_shm_to_readonly(processor->xce_src->cache->shm, (char *)$2);
 ')')
 define(`UNFIXPOINTER', `UNFIXPOINTER_EX(`$1', `dst->$2')')
 define(`UNFIXPOINTER_EX', `IFSTORE(`
-	$2 = ($1 *) processor->shm->handlers->to_readwrite(processor->shm, (char *)$2);
+	$2 = ($1 *) xc_shm_to_readwrite(processor->xce_src->cache->shm, (char *)$2);
 ')')
 dnl }}}
 dnl {{{ COPY
-define(`COPY', `IFNOTMEMCPY(`IFCOPY(`dst->$1 = SRC(`$1');')')DONE(`$1')')
-dnl }}}
-dnl {{{ COPY_N_EX
-define(`COPY_N_EX', `
-	ALLOC(`dst->$3', `$2', `SRC(`$1')')
-	IFCOPY(`
-		memcpy(dst->$3, SRC(`$3'), sizeof(dst->$3[0]) * SRC(`$1'));
-		')
-')
-dnl }}}
-dnl {{{ COPY_N
-define(`COPY_N', `COPY_N_EX(`$1',`$2')DONE(`$1')')
-dnl }}}
-dnl {{{ COPYPOINTER
-define(`COPYPOINTER', `COPY(`$1')')
-dnl }}}
-dnl {{{ COPYARRAY_EX
-define(`COPYARRAY_EX', `IFNOTMEMCPY(`IFCOPY(`memcpy(dst->$1, SRC(`$1'), sizeof(dst->$1));')')')
-dnl }}}
-dnl {{{ COPYARRAY
-define(`COPYARRAY', `COPYARRAY_EX(`$1',`$2')DONE(`$1')')
+define(`COPY', `IFNOTMEMCPY(`IFCOPY(`dst->$1 = src->$1;')')DONE(`$1')')
 dnl }}}
 dnl {{{ SETNULL_EX
@@ -160,70 +132,22 @@
 define(`SETNULL', `SETNULL_EX(`dst->$1')DONE(`$1')')
 dnl }}}
-dnl {{{ SETZERO_EX
-define(`SETZERO_EX', `IFCOPY(`$1 = 0;')')
-define(`SETZERO', `SETZERO_EX(`dst->$1')DONE(`$1')')
-dnl }}}
-dnl {{{ COPYNULL_EX(1:dst, 2:elm-name)
+dnl {{{ COPYNULL_EX
 define(`COPYNULL_EX', `
-	IFDASM(`add_assoc_null_ex(dst, ZEND_STRS("$2"));')
+	IFDASM(`add_assoc_null_ex(dst, ZEND_STRS("patsubst(`$1', `dst->')"));')
 	IFNOTMEMCPY(`IFCOPY(`$1 = NULL;')')
-	assert(patsubst($1, dst, src) == NULL);
-')
-dnl }}}
-dnl {{{ COPYNULL(1:elm)
+')
 define(`COPYNULL', `
-	COPYNULL_EX(`dst->$1', `$1')DONE(`$1')
-')
-dnl }}}
-dnl {{{ COPYZERO_EX(1:dst, 2:elm-name)
-define(`COPYZERO_EX', `
-	IFDASM(`add_assoc_long_ex(dst, ZEND_STRS("$2"), 0);')
-	IFNOTMEMCPY(`IFCOPY(`$1 = 0;')')
-	assert(patsubst($1, dst, src) == 0);
-')
-dnl }}}
-dnl {{{ COPYZERO(1:elm)
-define(`COPYZERO', `
-	COPYZERO_EX(`dst->$1', `$1')DONE(`$1')
-')
-dnl }}}
-dnl {{{ LIST_DIFF(1:left-list, 2:right-list)
-define(`foreach',
-       `pushdef(`$1')_foreach(`$1', `$2', `$3')popdef(`$1')')
-define(`_arg1', `$1')
-define(`_foreach',                             
-       `ifelse(`$2', `()', ,                       
-       `define(`$1', _arg1$2)$3`'_foreach(`$1',
-                                                       (shift$2),
-                                                       `$3')')')
-define(`LIST_DIFF', `dnl
-foreach(`i', `($1)', `pushdef(`item_'defn(`i'))')dnl allocate variable for items in $1 
-foreach(`i', `($2)', `pushdef(`item_'defn(`i'))undefine(`item_'defn(`i'))')dnl allocate variable for items in $2, and undefine it 
-foreach(`i', `($1)', `ifdef(`item_'defn(`i'), `defn(`i') ')')dnl see what is still defined
-foreach(`i', `($2)', `define(`item_'defn(`i'))popdef(`item_'defn(`i'))')dnl
-foreach(`i', `($1)', `popdef(`item_'defn(`i'))')dnl
+	COPYNULL_EX(`dst->$1')DONE(`$1')
 ')
 dnl }}}
 dnl {{{ DONE_*
-define(`DONE_SIZE', `IFAUTOCHECK(`dnl
-	xc_autocheck_done_size += (int) $1`';
-	xc_autocheck_done_count ++;
+define(`DONE_SIZE', `IFASSERT(`
+	done_size += $1`';
+	done_count ++;
 ')')
 define(`DONE', `
-	define(`ELEMENTS_DONE', defn(`ELEMENTS_DONE')`,"$1"')
-	IFAUTOCHECK(`dnl
-		if (zend_u_hash_exists(&xc_autocheck_done_names, IS_STRING, "$1", sizeof("$1"))) {
-			fprintf(stderr
-				, "duplicate field at %s `#'%d FUNC_NAME`' : %s\n"
-				, __FILE__, __LINE__
-				, "$1"
-				);
-		}
-		else {
-			zend_uchar b = 1;
-			zend_hash_add(&xc_autocheck_done_names, "$1", sizeof("$1"), (void*)&b, sizeof(b), NULL);
-		}
-	')
-	DONE_SIZE(`sizeof(SRC(`$1'))')
+	dnl ifelse(regexp(defn(`ELEMENTS'), ` $1'), -1, m4_errprint(`Unknown $1') m4exit(1))
+	define(`ELEMENTS', patsubst(defn(`ELEMENTS'), ` $1\>'))
+	DONE_SIZE(`sizeof(src->$1)')
 ')
 define(`DISABLECHECK', `
@@ -236,13 +160,19 @@
 dnl }}}
 dnl {{{ IF**
-define(`IFCALC', `ifelse(PROCESSOR_TYPE, `calc', `$1', `$2')')
-define(`IFSTORE', `ifelse(PROCESSOR_TYPE, `store', `$1', `$2')')
-define(`IFCALCSTORE', `IFSTORE(`$1', `IFCALC(`$1', `$2')')')
-define(`IFRESTORE', `ifelse(PROCESSOR_TYPE, `restore', `$1', `$2')')
-define(`IFCOPY', `IFSTORE(`$1', `IFRESTORE(`$1', `$2')')')
-define(`IFCALCCOPY', `IFCALC(`$1', `IFCOPY(`$1', `$2')')')
-define(`IFDPRINT', `ifelse(PROCESSOR_TYPE, `dprint', `$1', `$2')')
-define(`IFASM', `ifelse(PROCESSOR_TYPE, `asm', `$1', `$2')')
-define(`IFDASM', `ifelse(PROCESSOR_TYPE, `dasm', `$1', `$2')')
+define(`IFCALC', `ifelse(KIND, `calc', `$1', `$2')')
+define(`IFSTORE', `ifelse(KIND, `store', `$1', `$2')')
+define(`IFCALCSTORE', `IFSTORE(`$1', `
+	IFCALC(`$1', `$2')
+')')
+define(`IFRESTORE', `ifelse(KIND, `restore', `$1', `$2')')
+define(`IFCOPY', `IFSTORE(`$1', `
+	IFRESTORE(`$1', `$2')
+')')
+define(`IFCALCCOPY', `IFCALC(`$1', `
+	IFCOPY(`$1', `$2')
+')')
+define(`IFDPRINT', `ifelse(KIND, `dprint', `$1', `$2')')
+define(`IFASM', `ifelse(KIND, `asm', `$1', `$2')')
+define(`IFDASM', `ifelse(KIND, `dasm', `$1', `$2')')
 dnl }}}
 EXPORT(`zend_op')
@@ -253,33 +183,27 @@
 EXPORT(`xc_classinfo_t')
 EXPORT(`xc_funcinfo_t')
-EXPORT(`xc_entry_var_t')
-EXPORT(`xc_entry_php_t')
-EXPORT(`xc_entry_data_php_t')
+EXPORT(`xc_entry_t')
 EXPORT(`zval')
 
-include(srcdir`/processor/hashtable.m4')
-include(srcdir`/processor/string.m4')
-include(srcdir`/processor/struct.m4')
-include(srcdir`/processor/process.m4')
-include(srcdir`/processor/head.m4')
+include(hashtable.m4)
+include(string.m4)
+include(struct.m4)
+include(dispatch.m4)
+include(head.m4)
 
 define(`IFNOTMEMCPY', `ifdef(`USEMEMCPY', `', `$1')')
-REDEF(`PROCESSOR_TYPE', `calc') include(srcdir`/processor/processor.m4')
-pushdef(`xc_get_class_num', ``xc_get_class_num'($@)')
-REDEF(`PROCESSOR_TYPE', `store') include(srcdir`/processor/processor.m4')
-popdef(`xc_get_class_num')
-pushdef(`xc_get_class', ``xc_get_class'($@)')
-REDEF(`PROCESSOR_TYPE', `restore') include(srcdir`/processor/processor.m4')
-popdef(`xc_get_class')
+REDEF(`KIND', `calc') include(processor.m4)
+REDEF(`KIND', `store') include(processor.m4)
+REDEF(`KIND', `restore') include(processor.m4)
 
 REDEF(`IFNOTMEMCPY', `$1')
 #ifdef HAVE_XCACHE_DPRINT
-REDEF(`PROCESSOR_TYPE', `dprint') include(srcdir`/processor/processor.m4')
+REDEF(`KIND', `dprint') include(processor.m4)
 #endif /* HAVE_XCACHE_DPRINT */
 #ifdef HAVE_XCACHE_DISASSEMBLER
-REDEF(`PROCESSOR_TYPE', `dasm') include(srcdir`/processor/processor.m4')
+REDEF(`KIND', `dasm') include(processor.m4)
 #endif /* HAVE_XCACHE_DISASSEMBLER */
 #ifdef HAVE_XCACHE_ASSEMBLER
-REDEF(`PROCESSOR_TYPE', `asm') include(srcdir`/processor/processor.m4')
+REDEF(`KIND', `asm') include(processor.m4)
 #endif /* HAVE_XCACHE_ASSEMBLER */
 
Index: /trunk/processor/struct.m4
===================================================================
--- /trunk/processor/struct.m4	(revision 1112)
+++ /trunk/processor/struct.m4	(revision 1)
@@ -1,7 +1,7 @@
 define(`pushdefFUNC_NAME', `
-	pushdef(`FUNC_NAME', `xc_`'PROCESSOR_TYPE`'_`'ifelse(`$2', `', `$1', `$2')')
+	pushdef(`FUNC_NAME', `xc_`'KIND`'_`'ifelse(`$2', `', `$1', `$2')')
 ')
 dnl {{{ DECL_STRUCT_P_FUNC(1:type, 2:name, 3:comma=;)
-define(`DECL_STRUCT_P_FUNC', `translit(
+define(`DECL_STRUCT_P_FUNC', `patsubst(
 	pushdefFUNC_NAME(`$1', `$2')
 	define(`DEFINED_'ifelse(`$2', `', `$1', `$2'), `')
@@ -9,14 +9,14 @@
 	FUNC_NAME`'(
 		IFDPRINT( `const $1 * const src, int indent')
-		IFCALC(   `xc_processor_t *processor, const $1 * const src')
-		IFSTORE(  `xc_processor_t *processor, $1 *dst, const $1 * const src')
-		IFRESTORE(`xc_processor_t *processor, $1 *dst, const $1 * const src')
-		IFDASM(   `xc_dasm_t *dasm, zval *dst, const $1 * const src')
+		IFCALC(   `processor_t *processor, const $1 * const src')
+		IFSTORE(  `processor_t *processor, $1 *dst, const $1 * const src')
+		IFRESTORE(`processor_t *processor, $1 *dst, const $1 * const src')
+		IFDASM(   `zval *dst, const $1 * const src')
 		IFASM(    `$1 *dst, const $1 * const src')
 		TSRMLS_DC
 	)ifelse(`$3', `', `;')
 	popdef(`FUNC_NAME')dnl
-, `
-', ` ')')
+, `[
+	 ]+', ` ')')
 dnl }}}
 dnl {{{ DEF_STRUCT_P_FUNC(1:type, 2:name, 3:body)
@@ -29,46 +29,24 @@
 DECL_STRUCT_P_FUNC(`$1', `$2', 1)
 	{
-		pushdef(`ELEMENTS_DONE')
-		IFAUTOCHECK(`
+		IFASSERT(`
 			/* {{{ init assert */
-			ifdef(`SIZEOF_$1', , `m4_errprint(`Warning: missing SIZEOF_$1, safe to ignore')')
-			ifdef(`COUNTOF_$1', , `m4_errprint(`Warning: missing COUNTOF_$1, safe to ignore')')
-			dnl SIZEOF_x COUNTOF_x can be both defined or both not
-			ifdef(`SIZEOF_$1', `
-				ifdef(`COUNTOF_$1', , `m4_errprint(`AUTOCHECK WARN: missing COUNTOF_$1')')
-			', `
-				define(`SIZEOF_$1', 0)
+			ifdef(`SIZEOF_$1', , `m4_errprint(`missing SIZEOF_$1, safe to ignore')define(`SIZEOF_$1', 0)')
+			ifdef(`COUNTOF_$1', , `m4_errprint(`missing COUNTOF_$1, safe to ignore')define(`COUNTOF_$1', 0)')
+			int assert_size = SIZEOF_$1, assert_count = COUNTOF_$1;
+			int done_size = 0, done_count = 0;
+			ifdef(`ELEMENTSOF_$1', `
+				define(`ELEMENTS', defn(`ELEMENTSOF_$1'))
 			')
-			ifdef(`COUNTOF_$1', `
-				ifdef(`SIZEOF_$1', , `m4_errprint(`AUTOCHECK WARN: missing SIZEOF_$1')')
-			', `
-				define(`COUNTOF_$1', 0)
-			')
-			int xc_autocheck_assert_size = SIZEOF_$1, assert_count = COUNTOF_$1;
-			int xc_autocheck_done_size = 0, xc_autocheck_done_count = 0;
-			ifdef(`ELEMENTSOF_$1', `
-				const char *xc_autocheck_assert_names[] = { ELEMENTSOF_$1 };
-				size_t xc_autocheck_assert_names_count = sizeof(xc_autocheck_assert_names) / sizeof(xc_autocheck_assert_names[0]);
-			', `
-				const char **xc_autocheck_assert_names = NULL;
-				size_t xc_autocheck_assert_names_count = 0;
-			')
-			zend_bool xc_autocheck_skip = 0;
-			HashTable xc_autocheck_done_names;
-			zend_hash_init(&xc_autocheck_done_names, 0, NULL, NULL, 0);
 			/* }}} */
 			IFRESTORE(`assert(xc_is_shm(src));')
 			IFCALCSTORE(`assert(!xc_is_shm(src));')
-			do {
 		')
-		ifdef(`SIZEOF_$1', , `m4_errprint(`AUTOCHECK WARN: $1: missing structinfo, dont panic')')
 
 		ifdef(`USEMEMCPY', `IFCOPY(`
 			memcpy(dst, src, sizeof($1));
-			do {
 		')')
 
 		IFDPRINT(`
-			fprintf(stderr, "%s", "{\n");
+			fprintf(stderr, "%s", " {\n");
 			indent ++;
 		')
@@ -78,47 +56,33 @@
 			INDENT()fprintf(stderr, "}\n");
 		')
-		IFAUTOCHECK(`
-		/* {{{ autocheck */
-		if (!xc_autocheck_skip) {
-			int name_check_errors = xc_check_names(__FILE__, __LINE__, "FUNC_NAME", xc_autocheck_assert_names, xc_autocheck_assert_names_count, &xc_autocheck_done_names);
-
-			if (xc_autocheck_done_count != assert_count) {
-				fprintf(stderr
-					, "count assertion failed at %s `#'%d FUNC_NAME`' : unexpected:%d - expecting:%d = %d != 0\n"
-					, __FILE__, __LINE__
-					, xc_autocheck_done_count, assert_count, xc_autocheck_done_count - assert_count
-					);
-			}
-			if (xc_autocheck_done_size != xc_autocheck_assert_size) {
-				fprintf(stderr
-					, "size assertion failed at %s `#'%d FUNC_NAME`' : unexpected:%d - expecting:%d = %d != 0\n"
-					, __FILE__, __LINE__
-					, xc_autocheck_done_size, xc_autocheck_assert_size, xc_autocheck_done_size - xc_autocheck_assert_size
-					);
-			}
-			if (name_check_errors || xc_autocheck_done_count != assert_count || xc_autocheck_done_size != xc_autocheck_assert_size) {
-				assert(0);
-			}
-		}
-		zend_hash_destroy(&xc_autocheck_done_names);
-		/* }}} */
-		')
-		ifdef(`ELEMENTSOF_$1', `
-			pushdef(`ELEMENTS_UNDONE', LIST_DIFF(defn(`ELEMENTSOF_$1'), defn(`ELEMENTS_DONE')))
-			ifelse(defn(`ELEMENTS_UNDONE'), , `m4_errprint(`AUTOCHECK INFO: $1: processor looks good')', `
-				m4_errprint(`AUTOCHECK ERROR: ====' PROCESSOR_TYPE `$1 =================')
-				m4_errprint(`AUTOCHECK expected:' defn(`ELEMENTSOF_$1'))
-				m4_errprint(`AUTOCHECK missing :' defn(`ELEMENTS_UNDONE'))
-				define(`EXIT_PENDING', 1)
-			')
-			popdef(`ELEMENTS_UNDONE')
-		')
-		ifdef(`USEMEMCPY', `IFCOPY(`
-			} while (0);
+		ifdef(`SKIPASSERT_ONCE', `undefine(`SKIPASSERT_ONCE')', `IFASSERT(`
+				/* {{{ check assert */
+				if (done_count != assert_count) {
+					fprintf(stderr
+						, "count assertion failed at %s `#'%d FUNC_NAME`' : unexpected %d - expected %d = %d != 0\n"
+						, __FILE__, __LINE__
+						, done_count, assert_count, done_count - assert_count
+						);
+					abort();
+				}
+				if (done_size != assert_size) {
+					fprintf(stderr
+						, "size assertion failed at %s `#'%d FUNC_NAME`' : %d - %d = %d != 0\n"
+						, __FILE__, __LINE__
+						, done_size, assert_size, done_size - assert_size
+						);
+					abort();
+				}
+				ifdef(`ELEMENTSOF_$1', `
+					ifelse(ELEMENTS, , , `
+						m4_errprint(`====' KIND `$1 =================')
+						m4_errprint(`expected:' ELEMENTSOF_$1)
+						m4_errprint(`missing :' ELEMENTS)
+						define(`EXIT_PENDING', 1)
+					')
+				')
+				undefine(`ELEMENTS')
+				/* }}} */
 		')')
-		IFAUTOCHECK(`
-			} while (0);
-		')
-		popdef(`ELEMENTS_DONE')
 	}
 /* }`}'} */
@@ -126,11 +90,11 @@
 ')
 dnl }}}
-dnl {{{ STRUCT_P_EX(1:type, 2:dst, 3:src, 4:elm-name, 5:name=type, 6:&)
+dnl {{{ STRUCT_P_EX(1:type, 2:dst, 3:src, 4:name=type, 5:&)
 define(`STRUCT_P_EX', `
 	DBG(`$0($*)')
-	pushdefFUNC_NAME(`$1', `$5')
-	ifdef(`DEFINED_'ifelse(`$5', `', `$1', `$5'), `', `m4_errprint(`AUTOCHECK ERROR: Unknown struct "'ifelse(`$5', `', `$1', `$5')`"')define(`EXIT_PENDING', 1)')
-	assert(sizeof($1) == sizeof(($6 $3)[0]));
-	ifelse(`$6', `', `ALLOC(`$2', `$1')')
+	pushdefFUNC_NAME(`$1', `$4')
+	ifdef(`DEFINED_'ifelse(`$4', `', `$1', `$4'), `', `m4_errprint(`Unknown struct "'ifelse(`$4', `', `$1', `$4')`"')')
+	assert(sizeof($1) == sizeof(($5 $3)[0]));
+	ifelse(`$5', `', `ALLOC(`$2', `$1')')
 	IFDASM(`do {
 		zval *zv;
@@ -139,18 +103,18 @@
 	')
 	FUNC_NAME`'(
-		IFDPRINT( `           $6 $3, indent')
-		IFCALC(   `processor, $6 $3')
-		IFSTORE(  `processor, $6 $2, $6 $3')
-		IFRESTORE(`processor, $6 $2, $6 $3')
-		IFDASM(   `dasm, zv, $6 $3')
-		IFASM(    `$6 $2, $6 $3')
+		IFDPRINT( `           $5 $3, indent')
+		IFCALC(   `processor, $5 $3')
+		IFSTORE(  `processor, $5 $2, $5 $3')
+		IFRESTORE(`processor, $5 $2, $5 $3')
+		IFDASM(   `zv, $5 $3')
+		IFASM(    `$5 $2, $5 $3')
 		TSRMLS_CC
 	);
 	IFDASM(`
-		add_assoc_zval_ex(dst, ZEND_STRS("$4"), zv);
+		add_assoc_zval_ex(dst, ZEND_STRS("patsubst(`$2', `dst->')"), zv);
 	} while (0);
 	')
 	popdef(`FUNC_NAME')
-	ifelse(`$6', , `FIXPOINTER_EX(`$1', `$2')')
+	ifelse(`$5', , `FIXPOINTER_EX(`$1', `$2')')
 ')
 dnl }}}
@@ -158,11 +122,11 @@
 define(`STRUCT_P', `
 	DBG(`$0($*)')
-	if (SRC(`$2')) {
-		IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2 ");')
-		STRUCT_P_EX(`$1', `dst->$2', `SRC(`$2')', `$2', `$3')
+	if (src->$2) {
+		STRUCT_P_EX(`$1', `dst->$2', `src->$2', `$3')
+		IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2");')
 	}
 	else {
+		COPYNULL_EX(dst->$2)
 		IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2:\tNULL\n");')
-		COPYNULL_EX(`dst->$2', `$2')
 	}
 	DONE(`$2')
@@ -172,65 +136,43 @@
 define(`STRUCT', `
 	DBG(`$0($*)')
-	assert(sizeof($1) == sizeof(SRC(`$2')));
-	IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2 ");')
-	STRUCT_P_EX(`$1', `dst->$2', `SRC(`$2')', `$2', `$3', `&')
+	assert(sizeof($1) == sizeof(src->$2));
+	IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2");')
+	STRUCT_P_EX(`$1', `dst->$2', `src->$2', `$3', `&')
 	DONE(`$2')
 ')
 dnl }}}
-dnl {{{ STRUCT_ARRAY(1:count_type, 2:count, 3:type, 4:elm, 5:name=type, 6:loopcounter)
+dnl {{{ STRUCT_ARRAY(1:count, 2:type, 3:elm, 4:name=type)
 define(`STRUCT_ARRAY', `
-	if (SRC(`$4')) {
-		ifelse(
-			`$6', `', `ifelse(`$1', `', `size_t', `$1') i; pushdef(`LOOPCOUNTER', `i')',
-			`', `', `pushdef(`LOOPCOUNTER', `$6')')
-		pushdefFUNC_NAME(`$3', `$5')
+	if (src->$3) {
+		pushdefFUNC_NAME(`$2', `$4')
 		IFDASM(`
 			zval *arr;
 			ALLOC_INIT_ZVAL(arr);
 			array_init(arr);
-
-			for (LOOPCOUNTER = 0;
-					ifelse(`$2', `', `SRC(`$4[LOOPCOUNTER]')',
-					`', `', `LOOPCOUNTER < SRC(`$2')');
-					++LOOPCOUNTER) {
+			for (i = 0; i < src->$1; i ++) {
 				zval *zv;
 
 				ALLOC_INIT_ZVAL(zv);
 				array_init(zv);
-				FUNC_NAME (dasm, zv, &(SRC(`$4[LOOPCOUNTER]')) TSRMLS_CC);
+				FUNC_NAME (zv, &(src->$3[i]) TSRMLS_CC);
 				add_next_index_zval(arr, zv);
 			}
-			add_assoc_zval_ex(dst, ZEND_STRS("$4"), arr);
+			add_assoc_zval_ex(dst, ZEND_STRS("$3"), arr);
 		', `
-			dnl find count with NULL
-			ifelse(`$2', `', `
-				size_t count = 0;
-				while (SRC(`$4[count]')) {
-					++count;
-				}
-				++count;
-				pushdef(`ARRAY_ELEMENT_COUNT', `count')
-			',
-			`', `', `pushdef(`ARRAY_ELEMENT_COUNT', `SRC(`$2')')')
-			ALLOC(`dst->$4', `$3', `ARRAY_ELEMENT_COUNT')
-			popdef(`ARRAY_ELEMENT_COUNT')
-
-			for (LOOPCOUNTER = 0;
-					ifelse(`$2', `', `SRC(`$4[LOOPCOUNTER]')',
-					`', `', `LOOPCOUNTER < SRC(`$2')');
-					++LOOPCOUNTER) {
+			ALLOC(`dst->$3', `$2', `src->$1')
+			ifdef(`AFTER_ALLOC', AFTER_ALLOC)
+			for (i = 0; i < src->$1; i ++) {
 				DISABLECHECK(`
-					STRUCT(`$3', `$4[LOOPCOUNTER]', `$5')
+					ifdef(`BEFORE_LOOP', `BEFORE_LOOP')
+					STRUCT(`$2', `$3[i]', `$4')
 				')
 			}
-			dnl the end marker
-			ifelse(`$2', `', `IFCOPY(`DST(`$4[LOOPCOUNTER]') = NULL;')')
 		')dnl IFDASM
-		DONE(`$4')
+		DONE(`$3')
 		popdef(`FUNC_NAME')
-		popdef(`LOOPCOUNTER')
 	}
 	else {
-		COPYNULL(`$4')
+		COPYNULL(`$3')
+		ifdef(`AFTER_ALLOC', AFTER_ALLOC)
 	}
 ')
Index: /trunk/processor/string.m4
===================================================================
--- /trunk/processor/string.m4	(revision 860)
+++ /trunk/processor/string.m4	(revision 1)
@@ -3,28 +3,8 @@
 define(`PROC_STRING_N_EX', `
 	pushdef(`STRTYPE', `ifelse(`$5',,`char',`$5')')
-	pushdef(`PTRTYPE', ifelse(
-			STRTYPE, `char',      `char',
-			STRTYPE, `zstr_char', `char',
-			`',      `',          `UChar'))
-	pushdef(`ISTYPE', ifelse(PTRTYPE,`UChar',IS_UNICODE,IS_STRING))
-	pushdef(`UNI_STRLEN', ifelse(
-			STRTYPE, `zstr_uchar', `xc_zstrlen_uchar',
-			STRTYPE, `zstr_char',  `xc_zstrlen_char',
-			`',      `',           `strlen'))
-	pushdef(`SRCSTR', ifelse(STRTYPE,`char',`ZSTR($2)',STRTYPE,`UChar',`ZSTR($2)',`$2'))
-	pushdef(`SRCPTR', ifelse(
-			STRTYPE, `zstr_uchar', `ZSTR_U($2)',
-			STRTYPE, `zstr_char',  `ZSTR_S($2)',
-			`',      `',           `$2'))
-	pushdef(`DSTPTR', ifelse(
-			STRTYPE, `zstr_uchar', `ZSTR_U($1)',
-			STRTYPE, `zstr_char',  `ZSTR_S($1)',
-			`',      `',           `$1'))
-	pushdef(`STRDUP', ifelse(
-			PTRTYPE, `char',  `estrndup',
-			PTRTYPE, `UChar', `eustrndup'))
-	if (SRCPTR == NULL) {
+	pushdef(`ISTYPE', ifelse(STRTYPE,`char',IS_STRING,IS_UNICODE))
+	if ($2 == NULL) {
 		IFNOTMEMCPY(`IFCOPY(`
-			DSTPTR = NULL;
+			$1 = NULL;
 		')')
 		IFDASM(`
@@ -34,5 +14,5 @@
 	else {
 		IFDPRINT(`INDENT()
-			ifelse(STRTYPE, `zstr_uchar', `
+			ifelse(STRTYPE, `UChar', `
 #ifdef IS_UNICODE
 			do {
@@ -42,9 +22,7 @@
 
 				INIT_ZVAL(zv);
-				ZVAL_UNICODEL(&zv, ZSTR_U($2), $3 - 1, 1);
+				ZVAL_UNICODEL(&zv, (UChar *) ($2), $3 - 1, 1);
 				zend_make_printable_zval(&zv, &reszv, &usecopy);
-				fprintf(stderr, "string:%s:\t\"", "$1");
-				xc_dprint_str_len(Z_STRVAL(reszv), Z_STRLEN(reszv));
-				fprintf(stderr, "\" len=%lu\n", (unsigned long) $3 - 1);
+				fprintf(stderr, "string:%s:\t\"%s\" len=%d\n", "$1", reszv.value.str.val, $3 - 1);
 				if (usecopy) {
 					zval_dtor(&reszv);
@@ -54,32 +32,21 @@
 #endif
 			', `
-			fprintf(stderr, "string:%s:\t\"", "$1");
-			xc_dprint_str_len(SRCPTR, $3 - 1);
-			fprintf(stderr, "\" len=%lu\n", (unsigned long) $3 - 1);
+			fprintf(stderr, "string:%s:\t\"%s\" len=%d\n", "$1", $2, $3 - 1);
 			')
 		')
-		IFCALC(`xc_calc_string_n(processor, ISTYPE, SRCSTR, $3 C_RELAYLINE);')
-		IFSTORE(`DSTPTR = ifdef(`REALPTRTYPE', `(REALPTRTYPE() *)') ifelse(PTRTYPE,`char',`ZSTR_S',`ZSTR_U')(xc_store_string_n(processor, ISTYPE, SRCSTR, $3 C_RELAYLINE));')
+		IFCALC(`xc_calc_string_n(processor, ISTYPE, (void *) $2, `$3' IFASSERT(`, __LINE__'));')
+		IFSTORE(`$1 = (typeof($1)) xc_store_string_n(processor, ISTYPE, (char *) $2, `$3' IFASSERT(`, __LINE__'));')
 		IFRESTORE(`
-			DSTPTR = ifdef(`REALPTRTYPE', `(REALPTRTYPE() *)') STRDUP() (SRCPTR, ($3) - 1);
+			ALLOC(`$1', `typeof($1[0])', `sizeof(STRTYPE) * ($3)')
+			memcpy($1, $2, sizeof(STRTYPE) * ($3));
 		')
-		FIXPOINTER_EX(ifdef(`REALPTRTYPE', `REALPTRTYPE()', `PTRTYPE'), DSTPTR)
+		FIXPOINTER_EX(`typeof($1[0])', `$1')
 		IFDASM(`
-			ifelse(STRTYPE,zstr_uchar, `
-				add_assoc_unicodel_ex(dst, ZEND_STRS("$4"), ZSTR_U($2), $3-1, 1);
-				', ` dnl else
-				ifelse(STRTYPE,zstr_char, `
-					add_assoc_stringl_ex(dst, ZEND_STRS("$4"), (char *) ZSTR_S($2), $3-1, 1);
-					', `
-					add_assoc_stringl_ex(dst, ZEND_STRS("$4"), (char *) $2, $3-1, 1);
+				ifelse(STRTYPE,UChar, `
+					add_assoc_unicodel_ex(dst, ZEND_STRS("$4"), $2, $3-1, 1);
+					', ` dnl else
+					add_assoc_stringl_ex(dst, ZEND_STRS("$4"), $2, $3-1, 1);')
 				')
-			')
-		')
 	}
-	popdef(`STRDUP')
-	popdef(`DSTPTR')
-	popdef(`SRCPTR')
-	popdef(`SRCSTR')
-	popdef(`UNI_STRLEN')
 	popdef(`STRTYPE')
 	popdef(`ISTYPE')
@@ -87,38 +54,35 @@
 dnl }}}
 dnl PROC_STRING_N(1:name, 2:size, 3:type)
-define(`PROC_STRING_N', `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`DST(`$1')', `SRC(`$1')', `SRC(`$2')', `$1', `char')')
-define(`PROC_USTRING_N', `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`DST(`$1')', `SRC(`$1')', `SRC(`$2')', `$1', `UChar')')
+define(`PROC_STRING_N', `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`dst->$1', `src->$1', `src->$2', `$1', `char')')
 
 define(`PROC_STRING_L', `DBG(`$0($*)') PROC_STRING_N(`$1', `$2 + 1')')
-define(`PROC_USTRING_L', `DBG(`$0($*)') PROC_USTRING_N(`$1', `$2 + 1')')
-define(`PROC_STRING',   `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`DST(`$1')', `SRC(`$1')', `strlen(SRC(`$1')) + 1', `$1', `char')')
-define(`PROC_USTRING',  `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`DST(`$1')', `SRC(`$1')', `strlen(SRC(`$1')) + 1', `$1', `UChar')')
+define(`PROC_STRING',   `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`dst->$1', `src->$1', `strlen(src->$1) + 1', `$1', `char')')
 
-dnl {{{ PROC_ZSTRING_N(1:type, 2:name, 3:size, 4:size_type)
-define(`PROC_ZSTRING_N', `
+dnl {{{ PROC_USTRING_N(1:type, 2:name, 3:size, 4:size_type)
+define(`PROC_USTRING_N', `
 	DBG(`$0($*)')
 #ifdef IS_UNICODE
 	pushdef(`NSIZE', ifelse(
-			`$4', `strlen', `UNI_STRLEN (SRC(`$2')) + 1',
-			`$4', `len',    `SRC(`$3') + 1',
-			`',   `',       `SRC(`$3')',
+			`$4', `strlen', `strlen(src->$2) + 1',
+			`$4', `len',    `src->$3 + 1',
+			`',   `',       `src->$3',
 			))
 	DONE(`$2')
-	ifelse(`$1', `1', `PROC_STRING_N_EX(`DST(`$2')', `SRC(`$2')', defn(`NSIZE'), `$2', `zstr_uchar')
+	ifelse(`$1', `1', `PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `UChar')
 	', `
-		if (ifelse(`$1', `', `UG(unicode)', `SRC(`$1') == IS_UNICODE')) {
-			PROC_STRING_N_EX(`DST(`$2')', `SRC(`$2')', defn(`NSIZE'), `$2', `zstr_uchar')
+		if (ifelse(`$1', `', `UG(unicode)', `src->$1')) {
+			PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `UChar')
 		}
 		else {
-			PROC_STRING_N_EX(`DST(`$2')', `SRC(`$2')', defn(`NSIZE'), `$2', `zstr_char')
+			PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `char')
 		}
 	')
 #else
 	DONE(`$2')
-	PROC_STRING_N_EX(`DST(`$2')', `SRC(`$2')', NSIZE, `$2', `zstr_char')
+	PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `char')
 #endif
 	popdef(`NSIZE')
 ')
-dnl }}}
-define(`PROC_ZSTRING_L', `DBG(`$0($*)') PROC_ZSTRING_N(`$1', `$2', `$3', `len')')
-define(`PROC_ZSTRING', `DBG(`$0($*)') PROC_ZSTRING_N(`$1', `$2', , `strlen')')
+// }}}
+define(`PROC_USTRING_L', `DBG(`$0($*)') PROC_USTRING_N(`$1', `$2', `$3', `len')')
+define(`PROC_USTRING', `DBG(`$0($*)') PROC_USTRING_N(`$1', `$2', , `strlen')')
Index: /trunk/processor/hashtable.m4
===================================================================
--- /trunk/processor/hashtable.m4	(revision 1201)
+++ /trunk/processor/hashtable.m4	(revision 1)
@@ -1,3 +1,3 @@
-dnl DEF_HASH_TABLE_FUNC(1:name, 2:datatype [, 3:dataname] [, 4:check_function])
+dnl DEF_HASH_TABLE_FUNC(1:name, 2:datatype [, 3:dataname])
 define(`DEF_HASH_TABLE_FUNC', `
 	DEF_STRUCT_P_FUNC(`HashTable', `$1', `
@@ -5,5 +5,5 @@
 		dnl {{{ dasm
 		IFDASM(`
-			const Bucket *srcBucket;
+			Bucket *b;
 			zval *zv;
 			int bufsize = 2;
@@ -11,7 +11,4 @@
 			int keysize;
 
-#if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
-			DONE(canary)
-#endif
 			DONE(nTableSize)
 			DONE(nTableMask)
@@ -34,9 +31,9 @@
 
 			DISABLECHECK(`
-			for (srcBucket = src->pListHead; srcBucket != NULL; srcBucket = srcBucket->pListNext) {
+			for (b = src->pListHead; b != NULL; b = b->pListNext) {
 				ALLOC_INIT_ZVAL(zv);
 				array_init(zv);
-				FUNC_NAME (dasm, zv, (($2*)srcBucket->pData) TSRMLS_CC);
-				keysize = BUCKET_KEY_SIZE(srcBucket) + 2;
+				FUNC_NAME (zv, (($2*)b->pData) TSRMLS_CC);
+				keysize = BUCKET_KEY_SIZE(b) + 2;
 				if (keysize > bufsize) {
 					do {
@@ -45,9 +42,9 @@
 					buf = erealloc(buf, bufsize);
 				}
-				memcpy(buf, BUCKET_KEY_S(srcBucket), keysize);
+				memcpy(buf, BUCKET_KEY(b), keysize);
 				buf[keysize - 2] = buf[keysize - 1] = ""[0];
-				keysize = srcBucket->nKeyLength;
+				keysize = b->nKeyLength;
 #ifdef IS_UNICODE
-				if (BUCKET_KEY_TYPE(srcBucket) == IS_UNICODE) {
+				if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
 					if (buf[0] == ""[0] && buf[1] == ""[0]) {
 						keysize ++;
@@ -60,88 +57,52 @@
 					}
 				}
-				add_u_assoc_zval_ex(dst, BUCKET_KEY_TYPE(srcBucket), ZSTR(buf), keysize, zv);
+				add_u_assoc_zval_ex(dst, BUCKET_KEY_TYPE(b), buf, keysize, zv);
 			}
 			')
 
 			efree(buf);
+			return; /* no check size */
 		', `
 		dnl }}}
-		Bucket *srcBucket;
-		Bucket *pnew = NULL, *prev = NULL;
+		Bucket *b, *pnew = NULL, *prev = NULL;
 		zend_bool first = 1;
 		dnl only used for copy
 		IFCOPY(`uint n;')
-		IFCALCCOPY(`size_t bucketsize;')
+		IFCALCCOPY(`int bucketsize;')
 
-#if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
-		IFASM(`dst->canary = zend_hash_canary; DONE(canary)', `
-		dnl elseif
-			IFRESTORE(`dst->canary = zend_hash_canary; DONE(canary)', `
-				dnl else
-				PROCESS(unsigned int, canary)
-			')
-		')
-#endif
-		PROCESS(uint, nTableSize)
-		PROCESS(uint, nTableMask)
-		PROCESS(uint, nNumOfElements)
-		PROCESS(ulong, nNextFreeElement)
+		DISPATCH(uint, nTableSize)
+		DISPATCH(uint, nTableMask)
+		DISPATCH(uint, nNumOfElements)
+		DISPATCH(ulong, nNextFreeElement)
 		IFCOPY(`dst->pInternalPointer = NULL;	/* Used for element traversal */') DONE(pInternalPointer)
 		IFCOPY(`dst->pListHead = NULL;') DONE(pListHead)
-#ifdef ZEND_ENGINE_2_4
-		if (src->nTableMask) {
-#endif
 		CALLOC(dst->arBuckets, Bucket*, src->nTableSize)
 		DONE(arBuckets)
 		DISABLECHECK(`
-		for (srcBucket = src->pListHead; srcBucket != NULL; srcBucket = srcBucket->pListNext) {
-			ifelse($4, `', `', `
-				pushdef(`BUCKET', `srcBucket')
-				if ($4 == ZEND_HASH_APPLY_REMOVE) {
-					IFCOPY(`dst->nNumOfElements --;')
-					continue;
-				}
-				popdef(`BUCKET')
-			')
 
-			IFCALCCOPY(`bucketsize = BUCKET_SIZE(srcBucket);')
+		for (b = src->pListHead; b != NULL; b = b->pListNext) {
+			IFCALCCOPY(`bucketsize = BUCKET_SIZE(b);')
 			ALLOC(pnew, char, bucketsize, , Bucket)
+			IFCOPY(`memcpy(pnew, b, bucketsize);')
 			IFCOPY(`
-#ifdef ZEND_ENGINE_2_4
-			memcpy(pnew, srcBucket, BUCKET_HEAD_SIZE(Bucket));
-			if (BUCKET_KEY_SIZE(srcBucket)) {
-				memcpy((char *) (pnew + 1), srcBucket->arKey, BUCKET_KEY_SIZE(srcBucket));
-				pnew->arKey = (const char *) (pnew + 1);
-			}
-			else {
-				pnew->arKey = NULL;
-			}
-#else
-			memcpy(pnew, srcBucket, bucketsize);
-#endif
-			')
-			IFCOPY(`
-				n = srcBucket->h & src->nTableMask;
+				n = b->h & src->nTableMask;
 				/* pnew into hash node chain */
 				pnew->pLast = NULL;
-				pnew->pNext = dst->arBuckets[n];
-				if (pnew->pNext) {
+				if (dst->arBuckets[n]) {
+					pnew->pNext = dst->arBuckets[n];
 					pnew->pNext->pLast = pnew;
 				}
+				else {
+					pnew->pNext = NULL;
+				}
 				dst->arBuckets[n] = pnew;
-			')
-			IFDPRINT(`
-				INDENT()
-				fprintf(stderr, "$2:\"");
-				xc_dprint_str_len(BUCKET_KEY_S(srcBucket), BUCKET_KEY_SIZE(srcBucket));
-				fprintf(stderr, "\" %d:h=%lu ", BUCKET_KEY_SIZE(srcBucket), srcBucket->h);
 			')
 			if (sizeof(void *) == sizeof($2)) {
 				IFCOPY(`pnew->pData = &pnew->pDataPtr;')
 				dnl no alloc
-				STRUCT_P_EX(`$2', pnew->pData, (($2*)srcBucket->pData), `', `$3', ` ')
+				STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `$3', ` ')
 			}
 			else {
-				STRUCT_P_EX(`$2', pnew->pData, (($2*)srcBucket->pData), `', `$3')
+				STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `$3')
 				IFCOPY(`pnew->pDataPtr = NULL;')
 			}
@@ -163,20 +124,14 @@
 		}
 		')
-#ifdef ZEND_ENGINE_2_4
-	}
-	else { /* if (src->nTableMask) */
-		DONE(arBuckets)
-	}
-#endif
 		IFCOPY(`dst->pListTail = pnew;') DONE(pListTail)
 		IFCOPY(`dst->pDestructor = src->pDestructor;') DONE(pDestructor)
-		PROCESS(zend_bool, persistent)
+		DISPATCH(zend_bool, persistent)
 #ifdef IS_UNICODE
-		PROCESS(zend_bool, unicode)
+		DISPATCH(zend_bool, unicode)
 #endif
-		PROCESS(unsigned char, nApplyCount)
-		PROCESS(zend_bool, bApplyProtection)
+		DISPATCH(unsigned char, nApplyCount)
+		DISPATCH(zend_bool, bApplyProtection)
 #if ZEND_DEBUG
-		PROCESS(int, inconsistent)
+		DISPATCH(int, inconsistent)
 #endif
 		')dnl IFDASM
Index: /trunk/processor/dispatch.m4
===================================================================
--- /trunk/processor/dispatch.m4	(revision 1)
+++ /trunk/processor/dispatch.m4	(revision 1)
@@ -0,0 +1,27 @@
+dnl DISPATCH(1:type, 2:elm)
+define(`DISPATCH', `
+	DBG(`$0($*)')
+	ifelse(
+		`$1', `zend_bool',        `PROC_INT(`$2', `u',  `$1')'
+	, `$1', `zend_uchar',       `PROC_INT(`$2', `u',  `$1')'
+	, `$1', `char',             `PROC_INT(`$2', `d',  `$1')'
+	, `$1', `int32_t',          `PROC_INT(`$2', `d',  `$1')'
+	, `$1', `unsigned char',    `PROC_INT(`$2', `u',  `$1')'
+	, `$1', `zend_uint',        `PROC_INT(`$2', `u',  `$1')'
+	, `$1', `uint',             `PROC_INT(`$2', `u',  `$1')'
+	, `$1', `unsigned int',     `PROC_INT(`$2', `u',  `$1')'
+	, `$1', `zend_ulong',       `PROC_INT(`$2', `lu', `$1')'
+	, `$1', `ulong',            `PROC_INT(`$2', `lu', `$1')'
+	, `$1', `size_t',           `PROC_INT(`$2', `u', `$1')'
+	, `$1', `long',             `PROC_INT(`$2', `ld', `$1')'
+	, `$1', `time_t',           `PROC_INT(`$2', `ld', `$1')'
+	, `$1', `zend_ushort',      `PROC_INT(`$2', `hu', `$1')'
+	, `$1', `int',              `PROC_INT(`$2', `d',  `$1')'
+	, `$1', `double',           `PROC_INT(`$2', `f',  `$1')'
+	, `$1', `opcode_handler_t', `/* is copying enough? */COPY(`$2')'
+	, `$1', `zval_data_type',   `PROC_INT(`$2', `u',  `$1')'
+	, `$1', `xc_entry_type_t',  `PROC_INT(`$2', `d',  `$1')'
+	, `$1', `xc_hash_value_t',  `PROC_INT(`$2', `lu', `$1')'
+	, `', `', `m4_errprint(`Unknown type "$1"')'
+	)
+')
Index: /trunk/processor/processor.m4
===================================================================
--- /trunk/processor/processor.m4	(revision 1240)
+++ /trunk/processor/processor.m4	(revision 1)
@@ -3,13 +3,8 @@
 DECL_STRUCT_P_FUNC(`zval')
 DECL_STRUCT_P_FUNC(`zval_ptr')
-DECL_STRUCT_P_FUNC(`zval_ptr_nullable')
 DECL_STRUCT_P_FUNC(`zend_op_array')
 DECL_STRUCT_P_FUNC(`zend_class_entry')
-#ifdef HAVE_XCACHE_CONSTANT
-DECL_STRUCT_P_FUNC(`zend_constant')
-#endif
 DECL_STRUCT_P_FUNC(`zend_function')
-DECL_STRUCT_P_FUNC(`xc_entry_var_t')
-DECL_STRUCT_P_FUNC(`xc_entry_php_t')
+DECL_STRUCT_P_FUNC(`xc_entry_t')
 #ifdef ZEND_ENGINE_2
 DECL_STRUCT_P_FUNC(`zend_property_info')
@@ -17,13 +12,15 @@
 /* }}} */
 dnl ====================================================
+dnl {{{ zend_compiled_variable
 #ifdef IS_CV
-DEF_STRUCT_P_FUNC(`zend_compiled_variable', , `dnl {{{
-	PROCESS(int, name_len)
-	PROC_ZSTRING_L(, name, name_len)
-	PROCESS(ulong, hash_value)
-')
-dnl }}}
-#endif
-DEF_STRUCT_P_FUNC(`zend_uint', , `dnl {{{
+DEF_STRUCT_P_FUNC(`zend_compiled_variable', , `
+	DISPATCH(int, name_len)
+	PROC_USTRING_L(, name, name_len)
+	DISPATCH(ulong, hash_value)
+')
+#endif
+dnl }}}
+dnl {{{ zend_uint
+DEF_STRUCT_P_FUNC(`zend_uint', , `
 	IFCOPY(`dst[0] = src[0];')
 	IFDPRINT(`
@@ -34,6 +31,7 @@
 ')
 dnl }}}
+dnl {{{ int
 #ifndef ZEND_ENGINE_2
-DEF_STRUCT_P_FUNC(`int', , `dnl {{{
+DEF_STRUCT_P_FUNC(`int', , `
 	IFCOPY(`*dst = *src;')
 	IFDPRINT(`
@@ -43,24 +41,19 @@
 	DONE_SIZE(sizeof(src[0]))
 ')
-dnl }}}
-#endif
-#ifdef ZEND_ENGINE_2
-DEF_STRUCT_P_FUNC(`zend_try_catch_element', , `dnl {{{
-	PROCESS(zend_uint, try_op)
-	PROCESS(zend_uint, catch_op)
-#ifdef ZEND_ENGINE_2_5
-	PROCESS(zend_uint, finally_op)
-	PROCESS(zend_uint, finally_end)
-#endif
-')
-dnl }}}
-#endif
-DEF_STRUCT_P_FUNC(`zend_brk_cont_element', , `dnl {{{
-#ifdef ZEND_ENGINE_2_2
-	PROCESS(int, start)
-#endif
-	PROCESS(int, cont)
-	PROCESS(int, brk)
-	PROCESS(int, parent)
+#endif
+dnl }}}
+dnl {{{ zend_try_catch_element
+#ifdef ZEND_ENGINE_2
+DEF_STRUCT_P_FUNC(`zend_try_catch_element', , `
+	DISPATCH(zend_uint, try_op)
+	DISPATCH(zend_uint, catch_op)
+')
+#endif /* ifdef ZEND_ENGINE_2 */
+dnl }}}
+dnl {{{ zend_brk_cont_element
+DEF_STRUCT_P_FUNC(`zend_brk_cont_element', , `
+	DISPATCH(int, cont)
+	DISPATCH(int, brk)
+	DISPATCH(int, parent)
 ')
 dnl }}}
@@ -75,15 +68,11 @@
 		*dst = *src;
 		zval_copy_ctor(dst);
-		Z_SET_REFCOUNT(*dst, 1);
+		ZVAL_REFCOUNT(dst) = 1;
 		DONE(value)
+		DONE(refcount)
 		DONE(type)
-#ifdef ZEND_ENGINE_2_3
-		DONE(is_ref__gc)
-		DONE(refcount__gc)
-#else
 		DONE(is_ref)
-		DONE(refcount)
-#endif
 	} while(0);
+	return;
 	', `
 		dnl IFDASM else
@@ -91,12 +80,12 @@
 dnl {{{ zvalue_value
 		DISABLECHECK(`
-		switch ((Z_TYPE_P(src) & IS_CONSTANT_TYPE_MASK)) {
+		switch (src->type & ~IS_CONSTANT_INDEX) {
 			case IS_LONG:
 			case IS_RESOURCE:
 			case IS_BOOL:
-				PROCESS(long, value.lval)
+				DISPATCH(long, value.lval)
 				break;
 			case IS_DOUBLE:
-				PROCESS(double, value.dval)
+				DISPATCH(double, value.dval)
 				break;
 			case IS_NULL:
@@ -114,5 +103,5 @@
 			case FLAG_IS_BC:
 #endif
-				PROCESS(int, value.str.len)
+				DISPATCH(int, value.str.len)
 				PROC_STRING_L(value.str.val, value.str.len)
 				break;
@@ -120,6 +109,6 @@
 			case IS_UNICODE:
 proc_unicode:
-				PROCESS(int32_t, value.uni.len)
-				PROC_ZSTRING_L(1, value.uni.val, value.uni.len)
+				DISPATCH(int32_t, value.ustr.len)
+				PROC_USTRING_L(1, value.ustr.val, value.ustr.len)
 				break;
 #endif
@@ -145,18 +134,7 @@
 dnl }}}
 		DONE(value)
-		PROCESS(xc_zval_type_t, type)
-#ifdef ZEND_ENGINE_2_3
-		PROCESS(zend_uchar, is_ref__gc)
-#else
-		PROCESS(zend_uchar, is_ref)
-#endif
-
-#ifdef ZEND_ENGINE_2_3
-		PROCESS(zend_uint, refcount__gc)
-#elif defined(ZEND_ENGINE_2)
-		PROCESS(zend_uint, refcount)
-#else
-		PROCESS(zend_ushort, refcount)
-#endif
+		DISPATCH(zval_data_type, type)
+		DISPATCH(zend_uchar, is_ref)
+		DISPATCH(zend_ushort, refcount)
 	')dnl IFDASM
 ')
@@ -165,5 +143,5 @@
 	IFDASM(`
 		pushdefFUNC_NAME(`zval')
-		FUNC_NAME (dasm, dst, src[0] TSRMLS_CC);
+		FUNC_NAME (dst, src[0] TSRMLS_CC);
 		popdef(`FUNC_NAME')
 	', `
@@ -172,11 +150,10 @@
 				if (processor->reference) {
 					zval_ptr *ppzv;
-					if (zend_hash_find(&processor->zvalptrs, (char *) &src[0], sizeof(src[0]), (void **) &ppzv) == SUCCESS) {
+					if (zend_hash_find(&processor->zvalptrs, (char *)src[0], sizeof(src[0]), (void**)&ppzv) == SUCCESS) {
 						IFCOPY(`
 							dst[0] = *ppzv;
 							/* *dst is updated */
-							dnl fprintf(stderr, "*dst is set to %p, PROCESSOR_TYPE is_shm %d\n", dst[0], xc_is_shm(dst[0]));
+							dnl fprintf(stderr, "*dst is set to %p\n", dst[0]);
 						')
-						IFCALCSTORE(`processor->have_references = 1;')
 						IFSTORE(`assert(xc_is_shm(dst[0]));')
 						IFRESTORE(`assert(!xc_is_shm(dst[0]));')
@@ -194,7 +171,6 @@
 					', `
 						zval_ptr pzv = dst[0];
-						FIXPOINTER_EX(zval, pzv)
 					')
-					if (zend_hash_add(&processor->zvalptrs, (char *) &src[0], sizeof(src[0]), (void *) &pzv, sizeof(pzv), NULL) == SUCCESS) {
+					if (zend_hash_add(&processor->zvalptrs, (char *)src[0], sizeof(src[0]), (void*)&pzv, sizeof(pzv), NULL) == SUCCESS) {
 						/* first add, go on */
 						dnl fprintf(stderr, "mark[%p] = %p\n", src[0], pzv);
@@ -208,7 +184,5 @@
 				dnl fprintf(stderr, "copy from %p to %p\n", src[0], dst[0]);
 			')
-			IFDPRINT(`INDENT()`'fprintf(stderr, "[%p] ", src[0]);')
-			STRUCT_P_EX(zval, dst[0], src[0], `[0]', `', ` ')
-			FIXPOINTER_EX(zval, dst[0])
+			STRUCT_P_EX(zval, dst[0], src[0], `', ` ')
 		} while (0);
 	')
@@ -216,46 +190,19 @@
 ')
 dnl }}}
-DEF_STRUCT_P_FUNC(`zval_ptr_nullable', , `dnl {{{
-	if (src[0]) {
-		STRUCT_P_EX(zval_ptr, dst, src, `', `', ` ')
-	}
-	else {
-		IFCOPY(`COPYNULL_EX(src[0], src)')
-	}
-	DONE_SIZE(sizeof(zval_ptr_nullable))
-')
-dnl }}}
-#ifdef ZEND_ENGINE_2
-DEF_STRUCT_P_FUNC(`zend_arg_info', , `dnl {{{
-	PROCESS(zend_uint, name_len)
-	PROC_ZSTRING_L(, name, name_len)
-	PROCESS(zend_uint, class_name_len)
-	PROC_ZSTRING_L(, class_name, class_name_len)
-#ifdef ZEND_ENGINE_2_4
-	PROCESS(zend_uchar, type_hint)
-#else
-	PROCESS(zend_bool, array_type_hint)
-#endif
-	PROCESS(zend_bool, allow_null)
-	PROCESS(zend_bool, pass_by_reference)
-#ifndef ZEND_ENGINE_2_4
-	PROCESS(zend_bool, return_reference)
-	PROCESS(int, required_num_args)
-#endif
-')
-dnl }}}
-#endif
-#ifdef HAVE_XCACHE_CONSTANT
-DEF_STRUCT_P_FUNC(`zend_constant', , `dnl {{{
-	STRUCT(zval, value)
-	PROCESS(int, flags)
-	PROCESS(uint, name_len)
-	pushdef(`estrndup', `zend_strndup')
-	PROC_ZSTRING_N(, name, name_len)
-	popdef(`estrndup')
-	PROCESS(int, module_number)
-')
-dnl }}}
-#endif
+dnl {{{ zend_arg_info
+#ifdef ZEND_ENGINE_2
+DEF_STRUCT_P_FUNC(`zend_arg_info', , `
+	DISPATCH(zend_uint, name_len)
+	PROC_USTRING_L(, name, name_len)
+	DISPATCH(zend_uint, class_name_len)
+	PROC_USTRING_L(, class_name, class_name_len)
+	DISPATCH(zend_bool, array_type_hint)
+	DISPATCH(zend_bool, allow_null)
+	DISPATCH(zend_bool, pass_by_reference)
+	DISPATCH(zend_bool, return_reference)
+	DISPATCH(int, required_num_args)
+')
+#endif
+dnl }}}
 DEF_STRUCT_P_FUNC(`zend_function', , `dnl {{{
 	DISABLECHECK(`
@@ -279,86 +226,24 @@
 ')
 dnl }}}
-#ifdef ZEND_ENGINE_2
-DEF_STRUCT_P_FUNC(`zend_property_info', , `dnl {{{
-	PROCESS(zend_uint, flags)
-	PROCESS(int, name_length)
-	PROC_ZSTRING_L(, name, name_length)
-	PROCESS(ulong, h)
-#ifdef ZEND_ENGINE_2_4
-	PROCESS(int, offset)
-#endif
-#ifdef ZEND_ENGINE_2_1
-	PROCESS(int, doc_comment_len)
-	PROC_ZSTRING_L(, doc_comment, doc_comment_len)
-#endif
-	dnl isnt in php6 yet
-#if defined(ZEND_ENGINE_2_2)
-	PROC_CLASS_ENTRY_P(ce)
-#endif
-')
-dnl }}}
-#endif
-#ifdef ZEND_ENGINE_2_4
-DEF_STRUCT_P_FUNC(`zend_trait_method_reference', , `dnl {{{
-	PROCESS(unsigned int, mname_len)
-	PROC_STRING_L(method_name, mname_len)
-	COPYNULL(ce)
-	PROCESS(unsigned int, cname_len)
-	PROC_STRING_L(class_name, cname_len)
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`zend_trait_alias', , `dnl {{{
-	STRUCT_P(zend_trait_method_reference, trait_method)
-	PROCESS(unsigned int, alias_len)
-	PROC_STRING_L(alias, alias_len)
-	PROCESS(zend_uint, modifiers)
-#ifndef ZEND_ENGINE_2_5
-	COPYNULL(function)
-#endif
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`zend_trait_precedence', , `dnl {{{
-	STRUCT_P(zend_trait_method_reference, trait_method)
-	PROCESS_ARRAY(, xc_ztstring, exclude_from_classes, zend_class_entry*)
-#ifndef ZEND_ENGINE_2_5
-	COPYNULL(function)
-#endif
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`zend_trait_alias_ptr', , `dnl {{{
-	IFDASM(`
-		pushdefFUNC_NAME(`zend_trait_alias')
-		FUNC_NAME (dasm, dst, src[0] TSRMLS_CC);
-		popdef(`FUNC_NAME')
-	', `
-		ALLOC(dst[0], zend_trait_alias)
-		STRUCT_P_EX(zend_trait_alias, dst[0], src[0], `[0]', `', ` ')
-		FIXPOINTER_EX(zend_trait_alias, dst[0])
-	')
-	DONE_SIZE(sizeof(zend_trait_alias))
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`zend_trait_precedence_ptr', , `dnl {{{
-	IFDASM(`
-		pushdefFUNC_NAME(`zend_trait_precedence')
-		FUNC_NAME (dasm, dst, src[0] TSRMLS_CC);
-		popdef(`FUNC_NAME')
-	', `
-		ALLOC(dst[0], zend_trait_precedence)
-		STRUCT_P_EX(zend_trait_precedence, dst[0], src[0], `[0]', `', ` ')
-		FIXPOINTER_EX(zend_trait_precedence, dst[0])
-	')
-	DONE_SIZE(sizeof(zend_trait_precedence))
-')
-dnl }}}
-#endif
+dnl {{{ zend_property_info
+#ifdef ZEND_ENGINE_2
+DEF_STRUCT_P_FUNC(`zend_property_info', , `
+	DISPATCH(zend_uint, flags)
+	DISPATCH(int, name_length)
+	PROC_USTRING_L(, name, name_length)
+	DISPATCH(ulong, h)
+	DISPATCH(int, doc_comment_len)
+	PROC_USTRING_L(, doc_comment, doc_comment_len)
+')
+#endif
+dnl }}}
 DEF_STRUCT_P_FUNC(`zend_class_entry', , `dnl {{{
-	IFCALCCOPY(`
+	IFCOPY(`
 		processor->active_class_entry_src = src;
-		IFCOPY(`processor->active_class_entry_dst = dst;')
-	')
-	PROCESS(char, type)
-	PROCESS(zend_uint, name_length)
-	PROC_ZSTRING_L(, name, name_length)
+		processor->active_class_entry_dst = dst;
+	')
+	DISPATCH(char, type)
+	DISPATCH(zend_uint, name_length)
+	PROC_USTRING_L(, name, name_length)
 	IFRESTORE(`
 #ifndef ZEND_ENGINE_2
@@ -372,88 +257,64 @@
 	')
 #ifdef ZEND_ENGINE_2
-	PROCESS(int, refcount)
+	DISPATCH(int, refcount)
 #else
 	STRUCT_P(int, refcount)
 #endif
-#ifndef ZEND_ENGINE_2_4
-	PROCESS(zend_bool, constants_updated)
-#endif
-#ifdef ZEND_ENGINE_2
-	PROCESS(zend_uint, ce_flags)
-#endif
-
-#ifdef ZEND_ENGINE_2
-	STRUCT(HashTable, properties_info, HashTable_zend_property_info)
-#endif
-
-#ifdef ZEND_ENGINE_2_4
-	STRUCT_ARRAY(int, default_properties_count, zval_ptr_nullable, default_properties_table)
-	PROCESS(int, default_properties_count)
-	STRUCT_ARRAY(int, default_static_members_count, zval_ptr_nullable, default_static_members_table)
-	PROCESS(int, default_static_members_count)
-	IFCOPY(`dst->static_members_table = dst->default_static_members_table;')
-	DONE(static_members_table)
-#else
+	DISPATCH(zend_bool, constants_updated)
+#ifdef ZEND_ENGINE_2
+	DISPATCH(zend_uint, ce_flags)
+#endif
+
+	STRUCT(HashTable, default_properties, HashTable_zval_ptr)
 	IFCOPY(`dst->builtin_functions = src->builtin_functions;')
 	DONE(builtin_functions)
-	STRUCT(HashTable, default_properties, HashTable_zval_ptr)
+#ifdef ZEND_ENGINE_2
+	STRUCT(HashTable, properties_info, HashTable_zend_property_info)
 #	ifdef ZEND_ENGINE_2_1
 	STRUCT(HashTable, default_static_members, HashTable_zval_ptr)
 	IFCOPY(`dst->static_members = &dst->default_static_members;')
 	DONE(static_members)
-#	elif defined(ZEND_ENGINE_2)
+#	else
 	STRUCT_P(HashTable, static_members, HashTable_zval_ptr)
 #	endif
-#endif /* ZEND_ENGINE_2_4 */
-
-#ifdef ZEND_ENGINE_2
 	STRUCT(HashTable, constants_table, HashTable_zval_ptr)
 
-#ifdef ZEND_ENGINE_2_2
 	dnl runtime binding: ADD_INTERFACE will deal with it
-	COPYNULL(`interfaces')
-	COPYZERO(`num_interfaces')
-
-#	ifdef ZEND_ENGINE_2_4
-	dnl runtime binding: ADD_TRAIT will deal with it
-	COPYNULL(traits)
-	COPYZERO(num_traits)
-	STRUCT_ARRAY(, , zend_trait_alias_ptr, trait_aliases)
-	STRUCT_ARRAY(, , zend_trait_precedence_ptr, trait_precedences)
-#	endif
-#else
 	IFRESTORE(`
 		if (src->num_interfaces) {
 			CALLOC(dst->interfaces, zend_class_entry*, src->num_interfaces)
-			DONE(`interfaces')
 		}
 		else {
-			COPYNULL(`interfaces')
-		}
-	', `
-		DONE(`interfaces')
-	')
-	PROCESS(zend_uint, num_interfaces)
-#endif
-
-#	ifdef ZEND_ENGINE_2_4
-	DISABLECHECK(`
-	IFRESTORE(`dst->info.user.filename = processor->entry_php_src->filepath;', `PROC_STRING(info.user.filename)')
-	PROCESS(zend_uint, info.user.line_start)
-	PROCESS(zend_uint, info.user.line_end)
-	PROCESS(zend_uint, info.user.doc_comment_len)
-	PROC_ZSTRING_L(, info.user.doc_comment, info.user.doc_comment_len)
-	')
-	DONE(info)
-#	else
-	IFRESTORE(`dst->filename = processor->entry_php_src->filepath;DONE(filename)', `PROC_STRING(filename)')
-	PROCESS(zend_uint, line_start)
-	PROCESS(zend_uint, line_end)
-#		ifdef ZEND_ENGINE_2_1
-	PROCESS(zend_uint, doc_comment_len)
-	PROC_ZSTRING_L(, doc_comment, doc_comment_len)
-#		endif
-#	endif
-
+			COPYNULL_EX(dst->interfaces)
+		}
+	')
+	IFDASM(`
+		if (src->num_interfaces) {
+			/*
+			zval *arr;
+			ALLOC_INIT_ZVAL(arr);
+			array_init(arr);
+			for (i = 0; i < src->num_interfaces; i ++) {
+				zval *zv;
+				ALLOC_INIT_ZVAL(zv);
+				ZVAL_STRING(src->num_interfaces);
+			}
+			add_assoc_zval_ex(dst, ZEND_STRS("interfaces"), arr);
+			*/
+		}
+		else {
+			COPYNULL_EX(dst->interfaces)
+		}
+	')
+	DONE(`interfaces')
+	DISPATCH(zend_uint, num_interfaces)
+
+	IFRESTORE(`COPY(filename)', `PROC_STRING(filename)')
+	DISPATCH(zend_uint, line_start)
+	DISPATCH(zend_uint, line_end)
+#ifdef ZEND_ENGINE_2_1
+	DISPATCH(zend_uint, doc_comment_len)
+	PROC_USTRING_L(, doc_comment, doc_comment_len)
+#endif
 	/* # NOT DONE */
 	COPY(serialize_func)
@@ -463,7 +324,4 @@
 	COPY(get_iterator)
 	COPY(interface_gets_implemented)
-#	ifdef ZEND_ENGINE_2_3
-	COPY(get_static_method)
-#	endif
 	COPY(serialize)
 	COPY(unserialize)
@@ -475,107 +333,37 @@
 	COPY(__set)
 /* should be >5.1 */
-#	ifdef ZEND_ENGINE_2_1
+#ifdef ZEND_ENGINE_2_1
 	COPY(__unset)
 	COPY(__isset)
-#	 if defined(ZEND_ENGINE_2_2) || PHP_MAJOR_VERSION >= 6
+# if PHP_MAJOR_VERSION >= 6
 	COPY(__tostring)
-#	 endif
-#	endif
+# endif
+#endif
 	COPY(__call)
-#	ifdef ZEND_CALLSTATIC_FUNC_NAME
-	COPY(__callstatic)
-#	endif
-#	ifndef ZEND_ENGINE_2_4
+#ifdef IS_UNICODE
+	SETNULL(u_twin)
+#endif
 	/* # NOT DONE */
 	COPY(module)
-#	endif
-#else /* ZEND_ENGINE_2 */
+#else
 	COPY(handle_function_call)
 	COPY(handle_property_get)
 	COPY(handle_property_set)
 #endif
-	dnl must do after SETNULL(constructor) and dst->parent
+	dnl must after SETNULL(constructor)
 	STRUCT(HashTable, function_table, HashTable_zend_function)
-	IFRESTORE(`dst->function_table.pDestructor = ZEND_FUNCTION_DTOR;')
-	IFCALCCOPY(`
-		processor->active_class_entry_src = NULL;
-		IFCOPY(`processor->active_class_entry_dst = NULL;')
-	')
-')
-dnl }}}
-#ifdef ZEND_ENGINE_2_4
-undefine(`UNION_znode_op')
-define(`UNION_znode_op', `dnl {{{
-#ifndef NDEBUG
-	switch ((src->$1_type ifelse($1, `result', & ~EXT_TYPE_UNUSED))) {
-	case IS_CONST:
-	case IS_VAR:
-	case IS_CV:
-	case IS_TMP_VAR:
-	case IS_UNUSED:
-		break;
-
-	default:
-		assert(0);
-	}
-#endif
-
-	dnl dirty dispatch
-	DISABLECHECK(`
-	switch ((src->$1_type ifelse($1, `result', & ~EXT_TYPE_UNUSED))) {
-		case IS_CONST:
-			ifelse($1, `result', `
-				PROCESS(zend_uint, $1.constant)
-			', `
-				IFDASM(`{
-					zval *zv;
-					ALLOC_INIT_ZVAL(zv);
-					*zv = dasm->active_op_array_src->literals[src->$1.constant].constant;
-					zval_copy_ctor(zv);
-					add_assoc_zval_ex(dst, ZEND_STRS("$1.constant"), zv);
-				}
-				', `
-					IFCOPY(`
-						dst->$1 = src->$1;
-					', `
-						PROCESS(zend_uint, $1.constant)
-					')
-				')
-			')
-			break;
-		IFCOPY(`
-			IFNOTMEMCPY(`
-				default:
-					$1 = $2;
-			')
-		', `
-		case IS_VAR:
-		case IS_TMP_VAR:
-		case IS_CV:
-			PROCESS(zend_uint, $1.var)
-			break;
-		case IS_UNUSED:
-			IFDASM(`PROCESS(zend_uint, $1.var)')
-			PROCESS(zend_uint, $1.opline_num)
-			break;
-		')
-	}
-	')
-	DONE($1)
-')
-dnl }}}
-#else
+	IFRESTORE(`dst->function_table.pDestructor = (dtor_func_t) destroy_zend_function;')
+')
+dnl }}}
 DEF_STRUCT_P_FUNC(`znode', , `dnl {{{
-	PROCESS(xc_op_type, op_type)
-
-#ifdef IS_CV
-#	define XCACHE_IS_CV IS_CV
-#else
-/* compatible with zend optimizer */
-#	define XCACHE_IS_CV 16
-#endif
+	DISPATCH(int, op_type)
+
 	assert(src->op_type == IS_CONST ||
 		src->op_type == IS_VAR ||
-		src->op_type == XCACHE_IS_CV ||
+#ifdef IS_CV
+		src->op_type == IS_CV ||
+#else
+		src->op_type == 16 || /* zend optimizer */
+#endif
 		src->op_type == IS_TMP_VAR ||
 		src->op_type == IS_UNUSED);
@@ -594,15 +382,19 @@
 		case IS_VAR:
 		case IS_TMP_VAR:
-		case XCACHE_IS_CV:
-			PROCESS(zend_uint, u.var)
-			PROCESS(zend_uint, u.EA.type)
+#ifdef IS_CV
+		case IS_CV:
+#else
+		case 16:
+#endif
+			DISPATCH(zend_uint, u.var)
+			DISPATCH(zend_uint, u.EA.type)
 			break;
 		case IS_UNUSED:
-			IFDASM(`PROCESS(zend_uint, u.var)')
-			PROCESS(zend_uint, u.opline_num)
+			IFDASM(`DISPATCH(zend_uint, u.var)')
+			DISPATCH(zend_uint, u.opline_num)
 #ifndef ZEND_ENGINE_2
-			PROCESS(zend_uint, u.fetch_type)
-#endif
-			PROCESS(zend_uint, u.EA.type)
+			DISPATCH(zend_uint, u.fetch_type)
+#endif
+			DISPATCH(zend_uint, u.EA.type)
 			break;
 		')
@@ -610,64 +402,18 @@
 	')
 	DONE(u)
-#if 0
-	DONE(EA)
-#endif
-#undef XCACHE_IS_CV
-')
-dnl }}}
-#endif
+')
+dnl }}}
 DEF_STRUCT_P_FUNC(`zend_op', , `dnl {{{
-	PROCESS(xc_opcode, opcode)
-#ifdef ZEND_ENGINE_2_4
-	IFRESTORE(`', `
-	switch (src->opcode) {
-	case ZEND_BIND_TRAITS:
-		((zend_op *) src)->op2_type = IS_UNUSED;
-		break;
-	}
-	')
-	UNION_znode_op(result)
-	UNION_znode_op(op1)
-	UNION_znode_op(op2)
-#else
+	DISPATCH(zend_uchar, opcode)
 	STRUCT(znode, result)
 	STRUCT(znode, op1)
 	STRUCT(znode, op2)
-#endif
-	PROCESS(ulong, extended_value)
-	PROCESS(uint, lineno)
+	DISPATCH(ulong, extended_value)
+	DISPATCH(uint, lineno)
 #ifdef ZEND_ENGINE_2_1
-#ifdef ZEND_ENGINE_2_4
-	PROCESS(zend_uchar, op1_type)
-	PROCESS(zend_uchar, op2_type)
-	PROCESS(zend_uchar, result_type)
-#endif
 	IFCOPY(`
-		assert(processor->active_op_array_src);
-		assert(processor->active_op_array_dst);
-#ifdef ZEND_ENGINE_2_4
-		pushdef(`UNION_znode_op_literal', `
-			if (src->$1_type == IS_CONST) {
-				dst->$1.constant = src->$1.literal - processor->active_op_array_src->literals;
-				dst->$1.literal = &processor->active_op_array_dst->literals[dst->$1.constant];
-			}
-		')
-		UNION_znode_op_literal(op1)
-		UNION_znode_op_literal(op2)
-#endif
-		popdef(`UNION_znode_op_literal')
 		switch (src->opcode) {
-#ifdef ZEND_GOTO
-			case ZEND_GOTO:
-#endif
 			case ZEND_JMP:
-#ifdef ZEND_FAST_CALL
-			case ZEND_FAST_CALL:
-#endif
-#ifdef ZEND_ENGINE_2
-				assert(Z_OP(src->op1).jmp_addr >= processor->active_op_array_src->opcodes && Z_OP(src->op1).jmp_addr - processor->active_op_array_src->opcodes < processor->active_op_array_src->last);
-				Z_OP(dst->op1).jmp_addr = processor->active_op_array_dst->opcodes + (Z_OP(src->op1).jmp_addr - processor->active_op_array_src->opcodes);
-				assert(Z_OP(dst->op1).jmp_addr >= processor->active_op_array_dst->opcodes && Z_OP(dst->op1).jmp_addr - processor->active_op_array_dst->opcodes < processor->active_op_array_dst->last);
-#endif
+				dst->op1.u.jmp_addr = processor->active_opcodes_dst + (src->op1.u.jmp_addr - processor->active_opcodes_src);
 				break;
 
@@ -676,15 +422,5 @@
 			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
-#ifdef ZEND_ENGINE_2
-				assert(Z_OP(src->op2).jmp_addr >= processor->active_op_array_src->opcodes && Z_OP(src->op2).jmp_addr - processor->active_op_array_src->opcodes < processor->active_op_array_src->last);
-				Z_OP(dst->op2).jmp_addr = processor->active_op_array_dst->opcodes + (Z_OP(src->op2).jmp_addr - processor->active_op_array_src->opcodes);
-				assert(Z_OP(dst->op2).jmp_addr >= processor->active_op_array_dst->opcodes && Z_OP(dst->op2).jmp_addr - processor->active_op_array_dst->opcodes < processor->active_op_array_dst->last);
-#endif
+				dst->op2.u.jmp_addr = processor->active_opcodes_dst + (src->op2.u.jmp_addr - processor->active_opcodes_src);
 				break;
 
@@ -693,141 +429,27 @@
 		}
 	')
-	PROCESS(opcode_handler_t, handler)
-#endif
-')
-dnl }}}
-#ifdef ZEND_ENGINE_2_4
-DEF_STRUCT_P_FUNC(`zend_literal', , `dnl {{{
-	STRUCT(zval, constant)
-	PROCESS(zend_ulong, hash_value)
-	PROCESS(zend_uint,  cache_slot)
-')
-dnl }}}
-#endif
+	DISPATCH(opcode_handler_t, handler)
+#endif
+')
+dnl }}}
 DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{
-	IFCOPY(`
-		processor->active_op_array_dst = dst;
-		processor->active_op_array_src = src;
-	')
-	IFDASM(`
-		dasm->active_op_array_src = src;
-	')
-	{
 	IFRESTORE(`
-	const xc_op_array_info_t *op_array_info = &processor->active_op_array_infos_src[processor->active_op_array_index++];
-	dnl shadow copy must NOT meet:
-	dnl readonly_protection=on
-	dnl main op_array && have early binding
-#ifdef ZEND_COMPILE_DELAYED_BINDING
-	zend_bool need_early_binding = 0;
-#else
-	zend_bool need_early_binding = processor->php_src->have_early_binding;
-#endif
-	zend_bool shallow_copy = !processor->readonly_protection && !(src == processor->php_src->op_array && need_early_binding);
-	if (shallow_copy) {
-		zend_bool gc_arg_info = 0;
-		zend_bool gc_opcodes  = 0;
-#ifdef ZEND_ENGINE_2_4
-		zend_bool gc_literals = 0;
-#endif
+	if (!processor->readonly_protection) {
 		/* really fast shallow copy */
 		memcpy(dst, src, sizeof(src[0]));
 		dst->refcount[0] = 1000;
-#ifdef ZEND_ACC_ALIAS
-		if ((processor->active_class_entry_src && (processor->active_class_entry_src->ce_flags & ZEND_ACC_TRAIT))) {
-			PROC_ZSTRING(, function_name)
-		}
-#endif
 		/* deep */
 		STRUCT_P(HashTable, static_variables, HashTable_zval_ptr)
-#ifdef ZEND_ENGINE_2
-		STRUCT_ARRAY(zend_uint, num_args, zend_arg_info, arg_info)
-		gc_arg_info = 1;
-#endif
-		dst->filename = processor->entry_php_src->filepath;
-#ifdef ZEND_ENGINE_2_4
-		if (src->literals) {
-			gc_opcodes = 1;
-			if (op_array_info->literalinfo_cnt) {
-				gc_literals = 1;
-			}
-		}
-#else
-		if (op_array_info->oplineinfo_cnt) {
-			gc_opcodes = 1;
-		}
-#endif
-#ifdef ZEND_ENGINE_2_4
-		if (gc_literals) {
-			dnl used when copying opcodes
-			COPY_N_EX(last_literal, zend_literal, literals)
-		}
-#endif
-		if (gc_opcodes) {
-			zend_op *opline, *end;
-			COPY_N_EX(last, zend_op, opcodes)
-
-			for (opline = dst->opcodes, end = opline + src->last; opline < end; ++opline) {
-#ifdef ZEND_ENGINE_2_4
-				pushdef(`UNION_znode_op_literal', `
-					if (opline->$1_type == IS_CONST) {
-						opline->$1.literal = &dst->literals[opline->$1.literal - src->literals];
-					}
-				')
-				UNION_znode_op_literal(op1)
-				UNION_znode_op_literal(op2)
-				popdef(`UNION_znode_op_literal')
-#endif
-
-				switch (opline->opcode) {
-#ifdef ZEND_GOTO
-					case ZEND_GOTO:
-#endif
-					case ZEND_JMP:
-#ifdef ZEND_FAST_CALL
-					case ZEND_FAST_CALL:
-#endif
-#ifdef ZEND_ENGINE_2
-						Z_OP(opline->op1).jmp_addr = &dst->opcodes[Z_OP(opline->op1).jmp_addr - src->opcodes];
-#endif
-						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
-#ifdef ZEND_ENGINE_2
-						Z_OP(opline->op2).jmp_addr = &dst->opcodes[Z_OP(opline->op2).jmp_addr - src->opcodes];
-#endif
-						break;
-
-					default:
-						break;
-				}
-			}
-		}
-		if (gc_arg_info || gc_opcodes
-#ifdef ZEND_ENGINE_2_4
-		 || gc_literals
-#endif
-		) {
-			xc_gc_op_array_t gc_op_array;
-#ifdef ZEND_ENGINE_2
-			gc_op_array.num_args = gc_arg_info ? dst->num_args : 0;
-			gc_op_array.arg_info = gc_arg_info ? dst->arg_info : NULL;
-#endif
-			gc_op_array.opcodes  = gc_opcodes ? dst->opcodes : NULL;
-#ifdef ZEND_ENGINE_2_4
-			gc_op_array.literals = gc_literals ? dst->literals : NULL;
-#endif
-			xc_gc_add_op_array(&gc_op_array TSRMLS_CC);
-		}
-		IFAUTOCHECK(`xc_autocheck_skip = 1;')
+		define(`SKIPASSERT_ONCE')
+
+	IFRESTORE(`
+#ifdef ZEND_ENGINE_2
+		if (dst->scope) {
+			dst->scope = xc_get_class(processor, (int) dst->scope);
+			xc_fix_method(processor, dst);
+		}
+#endif
+	')
+
 	}
 	else
@@ -835,16 +457,26 @@
 	do {
 	dnl RESTORE is done above!
+	int i;
 
 	/* Common elements */
-	PROCESS(zend_uchar, type)
-	PROC_ZSTRING(, function_name)
-#ifdef ZEND_ENGINE_2
-	PROCESS(zend_uint, fn_flags)
-	STRUCT_ARRAY(zend_uint, num_args, zend_arg_info, arg_info)
-	PROCESS(zend_uint, num_args)
-	PROCESS(zend_uint, required_num_args)
-#	ifndef ZEND_ENGINE_2_4
-	PROCESS(zend_bool, pass_rest_by_reference)
-#	endif
+	DISPATCH(zend_uchar, type)
+	PROC_USTRING(, function_name)
+#ifdef ZEND_ENGINE_2
+	IFRESTORE(`
+		if (dst->scope) {
+			dst->scope = xc_get_class(processor, (int) dst->scope);
+			xc_fix_method(processor, dst);
+		}
+		DONE(scope)
+	', `
+		PROC_CLASS_ENTRY_P(scope)
+	')
+	DISPATCH(zend_uint, fn_flags)
+	/* useless */
+	COPY(prototype)
+	STRUCT_ARRAY(num_args, zend_arg_info, arg_info)
+	DISPATCH(zend_uint, num_args)
+	DISPATCH(zend_uint, required_num_args)
+	DISPATCH(zend_bool, pass_rest_by_reference)
 #else
 	if (src->arg_types) {
@@ -864,103 +496,80 @@
 	}
 	else {
+		IFDASM(`do {
+			/* empty array */
+			zval *zv;
+			ALLOC_INIT_ZVAL(zv);
+			array_init(zv);
+			add_assoc_zval_ex(dst, ZEND_STRS("arg_types"), zv);
+		} while (0);
+		DONE(arg_types)
+		', `
 		COPYNULL(arg_types)
+		')
 	}
 #endif
-#ifndef ZEND_ENGINE_2_4
-	PROCESS(unsigned char, return_reference)
-#endif
+	DISPATCH(unsigned char, return_reference)
 	/* END of common elements */
 #ifdef IS_UNICODE
-	dnl SETNULL(u_twin)
+	SETNULL(u_twin)
 #endif
 
 	STRUCT_P(zend_uint, refcount)
 	UNFIXPOINTER(zend_uint, refcount)
-	IFSTORE(`dst->refcount[0] = 1;')
-
-#ifdef ZEND_ENGINE_2_4
-	dnl used when copying opcodes
-	STRUCT_ARRAY(int, last_literal, zend_literal, literals)
-	PROCESS(int, last_literal)
-#endif
-
-	dnl uses literals
-	STRUCT_ARRAY(zend_uint, last, zend_op, opcodes)
-	PROCESS(zend_uint, last)
-#ifndef ZEND_ENGINE_2_4
-	IFCOPY(`dst->size = src->last;DONE(size)', `PROCESS(zend_uint, size)')
-#endif
+
+	pushdef(`AFTER_ALLOC', `IFCOPY(`
+		processor->active_opcodes_dst = dst->opcodes;
+		processor->active_opcodes_src = src->opcodes;
+	')')
+	STRUCT_ARRAY(last, zend_op, opcodes)
+	popdef(`AFTER_ALLOC')
+	DISPATCH(zend_uint, last)
+	IFCOPY(`dst->size = src->last;DONE(size)', `DISPATCH(zend_uint, size)')
 
 #ifdef IS_CV
-	STRUCT_ARRAY(int, last_var, zend_compiled_variable, vars)
-	PROCESS(int, last_var)
-#	ifndef ZEND_ENGINE_2_4
-	IFCOPY(`dst->size_var = src->last_var;DONE(size_var)', `PROCESS(zend_uint, size_var)')
-#	endif
+	STRUCT_ARRAY(last_var, zend_compiled_variable, vars)
+	DISPATCH(int, last_var)
+	IFCOPY(`dst->size_var = src->last_var;DONE(size_var)', `DISPATCH(zend_uint, size_var)')
 #else
 	dnl zend_cv.m4 is illegal to be made public, don not ask me for it
 	IFDASM(`
-		sinclude(srcdir`/processor/zend_cv.m4')
+		sinclude(`zend_cv.m4')
 		')
 #endif
 
-	PROCESS(zend_uint, T)
-
-#ifdef ZEND_ENGINE_2_5
-	PROCESS(zend_uint, nested_calls)
-	PROCESS(zend_uint, used_stack)
-#endif
-
-	STRUCT_ARRAY(last_brk_cont_t, last_brk_cont, zend_brk_cont_element, brk_cont_array)
-	PROCESS(last_brk_cont_t, last_brk_cont)
-#ifndef ZEND_ENGINE_2_4
-	PROCESS(zend_uint, current_brk_cont)
-#endif
+	DISPATCH(zend_uint, T)
+
+	STRUCT_ARRAY(last_brk_cont, zend_brk_cont_element, brk_cont_array)
+	DISPATCH(zend_uint, last_brk_cont)
+	DISPATCH(zend_uint, current_brk_cont)
 #ifndef ZEND_ENGINE_2
-	PROCESS(zend_bool, uses_globals)
-#endif
-
-#ifdef ZEND_ENGINE_2
-	STRUCT_ARRAY(int, last_try_catch, zend_try_catch_element, try_catch_array)
-	PROCESS(int, last_try_catch)
-#endif
-#ifdef ZEND_ENGINE_2_5
-	PROCESS(zend_bool, has_finally_block)
+	DISPATCH(zend_bool, uses_globals)
+#endif
+
+#ifdef ZEND_ENGINE_2
+	STRUCT_ARRAY(last_try_catch, zend_try_catch_element, try_catch_array)
+	DISPATCH(int, last_try_catch)
 #endif
 
 	STRUCT_P(HashTable, static_variables, HashTable_zval_ptr)
 
-#ifndef ZEND_ENGINE_2_4
-	COPY(start_op)
-	PROCESS(int, backpatch_count)
-#endif
-#ifdef ZEND_ENGINE_2_3
-	PROCESS(zend_uint, this_var)
-#endif
-
-#ifndef ZEND_ENGINE_2_4
-	PROCESS(zend_bool, done_pass_two)
-#endif
-	/* 5.0 <= ver < 5.3 */
-#if defined(ZEND_ENGINE_2) && !defined(ZEND_ENGINE_2_3)
-	PROCESS(zend_bool, uses_this)
-#endif
-
-	IFRESTORE(`dst->filename = processor->entry_php_src->filepath;DONE(filename)', `PROC_STRING(filename)')
-#ifdef IS_UNICODE
-	IFRESTORE(`
-		COPY(script_encoding)
-	', `
-		PROC_STRING(script_encoding)
-	')
-#endif
-#ifdef ZEND_ENGINE_2
-	PROCESS(zend_uint, line_start)
-	PROCESS(zend_uint, line_end)
-	PROCESS(int, doc_comment_len)
-	PROC_ZSTRING_L(, doc_comment, doc_comment_len)
-#endif
-#ifdef ZEND_COMPILE_DELAYED_BINDING
-	PROCESS(zend_uint, early_binding);
+	IFCOPY(`dst->start_op = src->start_op;')
+	DONE(start_op)
+	DISPATCH(int, backpatch_count)
+
+	DISPATCH(zend_bool, done_pass_two)
+#ifdef ZEND_ENGINE_2
+	DISPATCH(zend_bool, uses_this)
+#endif
+
+	IFRESTORE(`COPY(filename)', `PROC_STRING(filename)')
+#ifdef IS_UNICODE
+	PROC_STRING(script_encoding)
+#endif
+#ifdef ZEND_ENGINE_2
+	DISPATCH(zend_uint, line_start)
+	DISPATCH(zend_uint, line_end)
+	DISPATCH(int, doc_comment_len)
+	PROC_USTRING_L(, doc_comment, doc_comment_len)
 #endif
 
@@ -968,302 +577,133 @@
 	DONE(reserved)
 #if defined(HARDENING_PATCH) && HARDENING_PATCH
-	PROCESS(zend_bool, created_by_eval)
-#endif
-#ifdef ZEND_ENGINE_2_4
-	SETNULL(run_time_cache)
-	PROCESS(int, last_cache_slot)
+	DISPATCH(zend_bool, created_by_eval)
 #endif
 	} while (0);
-	IFRESTORE(`xc_fix_op_array_info(processor->entry_php_src, processor->php_src, dst, shallow_copy, op_array_info TSRMLS_CC);')
-
-#ifdef ZEND_ENGINE_2
-	dnl mark it as -1 on store, and lookup parent on restore
-	IFSTORE(`dst->prototype = (processor->active_class_entry_src && src->prototype) ? (zend_function *) -1 : NULL;', `
-		IFRESTORE(`do {
-			zend_function *parent;
-			if (src->prototype != NULL
-			 && zend_u_hash_find(&(processor->active_class_entry_dst->parent->function_table),
-					UG(unicode) ? IS_UNICODE : IS_STRING,
-					src->function_name, xc_zstrlen(UG(unicode) ? IS_UNICODE : IS_STRING, src->function_name) + 1,
-					(void **) &parent) == SUCCESS) {
-				/* see do_inherit_method_check() */
-				if ((parent->common.fn_flags & ZEND_ACC_ABSTRACT)) {
-					dst->prototype = parent;
-				} else if (!(parent->common.fn_flags & ZEND_ACC_CTOR) || (parent->common.prototype && (parent->common.prototype->common.scope->ce_flags & ZEND_ACC_INTERFACE))) {
-					/* ctors only have a prototype if it comes from an interface */
-					dst->prototype = parent->common.prototype ? parent->common.prototype : parent;
-				}
-				else {
-					dst->prototype = NULL;
-				}
+')
+dnl }}}
+
+DEF_STRUCT_P_FUNC(`xc_funcinfo_t', , `dnl {{{
+	DISPATCH(zend_uint, key_size)
+#ifdef IS_UNICODE
+	DISPATCH(zend_uchar, type)
+#endif
+	IFRESTORE(`COPY(key)', `
+		PROC_USTRING_N(type, key, key_size)
+	')
+	STRUCT(zend_function, func)
+')
+dnl }}}
+DEF_STRUCT_P_FUNC(`xc_classinfo_t', , `dnl {{{
+	DISPATCH(zend_uint, key_size)
+#ifdef IS_UNICODE
+	DISPATCH(zend_uchar, type)
+#endif
+	IFRESTORE(`COPY(key)', `
+		PROC_USTRING_N(type, key, key_size)
+	')
+#ifdef ZEND_ENGINE_2
+	STRUCT_P(zend_class_entry, cest)
+#else
+	STRUCT(zend_class_entry, cest)
+#endif
+')
+dnl }}}
+DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{
+	zend_uint i;
+
+#ifdef HAVE_INODE
+	DISPATCH(int, device)
+	DISPATCH(int, inode)
+#endif
+	DISPATCH(size_t, sourcesize)
+
+	DISPATCH(time_t, mtime)
+
+	STRUCT_P(zend_op_array, op_array)
+
+	DISPATCH(zend_uint, funcinfo_cnt)
+	STRUCT_ARRAY(funcinfo_cnt, xc_funcinfo_t, funcinfos)
+
+	DISPATCH(zend_uint, classinfo_cnt)
+	pushdef(`BEFORE_LOOP', `
+		IFCOPY(`
+			processor->active_class_num = i + 1;
+		')
+	')
+	STRUCT_ARRAY(classinfo_cnt, xc_classinfo_t, classinfos)
+	popdef(`BEFORE_LOOP')
+')
+dnl }}}
+DEF_STRUCT_P_FUNC(`xc_entry_data_var_t', , `dnl {{{
+	DISPATCH(time_t, etime)
+	IFSTORE(`
+		if (processor->reference) {
+			if (zend_hash_add(&processor->zvalptrs, (char *)&src->value, sizeof(&src->value), (void*)&src->value, sizeof(src->value), NULL) == SUCCESS) {
+				dnl fprintf(stderr, "mark[%p] = %p\n", &src->value, &dst->value);
 			}
 			else {
-				dst->prototype = NULL;
+				assert(0);
 			}
-		} while (0);
-		')
-	')
-	DONE(prototype)
-
-#endif
-
-#ifdef ZEND_ENGINE_2
-	PROC_CLASS_ENTRY_P(scope)
+		}
+	')
+	STRUCT_P_EX(zval_ptr, dst->value, src->value, `', `&')
+	DONE(value)
+')
+dnl }}}
+dnl {{{ xc_entry_t
+DEF_STRUCT_P_FUNC(`xc_entry_t', , `
 	IFCOPY(`
-		if (src->scope) {
-			xc_fix_method(processor, dst TSRMLS_CC);
-		}
-	')
-#endif
-
-	IFRESTORE(`
-		if (xc_have_op_array_ctor) {
-			zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) xc_zend_extension_op_array_ctor_handler, dst TSRMLS_CC);
-		}
-	')
-	}
-	IFCOPY(`
-		processor->active_op_array_dst = NULL;
-		processor->active_op_array_src = NULL;
-	')
-	IFDASM(`
-		dasm->active_op_array_src = NULL;
-	')
-')
-dnl }}}
-
-#ifdef HAVE_XCACHE_CONSTANT
-DEF_STRUCT_P_FUNC(`xc_constinfo_t', , `dnl {{{
-	PROCESS(zend_uint, key_size)
-#ifdef IS_UNICODE
-	PROCESS(zend_uchar, type)
-#endif
-	IFRESTORE(`COPY(key)', `
-		PROC_ZSTRING_N(type, key, key_size)
-	')
-	PROCESS(ulong, h)
-	STRUCT(zend_constant, constant)
-')
-dnl }}}
-#endif
-IFRESTORE(`', `
-DEF_STRUCT_P_FUNC(`xc_op_array_info_detail_t', , `dnl {{{
-	PROCESS(zend_uint, index)
-	PROCESS(zend_uint, info)
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`xc_op_array_info_t', , `dnl {{{
-#ifdef ZEND_ENGINE_2_4
-	PROCESS(zend_uint, literalinfo_cnt)
-	STRUCT_ARRAY(zend_uint, literalinfo_cnt, xc_op_array_info_detail_t, literalinfos)
-#else
-	PROCESS(zend_uint, oplineinfo_cnt)
-	STRUCT_ARRAY(zend_uint, oplineinfo_cnt, xc_op_array_info_detail_t, oplineinfos)
-#endif
-')
-dnl }}}
-')
-DEF_STRUCT_P_FUNC(`xc_funcinfo_t', , `dnl {{{
-	PROCESS(zend_uint, key_size)
-#ifdef IS_UNICODE
-	PROCESS(zend_uchar, type)
-#endif
-	IFRESTORE(`COPY(key)', `
-		PROC_ZSTRING_N(type, key, key_size)
-	')
-	PROCESS(ulong, h)
-	IFRESTORE(`COPY(op_array_info)', `
-		STRUCT(xc_op_array_info_t, op_array_info)
-	')
-	IFRESTORE(`
-		processor->active_op_array_infos_src = &src->op_array_info;
-		processor->active_op_array_index = 0;
-	')
-	STRUCT(zend_function, func)
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`xc_classinfo_t', , `dnl {{{
-	PROCESS(zend_uint, key_size)
-#ifdef IS_UNICODE
-	PROCESS(zend_uchar, type)
-#endif
-	IFRESTORE(`COPY(key)', `
-		PROC_ZSTRING_N(type, key, key_size)
-	')
-	PROCESS(ulong, h)
-	PROCESS(zend_uint, methodinfo_cnt)
-	IFRESTORE(`COPY(methodinfos)', `
-		STRUCT_ARRAY(zend_uint, methodinfo_cnt, xc_op_array_info_t, methodinfos)
-	')
-	IFRESTORE(`
-		processor->active_op_array_infos_src = src->methodinfos;
-		processor->active_op_array_index = 0;
-	')
-#ifdef ZEND_ENGINE_2
-	STRUCT_P(zend_class_entry, cest)
-#else
-	STRUCT(zend_class_entry, cest)
-#endif
-#ifndef ZEND_COMPILE_DELAYED_BINDING
-	PROCESS(int, oplineno)
-#endif
-')
-dnl }}}
-IFRESTORE(`', `
-#ifdef ZEND_ENGINE_2_1
-DEF_STRUCT_P_FUNC(`xc_autoglobal_t', , `dnl {{{
-	PROCESS(zend_uint, key_len)
-#ifdef IS_UNICODE
-	PROCESS(zend_uchar, type)
-#endif
-	IFRESTORE(`COPY(key)', `
-		PROC_ZSTRING_L(type, key, key_len)
-	')
-	PROCESS(ulong, h)
-')
-dnl }}}
-#endif
-')
-IFRESTORE(`', `
-#ifdef XCACHE_ERROR_CACHING
-DEF_STRUCT_P_FUNC(`xc_compilererror_t', , `dnl {{{
-	PROCESS(int, type)
-	PROCESS(uint, lineno)
-	PROCESS(int, error_len)
-	PROC_STRING_L(error, error_len)
-')
-dnl }}}
-#endif
-')
-DEF_STRUCT_P_FUNC(`xc_entry_data_php_t', , `dnl {{{
-	IFCOPY(`
-		processor->php_dst = dst;
-		processor->php_src = src;
-	')
-
+		processor->xce_dst = dst;
+		processor->xce_src = src;
+	')
+	DISPATCH(xc_entry_type_t, type)
+	DISPATCH(size_t, size)
+
+	DISPATCH(xc_hash_value_t, hvalue)
+	COPY(cache)
 	/* skip */
 	DONE(next)
-	PROCESS(xc_hash_value_t, hvalue)
-	PROCESS(xc_md5sum_t, md5)
-	PROCESS(zend_ulong, refcount)
-
-	PROCESS(zend_ulong, hits)
-	PROCESS(size_t, size)
-
-	IFRESTORE(`COPY(op_array_info)', `
-		STRUCT(xc_op_array_info_t, op_array_info)
-	')
-	IFRESTORE(`
-		processor->active_op_array_infos_src = &dst->op_array_info;
-		processor->active_op_array_index = 0;
-	')
-	STRUCT_P(zend_op_array, op_array)
-
-#ifdef HAVE_XCACHE_CONSTANT
-	PROCESS(zend_uint, constinfo_cnt)
-	STRUCT_ARRAY(zend_uint, constinfo_cnt, xc_constinfo_t, constinfos)
-#endif
-
-	PROCESS(zend_uint, funcinfo_cnt)
-	STRUCT_ARRAY(zend_uint, funcinfo_cnt, xc_funcinfo_t, funcinfos)
-
-	PROCESS(zend_uint, classinfo_cnt)
-	STRUCT_ARRAY(zend_uint, classinfo_cnt, xc_classinfo_t, classinfos, , IFRESTORE(`processor->active_class_index'))
-#ifdef ZEND_ENGINE_2_1
-	PROCESS(zend_uint, autoglobal_cnt)
-	IFRESTORE(`
-		COPY(autoglobals)
-	', `
-		STRUCT_ARRAY(zend_uint, autoglobal_cnt, xc_autoglobal_t, autoglobals)
-	')
-#endif
-#ifdef XCACHE_ERROR_CACHING
-	PROCESS(zend_uint, compilererror_cnt)
-	IFRESTORE(`
-		COPY(compilererrors)
-	', `
-		STRUCT_ARRAY(zend_uint, compilererror_cnt, xc_compilererror_t, compilererrors)
-	')
-#endif
-#ifndef ZEND_COMPILE_DELAYED_BINDING
-	PROCESS(zend_bool, have_early_binding)
-#endif
-	PROCESS(zend_bool, have_references)
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`xc_entry_t', , `dnl {{{
-	/* skip */
-	DONE(next)
-	PROCESS(size_t, size)
-
-	PROCESS(time_t, ctime)
-	PROCESS(time_t, atime)
-	PROCESS(time_t, dtime)
-	PROCESS(long, ttl)
-	PROCESS(zend_ulong, hits)
-	DONE(name) dnl handle in xc_entry_php_t and xc_entry_var_t
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`xc_entry_php_t', , `dnl {{{
-	STRUCT(xc_entry_t, entry)
+
+	IFSTORE(`dst->refcount = 0; DONE(refcount)', `DISPATCH(long, refcount)')
+
+	DISPATCH(time_t, ctime)
+	DISPATCH(time_t, atime)
+	DISPATCH(time_t, dtime)
+	DISPATCH(zend_ulong, hits)
+#ifdef IS_UNICODE
+	DISPATCH(zend_uchar, name_type)
+#endif
+	dnl {{{ name
 	DISABLECHECK(`
-		PROCESS(int, entry.name.str.len)
-		IFRESTORE(`COPY(entry.name.str.val)', `
-			PROC_STRING_L(entry.name.str.val, entry.name.str.len)
-		')
-	')
-
-	IFCALCCOPY(`COPY(php)', `STRUCT_P(xc_entry_data_php_t, php)')
-
-	IFSTORE(`dst->refcount = 0; DONE(refcount)', `PROCESS(long, refcount)')
-	PROCESS(time_t, file_mtime)
-	PROCESS(size_t, file_size)
-	PROCESS(size_t, file_device)
-	PROCESS(size_t, file_inode)
-
-	PROCESS(size_t, filepath_len)
-	IFRESTORE(`COPY(filepath)', `PROC_STRING_L(filepath, filepath_len)')
-	PROCESS(size_t, dirpath_len)
-	IFRESTORE(`COPY(dirpath)', `PROC_STRING_L(dirpath, dirpath_len)')
-#ifdef IS_UNICODE
-	PROCESS(int, ufilepath_len)
-	IFRESTORE(`COPY(ufilepath)', `PROC_USTRING_L(ufilepath, ufilepath_len)')
-	PROCESS(int, udirpath_len)
-	IFRESTORE(`COPY(udirpath)', `PROC_USTRING_L(udirpath, udirpath_len)')
-#endif
-')
-dnl }}}
-DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
-	STRUCT(xc_entry_t, entry)
-
-#ifdef IS_UNICODE
-	PROCESS(zend_uchar, name_type)
-#endif
-	dnl {{{ entry.name
+#ifdef IS_UNICODE
+		if (src->name_type == IS_UNICODE) {
+			DISPATCH(int32_t, name.ustr.len)
+		}
+		else {
+			DISPATCH(int, name.str.len)
+		}
+#else
+		DISPATCH(int, name.str.len)
+#endif
+		IFRESTORE(`COPY(name.str.val)', `PROC_USTRING_L(name_type, name.str.val, name.str.len)')
+	')
+	DONE(name)
+	dnl }}}
+
+	dnl {{{ data
 	DISABLECHECK(`
-#ifdef IS_UNICODE
-		if (src->name_type == IS_UNICODE) {
-			PROCESS(int32_t, entry.name.ustr.len)
-		}
-		else {
-			PROCESS(int, entry.name.str.len)
-		}
-#else
-		PROCESS(int, entry.name.str.len)
-#endif
-		IFRESTORE(`COPY(entry.name.str.val)', `
-#ifdef IS_UNICODE
-			PROC_ZSTRING_L(name_type, entry.name.uni.val, entry.name.uni.len)
-#else
-			PROC_STRING_L(entry.name.str.val, entry.name.str.len)
-#endif
-		')
-	')
+		switch (src->type) {
+		case XC_TYPE_PHP:
+			STRUCT_P(xc_entry_data_php_t, data.php)
+			break;
+		case XC_TYPE_VAR:
+			STRUCT_P(xc_entry_data_var_t, data.var)
+			break;
+		default:
+			assert(0);
+		}
+	')
+	DONE(data)
 	dnl }}}
-
-	IFDPRINT(`INDENT()`'fprintf(stderr, "zval:value");')
-	STRUCT_P_EX(zval_ptr, dst->value, src->value, `value', `', `&')
-	PROCESS(zend_bool, have_references)
-	DONE(value)
 ')
 dnl }}}
Index: /trunk/processor/head.m4
===================================================================
--- /trunk/processor/head.m4	(revision 1211)
+++ /trunk/processor/head.m4	(revision 1)
@@ -5,26 +5,13 @@
 
 #include "php.h"
-#include "zend_extensions.h"
 #include "zend_compile.h"
 #include "zend_API.h"
-#include "zend_ini.h"
-
-/* export: #include "xcache.h" :export */
+
 #include "xcache.h"
-/* export: #include "mod_cacher/xc_cache.h" :export */
-#include "mod_cacher/xc_cache.h"
-/* export: #include "xcache/xc_shm.h" :export */
-#include "xcache/xc_shm.h"
-/* export: #include "xcache/xc_allocator.h" :export */
-#include "xcache/xc_allocator.h"
-#include "xcache/xc_const_string.h"
-#include "xcache/xc_utils.h"
-#include "util/xc_align.h"
-#include "xc_processor.h"
+#include "align.h"
+#include "const_string.h"
+#include "processor.h"
+#include "stack.h"
 #include "xcache_globals.h"
-
-#if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
-extern unsigned int zend_hash_canary;
-#endif
 
 define(`SIZEOF_zend_uint', `sizeof(zend_uint)')
@@ -36,26 +23,12 @@
 define(`SIZEOF_zval_ptr', `sizeof(zval_ptr)')
 define(`COUNTOF_zval_ptr', `1')
-define(`SIZEOF_zval_ptr_nullable', `sizeof(zval_ptr_nullable)')
-define(`COUNTOF_zval_ptr_nullable', `1')
-define(`SIZEOF_zend_trait_alias_ptr', `sizeof(zend_trait_alias)')
-define(`COUNTOF_zend_trait_alias_ptr', `1')
-define(`SIZEOF_zend_trait_precedence_ptr', `sizeof(zend_trait_precedence)')
-define(`COUNTOF_zend_trait_precedence_ptr', `1')
 define(`SIZEOF_xc_entry_name_t', `sizeof(xc_entry_name_t)')
 define(`COUNTOF_xc_entry_name_t', `1')
-define(`SIZEOF_xc_ztstring', `sizeof(xc_ztstring)')
-define(`COUNTOF_xc_ztstring', `1')
 
 ifdef(`XCACHE_ENABLE_TEST', `
 #undef NDEBUG
 #include <assert.h>
-m4_errprint(`AUTOCHECK INFO: runtime autocheck Enabled (debug build)')
-', `
-m4_errprint(`AUTOCHECK INFO: runtime autocheck Disabled (optimized build)')
+include(structinfo.m4)
 ')
-ifdef(`DEBUG_SIZE', `static int xc_totalsize = 0;')
-
-sinclude(builddir`/structinfo.m4')
-
 #ifndef NDEBUG
 #	undef inline
@@ -64,75 +37,31 @@
 
 typedef zval *zval_ptr;
-typedef zval *zval_ptr_nullable;
-typedef char *xc_ztstring;
-#ifdef ZEND_ENGINE_2_4
-typedef zend_trait_alias *zend_trait_alias_ptr;
-typedef zend_trait_precedence *zend_trait_precedence_ptr;
-#endif
-#ifdef ZEND_ENGINE_2_3
-typedef int last_brk_cont_t;
-#else
-typedef zend_uint last_brk_cont_t;
-#endif
-
-typedef zend_uchar xc_zval_type_t;
-typedef int xc_op_type;
-typedef zend_uchar xc_opcode;
-#ifdef IS_UNICODE
-typedef UChar zstr_uchar;
-#endif
-typedef char  zstr_char;
+typedef zend_uchar zval_data_type;
 
 #define MAX_DUP_STR_LEN 256
 dnl }}}
-/* export: typedef struct _xc_processor_t xc_processor_t; :export {{{ */
-struct _xc_processor_t {
+/* export: typedef struct _processor_t processor_t; :export {{{ */
+struct _processor_t {
 	char *p;
-	size_t size;
+	zend_uint size;
 	HashTable strings;
 	HashTable zvalptrs;
 	zend_bool reference; /* enable if to deal with reference */
-	zend_bool have_references;
-	const xc_entry_php_t *entry_php_src;
-	const xc_entry_php_t *entry_php_dst;
-	const xc_entry_data_php_t *php_src;
-	const xc_entry_data_php_t *php_dst;
-	xc_shm_t                  *shm;
-	xc_allocator_t            *allocator;
+	const xc_entry_t *xce_src;
+	const xc_entry_t *xce_dst;
 	const zend_class_entry *cache_ce;
-	zend_ulong cache_class_index;
-
-	const zend_op_array    *active_op_array_src;
-	zend_op_array          *active_op_array_dst;
+	zend_uint cache_class_num;
+
+	const zend_op          *active_opcodes_src;
+	zend_op                *active_opcodes_dst;
 	const zend_class_entry *active_class_entry_src;
 	zend_class_entry       *active_class_entry_dst;
-	zend_uint                 active_class_index;
-	zend_uint                 active_op_array_index;
-	const xc_op_array_info_t *active_op_array_infos_src;
+	zend_uint               active_class_num;
 
 	zend_bool readonly_protection; /* wheather it's present */
-IFAUTOCHECK(xc_stack_t allocsizes;)
+IFASSERT(xc_stack_t allocsizes;)
 };
 /* }}} */
-/* export: typedef struct _xc_dasm_t { const zend_op_array *active_op_array_src; } xc_dasm_t; :export {{{ */
-/* }}} */
-/* {{{ memsetptr */
-IFAUTOCHECK(`dnl
-static void *memsetptr(void *mem, void *content, size_t n)
-{
-	void **p = (void **) mem;
-	void **end = (void **) ((char *) mem + n);
-	while (p < end - sizeof(content)) {
-		*p = content;
-		p += sizeof(content);
-	}
-	if (p < end) {
-		memset(p, -1, end - p);
-	}
-	return mem;
-}
-')
-/* }}} */
-#ifdef HAVE_XCACHE_DPRINT
+#ifdef XCACHE_HAVE_DPRINT
 static void xc_dprint_indent(int indent) /* {{{ */
 {
@@ -142,67 +71,22 @@
 	}
 }
-/* }}} */
-static void xc_dprint_str_len(const char *str, int len) /* {{{ */
-{
-	const unsigned char *p = (const unsigned char *) str;
-	int i;
-	for (i = 0; i < len; i ++) {
-		if (p[i] < 32 || p[i] == 127) {
-			fprintf(stderr, "\\%03o", (unsigned int) p[i]);
-		}
-		else {
-			fputc(p[i], stderr);
-		}
-	}
-}
-/* }}} */
-#endif
-/* {{{ xc_zstrlen_char */
-static inline size_t xc_zstrlen_char(const_zstr s)
-{
-	return strlen(ZSTR_S(s));
-}
-/* }}} */
-#ifdef IS_UNICODE
-/* {{{ xc_zstrlen_uchar */
-static inline size_t xc_zstrlen_uchar(zstr s)
-{
-	return u_strlen(ZSTR_U(s));
-}
-/* }}} */
-/* {{{ xc_zstrlen */
-static inline size_t xc_zstrlen(int type, const_zstr s)
-{
-	return type == IS_UNICODE ? xc_zstrlen_uchar(s) : xc_zstrlen_char(s);
-}
-/* }}} */
-#else
-/* {{{ xc_zstrlen */
-#define xc_zstrlen(dummy, s) xc_zstrlen_char(s)
-/* }}} */
-#endif
+#endif
+/* }}} */
 /* {{{ xc_calc_string_n */
-REDEF(`PROCESSOR_TYPE', `calc')
-#undef C_RELAYLINE
-#define C_RELAYLINE
-IFAUTOCHECK(`
-#undef C_RELAYLINE
-#define C_RELAYLINE , __LINE__
-')
-static inline void xc_calc_string_n(xc_processor_t *processor, zend_uchar type, const_zstr str, long size IFAUTOCHECK(`, int relayline')) {
+REDEF(`KIND', `calc')
+static inline void xc_calc_string_n(processor_t *processor, zend_uchar type, char *str, long size IFASSERT(`, int relayline')) {
 	pushdef(`__LINE__', `relayline')
-	size_t realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
-	long dummy = 1;
+	int realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
 
 	if (realsize > MAX_DUP_STR_LEN) {
 		ALLOC(, char, realsize)
 	}
-	else if (zend_u_hash_add(&processor->strings, type, str, (uint) size, (void *) &dummy, sizeof(dummy), NULL) == SUCCESS) {
+	else if (zend_u_hash_add(&processor->strings, type, str, size, (void*)&str, sizeof(char*), NULL) == SUCCESS) {
 		/* new string */
 		ALLOC(, char, realsize)
 	} 
-	IFAUTOCHECK(`
+	IFASSERT(`
 		else {
-			dnl fprintf(stderr, "dupstr %s\n", ZSTR_S(str));
+			dnl fprintf(stderr, "dupstr %s\n", str);
 		}
 	')
@@ -211,26 +95,24 @@
 /* }}} */
 /* {{{ xc_store_string_n */
-REDEF(`PROCESSOR_TYPE', `store')
-static inline zstr xc_store_string_n(xc_processor_t *processor, zend_uchar type, const_zstr str, long size IFAUTOCHECK(`, int relayline')) {
+REDEF(`KIND', `store')
+static inline char *xc_store_string_n(processor_t *processor, zend_uchar type, char *str, long size IFASSERT(`, int relayline')) {
 	pushdef(`__LINE__', `relayline')
-	size_t realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
-	zstr ret, *pret;
+	int realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
+	char *s;
 
 	if (realsize > MAX_DUP_STR_LEN) {
-		ALLOC(ZSTR_V(ret), char, realsize)
-		memcpy(ZSTR_V(ret), ZSTR_V(str), realsize);
-		return ret;
-	}
-
-	if (zend_u_hash_find(&processor->strings, type, str, (uint) size, (void **) &pret) == SUCCESS) {
-		return *pret;
-	}
-
-	/* new string */
-	ALLOC(ZSTR_V(ret), char, realsize)
-	memcpy(ZSTR_V(ret), ZSTR_V(str), realsize);
-	zend_u_hash_add(&processor->strings, type, str, (uint) size, (void *) &ret, sizeof(zstr), NULL);
-	return ret;
-
+		ALLOC(s, char, realsize)
+		memcpy(s, str, realsize);
+	}
+	else if (zend_u_hash_find(&processor->strings, type, str, size, (void*)&s) != SUCCESS) {
+		/* new string */
+		ALLOC(s, char, realsize)
+		memcpy(s, str, realsize);
+		zend_u_hash_add(&processor->strings, type, str, size, (void*)&s, sizeof(char*), NULL);
+	}
+	else {
+		s = *(char**)s;
+	}
+	return s;
 	popdef(`__LINE__')
 }
@@ -239,42 +121,39 @@
  * return class_index + 1
  */
-static zend_ulong xc_get_class_num(xc_processor_t *processor, zend_class_entry *ce) {
+static zend_uint xc_get_class_num(processor_t *processor, zend_class_entry *ce) {
 	zend_uint i;
-	const xc_entry_data_php_t *php = processor->php_src;
+	const xc_entry_t *xce = processor->xce_src;
 	zend_class_entry *ceptr;
 
 	if (processor->cache_ce == ce) {
-		return processor->cache_class_index + 1;
-	}
-	for (i = 0; i < php->classinfo_cnt; i ++) {
-		ceptr = CestToCePtr(php->classinfos[i].cest);
+		return processor->cache_class_num;
+	}
+	for (i = 0; i < xce->data.php->classinfo_cnt; i ++) {
+		ceptr = CestToCePtr(xce->data.php->classinfos[i].cest);
 		if (ZCEP_REFCOUNT_PTR(ceptr) == ZCEP_REFCOUNT_PTR(ce)) {
 			processor->cache_ce = ceptr;
-			processor->cache_class_index = i;
+			processor->cache_class_num = i + 1;
 			return i + 1;
 		}
 	}
 	assert(0);
-	return (zend_ulong) -1;
-}
-define(`xc_get_class_num', `xc_get_class_numNOTDEFINED')
+	return (zend_uint) -1;
+}
 /* }}} */
 /* {{{ xc_get_class */
 #ifdef ZEND_ENGINE_2
-static zend_class_entry *xc_get_class(xc_processor_t *processor, zend_ulong class_num) {
+static zend_class_entry *xc_get_class(processor_t *processor, zend_uint class_num) {
 	/* must be parent or currrent class */
-	assert(class_num <= processor->active_class_index + 1);
-	return CestToCePtr(processor->php_dst->classinfos[class_num - 1].cest);
-}
-#endif
-define(`xc_get_class', `xc_get_classNOTDEFINED')
+	assert(class_num <= processor->active_class_num);
+	return CestToCePtr(processor->xce_dst->data.php->classinfos[class_num - 1].cest);
+}
+#endif
 /* }}} */
 #ifdef ZEND_ENGINE_2
 /* fix method on store */
-static void xc_fix_method(xc_processor_t *processor, zend_op_array *dst TSRMLS_DC) /* {{{ */
+static void xc_fix_method(processor_t *processor, zend_op_array *dst) /* {{{ */
 {
 	zend_function *zf = (zend_function *) dst;
 	zend_class_entry *ce = processor->active_class_entry_dst;
-	const zend_class_entry *srcce = processor->active_class_entry_src;
 
 	/* Fixing up the default functions for objects here since
@@ -297,117 +176,39 @@
 	}
 	else {
-	pushdef(`SET_IF_SAME_NAMEs', `
+#define SET_IF_SAME_NAME(member) \
+		do { \
+			if(!strcasecmp(zf->common.function_name, #member)) { \
+				ce->member = zf; \
+			} \
+		} \
+		while(0)
+		/* if(ce->member && !strcmp(zf->common.function_name, ce->member->common.function_name)) { \ */
+
 		SET_IF_SAME_NAME(__get);
 		SET_IF_SAME_NAME(__set);
-#ifdef ZEND_ENGINE_2_1
 		SET_IF_SAME_NAME(__unset);
 		SET_IF_SAME_NAME(__isset);
-#endif
 		SET_IF_SAME_NAME(__call);
-#ifdef ZEND_CALLSTATIC_FUNC_NAME
-		SET_IF_SAME_NAME(__callstatic);
-#endif
-#if defined(ZEND_ENGINE_2_2) || PHP_MAJOR_VERSION >= 6
+#if PHP_MAJOR_VERSION >= 6
 		SET_IF_SAME_NAME(__tostring);
 #endif
-	')
-#ifdef IS_UNICODE
-		if (UG(unicode)) {
-#define SET_IF_SAME_NAME(member) \
-			do { \
-				if (srcce->member && u_strcmp(ZSTR_U(zf->common.function_name), ZSTR_U(srcce->member->common.function_name)) == 0) { \
-					ce->member = zf; \
-				} \
-			} \
-			while(0)
-
-			SET_IF_SAME_NAMEs()
+
 #undef SET_IF_SAME_NAME
-		}
-		else
-#endif
-		do {
-#define SET_IF_SAME_NAME(member) \
-			do { \
-				if (srcce->member && strcmp(ZSTR_S(zf->common.function_name), ZSTR_S(srcce->member->common.function_name)) == 0) { \
-					ce->member = zf; \
-				} \
-			} \
-			while(0)
-
-			SET_IF_SAME_NAMEs()
-#undef SET_IF_SAME_NAME
-		} while (0);
-
-	popdef(`SET_IF_SAME_NAMEs')
-
-	}
-}
-/* }}} */
-#endif
-/* {{{ call op_array ctor handler */
-extern zend_bool xc_have_op_array_ctor;
-static void xc_zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
-{
-	if (extension->op_array_ctor) {
-		extension->op_array_ctor(op_array);
-	}
-}
-/* }}} */
-/* {{{ field name checker */
-IFAUTOCHECK(`dnl
-static int xc_check_names(const char *file, int line, const char *functionName, const char **assert_names, size_t assert_names_count, HashTable *done_names)
-{
-	int errors = 0;
-	if (assert_names_count) {
-		size_t i;
-		Bucket *b;
-
-		for (i = 0; i < assert_names_count; ++i) {
-			if (!zend_u_hash_exists(done_names, IS_STRING, assert_names[i], (uint) strlen(assert_names[i]) + 1)) {
-				fprintf(stderr
-					, "Error: missing field at %s `#'%d %s`' : %s\n"
-					, file, line, functionName
-					, assert_names[i]
-					);
-				++errors;
-			}
-		}
-
-		for (b = done_names->pListHead; b != NULL; b = b->pListNext) {
-			int known = 0;
-			for (i = 0; i < assert_names_count; ++i) {
-				if (strcmp(assert_names[i], BUCKET_KEY_S(b)) == 0) {
-					known = 1;
-					break;
-				}
-			}
-			if (!known) {
-				fprintf(stderr
-					, "Error: unknown field at %s `#'%d %s`' : %s\n"
-					, file, line, functionName
-					, BUCKET_KEY_S(b)
-					);
-				++errors;
-			}
-		}
-	}
-	return errors;
-}
-')
-/* }}} */
+	}
+}
+/* }}} */
+#endif
 dnl ================ export API
-define(`DEFINE_STORE_API', `
-/* export: $1 *xc_processor_store_$1(xc_shm_t *shm, xc_allocator_t *allocator, $1 *src TSRMLS_DC); :export {{{ */
-$1 *xc_processor_store_$1(xc_shm_t *shm, xc_allocator_t *allocator, $1 *src TSRMLS_DC) {
-	$1 *dst;
-	xc_processor_t processor;
+/* export: xc_entry_t *xc_processor_store_xc_entry_t(xc_entry_t *src TSRMLS_DC); :export {{{ */
+xc_entry_t *xc_processor_store_xc_entry_t(xc_entry_t *src TSRMLS_DC) {
+	xc_entry_t *dst;
+	processor_t processor;
 
 	memset(&processor, 0, sizeof(processor));
-	processor.reference = 1;
-	processor.shm = shm;
-	processor.allocator = allocator;
-
-	IFAUTOCHECK(`xc_stack_init(&processor.allocsizes);')
+	if (src->type == XC_TYPE_VAR) {
+		processor.reference = 1;
+	}
+
+	IFASSERT(`xc_stack_init(&processor.allocsizes);')
 
 	/* calc size */ {
@@ -421,5 +222,5 @@
 		processor.size = ALIGN(processor.size + sizeof(src[0]));
 
-		xc_calc_$1(&processor, src TSRMLS_CC);
+		xc_calc_xc_entry_t(&processor, src TSRMLS_CC);
 		if (processor.reference) {
 			zend_hash_destroy(&processor.zvalptrs);
@@ -427,16 +228,10 @@
 		zend_hash_destroy(&processor.strings);
 	}
-	src->ifelse(
-		`$1', `xc_entry_data_php_t', `',
-		`', `', entry.)size = processor.size;
-	ifelse(
-		`$1', `xc_entry_var_t', `src->have_references = processor.have_references;',
-		`$1', `xc_entry_data_php_t', `src->have_references = processor.have_references;'
-	)
-
-	IFAUTOCHECK(`xc_stack_reverse(&processor.allocsizes);')
+	src->size = processor.size;
+
+	IFASSERT(`xc_stack_reverse(&processor.allocsizes);')
 	/* store {{{ */
 	{
-		IFAUTOCHECK(`char *oldp;')
+		IFASSERT(`char *oldp;')
 		zend_hash_init(&processor.strings, 0, NULL, NULL, 0);
 		if (processor.reference) {
@@ -444,23 +239,24 @@
 		}
 
-		/* allocator :) */
-		processor.p = (char *) processor.allocator->vtable->malloc(processor.allocator, processor.size);
+		/* mem :) */
+		processor.p = (char *)xc_mem_malloc(src->cache->mem, processor.size);
 		if (processor.p == NULL) {
 			dst = NULL;
 			goto err_alloc;
-		}
-		IFAUTOCHECK(`oldp = processor.p;')
+			return NULL;
+		}
+		IFASSERT(`oldp = processor.p;')
 		assert(processor.p == (char *) ALIGN(processor.p));
 
 		/* allocate */
-		dst = ($1 *) processor.p;
+		dst = (xc_entry_t *) processor.p;
 		processor.p = (char *) ALIGN(processor.p + sizeof(dst[0]));
 
-		xc_store_$1(&processor, dst, src TSRMLS_CC);
-		IFAUTOCHECK(` {
-			size_t unexpected = processor.p - oldp;
-			size_t expected = processor.size;
-			if (unexpected != processor.size) {
-				fprintf(stderr, "unexpected:%lu - expected:%lu = %ld != 0\n", (unsigned long) unexpected, (unsigned long) expected, (long) unexpected - expected);
+		xc_store_xc_entry_t(&processor, dst, src TSRMLS_CC);
+		IFASSERT(` {
+			int real = processor.p - oldp;
+			int should = processor.size;
+			if (real != processor.size) {
+				fprintf(stderr, "real %d - should %d = %d\n", real, should, real - should);
 				abort();
 			}
@@ -474,81 +270,42 @@
 	/* }}} */
 
-	IFAUTOCHECK(`xc_stack_destroy(&processor.allocsizes);')
+	IFASSERT(`xc_stack_destroy(&processor.allocsizes);')
 
 	return dst;
 }
 /* }}} */
-')
-DEFINE_STORE_API(`xc_entry_var_t')
-DEFINE_STORE_API(`xc_entry_php_t')
-DEFINE_STORE_API(`xc_entry_data_php_t')
-/* export: xc_entry_php_t *xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC); :export {{{ */
-xc_entry_php_t *xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC) {
-	xc_processor_t processor;
-
-	memset(&processor, 0, sizeof(processor));
-	xc_restore_xc_entry_php_t(&processor, dst, src TSRMLS_CC);
-
-	return dst;
-}
-/* }}} */
-/* export: xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t(const xc_entry_php_t *entry_php, xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC); :export {{{ */
-xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t(const xc_entry_php_t *entry_php, xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC) {
-	xc_processor_t processor;
+/* export: xc_entry_t *xc_processor_restore_xc_entry_t(xc_entry_t *dst, const xc_entry_t *src, zend_bool readonly_protection TSRMLS_DC); :export {{{ */
+xc_entry_t *xc_processor_restore_xc_entry_t(xc_entry_t *dst, const xc_entry_t *src, zend_bool readonly_protection TSRMLS_DC) {
+	processor_t processor;
 
 	memset(&processor, 0, sizeof(processor));
 	processor.readonly_protection = readonly_protection;
-	/* this function is used for php data only */
-	if (src->have_references) {
-		processor.reference = 1;
-	}
-	processor.entry_php_src = entry_php;
-
-	if (processor.reference) {
-		zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
-	}
-	xc_restore_xc_entry_data_php_t(&processor, dst, src TSRMLS_CC);
-	if (processor.reference) {
-		zend_hash_destroy(&processor.zvalptrs);
-	}
+
+	xc_restore_xc_entry_t(&processor, dst, src TSRMLS_CC);
 	return dst;
 }
 /* }}} */
-/* export: xc_entry_var_t *xc_processor_restore_xc_entry_var_t(xc_entry_var_t *dst, const xc_entry_var_t *src TSRMLS_DC); :export {{{ */
-xc_entry_var_t *xc_processor_restore_xc_entry_var_t(xc_entry_var_t *dst, const xc_entry_var_t *src TSRMLS_DC) {
-	xc_processor_t processor;
+/* export: zval *xc_processor_restore_zval(zval *dst, const zval *src TSRMLS_DC); :export {{{ */
+zval *xc_processor_restore_zval(zval *dst, const zval *src TSRMLS_DC) {
+	processor_t processor;
 
 	memset(&processor, 0, sizeof(processor));
-	xc_restore_xc_entry_var_t(&processor, dst, src TSRMLS_CC);
+	processor.reference = 1;
+
+	zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
+	dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
+	zend_hash_add(&processor.zvalptrs, (char *)src, sizeof(src), (void*)&dst, sizeof(dst), NULL);
+	xc_restore_zval(&processor, dst, src TSRMLS_CC);
+	zend_hash_destroy(&processor.zvalptrs);
 
 	return dst;
 }
 /* }}} */
-/* export: zval *xc_processor_restore_zval(zval *dst, const zval *src, zend_bool have_references TSRMLS_DC); :export {{{ */
-zval *xc_processor_restore_zval(zval *dst, const zval *src, zend_bool have_references TSRMLS_DC) {
-	xc_processor_t processor;
-
-	memset(&processor, 0, sizeof(processor));
-	processor.reference = have_references;
-
-	if (processor.reference) {
-		zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
-		dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
-		zend_hash_add(&processor.zvalptrs, (char *)src, sizeof(src), (void*)&dst, sizeof(dst), NULL);
-	}
-	xc_restore_zval(&processor, dst, src TSRMLS_CC);
-	if (processor.reference) {
-		zend_hash_destroy(&processor.zvalptrs);
-	}
-
-	return dst;
-}
-/* }}} */
-/* export: void xc_dprint(xc_entry_php_t *src, int indent TSRMLS_DC); :export {{{ */
-#ifdef HAVE_XCACHE_DPRINT
-void xc_dprint(xc_entry_php_t *src, int indent TSRMLS_DC) {
-	IFDPRINT(`INDENT()`'fprintf(stderr, "xc_entry_php_t:src");')
-	xc_dprint_xc_entry_php_t(src, indent TSRMLS_CC);
-}
-#endif
-/* }}} */
+/* export: void xc_dprint(xc_entry_t *src, int indent TSRMLS_DC); :export {{{ */
+#ifdef XCACHE_HAVE_DPRINT
+void xc_dprint(xc_entry_t *src, int indent TSRMLS_DC) {
+	IFDPRINT(`INDENT()`'fprintf(stderr, "xc_entry_t:src");')
+	xc_dprint_xc_entry_t(src, indent TSRMLS_CC);
+}
+#endif
+/* }}} */
Index: /unk/processor/process.m4
===================================================================
--- /trunk/processor/process.m4	(revision 917)
+++ 	(revision )
@@ -1,145 +1,0 @@
-define(`PROCESS_SCALAR', `dnl {{{ (1:elm, 2:format=%d, 3:type=)
-	IFNOTMEMCPY(`IFCOPY(`DST(`$1') = SRC(`$1');')')
-	IFDPRINT(`
-		INDENT()
-		fprintf(stderr, "$3:$1:\t%ifelse(`$2',`',`d',`$2')\n", SRC(`$1'));
-	')
-	IFDASM(`
-		ifelse(
-			`$3', `zend_bool', `add_assoc_bool_ex(dst, ZEND_STRS("$1"), SRC(`$1') ? 1 : 0);'
-		, `', `', `add_assoc_long_ex(dst, ZEND_STRS("$1"), SRC(`$1'));'
-		)
-	')
-	DONE(`$1')
-')
-dnl }}}
-define(`PROCESS_xc_ztstring', `dnl {{{ (1:elm)
-	pushdef(`REALPTRTYPE', `zend_class_entry')
-	PROC_STRING(`$1')
-	popdef(`REALPTRTYPE')
-')
-dnl }}}
-define(`PROCESS_xc_zval_type_t', `dnl {{{ (1:elm)
-	IFDPRINT(`
-		INDENT()
-		fprintf(stderr, ":$1:\t%d %s\n", SRC(`$1'), xc_get_data_type(SRC(`$1')));
-		DONE(`$1')
-	', `PROCESS_SCALAR(`$1')')
-')
-dnl }}}
-define(`PROCESS_xc_op_type', `dnl {{{ (1:elm)
-	IFDPRINT(`
-		INDENT()
-		fprintf(stderr, ":$1:\t%d %s\n", SRC(`$1'), xc_get_op_type(SRC(`$1')));
-		DONE(`$1')
-	', `PROCESS_SCALAR(`$1')')
-')
-dnl }}}
-define(`PROCESS_xc_opcode', `dnl {{{ (1:elm)
-	IFDPRINT(`
-		INDENT()
-		fprintf(stderr, ":$1:\t%u %s\n", SRC(`$1'), xc_get_opcode(SRC(`$1')));
-		DONE(`$1')
-	', `PROCESS_SCALAR(`$1')')
-')
-dnl }}}
-define(`PROCESS', `dnl PROCESS(1:type, 2:elm)
-	DBG(`$0($*)')
-	assert(sizeof($1) == sizeof(SRC(`$2')));
-	ifelse(
-		`$1', `zend_bool',        `PROCESS_SCALAR(`$2', `u',  `$1')'
-	, `$1', `zend_uchar',       `PROCESS_SCALAR(`$2', `u',  `$1')'
-	, `$1', `char',             `PROCESS_SCALAR(`$2', `d',  `$1')'
-	, `$1', `int32_t',          `PROCESS_SCALAR(`$2', `d',  `$1')'
-	, `$1', `unsigned char',    `PROCESS_SCALAR(`$2', `u',  `$1')'
-	, `$1', `zend_uint',        `PROCESS_SCALAR(`$2', `u',  `$1')'
-	, `$1', `uint',             `PROCESS_SCALAR(`$2', `u',  `$1')'
-	, `$1', `unsigned int',     `PROCESS_SCALAR(`$2', `u',  `$1')'
-	, `$1', `zend_ulong',       `PROCESS_SCALAR(`$2', `lu', `$1')'
-	, `$1', `ulong',            `PROCESS_SCALAR(`$2', `lu', `$1')'
-	, `$1', `size_t',           `PROCESS_SCALAR(`$2', `lu', `$1')'
-	, `$1', `long',             `PROCESS_SCALAR(`$2', `ld', `$1')'
-	, `$1', `time_t',           `PROCESS_SCALAR(`$2', `ld', `$1')'
-	, `$1', `zend_ushort',      `PROCESS_SCALAR(`$2', `hu', `$1')'
-	, `$1', `int',              `PROCESS_SCALAR(`$2', `d',  `$1')'
-	, `$1', `double',           `PROCESS_SCALAR(`$2', `f',  `$1')'
-	, `$1', `xc_entry_type_t',  `PROCESS_SCALAR(`$2', `d',  `$1')'
-	, `$1', `xc_hash_value_t',  `PROCESS_SCALAR(`$2', `lu', `$1')'
-	, `$1', `last_brk_cont_t',  `PROCESS_SCALAR(`$2', `d', `$1')'
-
-	, `$1', `xc_ztstring',       `PROCESS_xc_ztstring(`$2')'
-	, `$1', `xc_zval_type_t',    `PROCESS_xc_zval_type_t(`$2')'
-	, `$1', `xc_op_type',        `PROCESS_xc_op_type(`$2')'
-	, `$1', `xc_opcode',         `PROCESS_xc_opcode(`$2')'
-	, `$1', `opcode_handler_t',  `/* is copying enough? */COPY(`$2')'
-	, `$1', `xc_md5sum_t',       `COPY(`$2')'
-	, `', `', `m4_errprint(`AUTOCHECK ERROR: Unknown type "$1"')define(`EXIT_PENDING', 1)'
-	)
-')
-define(`PROCESS_ARRAY', `dnl {{{ (1:count, 2:type, 3:elm, [4:real_type])
-	if (src->$3) {
-		int LOOPCOUNTER;
-		IFDASM(`
-			zval *arr;
-			ALLOC_INIT_ZVAL(arr);
-			array_init(arr);
-
-			for (LOOPCOUNTER = 0;
-					ifelse(`$1', `', `src->$3[LOOPCOUNTER]',
-					`', `', `LOOPCOUNTER < SRC(`$1')');
-					++LOOPCOUNTER) {
-				pushdef(`dst', `arr')
-				pushdef(`SRC', `ifelse(`$4', `', `', `', `', `($2)')' defn(`SRC') `[LOOPCOUNTER]')
-				popdef(`add_assoc_bool_ex', `add_next_index_bool($1, $3)')
-				popdef(`add_assoc_string_ex', `add_next_index_string($1, $3)')
-				popdef(`add_assoc_long_ex', `add_next_index_long($1, $3)')
-				popdef(`add_assoc_zval_ex', `add_next_index_zval($1, $3)')
-				DISABLECHECK(`
-					PROCESS(`$2', `$3')
-				')
-				popdef(`add_assoc_zval_ex')
-				popdef(`add_assoc_long_ex')
-				popdef(`add_assoc_string_ex')
-				popdef(`add_assoc_bool_ex')
-				popdef(`SRC')
-				popdef(`dst')
-
-				++LOOPCOUNTER;
-			}
-			add_assoc_zval_ex(dst, ZEND_STRS("$3"), arr);
-		', `
-			dnl find count with NULL
-			ifelse(`$1', `', `
-				size_t count = 0;
-				while (SRC(`$3[count]')) {
-					++count;
-				}
-				++count;
-				pushdef(`STRUCT_COUNT', `count')
-			',
-			`', `', `pushdef(`STRUCT_COUNT', `SRC(`$1')')')
-			ALLOC(`dst->$3', `$2', `STRUCT_COUNT', , `$4')
-			popdef(`STRUCT_COUNT')
-
-			for (LOOPCOUNTER = 0;
-					ifelse(`$1', `', `src->$3[LOOPCOUNTER]',
-					`', `', `LOOPCOUNTER < SRC(`$1')');
-					++LOOPCOUNTER) {
-				DISABLECHECK(`
-					pushdef(`DST', defn(`DST') `[LOOPCOUNTER]')
-					pushdef(`SRC', `ifelse(`$4', `', `', `', `', `($2)')' defn(`SRC') `[LOOPCOUNTER]')
-					PROCESS(`$2', `$3')
-					popdef(`SRC')
-					popdef(`DST')
-				')
-			}
-			dnl the end marker
-			ifelse(`$1', `', `IFCOPY(`DST(`$3[LOOPCOUNTER]') = NULL;')')
-		')dnl IFDASM
-		DONE(`$3')
-	}
-	else {
-		COPYNULL(`$3')
-	}
-')
-dnl }}}
Index: /trunk/const_string_opcodes_php4.x.h
===================================================================
--- /trunk/const_string_opcodes_php4.x.h	(revision 1)
+++ /trunk/const_string_opcodes_php4.x.h	(revision 1)
@@ -0,0 +1,116 @@
+/* size = 112 */
+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/make.inc.example
===================================================================
--- /trunk/make.inc.example	(revision 1)
+++ /trunk/make.inc.example	(revision 1)
@@ -0,0 +1,7 @@
+# copy this file to make.inc before modifying
+PHP4_x_DIR=
+PHP5_0_DIR=
+PHP5_1_DIR=
+PHP6_x_DIR=
+
+PHP_DEVEL_DIR=
Index: /trunk/align.h
===================================================================
--- /trunk/align.h	(revision 1)
+++ /trunk/align.h	(revision 1)
@@ -0,0 +1,18 @@
+#ifndef __ALIGN_H
+#define __ALIGN_H
+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 /* __ALIGN_H */
Index: /trunk/utils.c
===================================================================
--- /trunk/utils.c	(revision 1)
+++ /trunk/utils.c	(revision 1)
@@ -0,0 +1,401 @@
+#include "php.h"
+#include "xcache.h"
+#include "utils.h"
+#ifdef ZEND_ENGINE_2_1
+#include "zend_vm.h"
+#endif
+#include "opcode_spec.h"
+#undef NDEBUG
+#include "assert.h"
+
+xc_compile_result_t *xc_compile_result_init(xc_compile_result_t *cr, /* {{{ */
+		zend_op_array *op_array,
+		HashTable *function_table,
+		HashTable *class_table)
+{
+	if (cr) {
+		cr->alloc = 0;
+	}
+	else {
+		cr = emalloc(sizeof(xc_compile_result_t));
+		cr->alloc = 1;
+	}
+	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) /* {{{ */
+{
+	return xc_compile_result_init(cr, op_array, CG(function_table), CG(class_table));
+}
+/* }}} */
+void xc_compile_result_free(xc_compile_result_t *cr) /* {{{ */
+{
+	if (cr->alloc) {
+		efree(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, applyer TSRMLS_CC);
+	zend_hash_apply_with_argument(cr->class_table, (apply_func_arg_t) xc_apply_cest, 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;
+
+	if (!op_array->done_pass_two) {
+		return 0;
+	}
+
+	opline = op_array->opcodes;
+	end = opline + op_array->last;
+	while (opline < end) {
+#ifdef ZEND_ENGINE_2_1
+		switch (opline->opcode) {
+			case ZEND_JMP:
+				opline->op1.u.opline_num = opline->op1.u.jmp_addr - op_array->opcodes;
+				assert(opline->op1.u.opline_num < op_array->last);
+				break;
+			case ZEND_JMPZ:
+			case ZEND_JMPNZ:
+			case ZEND_JMPZ_EX:
+			case ZEND_JMPNZ_EX:
+				opline->op2.u.opline_num = opline->op2.u.jmp_addr - op_array->opcodes;
+				assert(opline->op2.u.opline_num < op_array->last);
+				break;
+		}
+#endif
+		opline++;
+	}
+	op_array->done_pass_two = 0;
+
+	return 0;
+}
+/* }}} */
+int xc_redo_pass_two(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline, *end;
+
+	if (op_array->done_pass_two) {
+		return 0;
+	}
+
+	/*
+	op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last);
+	op_array->size = op_array->last;
+	*/
+
+	opline = op_array->opcodes;
+	end = opline + op_array->last;
+	while (opline < end) {
+		if (opline->op1.op_type == IS_CONST) {
+			opline->op1.u.constant.is_ref = 1;
+			opline->op1.u.constant.refcount = 2; /* Make sure is_ref won't be reset */
+		}
+		if (opline->op2.op_type == IS_CONST) {
+			opline->op2.u.constant.is_ref = 1;
+			opline->op2.u.constant.refcount = 2;
+		}
+#ifdef ZEND_ENGINE_2_1
+		switch (opline->opcode) {
+			case ZEND_JMP:
+				assert(opline->op1.u.opline_num < op_array->last);
+				opline->op1.u.jmp_addr = op_array->opcodes + opline->op1.u.opline_num;
+				break;
+			case ZEND_JMPZ:
+			case ZEND_JMPNZ:
+			case ZEND_JMPZ_EX:
+			case ZEND_JMPNZ_EX:
+				assert(opline->op2.u.opline_num < op_array->last);
+				opline->op2.u.jmp_addr = op_array->opcodes + opline->op2.u.opline_num;
+				break;
+		}
+		ZEND_VM_SET_OPCODE_HANDLER(opline);
+#endif
+		opline++;
+	}
+
+	op_array->done_pass_two = 1;
+	return 0;
+}
+/* }}} */
+
+static void xc_fix_opcode_ex_znode(int tofix, xc_op_spec_t spec, znode *znode, int type TSRMLS_DC) /* {{{ */
+{
+#ifdef ZEND_ENGINE_2
+	if ((znode->op_type != IS_UNUSED && (spec == OPSPEC_UCLASS || spec == OPSPEC_CLASS)) ||
+			spec == OPSPEC_FETCH) {
+		if (tofix) {
+			switch (znode->op_type) {
+			case IS_VAR:
+			case IS_TMP_VAR:
+				break;
+
+			default:
+				/* TODO: data lost, find a way to keep it */
+				/* assert(znode->op_type == IS_CONST); */
+				znode->op_type = IS_TMP_VAR;
+			}
+		}
+	}
+	switch (znode->op_type) {
+	case IS_TMP_VAR:
+	case IS_VAR:
+		if (tofix) {
+			znode->u.var /= sizeof(temp_variable);
+		}
+		else {
+			znode->u.var *= sizeof(temp_variable);
+		}
+	}
+#endif
+}
+/* }}} */
+
+static void xc_fix_opcode_ex(zend_op_array *op_array, int tofix TSRMLS_DC) /* {{{ */
+{
+	zend_op *opline;
+	int 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, &opline->op1, 0 TSRMLS_CC);
+			xc_fix_opcode_ex_znode(tofix, spec->op2, &opline->op2, 1 TSRMLS_CC);
+			xc_fix_opcode_ex_znode(tofix, spec->res, &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;
+}
+/* }}} */
+
+void xc_install_function(char *filename, zend_function *func, zend_uchar type, char *key, uint len TSRMLS_DC) /* {{{ */
+{
+	if (func->type == ZEND_USER_FUNCTION) {
+		if (zend_u_hash_add(CG(function_table), type, key, len,
+					func, sizeof(zend_op_array),
+					NULL
+					) == FAILURE) {
+			CG(in_compilation) = 1;
+			CG(compiled_filename) = filename;
+			CG(zend_lineno) = ZESW(func->op_array.opcodes[0].lineno, func->op_array.line_start);
+			zend_error(E_ERROR, "Cannot redeclare %s()", key);
+		}
+	}
+}
+/* }}} */
+ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
+{
+	ZESW(void *stored_ce_ptr, );
+	zend_class_entry *cep = CestToCePtr(*cest);
+
+	if (zend_u_hash_add(CG(class_table), type, key, len,
+				cest, sizeof(xc_cest_t),
+				ZESW(&stored_ce_ptr, NULL)
+				) == FAILURE) {
+		CG(in_compilation) = 1;
+		CG(compiled_filename) = filename;
+		CG(zend_lineno) = ZESW(0, cep->line_start);
+		zend_error(E_ERROR, "Cannot redeclare class %s", (char *) cep->name);
+	}
+	ZESW(return (xc_cest_t *) stored_ce_ptr, );
+}
+/* }}} */
+
+/* sandbox {{{ */
+#undef TG
+#undef OG
+#define TG(x) (sandbox->tmp_##x)
+#define OG(x) (sandbox->orig_##x)
+/* }}} */
+xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) /* {{{ */
+{
+	if (sandbox) {
+		memset(sandbox, 0, sizeof(sandbox[0]));
+	}
+	else {
+		ECALLOC_ONE(sandbox);
+		sandbox->alloc = 1;
+	}
+	memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files)));
+	memcpy(&OG(open_files), &CG(open_files), sizeof(CG(open_files)));
+
+	OG(function_table) = CG(function_table);
+	CG(function_table) = &TG(function_table);
+
+	assert(EG(class_table) == CG(class_table));
+
+	OG(class_table) = CG(class_table);
+	CG(class_table) = &TG(class_table);
+	EG(class_table) = CG(class_table);
+
+	TG(included_files) = &EG(included_files);
+	TG(open_files)     = &CG(open_files);
+
+	zend_llist_init(TG(open_files), sizeof(zend_file_handle), (void (*)(void *)) zend_file_handle_dtor, 0);
+	zend_hash_init_ex(TG(included_files), 5, NULL, NULL, 0, 1);
+	zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, 0, 0);
+	zend_hash_init_ex(&TG(class_table), 16, NULL, ZEND_CLASS_DTOR, 0, 0);
+
+	sandbox->filename = filename;
+
+	return sandbox;
+}
+/* }}} */
+static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
+{
+	int i;
+	Bucket *b;
+	zend_llist_position lpos;
+	zend_file_handle *handle;
+
+	b = 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), BUCKET_KEY(b), b->nKeyLength TSRMLS_CC);
+		b = b->pListNext;
+	}
+
+	b = TG(class_table).pListHead;
+	/* install class */
+	while (b != NULL) {
+		xc_install_class(sandbox->filename, (xc_cest_t*)b->pData,
+				BUCKET_KEY_TYPE(b), BUCKET_KEY(b), b->nKeyLength TSRMLS_CC);
+		b = b->pListNext;
+	}
+
+	i = 1;
+	zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL);
+	for (handle = zend_llist_get_first_ex(TG(open_files), &lpos);
+			handle;
+			handle = zend_llist_get_next_ex(TG(open_files), &lpos)) {
+		zend_llist_add_element(&OG(open_files), handle);
+	}
+}
+/* }}} */
+void xc_sandbox_free(xc_sandbox_t *sandbox, int install TSRMLS_DC) /* {{{ */
+{
+	/* restore first first install function/class */
+	CG(function_table) = OG(function_table);
+	CG(class_table)    = OG(class_table);
+	EG(class_table)    = CG(class_table);
+
+	if (install) {
+		xc_sandbox_install(sandbox TSRMLS_CC);
+
+		/* no free as it's installed */
+		TG(function_table).pDestructor = NULL;
+		TG(class_table).pDestructor = NULL;
+		TG(open_files)->dtor = NULL;
+	}
+
+	/* destroy all the tmp */
+	zend_hash_destroy(&TG(function_table));
+	zend_hash_destroy(&TG(class_table));
+	zend_hash_destroy(TG(included_files));
+	zend_llist_destroy(TG(open_files));
+
+	/* restore orig here, as EG/CG holded tmp before */
+	memcpy(&EG(included_files), &OG(included_files), sizeof(EG(included_files)));
+	memcpy(&CG(open_files),     &OG(open_files),     sizeof(CG(open_files)));
+
+	if (sandbox->alloc) {
+		efree(sandbox);
+	}
+}
+/* }}} */
Index: /trunk/const_string_opcodes_php6.x.h
===================================================================
--- /trunk/const_string_opcodes_php6.x.h	(revision 1)
+++ /trunk/const_string_opcodes_php6.x.h	(revision 1)
@@ -0,0 +1,155 @@
+/* size = 151 */
+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 */	"UNDEF",
+/* 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 */	"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 */	"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 */	"UNDEF",
+/* 144 */	"ADD_INTERFACE",
+/* 145 */	"UNDEF",
+/* 146 */	"VERIFY_ABSTRACT_CLASS",
+/* 147 */	"ASSIGN_DIM",
+/* 148 */	"ISSET_ISEMPTY_PROP_OBJ",
+/* 149 */	"HANDLE_EXCEPTION",
+/* 150 */	"USER_OPCODE",
+/* 151 */	"U_NORMALIZE"
+};
Index: /trunk/mkopcode.awk
===================================================================
--- /trunk/mkopcode.awk	(revision 1)
+++ /trunk/mkopcode.awk	(revision 1)
@@ -0,0 +1,72 @@
+#!/usr/bin/gawk -f
+# vim:ts=4:sw=4
+# process zend_vm_def.h or zend_compile.h
+BEGIN {
+	FS=" "
+	max = 0;
+	delete opcodes;
+}
+
+/^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|]+)\)/, array)) {
+		print "error unmatch $0";
+		exit;
+	}
+	id = 0 + array[1];
+	name = array[2];
+	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;
+	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/xcache_globals.h
===================================================================
--- /trunk/xcache_globals.h	(revision 1234)
+++ /trunk/xcache_globals.h	(revision 1)
@@ -1,47 +1,15 @@
-#include "util/xc_stack.h"
 
 ZEND_BEGIN_MODULE_GLOBALS(xcache)
-	zend_bool initial_compile_file_called; /* true if origin_compile_file is called */
 	zend_bool cacher;      /* true if enabled */
-	zend_bool stat;
-	zend_bool experimental;
 #ifdef HAVE_XCACHE_OPTIMIZER
 	zend_bool optimizer;   /* true if enabled */
 #endif
-#ifdef HAVE_XCACHE_COVERAGER
-	zend_bool coverager;
-	zend_bool coverager_autostart;
-	zend_bool coverager_started;
+#ifdef HAVE_XCACHE_COVERAGE
+	zend_bool coveragedumper;
 	HashTable *coverages;  /* coverages[file][line] = times */
 #endif
-#ifndef ZEND_WIN32
-	pid_t holds_pid;
-#endif
 	xc_stack_t *php_holds;
-	zend_uint php_holds_size;
 	xc_stack_t *var_holds;
-	zend_uint var_holds_size;
 	time_t request_time;
-	long   var_ttl;
-#ifdef IS_UNCODE
-	zval uvar_namespace_hard;
-	zval uvar_namespace_soft;
-#endif
-	zval var_namespace_hard;
-	zval var_namespace_soft;
-
-	zend_llist gc_op_arrays;
-#ifdef ZEND_ACC_ALIAS
-	zend_llist gc_class_entries;
-#endif
-
-#ifdef HAVE_XCACHE_CONSTANT
-	HashTable internal_constant_table;
-#endif
-	HashTable internal_function_table;
-	HashTable internal_class_table;
-	zend_bool internal_table_copied;
-
-	void *sandbox;
 ZEND_END_MODULE_GLOBALS(xcache)
 
Index: /trunk/stack.c
===================================================================
--- /trunk/stack.c	(revision 1)
+++ /trunk/stack.c	(revision 1)
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <assert.h>
+#include "stack.h"
+typedef xc_stack_t* S;
+
+void xc_stack_init(S stack)
+{
+	stack->cnt = 0;
+	stack->size = 8;
+	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_size(S stack)
+{
+	assert(stack != NULL);
+	return stack->cnt;
+}
+
+void xc_stack_reverse(S stack)
+{
+	typeof(stack->cnt) 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/utils.h
===================================================================
--- /trunk/utils.h	(revision 1)
+++ /trunk/utils.h	(revision 1)
@@ -0,0 +1,48 @@
+#include "php.h"
+
+typedef struct {
+	int alloc;
+	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);
+
+/* installer */
+void xc_install_function(char *filename, zend_function *func, zend_uchar type, char *key, uint len TSRMLS_DC);
+ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, void *key, uint len TSRMLS_DC);
+
+/* sandbox */
+typedef struct {
+	int alloc;
+	char *filename;
+
+	HashTable orig_included_files;
+	zend_llist orig_open_files;
+	HashTable *tmp_included_files;
+	zend_llist *tmp_open_files;
+
+	HashTable *orig_function_table;
+	HashTable *orig_class_table;
+	HashTable tmp_function_table;
+	HashTable tmp_class_table;
+} xc_sandbox_t;
+
+xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC);
+void xc_sandbox_free(xc_sandbox_t *sandbox, int install TSRMLS_DC);
Index: /trunk/Makefile.frag
===================================================================
--- /trunk/Makefile.frag	(revision 1015)
+++ /trunk/Makefile.frag	(revision 1)
@@ -1,35 +1,28 @@
 XCACHE_PROC_SRC=$(srcdir)/processor/main.m4
-XCACHE_PROC_OUT=$(builddir)/processor.out.c
-XCACHE_PROC_C=$(builddir)/xc_processor.c.h
-XCACHE_PROC_H=$(builddir)/xc_processor.h
+XCACHE_PROC_OUT=$(builddir)/processor.out
+XCACHE_PROC_C=$(builddir)/processor_real.c
+XCACHE_PROC_H=$(builddir)/processor.h
 XCACHE_INCLUDES_SRC=$(srcdir)/includes.c
 XCACHE_INCLUDES_I=$(builddir)/includes.i
-XCACHE_STRUCTINFO_OUT=$(builddir)/structinfo.m4
+XCACHE_STRUCT_OUT=$(builddir)/structinfo.m4
 
-$(XCACHE_INCLUDES_I):
-	$(CC) -I. -I$(srcdir) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -E $(XCACHE_INCLUDES_SRC) -o $(XCACHE_INCLUDES_I)
+$(XCACHE_INCLUDES_I): $(XCACHE_INCLUDES_SRC) $(srcdir)/xcache.h
+	$(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)/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)/gen_structinfo.awk < $(XCACHE_INCLUDES_I) > $(XCACHE_STRUCTINFO_OUT).tmp && mv $(XCACHE_STRUCTINFO_OUT).tmp $(XCACHE_STRUCTINFO_OUT)
+$(XCACHE_STRUCT_OUT): $(XCACHE_INCLUDES_I) $(srcdir)/mkstructinfo.awk
+	$(AWK) -f $(srcdir)/mkstructinfo.awk < $(XCACHE_INCLUDES_I) > $(XCACHE_STRUCT_OUT)
 
-$(XCACHE_PROC_OUT): $(XCACHE_PROC_SRC) $(XCACHE_STRUCTINFO_OUT) $(XCACHE_PROC_SOURCES)
-	$(M4) -D srcdir=$(XCACHE_BACKTICK)"$(srcdir)'" -D builddir=$(XCACHE_BACKTICK)"$(builddir)'" $(XCACHE_ENABLE_TEST) $(XCACHE_PROC_SRC) > $(XCACHE_PROC_OUT).tmp
-	mv $(XCACHE_PROC_OUT).tmp $(XCACHE_PROC_OUT)
+$(XCACHE_PROC_OUT): $(XCACHE_PROC_SRC) $(XCACHE_STRUCT_OUT) $(XCACHE_PROC_SOURCES)
+	m4 -I$(srcdir)/processor/ -I$(builddir)/ -I$(srcdir)/ $(XCACHE_ENABLE_TEST) -E $(XCACHE_PROC_SRC) > $(XCACHE_PROC_OUT).tmp && mv -f $(XCACHE_PROC_OUT).tmp $(XCACHE_PROC_OUT)
 
 $(XCACHE_PROC_H): $(XCACHE_PROC_OUT)
-	$(GREP) "export: " $(XCACHE_PROC_OUT) | $(SED) "s/.*export:\(.*\):export.*/\1/g" > $(XCACHE_PROC_H)
-	-$(XCACHE_INDENT) < $(XCACHE_PROC_H) > $(XCACHE_PROC_H).tmp && mv $(XCACHE_PROC_H).tmp $(XCACHE_PROC_H)
+	grep -F 'export: ' $(XCACHE_PROC_OUT) | sed -r 's/.*export:(.*):export.*/\1/g' | $(XCACHE_INDENT) > $(XCACHE_PROC_H).tmp && mv -f $(XCACHE_PROC_H).tmp $(XCACHE_PROC_H)
 
 $(XCACHE_PROC_C): $(XCACHE_PROC_OUT) $(XCACHE_PROC_H)
-	cp $(XCACHE_PROC_OUT) $(XCACHE_PROC_C)
-	-$(XCACHE_INDENT) < $(XCACHE_PROC_OUT) > $(XCACHE_PROC_C).tmp && mv $(XCACHE_PROC_C).tmp $(XCACHE_PROC_C)
+	cat $(XCACHE_PROC_OUT) | $(XCACHE_INDENT) > $(XCACHE_PROC_C).tmp && mv -f $(XCACHE_PROC_C).tmp $(XCACHE_PROC_C)
 
-xcachesvnclean: clean
-	-svn propget svn:ignore . > .svnignore.tmp 2>/dev/null && mv .svnignore.tmp .svnignore
-	cat .svnignore | grep -v devel | grep -v svnignore | grep -v ^Makefile | grep -v ^config.nice | xargs rm -rf
+$(builddir)/processor.lo: $(XCACHE_PROC_C) $(XCACHE_PROC_H) $(srcdir)/processor.c
 
-xcachetest: all
-	$(SED) "s#\\./modules/#$(top_builddir)/modules/#" < $(srcdir)/xcache-test.ini > $(top_builddir)/tmp-php.ini
-	TEST_PHP_SRCDIR=$(srcdir) $(srcdir)/run-xcachetest $(TESTS) $(TEST_ARGS) -c $(top_builddir)/tmp-php.ini
-	$(srcdir)/run-xcachetest $(TESTS) $(TEST_ARGS) -c $(top_builddir)/tmp-php.ini
+$(builddir)/disassembler.lo: $(XCACHE_PROC_H) $(srcdir)/processor.c
+
+$(builddir)/xcache.lo: $(XCACHE_PROC_H) $(srcdir)/myshm.h $(srcdir)/stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.c
Index: /trunk/stack.h
===================================================================
--- /trunk/stack.h	(revision 1)
+++ /trunk/stack.h	(revision 1)
@@ -0,0 +1,17 @@
+
+typedef struct {
+	void **data;
+	int cnt;
+	int size;
+} xc_stack_t;
+
+#define S xc_stack_t*
+void xc_stack_init(S stack);
+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_size(S stack);
+void xc_stack_reverse(S stack);
+#undef S
Index: /trunk/mkopcode_spec.awk
===================================================================
--- /trunk/mkopcode_spec.awk	(revision 1)
+++ /trunk/mkopcode_spec.awk	(revision 1)
@@ -0,0 +1,39 @@
+#!/usr/bin/gawk -f
+# vim:ts=4:sw=4
+# process eaccelerator/opcodes.c
+BEGIN {
+	FS=" "
+	max = 0;
+	started = 0
+	delete opcodes;
+}
+
+/OPDEF/ {
+	if (started) {
+		sub(/".*"/, "")
+		if (!match($0, /EXT_([^ |]+).*OP[1S]_([^ |]+).*OP2_([^ |]+).*RES_([^ |)]+).*/, array)) {
+			print "error" $0
+			exit
+		}
+		printf "\tOPSPEC(%10s, %10s, %10s, %10s)\n", array[1], array[2], array[3], array[4]
+		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/disassembler.c
===================================================================
--- /trunk/disassembler.c	(revision 1)
+++ /trunk/disassembler.c	(revision 1)
@@ -0,0 +1,154 @@
+#include "disassembler.h"
+#include "xcache.h"
+#include "utils.h"
+#include "processor.h"
+
+#define return_value dst
+
+static void xc_dasm(zval *dst, zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	Bucket *b;
+	zval *zv, *list;
+	xc_compile_result_t cr;
+	int bufsize = 2;
+	char *buf;
+	int keysize;
+
+	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(dst);
+
+	ALLOC_INIT_ZVAL(zv);
+	array_init(zv);
+	xc_dasm_zend_op_array(zv, op_array TSRMLS_CC);
+	add_assoc_zval_ex(dst, ZEND_STRS("op_array"), zv);
+
+	ALLOC_INIT_ZVAL(list);
+	array_init(list);
+	xc_dasm_HashTable_zend_function(list, CG(function_table) TSRMLS_CC);
+	add_assoc_zval_ex(dst, ZEND_STRS("function_table"), list);
+	
+	buf = emalloc(bufsize);
+	ALLOC_INIT_ZVAL(list);
+	array_init(list);
+	for (b = CG(class_table)->pListHead; b; b = b->pListNext) {
+		ALLOC_INIT_ZVAL(zv);
+		array_init(zv);
+		xc_dasm_zend_class_entry(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(b), keysize);
+		buf[keysize - 2] = buf[keysize - 1] = ""[0];
+		keysize = b->nKeyLength;
+#ifdef IS_UNICODE
+		if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
+			if (buf[0] == ""[0] && buf[1] == ""[0]) {
+				keysize ++;
+			}
+		} else
+#endif
+		{
+			if (buf[0] == ""[0]) {
+				keysize ++;
+			}
+		}
+		add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), buf, b->nKeyLength, zv);
+	}
+	efree(buf);
+	add_assoc_zval_ex(dst, ZEND_STRS("class_table"), list);
+
+	/*xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);*/
+	xc_compile_result_free(&cr);
+
+	return;
+}
+/* }}} */
+void xc_dasm_string(zval *dst, zval *source TSRMLS_DC) /* {{{ */
+{
+	int catched;
+	zend_op_array *op_array = NULL;
+	xc_sandbox_t sandbox;
+	char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
+
+	xc_sandbox_init(&sandbox, eval_name TSRMLS_CC);
+
+	catched = 0;
+	zend_try {
+		op_array = compile_string(source, eval_name TSRMLS_CC);
+	} zend_catch {
+		catched = 1;
+	} zend_end_try();
+
+	if (catched || !op_array) {
+		goto err_compile;
+	}
+
+	xc_dasm(dst, op_array TSRMLS_CC);
+
+	/* free */
+	efree(eval_name);
+	destroy_op_array(op_array TSRMLS_CC);
+	efree(op_array);
+	xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
+	return;
+
+err_compile:
+	efree(eval_name);
+	xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
+
+	RETURN_FALSE;
+}
+/* }}} */
+void xc_dasm_file(zval *dst, const char *filename TSRMLS_DC) /* {{{ */
+{
+	int catched;
+	zend_op_array *op_array = NULL;
+	xc_sandbox_t sandbox;
+	zval *zfilename;
+
+	MAKE_STD_ZVAL(zfilename);
+	zfilename->value.str.val = estrdup(filename);
+	zfilename->value.str.len = strlen(filename);
+	zfilename->type = IS_STRING;
+
+	xc_sandbox_init(&sandbox, zfilename->value.str.val TSRMLS_CC);
+
+	catched = 0;
+	zend_try {
+		op_array = compile_filename(ZEND_REQUIRE, zfilename TSRMLS_CC);
+	} zend_catch {
+		catched = 1;
+	} zend_end_try();
+
+	if (catched || !op_array) {
+		goto err_compile;
+	}
+
+	xc_dasm(dst, op_array TSRMLS_CC);
+
+	/* free */
+	destroy_op_array(op_array TSRMLS_CC);
+	efree(op_array);
+	xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
+	zval_dtor(zfilename);
+	FREE_ZVAL(zfilename);
+	return;
+
+err_compile:
+	xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
+
+	zval_dtor(zfilename);
+	FREE_ZVAL(zfilename);
+	RETURN_FALSE;
+}
+/* }}} */
Index: /trunk/processor.c
===================================================================
--- /trunk/processor.c	(revision 1)
+++ /trunk/processor.c	(revision 1)
@@ -0,0 +1,1 @@
+#include "processor_real.c"
Index: /trunk/disassembler.h
===================================================================
--- /trunk/disassembler.h	(revision 1)
+++ /trunk/disassembler.h	(revision 1)
@@ -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/optimizer.c
===================================================================
--- /trunk/optimizer.c	(revision 1)
+++ /trunk/optimizer.c	(revision 1)
@@ -0,0 +1,27 @@
+#include "optimizer.h"
+#include "utils.h"
+
+static int xc_optimize_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	if (op_array->type != ZEND_USER_FUNCTION) {
+		return 0;
+	}
+	//xc_undo_pass_two(op_array TSRMLS_CC);
+	//xc_redo_pass_two(op_array TSRMLS_CC);
+	//xc_dprint_zend_op_array(op_array, 0);
+	return 0;
+}
+/* }}} */
+void xc_optimize(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_undo_pass_two TSRMLS_CC);
+	xc_apply_op_array(&cr, (apply_func_t) xc_optimize_op_array TSRMLS_CC);
+	xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);
+
+	xc_compile_result_free(&cr);
+}
+/* }}} */
Index: /trunk/opcode_spec.c
===================================================================
--- /trunk/opcode_spec.c	(revision 1)
+++ /trunk/opcode_spec.c	(revision 1)
@@ -0,0 +1,41 @@
+#include "xcache.h"
+#include "opcode_spec.h"
+#include "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 "opcode_spec_def.h"
+
+int 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)
+{
+	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) };
+
+int 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/test.php
===================================================================
--- /trunk/test.php	(revision 1)
+++ /trunk/test.php	(revision 1)
@@ -0,0 +1,2 @@
+<?php
+xcache_coredump();
Index: /trunk/phpdc.phpr
===================================================================
--- /trunk/phpdc.phpr	(revision 1)
+++ /trunk/phpdc.phpr	(revision 1)
@@ -0,0 +1,30 @@
+#!/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[1])) {
+	$dc->decompileFile($argv[1]);
+}
+else {
+	$phpcode = '';
+	if (!defined('stdin')) {
+		define('stdin', fopen('php://stdin', 'rb'));
+	}
+	while (!feof(stdin)) {
+		$phpcode .= fgets(stdin);
+	}
+	$dc->decompileFile($phpcode);
+}
+$dc->output();
+
Index: /trunk/optimizer.h
===================================================================
--- /trunk/optimizer.h	(revision 1)
+++ /trunk/optimizer.h	(revision 1)
@@ -0,0 +1,4 @@
+#include "php.h"
+#include "xcache.h"
+
+void xc_optimize(zend_op_array *op_array TSRMLS_DC);
Index: /trunk/lock.c
===================================================================
--- /trunk/lock.c	(revision 1)
+++ /trunk/lock.c	(revision 1)
@@ -0,0 +1,129 @@
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+
+#include <php.h>
+#ifndef ZEND_WIN32
+typedef int HANDLE;
+#endif
+#include "lock.h"
+
+struct _xc_lock_t {
+	HANDLE fd;
+	char *pathname;
+};
+
+#ifndef ZEND_WIN32
+#	include <unistd.h>
+#	include <fcntl.h>
+#	include <errno.h>
+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;
+}
+/* }}} */
+#define LCK_WR F_WRLCK
+#define LCK_RD F_RDLCK
+#define LCK_UN F_UNLCK
+#define LCK_NB 0
+#else
+
+#	include <win32/flock.h>
+#	include <io.h>
+#	include <fcntl.h>
+#	include <sys/types.h>
+#	include <sys/stat.h>
+#	define errno GetLastError()
+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)fd, 0, 1, 0, &offset);
+	}
+	else {
+		return LockFileEx((HANDLE)fd, type, 0, 1, 0, &offset);
+	}
+}
+/* }}} */
+#define LCK_WR LOCKFILE_EXCLUSIVE_LOCK
+#define LCK_RD 0
+#define LCK_UN 0
+#define LCK_NB LOCKFILE_FAIL_IMMEDIATELY
+#endif
+
+xc_lock_t *xc_fcntl_init(const char *pathname) /* {{{ */
+{
+	HANDLE fd;
+	char myname[sizeof("/tmp/.xcache.lock") - 1 + 20];
+
+	if (pathname == NULL) {
+		static int i = 0;
+		snprintf(myname, sizeof(myname) - 1, "/tmp/.xcache.%d.%d.lock", (int) getuid(), i ++);
+		pathname = myname;
+	}
+
+	fd = open(pathname, O_RDWR|O_CREAT, 0666);
+
+	if (fd > 0) {
+		xc_lock_t *lck = malloc(sizeof(lck[0]));
+		int size;
+
+#ifndef __CYGWIN__
+		unlink(pathname);
+#endif
+		lck->fd = fd;
+		size = strlen(pathname) + 1;
+		lck->pathname = malloc(size);
+		memcpy(lck->pathname, pathname, size);
+		return lck;
+	}
+	else {
+		fprintf(stderr, "xc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
+		return NULL;
+	}
+}
+/* }}} */
+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) {
+		fprintf(stderr, "xc_fcntl_lock failed errno:%d", errno);
+	}
+}
+/* }}} */
+void xc_fcntl_rdlock(xc_lock_t *lck) /* {{{ */
+{   
+	if (dolock(lck, LCK_RD) < 0) {
+		fprintf(stderr, "xc_fcntl_lock failed errno:%d", errno);
+	}
+}
+/* }}} */
+void xc_fcntl_unlock(xc_lock_t *lck) /* {{{ */
+{   
+	if (dolock(lck, LCK_UN) < 0) {
+		fprintf(stderr, "xc_fcntl_unlock failed errno:%d", errno);
+	}
+}
+/* }}} */
Index: /trunk/opcode_spec.h
===================================================================
--- /trunk/opcode_spec.h	(revision 1)
+++ /trunk/opcode_spec.h	(revision 1)
@@ -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) } 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);
+int xc_get_opcode_spec_count();
+int xc_get_op_spec_count();
+const char *xc_get_op_spec(zend_uchar spec);
Index: /trunk/make.devel
===================================================================
--- /trunk/make.devel	(revision 1)
+++ /trunk/make.devel	(revision 1)
@@ -0,0 +1,43 @@
+#!/usr/bin/make -if
+# vim:syntax=make
+SELF=MAKELEVEL=0 ./make.devel
+
+# You should copy make.inc from make.inc.default
+include make.inc
+
+all: opcode_spec_def const_string tags
+
+clean: clean_const_string
+	rm -f tags opcode_spec_def.h
+
+const_string:
+	@-$(SELF) const_string_opcodes_php4.x.h
+	@-$(SELF) const_string_opcodes_php5.0.h
+	@-$(SELF) const_string_opcodes_php5.1.h
+	@-$(SELF) const_string_opcodes_php6.x.h
+
+clean_const_string:
+	rm -f const_string_opcodes_php4.x.h const_string_opcodes_php5.0.h const_string_opcodes_php5.1.h const_string_opcodes_php6.x.h
+
+const_string_opcodes_php4.x.h: $(PHP4_x_DIR)/Zend/zend_compile.h
+	./mkopcode.awk <       $(PHP4_x_DIR)/Zend/zend_compile.h > const_string_opcodes_php4.x.h
+
+const_string_opcodes_php5.0.h: $(PHP5_0_DIR)/Zend/zend_vm_def.h
+	./mkopcode.awk <       $(PHP5_0_DIR)/Zend/zend_vm_def.h  > const_string_opcodes_php5.0.h
+
+const_string_opcodes_php5.1.h: $(PHP5_1_DIR)/Zend/zend_vm_def.h
+	./mkopcode.awk <       $(PHP5_1_DIR)/Zend/zend_vm_def.h  > const_string_opcodes_php5.1.h
+
+const_string_opcodes_php6.x.h: $(PHP6_x_DIR)/Zend/zend_vm_def.h
+	./mkopcode.awk <       $(PHP6_x_DIR)/Zend/zend_vm_def.h  > const_string_opcodes_php6.x.h
+
+tags:
+	test -d $(PHP_DEVEL_DIR) && ctags -R . $(PHP_DEVEL_DIR)/main $(PHP_DEVEL_DIR)/Zend $(PHP_DEVEL_DIR)/TSRM $(PHP_DEVEL_DIR)/ext/standard || ctags -R .
+
+opcode_spec_def:
+	@-$(SELF) opcode_spec_def.h
+
+opcode_spec_def.h: $(EA_DIR)/opcodes.c
+	./mkopcode_spec.awk < $(EA_DIR)/opcodes.c > opcode_spec_def.h \
+
+.PHONY: const_string opcode_spec_def
Index: /trunk/xcache.c
===================================================================
--- /trunk/xcache.c	(revision 1230)
+++ /trunk/xcache.c	(revision 1)
@@ -1,2 +1,5 @@
+
+#undef DEBUG
+
 /* {{{ macros */
 #include <stdlib.h>
@@ -4,54 +7,816 @@
 #include <string.h>
 
+#include <malloc.h>
 #include <signal.h>
-
-#include "xcache.h"
-
-#ifdef HAVE_XCACHE_OPTIMIZER
-#	include "mod_optimizer/xc_optimizer.h"
-#endif
-#ifdef HAVE_XCACHE_CACHER
-#	include "mod_cacher/xc_cacher.h"
-#endif
-#ifdef HAVE_XCACHE_COVERAGER
-#	include "mod_coverager/xc_coverager.h"
-#endif
-#ifdef HAVE_XCACHE_DISASSEMBLER
-#	include "mod_disassembler/xc_disassembler.h"
-#endif
-
-#include "xcache_globals.h"
-#include "xcache/xc_extension.h"
-#include "xcache/xc_ini.h"
-#include "xcache/xc_const_string.h"
-#include "xcache/xc_opcode_spec.h"
-#include "xcache/xc_utils.h"
-#include "util/xc_stack.h"
 
 #include "php.h"
 #include "ext/standard/info.h"
-#include "ext/standard/php_string.h"
+#include "zend_extensions.h"
 #include "SAPI.h"
+
+#include "xcache.h"
+#include "optimizer.h"
+#include "coverage.h"
+#include "disassembler.h"
+#include "align.h"
+#include "stack.h"
+#include "xcache_globals.h"
+#include "processor.h"
+#include "utils.h"
+#include "const_string.h"
+#include "opcode_spec.h"
+
+#ifdef DEBUG
+#	undef NDEBUG
+#	undef inline
+#	define inline
+#else
+#	define NDEBUG
+#endif
+#include <assert.h>
+
+#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
+#define LOCK(x) xc_lock(x->lck)
+#define UNLOCK(x) xc_unlock(x->lck)
+#define ENTER_LOCK(x) do { \
+	int catched = 0; \
+	xc_lock(x->lck); \
+	zend_try { \
+		do
+#define LEAVE_LOCK(x) \
+		while (0); \
+	} zend_catch { \
+		catched = 1; \
+	} zend_end_try(); \
+	xc_unlock(x->lck); \
+} while(0)
 /* }}} */
 
 /* {{{ globals */
+static char *xc_mmap_path = NULL;
 static char *xc_coredump_dir = NULL;
-#ifdef ZEND_WIN32
-static zend_ulong xc_coredump_type = 0;
-#endif
-static zend_bool xc_disable_on_crash = 0;
-
-static zend_compile_file_t *old_compile_file = NULL;
-
-zend_bool xc_test = 0;
-
-ZEND_DECLARE_MODULE_GLOBALS(xcache)
-
-/* }}} */
-
-static zend_op_array *xc_check_initial_compile_file(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */
-{
-	XG(initial_compile_file_called) = 1;
-	return old_compile_file(h, type TSRMLS_CC);
+
+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};
+
+/* total size */
+static zend_ulong xc_php_size  = 0;
+static zend_ulong xc_var_size  = 0;
+
+static xc_cache_t **xc_php_caches = NULL;
+static xc_cache_t **xc_var_caches = NULL;
+
+static zend_bool xc_initized = 0;
+static zend_compile_file_t *origin_compile_file;
+
+static zend_bool xc_test = 0;
+static zend_bool xc_readonly_protection = 0;
+
+static zend_bool xc_module_gotup = 0;
+static zend_bool xc_zend_extension_gotup = 0;
+#if !COMPILE_DL_XCACHE
+#	define zend_extension_entry xcache_zend_extension_entry
+#endif
+ZEND_DLEXPORT zend_extension zend_extension_entry;
+ZEND_DECLARE_MODULE_GLOBALS(xcache);
+/* }}} */
+
+/* any function in *_dmz is only safe be called within locked(single thread) area */
+
+static inline int xc_entry_equal_dmz(xc_entry_t *a, xc_entry_t *b) /* {{{ */
+{
+	/* this function isn't required but can be in dmz */
+
+	if (a->type != b->type) {
+		return 0;
+	}
+	switch (a->type) {
+		case XC_TYPE_PHP:
+#ifdef HAVE_INODE
+			do {
+				xc_entry_data_php_t *ap = a->data.php;
+				xc_entry_data_php_t *bp = b->data.php;
+				return ap->inode == bp->inode
+					&& ap->device == bp->device;
+			} while(0);
+#endif
+			/* fall */
+
+		case XC_TYPE_VAR:
+			do {
+#ifdef IS_UNICODE
+				if (a->name_type == IS_UNICODE) {
+					if (a->name.ustr.len != b->name.ustr.len) {
+						return 0;
+					}
+					return memcmp(a->name.ustr.val, b->name.ustr.val, (a->name.ustr.len + 1) * sizeof(UChar)) == 0;
+				}
+				else {
+					return memcmp(a->name.str.val, b->name.str.val, a->name.str.len + 1) == 0;
+				}
+#else
+				return memcmp(a->name.str.val, b->name.str.val, a->name.str.len + 1) == 0;
+#endif
+
+			} while(0);
+		default:
+			assert(0);
+	}
+	return 0;
+}
+/* }}} */
+static void xc_entry_free_dmz(volatile xc_entry_t *xce) /* {{{ */
+{
+	xc_mem_free(xce->cache->mem, (xc_entry_t *)xce);
+}
+/* }}} */
+static void xc_entry_add_dmz(xc_entry_t *xce) /* {{{ */
+{
+	xc_entry_t **head = &(xce->cache->entries[xce->hvalue]);
+	xce->next = *head;
+	*head = xce;
+}
+/* }}} */
+static xc_entry_t *xc_entry_store_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */
+{
+	xc_entry_t *stored_xce;
+
+	xce->hits  = 0;
+	xce->ctime = XG(request_time);
+	xce->atime = XG(request_time);
+	stored_xce = xc_processor_store_xc_entry_t(xce TSRMLS_CC);
+	if (stored_xce) {
+		xc_entry_add_dmz(stored_xce);
+		return stored_xce;
+	}
+	else {
+		xce->cache->ooms ++;
+		return NULL;
+	}
+}
+/* }}} */
+static void xc_entry_remove_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */
+{
+	xc_entry_t **last = &(xce->cache->entries[xce->hvalue]);
+	xc_entry_t *p;
+	for (p = *last; p; last = &(p->next), p = p->next) {
+		if (xc_entry_equal_dmz(xce, p)) {
+			*last = p->next;
+			if (p->refcount == 0) {
+				xc_entry_free_dmz(p);
+			}
+			else {
+				p->next = p->cache->deletes;
+				p->cache->deletes = p;
+				p->dtime = XG(request_time);
+			}
+			return;
+		}
+	}
+	assert(0);
+}
+/* }}} */
+static xc_entry_t *xc_entry_find_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */
+{
+	xc_entry_t *p;
+	for (p = xce->cache->entries[xce->hvalue]; p; p = p->next) {
+		if (xc_entry_equal_dmz(xce, p)) {
+			if (p->type == XC_TYPE_VAR || /* PHP */ p->data.php->mtime == xce->data.php->mtime) {
+				p->hits ++;
+				p->atime = XG(request_time);
+				return p;
+			}
+			else {
+				xc_entry_remove_dmz(p TSRMLS_CC);
+				return NULL;
+			}
+		}
+	}
+	return NULL;
+}
+/* }}} */
+static void xc_entry_hold_php_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */
+{
+	xce->refcount ++;
+	xc_stack_push(&XG(php_holds)[xce->cache->cacheid], (void *)xce);
+}
+/* }}} */
+#if 0
+static void xc_entry_hold_var_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */
+{
+	xce->refcount ++;
+	xc_stack_push(&XG(var_holds)[xce->cache->cacheid], (void *)xce);
+}
+/* }}} */
+#endif
+
+/* helper functions for user functions */
+static void xc_fillinfo_dmz(xc_cache_t *cache, zval *return_value TSRMLS_DC) /* {{{ */
+{
+	zval *blocks;
+	const xc_block_t *b;
+#ifndef NDEBUG
+	xc_memsize_t avail = 0;
+#endif
+	xc_mem_t *mem = cache->mem;
+	int i, c, count;
+	xc_entry_t *e;
+
+	add_assoc_long_ex(return_value, ZEND_STRS("slots"),     cache->hentry->size);
+	add_assoc_long_ex(return_value, ZEND_STRS("compiling"), cache->compiling);
+	add_assoc_long_ex(return_value, ZEND_STRS("misses"),    cache->misses);
+	add_assoc_long_ex(return_value, ZEND_STRS("hits"),      cache->hits);
+	add_assoc_long_ex(return_value, ZEND_STRS("clogs"),     cache->clogs);
+	add_assoc_long_ex(return_value, ZEND_STRS("ooms"),      cache->ooms);
+
+	count = 0;
+	for (i = 0, c = cache->hentry->size; i < c; i ++) {
+		for (e = cache->entries[i]; e; e = e->next) {
+			count ++;
+		}
+	}
+	add_assoc_long_ex(return_value, ZEND_STRS("cached"), count);
+
+	count = 0;
+	for (e = cache->deletes; e; e = e->next) {
+		count ++;
+	}
+	add_assoc_long_ex(return_value, ZEND_STRS("deleted"), count);
+
+	MAKE_STD_ZVAL(blocks);
+	array_init(blocks);
+
+	add_assoc_long_ex(return_value, ZEND_STRS("size"),  xc_mem_size(mem));
+	add_assoc_long_ex(return_value, ZEND_STRS("avail"), xc_mem_avail(mem));
+	add_assoc_bool_ex(return_value, ZEND_STRS("can_readonly"), xc_readonly_protection);
+
+	for (b = xc_mem_freeblock_first(mem); b; b = xc_mem_freeblock_next(b)) {
+		zval *bi;
+
+		MAKE_STD_ZVAL(bi);
+		array_init(bi);
+
+		add_assoc_long_ex(bi, ZEND_STRS("size"),   xc_mem_block_size(b));
+		add_assoc_long_ex(bi, ZEND_STRS("offset"), xc_mem_block_offset(mem, b));
+		add_next_index_zval(blocks, bi);
+#ifndef NDEBUG
+		avail += b->size;
+#endif
+	}
+	add_assoc_zval_ex(return_value, ZEND_STRS("free_blocks"), blocks);
+	assert(avail == xc_mem_avail(mem));
+}
+/* }}} */
+static void xc_fillentry_dmz(xc_entry_t *entry, int del, zval *list TSRMLS_DC) /* {{{ */
+{
+	zval* ei;
+	xc_entry_data_php_t *php;
+	xc_entry_data_var_t *var;
+
+	ALLOC_INIT_ZVAL(ei);
+	array_init(ei);
+
+	add_assoc_long_ex(ei, ZEND_STRS("size"),     entry->size);
+	add_assoc_long_ex(ei, ZEND_STRS("refcount"), entry->refcount);
+	add_assoc_long_ex(ei, ZEND_STRS("hits"),     entry->hits);
+	add_assoc_long_ex(ei, ZEND_STRS("ctime"),    entry->ctime);
+	add_assoc_long_ex(ei, ZEND_STRS("atime"),    entry->atime);
+	add_assoc_long_ex(ei, ZEND_STRS("dtime"),    entry->dtime);
+#ifdef IS_UNICODE
+	do {
+		zval *zv;
+		ALLOC_INIT_ZVAL(zv);
+		switch (entry->name_type) {
+			case IS_UNICODE:
+					ZVAL_UNICODEL(zv, entry->name.ustr.val, entry->name.ustr.len, 1);
+				break;
+			case IS_STRING:
+				ZVAL_STRINGL(zv, entry->name.str.val, entry->name.str.len, 1);
+				break;
+			default:
+				assert(0);
+		}
+		zv->type = entry->name_type;
+		add_assoc_zval_ex(ei, ZEND_STRS("name"), zv);
+	} while (0);
+#else
+	add_assoc_stringl_ex(ei, ZEND_STRS("name"), entry->name.str.val, entry->name.str.len + 1, 1);
+#endif
+	switch (entry->type) {
+		case XC_TYPE_PHP:
+			php = entry->data.php;
+			add_assoc_long_ex(ei, ZEND_STRS("sourcesize"),   php->sourcesize);
+#ifdef HAVE_INODE
+			add_assoc_long_ex(ei, ZEND_STRS("device"),       php->device);
+			add_assoc_long_ex(ei, ZEND_STRS("inode"),        php->inode);
+#endif
+			add_assoc_long_ex(ei, ZEND_STRS("mtime"),        php->mtime);
+
+			add_assoc_long_ex(ei, ZEND_STRS("function_cnt"), php->funcinfo_cnt);
+			add_assoc_long_ex(ei, ZEND_STRS("class_cnt"),    php->classinfo_cnt);
+			break;
+		case XC_TYPE_VAR:
+			var = entry->data.var;
+			break;
+
+		default:
+			assert(0);
+	}
+
+	add_next_index_zval(list, ei);
+}
+/* }}} */
+static void xc_filllist_dmz(xc_cache_t *cache, zval *return_value TSRMLS_DC) /* {{{ */
+{
+	zval* list;
+	int i, c;
+	xc_entry_t *e;
+
+	ALLOC_INIT_ZVAL(list);
+	array_init(list);
+
+	for (i = 0, c = cache->hentry->size; i < c; i ++) {
+		for (e = cache->entries[i]; e; e = e->next) {
+			xc_fillentry_dmz(e, 0, list);
+		}
+	}
+	add_assoc_zval(return_value, "cache_list", list);
+
+	ALLOC_INIT_ZVAL(list);
+	array_init(list);
+	for (e = cache->deletes; e; e = e->next) {
+		xc_fillentry_dmz(e, 1, list);
+	}
+	add_assoc_zval(return_value, "deleted_list", list);
+}
+/* }}} */
+
+static zend_op_array *xc_entry_install(xc_entry_t *xce, zend_file_handle *h TSRMLS_DC) /* {{{ */
+{
+	zend_uint i;
+	xc_entry_data_php_t *p = xce->data.php;
+#ifndef ZEND_ENGINE_2
+	/* new ptr which is stored inside CG(class_table) */
+	xc_cest_t **new_cest_ptrs = (xc_cest_t **)do_alloca(sizeof(xc_cest_t*) * p->classinfo_cnt);
+#endif
+
+	/* install function */
+	for (i = 0; i < p->funcinfo_cnt; i ++) {
+		xc_funcinfo_t  *fi = &p->funcinfos[i];
+		xc_install_function(xce->name.str.val, &fi->func,
+				UNISW(0, fi->type), fi->key, fi->key_size TSRMLS_CC);
+	}
+
+	/* install class */
+	for (i = 0; i < p->classinfo_cnt; i ++) {
+		xc_classinfo_t *ci = &p->classinfos[i];
+#ifndef ZEND_ENGINE_2
+		zend_class_entry *ce = CestToCePtr(ci->cest);
+		/* fix pointer to the be which inside class_table */
+		if (ce->parent) {
+			zend_uint class_idx = (/* class_num */ (int) ce->parent) - 1;
+			assert(class_idx < i);
+			ci->cest.parent = new_cest_ptrs[class_idx];
+		}
+		new_cest_ptrs[i] =
+#endif
+		xc_install_class(xce->name.str.val, &ci->cest,
+				UNISW(0, ci->type), ci->key, ci->key_size TSRMLS_CC);
+	}
+
+	i = 1;
+	zend_hash_add(&EG(included_files), xce->name.str.val, xce->name.str.len+1, (void *)&i, sizeof(int), NULL);
+	zend_llist_add_element(&CG(open_files), h);
+
+#ifndef ZEND_ENGINE_2
+	free_alloca(new_cest_ptrs);
+#endif
+	return p->op_array;
+}
+/* }}} */
+static void xc_entry_gc_real(xc_cache_t **caches, int size TSRMLS_DC) /* {{{ */
+{
+	time_t t = XG(request_time);
+	int i;
+	xc_cache_t *cache;
+	typeof(cache->deletes) p, *last;
+
+	for (i = 0; i < size; i ++) {
+		cache = caches[i];
+		ENTER_LOCK(cache) {
+			if (cache->deletes) {
+				last = (typeof(last)) &cache->deletes;
+				for (p = *last; p; p = p->next) {
+					if (t - p->dtime > 3600) {
+						p->refcount = 0;
+						/* issue warning here */
+					}
+					if (p->refcount == 0) {
+						*last = p->next;
+						xc_entry_free_dmz(p);
+					}
+					else {
+						last = &(p->next);
+					}
+				}
+			}
+		} LEAVE_LOCK(cache);
+	}
+}
+/* }}} */
+static void xc_entry_gc(TSRMLS_D) /* {{{ */
+{
+	xc_entry_gc_real(xc_php_caches, xc_php_hcache.size TSRMLS_CC);
+	xc_entry_gc_real(xc_var_caches, xc_var_hcache.size TSRMLS_CC);
+}
+/* }}} */
+static inline void xc_entry_unholds_real(xc_stack_t *holds, xc_cache_t **caches, int cachecount) /* {{{ */
+{
+	int i;
+	xc_stack_t *s;
+	xc_cache_t *cache;
+	xc_entry_t *xce;
+
+	for (i = 0; i < cachecount; i ++) {
+		s = &holds[i];
+		if (xc_stack_size(s)) {
+			cache = ((xc_entry_t *)xc_stack_top(s))->cache;
+			ENTER_LOCK(cache) {
+				while (xc_stack_size(holds)) {
+					xce = (xc_entry_t*) xc_stack_pop(holds);
+					xce->refcount --;
+					assert(xce->refcount >= 0);
+				}
+			} LEAVE_LOCK(cache);
+		}
+	}
+}
+/* }}} */
+static void xc_entry_unholds(TSRMLS_D) /* {{{ */
+{
+	xc_entry_unholds_real(XG(php_holds), xc_php_caches, xc_php_hcache.size);
+	xc_entry_unholds_real(XG(var_holds), xc_var_caches, xc_var_hcache.size);
+}
+/* }}} */
+static int xc_stat(const char *filename, const char *include_path, struct stat *pbuf) /* {{{ */
+{
+	char filepath[1024];
+	char *paths, *path;
+	char *tokbuf;
+	int size = strlen(include_path) + 1;
+	char tokens[] = { DEFAULT_DIR_SEPARATOR, '\0' };
+
+	paths = (char *)do_alloca(size);
+	memcpy(paths, include_path, size);
+
+	for (path = strtok_r(paths, tokens, &tokbuf); path; path = strtok_r(NULL, tokens, &tokbuf)) {
+		if (strlen(path) + strlen(filename) + 1 > 1024) {
+			continue;
+		}
+		snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
+		if (VCWD_STAT(filepath, pbuf) == 0) {
+			free_alloca(paths);
+			return 0;
+		}
+	}
+
+	free_alloca(paths);
+
+	return 1;
+}
+/* }}} */
+
+#define HASH(i) (i)
+#define HASH_USTR_L(t, s, l) HASH(zend_u_inline_hash_func(t, s, (l + 1) * sizeof(UChar)))
+#define HASH_STR_L(s, l) HASH(zend_inline_hash_func(s, l + 1))
+#define HASH_STR(s) HASH_STR_L(s, strlen(s) + 1)
+#define HASH_NUM(n) HASH(n)
+static inline xc_hash_value_t xc_entry_hash_var(xc_entry_t *xce) /* {{{ */
+{
+	return UNISW(, UG(unicode) ? HASH_USTR_L(xce->name_type, (char *)xce->name.ustr.val, xce->name.ustr.len) :)
+		HASH_STR_L(xce->name.str.val, xce->name.str.len);
+}
+/* }}} */
+static inline xc_hash_value_t xc_entry_hash_php(xc_entry_t *xce) /* {{{ */
+{
+#ifdef HAVE_INODE
+	return HASH(xce->data.php->device + xce->data.php->inode);
+#else
+	return xc_entry_hash_var(xce);
+#endif
+}
+/* }}} */
+static int xc_entry_init_key_php(xc_entry_t *xce, char *filename TSRMLS_DC) /* {{{ */
+{
+	struct stat buf, *pbuf;
+	xc_hash_value_t hv;
+	int cacheid;
+	xc_entry_data_php_t *php;
+
+	if (!filename || !SG(request_info).path_translated) {
+		return 0;
+	}
+
+	do {
+		if (strcmp(SG(request_info).path_translated, filename) == 0) {
+			/* sapi has already done this stat() for us */
+			pbuf = sapi_get_stat(TSRMLS_C);
+			if (pbuf) {
+				break;
+			}
+		}
+
+		pbuf = &buf;
+		if (IS_ABSOLUTE_PATH(filename, strlen(filename))) {
+			if (VCWD_STAT(filename, pbuf) != 0) {
+				return 0;
+			}
+		}
+		else {
+			if (xc_stat(filename, PG(include_path), pbuf) != 0) {   
+				return 0;
+			}
+		}
+	} while (0);
+
+	if (XG(request_time) - pbuf->st_mtime < 2) {
+		return 0;
+	}
+
+	UNISW(, xce->name_type = IS_STRING;)
+	xce->name.str.val = filename;
+	xce->name.str.len = strlen(filename);
+
+	php = xce->data.php;
+	php->mtime        = pbuf->st_mtime;
+#ifdef HAVE_INODE
+	php->device       = pbuf->st_dev;
+	php->inode        = pbuf->st_ino;
+#endif
+	php->sourcesize   = pbuf->st_size;
+
+
+	hv = xc_entry_hash_php(xce);
+	cacheid = (hv & xc_php_hcache.mask);
+	xce->cache = xc_php_caches[cacheid];
+	hv >>= xc_php_hcache.bits;
+	xce->hvalue = (hv & xc_php_hentry.mask);
+
+	xce->type = XC_TYPE_PHP;
+	return 1;
+}
+/* }}} */
+static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */
+{
+	xc_sandbox_t sandbox;
+	zend_op_array *op_array;
+	xc_entry_t xce, *stored_xce;
+	xc_entry_data_php_t php;
+	xc_cache_t *cache;
+	zend_bool clogged = 0;
+	zend_bool catched = 0;
+	char *filename;
+
+	if (!xc_initized) {
+		assert(0);
+	}
+
+	if (!XG(cacher)) {
+		op_array = origin_compile_file(h, type TSRMLS_CC);
+#ifdef HAVE_XCACHE_OPTIMIZER
+		if (XG(optimizer)) {
+			xc_optimize(op_array TSRMLS_CC);
+		}
+#endif
+		return op_array;
+	}
+
+	/* {{{ prepare key
+	 * include_once() and require_once() gives us opened_path
+	 * however, include() and require() non-absolute path which break
+	 * included_files, and may confuse with (include|require)_once
+	 * -- Xuefer
+	 */
+
+	filename = h->opened_path ? h->opened_path : h->filename;
+	xce.data.php = &php;
+	if (!xc_entry_init_key_php(&xce, filename TSRMLS_CC)) {
+		return origin_compile_file(h, type TSRMLS_CC);
+	}
+	cache = xce.cache;
+	/* }}} */
+	/* {{{ restore */
+	/* stale precheck */
+	if (cache->compiling) {
+		cache->clogs ++; /* is it safe here? */
+		return origin_compile_file(h, type TSRMLS_CC);
+	}
+
+	stored_xce = NULL;
+	op_array = NULL;
+	ENTER_LOCK(cache) {
+		/* clogged */
+		if (cache->compiling) {
+			cache->clogs ++;
+			op_array = NULL;
+			clogged = 1;
+			break;
+		}
+
+		stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC);
+		/* found */
+		if (stored_xce) {
+#ifdef DEBUG
+			fprintf(stderr, "found %s, catch it\n", stored_xce->name.str.val);
+#endif
+			xc_entry_hold_php_dmz(stored_xce TSRMLS_CC);
+			cache->hits ++;
+			break;
+		}
+
+		cache->compiling = XG(request_time);
+		cache->misses ++;
+	} LEAVE_LOCK(cache);
+
+	/* found */
+	if (stored_xce) {
+		goto restore;
+	}
+
+	/* clogged */
+	if (clogged) {
+		return origin_compile_file(h, type TSRMLS_CC);
+	}
+	/* }}} */
+
+	/* {{{ compile */
+#ifdef DEBUG
+	fprintf(stderr, "compiling %s\n", filename);
+#endif
+
+	/* make compile inside sandbox */
+	xc_sandbox_init(&sandbox, filename TSRMLS_CC);
+
+	zend_try {
+		op_array = origin_compile_file(h, type TSRMLS_CC);
+	} zend_catch {
+		catched = 1;
+	} zend_end_try();
+
+	if (catched) {
+		goto err_bailout;
+	}
+
+	if (op_array == NULL) {
+		goto err_oparray;
+	}
+
+#ifdef HAVE_XCACHE_OPTIMIZER
+	if (XG(optimizer)) {
+		xc_optimize(op_array TSRMLS_CC);
+	}
+#endif
+
+	php.op_array      = op_array;
+
+	php.funcinfo_cnt  = zend_hash_num_elements(CG(function_table));
+	php.classinfo_cnt = zend_hash_num_elements(CG(class_table));
+
+	php.funcinfos     = ECALLOC_N(php.funcinfos, php.funcinfo_cnt);
+	if (!php.funcinfos) {
+		goto err_func;
+	}
+	php.classinfos    = ECALLOC_N(php.classinfos, php.classinfo_cnt);
+	if (!php.classinfos) {
+		goto err_class;
+	}
+	/* }}} */
+	/* {{{ shallow copy, pointers only */ {
+		Bucket *b;
+		unsigned int i;
+
+		b = CG(function_table)->pListHead;
+		for (i = 0; b; i ++, b = b->pListNext) {
+			xc_funcinfo_t *fi = &php.funcinfos[i];
+
+			assert(i < php.funcinfo_cnt);
+			assert(b->pData);
+			memcpy(&fi->func, b->pData, sizeof(zend_function));
+			UNISW(, fi->type = b->key.type;)
+			fi->key        = BUCKET_KEY(b);
+			fi->key_size   = b->nKeyLength;
+		}
+
+		b = CG(class_table)->pListHead;
+		for (i = 0; b; i ++, b = b->pListNext) {
+			xc_classinfo_t *ci = &php.classinfos[i];
+
+			assert(i < php.classinfo_cnt);
+			assert(b->pData);
+			memcpy(&ci->cest, b->pData, sizeof(xc_cest_t));
+			UNISW(, ci->type = b->key.type;)
+			ci->key        = BUCKET_KEY(b);
+			ci->key_size   = b->nKeyLength;
+			/* need to fix inside store */
+		}
+	}
+	/* }}} */
+	xc_entry_gc(TSRMLS_C);
+	ENTER_LOCK(cache) { /* {{{ store/add entry */
+		stored_xce = xc_entry_store_dmz(&xce TSRMLS_CC);
+	} LEAVE_LOCK(cache);
+	/* }}} */
+#ifdef DEBUG
+	fprintf(stderr, "stored\n");
+#endif
+
+	efree(xce.data.php->classinfos);
+err_class:
+	efree(xce.data.php->funcinfos);
+err_func:
+err_oparray:
+err_bailout:
+
+	if (xc_test && stored_xce) {
+		/* no install, keep open_files too for h */
+		xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
+		sandbox.tmp_open_files->dtor = NULL;
+	}
+	else {
+		xc_sandbox_free(&sandbox, 1 TSRMLS_CC);
+	}
+
+	ENTER_LOCK(cache) {
+		cache->compiling = 0;
+	} LEAVE_LOCK(cache);
+	if (catched) {
+		zend_bailout();
+	}
+	if (xc_test && stored_xce) {
+		goto restore;
+	}
+	return op_array;
+
+restore:
+#ifdef DEBUG
+	fprintf(stderr, "restoring\n");
+#endif
+	xc_processor_restore_xc_entry_t(&xce, stored_xce, xc_readonly_protection TSRMLS_CC);
+	op_array = xc_entry_install(&xce, h TSRMLS_CC);
+
+	efree(xce.data.php->funcinfos);
+	efree(xce.data.php->classinfos);
+	efree(xce.data.php);
+#ifdef DEBUG
+	fprintf(stderr, "restored\n");
+#endif
+	return op_array;
+}
+/* }}} */
+
+/* gdb helper functions, but N/A for coredump */
+int xc_is_rw(const void *p) /* {{{ */
+{
+	int i;
+	if (!xc_initized) {
+		return 0;
+	}
+	for (i = 0; i < xc_php_hcache.size; i ++) {
+		if (xc_shm_is_readwrite(xc_php_caches[i]->shm, p)) {
+			return 1;
+		}
+	}
+	for (i = 0; i < xc_var_hcache.size; i ++) {
+		if (xc_shm_is_readwrite(xc_var_caches[i]->shm, p)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+/* }}} */
+int xc_is_ro(const void *p) /* {{{ */
+{
+	int i;
+	if (!xc_initized) {
+		return 0;
+	}
+	for (i = 0; i < xc_php_hcache.size; i ++) {
+		if (xc_shm_is_readonly(xc_php_caches[i]->shm, p)) {
+			return 1;
+		}
+	}
+	for (i = 0; i < xc_var_hcache.size; i ++) {
+		if (xc_shm_is_readonly(xc_var_caches[i]->shm, p)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+/* }}} */
+int xc_is_shm(const void *p) /* {{{ */
+{
+	return xc_is_ro(p) || xc_is_rw(p);
 }
 /* }}} */
@@ -60,10 +825,9 @@
 static int xc_init_constant(int module_number TSRMLS_DC) /* {{{ */
 {
-	typedef struct {
+	struct {
 		const char *prefix;
-		zend_uchar (*getsize)();
+		int (*getsize)();
 		const char *(*get)(zend_uchar i);
-	} xc_nameinfo_t;
-	xc_nameinfo_t nameinfos[] = {
+	} nameinfos[] = {
 		{ "",        xc_get_op_type_count,   xc_get_op_type   },
 		{ "",        xc_get_data_type_count, xc_get_data_type },
@@ -72,14 +836,12 @@
 		{ NULL, NULL, NULL }
 	};
+	typeof(nameinfos[0])* p;
+	int i;
+	char const_name[96];
+	int const_name_len;
 	int undefdone = 0;
-	xc_nameinfo_t *p;
 
 	for (p = nameinfos; p->getsize; p ++) {
-		zend_uchar i, count;
-		char const_name[96];
-		int const_name_len;
-
-		count = p->getsize();
-		for (i = 0; i < count; i ++) {
+		for (i = p->getsize() - 1; i >= 0; i --) {
 			const char *name = p->get(i);
 			if (!name) continue;
@@ -94,116 +856,559 @@
 
 	zend_register_long_constant(ZEND_STRS("XC_SIZEOF_TEMP_VARIABLE"), sizeof(temp_variable), CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);
-	zend_register_stringl_constant(ZEND_STRS("XCACHE_VERSION"), ZEND_STRL(XCACHE_VERSION), CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);
-	zend_register_stringl_constant(ZEND_STRS("XCACHE_MODULES"), ZEND_STRL(XCACHE_MODULES), CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);
+	zend_register_long_constant(ZEND_STRS("XC_TYPE_PHP"), XC_TYPE_PHP, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);
+	zend_register_long_constant(ZEND_STRS("XC_TYPE_VAR"), XC_TYPE_VAR, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);
 	return 0;
 }
 /* }}} */
-/* {{{ PHP_GINIT_FUNCTION(xcache) */
-#pragma GCC push_options
-#pragma GCC diagnostic ignored "-Wshadow"
-
-#ifdef PHP_GINIT_FUNCTION
-static PHP_GINIT_FUNCTION(xcache)
+static xc_shm_t *xc_cache_destroy(xc_cache_t **caches, xc_hash_t *hcache TSRMLS_DC) /* {{{ */
+{
+	int i;
+	xc_cache_t *cache;
+	xc_shm_t *shm;
+
+	if (!caches) {
+		return NULL;
+	}
+	shm = NULL;
+	for (i = 0; i < hcache->size; i ++) {
+		cache = caches[i];
+		if (cache) {
+			if (cache->lck) {
+				xc_lock_destroy(cache->lck);
+			}
+			/* do NOT free
+			if (cache->entries) {
+				xc_mem_free(cache->mem, cache->entries);
+			}
+			xc_mem_free(cache->mem, cache);
+			*/
+			xc_mem_destroy(cache->mem);
+			shm = cache->shm;
+		}
+	}
+	free(caches);
+	return shm;
+}
+/* }}} */
+static xc_cache_t **xc_cache_init(xc_shm_t *shm, char *ptr, xc_hash_t *hcache, xc_hash_t *hentry, xc_shmsize_t shmsize TSRMLS_DC) /* {{{ */
+{
+	xc_cache_t **caches = NULL, *cache;
+	xc_mem_t *mem;
+	int i;
+	xc_memsize_t memsize = shmsize / hcache->size;
+
+	CHECK(caches = calloc(hcache->size, sizeof(xc_cache_t *)), "caches OOM");
+
+	for (i = 0; i < hcache->size; i ++) {
+		mem = xc_mem_init(ptr, memsize);
+		ptr += ALIGN(memsize);
+		CHECK(cache          = xc_mem_calloc(mem, 1, sizeof(xc_cache_t)), "cache OOM");
+		CHECK(cache->entries = xc_mem_calloc(mem, hentry->size, sizeof(xc_entry_t*)), "entries OOM");
+		CHECK(cache->lck     = xc_lock_init(NULL), "can't create lock");
+
+		cache->hcache  = hcache;
+		cache->hentry  = hentry;
+		cache->shm     = shm;
+		cache->mem     = mem;
+		cache->cacheid = i;
+		caches[i] = cache;
+	}
+	assert(ptr <= (char*)xc_shm_ptr(shm) + shmsize);
+	return caches;
+
+err:
+	if (caches) {
+		xc_cache_destroy(caches, hcache);
+	}
+	return NULL;
+}
+/* }}} */
+static void xc_destroy() /* {{{ */
+{
+	xc_shm_t *shm = NULL;
+
+	if (origin_compile_file) {
+		zend_compile_file = origin_compile_file;
+		origin_compile_file = NULL;
+	}
+
+	if (xc_php_caches) {
+		shm = xc_cache_destroy(xc_php_caches, &xc_php_hcache);
+		xc_php_caches = NULL;
+	}
+	if (xc_var_caches) {
+		shm = xc_cache_destroy(xc_var_caches, &xc_var_hcache);
+		xc_var_caches = NULL;
+	}
+	if (shm) {
+		xc_shm_destroy(shm);
+	}
+}
+/* }}} */
+static int xc_init(int module_number TSRMLS_DC) /* {{{ */
+{
+	xc_php_caches = xc_var_caches = NULL;
+	xc_shm_t *shm;
+	char *ptr;
+
+	if (xc_php_size || xc_var_size) {
+		CHECK(shm = xc_shm_init(xc_mmap_path, ALIGN(xc_php_size) + ALIGN(xc_var_size), xc_readonly_protection), "Cannot create shm");
+		if (!xc_shm_can_readonly(shm)) {
+			xc_readonly_protection = 0;
+		}
+
+		ptr = (char *)xc_shm_ptr(shm);
+		if (xc_php_size) {
+			origin_compile_file = zend_compile_file;
+			zend_compile_file = xc_compile_file;
+
+			CHECK(xc_php_caches = xc_cache_init(shm, ptr, &xc_php_hcache, &xc_php_hentry, xc_php_size), "failed init opcode cache");
+			ptr += ALIGN(xc_php_size);
+		}
+
+		if (xc_var_size) {
+			CHECK(xc_var_caches = xc_cache_init(shm, ptr, &xc_var_hcache, &xc_var_hentry, xc_var_size), "failed init variable cache");
+		}
+	}
+	return 1;
+
+err:
+	if (xc_php_caches || xc_var_caches) {
+		xc_destroy();
+		/* shm destroied */
+	}
+	else if (shm) {
+		xc_shm_destroy(shm);
+	}
+	return 0;
+}
+/* }}} */
+static void xc_request_init(TSRMLS_D) /* {{{ */
+{
+	if (XG(cacher)) {
+#if PHP_API_VERSION <= 20041225
+		XG(request_time) = time(NULL);
 #else
-static void xc_init_globals(zend_xcache_globals* xcache_globals TSRMLS_DC)
-#endif
-{
-#pragma GCC pop_options
-
-	memset(xcache_globals, 0, sizeof(zend_xcache_globals));
-
-#ifdef HAVE_XCACHE_CONSTANT
-	zend_hash_init_ex(&xcache_globals->internal_constant_table, 1, NULL, (dtor_func_t) xc_zend_constant_dtor, 1, 0);
-#endif
-	zend_hash_init_ex(&xcache_globals->internal_function_table, 1, NULL, NULL, 1, 0);
-	zend_hash_init_ex(&xcache_globals->internal_class_table,    1, NULL, NULL, 1, 0);
-}
-/* }}} */
-/* {{{ PHP_GSHUTDOWN_FUNCTION(xcache) */
-static
-#ifdef PHP_GSHUTDOWN_FUNCTION
-PHP_GSHUTDOWN_FUNCTION(xcache)
+		XG(request_time) = sapi_get_request_time(TSRMLS_C);
+#endif
+	}
+#ifdef HAVE_XCACHE_COVERAGE
+	xc_coverage_request_init(TSRMLS_C);
+#endif
+}
+/* }}} */
+static void xc_request_shutdown(TSRMLS_D) /* {{{ */
+{
+	xc_entry_unholds(TSRMLS_C);
+#ifdef HAVE_XCACHE_COVERAGE
+	xc_coverage_request_shutdown(TSRMLS_C);
+#endif
+}
+/* }}} */
+static void xc_init_globals(zend_xcache_globals* xc_globals TSRMLS_DC) /* {{{ */
+{
+	int i;
+
+	if (xc_php_hcache.size) {
+		xc_globals->php_holds = calloc(xc_php_hcache.size, sizeof(xc_stack_t));
+		for (i = 0; i < xc_php_hcache.size; i ++) {
+			xc_stack_init(&xc_globals->php_holds[i]);
+		}
+	}
+	else {
+		xc_globals->php_holds = NULL;
+	}
+
+	if (xc_var_hcache.size) {
+		xc_globals->var_holds = calloc(xc_var_hcache.size, sizeof(xc_stack_t));
+		for (i = 0; i < xc_var_hcache.size; i ++) {
+			xc_stack_init(&xc_globals->var_holds[i]);
+		}
+	}
+	else {
+		xc_globals->var_holds = NULL;
+	}
+
+#ifdef HAVE_XCACHE_COVERAGE
+	xc_globals->coverages = NULL;
+#endif
+}
+/* }}} */
+static void xc_shutdown_globals(zend_xcache_globals* xc_globals TSRMLS_DC) /* {{{ */
+{
+	int i;
+
+	if (xc_globals->php_holds != NULL) {
+		for (i = 0; i < xc_php_hcache.size; i ++) {
+			xc_stack_destroy(&xc_globals->php_holds[i]);
+		}
+		free(xc_globals->php_holds);
+		xc_globals->php_holds = NULL;
+	}
+
+	if (xc_globals->var_holds != NULL) {
+		for (i = 0; i < xc_var_hcache.size; i ++) {
+			xc_stack_destroy(&xc_globals->var_holds[i]);
+		}
+		free(xc_globals->var_holds);
+		xc_globals->var_holds = NULL;
+	}
+}
+/* }}} */
+
+#define NEED_INITIZED() do { \
+	if (!xc_initized) { \
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "XCache is not initized"); \
+		RETURN_FALSE; \
+	} \
+} while (0)
+
+/* user functions */
+/* {{{ xcache_op */
+typedef enum { XC_OP_COUNT, XC_OP_INFO, XC_OP_LIST, XC_OP_CLEAR } xcache_op_type;
+static void xcache_op(xcache_op_type optype, INTERNAL_FUNCTION_PARAMETERS)
+{
+	NEED_INITIZED();
+	long type;
+	int size;
+	xc_cache_t **caches, *cache;
+	long id = 0;
+
+	if (optype == XC_OP_COUNT) {
+		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type) == FAILURE) {
+			return;
+		}
+	}
+	else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &type, &id) == FAILURE) {
+		return;
+	}
+
+	switch (type) {
+		case XC_TYPE_PHP:
+			size = xc_php_hcache.size;
+			caches = xc_php_caches;
+			break;
+
+		case XC_TYPE_VAR:
+			size = xc_var_hcache.size;
+			caches = xc_var_caches;
+			break;
+
+		default:
+			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown type %ld", type);
+			RETURN_FALSE;
+	}
+
+	switch (optype) {
+		case XC_OP_COUNT:
+			RETURN_LONG(size)
+			break;
+
+		case XC_OP_INFO:
+		case XC_OP_LIST:
+			if (id < 0 || id >= size) {
+				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cache not exists");
+				RETURN_FALSE;
+			}
+
+			array_init(return_value);
+
+			cache = caches[id];
+			ENTER_LOCK(cache) {
+				if (optype == XC_OP_INFO) {
+					xc_fillinfo_dmz(cache, return_value TSRMLS_CC);
+				}
+				else {
+					xc_filllist_dmz(cache, return_value TSRMLS_CC);
+				}
+			} LEAVE_LOCK(cache);
+			break;
+		case XC_OP_CLEAR:
+			{
+				xc_entry_t *e;
+				int i, c;
+
+				if (id < 0 || id >= size) {
+					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cache not exists");
+					RETURN_FALSE;
+				}
+
+				cache = caches[id];
+				ENTER_LOCK(cache) {
+					for (i = 0, c = cache->hentry->size; i < c; i ++) {
+						for (e = cache->entries[i]; e; e = e->next) {
+							xc_entry_remove_dmz(e TSRMLS_CC);
+						}
+						cache->entries[i] = NULL;
+					}
+				} LEAVE_LOCK(cache);
+				xc_entry_gc(TSRMLS_C);
+			}
+			break;
+
+		default:
+			assert(0);
+	}
+}
+/* }}} */
+/* {{{ proto array xcache_count(int type) */
+PHP_FUNCTION(xcache_count)
+{
+	xcache_op(XC_OP_COUNT, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+/* {{{ proto array xcache_info(int type, int id) */
+PHP_FUNCTION(xcache_info)
+{
+	xcache_op(XC_OP_INFO, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+/* {{{ proto array xcache_list(int type, int id) */
+PHP_FUNCTION(xcache_list)
+{
+	xcache_op(XC_OP_LIST, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+/* {{{ proto array xcache_clear_cache(int type, int id) */
+PHP_FUNCTION(xcache_clear_cache)
+{
+	xcache_op(XC_OP_CLEAR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+static int xc_entry_init_key_var(xc_entry_t *xce, zval *name TSRMLS_DC) /* {{{ */
+{
+	xc_hash_value_t hv;
+	int cacheid;
+
+	switch (Z_TYPE_P(name)) {
+#ifdef IS_UNICODE
+		case IS_UNICODE:
+#endif
+		case IS_STRING:
+			break;
+		default:
+#ifdef IS_UNICODE
+			convert_to_text(name);
 #else
-void xc_shutdown_globals(zend_xcache_globals* xcache_globals TSRMLS_DC)
-#endif
-{
-	size_t i;
-
-	if (xcache_globals->php_holds != NULL) {
-		for (i = 0; i < xcache_globals->php_holds_size; i ++) {
-			xc_stack_destroy(&xcache_globals->php_holds[i]);
-		}
-		free(xcache_globals->php_holds);
-		xcache_globals->php_holds = NULL;
-		xcache_globals->php_holds_size = 0;
-	}
-
-	if (xcache_globals->var_holds != NULL) {
-		for (i = 0; i < xcache_globals->var_holds_size; i ++) {
-			xc_stack_destroy(&xcache_globals->var_holds[i]);
-		}
-		free(xcache_globals->var_holds);
-		xcache_globals->var_holds = NULL;
-		xcache_globals->var_holds_size = 0;
-	}
-
-	if (xcache_globals->internal_table_copied) {
-#ifdef HAVE_XCACHE_CONSTANT
-		zend_hash_destroy(&xcache_globals->internal_constant_table);
-#endif
-		zend_hash_destroy(&xcache_globals->internal_function_table);
-		zend_hash_destroy(&xcache_globals->internal_class_table);
-	}
-}
-/* }}} */
-
-/* {{{ proto int xcache_get_refcount(mixed variable)
-   XCache internal uses only: Get reference count of variable */
-PHP_FUNCTION(xcache_get_refcount)
-{
-	zval *variable;
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &variable) == FAILURE) {
-		RETURN_NULL();
-	}
-
-	RETURN_LONG(Z_REFCOUNT(*variable));
-}
-/* }}} */
-/* {{{ proto bool xcache_get_isref(mixed variable)
-   XCache internal uses only: Check if variable data is marked referenced */
-#ifdef ZEND_BEGIN_ARG_INFO_EX
-ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_get_isref, 0, 0, 1)
-	ZEND_ARG_INFO(1, variable)
-ZEND_END_ARG_INFO()
-#else
-static unsigned char arginfo_xcache_get_isref[] = { 1, BYREF_FORCE };
-#endif
-
-PHP_FUNCTION(xcache_get_isref)
-{
-	zval *variable;
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &variable) == FAILURE) {
-		RETURN_NULL();
-	}
-
-	RETURN_BOOL(Z_ISREF(*variable) && Z_REFCOUNT(*variable) >= 3);
-}
-/* }}} */
-#ifdef HAVE_XCACHE_DPRINT
-/* {{{ proto bool  xcache_dprint(mixed value)
-   Prints variable (or value) internal struct (debug only) */
-PHP_FUNCTION(xcache_dprint)
-{
+			convert_to_string(name);
+#endif
+	}
+#ifdef IS_UNICODE
+	xce->name_type = name->type;
+#endif
+	xce->name = name->value;
+
+	hv = xc_entry_hash_var(xce);
+
+	cacheid = (hv & xc_var_hcache.mask);
+	xce->cache = xc_var_caches[cacheid];
+	hv >>= xc_var_hcache.bits;
+	xce->hvalue = (hv & xc_var_hentry.mask);
+
+	xce->type = XC_TYPE_VAR;
+	return SUCCESS;
+}
+/* }}} */
+#define TIME_MAX (sizeof(time_t) == sizeof(long) ? LONG_MAX : INT_MAX)
+/* {{{ proto mixed xcache_get(string name) */
+PHP_FUNCTION(xcache_get)
+{
+	xc_entry_t xce, *stored_xce;
+	xc_entry_data_var_t var;
+	zval *name;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
+		return;
+	}
+	xce.data.var = &var;
+	xc_entry_init_key_var(&xce, name TSRMLS_CC);
+
+	ENTER_LOCK(xce.cache) {
+		stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC);
+		if (stored_xce) {
+			if (XG(request_time) <= stored_xce->data.var->etime) {
+				xc_processor_restore_zval(return_value, stored_xce->data.var->value TSRMLS_CC);
+				/* return */
+				break;
+			}
+			else {
+				xc_entry_remove_dmz(stored_xce);
+			}
+		}
+
+		RETVAL_NULL();
+	} LEAVE_LOCK(xce.cache);
+}
+/* }}} */
+/* {{{ proto bool  xcache_set(string name, mixed value [, int ttl]) */
+PHP_FUNCTION(xcache_set)
+{
+	xc_entry_t xce, *stored_xce;
+	xc_entry_data_var_t var;
+	zval *name;
 	zval *value;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
+	long ttl = 0;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &name, &value, &ttl) == FAILURE) {
 		return;
 	}
-	xc_dprint_zval(value, 0 TSRMLS_CC);
-}
-/* }}} */
-#endif
-/* {{{ proto string xcache_asm(string filename)
- */
+	xce.data.var = &var;
+	xc_entry_init_key_var(&xce, name TSRMLS_CC);
+
+	ENTER_LOCK(xce.cache) {
+		stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC);
+		if (stored_xce) {
+			xc_entry_remove_dmz(stored_xce);
+		}
+		var.value = value;
+		var.etime = ttl ? XG(request_time) + ttl : TIME_MAX;
+		RETVAL_BOOL(xc_entry_store_dmz(&xce) != NULL ? 1 : 0);
+	} LEAVE_LOCK(xce.cache);
+}
+/* }}} */
+/* {{{ proto mixed xcache_isset(string name) */
+PHP_FUNCTION(xcache_isset)
+{
+	xc_entry_t xce, *stored_xce;
+	xc_entry_data_var_t var;
+	zval *name;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
+		return;
+	}
+	xce.data.var = &var;
+	xc_entry_init_key_var(&xce, name TSRMLS_CC);
+
+	ENTER_LOCK(xce.cache) {
+		stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC);
+		if (stored_xce) {
+			if (XG(request_time) <= stored_xce->data.var->etime) {
+				RETVAL_TRUE;
+				/* return */
+				break;
+			}
+			else {
+				xc_entry_remove_dmz(stored_xce);
+			}
+		}
+
+		RETVAL_FALSE;
+	} LEAVE_LOCK(xce.cache);
+}
+/* }}} */
+/* {{{ proto bool  xcache_unset(string name) */
+PHP_FUNCTION(xcache_unset)
+{
+	xc_entry_t xce, *stored_xce;
+	xc_entry_data_var_t var;
+	zval *name;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
+		return;
+	}
+	xce.data.var = &var;
+	xc_entry_init_key_var(&xce, name TSRMLS_CC);
+
+	ENTER_LOCK(xce.cache) {
+		stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC);
+		if (stored_xce) {
+			xc_entry_remove_dmz(stored_xce);
+			RETVAL_TRUE;
+		}
+		else {
+			RETVAL_FALSE;
+		}
+	} LEAVE_LOCK(xce.cache);
+}
+/* }}} */
+static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
+{
+	xc_entry_t xce, *stored_xce;
+	xc_entry_data_var_t var, *stored_var;
+	zval *name;
+	long count = 1;
+	long ttl = 0;
+	long value = 0;
+	zval oldzval;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &name, &count, &ttl) == FAILURE) {
+		return;
+	}
+	xce.data.var = &var;
+	xc_entry_init_key_var(&xce, name TSRMLS_CC);
+
+	ENTER_LOCK(xce.cache) {
+		stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC);
+		if (stored_xce) {
+#ifdef DEBUG
+			fprintf(stderr, "incdec: gotxce %s\n", xce.name.str.val);
+#endif
+			stored_var = stored_xce->data.var;
+			/* timeout */
+			if (XG(request_time) > stored_var->etime) {
+#ifdef DEBUG
+				fprintf(stderr, "incdec: expired\n");
+#endif
+				xc_entry_remove_dmz(stored_xce);
+				stored_xce = NULL;
+			}
+			else {
+				/* do it in place */
+				if (Z_TYPE_P(stored_var->value) == IS_LONG) {
+#ifdef DEBUG
+					fprintf(stderr, "incdec: islong\n");
+#endif
+					value = Z_LVAL_P(stored_var->value);
+					value += (inc == 1 ? count : - count);
+					RETVAL_LONG(value);
+					Z_LVAL_P(stored_var->value) = value;
+					break;
+				}
+				else {
+#ifdef DEBUG
+					fprintf(stderr, "incdec: notlong\n");
+#endif
+					xc_processor_restore_zval(&oldzval, stored_xce->data.var->value TSRMLS_CC);
+					convert_to_long(&oldzval);
+					value = Z_LVAL(oldzval);
+					zval_dtor(&oldzval);
+				}
+			}
+		}
+#ifdef DEBUG
+		else {
+			fprintf(stderr, "incdec: %s not found\n", xce.name.str.val);
+		}
+#endif
+
+		value += (inc == 1 ? count : - count);
+		RETVAL_LONG(value);
+		var.value = return_value;
+		var.etime = ttl ? XG(request_time) + ttl : TIME_MAX;
+		if (stored_xce) {
+			xce.atime = stored_xce->atime;
+			xce.ctime = stored_xce->ctime;
+			xce.hits  = stored_xce->hits;
+			xc_entry_remove_dmz(stored_xce);
+		}
+		xc_entry_store_dmz(&xce);
+
+	} LEAVE_LOCK(xce.cache);
+}
+/* }}} */
+/* {{{ proto int xcache_inc(string name [, int value [, int ttl]]) */
+PHP_FUNCTION(xcache_inc)
+{
+	xc_var_inc_dec(1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+/* {{{ proto int xcache_dec(string name [, int value [, int ttl]]) */
+PHP_FUNCTION(xcache_dec)
+{
+	xc_var_inc_dec(-1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+/* {{{ proto string xcache_asm(string filename) */
 #ifdef HAVE_XCACHE_ASSEMBLER
 PHP_FUNCTION(xcache_asm)
@@ -212,6 +1417,32 @@
 #endif
 /* }}} */
-/* {{{ proto string xcache_encode(string filename)
-   Encode php file into XCache opcode encoded format */
+#ifdef HAVE_XCACHE_DISASSEMBLER
+/* {{{ proto string xcache_dasm_file(string filename) */
+PHP_FUNCTION(xcache_dasm_file)
+{
+	char *filename;
+	long filename_len;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
+		return;
+	}
+	if (!filename_len) RETURN_FALSE;
+
+	xc_dasm_file(return_value, filename TSRMLS_CC);
+}
+/* }}} */
+/* {{{ proto string xcache_dasm_string(string code) */
+PHP_FUNCTION(xcache_dasm_string)
+{
+	zval *code;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &code) == FAILURE) {
+		return;
+	}
+	xc_dasm_string(return_value, code TSRMLS_CC);
+}
+/* }}} */
+#endif
+/* {{{ proto string xcache_encode(string filename) */
 #ifdef HAVE_XCACHE_ENCODER
 PHP_FUNCTION(xcache_encode)
@@ -220,16 +1451,7 @@
 #endif
 /* }}} */
-/* {{{ proto bool xcache_decode_file(string filename)
-   Decode(load) opcode from XCache encoded format file */
+/* {{{ proto bool xcache_decode(string filename) */
 #ifdef HAVE_XCACHE_DECODER
-PHP_FUNCTION(xcache_decode_file)
-{
-}
-#endif
-/* }}} */
-/* {{{ proto bool xcache_decode_string(string data)
-   Decode(load) opcode from XCache encoded format data */
-#ifdef HAVE_XCACHE_DECODER
-PHP_FUNCTION(xcache_decode_string)
+PHP_FUNCTION(xcache_decode)
 {
 }
@@ -247,8 +1469,8 @@
 	}
 	if (spec >= 0 && spec < count) {
-		name = getter((zend_uchar) spec);
+		name = getter(spec);
 		if (name) {
 			/* RETURN_STRING */
-			int len = (int) strlen(name);
+			int len = strlen(name);
 			return_value->value.str.len = len;
 			return_value->value.str.val = estrndup(name, len);
@@ -293,6 +1515,6 @@
 		return;
 	}
-	if ((zend_uchar) spec <= xc_get_opcode_spec_count()) {
-		opspec = xc_get_opcode_spec((zend_uchar) spec);
+	if (spec <= xc_get_opcode_spec_count()) {
+		opspec = xc_get_opcode_spec(spec);
 		if (opspec) {
 			array_init(return_value);
@@ -307,6 +1529,5 @@
 }
 /* }}} */
-/* {{{ proto mixed xcache_get_special_value(zval value)
-   XCache internal use only: For decompiler to get static value with type fixed */
+/* {{{ proto mixed xcache_get_special_value(zval value) */
 PHP_FUNCTION(xcache_get_special_value)
 {
@@ -317,33 +1538,19 @@
 	}
 
-	switch ((Z_TYPE_P(value) & IS_CONSTANT_TYPE_MASK)) {
-	case IS_CONSTANT:
+	if (value->type == IS_CONSTANT) {
 		*return_value = *value;
 		zval_copy_ctor(return_value);
 		return_value->type = UNISW(IS_STRING, UG(unicode) ? IS_UNICODE : IS_STRING);
-		break;
-
-	case IS_CONSTANT_ARRAY:
+		return;
+	}
+
+	if (value->type == IS_CONSTANT_ARRAY) {
 		*return_value = *value;
 		zval_copy_ctor(return_value);
 		return_value->type = IS_ARRAY;
-		break;
-
-	default:
-		RETURN_NULL();
-	}
-}
-/* }}} */
-/* {{{ proto int xcache_get_type(zval value)
-   XCache internal use only for disassembler to get variable type in engine level */
-PHP_FUNCTION(xcache_get_type)
-{
-	zval *value;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
 		return;
 	}
 
-	RETURN_LONG(Z_TYPE_P(value));
+	RETURN_NULL();
 }
 /* }}} */
@@ -351,12 +1558,5 @@
 PHP_FUNCTION(xcache_coredump)
 {
-	if (xc_test) {
-		char *null_ptr = NULL;
-		*null_ptr = 0;
-		raise(SIGSEGV);
-	}
-	else {
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "xcache.test must be enabled to test xcache_coredump()");
-	}
+	raise(SIGSEGV);
 }
 /* }}} */
@@ -364,34 +1564,38 @@
 PHP_FUNCTION(xcache_is_autoglobal)
 {
-	zval *name;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) {
+	char *name;
+	long name_len;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
 		return;
 	}
 
-#ifdef IS_UNICODE
-	convert_to_unicode(name);
-#else
-	convert_to_string(name);
-#endif
-
-	RETURN_BOOL(zend_u_hash_exists(CG(auto_globals), UG(unicode), Z_STRVAL_P(name), Z_STRLEN_P(name) + 1));
-}
-/* }}} */
-static zend_function_entry xcache_functions[] = /* {{{ */
-{
+	RETURN_BOOL(zend_hash_exists(CG(auto_globals), name, name_len + 1));
+}
+/* }}} */
+static function_entry xcache_functions[] = /* {{{ */
+{
+	PHP_FE(xcache_count,             NULL)
+	PHP_FE(xcache_info,              NULL)
+	PHP_FE(xcache_list,              NULL)
+	PHP_FE(xcache_clear_cache,       NULL)
 	PHP_FE(xcache_coredump,          NULL)
 #ifdef HAVE_XCACHE_ASSEMBLER
 	PHP_FE(xcache_asm,               NULL)
 #endif
+#ifdef HAVE_XCACHE_DISASSEMBLER
+	PHP_FE(xcache_dasm_file,         NULL)
+	PHP_FE(xcache_dasm_string,       NULL)
+#endif
 #ifdef HAVE_XCACHE_ENCODER
 	PHP_FE(xcache_encode,            NULL)
 #endif
 #ifdef HAVE_XCACHE_DECODER
-	PHP_FE(xcache_decode_file,       NULL)
-	PHP_FE(xcache_decode_string,     NULL)
+	PHP_FE(xcache_decode,            NULL)
+#endif
+#ifdef HAVE_XCACHE_COVERAGE
+	PHP_FE(xcache_coverage_decode,   NULL)
 #endif
 	PHP_FE(xcache_get_special_value, NULL)
-	PHP_FE(xcache_get_type,          NULL)
 	PHP_FE(xcache_get_op_type,       NULL)
 	PHP_FE(xcache_get_data_type,     NULL)
@@ -399,305 +1603,326 @@
 	PHP_FE(xcache_get_opcode_spec,   NULL)
 	PHP_FE(xcache_is_autoglobal,     NULL)
-	PHP_FE(xcache_get_refcount,      NULL)
-	PHP_FE(xcache_get_isref,         arginfo_xcache_get_isref)
-#ifdef HAVE_XCACHE_DPRINT
-	PHP_FE(xcache_dprint,            NULL)
-#endif
-	PHP_FE_END
+	PHP_FE(xcache_inc,               NULL)
+	PHP_FE(xcache_dec,               NULL)
+	PHP_FE(xcache_get,               NULL)
+	PHP_FE(xcache_set,               NULL)
+	PHP_FE(xcache_isset,             NULL)
+	PHP_FE(xcache_unset,             NULL)
+	{NULL, NULL,                     NULL}
 };
 /* }}} */
 
-#ifdef ZEND_WIN32
-#include "dbghelp.h"
-typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
-		CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
-		CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
-		CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam
-		);
-
-static PTOP_LEVEL_EXCEPTION_FILTER oldFilter = NULL;
-static HMODULE dbghelpModule = NULL;
-static char crash_dumpPath[_MAX_PATH] = { 0 };
-static MINIDUMPWRITEDUMP dbghelp_MiniDumpWriteDump = NULL;
-
-static LONG WINAPI miniDumperFilter(struct _EXCEPTION_POINTERS *pExceptionInfo) /* {{{ */
-{
-	HANDLE fileHandle;
-	LONG ret = EXCEPTION_CONTINUE_SEARCH;
-
-	SetUnhandledExceptionFilter(oldFilter);
-
-	/* create the file */
-	fileHandle = CreateFile(crash_dumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
-	if (fileHandle != INVALID_HANDLE_VALUE) {
-		MINIDUMP_EXCEPTION_INFORMATION exceptionInformation;
-		MINIDUMP_TYPE type = xc_coredump_type ? xc_coredump_type : (MiniDumpNormal|MiniDumpWithDataSegs|MiniDumpWithIndirectlyReferencedMemory);
-		BOOL ok;
-
-		exceptionInformation.ThreadId = GetCurrentThreadId();
-		exceptionInformation.ExceptionPointers = pExceptionInfo;
-		exceptionInformation.ClientPointers = FALSE;
-
-		/* write the dump */
-		ok = dbghelp_MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, type, &exceptionInformation, NULL, NULL);
-		CloseHandle(fileHandle);
-		if (ok) {
-			zend_error(E_ERROR, "Saved dump file to '%s'", crash_dumpPath);
-			ret = EXCEPTION_EXECUTE_HANDLER;
-		}
-		else {
-			zend_error(E_ERROR, "Failed to save dump file to '%s' (error %d)", crash_dumpPath, GetLastError());
-		}
+/* signal handler */
+static void (*original_sigsegv_handler)(int) = NULL;
+static void xcache_sigsegv_handler(int dummy) /* {{{ */
+{
+	if (original_sigsegv_handler == xcache_sigsegv_handler) {
+		signal(SIGSEGV, original_sigsegv_handler);
+	} else {
+		signal(SIGSEGV, SIG_DFL);
+	}
+	if (xc_coredump_dir && xc_coredump_dir[0]) {
+		chdir(xc_coredump_dir);
+	}
+	if (original_sigsegv_handler != xcache_sigsegv_handler) {
+		original_sigsegv_handler(dummy);
+	}
+}
+/* }}} */
+
+/* {{{ PHP_INI */
+static PHP_INI_MH(xc_OnUpdateLong)
+{
+	long *p = (long *)mh_arg1;
+	*p = zend_atoi(new_value, new_value_length);
+	return SUCCESS;
+}
+
+static PHP_INI_MH(xc_OnUpdateBool)
+{
+	zend_bool *p = (zend_bool *)mh_arg1;
+
+	if (strncasecmp("on", new_value, sizeof("on"))) {
+		*p = (zend_bool) atoi(new_value);
 	}
 	else {
-		zend_error(E_ERROR, "Failed to create dump file '%s' (error %d)", crash_dumpPath, GetLastError());
-	}
-
-	if (xc_disable_on_crash) {
-		xc_disable_on_crash = 0;
-		xc_cacher_disable();
-	}
-
-	return ret;
-}
-/* }}} */
-
-static void xcache_restore_crash_handler() /* {{{ */
-{
-	if (oldFilter) {
-		SetUnhandledExceptionFilter(oldFilter);
-		oldFilter = NULL;
-	}
-}
-/* }}} */
-static void xcache_init_crash_handler() /* {{{ */
-{
-	/* firstly see if dbghelp.dll is around and has the function we need
-	   look next to the EXE first, as the one in System32 might be old
-	   (e.g. Windows 2000) */
-	char dbghelpPath[_MAX_PATH];
-
-	if (GetModuleFileName(NULL, dbghelpPath, _MAX_PATH)) {
-		char *slash = strchr(dbghelpPath, '\\');
-		if (slash) {
-			strcpy(slash + 1, "DBGHELP.DLL");
-			dbghelpModule = LoadLibrary(dbghelpPath);
-		}
-	}
-
-	if (!dbghelpModule) {
-		/* load any version we can */
-		dbghelpModule = LoadLibrary("DBGHELP.DLL");
-		if (!dbghelpModule) {
-			zend_error(E_ERROR, "Unable to enable crash dump saver: %s", "DBGHELP.DLL not found");
-			return;
-		}
-	}
-
-	dbghelp_MiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress(dbghelpModule, "MiniDumpWriteDump");
-	if (!dbghelp_MiniDumpWriteDump) {
-		zend_error(E_ERROR, "Unable to enable crash dump saver: %s", "DBGHELP.DLL too old. Get updated dll and put it aside of php_xcache.dll");
-		return;
-	}
-
-#ifdef XCACHE_VERSION_REVISION
-#define REVISION "r" XCACHE_VERSION_REVISION
+		*p = (zend_bool) 1;
+	}
+	return SUCCESS;
+}
+
+static PHP_INI_MH(xc_OnUpdateHashInfo)
+{
+	xc_hash_t *p = (xc_hash_t *)mh_arg1;
+	int bits, size;
+
+	p->size = zend_atoi(new_value, new_value_length);
+	for (size = 1, bits = 1; size < p->size; bits ++, size <<= 1) {
+		/* empty body */
+	}
+	p->size = size;
+	p->bits = bits;
+	p->mask = size - 1;
+
+	return SUCCESS;
+}
+
+static PHP_INI_MH(xc_OnUpdateString)
+{
+	char **p = (char**)mh_arg1;
+	if (*p) {
+		pefree(*p, 1);
+	}
+	*p = pemalloc(strlen(new_value) + 1, 1);
+	strcpy(*p, new_value);
+	return SUCCESS;
+}
+#ifdef ZEND_ENGINE_2
+#define OnUpdateInt OnUpdateLong
+#endif
+
+PHP_INI_BEGIN()
+	PHP_INI_ENTRY1     ("xcache.size",                   "0", PHP_INI_SYSTEM, xc_OnUpdateLong,     &xc_php_size)
+	PHP_INI_ENTRY1     ("xcache.count",                  "1", PHP_INI_SYSTEM, xc_OnUpdateHashInfo, &xc_php_hcache)
+	PHP_INI_ENTRY1     ("xcache.slots",                 "8K", PHP_INI_SYSTEM, xc_OnUpdateHashInfo, &xc_php_hentry)
+
+	PHP_INI_ENTRY1     ("xcache.var_size",               "0", PHP_INI_SYSTEM, xc_OnUpdateLong,     &xc_var_size)
+	PHP_INI_ENTRY1     ("xcache.var_count",              "1", PHP_INI_SYSTEM, xc_OnUpdateHashInfo, &xc_var_hcache)
+	PHP_INI_ENTRY1     ("xcache.var_slots",             "8K", PHP_INI_SYSTEM, xc_OnUpdateHashInfo, &xc_var_hentry)
+
+	PHP_INI_ENTRY1     ("xcache.mmap_path",      "/dev/zero", PHP_INI_SYSTEM, xc_OnUpdateString,   &xc_mmap_path)
+	PHP_INI_ENTRY1     ("xcache.coredump_directory",      "", PHP_INI_SYSTEM, xc_OnUpdateString,   &xc_coredump_dir)
+	PHP_INI_ENTRY1     ("xcache.test",                   "0", PHP_INI_SYSTEM, xc_OnUpdateBool,     &xc_test)
+	PHP_INI_ENTRY1     ("xcache.readonly_protection",    "0", PHP_INI_SYSTEM, xc_OnUpdateBool,     &xc_readonly_protection)
+
+	STD_PHP_INI_BOOLEAN("xcache.cacher",                 "1", PHP_INI_ALL,    OnUpdateBool,        cacher,            zend_xcache_globals, xcache_globals)
+#ifdef HAVE_XCACHE_OPTIMIZER
+	STD_PHP_INI_BOOLEAN("xcache.optimizer",              "0", PHP_INI_ALL,    OnUpdateBool,        optimizer,         zend_xcache_globals, xcache_globals)
+#endif
+#ifdef HAVE_XCACHE_COVERAGE
+	PHP_INI_ENTRY1     ("xcache.coveragedump_directory",  "", PHP_INI_SYSTEM, xc_OnUpdateString,   &xc_coveragedump_dir)
+	STD_PHP_INI_BOOLEAN("xcache.coveragedumper" ,        "1", PHP_INI_ALL,    OnUpdateBool,        coveragedumper,    zend_xcache_globals, xcache_globals)
+#endif
+PHP_INI_END()
+/* }}} */
+/* {{{ PHP_MINFO_FUNCTION(xcache) */
+static PHP_MINFO_FUNCTION(xcache)
+{
+	php_info_print_table_start();
+	php_info_print_table_header(2, "XCache Support", (xc_php_size || xc_var_size) ? "enabled" : "disabled");
+	php_info_print_table_row(2, "Version", XCACHE_VERSION);
+	php_info_print_table_row(2, "Readonly Protection", xc_readonly_protection ? "enabled" : "N/A");
+	php_info_print_table_row(2, "Opcode Cache", xc_php_size ? "enabled" : "disabled");
+	php_info_print_table_row(2, "Variable Cache", xc_var_size ? "enabled" : "disabled");
+	php_info_print_table_end();
+	DISPLAY_INI_ENTRIES();
+}
+/* }}} */
+/* {{{ extension startup */
+static void xc_zend_extension_register(zend_extension *new_extension, DL_HANDLE handle)
+{
+    zend_extension extension;
+
+    extension = *new_extension;
+    extension.handle = handle;
+
+    zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension);
+
+    zend_llist_add_element(&zend_extensions, &extension);
+#ifdef DEBUG
+	fprintf(stderr, "registered\n");
+#endif
+}
+
+/* dirty check */
+#if defined(COMPILE_DL_XCACHE) && (defined(ZEND_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__))
+#	define zend_append_version_info(x) do { } while (0)
 #else
-#define REVISION ""
-#endif
-	sprintf(crash_dumpPath, "%s\\php-%s-xcache-%s%s-%lu-%lu.dmp", xc_coredump_dir, zend_get_module_version("standard"), XCACHE_VERSION, REVISION, (unsigned long) time(NULL), (unsigned long) GetCurrentProcessId());
-#undef REVISION
-
-	oldFilter = SetUnhandledExceptionFilter(&miniDumperFilter);
-}
-/* }}} */
+extern void zend_append_version_info(zend_extension *extension);
+#endif
+static int xc_zend_extension_startup(zend_extension *extension)
+{
+    if (extension->startup) {
+        if (extension->startup(extension) != SUCCESS) {
+			return FAILURE;
+        }
+        zend_append_version_info(extension);
+    }
+	return SUCCESS;
+}
+/* }}} */
+/* {{{ PHP_MINIT_FUNCTION(xcache) */
+static PHP_MINIT_FUNCTION(xcache)
+{
+	char *env;
+
+	REGISTER_INI_ENTRIES();
+
+	xc_module_gotup = 1;
+	if (!xc_zend_extension_gotup) {
+		if (zend_get_extension(XCACHE_NAME) == NULL) {
+			xc_zend_extension_register(&zend_extension_entry, 0);
+			xc_zend_extension_startup(&zend_extension_entry);
+		}
+	}
+
+	if (strcmp(sapi_module.name, "cli") == 0) {
+		if ((env = getenv("XCACHE_TEST")) != NULL) {
+			zend_alter_ini_entry("xcache.test", sizeof("xcache.test"), env, strlen(env) + 1, PHP_INI_SYSTEM, PHP_INI_STAGE_STARTUP);
+		}
+		if (!xc_test) {
+			/* disable cache for cli except for test */
+			xc_php_size = xc_var_size = 0;
+		}
+	}
+
+	if (xc_php_size <= 0) {
+		xc_php_size = xc_php_hcache.size = 0;
+	}
+	if (xc_var_size <= 0) {
+		xc_var_size = xc_var_hcache.size = 0;
+	}
+	/* xc_init_globals depends on all the aboves */
+
+	ZEND_INIT_MODULE_GLOBALS(xcache, xc_init_globals, xc_shutdown_globals);
+
+	original_sigsegv_handler = signal(SIGSEGV, xcache_sigsegv_handler);
+
+	xc_init_constant(module_number TSRMLS_CC);
+
+	if ((xc_php_size || xc_var_size) && xc_mmap_path && xc_mmap_path[0]) {
+		if (!xc_init(module_number TSRMLS_CC)) {
+			zend_error(E_ERROR, "XCache: Cannot init xcache");
+			goto err_init;
+		}
+		xc_initized = 1;
+	}
+
+#ifdef HAVE_XCACHE_COVERAGE
+	xc_coverage_init(module_number TSRMLS_CC);
+#endif
+
+	return SUCCESS;
+
+err_init:
+	return FAILURE;
+}
+/* }}} */
+/* {{{ PHP_MSHUTDOWN_FUNCTION(xcache) */
+static PHP_MSHUTDOWN_FUNCTION(xcache)
+{
+	if (xc_initized) {
+		xc_destroy();
+		xc_initized = 0;
+	}
+	if (xc_mmap_path) {
+		pefree(xc_mmap_path, 1);
+		xc_mmap_path = NULL;
+	}
+
+#ifdef HAVE_XCACHE_COVERAGE
+	xc_coverage_destroy();
+#endif
+
+	signal(SIGSEGV, original_sigsegv_handler);
+	if (xc_coredump_dir) {
+		pefree(xc_coredump_dir, 1);
+		xc_coredump_dir = NULL;
+	}
+#ifndef ZTS
+	xc_shutdown_globals(&xcache_globals TSRMLS_CC);
+#endif
+
+	UNREGISTER_INI_ENTRIES();
+	return SUCCESS;
+}
+/* }}} */
+/* {{{ PHP_RINIT_FUNCTION(xcache) */
+static PHP_RINIT_FUNCTION(xcache)
+{
+	xc_request_init(TSRMLS_C);
+	return SUCCESS;
+}
+/* }}} */
+/* {{{ PHP_RSHUTDOWN_FUNCTION(xcache) */
+#ifndef ZEND_ENGINE_2
+static PHP_RSHUTDOWN_FUNCTION(xcache)
 #else
-/* old signal handlers {{{ */
-typedef void (*xc_sighandler_t)(int);
-#define FOREACH_SIG(sig) static xc_sighandler_t old_##sig##_handler = NULL
-#include "util/xc_foreachcoresig.h"
-#undef FOREACH_SIG
-/* }}} */
-static void xcache_signal_handler(int sig);
-static void xcache_restore_crash_handler() /* {{{ */
-{
-#define FOREACH_SIG(sig) do { \
-	if (old_##sig##_handler != xcache_signal_handler) { \
-		signal(sig, old_##sig##_handler); \
-	} \
-	else { \
-		signal(sig, SIG_DFL); \
-	} \
-} while (0)
-#include "util/xc_foreachcoresig.h"
-#undef FOREACH_SIG
-}
-/* }}} */
-static void xcache_init_crash_handler() /* {{{ */
-{
-#define FOREACH_SIG(sig) \
-	old_##sig##_handler = signal(sig, xcache_signal_handler)
-#include "util/xc_foreachcoresig.h"
-#undef FOREACH_SIG
-}
-/* }}} */
-static void xcache_signal_handler(int sig) /* {{{ */
-{
-	xcache_restore_crash_handler();
-	if (xc_coredump_dir && xc_coredump_dir[0]) {
-		if (chdir(xc_coredump_dir) != 0) {
-			/* error, but nothing can do about it
-			 * and should'nt print anything which might SEGV again */
-		}
-	}
-	if (xc_disable_on_crash) {
-		xc_disable_on_crash = 0;
-		xc_cacher_disable();
-	}
-	raise(sig);
-}
-/* }}} */
-#endif
-
-/* {{{ incompatible zend extensions handling */
-typedef struct {
-	const char *name;
-	startup_func_t old_startup;
-} xc_incompatible_zend_extension_info_t;
-static xc_incompatible_zend_extension_info_t xc_incompatible_zend_extensions[] = {
-	{ "Zend Optimizer", NULL },
-	{ "the ionCube PHP Loader", NULL }
+static ZEND_MODULE_POST_ZEND_DEACTIVATE_D(xcache)
+#endif
+{
+	xc_request_shutdown(TSRMLS_C);
+	return SUCCESS;
+}
+/* }}} */
+/* {{{ module definition structure */
+
+zend_module_entry xcache_module_entry = {
+	STANDARD_MODULE_HEADER,
+	"xcache",
+	xcache_functions,
+	PHP_MINIT(xcache),
+	PHP_MSHUTDOWN(xcache),
+	PHP_RINIT(xcache),
+#ifndef ZEND_ENGINE_2
+	PHP_RSHUTDOWN(xcache),
+#else
+	NULL,
+#endif
+	PHP_MINFO(xcache),
+	XCACHE_VERSION,
+#ifdef ZEND_ENGINE_2
+	ZEND_MODULE_POST_ZEND_DEACTIVATE_N(xcache),
+#else
+	NULL,
+	NULL,
+#endif
+	STANDARD_MODULE_PROPERTIES_EX
 };
-zend_llist_element **xc_zend_extension_elements;
-
-static xc_incompatible_zend_extension_info_t *xc_get_incompatible_zend_extension_info(const char *name)
-{
-	size_t i;
-
-	for (i = 0; i < sizeof(xc_incompatible_zend_extensions) / sizeof(xc_incompatible_zend_extensions[0]); ++i) {
-		xc_incompatible_zend_extension_info_t *incompatible_zend_extension_info = &xc_incompatible_zend_extensions[i];
-		if (strcmp(incompatible_zend_extension_info->name, name) == 0) {
-			return incompatible_zend_extension_info;
-		}
-	}
-
-	return NULL;
-}
-/* }}} */
-static void xc_zend_llist_add_element(zend_llist *list, zend_llist_element *element) /* {{{ */
-{
-	if (!zend_extensions.head) {
-		zend_extensions.head = zend_extensions.tail = element;
-	}
-	else {
-		zend_extensions.tail->next = element;
-		element->prev = zend_extensions.tail;
-		zend_extensions.tail = element;
-	}
-}
-/* }}} */
-static int xc_incompatible_zend_extension_startup_hook(zend_extension *extension) /* {{{ */
-{
-	xc_incompatible_zend_extension_info_t *incompatible_zend_extension_info = xc_get_incompatible_zend_extension_info(extension->name);
-	int status;
-	zend_bool catched = 0;
-	zend_llist old_zend_extensions;
-	zend_extension *ext;
-	size_t i;
-	zend_llist_element *element;
-	TSRMLS_FETCH();
-
-	/* restore */
-	extension->startup = incompatible_zend_extension_info->old_startup;
-	incompatible_zend_extension_info->old_startup = NULL;
-	assert(extension->startup);
-
-	/* save */
-	assert(!xc_zend_extension_elements);
-	old_zend_extensions = zend_extensions;
-	xc_zend_extension_elements = malloc(sizeof(zend_llist_element *) * old_zend_extensions.count);
-	for (i = 0, element = old_zend_extensions.head; element; ++i, element = element->next) {
-		xc_zend_extension_elements[i] = element;
-	}
-
-	/* hide all XCache extensions from it */
-	zend_extensions.head = NULL;
-	zend_extensions.tail = NULL;
-	zend_extensions.count = 0;
-
-	for (i = 0; i < old_zend_extensions.count; ++i) {
-		element = xc_zend_extension_elements[i];
-		element->next = element->prev = NULL;
-
-		ext = (zend_extension *) element->data;
-
-		if (!(strcmp(ext->name, XCACHE_NAME) == 0 || strncmp(ext->name, XCACHE_NAME " ", sizeof(XCACHE_NAME " ") - 1) == 0)) {
-			xc_zend_llist_add_element(&zend_extensions, element);
-			++zend_extensions.count;
-		}
-	}
-
-	assert(extension->startup != xc_incompatible_zend_extension_startup_hook);
-	zend_try {
-		status = extension->startup(extension);
-	} zend_catch {
-		catched = 1;
-	} zend_end_try();
-
-	/* restore */
-	zend_extensions = old_zend_extensions;
-	zend_extensions.head = NULL;
-	zend_extensions.tail = NULL;
-	zend_extensions.count = 0;
-	for (i = 0; i < old_zend_extensions.count; ++i) {
-		element = xc_zend_extension_elements[i];
-		element->next = element->prev = NULL;
-
-		xc_zend_llist_add_element(&zend_extensions, element);
-		++zend_extensions.count;
-	}
-
-	free(xc_zend_extension_elements);
-	xc_zend_extension_elements = NULL;
-
-	if (catched) {
-		zend_bailout();
-	}
-	return status;
-}
-/* }}} */
-static int xc_zend_startup(zend_extension *extension) /* {{{ */
-{
-	zend_llist_position lpos;
-	zend_extension *ext;
-
-	ext = (zend_extension *) zend_extensions.head->data;
-	if (strcmp(ext->name, XCACHE_NAME) != 0) {
-		zend_error(E_WARNING, "XCache failed to load itself as the before \"%s\". compatibility downgraded", ext->name);
-	}
-
-	old_compile_file = zend_compile_file;
-	zend_compile_file = xc_check_initial_compile_file;
-
-	for (ext = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &lpos);
-			ext;
-			ext = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &lpos)) {
-		xc_incompatible_zend_extension_info_t *incompatible_zend_extension_info = xc_get_incompatible_zend_extension_info(ext->name);
-		if (incompatible_zend_extension_info) {
-			assert(!incompatible_zend_extension_info->old_startup);
-			incompatible_zend_extension_info->old_startup = ext->startup;
-			ext->startup = xc_incompatible_zend_extension_startup_hook;
-		}
+
+#ifdef COMPILE_DL_XCACHE
+ZEND_GET_MODULE(xcache)
+#endif
+/* }}} */
+ZEND_DLEXPORT int xcache_zend_startup(zend_extension *extension) /* {{{ */
+{
+	if (xc_zend_extension_gotup) {
+		return FAILURE;
+	}
+	xc_zend_extension_gotup = 1;
+	if (!xc_module_gotup) {
+		return zend_startup_module(&xcache_module_entry);
 	}
 	return SUCCESS;
 }
 /* }}} */
-static void xc_zend_shutdown(zend_extension *extension) /* {{{ */
-{
+ZEND_DLEXPORT void xcache_zend_shutdown(zend_extension *extension) /* {{{ */
+{
+	/* empty */
+}
+/* }}} */
+ZEND_DLEXPORT void xcache_statement_handler(zend_op_array *op_array) /* {{{ */
+{
+#ifdef HAVE_XCACHE_COVERAGE
+	xc_coverage_handle_ext_stmt(op_array, ZEND_EXT_STMT);
+#endif
+}
+/* }}} */
+ZEND_DLEXPORT void xcache_fcall_begin_handler(zend_op_array *op_array) /* {{{ */
+{
+#if 0
+	xc_coverage_handle_ext_stmt(op_array, ZEND_EXT_FCALL_BEGIN);
+#endif
+}
+/* }}} */
+ZEND_DLEXPORT void xcache_fcall_end_handler(zend_op_array *op_array) /* {{{ */
+{
+#if 0
+	xc_coverage_handle_ext_stmt(op_array, ZEND_EXT_FCALL_END);
+#endif
 }
 /* }}} */
 /* {{{ zend extension definition structure */
-static zend_extension xc_zend_extension_entry = {
+ZEND_DLEXPORT zend_extension zend_extension_entry = {
 	XCACHE_NAME,
 	XCACHE_VERSION,
@@ -705,153 +1930,23 @@
 	XCACHE_URL,
 	XCACHE_COPYRIGHT,
-	xc_zend_startup,
-	xc_zend_shutdown,
+	xcache_zend_startup,
+	xcache_zend_shutdown,
 	NULL,           /* activate_func_t */
 	NULL,           /* deactivate_func_t */
 	NULL,           /* message_handler_func_t */
 	NULL,           /* op_array_handler_func_t */
-	NULL,           /* statement_handler_func_t */
-	NULL,           /* fcall_begin_handler_func_t */
-	NULL,           /* fcall_end_handler_func_t */
+	xcache_statement_handler,
+	xcache_fcall_begin_handler,
+	xcache_fcall_end_handler,
 	NULL,           /* op_array_ctor_func_t */
 	NULL,           /* op_array_dtor_func_t */
 	STANDARD_ZEND_EXTENSION_PROPERTIES
 };
-/* }}} */
-
-/* {{{ PHP_INI */
-PHP_INI_BEGIN()
-	PHP_INI_ENTRY1     ("xcache.coredump_directory",      "", PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_coredump_dir)
-#ifdef ZEND_WIN32
-	PHP_INI_ENTRY1     ("xcache.coredump_type",          "0", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_coredump_type)
-#endif
-	PHP_INI_ENTRY1_EX  ("xcache.disable_on_crash",       "0", PHP_INI_SYSTEM, xcache_OnUpdateBool,     &xc_disable_on_crash, zend_ini_boolean_displayer_cb)
-	PHP_INI_ENTRY1_EX  ("xcache.test",                   "0", PHP_INI_SYSTEM, xcache_OnUpdateBool,     &xc_test,             zend_ini_boolean_displayer_cb)
-	STD_PHP_INI_BOOLEAN("xcache.experimental",           "0", PHP_INI_ALL,    OnUpdateBool,        experimental,      zend_xcache_globals, xcache_globals)
-PHP_INI_END()
-/* }}} */
-static PHP_MINFO_FUNCTION(xcache) /* {{{ */
-{
-	php_info_print_table_start();
-	php_info_print_table_row(2, "XCache Version", XCACHE_VERSION);
-#ifdef XCACHE_VERSION_REVISION
-	php_info_print_table_row(2, "Revision", "r" XCACHE_VERSION_REVISION);
-#endif
-	php_info_print_table_row(2, "Modules Built", XCACHE_MODULES);
-	php_info_print_table_end();
-
-	DISPLAY_INI_ENTRIES();
-}
-/* }}} */
-static PHP_MINIT_FUNCTION(xcache) /* {{{ */
-{
-#ifndef PHP_GINIT
-	ZEND_INIT_MODULE_GLOBALS(xcache, xc_init_globals, xc_shutdown_globals);
-#endif
-	REGISTER_INI_ENTRIES();
-
-	if (xc_coredump_dir && xc_coredump_dir[0]) {
-		xcache_init_crash_handler();
-	}
-
-	if (strcmp(sapi_module.name, "cli") == 0) {
-		char *env;
-		if ((env = getenv("XCACHE_TEST")) != NULL) {
-			xc_test = (zend_bool) atoi(env);
-		}
-	}
-
-	xc_init_constant(module_number TSRMLS_CC);
-	xc_shm_init_modules();
-
-	/* must be the first */
-	xcache_zend_extension_add(&xc_zend_extension_entry, 1);
-#ifdef HAVE_XCACHE_OPTIMIZER
-	xc_optimizer_startup_module();
-#endif
-#ifdef HAVE_XCACHE_CACHER
-	xc_cacher_startup_module();
-#endif
-#ifdef HAVE_XCACHE_COVERAGER
-	xc_coverager_startup_module();
-#endif
-#ifdef HAVE_XCACHE_DISASSEMBLER
-	xc_disassembler_startup_module();
-#endif
-
-	return SUCCESS;
-}
-/* }}} */
-static PHP_MSHUTDOWN_FUNCTION(xcache) /* {{{ */
-{
-	if (old_compile_file && zend_compile_file == xc_check_initial_compile_file) {
-		zend_compile_file = old_compile_file;
-		old_compile_file = NULL;
-	}
-
-	if (xc_coredump_dir && xc_coredump_dir[0]) {
-		xcache_restore_crash_handler();
-	}
-	if (xc_coredump_dir) {
-		pefree(xc_coredump_dir, 1);
-		xc_coredump_dir = NULL;
-	}
-#ifndef PHP_GINIT
-#	ifdef ZTS
-	ts_free_id(xcache_globals_id);
-#	else
-	xc_shutdown_globals(&xcache_globals TSRMLS_CC);
-#	endif
-#endif
-
-	UNREGISTER_INI_ENTRIES();
-	xcache_zend_extension_remove(&xc_zend_extension_entry);
-	return SUCCESS;
-}
-/* }}} */
-/* {{{ module dependencies */
-#ifdef STANDARD_MODULE_HEADER_EX
-static zend_module_dep xcache_module_deps[] = {
-	ZEND_MOD_REQUIRED("standard")
-	ZEND_MOD_CONFLICTS("apc")
-	ZEND_MOD_CONFLICTS("eAccelerator")
-	ZEND_MOD_CONFLICTS("Turck MMCache")
-	ZEND_MOD_END
-};
-#endif
-/* }}} */ 
-/* {{{ module definition structure */
-zend_module_entry xcache_module_entry = {
-#ifdef STANDARD_MODULE_HEADER_EX
-	STANDARD_MODULE_HEADER_EX,
-	NULL,
-	xcache_module_deps,
-#else
-	STANDARD_MODULE_HEADER,
-#endif
-	XCACHE_NAME,
-	xcache_functions,
-	PHP_MINIT(xcache),
-	PHP_MSHUTDOWN(xcache),
-	NULL, /* RINIT */
-	NULL, /* RSHUTDOWN */
-	PHP_MINFO(xcache),
-	XCACHE_VERSION,
-#ifdef PHP_GINIT
-	PHP_MODULE_GLOBALS(xcache),
-	PHP_GINIT(xcache),
-	PHP_GSHUTDOWN(xcache),
-#endif
-#ifdef ZEND_ENGINE_2
-	NULL /* ZEND_MODULE_POST_ZEND_DEACTIVATE_N */,
-#else
-	NULL,
-	NULL,
-#endif
-	STANDARD_MODULE_PROPERTIES_EX
-};
-
-#ifdef COMPILE_DL_XCACHE
-ZEND_GET_MODULE(xcache)
-#endif
-/* }}} */
+
+#ifndef ZEND_EXT_API
+#	define ZEND_EXT_API ZEND_DLEXPORT
+#endif
+#if COMPILE_DL_XCACHE
+ZEND_EXTENSION();
+#endif
+/* }}} */
Index: /trunk/coverage.c
===================================================================
--- /trunk/coverage.c	(revision 1)
+++ /trunk/coverage.c	(revision 1)
@@ -0,0 +1,425 @@
+#include <stdio.h>
+#include "xcache.h"
+#include "ext/standard/flock_compat.h"
+#ifdef HAVE_SYS_FILE_H
+#	include <sys/file.h>
+#endif
+#include "stack.h"
+#include "xcache_globals.h"
+#include "coverage.h"
+#include "utils.h"
+typedef HashTable *coverage_t;
+#define PCOV_HEADER_MAGIC 0x564f4350
+
+char *xc_coveragedump_dir = NULL;
+static zend_compile_file_t *origin_compile_file;
+
+#undef DEBUG
+/* dumper */
+static void xc_destroy_coverage(void *pDest) /* {{{ */
+{
+	coverage_t cov = *(coverage_t*) pDest;
+#ifdef DEBUG
+	fprintf(stderr, "destroy %p\n", cov);
+#endif
+	zend_hash_destroy(cov);
+	efree(cov);
+}
+/* }}} */
+PHPAPI void xcache_mkdirs_ex(char *root, int rootlen, char *path, int pathlen TSRMLS_DC) /* {{{ */
+{
+	char *fullpath;
+	struct stat st;
+
+#ifdef DEBUG
+	fprintf(stderr, "mkdirs %s %d %s %d\n", root, rootlen, path, pathlen);
+#endif
+	fullpath = do_alloca(rootlen + pathlen + 1);
+	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;
+		}
+#ifdef DEBUG
+		fprintf(stderr, "mkdir %s\n", fullpath);
+#endif
+		php_stream_mkdir(fullpath, 0700, REPORT_ERRORS, NULL);
+	}
+	free_alloca(fullpath);
+}
+/* }}} */
+static void xc_coverage_save_cov(char *srcfile, char *outfilename, coverage_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) {
+#ifdef DEBUG
+		fprintf(stderr, "new file\n");
+#endif
+	}
+	else if (outstat.st_size) {
+		len = outstat.st_size;
+		contents = emalloc(len);
+		if (read(fd, (void *) contents, len) != len) {
+			goto bailout;
+		}
+#ifdef DEBUG
+		fprintf(stderr, "oldsize %d\n", (int) len);
+#endif
+		do {
+			p = (long *) contents;
+			len -= sizeof(long);
+			if (len < 0) {
+				break;
+			}
+			if (*p++ != PCOV_HEADER_MAGIC) {
+#ifdef DEBUG
+				fprintf(stderr, "wrong magic in file %s\n", outfilename);
+#endif
+				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] <= 0) {
+						/* already marked */
+						continue;
+					}
+					if (*phits > 0) {
+						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;
+		if (*phits <= 0) {
+			*p++ = 0;
+		}
+		else {
+			*p++ = *phits;
+			covlines ++;
+		}
+		zend_hash_move_forward_ex(cov, &pos);
+	}
+	p = buf + 1;
+	p[0] = 0;
+	p[1] = covlines;
+
+	ftruncate(fd, 0);
+	lseek(fd, 0, SEEK_SET);
+	write(fd, (char *) buf, size);
+
+bailout:
+	if (contents) efree(contents);
+	if (fd >= 0) close(fd);
+	if (buf) efree(buf);
+}
+/* }}} */
+void xc_coverage_request_init(TSRMLS_D) /* {{{ */
+{
+	if (XG(coveragedumper)) {
+		XG(coverages) = emalloc(sizeof(HashTable));
+		zend_hash_init(XG(coverages), 0, NULL, xc_destroy_coverage, 0);
+	}
+}
+/* }}} */
+void xc_coverage_request_shutdown(TSRMLS_D) /* {{{ */
+{
+	coverage_t *pcov;
+	zstr s;
+	char *outfilename;
+	int dumpdir_len, outfilelen, size, alloc_len = 0;
+
+	if (!XG(coverages)) {
+		return;
+	}
+	if (XG(coveragedumper)) {	
+		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(XG(coverages));
+		while (zend_hash_get_current_data(XG(coverages), (void **) &pcov) == SUCCESS) {
+			zend_hash_get_current_key_ex(XG(coverages), &s, &size, NULL, 0, NULL);
+			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");
+
+#ifdef DEBUG
+			fprintf(stderr, "outfilename %s\n", outfilename);
+#endif
+			xc_coverage_save_cov(ZSTR_S(s), outfilename, *pcov TSRMLS_CC);
+			zend_hash_move_forward(XG(coverages));
+		}
+	}
+
+	zend_hash_destroy(XG(coverages));
+	efree(XG(coverages));
+	XG(coverages) = NULL;
+}
+/* }}} */
+
+/* helper func to store hits into coverages */
+static coverage_t xc_coverage_get(char *filename TSRMLS_DC) /* {{{ */
+{
+	int len = strlen(filename) + 1;
+	coverage_t cov, *pcov;
+
+	if (zend_hash_find(XG(coverages), filename, len, (void **) &pcov) == SUCCESS) {
+#ifdef DEBUG
+		fprintf(stderr, "got coverage %s %p\n", filename, *pcov);
+#endif
+		return *pcov;
+	}
+	else {
+		cov = emalloc(sizeof(HashTable));
+		zend_hash_init(cov, 0, NULL, NULL, 0);
+		zend_hash_add(XG(coverages), filename, len, (void **) &cov, sizeof(cov), NULL);
+#ifdef DEBUG
+		fprintf(stderr, "new coverage %s %p\n", filename, cov);
+#endif
+		return cov;
+	}
+}
+/* }}} */
+static void xc_coverage_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) {
+			/* already marked */
+			return;
+		}
+		if (*poldhits != -1) {
+			hits += *poldhits;
+		}
+	}
+	zend_hash_index_update(cov, line, &hits, sizeof(hits), NULL);
+}
+/* }}} */
+
+static int xc_coverage_get_op_array_size_no_tail(zend_op_array *op_array) /* {{{ */
+{
+	zend_uint size;
+
+	size = op_array->size;
+#ifdef ZEND_ENGINE_2
+	if (op_array->opcodes[size - 1].opcode == ZEND_HANDLE_EXCEPTION) {
+		size --;
+#endif
+		if (op_array->opcodes[size - 1].opcode == ZEND_RETURN) {
+			size --;
+			/* it's not real php statement */
+			if (op_array->opcodes[size - 1].opcode == ZEND_EXT_STMT) {
+				size --;
+			}
+		}   
+#ifdef ZEND_ENGINE_2
+	}
+#endif
+	return size;
+}
+/* }}} */
+
+/* prefill */
+static int xc_coverage_init_op_array(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	zend_uint size;
+	coverage_t cov;
+	int i;
+
+	if (op_array->type != ZEND_USER_FUNCTION) {
+		return 0;
+	}
+
+	size = xc_coverage_get_op_array_size_no_tail(op_array);
+	cov = xc_coverage_get(op_array->filename);
+	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_coverage_add_hits(cov, op_array->opcodes[i].lineno, -1 TSRMLS_CC);
+				break;
+		}
+	}
+	return 0;
+}
+/* }}} */
+static void xc_coverage_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_coverage_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 = origin_compile_file(h, type TSRMLS_CC);
+	if (XG(coveragedumper) && XG(coverages)) {
+		xc_coverage_init_compile_result(op_array TSRMLS_CC);
+	}
+	return op_array;
+}
+/* }}} */
+
+/* hits */
+void xc_coverage_handle_ext_stmt(zend_op_array *op_array, zend_uchar op) /* {{{ */
+{
+	if (XG(coveragedumper) && XG(coverages)) {
+		TSRMLS_FETCH();
+		int size = xc_coverage_get_op_array_size_no_tail(op_array);
+		int oplineno = (*EG(opline_ptr)) - op_array->opcodes;
+		if (oplineno < size) {
+			xc_coverage_add_hits(xc_coverage_get(op_array->filename), (*EG(opline_ptr))->lineno, 1 TSRMLS_CC);
+		}
+	}
+}
+/* }}} */
+
+/* init/destroy */
+int xc_coverage_init(int module_number TSRMLS_DC) /* {{{ */
+{
+	if (xc_coveragedump_dir) {
+		int len = strlen(xc_coveragedump_dir);
+		if (len) {
+			if (xc_coveragedump_dir[len - 1] == '/') {
+				xc_coveragedump_dir[len - 1] = '\0';
+			}
+		}
+	}
+	if (xc_coveragedump_dir && xc_coveragedump_dir[0]) {
+		origin_compile_file = zend_compile_file;
+		zend_compile_file = xc_compile_file_for_coverage;
+		CG(extended_info) = 1;
+	}
+	return SUCCESS;
+}
+/* }}} */
+void xc_coverage_destroy() /* {{{ */
+{
+	if (origin_compile_file == xc_compile_file_for_coverage) {
+		zend_compile_file = origin_compile_file;
+	}
+	if (xc_coveragedump_dir) {
+		pefree(xc_coveragedump_dir, 1);
+		xc_coveragedump_dir = NULL;
+	}
+}
+/* }}} */
+
+/* user api */
+PHP_FUNCTION(xcache_coverage_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) {
+#ifdef DEBUG
+		fprintf(stderr, "wrong magic in xcache_coverage_decode");
+#endif
+		return;
+	}
+
+	for (; len >= sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
+		add_index_long(return_value, p[0], p[1]);
+	}
+}
+/* }}} */
+
Index: /trunk/Decompiler.class.php
===================================================================
--- /trunk/Decompiler.class.php	(revision 1)
+++ /trunk/Decompiler.class.php	(revision 1)
@@ -0,0 +1,1886 @@
+<?php
+
+define('INDENT', "\t");
+ini_set('error_reporting', E_ALL);
+
+function color($str, $color = 33)
+{
+	return "\x1B[{$color}m$str\x1B[0m";
+}
+
+function str($src, $indent = '') // {{{
+{
+	if (is_array($indent)) {
+		$indent = $indent['indent'];
+	}
+
+	/*
+	$e = xcache_get_special_value($src);
+	if (isset($e)) {
+		if (is_array($e)) {
+			$src = $e;
+		}
+		else {
+			return $e;
+		}
+	}
+	*/
+
+	if (is_array($src)) {
+		die_error('array str');
+		$src = new Decompiler_Array($src);
+		return $src->__toString($indent);
+	}
+
+	if (is_object($src)) {
+		if (!method_exists($src, '__toString')) {
+			var_dump($src);
+			die_error('no __toString');
+		}
+		return $src->__toString($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_array($value)) {
+		$value = new Decompiler_Array($value, true);
+	}
+	else {
+		$value = new Decompiler_Value($value, true);
+	}
+	return $value;
+}
+// }}}
+class Decompiler_Object // {{{
+{
+}
+// }}}
+class Decompiler_Value extends Decompiler_Object // {{{
+{
+	var $value;
+
+	function Decompiler_Value($value = null)
+	{
+		$this->value = $value;
+	}
+
+	function __toString()
+	{
+		return var_export($this->value, true);
+	}
+}
+// }}}
+class Decompiler_Code extends Decompiler_Object // {{{
+{
+	var $src;
+
+	function Decompiler_Code($src)
+	{
+		$this->src = $src;
+	}
+
+	function __toString()
+	{
+		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 __toString()
+	{
+		$op1 = str($this->op1);
+		if (is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) {
+			$op1 = "($op1)";
+		}
+		$opstr = $this->parent->binops[$this->opc];
+		if ($op1 == '0' && $this->opc == XC_SUB) {
+			return $opstr . str($this->op2);
+		}
+		return $op1 . ' ' . $opstr . ' ' . str($this->op2);
+	}
+}
+// }}}
+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 __toString()
+	{
+		switch ($this->fetchType) {
+		case ZEND_FETCH_LOCAL:
+			return '$' . substr($this->src, 1, -1);
+		case ZEND_FETCH_STATIC:
+			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 __toString($indent)
+	{
+		return $this->obj->__toString($indent);
+	}
+}
+// }}}
+class Decompiler_Dim extends Decompiler_Value // {{{
+{
+	var $offsets = array();
+	var $isLast = false;
+	var $assign = null;
+
+	function __toString()
+	{
+		if (is_a($this->value, 'Decompiler_ListBox')) {
+			$exp = str($this->value->obj->src);
+		}
+		else {
+			$exp = str($this->value);
+		}
+		foreach ($this->offsets as $dim) {
+			$exp .= '[' . str($dim) . ']';
+		}
+		return $exp;
+	}
+}
+// }}}
+class Decompiler_DimBox extends Decompiler_Box // {{{
+{
+}
+// }}}
+class Decompiler_List extends Decompiler_Code // {{{
+{
+	var $src;
+	var $dims = array();
+	var $everLocked = false;
+
+	function __toString()
+	{
+		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);
+			}
+			return str($this->dims[0]->assign) . ' = ' . str($dim);
+		}
+		/* flatten dims */
+		$assigns = array();
+		foreach ($this->dims as $dim) {
+			$assign = &$assigns;
+			foreach ($dim->offsets as $offset) {
+				$assign = &$assign[$offset];
+			}
+			$assign = str($dim->assign);
+		}
+		return $this->toList($assigns) . ' = ' . str($this->src);
+	}
+
+	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 // {{{
+{
+	var $needExport = false;
+
+	function Decompiler_Array($value = array(), $needexport = false)
+	{
+		$this->value = $value;
+		$this->needExport = $needexport;
+	}
+
+	function __toString($indent)
+	{
+		$exp = "array(";
+		$indent .= INDENT;
+		$assoclen = 0;
+		$multiline = 0;
+		$i = 0;
+		foreach ($this->value as $k => $v) {
+			if ($i !== $k) {
+				$len = strlen($k);
+				if ($assoclen < $len) {
+					$assoclen = $len;
+				}
+			}
+			if (is_array($v)) {
+				$multiline ++;
+			}
+			++ $i;
+		}
+		if ($assoclen && $this->needExport) {
+			$assoclen += 2;
+		}
+
+		$i = 0;
+		$subindent = $indent . INDENT;
+		foreach ($this->value as $k => $v) {
+			if ($multiline) {
+				if ($i) {
+					$exp .= ",";
+				}
+				$exp .= "\n";
+				$exp .= $indent;
+			}
+			else {
+				if ($i) {
+					$exp .= ", ";
+				}
+			}
+
+			if ($this->needExport) {
+				$k = var_export($k, true);
+			}
+			if ($multiline) {
+				$exp .= sprintf("%{$assoclen}s => ", $k);
+			}
+			else if ($assoclen) {
+				$exp .= $k . ' => ';
+			}
+
+			if (is_array($v)) {
+				$v = new Decompiler_Array($v, $this->needExport);
+			}
+			$exp .= str($v, $subindent);
+
+			$i ++;
+		}
+		if ($multiline) {
+			$exp .= "$indent);";
+		}
+		else {
+			$exp .= ")";
+		}
+		return $exp;
+	}
+}
+// }}}
+class Decompiler_ForeachBox extends Decompiler_Box // {{{
+{
+	var $iskey;
+
+	function __toString($indent)
+	{
+		return 'foreach (' . '';
+	}
+}
+// }}}
+
+class Decompiler
+{
+	var $rName = '!^[\\w_][\\w\\d_]*$!';
+	var $rQuotedName = "!^'[\\w_][\\w\\d_]*'\$!";
+
+	function Decompiler()
+	{
+		// {{{ 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",
+				);
+		// }}}
+		$this->includeTypes = array( // {{{
+				ZEND_EVAL         => 'eval',
+				ZEND_INCLUDE      => 'include',
+				ZEND_INCLUDE_ONCE => 'include_once',
+				ZEND_REQUIRE      => 'require',
+				ZEND_REQUIRE_ONCE => 'require_once',
+				);
+				// }}}
+	}
+	function outputPhp(&$opcodes, $opline, $last, $indent) // {{{
+	{
+		$origindent = $indent;
+		$curticks = 0;
+		for ($i = $opline; $i <= $last; $i ++) {
+			$op = $opcodes[$i];
+			if (isset($op['php'])) {
+				$toticks = isset($op['ticks']) ? $op['ticks'] : 0;
+				if ($curticks != $toticks) {
+					if (!$toticks) {
+						echo $origindent, "}\n";
+						$indent = $origindent;
+					}
+					else {
+						if ($curticks) {
+							echo $origindent, "}\n";
+						}
+						else if (!$curticks) {
+							$indent .= INDENT;
+						}
+						echo $origindent, "declare(ticks=$curticks) {\n";
+					}
+					$curticks = $toticks;
+				}
+				echo $indent, str($op['php']), ";\n";
+			}
+		}
+		if ($curticks) {
+			echo $origindent, "}\n";
+		}
+	}
+	// }}}
+	function getOpVal($op, &$EX, $tostr = true, $free = false) // {{{
+	{
+		switch ($op['op_type']) {
+		case XC_IS_CONST:
+			return str(value($op['u.constant']));
+
+		case XC_IS_VAR:
+		case XC_IS_TMP_VAR:
+			$T = &$EX['Ts'];
+			$ret = $T[$op['u.var']];
+			if ($tostr) {
+				$ret = str($ret, $EX);
+			}
+			if ($free) {
+				unset($T[$op['u.var']]);
+			}
+			return $ret;
+
+		case XC_IS_CV:
+			$var = $op['u.var'];
+			$var = $EX['op_array']['vars'][$var];
+			return '$' . $var['name'];
+
+		case XC_IS_UNUSED:
+			return null;
+		}
+	}
+	// }}}
+	function &dop_array($op_array, $indent = '') // {{{
+	{
+		$opcodes = &$op_array['opcodes'];
+		$last = count($opcodes) - 1;
+		if ($opcodes[$last]['opcode'] == XC_HANDLE_EXCEPTION) {
+			unset($opcodes[$last]);
+		}
+		$EX['indent'] = '';
+		//for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) {
+		//	$opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i);
+		//}
+		// {{{ build jmp array
+		for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) {
+			$op = &$opcodes[$i];
+			/*
+			if ($op['opcode'] == XC_JMPZ) {
+				$this->dumpop($op, $EX);
+				var_dump($op);
+			}
+			continue;
+			*/
+			$op['line'] = $i;
+			switch ($op['opcode']) {
+			case XC_JMP:
+				$target = $op['op1']['u.var'];
+				$op['jmpouts'] = array($target);
+				$opcodes[$target]['jmpins'][] = $i;
+				break;
+
+			case XC_JMPZNZ:
+				$jmpz = $op['op2']['u.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_FE_RESET:
+			case XC_FE_FETCH:
+			// case XC_JMP_NO_CTOR:
+				$target = $op['op2']['u.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;
+			*/
+			}
+		}
+		unset($op);
+		// }}}
+		// build semi-basic blocks
+		$nextbbs = array();
+		$starti = 0;
+		for ($i = 1, $cnt = count($opcodes); $i < $cnt; $i ++) {
+			if (isset($opcodes[$i]['jmpins'])
+			 || isset($opcodes[$i - 1]['jmpouts'])) {
+				$nextbbs[$starti] = $i;
+				$starti = $i;
+			}
+		}
+		$nextbbs[$starti] = $cnt;
+
+		$EX = array();
+		$EX['Ts'] = array();
+		$EX['indent'] = $indent;
+		$EX['nextbbs'] = $nextbbs;
+		$EX['op_array'] = &$op_array;
+		$EX['opcodes'] = &$opcodes;
+		// func call
+		$EX['object'] = null;
+		$EX['fbc'] = null;
+		$EX['argstack'] = array();
+		$EX['arg_types_stack'] = array();
+		$EX['last'] = count($opcodes) - 1;
+		$EX['silence'] = 0;
+
+		for ($next = 0, $last = $EX['last'];
+				$loop = $this->outputCode($EX, $next, $last, $indent, true);
+				list($next, $last) = $loop) {
+			// empty
+		}
+		return $EX;
+	}
+	// }}}
+	function outputCode(&$EX, $opline, $last, $indent, $loop = false) // {{{
+	{
+		$op = &$EX['opcodes'][$opline];
+		$next = $EX['nextbbs'][$opline];
+
+		$end = $next - 1;
+		if ($end > $last) {
+			$end = $last;
+		}
+
+		if (isset($op['jmpins'])) {
+			echo "\nline", $op['line'], ":\n";
+		}
+		else {
+			// echo ";;;\n";
+		}
+		$this->dasmBasicBlock($EX, $opline, $end);
+		$this->outputPhp($EX['opcodes'], $opline, $end, $indent);
+		// jmpout op
+		$op = &$EX['opcodes'][$end];
+		$op1 = $op['op1'];
+		$op2 = $op['op2'];
+		$ext = $op['extended_value'];
+		$line = $op['line'];
+
+		if (isset($EX['opcodes'][$next])) {
+			if (isset($last) && $next > $last) {
+				$next = null;
+			}
+		}
+		else {
+			$next = null;
+		}
+		if ($op['opcode'] == XC_FE_FETCH) {
+			$opline = $next;
+			$next = $op['op2']['u.opline_num'];
+			$end = $next - 1;
+
+			ob_start();
+			$this->outputCode($EX, $opline, $end /* - 1 skip last jmp */, $indent . INDENT);
+			$body = ob_get_clean();
+
+			$as = str($op['fe_as']);
+			if (isset($op['fe_key'])) {
+				$as = str($op['fe_key']) . ' => ' . $as;
+			}
+			echo "{$indent}foreach (" . str($op['fe_src']) . " as $as) {\n";
+			echo $body;
+			echo "{$indent}}";
+			// $this->outputCode($EX, $next, $last, $indent);
+			// return;
+		}
+		/*
+		if ($op['opcode'] == XC_JMPZ) {
+			$target = $op2['u.opline_num'];
+			if ($line + 1) {
+				$nextblock = $EX['nextbbs'][$next];
+				$jmpop = end($nextblock);
+				if ($jmpop['opcode'] == XC_JMP) {
+					$ifendline = $op2['u.opline_num'];
+					if ($ifendline >= $line) {
+						$cond = $op['cond'];
+						echo "{$indent}if ($cond) {\n";
+						$this->outputCode($EX, $next, $last, INDENT . $indent);
+						echo "$indent}\n";
+						$this->outputCode($EX, $target, $last, $indent);
+						return;
+					}
+				}
+			}
+		}
+		*/
+		if (!isset($next)) {
+			return;
+		}
+		if (!empty($op['jmpouts']) && isset($op['isjmp'])) {
+			if (isset($op['cond'])) {
+				echo "{$indent}check ($op[cond]) {\n";
+				echo INDENT;
+			}
+			echo $indent;
+			echo xcache_get_opcode($op['opcode']), ' line', $op['jmpouts'][0];
+			if (isset($op['jmpouts'][1])) {
+				echo ', line', $op['jmpouts'][1];
+			}
+			echo ";";
+			// echo ' // <- line', $op['line'];
+			echo "\n";
+			if (isset($op['cond'])) echo "$indent}\n";
+		}
+
+		// proces JMPZ_EX/JMPNZ_EX for AND,OR
+		$op = &$EX['opcodes'][$next];
+		/*
+		if (isset($op['jmpins'])) {
+			foreach (array_reverse($op['jmpins']) as $fromline) {
+				$fromop = $EX['opcodes'][$fromline];
+				switch ($fromop['opcode']) {
+				case XC_JMPZ_EX: $opstr = 'and'; break;
+				case XC_JMPNZ_EX: $opstr = 'or'; break;
+				case XC_JMPZNZ: var_dump($fromop); exit;
+				default: continue 2;
+				}
+
+				$var = $fromop['result']['u.var'];
+				var_dump($EX['Ts'][$var]);
+				$EX['Ts'][$var] = '(' . $fromop['and_or'] . " $opstr " . $EX['Ts'][$var] . ')';
+			}
+			#$this->outputCode($EX, $next, $last, $indent);
+			#return;
+		}
+		*/
+		if (isset($op['cond_false'])) {
+			// $this->dumpop($op, $EX);
+			// any true comes here, so it's a "or"
+			$cond = implode(' and ', $op['cond_false']);
+			// var_dump($op['cond'] = $cond);
+			/*
+			$rvalue = implode(' or ', $op['cond_true']) . ' or ' . $rvalue;
+			unset($op['cond_true']);
+			*/
+		}
+
+		if ($loop) {
+			return array($next, $last);
+		}
+		$this->outputCode($EX, $next, $last, $indent);
+	}
+	// }}}
+	function unquoteName($str) // {{{
+	{
+		if (preg_match($this->rQuotedName, $str)) {
+			$str = substr($str, 1, -1);
+		}
+		return $str;
+	}
+	// }}}
+	function dasmBasicBlock(&$EX, $opline, $last) // {{{
+	{
+		$T = &$EX['Ts'];
+		$opcodes = &$EX['opcodes'];
+		$lastphpop = null;
+
+		for ($i = $opline, $ic = $last + 1; $i < $ic; $i ++) {
+			// {{{ prepair
+			$op = &$opcodes[$i];
+			$opc = $op['opcode'];
+			if ($opc == XC_NOP) {
+				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;
+			}
+			// $this->dumpop($op, $EX); //var_dump($op);
+
+			$resvar = null;
+			if (($res['u.EA.type'] & EXT_TYPE_UNUSED) || $res['op_type'] == XC_IS_UNUSED) {
+				$istmpres = false;
+			}
+			else {
+				$istmpres = true;
+			}
+			// }}}
+			// echo $opname, "\n";
+
+			$call = array(&$this, $opname);
+			if (is_callable($call)) {
+				$this->{$opname}($op, $EX);
+			}
+			else if (isset($this->binops[$opc])) { // {{{
+				$op1val = $this->getOpVal($op1, $EX, false);
+				$op2val = $this->getOpVal($op2, $EX, false);
+				$rvalue = new Decompiler_Binop($this, $op1val, $opc, $op2val);
+				$resvar = $rvalue;
+				// }}}
+			}
+			else if (isset($this->unaryops[$opc])) { // {{{
+				$op1val = $this->getOpVal($op1, $EX);
+				$myop = $this->unaryops[$opc];
+				$rvalue = "$myop$op1val";
+				$resvar = $rvalue;
+				// }}}
+			}
+			else {
+				switch ($opc) {
+				case XC_NEW: // {{{
+					array_push($EX['arg_types_stack'], array($EX['object'], $EX['fbc']));
+					$EX['object'] = (int) $res['u.var'];
+					$EX['fbc'] = 'new ' . $this->unquoteName($this->getOpVal($op1, $EX));
+					if (PHP_VERSION < 5) {
+						$resvar = '$new object$';
+					}
+					break;
+					// }}}
+				case XC_FETCH_CLASS: // {{{
+					if ($op2['op_type'] == XC_IS_UNUSED) {
+						switch ($ext) {
+						case ZEND_FETCH_CLASS_SELF:
+							$class = 'self';
+							break;
+						case ZEND_FETCH_CLASS_PARENT:
+							$class = 'parent';
+						}
+					}
+					else {
+						$class = $op2['u.constant'];
+						if (is_object($class)) {
+							$class = get_class($class);
+						}
+					}
+					$resvar = $class;
+					break;
+					// }}}
+				case XC_FETCH_CONSTANT: // {{{
+					if ($op1['op_type'] == XC_IS_CONST) {
+						$resvar = $op1['u.constant'];
+					}
+					else if ($op1['op_type'] == XC_IS_UNUSED) {
+						$resvar = $op2['u.constant'];
+					}
+					else {
+						$class = $T[$op1['u.var']];
+						assert($class[0] == 'class');
+						$resvar = $class[1] . '::' . $op2['u.constant'];
+					}
+					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);
+					$fetchtype = $op2[PHP_VERSION < 5 ? 'u.fetch_type' : 'u.EA.type'];
+					switch ($fetchtype) {
+					case ZEND_FETCH_STATIC_MEMBER:
+						$class = $this->getOpVal($op2, $EX);
+						$rvalue = $class . '::$' . $this->unquoteName($rvalue);
+						break;
+					default:
+						$name = $this->unquoteName($rvalue);
+						$globalname = xcache_is_autoglobal($name) ? "\$$name" : "\$GLOBALS[$rvalue]";
+						$rvalue = new Decompiler_Fetch($rvalue, $fetchtype, $globalname);
+						break;
+					}
+					if ($opc == XC_UNSET_VAR) {
+						$op['php'] = "unset(" . str($rvalue) . ")";
+						$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:
+				case XC_UNSET_DIM_OBJ:
+					$src = $this->getOpVal($op1, $EX, false);
+					if (is_a($src, "Decompiler_ForeachBox")) {
+						$src->iskey = $this->getOpVal($op2, $EX);
+						$resvar = $src;
+						break;
+					}
+					else if (is_a($src, "Decompiler_DimBox")) {
+						$dimbox = $src;
+					}
+					else {
+						if (!is_a($src, "Decompiler_ListBox")) {
+							$list = new Decompiler_List($this->getOpVal($op1, $EX, false));
+
+							$src = new Decompiler_ListBox($list);
+							if (!isset($op1['u.var'])) {
+								$this->dumpop($op, $EX);
+								var_dump($op);
+								die('missing u.var');
+							}
+							$T[$op1['u.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;
+					}
+					unset($dim);
+					$rvalue = $dimbox;
+
+					if ($opc == XC_ASSIGN_DIM) {
+						$lvalue = $rvalue;
+						++ $i;
+						$rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX);
+						$resvar = str($lvalue) . ' = ' . $rvalue;
+					}
+					else if ($opc == XC_UNSET_DIM) {
+						$op['php'] = "unset(" . str($rvalue) . ")";
+						$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, false);
+					if (is_a($rvalue, 'Decompiler_ForeachBox')) {
+						$type = $rvalue->iskey ? 'fe_key' : 'fe_as';
+						$rvalue->obj[$type] = $lvalue;
+						unset($T[$op2['u.var']]);
+						break;
+					}
+					if (is_a($rvalue, "Decompiler_DimBox")) {
+						$dim = &$rvalue->obj;
+						$dim->assign = $lvalue;
+						if ($dim->isLast) {
+							$resvar = str($dim->value);
+						}
+						unset($dim);
+						break;
+					}
+					$resvar = "$lvalue = " . str($rvalue, $EX);
+					break;
+					// }}}
+				case XC_ASSIGN_REF: // {{{
+					$lvalue = $this->getOpVal($op1, $EX);
+					$rvalue = $this->getOpVal($op2, $EX, false);
+					if (is_a($rvalue, 'Decompiler_Fetch')) {
+						$src = str($rvalue->src);
+						if (substr($src, 1, -1) == substr($lvalue, 1)) {
+							switch ($rvalue->fetchType) {
+							case ZEND_FETCH_GLOBAL:
+								$resvar = 'global ' . $lvalue;
+								break 2;
+							case ZEND_FETCH_STATIC:
+								$statics = &$EX['op_array']['static_variables'];
+								$resvar = 'static ' . $lvalue;
+								$name = substr($src, 1, -1);
+								if (isset($statics[$name])) {
+									$var = $statics[$name];
+									$resvar .= ' = ';
+									$resvar .= str(value($var), $EX);
+								}
+								unset($statics);
+								break 2;
+							}
+						}
+					}
+					$rvalue = str($rvalue);
+					$resvar = "$lvalue = &$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';
+					}
+					$prop = $this->getOpVal($op2, $EX);
+					if (preg_match($this->rQuotedName, $prop)) {
+						$prop = substr($prop, 1, -1);;
+						$rvalue = "{$obj}->$prop";
+					}
+					else {
+						$rvalue = "{$obj}->{" . "$prop}";
+					}
+					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 = $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);;
+						if (preg_match($this->rQuotedName, $rvalue)) {
+							$rvalue = '$' . substr($rvalue, 1, -1);
+						}
+						else {
+							$rvalue = "${" . $rvalue . "}";
+						}
+						if ($op2['u.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);
+						$rvalue = $container . "[$dim]";
+					}
+
+					switch (PHP_VERSION < 5 ? $op['op2']['u.var'] /* u.constant */ : $ext) {
+					case ZEND_ISSET:
+						$rvalue = "isset($rvalue)";
+						break;
+					case ZEND_ISEMPTY:
+						$rvalue = "empty($rvalue)";
+						break;
+					default:
+						$this->dumpop($op, $EX);
+						die_error('1');
+					}
+					$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 . $this->getOpVal($op1, $EX);
+					break;
+					// }}}
+				case XC_INIT_METHOD_CALL:
+				case XC_INIT_FCALL_BY_FUNC:
+				case XC_INIT_FCALL_BY_NAME: // {{{
+					if (($ext & ZEND_CTOR_CALL)) {
+						break;
+					}
+					array_push($EX['arg_types_stack'], array($EX['object'], $EX['fbc']));
+					if ($opc == XC_INIT_METHOD_CALL || $op1['op_type'] != XC_IS_UNUSED) {
+						$obj = $this->getOpVal($op1, $EX);
+						if (!isset($obj)) {
+							$obj = '$this';
+						}
+						$EX['object'] = $obj;
+						if ($res['op_type'] != XC_IS_UNUSED) {
+							$resvar = '$obj call$';
+						}
+					}
+					else {
+						$EX['object'] = null;
+					}
+
+					if ($opc == XC_INIT_FCALL_BY_FUNC) {
+						$which = $op1['u.var'];
+						$EX['fbc'] = $EX['op_array']['funcs'][$which]['name'];
+					}
+					else {
+						$EX['fbc'] = $this->getOpVal($op2, $EX, false);
+					}
+					break;
+					// }}}
+				case XC_DO_FCALL_BY_FUNC:
+					$which = $op1['u.var'];
+					$fname = $EX['op_array']['funcs'][$which]['name'];
+					$args = $this->popargs($EX, $ext);
+					$resvar = $fname . "($args)";
+					break;
+				case XC_DO_FCALL:
+					$fname = $this->unquoteName($this->getOpVal($op1, $EX, false));
+					$args = $this->popargs($EX, $ext);
+					$resvar = $fname . "($args)";
+					break;
+				case XC_DO_FCALL_BY_NAME: // {{{
+					$object = null;
+
+					$fname = $this->unquoteName($EX['fbc']);
+					if (!is_int($EX['object'])) {
+						$object = $EX['object'];
+					}
+
+					$args = $this->popargs($EX, $ext);
+
+					$resvar =
+						(isset($object) ? $object . '->' : '' )
+						. $fname . "($args)";
+					unset($args);
+
+					if (is_int($EX['object'])) {
+						$T[$EX['object']] = $resvar;
+						$resvar = null;
+					}
+					list($EX['object'], $EX['fbc']) = array_pop($EX['arg_types_stack']);
+					break;
+					// }}}
+				case XC_VERIFY_ABSTRACT_CLASS: // {{{
+					//unset($T[$op1['u.var']]);
+					break;
+					// }}}
+				case XC_DECLARE_CLASS: 
+				case XC_DECLARE_INHERITED_CLASS: // {{{
+					$key = $op1['u.constant'];
+					$class = &$this->dc['class_table'][$key];
+					if (!isset($class)) {
+						echo 'class not found: ' . $key;
+						exit;
+					}
+					$class['name'] = $this->unquoteName($this->getOpVal($op2, $EX));
+					if ($opc == XC_DECLARE_INHERITED_CLASS) {
+						$ext /= XC_SIZEOF_TEMP_VARIABLE;
+						$class['parent'] = $T[$ext];
+						unset($T[$ext]);
+					}
+					else {
+						$class['parent'] = null;
+					}
+
+					while ($i + 2 < $ic
+					 && $opcodes[$i + 2]['opcode'] == XC_ADD_INTERFACE
+					 && $opcodes[$i + 2]['op1']['u.var'] == $res['u.var']
+					 && $opcodes[$i + 1]['opcode'] == XC_FETCH_CLASS) {
+						$fetchop = &$opcodes[$i + 1];
+						$impl = $this->unquoteName($this->getOpVal($fetchop['op2'], $EX));
+						$addop = &$opcodes[$i + 2];
+						$class['interfaces'][$addop['extended_value']] = $impl;
+						unset($fetchop, $addop);
+						$i += 2;
+					}
+					$this->dclass($class);
+					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 = str(chr($op2val), $EX);
+						break;
+					case XC_ADD_STRING:
+						$op2val = str($op2val, $EX);
+						break;
+					case XC_ADD_VAR:
+						break;
+					}
+					if ($op1val == "''") {
+						$rvalue = $op2val;
+					}
+					else if ($op2val == "''") {
+						$rvalue = $op1val;
+					}
+					else {
+						$rvalue = $op1val . ' . ' . $op2val;
+					}
+					$resvar = $rvalue;
+					// }}}
+					break;
+				case XC_PRINT: // {{{
+					$op1val = $this->getOpVal($op1, $EX);
+					$resvar = "print($op1val)";
+					break;
+					// }}}
+				case XC_ECHO: // {{{
+					$op1val = $this->getOpVal($op1, $EX);
+					$resvar = "echo $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, false, true);
+
+					if ($opc == XC_ADD_ARRAY_ELEMENT) {
+						$offset = $this->getOpVal($op2, $EX);
+						if (isset($offset)) {
+							$T[$res['u.var']]->value[$offset] = $rvalue;
+						}
+						else {
+							$T[$res['u.var']]->value[] = $rvalue;
+						}
+					}
+					else {
+						if ($opc == XC_INIT_ARRAY) {
+							$resvar = new Decompiler_Array();
+							if (!isset($rvalue)) {
+								continue;
+							}
+						}
+
+						$offset = $this->getOpVal($op2, $EX);
+						if (isset($offset)) {
+							$resvar->value[$offset] = $rvalue;
+						}
+						else {
+							$resvar->value[] = $rvalue;
+						}
+					}
+					break;
+					// }}}
+				case XC_QM_ASSIGN: // {{{
+					$resvar = $this->getOpVal($op1, $EX);
+					break;
+					// }}}
+				case XC_BOOL: // {{{
+					$resvar = /*'(bool) ' .*/ $this->getOpVal($op1, $EX);
+					break;
+					// }}}
+				case XC_RETURN: // {{{
+					$resvar = "return " . $this->getOpVal($op1, $EX);
+					break;
+					// }}}
+				case XC_INCLUDE_OR_EVAL: // {{{
+					$type = $op2['u.var']; // hack
+					$keyword = $this->includeTypes[$type];
+					$resvar = "$keyword(" . $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);
+					$fe = new Decompiler_ForeachBox($op);
+					$fe->iskey = false;
+					$T[$res['u.var']] = $fe;
+
+					++ $i;
+					if (($ext & ZEND_FE_FETCH_WITH_KEY)) {
+						$fe = new Decompiler_ForeachBox($op);
+						$fe->iskey = true;
+
+						$res = $opcodes[$i]['result'];
+						$T[$res['u.var']] = $fe;
+					}
+					break;
+					// }}}
+				case XC_SWITCH_FREE: // {{{
+					// unset($T[$op1['u.var']]);
+					break;
+					// }}}
+				case XC_FREE: // {{{
+					$free = $T[$op1['u.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['u.var']], $free);
+					break;
+					// }}}
+				case XC_JMP_NO_CTOR:
+					break;
+				case XC_JMPNZ: // while
+				case XC_JMPZNZ: // for
+				case XC_JMPZ_EX: // and
+				case XC_JMPNZ_EX: // or
+				case XC_JMPZ: // {{{
+					if ($opc == XC_JMP_NO_CTOR && $EX['object']) {
+						$rvalue = $EX['object'];
+					}
+					else {
+						$rvalue = $this->getOpVal($op1, $EX);
+					}
+
+					if (isset($op['cond_true'])) {
+						// any true comes here, so it's a "or"
+						$rvalue = implode(' or ', $op['cond_true']) . ' or ' . $rvalue;
+						unset($op['cond_true']);
+					}
+					if (isset($op['cond_false'])) {
+						var_dump($op);// exit;
+					}
+					if ($opc == XC_JMPZ_EX || $opc == XC_JMPNZ_EX || $opc == XC_JMPZ) {
+						$targetop = &$EX['opcodes'][$op2['u.opline_num']];
+						if ($opc == XC_JMPNZ_EX) {
+							$targetop['cond_true'][] = str($rvalue);
+						}
+						else {
+							$targetop['cond_false'][] = str($rvalue);
+						}
+						unset($targetop);
+					}
+					else {
+						$op['cond'] = $rvalue; 
+						$op['isjmp'] = true;
+					}
+					break;
+					// }}}
+				case XC_JMP: // {{{
+					$op['cond'] = null;
+					$op['isjmp'] = true;
+					break;
+					// }}}
+				case XC_CASE:
+				case XC_BRK:
+					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']['u.constant']);
+					}
+					else {
+						$default = null;
+					}
+					$EX['recvs'][$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);
+						$prop = $this->unquoteName($this->getOpVal($op2, $EX));
+						if ($prop{0} == '$') {
+							$resvar = $resvar . "{" . $prop . "}";
+						}
+						else {
+							$resvar = $resvar . "->" . $prop;
+						}
+					}
+					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);
+					break;
+					// }}}
+				case XC_CONT: // {{{
+					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_OR_CLASS:
+					/* always removed by compiler */
+					break;
+				case XC_TICKS:
+					$lastphpop['ticks'] = $this->getOpVal($op1, $EX);
+					// $EX['tickschanged'] = true;
+					break;
+				default: // {{{
+					echo "\x1B[31m * TODO ", $opname, "\x1B[0m\n";
+					// }}}
+				}
+			}
+			if (isset($resvar)) {
+				if ($istmpres) {
+					$T[$res['u.var']] = $resvar;
+					$lastresvar = &$T[$res['u.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, str($a, $EX));
+			}
+			else {
+				array_unshift($args, $a);
+			}
+		}
+		return implode(', ', $args);
+	}
+	// }}}
+	function dumpop($op, &$EX) // {{{
+	{
+		$op1 = $op['op1'];
+		$op2 = $op['op2'];
+		$d = array('opname' => xcache_get_opcode($op['opcode']), 'opcode' => $op['opcode']);
+
+		foreach (array('op1' => 'op1', 'op2' => 'op2', 'result' => 'res') as $k => $kk) {
+			switch ($op[$k]['op_type']) {
+			case XC_IS_UNUSED:
+				$d[$kk] = '*UNUSED* ' . $op[$k]['u.opline_num'];
+				break;
+
+			case XC_IS_VAR:
+				$d[$kk] = '$' . $op[$k]['u.var'];
+				if ($kk != 'res') {
+					$d[$kk] .= ':' . $this->getOpVal($op[$k], $EX);
+				}
+				break;
+
+			case XC_IS_TMP_VAR:
+				$d[$kk] = '#' . $op[$k]['u.var'];
+				if ($kk != 'res') {
+					$d[$kk] .= ':' . $this->getOpVal($op[$k], $EX);
+				}
+				break;
+
+			case XC_IS_CV:
+				$d[$kk] = $this->getOpVal($op[$k], $EX);
+				break;
+
+			default:
+				if ($kk == 'res') {
+					assert(0);
+				}
+				else {
+					$d[$kk] = $this->getOpVal($op[$k], $EX);
+				}
+			}
+		}
+		$d['ext'] = $op['extended_value'];
+
+		var_dump($d);
+	}
+	// }}}
+	function dargs(&$EX, $indent) // {{{
+	{
+		$EX['indent'] = $indent;
+		$op_array = &$EX['op_array'];
+
+		if (isset($op_array['num_args'])) {
+			$c = $op_array['num_args'];
+		}
+		else if ($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 ', ';
+			}
+			if (isset($op_array['arg_info'])) {
+				$ai = $op_array['arg_info'][$i];
+				if (!empty($ai['class_name'])) {
+					echo $ai['class_name'], ' ';
+					if ($ai['allow_null']) {
+						echo 'or NULL ';
+					}
+				}
+				else if (!empty($ai['array_type_hint'])) {
+					echo 'array ';
+					if ($ai['allow_null']) {
+						echo 'or NULL ';
+					}
+				}
+				if ($ai['pass_by_reference']) {
+					echo '&';
+				}
+				printf("\$%s", $ai['name']);
+			}
+			else {
+				if ($refrest) {
+					echo '&';
+				}
+				else if (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);
+					}
+				}
+				$arg = $EX['recvs'][$i + 1];
+				echo str($arg[0]);
+				if (isset($arg[1])) {
+					echo ' = ', str($arg[1]);
+				}
+			}
+		}
+	}
+	// }}}
+	function dfunction($func, $indent = '', $nobody = false) // {{{
+	{
+		if ($nobody) {
+			$body = ";\n";
+			$EX = array();
+			$EX['op_array'] = &$func['op_array'];
+			$EX['recvs'] = array();
+		}
+		else {
+			ob_start();
+			$newindent = INDENT . $indent;
+			$EX = &$this->dop_array($func['op_array'], $newindent);
+			$body = ob_get_clean();
+			if (!isset($EX['recvs'])) {
+				$EX['recvs'] = array();
+			}
+		}
+
+		echo 'function ', $func['op_array']['function_name'], '(';
+		$this->dargs($EX, $indent);
+		echo ")\n";
+		echo $indent, "{\n";
+		echo $body;
+		echo "$indent}\n";
+	}
+	// }}}
+	function dclass($class, $indent = '') // {{{
+	{
+		// {{{ class decl
+		if (!empty($class['doc_comment'])) {
+			echo $indent;
+			echo $class['doc_comment'];
+			echo "\n";
+		}
+		$isinterface = false;
+		if (!empty($class['ce_flags'])) {
+			if ($class['ce_flags'] & ZEND_ACC_INTERFACE) {
+				echo 'interface ';
+				$isinterface = true;
+			}
+			else {
+				if ($class['ce_flags'] & ZEND_ACC_IMPLICIT_ABSTRACT) {
+					echo "abstract ";
+				}
+				if ($class['ce_flags'] & ZEND_ACC_FINAL) {
+					echo "final ";
+				}
+			}
+		}
+		echo 'class ', $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), $EX);
+					echo ";\n";
+				}
+			}
+		}
+		// }}}
+		// {{{ properties
+		if (!empty($class['default_properties'])) {
+			echo "\n";
+			$infos = empty($class['properties_info']) ? null : $class['properties_info'];
+			foreach ($class['default_properties'] as $name => $v) {
+				$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;
+				if (PHP_VERSION < 5) {
+					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 ";
+						break;
+					case ZEND_ACC_PROTECTED:
+						echo "protected ";
+						break;
+					}
+					if ($info['flags'] & ZEND_ACC_STATIC) {
+						echo "static ";
+					}
+				}
+
+				echo '$', $name;
+				if (isset($v)) {
+					echo ' = ';
+					echo str(value($v));
+				}
+				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";
+					}
+					echo $newindent;
+					if (isset($opa['fn_flags'])) {
+						if ($opa['fn_flags'] & ZEND_ACC_ABSTRACT) {
+							echo "abstract ";
+						}
+						if ($opa['fn_flags'] & ZEND_ACC_FINAL) {
+							echo "final ";
+						}
+						if ($opa['fn_flags'] & ZEND_ACC_STATIC) {
+							echo "static ";
+						}
+
+						switch ($opa['fn_flags'] & ZEND_ACC_PPP_MASK) {
+							case ZEND_ACC_PUBLIC:
+								echo "public ";
+								break;
+							case ZEND_ACC_PRIVATE:
+								echo "private ";
+								break;
+							case ZEND_ACC_PROTECTED:
+								echo "protected ";
+								break;
+							default:
+								echo "<visibility error> ";
+								break;
+						}
+					}
+					$this->dfunction($func, $newindent, $isinterface);
+					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 output() // {{{
+	{
+		echo "<?". "php\n";
+		foreach ($this->dc['class_table'] as $key => $class) {
+			if ($key{0} != "\0") {
+				echo "\n";
+				$this->dclass($class);
+			}
+		}
+
+		foreach ($this->dc['function_table'] as $key => $func) {
+			if ($key{0} != "\0") {
+				echo "\n";
+				$this->dfunction($func);
+			}
+		}
+
+		echo "\n";
+		$this->dop_array($this->dc['op_array']);
+		echo "\n?" . ">\n";
+		return true;
+	}
+	// }}}
+}
+
+// {{{ defines
+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);
+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);
+
+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_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));
+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_STRING',   3);
+define('IS_ARRAY',    4);
+define('IS_OBJECT',   5);
+define('IS_BOOL',     6);
+define('IS_RESOURCE', 7);
+define('IS_CONSTANT', 8);
+define('IS_CONSTANT_ARRAY',   9);
+
+@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_FETCH_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_METHOD_CALL' => -1,
+	'XC_VERIFY_ABSTRACT_CLASS' => -1,
+	'XC_DECLARE_CLASS' => -1,
+	'XC_DECLARE_INHERITED_CLASS' => -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_FETCH_OBJ_' => -1,
+	'XC_ISSET_ISEMPTY' => -1,
+	'XC_INIT_FCALL_BY_FUNC' => -1,
+	'XC_DO_FCALL_BY_FUNC' => -1,
+	'XC_DECLARE_FUNCTION_OR_CLASS' => -1,
+) as $k => $v) {
+	if (!defined($k)) {
+		define($k, $v);
+	}
+}
+
+/* XC_UNDEF XC_OP_DATA
+$content = file_get_contents(__FILE__);
+for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
+	if (!preg_match("/\\bXC_" . $opname . "\\b(?!')/", $content)) {
+		echo "not done ", $opname, "\n";
+	}
+}
+// */
+// }}}
+
Index: /trunk/lock.h
===================================================================
--- /trunk/lock.h	(revision 1)
+++ /trunk/lock.h	(revision 1)
@@ -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/coverage.h
===================================================================
--- /trunk/coverage.h	(revision 1)
+++ /trunk/coverage.h	(revision 1)
@@ -0,0 +1,11 @@
+#include "php.h"
+#include "xcache.h"
+
+extern char *xc_coveragedump_dir;
+
+void xc_coverage_handle_ext_stmt(zend_op_array *op_array, zend_uchar op);
+int xc_coverage_init(int module_number TSRMLS_DC);
+void xc_coverage_destroy();
+void xc_coverage_request_init(TSRMLS_D);
+void xc_coverage_request_shutdown(TSRMLS_D);
+PHP_FUNCTION(xcache_coverage_decode);
Index: /trunk/xcache.h
===================================================================
--- /trunk/xcache.h	(revision 1221)
+++ /trunk/xcache.h	(revision 1)
@@ -2,29 +2,207 @@
 #define __XCACHE_H
 #define XCACHE_NAME       "XCache"
-#ifndef XCACHE_VERSION
-#	define XCACHE_VERSION "3.1.0-dev"
-#endif
+#define XCACHE_VERSION    "1.0"
 #define XCACHE_AUTHOR     "mOo"
-#define XCACHE_COPYRIGHT  "Copyright (c) 2005-2013"
+#define XCACHE_COPYRIGHT  "Copyright (c) 2005-2006"
 #define XCACHE_URL        "http://xcache.lighttpd.net"
-#define XCACHE_WIKI_URL   XCACHE_URL "/wiki"
-
-#include "php.h"
-
-#if defined(E_STRICT) || defined(E_DEPRECATED)
-#define XCACHE_ERROR_CACHING
-#endif
+
+#include <php.h>
+#include <zend_compile.h>
+#include <zend_API.h>
+#include "php_ini.h"
+#include "zend_hash.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-#include "xcache/xc_shm.h"
-#include "xcache/xc_lock.h"
-#include "xcache/xc_compatibility.h"
+#include "myshm.h"
+#include "mem.h"
+#include "lock.h"
+
+#ifndef ZEND_WIN32
+/* UnDefine if your filesystem doesn't support inodes */
+#	define HAVE_INODE
+#endif
+#if !defined(ZEND_ENGINE_2_1) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1 || PHP_MAJOR_VERSION > 5)
+#	define ZEND_ENGINE_2_1
+#endif
+
+/* ZendEngine code Switcher */
+#ifndef ZEND_ENGINE_2
+#	define ZESW(v1, v2) v1
+#else
+#	define ZESW(v1, v2) v2
+#endif
+
+/* unicode */
+#ifdef IS_UNICODE
+#	define UNISW(text, unicode) unicode
+#else
+#	define UNISW(text, unicode) text
+#endif
+#define BUCKET_KEY_SIZE(b) \
+		(UNISW( \
+			(b)->nKeyLength, \
+				((b)->key.type == IS_UNICODE) \
+				? UBYTES(b->nKeyLength) \
+				: b->nKeyLength \
+				))
+#define BUCKET_KEY(b) (UNISW((b)->arKey, (b)->key.u.string))
+#define BUCKET_UKEY(b) (UNISW((b)->arKey, (b)->key.u.unicode))
+#define BUCKET_KEY_TYPE(b) (UNISW(0, (b)->key.type))
+#define BUCKET_HEAD_SIZE(b) XtOffsetOf(UNISW(sizeof((b)->arKey), sizeof((b)->key.u)))
+#define BUCKET_SIZE(b) (BUCKET_HEAD_SIZE(b) + BUCKET_KEY_SIZE(b))
+
+#ifndef IS_UNICODE
+typedef char *zstr;
+#	define ZSTR_S(s) (s)
+#	define ZSTR_U(s) (s)
+#	define ZSTR_V(s) (s)
+#else
+#	define ZSTR_S(s) ((s)->s)
+#	define ZSTR_U(s) ((s)->u)
+#	define ZSTR_V(s) ((s)->v)
+#endif
+
+/* {{{ u hash wrapper */
+#ifndef IS_UNICODE
+#	define zend_u_hash_add(ht, type, arKey, nKeyLength, pData, nDataSize, pDest) \
+ 	   zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest)
+
+#	define zend_u_hash_find(ht, type, arKey, nKeyLength, pData) \
+ 	   zend_hash_find(ht, arKey, nKeyLength, pData)
+
+#	define add_u_assoc_zval_ex(arg, type, key, key_len, value) \
+		add_assoc_zval_ex(arg, key, key_len, value)
+
+#endif
+/* }}} */
+
+
+#define ECALLOC_N(x, n) ((x) = ecalloc(n, sizeof((x)[0])))
+#define ECALLOC_ONE(x) ECALLOC_N(x, 1)
+
+
+
+typedef ulong xc_hash_value_t;
+typedef struct {
+	int bits;
+	int size;
+	int mask;
+} xc_hash_t;
+
+/* the class entry type to be stored in class_table */
+typedef ZESW(zend_class_entry, zend_class_entry*) xc_cest_t;
+
+/* xc_cest_t to (zend_class_entry*) */
+#define CestToCePtr(st) (ZESW(\
+			&(st), \
+			st \
+			) )
+
+/* ZCEP=zend class entry ptr */
+#define ZCEP_REFCOUNT_PTR(pce) (ZESW( \
+			(pce)->refcount, \
+			&((pce)->refcount) \
+			))
+
+#define ZCE_REFCOUNT_PTR(ce) ZCE_REFCOUNT_PTR(&ce)
+
+typedef zend_op_array *(zend_compile_file_t)(zend_file_handle *h, int type TSRMLS_DC);
+
+/* {{{ xc_cache_t */
+typedef struct _xc_entry_t xc_entry_t;
+typedef volatile struct {
+	int cacheid;
+	xc_hash_t  *hcache; /* hash to cacheid */
+
+	zend_bool  compiling;
+	zend_ulong misses;
+	zend_ulong hits;
+	zend_ulong clogs;
+	zend_ulong ooms;
+	xc_lock_t  *lck;
+	xc_shm_t   *shm; /* to which shm contains us */
+	xc_mem_t   *mem; /* to which mem contains us */
+
+	xc_entry_t **entries;
+	xc_entry_t *deletes;
+	xc_hash_t  *hentry; /* hash to entry */
+} xc_cache_t;
+/* }}} */
+/* {{{ xc_classinfo_t */
+typedef struct {
+	UNISW(,zend_uchar type;)
+	char *key;
+	zend_uint key_size;
+	xc_cest_t cest;
+} xc_classinfo_t;
+/* }}} */
+/* {{{ xc_funcinfo_t */
+typedef struct {
+	UNISW(,zend_uchar type;)
+	char *key;
+	zend_uint key_size;
+	zend_function func;
+} xc_funcinfo_t;
+/* }}} */
+typedef enum { XC_TYPE_PHP, XC_TYPE_VAR } xc_entry_type_t;
+/* {{{ xc_entry_data_php_t */
+typedef struct {
+	size_t sourcesize;
+#ifdef HAVE_INODE
+	int device;             /* the filesystem device */
+	int inode;              /* the filesystem inode */
+#endif
+	time_t mtime;           /* the mtime of origin source file */
+
+	zend_op_array *op_array;
+
+	zend_uint funcinfo_cnt;
+	xc_funcinfo_t *funcinfos;
+
+	zend_uint classinfo_cnt;
+	xc_classinfo_t *classinfos;
+} xc_entry_data_php_t;
+/* }}} */
+/* {{{ xc_entry_data_var_t */
+typedef struct {
+	zval   *value;
+	time_t etime;
+} xc_entry_data_var_t;
+/* }}} */
+typedef zvalue_value xc_entry_name_t;
+/* {{{ xc_entry_t */
+struct _xc_entry_t {
+	xc_entry_type_t type;
+	xc_hash_value_t hvalue;
+	xc_entry_t *next;
+	xc_cache_t *cache;      /* which cache it's on */
+
+	size_t     size;
+	zend_ulong refcount;
+	zend_ulong hits;
+	time_t     ctime;           /* the ctime of this entry */
+	time_t     atime;           /* the atime of this entry */
+	time_t     dtime;           /* the deletion time of this entry */
+
+#ifdef IS_UNICODE
+	zend_uchar name_type;
+#endif
+	xc_entry_name_t name;
+
+	union {
+		xc_entry_data_php_t *php;
+		xc_entry_data_var_t *var;
+	} data;
+};
+/* }}} */
 
 extern zend_module_entry xcache_module_entry;
 #define phpext_xcache_ptr &xcache_module_entry
 
-extern zend_bool xc_test;
+int xc_is_rw(const void *p);
+int xc_is_ro(const void *p);
+int xc_is_shm(const void *p);
 
 #endif /* __XCACHE_H */
Index: /trunk/myshm.h
===================================================================
--- /trunk/myshm.h	(revision 1)
+++ /trunk/myshm.h	(revision 1)
@@ -0,0 +1,13 @@
+typedef struct _xc_shm_t xc_shm_t;
+typedef unsigned int xc_shmsize_t;
+
+int xc_shm_can_readonly(xc_shm_t *shm);
+int xc_shm_is_readwrite(xc_shm_t *shm, const void *p);
+int xc_shm_is_readonly(xc_shm_t *shm, const void *p);
+void *xc_shm_to_readwrite(xc_shm_t *shm, void *p);
+void *xc_shm_to_readonly(xc_shm_t *shm, void *p);
+
+void *xc_shm_ptr(xc_shm_t *shm);
+
+xc_shm_t *xc_shm_init(const char *path, xc_shmsize_t size, zend_bool readonly_protection);
+void xc_shm_destroy(xc_shm_t *shm);
Index: /trunk/config.m4
===================================================================
--- /trunk/config.m4	(revision 1135)
+++ /trunk/config.m4	(revision 1)
@@ -1,72 +1,44 @@
+dnl
+dnl $Id:$
 dnl vim:ts=2:sw=2:expandtab
 
-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 mod_$1/xc_$1.c"
-    XCACHE_MODULES="$XCACHE_MODULES $1"
-    HAVE_$3=1
-    AC_DEFINE([HAVE_$3], 1, [Define for XCache: $4])
-  else
-    HAVE_$3=
+AC_DEFUN([XCACHE_OPTION], [
+  PHP_ARG_ENABLE(xcache-$1, for XCACHE $1,
+  [  --enable-xcache-$2    XCACHE: $4], no, no)
+  if test "$PHP_$3" = "yes"; then
+    xcache_sources="$xcache_sources $1.c"
+    AC_DEFINE([HAVE_$3], 1, [Define for XCACHE: $4])
   fi
 ])dnl
 
-PHP_ARG_ENABLE(xcache, for XCache support,
-[  --enable-xcache         Include XCache support.])
+PHP_ARG_ENABLE(xcache, for XCACHE support,
+[  --enable-xcache         Include XCACHE support.])
 
 if test "$PHP_XCACHE" != "no"; then
-  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
+  xcache_sources="processor.c \
+                  xcache.c \
+                  mmap.c \
+                  mem.c \
+                  const_string.c \
+                  opcode_spec.c \
+                  stack.c \
+                  utils.c \
+                  lock.c \
+                  "
+  XCACHE_OPTION([optimizer],    [optimizer   ], [XCACHE_OPTIMIZER],    [(N/A)])
+  XCACHE_OPTION([coverage],     [coverage    ], [XCACHE_COVERAGE],     [Enable code coverage dumper, NOT for production server])
+  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_sources="xcache.c"
-  for i in \
-xc_stack.c \
-xc_trace.c \
-; do
-  xcache_sources="$xcache_sources util/$i"
-done
-  for i in \
-xc_allocator.c \
-xc_allocator_bestfit.c \
-xc_compatibility.c \
-xc_const_string.c \
-xc_extension.c \
-xc_ini.c \
-xc_lock.c \
-xc_opcode_spec.c \
-xc_processor.c \
-xc_sandbox.c \
-xc_shm.c \
-xc_shm_mmap.c \
-xc_utils.c \
-; do
-  xcache_sources="$xcache_sources xcache/$i"
-done
-  for i in \
-xc_cacher.c \
-; do
-  xcache_sources="$xcache_sources mod_cacher/$i"
-done
-  XCACHE_MODULES="cacher"
-  AC_DEFINE([HAVE_XCACHE_CACHER], 1, [Define to enable XCache cacher])
-  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 server usage])
-  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])
+  PHP_NEW_EXTENSION(xcache, $xcache_sources, $ext_shared)
+  PHP_ADD_MAKEFILE_FRAGMENT()
 
-  PHP_ARG_ENABLE(xcache-test, for XCache self test,
-  [  --enable-xcache-test            XCache: Enable self test - FOR DEVELOPERS ONLY!!], no, no)
-  if test "$PHP_XCACHE_TEST" != "no"; then
+  PHP_ARG_ENABLE(xcache-test, for XCACHE self test,
+  [  --enable-xcache-test            XCACHE: Enable self test - FOR DEVELOPERS ONLY!!], no, no)
+  if test "$PHP_XCACHE_TEST" = "yes"; then
     XCACHE_ENABLE_TEST=-DXCACHE_ENABLE_TEST
-    xcache_sources="$xcache_sources xcache/xc_malloc.c"
-    AC_DEFINE([HAVE_XCACHE_TEST], 1, [Define to enable XCache self test])
+    AC_DEFINE([HAVE_XCACHE_TEST], 1, [Define to enable XCACHE self test])
   else
     XCACHE_ENABLE_TEST=
@@ -74,67 +46,15 @@
   PHP_SUBST([XCACHE_ENABLE_TEST])
 
-  PHP_ARG_ENABLE(xcache-dprint, for XCache self test,
-  [  --enable-xcache-dprint          XCache: Enable debug print functions - FOR DEVELOPERS ONLY!!], no, no)
-  if test "$PHP_XCACHE_DPRINT" != "no"; then
-    AC_DEFINE([HAVE_XCACHE_DPRINT], 1, [Define to enable XCache debug print functions])
-  fi
-
-  PHP_NEW_EXTENSION(xcache, $xcache_sources, $ext_shared)
-  PHP_ADD_BUILD_DIR($ext_builddir/util)
-  PHP_ADD_BUILD_DIR($ext_builddir/xcache)
-  PHP_ADD_BUILD_DIR($ext_builddir/submodules)
-  PHP_ADD_MAKEFILE_FRAGMENT()
-  PHP_ADD_MAKEFILE_FRAGMENT($ext_srcdir/Makefile.frag.deps)
-
-  AC_PATH_PROGS([XCACHE_AWK], [gawk awk])
-  dnl clean locale for gawk 3.1.5 assertion bug
-  if echo | LANG=C "$XCACHE_AWK" -- '' > /dev/null 2>&1 ; then
-    XCACHE_AWK="LANG=C $XCACHE_AWK"
-  else
-    if echo | /usr/bin/env - "$XCACHE_AWK" -- '' > /dev/null 2>&1 ; then
-      XCACHE_AWK="/usr/bin/env - $XCACHE_AWK"
-    fi
-  fi
-  PHP_SUBST([XCACHE_AWK])
-  AC_PATH_PROGS([M4], [m4])
-  if test "$PHP_XCACHE_TEST" != "no"; then
-    if echo | "$M4" -E > /dev/null 2>&1 ; then
-      M4="$M4 -E"
-    fi
-  fi
-   dnl fix for solaris m4: size of the push-back and argument
-  if echo | "$M4" -B 102400 > /dev/null 2>&1 ; then
-    M4="$M4 -B 102400"
-  fi
-  PHP_SUBST([M4])
-  XCACHE_BACKTICK="'"'`'"'"
-  PHP_SUBST([XCACHE_BACKTICK])
-  AC_PATH_PROGS([GREP], [grep])
-  PHP_SUBST([GREP])
-  AC_PATH_PROGS([SED], [sed])
-  PHP_SUBST([SED])
-
-  AC_PATH_PROGS([INDENT], [indent cat])
-  XCACHE_INDENT=cat
+  AC_PATH_PROGS(INDENT, [indent cat])
   case $INDENT in
   */indent[)]
-    XCACHE_INDENT="$INDENT"
-    opts="-kr --use-tabs --tab-size 4"
-    if echo | $INDENT $opts > /dev/null 2>&1 ; then
-      XCACHE_INDENT="$XCACHE_INDENT $opts"
-    fi
-    opts="-sob -nce"
-    if echo | $INDENT $opts > /dev/null 2>&1 ; then
-      XCACHE_INDENT="$XCACHE_INDENT $opts"
-    fi
-    opts="-l 160"
-    if echo | $INDENT $opts > /dev/null 2>&1 ; then
-      XCACHE_INDENT="$XCACHE_INDENT $opts"
-    fi
+    XCACHE_INDENT="$INDENT -kr --use-tabs --tab-size 4 -sob -nce"
+    ;;
+  *[)]
+    XCACHE_INDENT=cat
     ;;
   esac
   PHP_SUBST([XCACHE_INDENT])
 
-  dnl $ac_srcdir etc require PHP_NEW_EXTENSION
   XCACHE_PROC_SOURCES=`ls $ac_srcdir/processor/*.m4`
   PHP_SUBST([XCACHE_PROC_SOURCES])
Index: /unk/THANKS
===================================================================
--- /trunk/THANKS	(revision 605)
+++ 	(revision )
@@ -1,9 +1,0 @@
-
-Jan <jan@kneschke.de>, host XCache website
-Alex <ale@freebsd.org>, redist to FreeBSD
-darix <darix@irssi.org>, redist to openSUSE
-judas_iscariote <judas.iscariote@gmail.com>, redist/test with openSUSE
-Finjon Kiang <kiange@gmail.com>, Chinese Traditional translation
-
-There is also many ppl on IRC or forum helped me a lot testing XCache.
-Without them, XCache may not even be released.
Index: /unk/COPYING
===================================================================
--- /trunk/COPYING	(revision 1166)
+++ 	(revision )
@@ -1,31 +1,0 @@
-
-
-Copyright (c) 2005-2012, mOo, phpxcache@gmail.com, XCache
- All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-- Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-- Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-- Neither the name of the 'XCache' nor the names of its contributors may
-  be used to endorse or promote products derived from this software without
-  specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGE.
-
Index: /unk/NEWS
===================================================================
--- /trunk/NEWS	(revision 1238)
+++ 	(revision )
@@ -1,102 +1,0 @@
-3.1.0 2013-??-??
-========
- * adds support for PHP_5_5
- * compatible with fcntl fork
-
-3.0.2 2013-??-??
-========
- * bug fixes
- * "cannot redeclare class" errors is now gone. Can also be avoid by using readonly_protection (unavailable with /dev/zero).
-
-3.0.1 2013-01-11
-========
- * bug fixes
- * improve compatibility with "the ionCube PHP Loader", Zend Optimizer
- * improve stability
- * improve support for PHP_5_4
- * improve stability on threaded env
-
-3.0.0 2012-10-29
-========
- * lots of improvements
- * bug fixes
- * updates api, adds a few ini
- * uses extension= to load XCache. loading via zend_extension= is unsupported
- * updates XCache admin page
- * namespace support
- * professional helpers
-   * adds an diagnosis module to give advise @ htdocs
-   * auto disable caching on crash @ runtime
-
-2.0.1 2012-07-14
-========
- * improve stability
- * admin/ config changed. please update accordingly
- * PHP 5.3.14 is unstable. Please upgrade to new version. You have been warned
- * fixed __FILE__ __DIR__ handling for moved/hardlinked files (set "xcache.experimental = on" to eanble this fix)
-
-2.0.0 2012-04-20
-========
- * support for PHP_5_4
- * reduce memory usage by caching 1 for multiple same content files
- * correct __FILE__ __DIR__ supported for hardlinked files
-
-1.3.2 2011-06-04
-========
- * admin page security fix
- * adds 30 seconds timeout to "compiling" flag
- * improves decompiling
- * memory leak on recompile
- * disassembler fixes and updates for new PHP
- * win32 build fix
- * improve compatibility with ionCube Loader
-
-1.3.1 2010-11-27
-========
- * 2G/4G limitation on 64bit arch
- * xcache_unset matching e.g. prefixed_ values
-
-1.3.0 2009-08-04
-========
- * PHP 5.3 support
- * many cacher/coverager bug fixes
- * improved admin pages
- * admin page is now magic quote gpc aware
-
-1.2.2 2007-12-29
-========
- * live with wrong system time: allow caching files with mtime in further
- * bug fix for compatibility with Zend Optimizer and other non-cachable
- * a rare segv bug with token_get_all
- * minor bug fixes
-
-1.2.1 2007-07-01
-========
- * compatibility fix for apache 1.x, which init XCache module correctly
- * full Zend Optimizer compatibility
- * ini settings changed
- * other bug fixes
-
-1.2.0 2006-12-10
-========
- * full 5.2 support
- * minor admin/coverage-viewer page improves
- * compatible with suhosin/ZendOptimizer
- * xcache_get reference handling
- * new apis for coverager
- * some ini settings changed
-
-1.1.0 2006-11-11
-========
- * fix xcache_get issue on ttl 0 data
- * avoid crash when php failed to compile file when coverager enabled
- * gc expired items, new ini
- * Partial php 5.2 support
- * "Cannot redeclare ()" bug
- * bug fixes
- * Chinese Simplified/Traditional translations
- * admin page fixes and applied phpinfo style
- * coverage viewer page use phpinfo style
- * fix build on rare arch and Mac OS X
- * zts build
- * includes all fixes from <=1.0.2
Index: /unk/config.w32
===================================================================
--- /trunk/config.w32	(revision 1135)
+++ 	(revision )
@@ -1,148 +1,0 @@
-// vim:ft=javascript
-
-
-ARG_ENABLE("xcache", "Include XCache support", "yes,shared");
-
-if (PHP_XCACHE != "no") {
-	EXTENSION("xcache", "xcache.c", null, "/I " + configure_module_dirname);
-	// {{{ check for xcache-constant 
-	ARG_ENABLE("xcache-constant", "XCache: Handle new constants made by php compiler (e.g.: for __halt_compiler)", "yes");
-	if (PHP_XCACHE_CONSTANT != "no") {
-		AC_DEFINE("HAVE_XCACHE_CONSTANT", 1, "Define to enable XCache handling of compile time constants");
-	}
-	// }}}
-
-	ADD_SOURCES(configure_module_dirname + "/util", " \
-xc_stack.c \
-xc_trace.c \
-", "xcache");
-
-	ADD_SOURCES(configure_module_dirname + "/xcache", " \
-xc_allocator.c \
-xc_allocator_bestfit.c \
-xc_compatibility.c \
-xc_const_string.c \
-xc_extension.c \
-xc_ini.c \
-xc_lock.c \
-xc_opcode_spec.c \
-xc_processor.c \
-xc_sandbox.c \
-xc_shm.c \
-xc_shm_mmap.c \
-xc_utils.c \
-", "xcache");
-	ADD_SOURCES(configure_module_dirname + "/mod_cacher", " \
-xc_cacher.c \
-", "xcache");
-
-	// {{{ add sources on enabled
-	ARG_ENABLE("xcache-optimizer",    "(N/A)", "no");
-	ARG_ENABLE("xcache-coverager",    "Enable code coverage dumper, useful for testing php scripts", "no");
-	ARG_ENABLE("xcache-assembler",    "(N/A)", "no");
-	ARG_ENABLE("xcache-disassembler", "Enable opcode to php variable dumper, not for server usage", "no");
-	ARG_ENABLE("xcache-encoder",      "(N/A)", "no");
-	ARG_ENABLE("xcache-decoder",      "(N/A)", "no");
-
-	var XCACHE_MODULES = "cacher";
-	AC_DEFINE("HAVE_XCACHE_CACHER", 1, "Define for XCache: cacher")
-	var options = ["optimizer",
-	               "coverager",
-	               "assembler", "disassembler",
-	               "encoder", "decoder"];
-	for (var i in options) {
-		var name = options[i];
-		var uname = name.toUpperCase();
-		var withval = eval("PHP_XCACHE_" + uname);
-		if (withval != "no") {
-			ADD_SOURCES(configure_module_dirname + "/mod_" + name, "xc_" + name + ".c", "xcache");
-			XCACHE_MODULES += " " + name;
-			STDOUT.WriteLine("Enabling XCache Module: " + name);
-			AC_DEFINE("HAVE_XCACHE_" + uname, 1, "Define for XCache: " + name)
-		}
-	}
-	AC_DEFINE("XCACHE_MODULES", XCACHE_MODULES);
-	// }}}
-	// {{{ check for programs needed
-	var apps = ["m4", "grep", "sed"];
-	for (var i in apps) {
-		if (!PATH_PROG(apps[i])) {
-			ERROR(apps[i] + " is currently required to build XCache");
-		}
-	}
-	DEFINE("XCACHE_BACKTICK", "`")
-	PATH_PROG("gawk", null, "XCACHE_AWK") || PATH_PROG("awk", null, "XCACHE_AWK");
-
-	// the cygwin indent is known broken on our output
-	var indent = false; // PATH_PROG("indent");
-	if (indent) {
-		indent += " -kr --use-tabs --tab-size 4 -sob -nce";
-	}
-	else {
-		indent = PATH_PROG("cat");
-		if (!indent) {
-			indent = '';
-		}
-	}
-	DEFINE("XCACHE_INDENT", indent);
-	// }}}
-	// {{{ check for xcache-test
-	ARG_ENABLE("xcache-test", "XCache: Enable self test - FOR DEVELOPERS ONLY!!", "no");
-	if (PHP_XCACHE_TEST != "no") {
-		ADD_FLAG("XCACHE_ENABLE_TEST", "-DXCACHE_ENABLE_TEST");
-		ADD_SOURCES(configure_module_dirname + "/xcache", "xc_malloc.c", "xcache");
-		AC_DEFINE("HAVE_XCACHE_TEST", 1, "Define to enable XCache self test");
-	}
-	else {
-		ADD_FLAG("XCACHE_ENABLE_TEST", "");
-	}
-	// }}}
-	// {{{ check for xcache-test
-	ARG_ENABLE("xcache-dprint", "XCache: Enable self debug print functions - FOR DEVELOPERS ONLY!!", "no");
-	if (PHP_XCACHE_DPRINT != "no") {
-		AC_DEFINE("HAVE_XCACHE_DPRINT", 1, "Define to enable XCache debug print functions");
-	}
-	// }}}
-	// {{{ get ccrule
-	var srcdir = configure_module_dirname;
-	// it's a bit harder to get builddir
-	var mfofile = "Makefile.objects";
-	MFO.Close();
-
-	var mfo = file_get_contents(mfofile);
-	mfo.match(/(.*)\\xcache.obj:/);
-	var builddir = RegExp.$1;
-	mfo.match(/(.*\$\(CC\).* )\/c.*\\xcache.c.*/i);
-	var ccrule = RegExp.$1;
-
-	MFO = FSO.OpenTextFile(mfofile, 8);
-	mfo = null;
-	// }}}
-	// {{{ add make fragments
-	var makefileFrag = srcdir + "\\Makefile.frag";
-	var makefileFragDeps = srcdir + "\\Makefile.frag.deps";
-	STDOUT.WriteLine("Adding Makefile.frag: " + makefileFrag);
-	STDOUT.WriteLine("Adding Makefile.frag.deps: " + makefileFragDeps);
-	var frag = file_get_contents(makefileFrag) + "\r\n" + file_get_contents(makefileFragDeps);
-	frag = frag.replace(/\$\(srcdir\)\//g,   srcdir + '\\');
-	frag = frag.replace(/\$\(srcdir\)/g,     srcdir);
-	frag = frag.replace(/\$\(builddir\)\//g, builddir + '\\');
-	frag = frag.replace(/\$\(builddir\)/g,   builddir);
-	frag = frag.replace(/processor\//g,      "processor\\");
-	frag = frag.replace(/\.lo:/g, ".obj:");
-	frag = frag.replace(/.*\$\(CC\).* -E (.*) -o (.*)/, ccrule + " /E $1 > $2");
-	frag = frag.replace(/ -o /g, " /Fo");
-	frag = frag.replace(/cp /g, "copy ");
-	frag = frag.replace(/mv /g, "move ");
-	frag = frag.replace(/ \|\| /g, "\r\n\tif errorlevel 1 ");
-	frag = frag.replace(/ && /g, "\r\n\tif not errorlevel 1 ");
-	if (indent == '') {
-		frag = frag.replace(/\| +\$\(XCACHE_INDENT\)/, '');
-		frag = frag.replace(/\$\(XCACHE_INDENT\) < /, 'type ');
-	}
-	MFO.WriteLine(frag);
-	ADD_FLAG("CFLAGS_XCACHE", "/I " + builddir);
-	/// }}}
-	XCACHE_PROC_SOURCES=glob(srcdir + "\\processor\\*.m4").join(' ');
-	ADD_FLAG("XCACHE_PROC_SOURCES", XCACHE_PROC_SOURCES);
-}
Index: /unk/Makefile.frag.deps
===================================================================
--- /trunk/Makefile.frag.deps	(revision 1160)
+++ 	(revision )
@@ -1,25 +1,0 @@
-$(XCACHE_INCLUDES_I) includes.lo $(builddir)/includes.lo: $(srcdir)/mod_cacher/xc_cache.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h
-mod_assembler/xc_assembler.lo $(builddir)/mod_assembler/xc_assembler.lo:
-mod_cacher/xc_cacher.lo $(builddir)/mod_cacher/xc_cacher.lo: $(srcdir)/mod_cacher/xc_cache.h $(srcdir)/mod_cacher/xc_cacher.h $(srcdir)/util/xc_align.h $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/util/xc_vector.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_allocator.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_sandbox.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h $(XCACHE_PROC_H)
-mod_coverager/xc_coverager.lo $(builddir)/mod_coverager/xc_coverager.lo: $(srcdir)/mod_coverager/xc_coverager.h $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h
-mod_decoder/xc_decoder.lo $(builddir)/mod_decoder/xc_decoder.lo:
-mod_disassembler/xc_disassembler.lo $(builddir)/mod_disassembler/xc_disassembler.lo: $(srcdir)/mod_cacher/xc_cache.h $(srcdir)/mod_disassembler/xc_disassembler.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_allocator.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_sandbox.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h $(XCACHE_PROC_H)
-mod_encoder/xc_encoder.lo $(builddir)/mod_encoder/xc_encoder.lo:
-mod_optimizer/xc_optimizer.lo $(builddir)/mod_optimizer/xc_optimizer.lo: $(srcdir)/mod_optimizer/xc_optimizer.h $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h
-util/xc_stack.lo $(builddir)/util/xc_stack.lo: $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h
-util/xc_trace.lo $(builddir)/util/xc_trace.lo: $(srcdir)/util/xc_trace.h
-xcache.lo $(builddir)/xcache.lo: $(srcdir)/util/xc_foreachcoresig.h $(srcdir)/util/xc_stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_const_string.h $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_opcode_spec.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h
-xcache/xc_allocator_bestfit.lo $(builddir)/xcache/xc_allocator_bestfit.lo: $(srcdir)/util/xc_align.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache/xc_allocator.h $(srcdir)/xcache/xc_shm.h
-xcache/xc_allocator.lo $(builddir)/xcache/xc_allocator.lo: $(srcdir)/xcache/xc_allocator.h $(srcdir)/xcache/xc_shm.h
-xcache/xc_compatibility.lo $(builddir)/xcache/xc_compatibility.lo: $(srcdir)/xcache/xc_compatibility.h
-xcache/xc_const_string.lo $(builddir)/xcache/xc_const_string.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_const_string.h $(srcdir)/xcache/xc_const_string_opcodes_php5.4.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h
-xcache/xc_extension.lo $(builddir)/xcache/xc_extension.lo: $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h
-xcache/xc_ini.lo $(builddir)/xcache/xc_ini.lo: $(srcdir)/xcache/xc_ini.h
-xcache/xc_lock.lo $(builddir)/xcache/xc_lock.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h
-xcache/xc_malloc.lo $(builddir)/xcache/xc_malloc.lo: $(srcdir)/util/xc_align.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_allocator.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h
-xcache/xc_opcode_spec.lo $(builddir)/xcache/xc_opcode_spec.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_const_string.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_opcode_spec_def.h $(srcdir)/xcache/xc_opcode_spec.h $(srcdir)/xcache/xc_shm.h
-xcache/xc_processor.lo $(builddir)/xcache/xc_processor.lo: $(srcdir)/mod_cacher/xc_cache.h $(srcdir)/util/xc_align.h $(srcdir)/util/xc_stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_allocator.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_const_string.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h $(XCACHE_PROC_C) $(XCACHE_PROC_H)
-xcache/xc_sandbox.lo $(builddir)/xcache/xc_sandbox.lo: $(srcdir)/util/xc_stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_sandbox.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h
-xcache/xc_shm.lo $(builddir)/xcache/xc_shm.lo: $(srcdir)/xcache/xc_shm.h
-xcache/xc_shm_mmap.lo $(builddir)/xcache/xc_shm_mmap.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h
-xcache/xc_utils.lo $(builddir)/xcache/xc_utils.lo: $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_opcode_spec.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_utils.h
Index: /unk/xcache-zh-gb2312.ini
===================================================================
--- /trunk/xcache-zh-gb2312.ini	(revision 1182)
+++ 	(revision )
@@ -1,78 +1,0 @@
-;; ���ļ�ֻ������, ���� php.ini �������Ա���Ч
-[xcache-common]
-;; �� windows ����:
-extension = xcache.so
-;; Windows ϵͳ����:
-; extension = php_xcache.dll
-
-[xcache.admin]
-xcache.admin.enable_auth = On
-xcache.admin.user = "mOo"
-; xcache.admin.pass = md5($��������)
-; ��¼ʹ�� $your_password
-xcache.admin.pass = ""
-
-[xcache]
-; ����Ķ���ѡ����� ini ������޸�, �����г��Ķ���Ĭ��ֵ, ��������˵��
-
-; ѡ��ײ��ڴ湲��ʵ�ַ���
-xcache.shm_scheme =        "mmap"
-; ����: xcache.size=0
-; ����: xcache.size=64M ֮�� (����>0��ֵ) ͬʱ��ע������ϵͳ mmap ����
-xcache.size  =               60M
-; ��������Ϊ cpu �� (cat /proc/cpuinfo |grep -c processor)
-xcache.count =                 1
-; ֻ�Ǹ� hash �ο�ֵ, ʵ�ʴ洢��Ŀ(php�ű�/����)�ɳ����������
-xcache.slots =                8K
-; ������Ŀ�� ttl, 0=����
-xcache.ttl   =                 0
-; ɨ�������Ŀ��ʱ����, 0=��ɨ��, ����ֵ����Ϊ��λ
-xcache.gc_interval =           0
-
-; ͬ��, ֻ����Ա�����������
-xcache.var_size  =            4M
-xcache.var_count =             1
-xcache.var_slots =            8K
-; xcache_*() ���� ttl ������Ĭ��ֵ
-xcache.var_ttl   =             0
-; ���� xcache_*() ���� ttl ����������������. 0=������
-xcache.var_maxttl   =          0
-xcache.var_gc_interval =     300
-
-; /dev/zero ʱ��Ч
-xcache.readonly_protection = Off
-; ���� *nix ϵͳ, xcache.mmap_path ���ļ�·��������Ŀ¼. (�Զ�����/����)
-; ������������� ReadonlyProtection, �������ʹ�� "/dev/*", ����ʹ������ "/tmp/xcache"
-; ��ͬ php �����鲻�Ṳ��ͬһ�� /tmp/xcache
-; ���� Win32 ϵͳ, xcache.mmap_path=����MAP����, �����ļ�·��. ����ʹ�� XCache ���۱�������������ͻ
-xcache.mmap_path =    "/dev/zero"
-
-
-; ���� XCache �쳣ʱ����. ����Ϊ��(����) �������� "/tmp/phpcore/" (�ܱ� php д���ļ�)
-xcache.coredump_directory =   ""
-; ������ Windows. ���� XCache ������Ա������, ���򱣳�Ĭ��ֵ
-xcache.coredump_type =         0
-
-; �쳣ʱ�Զ���ֹ����
-xcache.disable_on_crash =    Off
-
-; ����ʵ���Թ��� (�����)
-xcache.experimental =        Off
-
-; ������ Request ���ɸ�����. ���� ini_set, .htaccess ��
-xcache.cacher =               On
-xcache.stat   =               On
-xcache.optimizer =           Off
-
-[xcache.coverager]
-; �����ܿ���󽵵���������
-; ���� xcache.coverager == On && xcache.coveragedump_directory == "�ǿ�ֵ" ʱ�����ܲŻ�����
-
-; per request settings. ���� ini_set, .htaccess ��
-; ���ô������̸�������Ϣ�ɼ��Լ� xcache_coverager_start/stop/get/clean() �Ⱥ���
-xcache.coverager =           Off
-xcache.coverager_autostart =  On
-
-; ���� php ini �ļ�������
-; ��ȷ����Ŀ¼�ܱ� coverage viewer �ű���ȡ (ע�� open_basedir)
-xcache.coveragedump_directory = ""
Index: /unk/ChangeLog
===================================================================
--- /trunk/ChangeLog	(revision 1238)
+++ 	(revision )
@@ -1,238 +1,0 @@
-3.1.0 2013-??-??
-ChangeLog
-========
- * adds support for PHP_5_5
- * compatible with fcntl fork
-
-3.0.2 2013-??-??
-ChangeLog
-========
- * fixes #303: tablesort.js not found in Diagnosis and Coverager
- * fixes #297: segv on startup under sparc, ini setting overflow
- * fixes #296: Multiple instances of the same software causes PHP "cannot redeclare class" errors when readonly_protection is not in use
-
-3.0.1 2013-01-11
-ChangeLog
-========
- * fixes crash when cache is too small on start up
- * fixes #295: crash using traits with PHP 5.4.8+
- * fixes #290: workaround phpize vs fbsd make bug again
- * improve compatibility with "the ionCube PHP Loader", Zend Optimizer
- * fix random crash when cache is reinitialized yet failed (Thanks to Brad Baker for generating crash dump)
- * fix locking impl: improve stability on threaded env (Thanks to Mircea Nicolae for reproducing the bug)
- * diagnosis: undefined variable when ini is not found
- * PHP_5_4 optimizer: fix ZEND_JMP_SET_VAR
- * PHP_5_4 optimizer: fix for goto
-
-3.0.0 2012-10-29
-API Changes
-========
- * chg: proto array xcache_clear_cache(int type, [ int id = -1 ]). -1 means all cache splits
- * new: proto array xcache_enable_cache(int type, [ int id = -1, [ bool enable = true ] ])
- * new: proto array xcache_admin_namespace()
- * new: proto array xcache_set_namespace(string namespace)
-
-Ini Settings Changes
-========
- * new: xcache.disable_on_crash = Off
- * new: xcache.coverager_autostart = On
- * new: xcache.allocator = bestfit (no other option value yet)
- * new: xcache.var_allocator = bestfit (no other option value yet)
- * new: xcache.var_namespace_mode = 0
- * new: xcache.var_namespace = ""
-
-ChangeLog
-========
- * closes #2: auto disable caching on crash
- * closes #73: warn for improper PHP_FCGI_CHILDREN setting fcgi mode (>=PHP_5_3)
- * closes #174: updates api to support "clear all cache"
- * closes #198: support for caching protocol url
- * closes #287: namespace support
- * fixes #39: ini_set never work for xcache.coverager setting. use API instead
- * code refactor
-   * uses extension= to load XCache. loading via zend_extension= is unsupported
-   * split XCache features into multiple sub modules
- * updates XCache admin page
- * adds an diagnosis module to give professional advise, accessable via htdocs pages
- * cache can be enabled/disabled manually
-
-2.0.1 2012-07-14
-ChangeLog
-========
- * fixed #279: segv when cache is full (since 2.0)
- * fixed #281: subsequenc request segv when timeout happens during compiling
- * admin/ config changed. please update accordingly
- * WIN32: kill invalidate CRT parameters on shutdown
- * fixed: <=PHP_5_2 duplicate error message failed to include file
- * fixed #283: XCache admin APIs (admin page) cause SEGV if XCache failed to initize
- * fixed possible re-include a file by mixing include/include_once
- * fixed #264, #284: __FILE__ __DIR__ handling for moved/hardlinked files (set "xcache.experimental = on" to eanble this fix)
-
-2.0.0 2012-04-20
-Ini Settings Changes
-========
- * new: xcache.experimental = Off
-
-ChangeLog
-========
- * support for PHP_5_4
- * reduce memory usage by caching 1 for multiple same content files
- * correct __FILE__ __DIR__ supported for hardlinked files
- * fixed #275: one line struct definition was confusing struct parser
- * fixed #102: segv when var cacher is too small
- * fixed #55: segv php tokenizer on certain special situation
- * fixed #278: admin page: wrong layout in opera
- * compiler errors: all compiler warning (E_STRICT only currently) is now cached and is supported for user handler
- * tests/bug52160.phpt: report multiple error correctly
-
-1.3.2 2011-06-04
-========
- * avoid possible filename injection in admin page
- * adds 30 seconds timeout to "compiling" flag
- * decompiler: improves decompiling
- * disassembler: improper handling of null field
- * disassembler: DECLARE_INHERITED_CLASS/DELAYED class not found
- * disassembler: don't dump builtin functions
- * fix win32 build against win32 native gnu tools
- * compatibility fix: fix segv on shutdown when ionCube Loader is loaded
- * fixed undefined index for xcache.count=1 and xcache.var_size>1
- * fixed #258: builtin constant memory leak on compile
-
-1.3.1 2010-11-27
-========
- * 2G/4G limitation on 64bit arch
- * xcache_unset matching e.g. prefixed_ values
-
-1.3.0 2009-08-04
-== ChangeLog ==
- * PHP 5.3 support
- * fixed #138: no segv if cache is not initialized correctly
- * default to 64M for xcache.size in xcache.ini
- * could not show module info in admin page when XCache is the last module
- * wrong http auth realm
- * coverager: font-size and newline fix for firefox
- * admin page is now magic quote gpc aware
-
-1.2.2 2007-12-29
-== ChangeLog ==
- * added module dependency
- * live with wrong system time: allow caching files with mtime in further
- * bug fix for compatibility with Zend Optimizer and other non-cachable
- * #59: Maximum execution time of 60 seconds exceeded
- * #102: segv when var cacher is too small
- * #55: segv php tokenizer on certain special situation
-
-1.2.1 2007-07-01
-== Ini Settings Changes ==
- * new: xcache.admin.enable_auth = On
-
-== ChangeLog ==
- * #86: remove/edit variable in admin page
- * fixed #109: fast inc/dec was trying to break ro protection
- * fixed #101, #105: Fixed compatibility issue for apache 1.x
- * fixed #94: Garbage collector disabled when xcache.cacher set to off
- * fixed #92: Zend Optimizer compatibility issue
- * fixed #77: hits/misses was not updated
- * fixed #59: pass by reference for internal function was broken
- * fixed #56: xcache_set segfaults when xcache.var_size=0
-
-========
-1.2.0 2006-12-10
-Ini Settings Changes
-========
- * new: xcache.stat = On
- * new: xcache.coverager =  Off
- * chg: xcache.coveragedump_directory default to ""
- * del: xcache.coveragedumper = Off
-
-New APIs
-========
- * array xcache_coverager_decode(string data)
- * void  xcache_coverager_start([bool clean = true])
- * void  xcache_coverager_stop([bool clean = false])
- * array xcache_coverager_get([bool clean = false])
-
-ChangeLog
-========
- * [290] [291] [292] build with the m4 on solaris
- * [283] removed zend_append_version_info. not needed after [282] 
- * [282] fix possible alloca() scope problem in lock 
- * [281] keep config.nice on make xcachesvnclean 
- * [279] fixed #48, was leaking info when cacher is not enabled by size 
- * [280] [278] trunk: fix coredump on shutdown when loaded as "extension" and after "suhosin" or "zend optimizer". thanks to Alex, Cristian and Esser 
- * [271] fix auto detection of php-cli/php-cgi for test 
- * [270] make [269] pass test cases 
- * [269] do not destruct shallow copied tmp_auto_globals. also improve copying of other hash tables
- * [268] full compatible with auto_globals_jit, no need to disable it in ini from now on 
- * [250] fixed css class on switcher
- * [231] fix zval reference handling
- * [230] update dprint support, added configure option: --enable-xcache-dprint
- * [228] more robust coverager
- * [227] cacher: remove redundant open_basedir check which broke php-src/ext/standard/tests/file/bug24313.phpt 
- * [221] cacher: fix eleak in op_array non-shadow-copy (readonly_protection=on)
- * [220] fixed #36, Bug in inherited static class variables
- * [219] fix prototype for readonly_protection=off, fix testcase Zend/tests/bug37632.phpt 
- * [217] kill leak warning on debug build
- * [216] avoid crash on php compiler error
- * [215] add `make xcachetest` to run xcache enabled test
- * [214] [212] fixed #41, early class binding
- * [272] [267] [263] [200] fixes for php6
- * [224] [193] kill 64bit warning when self test is enabled 
- * [190] trick to load and work with zend optimizer 
- * [189] call op_array_ctor handler on restore to be more compatible with other zend_extension 
- * [257] [183] xcache module is not required by coverage viewer any more
- * [165] xcache.stat support to allow tuning off stat (new ini)
- * [164] better way to handle system level ini settings so it can be display in phpinfo standardly
-
-1.1.0 2006-11-11
- * merged [254] fix xcache.var_ttl displaying in info, fix xcache_get for ttl-unlimited
- * merged [250] admin: fix switcher class on active
- * merged [249] return 0 s instead of empty for deltatime
- * merged [201] coverager: avoid crash when upstream failed to compile file
- * merged from trunk: 159,161-162,167-180,182,184,186-187,194
-   * [194] PHP_5_2: new element in zend_brk_cont_element
-   * [186] [187] fix build on some rare arch
-   * [184] fix tplcov
-   * [178] fix type processor_t conflict with Mac OS X
- * remove redundant open_basedir check, it's done before compiling
- * trick in_compilation state, don't trigger __autoload at compile time
- * FIX conflict between sandbox and user error handler 
- * [154] fix segv on MSHUTDOWN
- * [153] win32/vc build fix
- * [150] avoid crash when OOM on mem_realloc
- * [148] reconstruct shm/allocator
- * [147] show module info in statistics page
- * [146] avoid reading of uninitialized data. thanks to valgrind
- * [144] compat size displaying in admin page func
- * [143] fixed string parameter parsing arg type for disassembler functions. thanks to check_paramaters.php
- * [141] fix cache clear corruption bug
- * [140] fix refcount on cache #1 #2 …
- * [133] admin-page: be more friendly if XCache isn't loaded
- * [132] fix zts on calling destroy_op_array
- * [131] move open_files out of sandbox, it's not needed
- * [130] improve locking for compile
- * [137] [138] changed the coding way of unlinking list. fixed ttl expires dead loop
- * [114] gc expired items, new ini: xcache.ttl xcache.gc_interval xcache.var_ttl …
- * [126] fix xcache_isset reported by http://forum.lighttpd.net/topic/1397
- * [119] fix leak in xcache.test=1; XCACHE_VERSION/XCACHE_MODULES length off-by-one
- * [118] show gc countdown in admin page
- * [113] zts build fix
- * [112] avoid crash when OOM on mem_(calloc|realloc|strndup)
- * [108] update percent bar to vertical/avail
- * [107] show XCache version in admin page
- * [105] trigger jit on $_SERVER when needed
- * [101] note: xcache.mmap_path is a file
- * [100] FIX: alloc'ed wrong size for string on restore
- * [99]  sohosin compatible & TSRM fix.
- * [96]  remove tailing \0 in filename of administration html output. reported by …
- * [94]  PHP_5_2: __tostring cache was MFH by php
- * [93]  try to show both count/size assert before abort
- * [92]  PHP_5_2: auto module_global is maintained by php engine
- * [90] [91] kill compiler warnings
- * [87]  XCACHE_INDENT fallback
- * [84]  handle without inodes
- * [79]  fix messy XCACHE_MAP_FAILED checking
- * [78]  catch up with PHP_5_2, zend_property_info.ce
- * [77]  leakcheck
-
- (not all changesets is list here)
Index: /unk/README
===================================================================
--- /trunk/README	(revision 1003)
+++ 	(revision )
@@ -1,5 +1,0 @@
-XCache is a fast, stable PHP opcode cacher that has been tested and is now running on production servers under high load.
-It is tested (on linux) and supported on all of the latest version of PHP popular release branches.
-ThreadSafe/Windows is also perfectly supported.
-
-Please check http://xcache.lighttpd.net/ and https://groups.google.com/group/xcache for help
Index: /unk/run-xcachetest
===================================================================
--- /trunk/run-xcachetest	(revision 863)
+++ 	(revision )
@@ -1,36 +1,0 @@
-#!/bin/sh
-
-getAbsolutePath() {
-	which readlink >/dev/null 2>&1 && readlink -f "$@" || echo "$@"
-}
-
-# use symlink first
-if test -x ./php-cli ; then
-	php_cli=`getAbsolutePath ./php-cli`
-elif test ! -z "$TEST_PHP_EXECUTABLE" && test -x "$TEST_PHP_EXECUTABLE"; then
-	php_cli="$TEST_PHP_EXECUTABLE"
-else
-	php_cli="`which php`"
-fi
-
-if test -x ./php-cgi ; then
-	php_cgi=`getAbsolutePath ./php-cgi`
-else
-	php_cgi="`which php-cgi`"
-fi
-
-TEST_PHP_EXECUTABLE="$php_cli"
-TEST_PHP_CGI_EXECUTABLE="$php_cgi"
-test -z "$TEST_PHP_SRCDIR" && TEST_PHP_SRCDIR=`getAbsolutePath ./php-src`
-
-export TEST_PHP_EXECUTABLE
-export TEST_PHP_CGI_EXECUTABLE
-export TEST_PHP_SRCDIR
-
-echo "XCache test running with:"
-echo "TEST_PHP_CGI_EXECUTABLE: $TEST_PHP_CGI_EXECUTABLE"
-echo "TEST_PHP_EXECUTABLE:     $TEST_PHP_EXECUTABLE"
-echo "TEST_PHP_SRCDIR:         $TEST_PHP_SRCDIR"
-
-run_tests_php=$TEST_PHP_SRCDIR/run-tests.php
-exec "$php_cli" -d "open_basedir=" -d "safe_mode=0" -d "output_buffering=0" -d "memory_limit=-1" $run_tests_php "$@"
Index: /unk/gen_structinfo.awk
===================================================================
--- /trunk/gen_structinfo.awk	(revision 982)
+++ 	(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/AUTHORS
===================================================================
--- /trunk/AUTHORS	(revision 393)
+++ 	(revision )
@@ -1,1 +1,0 @@
-mOo <phpxcache@gmail.com>
Index: /unk/xcache-test.ini
===================================================================
--- /trunk/xcache-test.ini	(revision 1026)
+++ 	(revision )
@@ -1,25 +1,0 @@
-memory_limit = 256M
-error_reporting = E_ALL|E_STRICT
-
-[xcache]
-extension_dir="./modules/"
-extension=xcache.so
-xcache.cacher = On
-xcache.test = 1
-xcache.stat = 1
-xcache.experimental = On
-xcache.size = 16M
-xcache.count = 1
-xcache.var_size = 1M
-xcache.var_count = 1
-xcache.var_slots = 1000
-; xcache.mmap_path = "/dev/zero"
-xcache.mmap_path = "/tmp/xcache"
-xcache.readonly_protection = Off
-xcache.optimizer = On
-xcache.coredump_directory = "/tmp/"
-;xcache.coveragedump_directory = "/tmp/pcov/"
-xcache.coverager = On
-
-xcache.admin.user = "test"
-xcache.admin.pass = "098f6bcd4621d373cade4e832627b4f6"
