Index: /trunk/processor/head.m4
===================================================================
--- /trunk/processor/head.m4	(revision 102)
+++ /trunk/processor/head.m4	(revision 103)
@@ -47,4 +47,8 @@
 typedef zval *zval_ptr;
 typedef zend_uchar zval_data_type;
+#ifdef IS_UNICODE
+typedef UChar zstr_uchar;
+#endif
+typedef char  zstr_char;
 
 #define MAX_DUP_STR_LEN 256
@@ -82,14 +86,44 @@
 #endif
 /* }}} */
+/* {{{ xc_zstrlen_char */
+static inline int xc_zstrlen_char(zstr s)
+{
+	return strlen(ZSTR_S(s));
+}
+/* }}} */
+#ifdef IS_UNICODE
+/* {{{ xc_zstrlen_uchar */
+static inline int xc_zstrlen_uchar(zstr s)
+{
+	int i;
+	UChar *p = ZSTR_U(s);
+	for (i = 0; *p; i ++, p++) {
+		/* empty */
+	}
+	return i;
+}
+/* }}} */
+/* {{{ xc_zstrlen */
+static inline int xc_zstrlen(int type, 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
 /* {{{ xc_calc_string_n */
 REDEF(`KIND', `calc')
-static inline void xc_calc_string_n(processor_t *processor, zend_uchar type, char *str, long size IFASSERT(`, int relayline')) {
+static inline void xc_calc_string_n(processor_t *processor, zend_uchar type, zstr str, long size IFASSERT(`, int relayline')) {
 	pushdef(`__LINE__', `relayline')
 	int realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
+	long dummy = 1;
 
 	if (realsize > MAX_DUP_STR_LEN) {
 		ALLOC(, char, realsize)
 	}
-	else if (zend_u_hash_add(&processor->strings, type, str, size, (void*)&str, sizeof(char*), NULL) == SUCCESS) {
+	else if (zend_u_hash_add(&processor->strings, type, str, size, (void *) &dummy, sizeof(dummy), NULL) == SUCCESS) {
 		/* new string */
 		ALLOC(, char, realsize)
@@ -97,5 +131,5 @@
 	IFASSERT(`
 		else {
-			dnl fprintf(stderr, "dupstr %s\n", str);
+			dnl fprintf(stderr, "dupstr %s\n", ZSTR_S(str));
 		}
 	')
@@ -105,23 +139,25 @@
 /* {{{ xc_store_string_n */
 REDEF(`KIND', `store')
-static inline char *xc_store_string_n(processor_t *processor, zend_uchar type, char *str, long size IFASSERT(`, int relayline')) {
+static inline zstr xc_store_string_n(processor_t *processor, zend_uchar type, zstr str, long size IFASSERT(`, int relayline')) {
 	pushdef(`__LINE__', `relayline')
 	int realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
-	char *s;
+	zstr ret, *pret;
 
 	if (realsize > MAX_DUP_STR_LEN) {
-		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;
+		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, 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, size, (void *) &ret, sizeof(zstr), NULL);
+	return ret;
+
 	popdef(`__LINE__')
 }
@@ -185,7 +221,8 @@
 	}
 	else {
+dnl FIXME: handle common.function_name here
 #define SET_IF_SAME_NAME(member) \
 		do { \
-			if(!strcasecmp(zf->common.function_name, #member)) { \
+			if (!strcasecmp(ZSTR_S(zf->common.function_name), #member)) { \
 				ce->member = zf; \
 			} \
Index: /trunk/processor/processor.m4
===================================================================
--- /trunk/processor/processor.m4	(revision 102)
+++ /trunk/processor/processor.m4	(revision 103)
@@ -19,5 +19,5 @@
 DEF_STRUCT_P_FUNC(`zend_compiled_variable', , `
 	DISPATCH(int, name_len)
-	PROC_USTRING_L(, name, name_len)
+	PROC_ZSTRING_L(, name, name_len)
 	DISPATCH(ulong, hash_value)
 ')
@@ -115,6 +115,6 @@
 			case IS_UNICODE:
 proc_unicode:
-				DISPATCH(int32_t, value.ustr.len)
-				PROC_USTRING_L(1, value.ustr.val, value.ustr.len)
+				DISPATCH(int32_t, value.uni.len)
+				PROC_ZSTRING_L(1, value.uni.val, value.uni.len)
 				break;
 #endif
@@ -200,7 +200,7 @@
 DEF_STRUCT_P_FUNC(`zend_arg_info', , `
 	DISPATCH(zend_uint, name_len)
-	PROC_USTRING_L(, name, name_len)
+	PROC_ZSTRING_L(, name, name_len)
 	DISPATCH(zend_uint, class_name_len)
-	PROC_USTRING_L(, class_name, class_name_len)
+	PROC_ZSTRING_L(, class_name, class_name_len)
 	DISPATCH(zend_bool, array_type_hint)
 	DISPATCH(zend_bool, allow_null)
@@ -216,5 +216,5 @@
 	DISPATCH(int, flags)
 	DISPATCH(uint, name_len)
-	PROC_STRING_L(name, name_len)
+	PROC_ZSTRING_L(, name, name_len)
 	zstr name;
 	DISPATCH(int, module_number)
@@ -248,9 +248,9 @@
 	DISPATCH(zend_uint, flags)
 	DISPATCH(int, name_length)
-	PROC_USTRING_L(, name, name_length)
+	PROC_ZSTRING_L(, name, name_length)
 	DISPATCH(ulong, h)
 #ifdef ZEND_ENGINE_2_1
 	DISPATCH(int, doc_comment_len)
-	PROC_USTRING_L(, doc_comment, doc_comment_len)
+	PROC_STRING_L(doc_comment, doc_comment_len)
 #endif
 	dnl isnt in php6 yet
@@ -268,5 +268,5 @@
 	DISPATCH(char, type)
 	DISPATCH(zend_uint, name_length)
-	PROC_USTRING_L(, name, name_length)
+	PROC_ZSTRING_L(, name, name_length)
 	IFRESTORE(`
 #ifndef ZEND_ENGINE_2
@@ -344,5 +344,5 @@
 #ifdef ZEND_ENGINE_2_1
 	DISPATCH(zend_uint, doc_comment_len)
-	PROC_USTRING_L(, doc_comment, doc_comment_len)
+	PROC_STRING_L(doc_comment, doc_comment_len)
 #endif
 	/* # NOT DONE */
@@ -370,7 +370,4 @@
 #endif
 	COPY(__call)
-#ifdef IS_UNICODE
-	SETNULL(u_twin)
-#endif
 	/* # NOT DONE */
 	COPY(module)
@@ -498,5 +495,5 @@
 	/* Common elements */
 	DISPATCH(zend_uchar, type)
-	PROC_USTRING(, function_name)
+	PROC_ZSTRING(, function_name)
 #ifdef ZEND_ENGINE_2
 	IFRESTORE(`
@@ -517,5 +514,5 @@
 				 && zend_u_hash_find(&(processor->active_class_entry_dst->parent->function_table),
 						UG(unicode) ? IS_UNICODE : IS_STRING,
-						src->function_name, strlen(src->function_name) + 1,
+						src->function_name, xc_zstrlen(UG(unicode), src->function_name) + 1,
 						(void **) &parent) == SUCCESS) {
 					/* see do_inherit_method_check() */
@@ -574,5 +571,5 @@
 	/* END of common elements */
 #ifdef IS_UNICODE
-	SETNULL(u_twin)
+	dnl SETNULL(u_twin)
 #endif
 
@@ -632,5 +629,5 @@
 	DISPATCH(zend_uint, line_end)
 	DISPATCH(int, doc_comment_len)
-	PROC_USTRING_L(, doc_comment, doc_comment_len)
+	PROC_STRING_L(doc_comment, doc_comment_len)
 #endif
 
@@ -651,5 +648,5 @@
 #endif
 	IFRESTORE(`COPY(key)', `
-		PROC_USTRING_N(type, key, key_size)
+		PROC_ZSTRING_N(type, key, key_size)
 	')
 	STRUCT(zend_constant, constant)
@@ -663,5 +660,5 @@
 #endif
 	IFRESTORE(`COPY(key)', `
-		PROC_USTRING_N(type, key, key_size)
+		PROC_ZSTRING_N(type, key, key_size)
 	')
 	STRUCT(zend_function, func)
@@ -674,5 +671,5 @@
 #endif
 	IFRESTORE(`COPY(key)', `
-		PROC_USTRING_N(type, key, key_size)
+		PROC_ZSTRING_N(type, key, key_size)
 	')
 #ifdef ZEND_ENGINE_2
@@ -765,5 +762,11 @@
 		DISPATCH(int, name.str.len)
 #endif
-		IFRESTORE(`COPY(name.str.val)', `PROC_USTRING_L(name_type, name.str.val, name.str.len)')
+		IFRESTORE(`COPY(name.str.val)', `
+#ifdef IS_UNICODE
+			PROC_ZSTRING_L(name_type, name.uni.val, name.uni.len)
+#else
+			PROC_STRING_L(name.str.val, name.str.len)
+#endif
+		')
 	')
 	DONE(name)
Index: /trunk/processor/string.m4
===================================================================
--- /trunk/processor/string.m4	(revision 102)
+++ /trunk/processor/string.m4	(revision 103)
@@ -3,8 +3,25 @@
 define(`PROC_STRING_N_EX', `
 	pushdef(`STRTYPE', `ifelse(`$5',,`char',`$5')')
-	pushdef(`ISTYPE', ifelse(STRTYPE,`char',IS_STRING,IS_UNICODE))
-	if ($2 == NULL) {
+	pushdef(`PTRTYPE', ifelse(
+			STRTYPE, `char',      `char',
+			STRTYPE, `zstr_char', `char',
+			`',      `',          `UChar'))
+	pushdef(`ISTYPE', ifelse(STRTYPE,`zstr_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)',`$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'))
+	if (SRCPTR == NULL) {
 		IFNOTMEMCPY(`IFCOPY(`
-			$1 = NULL;
+			DSTPTR = NULL;
 		')')
 		IFDASM(`
@@ -14,5 +31,5 @@
 	else {
 		IFDPRINT(`INDENT()
-			ifelse(STRTYPE, `UChar', `
+			ifelse(STRTYPE, `zstr_uchar', `
 #ifdef IS_UNICODE
 			do {
@@ -32,16 +49,16 @@
 #endif
 			', `
-			fprintf(stderr, "string:%s:\t\"%s\" len=%d\n", "$1", $2, $3 - 1);
+			fprintf(stderr, "string:%s:\t\"%s\" len=%d\n", "$1", SRCPTR, $3 - 1);
 			')
 		')
-		IFCALC(`xc_calc_string_n(processor, ISTYPE, (void *) $2, `$3' IFASSERT(`, __LINE__'));')
-		IFSTORE(`$1 = (STRTYPE *) xc_store_string_n(processor, ISTYPE, (char *) $2, `$3' IFASSERT(`, __LINE__'));')
+		IFCALC(`xc_calc_string_n(processor, ISTYPE, SRCSTR, $3 IFASSERT(`, __LINE__'));')
+		IFSTORE(`DSTPTR = ifelse(PTRTYPE,`char',`ZSTR_S',`ZSTR_U')(xc_store_string_n(processor, ISTYPE, SRCSTR, $3 IFASSERT(`, __LINE__')));')
 		IFRESTORE(`
-			ALLOC(`$1', `STRTYPE', `($3)')
-			memcpy($1, $2, sizeof(STRTYPE) * ($3));
+			ALLOC(DSTPTR, `STRTYPE', `($3)')
+			memcpy(DSTPTR, SRCPTR, sizeof(STRTYPE) * ($3));
 		')
-		FIXPOINTER_EX(`STRTYPE', `$1')
+		FIXPOINTER_EX(`PTRTYPE', DSTPTR)
 		IFDASM(`
-				ifelse(STRTYPE,UChar, `
+				ifelse(STRTYPE,zstr_uchar, `
 					add_assoc_unicodel_ex(dst, ZEND_STRS("$4"), $2, $3-1, 1);
 					', ` dnl else
@@ -49,4 +66,8 @@
 				')
 	}
+	popdef(`DSTPTR')
+	popdef(`SRCPTR')
+	popdef(`SRCSTR')
+	popdef(`UNI_STRLEN')
 	popdef(`STRTYPE')
 	popdef(`ISTYPE')
@@ -59,30 +80,30 @@
 define(`PROC_STRING',   `DBG(`$0($*)') DONE(`$1')`'PROC_STRING_N_EX(`dst->$1', `src->$1', `strlen(src->$1) + 1', `$1', `char')')
 
-dnl {{{ PROC_USTRING_N(1:type, 2:name, 3:size, 4:size_type)
-define(`PROC_USTRING_N', `
+dnl {{{ PROC_ZSTRING_N(1:type, 2:name, 3:size, 4:size_type)
+define(`PROC_ZSTRING_N', `
 	DBG(`$0($*)')
 #ifdef IS_UNICODE
 	pushdef(`NSIZE', ifelse(
-			`$4', `strlen', `strlen(src->$2) + 1',
+			`$4', `strlen', `UNI_STRLEN (src->$2) + 1',
 			`$4', `len',    `src->$3 + 1',
 			`',   `',       `src->$3',
 			))
 	DONE(`$2')
-	ifelse(`$1', `1', `PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `UChar')
+	ifelse(`$1', `1', `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')
+		if (ifelse(`$1', `', `UG(unicode)', `src->$1 == IS_UNICODE')) {
+			PROC_STRING_N_EX(`dst->$2', `src->$2', defn(`NSIZE'), `$2', `zstr_uchar')
 		}
 		else {
-			PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `char')
+			PROC_STRING_N_EX(`dst->$2', `src->$2', defn(`NSIZE'), `$2', `zstr_char')
 		}
 	')
 #else
 	DONE(`$2')
-	PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `char')
+	PROC_STRING_N_EX(`dst->$2', `src->$2', NSIZE, `$2', `zstr_char')
 #endif
 	popdef(`NSIZE')
 ')
 // }}}
-define(`PROC_USTRING_L', `DBG(`$0($*)') PROC_USTRING_N(`$1', `$2', `$3', `len')')
-define(`PROC_USTRING', `DBG(`$0($*)') PROC_USTRING_N(`$1', `$2', , `strlen')')
+define(`PROC_ZSTRING_L', `DBG(`$0($*)') PROC_ZSTRING_N(`$1', `$2', `$3', `len')')
+define(`PROC_ZSTRING', `DBG(`$0($*)') PROC_ZSTRING_N(`$1', `$2', , `strlen')')
Index: /trunk/utils.c
===================================================================
--- /trunk/utils.c	(revision 102)
+++ /trunk/utils.c	(revision 103)
@@ -266,5 +266,5 @@
 
 #ifdef HAVE_XCACHE_CONSTANT
-void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
+void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, zstr key, uint len TSRMLS_DC) /* {{{ */
 {
 	if (zend_u_hash_add(EG(zend_constants), type, key, len,
@@ -275,6 +275,10 @@
 		CG(compiled_filename) = filename;
 		CG(zend_lineno) = 0;
+#ifdef IS_UNICODE
+		zend_error(E_NOTICE, "Constant %R already defined", type, key);
+#else
 		zend_error(E_NOTICE, "Constant %s already defined", key);
-		free(constant->name);
+#endif
+		free(ZSTR_V(constant->name));
 		if (!(constant->flags & CONST_PERSISTENT)) {
 			zval_dtor(&constant->value);
@@ -284,8 +288,15 @@
 /* }}} */
 #endif
-void xc_install_function(char *filename, zend_function *func, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
-{
+void xc_install_function(char *filename, zend_function *func, zend_uchar type, zstr key, uint len TSRMLS_DC) /* {{{ */
+{
+	zend_bool istmpkey;
+
 	if (func->type == ZEND_USER_FUNCTION) {
-		if (*(char *) key == '\0') {
+#ifdef IS_UNICODE
+		istmpkey = (type == IS_STRING && ZSTR_S(key)[0] == 0) || ZSTR_U(key)[0] == 0;
+#else
+		istmpkey = ZSTR_S(key)[0] == 0;
+#endif
+		if (istmpkey) {
 			zend_u_hash_update(CG(function_table), type, key, len,
 						func, sizeof(zend_op_array),
@@ -300,15 +311,25 @@
 			CG(compiled_filename) = filename;
 			CG(zend_lineno) = ZESW(func->op_array.opcodes[0].lineno, func->op_array.line_start);
+#ifdef IS_UNICODE
+			zend_error(E_ERROR, "Cannot redeclare %R()", type, key);
+#else
 			zend_error(E_ERROR, "Cannot redeclare %s()", key);
-		}
-	}
-}
-/* }}} */
-ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, void *key, uint len TSRMLS_DC) /* {{{ */
-{
+#endif
+		}
+	}
+}
+/* }}} */
+ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, zstr key, uint len TSRMLS_DC) /* {{{ */
+{
+	zend_bool istmpkey;
 	zend_class_entry *cep = CestToCePtr(*cest);
 	ZESW(void *stored_ce_ptr, NOTHING);
 
-	if (*(char *) key == '\0') {
+#ifdef IS_UNICODE
+	istmpkey = (type == IS_STRING && ZSTR_S(key)[0] == 0) || ZSTR_U(key)[0] == 0;
+#else
+	istmpkey = ZSTR_S(key)[0] == 0;
+#endif
+	if (istmpkey) {
 		zend_u_hash_update(CG(class_table), type, key, len,
 					cest, sizeof(xc_cest_t),
@@ -323,5 +344,9 @@
 		CG(compiled_filename) = filename;
 		CG(zend_lineno) = ZESW(0, cep->line_start);
-		zend_error(E_ERROR, "Cannot redeclare class %s", (char *) cep->name);
+#ifdef IS_UNICODE
+		zend_error(E_ERROR, "Cannot redeclare class %R", type, cep->name);
+#else
+		zend_error(E_ERROR, "Cannot redeclare class %s", cep->name);
+#endif
 	}
 	ZESW(return (xc_cest_t *) stored_ce_ptr, NOTHING);
@@ -338,5 +363,13 @@
 static void xc_constant_copy_ctor(zend_constant *c) /* {{{ */
 {
-	c->name = zend_strndup(c->name, c->name_len - 1);
+#ifdef IS_UNICODE
+	if (UG(unicode)) {
+		ZSTR_U(c->name) = zend_ustrndup(ZSTR_U(c->name), c->name_len - 1);
+	}
+	else
+#endif
+	{
+		ZSTR_S(c->name) = zend_strndup(ZSTR_S(c->name), c->name_len - 1);
+	}
 	if (!(c->flags & CONST_PERSISTENT)) {
 		zval_copy_ctor(&c->value);
@@ -401,5 +434,5 @@
 		zend_constant *c = (zend_constant*) b->pData;
 		xc_install_constant(sandbox->filename, c,
-				BUCKET_KEY_TYPE(b), BUCKET_KEY(b), b->nKeyLength TSRMLS_CC);
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY(b)), b->nKeyLength TSRMLS_CC);
 		b = b->pListNext;
 	}
@@ -411,5 +444,5 @@
 		zend_function *func = (zend_function*) b->pData;
 		xc_install_function(sandbox->filename, func,
-				BUCKET_KEY_TYPE(b), BUCKET_KEY(b), b->nKeyLength TSRMLS_CC);
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY(b)), b->nKeyLength TSRMLS_CC);
 		b = b->pListNext;
 	}
@@ -419,5 +452,5 @@
 	while (b != NULL) {
 		xc_install_class(sandbox->filename, (xc_cest_t*)b->pData,
-				BUCKET_KEY_TYPE(b), BUCKET_KEY(b), b->nKeyLength TSRMLS_CC);
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY(b)), b->nKeyLength TSRMLS_CC);
 		b = b->pListNext;
 	}
Index: /trunk/utils.h
===================================================================
--- /trunk/utils.h	(revision 102)
+++ /trunk/utils.h	(revision 103)
@@ -27,8 +27,8 @@
 /* installer */
 #ifdef HAVE_XCACHE_CONSTANT
-void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, void *key, uint len TSRMLS_DC);
+void xc_install_constant(char *filename, zend_constant *constant, zend_uchar type, zstr 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);
+void xc_install_function(char *filename, zend_function *func, zend_uchar type, zstr key, uint len TSRMLS_DC);
+ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, zstr key, uint len TSRMLS_DC);
 
 /* sandbox */
Index: /trunk/xcache.c
===================================================================
--- /trunk/xcache.c	(revision 102)
+++ /trunk/xcache.c	(revision 103)
@@ -503,5 +503,5 @@
 static inline xc_hash_value_t xc_entry_hash_var(xc_entry_t *xce) /* {{{ */
 {
-	return UNISW(NOTHING, UG(unicode) ? HASH_USTR_L(xce->name_type, (char *)xce->name.ustr.val, xce->name.ustr.len) :)
+	return UNISW(NOTHING, UG(unicode) ? HASH_USTR_L(xce->name_type, xce->name.uni.val, xce->name.uni.len) :)
 		HASH_STR_L(xce->name.str.val, xce->name.str.len);
 }
@@ -761,5 +761,10 @@
 		memcpy(&data->name, b->pData, sizeof(datatype));      \
 		UNISW(NOTHING, data->type = b->key.type;)             \
-		data->key        = BUCKET_KEY(b);                     \
+		if (UNISW(1, b->key.type == IS_STRING)) {             \
+			ZSTR_S(data->key)      = BUCKET_KEY(b);           \
+		}                                                     \
+		else {                                                \
+			ZSTR_U(data->key)      = BUCKET_UKEY(b);          \
+		}                                                     \
 		data->key_size   = b->nKeyLength;                     \
 	}                                                         \
Index: /trunk/xcache.h
===================================================================
--- /trunk/xcache.h	(revision 102)
+++ /trunk/xcache.h	(revision 103)
@@ -52,6 +52,6 @@
 				: 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(b)  (UNISW((b)->arKey, (b)->key.arKey.s))
+#define BUCKET_UKEY(b) (UNISW((b)->arKey, (b)->key.arKey.u))
 #define BUCKET_KEY_TYPE(b) (UNISW(0, (b)->key.type))
 #ifdef IS_UNICODE
@@ -64,11 +64,26 @@
 #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)
+#	define ZSTR_S(s)     (s)
+#	define ZSTR_U(s)     (s)
+#	define ZSTR_V(s)     (s)
+#	define ZSTR_PS(s)    (s)
+#	define ZSTR_PU(s)    (s)
+#	define ZSTR_PV(s)    (s)
+#else
+#	define ZSTR_S(zs)    ((zs).s)
+#	define ZSTR_U(zs)    ((zs).u)
+#	define ZSTR_V(zs)    ((zs).v)
+#	define ZSTR_PS(pzs)  ((pzs)->s)
+#	define ZSTR_PU(pzs)  ((pzs)->u)
+#	define ZSTR_PV(pzs)  ((pzs)->v)
+#endif
+
+#ifndef ZSTR
+#	define ZSTR(s)      (s)
+#endif
+
+#ifndef Z_UNIVAL
+#	define Z_UNIVAL(zval) (zval).value.str.val
+#	define Z_UNILEN(zval) (zval).value.str.len
 #endif
 
@@ -149,5 +164,5 @@
 	zend_uchar type;
 #endif
-	char *key;
+	zstr      key;
 	zend_uint key_size;
 	xc_cest_t cest;
@@ -160,5 +175,5 @@
 	zend_uchar type;
 #endif
-	char *key;
+	zstr      key;
 	zend_uint key_size;
 	zend_constant constant;
@@ -171,5 +186,5 @@
 	zend_uchar type;
 #endif
-	char *key;
+	zstr      key;
 	zend_uint key_size;
 	zend_function func;
