Index: /trunk/xcache.h
===================================================================
--- /trunk/xcache.h	(revision 798)
+++ /trunk/xcache.h	(revision 822)
@@ -22,5 +22,5 @@
 
 #define HAVE_INODE
-#if !defined(ZEND_ENGINE_2_4) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION >= 99 || PHP_MAJOR_VERSION > 5)
+#if !defined(ZEND_ENGINE_2_4) && (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4 || PHP_MAJOR_VERSION > 5)
 #	define ZEND_ENGINE_2_4
 #endif
@@ -450,5 +450,4 @@
 	zend_arg_info *arg_info;
 #endif
-	zend_uint last;
 	zend_op *opcodes;
 } xc_gc_op_array_t;
Index: /trunk/processor/hashtable.m4
===================================================================
--- /trunk/processor/hashtable.m4	(revision 721)
+++ /trunk/processor/hashtable.m4	(revision 822)
@@ -109,10 +109,7 @@
 				/* pnew into hash node chain */
 				pnew->pLast = NULL;
-				if (dst->arBuckets[n]) {
-					pnew->pNext = dst->arBuckets[n];
+				pnew->pNext = dst->arBuckets[n];
+				if (pnew->pNext) {
 					pnew->pNext->pLast = pnew;
-				}
-				else {
-					pnew->pNext = NULL;
 				}
 				dst->arBuckets[n] = pnew;
Index: /trunk/processor/processor.m4
===================================================================
--- /trunk/processor/processor.m4	(revision 785)
+++ /trunk/processor/processor.m4	(revision 822)
@@ -486,5 +486,6 @@
 undefine(`UNION_znode_op')
 define(`UNION_znode_op', `dnl {{{
-	switch ((src->$1_type & ~EXT_TYPE_UNUSED)) {
+#ifndef NDEBUG
+	switch ((src->$1_type ifelse($1, `result', & ~EXT_TYPE_UNUSED))) {
 	case IS_CONST:
 	case IS_VAR:
@@ -497,19 +498,27 @@
 		assert(0);
 	}
+#endif
 
 	dnl dirty dispatch
 	DISABLECHECK(`
-	switch ((src->$1_type & ~EXT_TYPE_UNUSED)) {
+	switch ((src->$1_type ifelse($1, `result', & ~EXT_TYPE_UNUSED))) {
 		case IS_CONST:
-			dnl TODO: fix me, use literals
-			IFDASM(`{
-				zval *zv;
-				ALLOC_INIT_ZVAL(zv);
-				*zv = ((zend_literal *) src->$1.ptr)->constant;
-				zval_copy_ctor(zv);
-				add_assoc_zval_ex(dst, ZEND_STRS("$1.constant"), zv);
+			ifelse($1, `result', `
+				DISPATCH(zend_uint, $1.constant)
+			', `
+				IFDASM(`{
+					zval *zv;
+					ALLOC_INIT_ZVAL(zv);
+					*zv = src->$1.literal->constant;
+					zval_copy_ctor(zv);
+					add_assoc_zval_ex(dst, ZEND_STRS("$1.constant"), zv);
 				}
-			', `
-				DISPATCH(zend_uint, $1.constant)
+				', `
+					IFCOPY(`
+						dst->$1 = src->$1;
+					', `
+						DISPATCH(zend_uint, $1.constant)
+					')
+				')
 			')
 			break;
@@ -517,5 +526,5 @@
 			IFNOTMEMCPY(`
 				default:
-					*dst = *src;
+					$1 = $2;
 			')
 		', `
@@ -607,4 +616,15 @@
 #endif
 	IFCOPY(`
+		pushdef(`UNION_znode_op_literal', `
+			if (dst->$1_type == IS_CONST) {
+				IFSTORE(`
+					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)
+		popdef(`UNION_znode_op_literal')
 		switch (src->opcode) {
 #ifdef ZEND_GOTO
@@ -659,5 +679,5 @@
 	if (shallow_copy) {
 		zend_bool gc_arg_info = 0;
-		int gc_opcodes        = 0;
+		zend_bool gc_opcodes  = 0;
 		/* really fast shallow copy */
 		memcpy(dst, src, sizeof(src[0]));
@@ -669,12 +689,31 @@
 		gc_arg_info = 1;
 #endif
-		IFRESTORE(`dst->filename = processor->entry_src->filepath;')
-#ifndef ZEND_ENGINE_2_4
+		dst->filename = processor->entry_src->filepath;
+#ifdef ZEND_ENGINE_2_4
+		if (src->literals /* || op_array_info->literalsinfo_cnt */) {
+			gc_opcodes = 1;
+		}
+#else
 		if (op_array_info->oplineinfo_cnt) {
+			gc_opcodes = 1;
+		}
+#endif
+		if (gc_opcodes) {
 			zend_op *opline, *end;
-			gc_opcodes = 1;
 			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.constant = opline->$1.literal - src->literals;
+						opline->$1.literal = &dst->literals[opline->$1.constant];
+					}
+				')
+				UNION_znode_op_literal(op1)
+				UNION_znode_op_literal(op2)
+				popdef(`UNION_znode_op_literal')
+#endif
+
 				switch (opline->opcode) {
 #ifdef ZEND_GOTO
@@ -700,5 +739,4 @@
 			}
 		}
-#endif
 		if (gc_arg_info || gc_opcodes) {
 			xc_gc_op_array_t gc_op_array;
@@ -707,5 +745,4 @@
 			gc_op_array.arg_info = gc_arg_info ? dst->arg_info : NULL;
 #endif
-			gc_op_array.last     = gc_opcodes > 1 ? dst->last : 0;
 			gc_op_array.opcodes  = gc_opcodes ? dst->opcodes : NULL;
 			xc_gc_add_op_array(&gc_op_array TSRMLS_CC);
@@ -771,4 +808,10 @@
 	IFSTORE(`dst->refcount[0] = 1;')
 
+#ifdef ZEND_ENGINE_2_4
+	dnl before copying opcodes
+	DISPATCH(int, last_literal)
+	STRUCT_ARRAY(last_literal, zend_literal, literals)
+#endif
+
 	pushdef(`AFTER_ALLOC', `IFCOPY(`
 #ifndef NDEBUG
@@ -857,7 +900,4 @@
 #endif
 #ifdef ZEND_ENGINE_2_4
-	DISPATCH(int, last_literal)
-	IFRESTORE(`COPY(literals)', `STRUCT_ARRAY(last_literal, zend_literal, literals)')
-
 	COPYNULL(run_time_cache)
 	COPYNULL(last_cache_slot)
Index: /trunk/utils.c
===================================================================
--- /trunk/utils.c	(revision 785)
+++ /trunk/utils.c	(revision 822)
@@ -19,8 +19,12 @@
 #endif
 
-#define OP_ZVAL_DTOR(op) do { \
-	Z_UNSET_ISREF(Z_OP_CONSTANT(op)); \
-	zval_dtor(&Z_OP_CONSTANT(op)); \
-} while(0)
+#ifdef ZEND_ENGINE_2_4
+#	define OP_ZVAL_DTOR(op) do { } while(0)
+#else
+#	define OP_ZVAL_DTOR(op) do { \
+		Z_UNSET_ISREF(Z_OP_CONSTANT(op)); \
+		zval_dtor(&Z_OP_CONSTANT(op)); \
+	} while(0)
+#endif
 xc_compile_result_t *xc_compile_result_init(xc_compile_result_t *cr, /* {{{ */
 		zend_op_array *op_array,
@@ -130,10 +134,13 @@
 }
 /* }}} */
-
 int xc_undo_pass_two(zend_op_array *op_array TSRMLS_DC) /* {{{ */
 {
 	zend_op *opline, *end;
 
-#ifndef ZEND_ENGINE_2_4
+#ifdef ZEND_ENGINE_2_4
+	if (!(op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO)) {
+		return 0;
+	}
+#else
 	if (!op_array->done_pass_two) {
 		return 0;
@@ -144,4 +151,13 @@
 	end = opline + op_array->last;
 	while (opline < end) {
+#ifdef ZEND_ENGINE_2_4
+		if (opline->op1_type == IS_CONST) {
+			opline->op1.constant = opline->op1.literal - op_array->literals;
+		}
+		if (opline->op2_type == IS_CONST) {
+			opline->op2.constant = opline->op2.literal - op_array->literals;
+		}
+#endif
+
 #ifdef ZEND_ENGINE_2_1
 		switch (opline->opcode) {
@@ -167,5 +183,7 @@
 		opline++;
 	}
-#ifndef ZEND_ENGINE_2_4
+#ifdef ZEND_ENGINE_2_4
+	op_array->fn_flags &= ~ZEND_ACC_DONE_PASS_TWO;
+#else
 	op_array->done_pass_two = 0;
 #endif
@@ -177,6 +195,13 @@
 {
 	zend_op *opline, *end;
-
-#ifndef ZEND_ENGINE_2_4
+#ifdef ZEND_ENGINE_2_4
+	zend_literal *literal = op_array->literals;
+#endif
+
+#ifdef ZEND_ENGINE_2_4
+	if ((op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO)) {
+		return 0;
+	}
+#else
 	if (op_array->done_pass_two) {
 		return 0;
@@ -188,12 +213,22 @@
 	op_array->size = op_array->last;
 	*/
+#ifdef ZEND_ENGINE_2_4
+	if (literal) {
+		zend_literal *end = literal + op_array->last_literal;
+		while (literal < end) {
+			Z_SET_ISREF(literal->constant);
+			Z_SET_REFCOUNT(literal->constant, 2); /* Make sure is_ref won't be reset */
+			literal++;
+		}
+	}
+#endif
 
 	opline = op_array->opcodes;
 	end = opline + op_array->last;
 	while (opline < end) {
+#ifndef ZEND_ENGINE_2_4
 		if (Z_OP_TYPE(opline->op1) == IS_CONST) {
 			Z_SET_ISREF(Z_OP_CONSTANT(opline->op1));
 			Z_SET_REFCOUNT(Z_OP_CONSTANT(opline->op1), 2); /* Make sure is_ref won't be reset */
-
 		}
 		if (Z_OP_TYPE(opline->op2) == IS_CONST) {
@@ -201,4 +236,5 @@
 			Z_SET_REFCOUNT(Z_OP_CONSTANT(opline->op2), 2);
 		}
+#endif
 #ifdef ZEND_ENGINE_2_1
 		switch (opline->opcode) {
@@ -226,5 +262,7 @@
 	}
 
-#ifndef ZEND_ENGINE_2_4
+#ifdef ZEND_ENGINE_2_4
+	op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
+#else
 	op_array->done_pass_two = 1;
 #endif
Index: /trunk/optimizer.c
===================================================================
--- /trunk/optimizer.c	(revision 716)
+++ /trunk/optimizer.c	(revision 822)
@@ -19,4 +19,10 @@
 #else
 #	define XCACHE_IS_CV 16
+#endif
+
+#ifdef ZEND_ENGINE_2_4
+#	undef Z_OP_CONSTANT
+/* Z_OP_CONSTANT is used before pass_two is applied */
+#	define Z_OP_CONSTANT(op) op_array->literals[op.constant].constant
 #endif
 
