Index: /trunk/config.m4
===================================================================
--- /trunk/config.m4	(revision 94)
+++ /trunk/config.m4	(revision 95)
@@ -18,4 +18,10 @@
 
 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 \
Index: /trunk/config.w32
===================================================================
--- /trunk/config.w32	(revision 94)
+++ /trunk/config.w32	(revision 95)
@@ -5,4 +5,11 @@
 
 if (PHP_XCACHE != "no") {
+	// {{{ 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");
+	}
+	// }}}
+
 	var xcache_sources = "processor.c \
 	                      xcache.c \
Index: /trunk/processor/processor.m4
===================================================================
--- /trunk/processor/processor.m4	(revision 94)
+++ /trunk/processor/processor.m4	(revision 95)
@@ -5,4 +5,7 @@
 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_t')
@@ -59,4 +62,7 @@
 dnl }}}
 DEF_HASH_TABLE_FUNC(`HashTable_zval_ptr',           `zval_ptr')
+#ifdef HAVE_XCACHE_CONSTANT
+DEF_HASH_TABLE_FUNC(`HashTable_zend_constant',      `zend_constant')
+#endif
 DEF_HASH_TABLE_FUNC(`HashTable_zend_function',      `zend_function')
 #ifdef ZEND_ENGINE_2
@@ -205,4 +211,15 @@
 #endif
 dnl }}}
+#ifdef HAVE_XCACHE_CONSTANT
+DEF_STRUCT_P_FUNC(`zend_constant', , `dnl {{{
+	STRUCT(zval, value)
+	DISPATCH(int, flags)
+	DISPATCH(uint, name_len)
+	PROC_STRING_L(name, name_len)
+	zstr name;
+	DISPATCH(int, module_number)
+')
+dnl }}}
+#endif
 DEF_STRUCT_P_FUNC(`zend_function', , `dnl {{{
 	DISABLECHECK(`
@@ -599,6 +616,5 @@
 	STRUCT_P(HashTable, static_variables, HashTable_zval_ptr)
 
-	IFCOPY(`dst->start_op = src->start_op;')
-	DONE(start_op)
+	COPY(start_op)
 	DISPATCH(int, backpatch_count)
 
@@ -628,4 +644,17 @@
 dnl }}}
 
+#ifdef HAVE_XCACHE_CONSTANT
+DEF_STRUCT_P_FUNC(`xc_constinfo_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_constant, constant)
+')
+dnl }}}
+#endif
 DEF_STRUCT_P_FUNC(`xc_funcinfo_t', , `dnl {{{
 	DISPATCH(zend_uint, key_size)
@@ -666,4 +695,9 @@
 
 	STRUCT_P(zend_op_array, op_array)
+
+#ifdef HAVE_XCACHE_CONSTANT
+	DISPATCH(zend_uint, constinfo_cnt)
+	STRUCT_ARRAY(constinfo_cnt, xc_constinfo_t, constinfos)
+#endif
 
 	DISPATCH(zend_uint, funcinfo_cnt)
Index: /trunk/utils.c
===================================================================
--- /trunk/utils.c	(revision 94)
+++ /trunk/utils.c	(revision 95)
@@ -265,4 +265,23 @@
 #endif
 
+#ifdef HAVE_XCACHE_CONSTANT
+void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
+{
+	if (zend_u_hash_add(EG(zend_constants), type, key, len,
+				constant, sizeof(zend_constant),
+				NULL
+				) == FAILURE) {
+		CG(in_compilation) = 1;
+		CG(compiled_filename) = filename;
+		CG(zend_lineno) = 0;
+		zend_error(E_NOTICE, "Constant %s already defined", key);
+		free(constant->name);
+		if (!(constant->flags & CONST_PERSISTENT)) {
+			zval_dtor(&constant->value);
+		}
+	}
+}
+/* }}} */
+#endif
 void xc_install_function(char *filename, zend_function *func, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
 {
@@ -316,4 +335,14 @@
 #define OG(x) (sandbox->orig_##x)
 /* }}} */
+#ifdef HAVE_XCACHE_CONSTANT
+static void xc_constant_copy_ctor(zend_constant *c) /* {{{ */
+{
+	c->name = zend_strndup(c->name, c->name_len - 1);
+	if (!(c->flags & CONST_PERSISTENT)) {
+		zval_copy_ctor(&c->value);
+	}
+}
+/* }}} */
+#endif
 xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, char *filename TSRMLS_DC) /* {{{ */
 {
@@ -325,6 +354,12 @@
 		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)));
+
+#ifdef HAVE_XCACHE_CONSTANT
+	OG(zend_constants) = EG(zend_constants);
+	EG(zend_constants) = &TG(zend_constants);
+#endif
 
 	OG(function_table) = CG(function_table);
@@ -342,4 +377,7 @@
 	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);
+#ifdef HAVE_XCACHE_CONSTANT
+	zend_hash_init_ex(&TG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1, 0);
+#endif
 	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);
@@ -356,4 +394,15 @@
 	zend_llist_position lpos;
 	zend_file_handle *handle;
+
+#ifdef HAVE_XCACHE_CONSTANT
+	b = TG(zend_constants).pListHead;
+	/* install constants */
+	while (b != NULL) {
+		zend_constant *c = (zend_constant*) b->pData;
+		xc_install_constant(sandbox->filename, c,
+				BUCKET_KEY_TYPE(b), BUCKET_KEY(b), b->nKeyLength TSRMLS_CC);
+		b = b->pListNext;
+	}
+#endif
 
 	b = TG(function_table).pListHead;
@@ -386,4 +435,7 @@
 {
 	/* restore first first install function/class */
+#ifdef HAVE_XCACHE_CONSTANT
+	EG(zend_constants) = OG(zend_constants);
+#endif
 	CG(function_table) = OG(function_table);
 	CG(class_table)    = OG(class_table);
@@ -394,4 +446,7 @@
 
 		/* no free as it's installed */
+#ifdef HAVE_XCACHE_CONSTANT
+		TG(zend_constants).pDestructor = NULL;
+#endif
 		TG(function_table).pDestructor = NULL;
 		TG(class_table).pDestructor = NULL;
@@ -400,4 +455,7 @@
 
 	/* destroy all the tmp */
+#ifdef HAVE_XCACHE_CONSTANT
+	zend_hash_destroy(&TG(zend_constants));
+#endif
 	zend_hash_destroy(&TG(function_table));
 	zend_hash_destroy(&TG(class_table));
Index: /trunk/utils.h
===================================================================
--- /trunk/utils.h	(revision 94)
+++ /trunk/utils.h	(revision 95)
@@ -26,4 +26,7 @@
 
 /* installer */
+#ifdef HAVE_XCACHE_CONSTANT
+void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, void *key, uint len TSRMLS_DC);
+#endif
 void xc_install_function(char *filename, zend_function *func, zend_uchar type, void *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);
@@ -39,4 +42,8 @@
 	zend_llist *tmp_open_files;
 
+#ifdef HAVE_XCACHE_CONSTANT
+	HashTable *orig_zend_constants;
+	HashTable tmp_zend_constants;
+#endif
 	HashTable *orig_function_table;
 	HashTable *orig_class_table;
Index: /trunk/xcache.c
===================================================================
--- /trunk/xcache.c	(revision 94)
+++ /trunk/xcache.c	(revision 95)
@@ -301,13 +301,16 @@
 		case XC_TYPE_PHP:
 			php = entry->data.php;
-			add_assoc_long_ex(ei, ZEND_STRS("sourcesize"),   php->sourcesize);
+			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);
+			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);
+
+#ifdef HAVE_XCACHE_CONSTANT
+			add_assoc_long_ex(ei, ZEND_STRS("constinfo_cnt"), php->constinfo_cnt);
+#endif
+			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:
@@ -354,4 +357,13 @@
 	/* 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
+
+#ifdef HAVE_XCACHE_CONSTANT
+	/* install constant */
+	for (i = 0; i < p->constinfo_cnt; i ++) {
+		xc_constinfo_t *ci = &p->constinfos[i];
+		xc_install_constant(xce->name.str.val, &ci->constant,
+				UNISW(0, ci->type), ci->key, ci->key_size TSRMLS_CC);
+	}
 #endif
 
@@ -594,4 +606,5 @@
 	zend_bool catched = 0;
 	char *filename;
+	int old_constinfo_cnt, old_funcinfo_cnt, old_classinfo_cnt;
 
 	if (!xc_initized) {
@@ -675,4 +688,8 @@
 	xc_sandbox_init(&sandbox, filename TSRMLS_CC);
 
+	old_classinfo_cnt = zend_hash_num_elements(CG(class_table));
+	old_funcinfo_cnt  = zend_hash_num_elements(CG(function_table));
+	old_constinfo_cnt  = zend_hash_num_elements(EG(zend_constants));
+
 	zend_try {
 		op_array = origin_compile_file(h, type TSRMLS_CC);
@@ -703,15 +720,28 @@
 	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;
-	}
+#ifdef HAVE_XCACHE_CONSTANT
+	php.constinfo_cnt = zend_hash_num_elements(EG(zend_constants)) - old_constinfo_cnt;
+#endif
+	php.funcinfo_cnt  = zend_hash_num_elements(CG(function_table)) - old_funcinfo_cnt;
+	php.classinfo_cnt = zend_hash_num_elements(CG(class_table))    - old_classinfo_cnt;
+
+#define X_ALLOC_N(var, cnt) do {     \
+	if (php.cnt) {                   \
+		ECALLOC_N(php.var, php.cnt); \
+		if (!php.var) {              \
+			goto err_##var;          \
+		}                            \
+	}                                \
+	else {                           \
+		php.var = NULL;              \
+	}                                \
+} while (0)
+
+#ifdef HAVE_XCACHE_CONSTANT
+	X_ALLOC_N(constinfos, constinfo_cnt);
+#endif
+	X_ALLOC_N(funcinfos,  funcinfo_cnt);
+	X_ALLOC_N(classinfos, classinfo_cnt);
+#undef X_ALLOC
 	/* }}} */
 	/* {{{ shallow copy, pointers only */ {
@@ -719,28 +749,29 @@
 		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(NOTHING, 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(NOTHING, ci->type = b->key.type;)
-			ci->key        = BUCKET_KEY(b);
-			ci->key_size   = b->nKeyLength;
-			/* need to fix inside store */
-		}
+#define COPY_H(vartype, var, cnt, name, datatype) do {        \
+	for (i = 0; b; i ++, b = b->pListNext) {                  \
+		vartype *data = &php.var[i];                          \
+                                                              \
+		if (i < old_##cnt) {                                  \
+			continue;                                         \
+		}                                                     \
+                                                              \
+		assert(i < old_##cnt + php.cnt);                      \
+		assert(b->pData);                                     \
+		memcpy(&data->name, b->pData, sizeof(datatype));      \
+		UNISW(NOTHING, data->type = b->key.type;)             \
+		data->key        = BUCKET_KEY(b);                     \
+		data->key_size   = b->nKeyLength;                     \
+	}                                                         \
+} while(0)
+
+#ifdef HAVE_XCACHE_CONSTANT
+		b = EG(zend_constants)->pListHead; COPY_H(xc_constinfo_t, constinfos, constinfo_cnt, constant, zend_constant);
+#endif
+		b = CG(function_table)->pListHead; COPY_H(xc_funcinfo_t,  funcinfos,  funcinfo_cnt,  func,     zend_function);
+		b = CG(class_table)->pListHead;    COPY_H(xc_classinfo_t, classinfos, classinfo_cnt, cest,     xc_cest_t);
+
+#undef COPY_H
+		/* for ZE1, cest need to fix inside store */
 	}
 	/* }}} */
@@ -754,8 +785,17 @@
 #endif
 
-	efree(xce.data.php->classinfos);
-err_class:
-	efree(xce.data.php->funcinfos);
-err_func:
+#define X_FREE(var) \
+	if (xce.data.php->var) { \
+		efree(xce.data.php->var); \
+	} \
+err_##var:
+
+	X_FREE(classinfos)
+	X_FREE(funcinfos)
+#ifdef HAVE_XCACHE_CONSTANT
+	X_FREE(constinfos)
+#endif
+#undef X_FREE
+
 err_oparray:
 err_bailout:
@@ -790,9 +830,27 @@
 #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);
+
+	catched = 0;
+	zend_try {
+		op_array = xc_entry_install(&xce, h TSRMLS_CC);
+	} zend_catch {
+		catched = 1;
+	} zend_end_try();
+
+#define X_FREE(var) \
+	if (xce.data.php->var) { \
+		efree(xce.data.php->var); \
+	}
+	X_FREE(classinfos)
+	X_FREE(funcinfos)
+#ifdef HAVE_XCACHE_CONSTANT
+	X_FREE(constinfos)
+#endif
+#undef X_FREE
 	efree(xce.data.php);
+
+	if (catched) {
+		zend_bailout();
+	}
 #ifdef DEBUG
 	fprintf(stderr, "restored\n");
Index: /trunk/xcache.h
===================================================================
--- /trunk/xcache.h	(revision 94)
+++ /trunk/xcache.h	(revision 95)
@@ -154,4 +154,16 @@
 } xc_classinfo_t;
 /* }}} */
+#ifdef HAVE_XCACHE_CONSTANT
+/* {{{ xc_constinfo_t */
+typedef struct {
+#ifdef IS_UNICODE
+	zend_uchar type;
+#endif
+	char *key;
+	zend_uint key_size;
+	zend_constant constant;
+} xc_constinfo_t;
+/* }}} */
+#endif
 /* {{{ xc_funcinfo_t */
 typedef struct {
@@ -175,4 +187,9 @@
 
 	zend_op_array *op_array;
+
+#ifdef HAVE_XCACHE_CONSTANT
+	zend_uint constinfo_cnt;
+	xc_constinfo_t *constinfos;
+#endif
 
 	zend_uint funcinfo_cnt;
