Index: /trunk/xcache.ini
===================================================================
--- /trunk/xcache.ini	(revision 979)
+++ /trunk/xcache.ini	(revision 1026)
@@ -1,14 +1,8 @@
 ;; this is an example, it won't work unless properly configured into php.ini
 [xcache-common]
-;; WARNING: zend_extension* = *xcache* MUST be the first(above) of all zend_extension*=*
-;; using extension=xcache.so is not recommended
-
-;; non-windows example
-;; update xxx accordingly
-zend_extension = /usr/local/lib/php/extensions/non-debug-non-zts-xxx/xcache.so
-;; windows example:
-zend_extension_ts = c:/php/extensions/php_xcache.dll
-;; for newer PHP, _ts is removed, use the following line instead
-zend_extension = c:/php/extensions/php_xcache.dll
+;; non-Windows example:
+extension = xcache.so
+;; Windows example:
+; extension = php_xcache.dll
 
 [xcache.admin]
Index: /trunk/mod_coverager/xc_coverager.h
===================================================================
--- /trunk/mod_coverager/xc_coverager.h	(revision 1003)
+++ /trunk/mod_coverager/xc_coverager.h	(revision 1026)
@@ -1,17 +1,12 @@
+#ifndef XC_COVERAGER_H_D5BB29AAB992B932E91C70A8C2F5D2B1
+#define XC_COVERAGER_H_D5BB29AAB992B932E91C70A8C2F5D2B1
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
 #include "php.h"
-#include "xcache.h"
 
-void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op);
-int xc_coverager_module_init(int module_number TSRMLS_DC);
-void xc_coverager_module_shutdown();
-void xc_coverager_request_init(TSRMLS_D);
-void xc_coverager_request_shutdown(TSRMLS_D);
-PHP_FUNCTION(xcache_coverager_decode);
-PHP_FUNCTION(xcache_coverager_start);
-PHP_FUNCTION(xcache_coverager_stop);
-PHP_FUNCTION(xcache_coverager_get);
-#define XCACHE_COVERAGER_FUNCTIONS() \
-	PHP_FE(xcache_coverager_decode,  NULL) \
-	PHP_FE(xcache_coverager_start,   NULL) \
-	PHP_FE(xcache_coverager_stop,    NULL) \
-	PHP_FE(xcache_coverager_get,     NULL)
+int xc_coverager_startup_module();
+
+#endif /* XC_COVERAGER_H_D5BB29AAB992B932E91C70A8C2F5D2B1 */
Index: /trunk/mod_coverager/xc_coverager.c
===================================================================
--- /trunk/mod_coverager/xc_coverager.c	(revision 1008)
+++ /trunk/mod_coverager/xc_coverager.c	(revision 1026)
@@ -2,4 +2,6 @@
 #define XCACHE_DEBUG
 #endif
+
+#include "xc_coverager.h"
 
 #include <stdio.h>
@@ -13,9 +15,12 @@
 #include <fcntl.h>
 
+#include "xcache/xc_extension.h"
+#include "xcache/xc_ini.h"
+#include "xcache/xc_utils.h"
 #include "util/xc_stack.h"
 #include "util/xc_trace.h"
 #include "xcache_globals.h"
-#include "xc_coverager.h"
-#include "xcache/xc_utils.h"
+
+#include "ext/standard/info.h"
 
 typedef HashTable *coverager_t;
@@ -34,5 +39,5 @@
 }
 /* }}} */
-void xcache_mkdirs_ex(char *root, int rootlen, char *path, int pathlen TSRMLS_DC) /* {{{ */
+static void xcache_mkdirs_ex(char *root, int rootlen, char *path, int pathlen TSRMLS_DC) /* {{{ */
 {
 	char *fullpath;
@@ -248,5 +253,5 @@
 /* }}} */
 
-void xc_coverager_request_init(TSRMLS_D) /* {{{ */
+static PHP_RINIT_FUNCTION(xcache_coverager) /* {{{ */
 {
 	if (XG(coverager)) {
@@ -261,4 +266,5 @@
 		XG(coverage_enabled) = 0;
 	}
+	return SUCCESS;
 }
 /* }}} */
@@ -335,5 +341,5 @@
 }
 /* }}} */
-void xc_coverager_request_shutdown(TSRMLS_D) /* {{{ */
+static PHP_RSHUTDOWN_FUNCTION(xcache_coverager) /* {{{ */
 {
 	if (XG(coverager)) {
@@ -341,4 +347,5 @@
 		xc_coverager_cleanup(TSRMLS_C);
 	}
+	return SUCCESS;
 }
 /* }}} */
@@ -457,5 +464,5 @@
 
 /* hits */
-void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op) /* {{{ */
+static void xc_coverager_handle_ext_stmt(zend_op_array *op_array, zend_uchar op) /* {{{ */
 {
 	TSRMLS_FETCH();
@@ -471,9 +478,180 @@
 /* }}} */
 
-/* MINIT/MSHUTDOWN */
-int xc_coverager_module_init(int module_number TSRMLS_DC) /* {{{ */
+/* user api */
+/* {{{ proto array xcache_coverager_decode(string data)
+ * decode specified data which is saved by auto dumper to array
+ */
+PHP_FUNCTION(xcache_coverager_decode)
+{
+	char *str;
+	int len;
+	long *p;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) {
+		return;
+	}
+
+	array_init(return_value);
+
+	p = (long*) str;
+	len -= sizeof(long);
+	if (len < 0) {
+		return;
+	}
+	if (*p++ != PCOV_HEADER_MAGIC) {
+		TRACE("%s", "wrong magic in xcache_coverager_decode");
+		return;
+	}
+
+	for (; len >= (int) sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
+		add_index_long(return_value, p[0], p[1] < 0 ? 0 : p[1]);
+	}
+}
+/* }}} */
+/* {{{ proto void xcache_coverager_start([bool clean = true])
+ * starts coverager data collecting
+ */
+PHP_FUNCTION(xcache_coverager_start)
+{
+	zend_bool clean = 1;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
+		return;
+	}
+
+	if (clean) {
+		xc_coverager_clean(TSRMLS_C);
+	}
+
+	if (XG(coverager)) {
+		xc_coverager_enable(TSRMLS_C);
+	}
+	else {
+		php_error(E_WARNING, "You can only start coverager after you set 'xcache.coverager' to 'On' in ini");
+	}
+}
+/* }}} */
+/* {{{ proto void xcache_coverager_stop([bool clean = false])
+ * stop coverager data collecting
+ */
+PHP_FUNCTION(xcache_coverager_stop)
+{
+	zend_bool clean = 0;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
+		return;
+	}
+
+	xc_coverager_disable(TSRMLS_C);
+	if (clean) {
+		xc_coverager_clean(TSRMLS_C);
+	}
+}
+/* }}} */
+/* {{{ proto array xcache_coverager_get([bool clean = false])
+ * get coverager data collected
+ */
+PHP_FUNCTION(xcache_coverager_get)
+{
+	zend_bool clean = 0;
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
+		return;
+	}
+
+	xc_coverager_dump(return_value TSRMLS_CC);
+	if (clean) {
+		xc_coverager_clean(TSRMLS_C);
+	}
+}
+/* }}} */
+static zend_function_entry xcache_coverager_functions[] = /* {{{ */
+{
+	PHP_FE(xcache_coverager_decode,  NULL)
+	PHP_FE(xcache_coverager_start,   NULL)
+	PHP_FE(xcache_coverager_stop,    NULL)
+	PHP_FE(xcache_coverager_get,     NULL)
+	PHP_FE_END
+};
+/* }}} */
+
+static int xc_zend_startup(zend_extension *extension) /* {{{ */
+{
+	return SUCCESS;
+}
+/* }}} */
+static void xc_zend_shutdown(zend_extension *extension) /* {{{ */
+{
+	/* empty */
+}
+/* }}} */
+static void xc_statement_handler(zend_op_array *op_array) /* {{{ */
+{
+#ifdef HAVE_XCACHE_COVERAGER
+	xc_coverager_handle_ext_stmt(op_array, ZEND_EXT_STMT);
+#endif
+}
+/* }}} */
+static void xc_fcall_begin_handler(zend_op_array *op_array) /* {{{ */
+{
+#if 0
+	xc_coverager_handle_ext_stmt(op_array, ZEND_EXT_FCALL_BEGIN);
+#endif
+}
+/* }}} */
+static void xc_fcall_end_handler(zend_op_array *op_array) /* {{{ */
+{
+#if 0
+	xc_coverager_handle_ext_stmt(op_array, ZEND_EXT_FCALL_END);
+#endif
+}
+/* }}} */
+/* {{{ zend extension definition structure */
+static zend_extension xc_coverager_zend_extension_entry = {
+	XCACHE_NAME " Coverager",
+	XCACHE_VERSION,
+	XCACHE_AUTHOR,
+	XCACHE_URL,
+	XCACHE_COPYRIGHT,
+	xc_zend_startup,
+	xc_zend_shutdown,
+	NULL,           /* activate_func_t */
+	NULL,           /* deactivate_func_t */
+	NULL,           /* message_handler_func_t */
+	NULL,           /* statement_handler_func_t */
+	xc_statement_handler,
+	xc_fcall_begin_handler,
+	xc_fcall_end_handler,
+	NULL,           /* op_array_ctor_func_t */
+	NULL,           /* op_array_dtor_func_t */
+	STANDARD_ZEND_EXTENSION_PROPERTIES
+};
+/* }}} */
+/* {{{ PHP_INI */
+PHP_INI_BEGIN()
+	STD_PHP_INI_BOOLEAN("xcache.coverager"      ,        "0", PHP_INI_ALL,    OnUpdateBool,         coverager,         zend_xcache_globals, xcache_globals)
+	PHP_INI_ENTRY1     ("xcache.coveragedump_directory",  "", PHP_INI_SYSTEM, xcache_OnUpdateDummy, NULL)
+PHP_INI_END()
+/* }}} */
+static PHP_MINFO_FUNCTION(xcache_coverager) /* {{{ */
+{
+	char *covdumpdir;
+
+	php_info_print_table_start();
+	php_info_print_table_row(2, "XCache Coverager Version", XCACHE_VERSION);
+	if (cfg_get_string("xcache.coveragedump_directory", &covdumpdir) != SUCCESS || !covdumpdir[0]) {
+		covdumpdir = NULL;
+	}
+	php_info_print_table_row(2, "Coverage Auto Dumper", XG(coverager) && covdumpdir ? "enabled" : "disabled");
+	php_info_print_table_end();
+
+	DISPLAY_INI_ENTRIES();
+}
+/* }}} */
+static PHP_MINIT_FUNCTION(xcache_coverager) /* {{{ */
 {
 	old_compile_file = zend_compile_file;
 	zend_compile_file = xc_compile_file_for_coverage;
+
+	REGISTER_INI_ENTRIES();
 
 	if (cfg_get_string("xcache.coveragedump_directory", &xc_coveragedump_dir) == SUCCESS && xc_coveragedump_dir) {
@@ -492,8 +670,8 @@
 	}
 
-	return SUCCESS;
-}
-/* }}} */
-void xc_coverager_module_shutdown() /* {{{ */
+	return xcache_zend_extension_register(&xc_coverager_zend_extension_entry, 0);
+}
+/* }}} */
+static PHP_MSHUTDOWN_FUNCTION(xcache_coverager) /* {{{ */
 {
 	if (old_compile_file == xc_compile_file_for_coverage) {
@@ -504,92 +682,34 @@
 		xc_coveragedump_dir = NULL;
 	}
-}
-/* }}} */
-
-/* user api */
-/* {{{ proto array xcache_coverager_decode(string data)
- * decode specified data which is saved by auto dumper to array
- */
-PHP_FUNCTION(xcache_coverager_decode)
-{
-	char *str;
-	int len;
-	long *p;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &len) == FAILURE) {
-		return;
-	}
-
-	array_init(return_value);
-
-	p = (long*) str;
-	len -= sizeof(long);
-	if (len < 0) {
-		return;
-	}
-	if (*p++ != PCOV_HEADER_MAGIC) {
-		TRACE("%s", "wrong magic in xcache_coverager_decode");
-		return;
-	}
-
-	for (; len >= (int) sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
-		add_index_long(return_value, p[0], p[1] < 0 ? 0 : p[1]);
-	}
-}
-/* }}} */
-/* {{{ proto void xcache_coverager_start([bool clean = true])
- * starts coverager data collecting
- */
-PHP_FUNCTION(xcache_coverager_start)
-{
-	zend_bool clean = 1;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
-		return;
-	}
-
-	if (clean) {
-		xc_coverager_clean(TSRMLS_C);
-	}
-
-	if (XG(coverager)) {
-		xc_coverager_enable(TSRMLS_C);
-	}
-	else {
-		php_error(E_WARNING, "You can only start coverager after you set 'xcache.coverager' to 'On' in ini");
-	}
-}
-/* }}} */
-/* {{{ proto void xcache_coverager_stop([bool clean = false])
- * stop coverager data collecting
- */
-PHP_FUNCTION(xcache_coverager_stop)
-{
-	zend_bool clean = 0;
-
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
-		return;
-	}
-
-	xc_coverager_disable(TSRMLS_C);
-	if (clean) {
-		xc_coverager_clean(TSRMLS_C);
-	}
-}
-/* }}} */
-/* {{{ proto array xcache_coverager_get([bool clean = false])
- * get coverager data collected
- */
-PHP_FUNCTION(xcache_coverager_get)
-{
-	zend_bool clean = 0;
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &clean) == FAILURE) {
-		return;
-	}
-
-	xc_coverager_dump(return_value TSRMLS_CC);
-	if (clean) {
-		xc_coverager_clean(TSRMLS_C);
-	}
-}
-/* }}} */
+	UNREGISTER_INI_ENTRIES();
+	return xcache_zend_extension_unregister(&xc_coverager_zend_extension_entry);
+}
+/* }}} */
+
+static zend_module_entry xcache_coverager_module_entry = { /* {{{ */
+	STANDARD_MODULE_HEADER,
+	XCACHE_NAME "_Coverager",
+	xcache_coverager_functions,
+	PHP_MINIT(xcache_coverager),
+	PHP_MSHUTDOWN(xcache_coverager),
+	PHP_RINIT(xcache_coverager),
+	PHP_RSHUTDOWN(xcache_coverager),
+	PHP_MINFO(xcache_coverager),
+	XCACHE_VERSION,
+#ifdef PHP_GINIT
+	NO_MODULE_GLOBALS,
+#endif
+#ifdef ZEND_ENGINE_2
+	NULL,
+#else
+	NULL,
+	NULL,
+#endif
+	STANDARD_MODULE_PROPERTIES_EX
+};
+/* }}} */
+int xc_coverager_startup_module() /* {{{ */
+{
+	return zend_startup_module(&xcache_coverager_module_entry);
+}
+/* }}} */
Index: /trunk/mod_disassembler/xc_disassembler.h
===================================================================
--- /trunk/mod_disassembler/xc_disassembler.h	(revision 1003)
+++ /trunk/mod_disassembler/xc_disassembler.h	(revision 1026)
@@ -1,7 +1,10 @@
-#include "php.h"
+#ifndef XC_DISASSEMBLER_H_1547840703D7ADD9C19041818BE9E3C7
+#define XC_DISASSEMBLER_H_1547840703D7ADD9C19041818BE9E3C7
 
-PHP_FUNCTION(xcache_dasm_file);
-PHP_FUNCTION(xcache_dasm_string);
-#define XCACHE_DISASSEMBLER_FUNCTIONS() \
-	PHP_FE(xcache_dasm_file,         NULL) \
-	PHP_FE(xcache_dasm_string,       NULL)
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+int xc_disassembler_startup_module();
+
+#endif /* XC_DISASSEMBLER_H_1547840703D7ADD9C19041818BE9E3C7 */
Index: /trunk/mod_disassembler/xc_disassembler.c
===================================================================
--- /trunk/mod_disassembler/xc_disassembler.c	(revision 1003)
+++ /trunk/mod_disassembler/xc_disassembler.c	(revision 1026)
@@ -3,5 +3,8 @@
 #include "xcache/xc_utils.h"
 #include "xcache/xc_sandbox.h"
+#include "xcache/xc_compatibility.h"
 #include "xc_processor.h"
+
+#include "ext/standard/info.h"
 
 static void xc_dasm(zval *output, zend_op_array *op_array TSRMLS_DC) /* {{{ */
@@ -216,2 +219,47 @@
 }
 /* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION(xcache_disassembler) */
+static PHP_MINFO_FUNCTION(xcache_disassembler)
+{
+	php_info_print_table_start();
+	php_info_print_table_row(2, "XCache Disassembler Version", XCACHE_VERSION);
+	php_info_print_table_end();
+
+	DISPLAY_INI_ENTRIES();
+}
+/* }}} */
+static zend_function_entry xcache_disassembler_functions[] = /* {{{ */
+{
+	PHP_FE(xcache_dasm_file,         NULL)
+	PHP_FE(xcache_dasm_string,       NULL)
+	PHP_FE_END
+};
+/* }}} */
+static zend_module_entry xcache_disassembler_module_entry = { /* {{{ */
+	STANDARD_MODULE_HEADER,
+	XCACHE_NAME "_Disassembler",
+	xcache_disassembler_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	PHP_MINFO(xcache_disassembler),
+	XCACHE_VERSION,
+#ifdef PHP_GINIT
+	NO_MODULE_GLOBALS,
+#endif
+#ifdef ZEND_ENGINE_2
+	NULL,
+#else
+	NULL,
+	NULL,
+#endif
+	STANDARD_MODULE_PROPERTIES_EX
+};
+/* }}} */
+int xc_disassembler_startup_module() /* {{{ */
+{
+	return zend_startup_module(&xcache_disassembler_module_entry);
+}
+/* }}} */
Index: /trunk/mod_optimizer/xc_optimizer.h
===================================================================
--- /trunk/mod_optimizer/xc_optimizer.h	(revision 1003)
+++ /trunk/mod_optimizer/xc_optimizer.h	(revision 1026)
@@ -1,5 +1,12 @@
+#ifndef XC_OPTIMIZER_H_6614228F428A266C39CDAC30269D9857
+#define XC_OPTIMIZER_H_6614228F428A266C39CDAC30269D9857
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
 #include "php.h"
-#include "xcache.h"
 
-void xc_optimizer_op_array_handler(zend_op_array *op_array);
-#define XCACHE_OPTIMIZER_FUNCTIONS()
+int xc_optimizer_startup_module();
+
+#endif /* XC_OPTIMIZER_H_6614228F428A266C39CDAC30269D9857 */
Index: /trunk/mod_optimizer/xc_optimizer.c
===================================================================
--- /trunk/mod_optimizer/xc_optimizer.c	(revision 1008)
+++ /trunk/mod_optimizer/xc_optimizer.c	(revision 1026)
@@ -3,10 +3,13 @@
 #endif
 
+#include "xc_optimizer.h"
+#include "xcache/xc_extension.h"
+#include "xcache/xc_ini.h"
 #include "xcache/xc_utils.h"
-#include "xc_optimizer.h"
-/* the "vector" stack */
 #include "util/xc_stack.h"
 #include "util/xc_trace.h"
 #include "xcache_globals.h"
+
+#include "ext/standard/info.h"
 
 #ifdef XCACHE_DEBUG
@@ -607,5 +610,5 @@
 }
 /* }}} */
-void xc_optimizer_op_array_handler(zend_op_array *op_array) /* {{{ */
+static void xc_optimizer_op_array_handler(zend_op_array *op_array) /* {{{ */
 {
 	TSRMLS_FETCH();
@@ -615,2 +618,87 @@
 }
 /* }}} */
+
+static int xc_zend_startup(zend_extension *extension) /* {{{ */
+{
+	return SUCCESS;
+}
+/* }}} */
+static void xc_zend_shutdown(zend_extension *extension) /* {{{ */
+{
+}
+/* }}} */
+/* {{{ zend extension definition structure */
+static zend_extension xc_optimizer_zend_extension_entry = {
+	XCACHE_NAME " Optimizer",
+	XCACHE_VERSION,
+	XCACHE_AUTHOR,
+	XCACHE_URL,
+	XCACHE_COPYRIGHT,
+	xc_zend_startup,
+	xc_zend_shutdown,
+	NULL,           /* activate_func_t */
+	NULL,           /* deactivate_func_t */
+	NULL,           /* message_handler_func_t */
+	xc_optimizer_op_array_handler,
+	NULL,           /* statement_handler_func_t */
+	NULL,           /* fcall_begin_handler_func_t */
+	NULL,           /* fcall_end_handler_func_t */
+	NULL,           /* op_array_ctor_func_t */
+	NULL,           /* op_array_dtor_func_t */
+	STANDARD_ZEND_EXTENSION_PROPERTIES
+};
+/* }}} */
+
+/* {{{ ini */
+PHP_INI_BEGIN()
+	STD_PHP_INI_BOOLEAN("xcache.optimizer",              "0", PHP_INI_ALL,    OnUpdateBool,        optimizer,         zend_xcache_globals, xcache_globals)
+PHP_INI_END()
+/* }}} */
+static PHP_MINFO_FUNCTION(xcache_optimizer) /* {{{ */
+{
+	php_info_print_table_start();
+	php_info_print_table_row(2, "XCache Optimizer Version", XCACHE_VERSION);
+	php_info_print_table_end();
+
+	DISPLAY_INI_ENTRIES();
+}
+/* }}} */
+static PHP_MINIT_FUNCTION(xcache_optimizer) /* {{{ */
+{
+	REGISTER_INI_ENTRIES();
+	return xcache_zend_extension_register(&xc_optimizer_zend_extension_entry, 0);
+}
+/* }}} */
+static PHP_MSHUTDOWN_FUNCTION(xcache_optimizer) /* {{{ */
+{
+	UNREGISTER_INI_ENTRIES();
+	return xcache_zend_extension_unregister(&xc_optimizer_zend_extension_entry);
+}
+/* }}} */
+static zend_module_entry xcache_optimizer_module_entry = { /* {{{ */
+	STANDARD_MODULE_HEADER,
+	XCACHE_NAME "_Optimizer",
+	NULL,
+	PHP_MINIT(xcache_optimizer),
+	PHP_MSHUTDOWN(xcache_optimizer),
+	NULL,
+	NULL,
+	PHP_MINFO(xcache_optimizer),
+	XCACHE_VERSION,
+#ifdef PHP_GINIT
+	NO_MODULE_GLOBALS,
+#endif
+#ifdef ZEND_ENGINE_2
+	NULL,
+#else
+	NULL,
+	NULL,
+#endif
+	STANDARD_MODULE_PROPERTIES_EX
+};
+/* }}} */
+int xc_optimizer_startup_module() /* {{{ */
+{
+	return zend_startup_module(&xcache_optimizer_module_entry);
+}
+/* }}} */
Index: /trunk/config.m4
===================================================================
--- /trunk/config.m4	(revision 1011)
+++ /trunk/config.m4	(revision 1026)
@@ -32,6 +32,8 @@
 done
   for i in \
+xc_compatibility.c \
 xc_const_string.c \
-xc_compatibility.c \
+xc_extension.c \
+xc_ini.c \
 xc_lock.c \
 xc_mem.c \
Index: /trunk/mod_cacher/htdocs/xcache.php
===================================================================
--- /trunk/mod_cacher/htdocs/xcache.php	(revision 976)
+++ /trunk/mod_cacher/htdocs/xcache.php	(revision 1026)
@@ -355,6 +355,6 @@
 	phpinfo(INFO_MODULES);
 	$moduleinfo = ob_get_clean();
-	if (preg_match('!XCache</a></h2>(.*?)<h2>!is', $moduleinfo, $m)) {
-		$moduleinfo = $m[1];
+	if (preg_match_all('!XCache[^<]*</a></h2>(.*?)<h2>!is', $moduleinfo, $m)) {
+		$moduleinfo = implode('', $m[1]);
 	}
 	else {
Index: /trunk/ChangeLog
===================================================================
--- /trunk/ChangeLog	(revision 979)
+++ /trunk/ChangeLog	(revision 1026)
@@ -14,4 +14,5 @@
  * closes #73: warn for improper PHP_FCGI_CHILDREN setting fcgi mode (>=PHP_5_3)
  * closes #174: updated api for clear all cache
+ * uses extension to load XCache. load via zend_extension is unsupported
 
 2.0.1 2012-07-14
Index: /trunk/xcache/xc_compatibility.h
===================================================================
--- /trunk/xcache/xc_compatibility.h	(revision 991)
+++ /trunk/xcache/xc_compatibility.h	(revision 1026)
@@ -228,3 +228,11 @@
 #endif
 
+#ifndef ZEND_MOD_END
+#	define ZEND_MOD_END {NULL, NULL, NULL, 0}
+#endif
+
+#ifndef PHP_FE_END
+#	define PHP_FE_END {NULL, NULL, NULL}
+#endif
+
 #endif /* XC_COMPATIBILITY_H_54F26ED90198353558718191D5EE244C */
Index: /trunk/xcache/xc_ini.c
===================================================================
--- /trunk/xcache/xc_ini.c	(revision 1026)
+++ /trunk/xcache/xc_ini.c	(revision 1026)
@@ -0,0 +1,38 @@
+#include "xc_ini.h"
+
+PHP_INI_MH(xcache_OnUpdateDummy)
+{
+	return SUCCESS;
+}
+
+PHP_INI_MH(xcache_OnUpdateULong)
+{
+	zend_ulong *p = (zend_ulong *) mh_arg1;
+
+	*p = (zend_ulong) atoi(new_value);
+	return SUCCESS;
+}
+
+PHP_INI_MH(xcache_OnUpdateBool)
+{
+	zend_bool *p = (zend_bool *)mh_arg1;
+
+	if (strncasecmp("on", new_value, sizeof("on"))) {
+		*p = (zend_bool) atoi(new_value);
+	}
+	else {
+		*p = (zend_bool) 1;
+	}
+	return SUCCESS;
+}
+
+PHP_INI_MH(xcache_OnUpdateString)
+{
+	char **p = (char**)mh_arg1;
+	if (*p) {
+		pefree(*p, 1);
+	}
+	*p = pemalloc(strlen(new_value) + 1, 1);
+	strcpy(*p, new_value);
+	return SUCCESS;
+}
Index: /trunk/xcache/xc_extension.h
===================================================================
--- /trunk/xcache/xc_extension.h	(revision 1026)
+++ /trunk/xcache/xc_extension.h	(revision 1026)
@@ -0,0 +1,16 @@
+#ifndef XC_EXTENSION_H_9885D3A6DE7C469D13E34AF331E02BB8
+#define XC_EXTENSION_H_9885D3A6DE7C469D13E34AF331E02BB8
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "zend_extensions.h"
+int xcache_zend_extension_register(zend_extension *new_extension, zend_bool prepend);
+int xcache_zend_extension_unregister(zend_extension *extension);
+
+zend_llist_element *xcache_llist_get_element_by_zend_extension(zend_llist *l, const char *extension_name);
+void xcache_llist_prepend(zend_llist *l, zend_llist_element *element);
+void xcache_llist_unlink(zend_llist *l, zend_llist_element *element);
+
+#endif /* XC_EXTENSION_H_9885D3A6DE7C469D13E34AF331E02BB8 */
Index: /trunk/xcache/xc_ini.h
===================================================================
--- /trunk/xcache/xc_ini.h	(revision 1026)
+++ /trunk/xcache/xc_ini.h	(revision 1026)
@@ -0,0 +1,19 @@
+#ifndef XC_INI_H_E208B8E597E7FAD950D249BE9C6B6F53
+#define XC_INI_H_E208B8E597E7FAD950D249BE9C6B6F53
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "php.h"
+#include "php_ini.h"
+
+PHP_INI_MH(xcache_OnUpdateDummy);
+PHP_INI_MH(xcache_OnUpdateULong);
+PHP_INI_MH(xcache_OnUpdateBool);
+PHP_INI_MH(xcache_OnUpdateString);
+#ifndef ZEND_ENGINE_2
+#define OnUpdateLong OnUpdateInt
+#endif
+
+#endif /* XC_INI_H_E208B8E597E7FAD950D249BE9C6B6F53 */
Index: /trunk/xcache/xc_sandbox.h
===================================================================
--- /trunk/xcache/xc_sandbox.h	(revision 1018)
+++ /trunk/xcache/xc_sandbox.h	(revision 1026)
@@ -9,6 +9,5 @@
  */
 
-#include "xcache.h"
-#include "xcache/xc_compatibility.h"
+#include "xc_compatibility.h"
 
 int xc_sandbox_module_init(int module_number TSRMLS_DC);
Index: /trunk/xcache/xc_extension.c
===================================================================
--- /trunk/xcache/xc_extension.c	(revision 1026)
+++ /trunk/xcache/xc_extension.c	(revision 1026)
@@ -0,0 +1,104 @@
+
+#include "xc_extension.h"
+#include "xcache.h"
+#include "util/xc_trace.h"
+
+
+int xcache_zend_extension_register(zend_extension *new_extension, zend_bool prepend) /* {{{ */
+{
+	zend_extension extension;
+
+	extension = *new_extension;
+	extension.handle = 0;
+
+	zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension);
+
+	if (prepend) {
+		zend_llist_prepend_element(&zend_extensions, &extension);
+	}
+	else {
+		zend_llist_add_element(&zend_extensions, &extension);
+	}
+	TRACE("%s", "registered");
+	return SUCCESS;
+}
+/* }}} */
+static int xc_ptr_compare_func(void *p1, void *p2) /* {{{ */
+{
+	return p1 == p2;
+}
+/* }}} */
+static int xc_zend_extension_remove(zend_extension *extension) /* {{{ */
+{
+	llist_dtor_func_t dtor;
+
+	assert(extension);
+	dtor = zend_extensions.dtor; /* avoid dtor */
+	zend_extensions.dtor = NULL;
+	zend_llist_del_element(&zend_extensions, extension, xc_ptr_compare_func);
+	zend_extensions.dtor = dtor;
+	return SUCCESS;
+}
+/* }}} */
+int xcache_zend_extension_unregister(zend_extension *extension) /* {{{ */
+{
+	zend_extension *ext = zend_get_extension(extension->name);
+	if (!ext) {
+		return FAILURE;
+	}
+
+	if (ext->shutdown) {
+		ext->shutdown(ext);
+	}
+	xc_zend_extension_remove(ext);
+	return SUCCESS;
+}
+/* }}} */
+
+zend_llist_element *xcache_llist_get_element_by_zend_extension(zend_llist *l, const char *extension_name) /* {{{ */
+{
+	zend_llist_element *element;
+
+	for (element = zend_extensions.head; element; element = element->next) {
+		zend_extension *extension = (zend_extension *) element->data;
+
+		if (!strcmp(extension->name, extension_name)) {
+			return element;
+		}
+	}
+	return NULL;
+}
+/* }}} */
+void xcache_llist_prepend(zend_llist *l, zend_llist_element *element) /* {{{ */
+{
+	element->next = l->head;
+	element->prev = NULL;
+	if (l->head) {
+		l->head->prev = element;
+	}
+	else {
+		l->tail = element;
+	}
+	l->head = element;
+	++l->count;
+}
+/* }}} */
+void xcache_llist_unlink(zend_llist *l, zend_llist_element *element) /* {{{ */
+{
+	if ((element)->prev) {
+		(element)->prev->next = (element)->next;
+	}
+	else {
+		(l)->head = (element)->next;
+	}
+
+	if ((element)->next) {
+		(element)->next->prev = (element)->prev;
+	}
+	else {
+		(l)->tail = (element)->prev;
+	}
+
+	--l->count;
+}
+/* }}} */
Index: /trunk/NEWS
===================================================================
--- /trunk/NEWS	(revision 979)
+++ /trunk/NEWS	(revision 1026)
@@ -4,4 +4,5 @@
  * adds warning for misconfiguration
  * auto disable caching on crash
+ * uses extension to load XCache. load via zend_extension is unsupported
 
 2.0.1 2012-07-14
Index: /trunk/xcache.c
===================================================================
--- /trunk/xcache.c	(revision 1003)
+++ /trunk/xcache.c	(revision 1026)
@@ -15,12 +15,4 @@
 #include <signal.h>
 
-#include "php.h"
-#include "ext/standard/info.h"
-#include "ext/standard/md5.h"
-#include "ext/standard/php_math.h"
-#include "ext/standard/php_string.h"
-#include "zend_extensions.h"
-#include "SAPI.h"
-
 #include "xcache.h"
 #ifdef ZEND_ENGINE_2_1
@@ -30,20 +22,16 @@
 #ifdef HAVE_XCACHE_OPTIMIZER
 #	include "mod_optimizer/xc_optimizer.h"
-#else
-#	define XCACHE_OPTIMIZER_FUNCTIONS()
 #endif
 #ifdef HAVE_XCACHE_COVERAGER
 #	include "mod_coverager/xc_coverager.h"
-#else
-#	define XCACHE_COVERAGER_FUNCTIONS()
 #endif
 #ifdef HAVE_XCACHE_DISASSEMBLER
 #	include "mod_disassembler/xc_disassembler.h"
-#else
-#	define XCACHE_DISASSEMBLER_FUNCTIONS()
 #endif
 
 #include "xcache_globals.h"
 #include "xc_processor.h"
+#include "xcache/xc_extension.h"
+#include "xcache/xc_ini.h"
 #include "xcache/xc_const_string.h"
 #include "xcache/xc_opcode_spec.h"
@@ -54,4 +42,11 @@
 #include "util/xc_vector.h"
 #include "util/xc_trace.h"
+
+#include "php.h"
+#include "ext/standard/info.h"
+#include "ext/standard/md5.h"
+#include "ext/standard/php_math.h"
+#include "ext/standard/php_string.h"
+#include "SAPI.h"
 
 #define VAR_ENTRY_EXPIRED(pentry) ((pentry)->ttl && XG(request_time) > (pentry)->ctime + (time_t) (pentry)->ttl)
@@ -124,11 +119,4 @@
 zend_bool xc_have_op_array_ctor = 0;
 
-static zend_bool xc_module_gotup = 0;
-static zend_bool xc_zend_extension_gotup = 0;
-static zend_bool xc_zend_extension_faked = 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)
 
@@ -2527,8 +2515,4 @@
 	XG(request_time) = sapi_get_request_time(TSRMLS_C);
 #endif
-
-#ifdef HAVE_XCACHE_COVERAGER
-	xc_coverager_request_init(TSRMLS_C);
-#endif
 }
 /* }}} */
@@ -2543,7 +2527,4 @@
 #ifdef ZEND_ENGINE_2
 	zend_llist_destroy(&XG(gc_op_arrays));
-#endif
-#ifdef HAVE_XCACHE_COVERAGER
-	xc_coverager_request_shutdown(TSRMLS_C);
 #endif
 }
@@ -3359,9 +3340,7 @@
 	PHP_FE(xcache_clear_cache,       NULL)
 	PHP_FE(xcache_coredump,          NULL)
-	XCACHE_OPTIMIZER_FUNCTIONS()
 #ifdef HAVE_XCACHE_ASSEMBLER
 	PHP_FE(xcache_asm,               NULL)
 #endif
-	XCACHE_DISASSEMBLER_FUNCTIONS()
 #ifdef HAVE_XCACHE_ENCODER
 	PHP_FE(xcache_encode,            NULL)
@@ -3371,5 +3350,4 @@
 	PHP_FE(xcache_decode_string,     NULL)
 #endif
-	XCACHE_COVERAGER_FUNCTIONS()
 	PHP_FE(xcache_get_special_value, NULL)
 	PHP_FE(xcache_get_type,          NULL)
@@ -3391,9 +3369,5 @@
 	PHP_FE(xcache_dprint,            NULL)
 #endif
-#ifdef PHP_FE_END
 	PHP_FE_END
-#else
-	{NULL, NULL,                     NULL}
-#endif
 };
 /* }}} */
@@ -3547,47 +3521,76 @@
 #endif
 
+static startup_func_t xc_last_ext_startup;
+static int xc_zend_startup_last(zend_extension *extension) /* {{{ */
+{
+	zend_extension *ext = zend_get_extension(XCACHE_NAME);
+	if (ext) {
+		zend_error(E_WARNING, "Module '" XCACHE_NAME "' already loaded");
+	}
+	/* restore */
+	extension->startup = xc_last_ext_startup;
+	if (extension->startup) {
+		if (extension->startup(extension) != SUCCESS) {
+			return FAILURE;
+		}
+	}
+	assert(xc_llist_zend_extension);
+	xcache_llist_prepend(&zend_extensions, xc_llist_zend_extension);
+	return SUCCESS;
+}
+/* }}} */
+static int xc_zend_startup(zend_extension *extension) /* {{{ */
+{
+	if (!origin_compile_file) {
+		origin_compile_file = zend_compile_file;
+		zend_compile_file = xc_check_initial_compile_file;
+	}
+
+	if (zend_llist_count(&zend_extensions) > 1) {
+		zend_llist_position lpos;
+		zend_extension *ext;
+
+		xc_llist_zend_extension = xcache_llist_get_element_by_zend_extension(&zend_extensions, XCACHE_NAME);
+		if (xc_llist_zend_extension != zend_extensions.head) {
+			zend_error(E_WARNING, "XCache failed to load itself as the first zend_extension. compatibility downgraded");
+		}
+		/* hide myself */
+		xcache_llist_unlink(&zend_extensions, xc_llist_zend_extension);
+
+		ext = (zend_extension *) zend_llist_get_last_ex(&zend_extensions, &lpos);
+		assert(ext && ext != (zend_extension *) xc_llist_zend_extension->data);
+		xc_last_ext_startup = ext->startup;
+		ext->startup = xc_zend_startup_last;
+	}
+	return SUCCESS;
+}
+/* }}} */
+static void xc_zend_shutdown(zend_extension *extension) /* {{{ */
+{
+}
+/* }}} */
+/* {{{ zend extension definition structure */
+static zend_extension zend_extension_entry = {
+	XCACHE_NAME,
+	XCACHE_VERSION,
+	XCACHE_AUTHOR,
+	XCACHE_URL,
+	XCACHE_COPYRIGHT,
+	xc_zend_startup,
+	xc_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 */
+	NULL,           /* op_array_ctor_func_t */
+	NULL,           /* op_array_dtor_func_t */
+	STANDARD_ZEND_EXTENSION_PROPERTIES
+};
+/* }}} */
+
 /* {{{ PHP_INI */
-
-static PHP_INI_MH(xc_OnUpdateDummy)
-{
-	return SUCCESS;
-}
-
-static PHP_INI_MH(xc_OnUpdateULong)
-{
-	zend_ulong *p = (zend_ulong *) mh_arg1;
-
-	*p = (zend_ulong) atoi(new_value);
-	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 {
-		*p = (zend_bool) 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;
-}
-
-#ifndef ZEND_ENGINE_2
-#define OnUpdateLong OnUpdateInt
-#endif
-
 #ifdef ZEND_WIN32
 #	define DEFAULT_PATH "xcache"
@@ -3596,22 +3599,22 @@
 #endif
 PHP_INI_BEGIN()
-	PHP_INI_ENTRY1     ("xcache.mmap_path",     DEFAULT_PATH, 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.disable_on_crash",       "0", PHP_INI_SYSTEM, xc_OnUpdateBool,     &xc_disable_on_crash)
-	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)
+	PHP_INI_ENTRY1     ("xcache.mmap_path",     DEFAULT_PATH, PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_mmap_path)
+	PHP_INI_ENTRY1     ("xcache.coredump_directory",      "", PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_coredump_dir)
+	PHP_INI_ENTRY1     ("xcache.disable_on_crash",       "0", PHP_INI_SYSTEM, xcache_OnUpdateBool,     &xc_disable_on_crash)
+	PHP_INI_ENTRY1     ("xcache.test",                   "0", PHP_INI_SYSTEM, xcache_OnUpdateBool,     &xc_test)
+	PHP_INI_ENTRY1     ("xcache.readonly_protection",    "0", PHP_INI_SYSTEM, xcache_OnUpdateBool,     &xc_readonly_protection)
 	/* opcode cache */
-	PHP_INI_ENTRY1     ("xcache.size",                   "0", PHP_INI_SYSTEM, xc_OnUpdateDummy,    NULL)
-	PHP_INI_ENTRY1     ("xcache.count",                  "1", PHP_INI_SYSTEM, xc_OnUpdateDummy,    NULL)
-	PHP_INI_ENTRY1     ("xcache.slots",                 "8K", PHP_INI_SYSTEM, xc_OnUpdateDummy,    NULL)
-	PHP_INI_ENTRY1     ("xcache.shm_scheme",          "mmap", PHP_INI_SYSTEM, xc_OnUpdateString,   &xc_shm_scheme)
-	PHP_INI_ENTRY1     ("xcache.ttl",                    "0", PHP_INI_SYSTEM, xc_OnUpdateULong,    &xc_php_ttl)
-	PHP_INI_ENTRY1     ("xcache.gc_interval",            "0", PHP_INI_SYSTEM, xc_OnUpdateULong,    &xc_php_gc_interval)
+	PHP_INI_ENTRY1     ("xcache.size",                   "0", PHP_INI_SYSTEM, xcache_OnUpdateDummy,    NULL)
+	PHP_INI_ENTRY1     ("xcache.count",                  "1", PHP_INI_SYSTEM, xcache_OnUpdateDummy,    NULL)
+	PHP_INI_ENTRY1     ("xcache.slots",                 "8K", PHP_INI_SYSTEM, xcache_OnUpdateDummy,    NULL)
+	PHP_INI_ENTRY1     ("xcache.shm_scheme",          "mmap", PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_shm_scheme)
+	PHP_INI_ENTRY1     ("xcache.ttl",                    "0", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_php_ttl)
+	PHP_INI_ENTRY1     ("xcache.gc_interval",            "0", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_php_gc_interval)
 	/* var cache */
-	PHP_INI_ENTRY1     ("xcache.var_size",               "0", PHP_INI_SYSTEM, xc_OnUpdateDummy,    NULL)
-	PHP_INI_ENTRY1     ("xcache.var_count",              "1", PHP_INI_SYSTEM, xc_OnUpdateDummy,    NULL)
-	PHP_INI_ENTRY1     ("xcache.var_slots",             "8K", PHP_INI_SYSTEM, xc_OnUpdateDummy,    NULL)
-	PHP_INI_ENTRY1     ("xcache.var_maxttl",             "0", PHP_INI_SYSTEM, xc_OnUpdateULong,    &xc_var_maxttl)
-	PHP_INI_ENTRY1     ("xcache.var_gc_interval",      "120", PHP_INI_SYSTEM, xc_OnUpdateULong,    &xc_var_gc_interval)
+	PHP_INI_ENTRY1     ("xcache.var_size",               "0", PHP_INI_SYSTEM, xcache_OnUpdateDummy,    NULL)
+	PHP_INI_ENTRY1     ("xcache.var_count",              "1", PHP_INI_SYSTEM, xcache_OnUpdateDummy,    NULL)
+	PHP_INI_ENTRY1     ("xcache.var_slots",             "8K", PHP_INI_SYSTEM, xcache_OnUpdateDummy,    NULL)
+	PHP_INI_ENTRY1     ("xcache.var_maxttl",             "0", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_var_maxttl)
+	PHP_INI_ENTRY1     ("xcache.var_gc_interval",      "120", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_var_gc_interval)
 
 	STD_PHP_INI_BOOLEAN("xcache.cacher",                 "1", PHP_INI_ALL,    OnUpdateBool,        cacher,            zend_xcache_globals, xcache_globals)
@@ -3619,16 +3622,8 @@
 	STD_PHP_INI_BOOLEAN("xcache.admin.enable_auth",      "1", PHP_INI_SYSTEM, OnUpdateBool,        auth_enabled,      zend_xcache_globals, xcache_globals)
 	STD_PHP_INI_BOOLEAN("xcache.experimental",           "0", PHP_INI_ALL,    OnUpdateBool,        experimental,      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
 	STD_PHP_INI_ENTRY  ("xcache.var_ttl",                "0", PHP_INI_ALL,    OnUpdateLong,        var_ttl,           zend_xcache_globals, xcache_globals)
-#ifdef HAVE_XCACHE_COVERAGER
-	STD_PHP_INI_BOOLEAN("xcache.coverager"      ,        "0", PHP_INI_ALL,    OnUpdateBool,        coverager,         zend_xcache_globals, xcache_globals)
-	PHP_INI_ENTRY1     ("xcache.coveragedump_directory",  "", PHP_INI_SYSTEM, xc_OnUpdateDummy,    NULL)
-#endif
 PHP_INI_END()
 /* }}} */
-/* {{{ PHP_MINFO_FUNCTION(xcache) */
-static PHP_MINFO_FUNCTION(xcache)
+static PHP_MINFO_FUNCTION(xcache) /* {{{ */
 {
 	char buf[100];
@@ -3636,16 +3631,12 @@
 	int left, len;
 	xc_shm_scheme_t *scheme;
-#ifdef HAVE_XCACHE_COVERAGER
-	char *covdumpdir;
-#endif
 
 	php_info_print_table_start();
-	php_info_print_table_header(2, "XCache Support", "enabled");
-	php_info_print_table_row(2, "Version", XCACHE_VERSION);
+	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_row(2, "Readonly Protection", xc_readonly_protection ? "enabled" : "N/A");
+	php_info_print_table_row(2, "Readonly Protection", xc_readonly_protection ? "enabled" : "disabled");
 #ifdef ZEND_ENGINE_2_1
 	ptr = php_format_date("Y-m-d H:i:s", sizeof("Y-m-d H:i:s") - 1, xc_init_time, 1 TSRMLS_CC);
@@ -3693,101 +3684,7 @@
 	php_info_print_table_row(2, "Shared Memory Schemes", buf);
 
-#ifdef HAVE_XCACHE_COVERAGER
-	if (cfg_get_string("xcache.coveragedump_directory", &covdumpdir) != SUCCESS || !covdumpdir[0]) {
-		covdumpdir = NULL;
-	}
-	php_info_print_table_row(2, "Coverage Auto Dumper", XG(coverager) && covdumpdir ? "enabled" : "disabled");
-#endif
 	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_prepend_element(&zend_extensions, &extension);
-	TRACE("%s", "registered");
-}
-
-static zend_llist_element *xc_llist_get_element_by_zend_extension(zend_llist *l, const char *extension_name)
-{
-	zend_llist_element *element;
-
-	for (element = zend_extensions.head; element; element = element->next) {
-		zend_extension *extension = (zend_extension *) element->data;
-
-		if (!strcmp(extension->name, extension_name)) {
-			return element;
-		}
-	}
-	return NULL;
-}
-
-static void xc_llist_prepend(zend_llist *l, zend_llist_element *element)
-{
-	element->next = l->head;
-	element->prev = NULL;
-	if (l->head) {
-		l->head->prev = element;
-	}
-	else {
-		l->tail = element;
-	}
-	l->head = element;
-	++l->count;
-}
-
-static void xc_llist_unlink(zend_llist *l, zend_llist_element *element)
-{
-	if ((element)->prev) {
-		(element)->prev->next = (element)->next;
-	}
-	else {
-		(l)->head = (element)->next;
-	}
-
-	if ((element)->next) {
-		(element)->next->prev = (element)->prev;
-	}
-	else {
-		(l)->tail = (element)->prev;
-	}
-
-	--l->count;
-}
-
-static int xc_zend_extension_startup(zend_extension *extension)
-{
-	if (extension->startup) {
-		if (extension->startup(extension) != SUCCESS) {
-			return FAILURE;
-		}
-	}
-	return SUCCESS;
-}
-/* }}} */
-static int xc_ptr_compare_func(void *p1, void *p2) /* {{{ */
-{
-	return p1 == p2;
-}
-/* }}} */
-static int xc_zend_remove_extension(zend_extension *extension) /* {{{ */
-{
-	llist_dtor_func_t dtor;
-
-	assert(extension);
-	dtor = zend_extensions.dtor; /* avoid dtor */
-	zend_extensions.dtor = NULL;
-	zend_llist_del_element(&zend_extensions, extension, xc_ptr_compare_func);
-	zend_extensions.dtor = dtor;
-	return SUCCESS;
 }
 /* }}} */
@@ -3824,6 +3721,5 @@
 }
 /* }}} */
-/* {{{ PHP_MINIT_FUNCTION(xcache) */
-static PHP_MINIT_FUNCTION(xcache)
+static PHP_MINIT_FUNCTION(xcache) /* {{{ */
 {
 	char *env;
@@ -3831,12 +3727,5 @@
 	zend_llist_position lpos;
 
-	xc_module_gotup = 1;
-	if (!xc_zend_extension_gotup) {
-		zend_error(E_WARNING, "XCache is designed to be loaded as zend_extension not extension");
-		xc_zend_extension_register(&zend_extension_entry, 0);
-		xc_zend_extension_startup(&zend_extension_entry);
-		xc_zend_extension_faked = 1;
-	}
-
+	xcache_zend_extension_register(&zend_extension_entry, 1);
 	ext = zend_get_extension("Zend Optimizer");
 	if (ext) {
@@ -3918,9 +3807,14 @@
 	}
 
+#ifdef HAVE_XCACHE_OPTIMIZER
+	xc_optimizer_startup_module();
+#endif
+#ifdef HAVE_XCACHE_COVERAGER
+	xc_coverager_startup_module();
+#endif
+#ifdef HAVE_XCACHE_DISASSEMBLER
+	xc_disassembler_startup_module();
+#endif
 	xc_sandbox_module_init(module_number TSRMLS_CC);
-#ifdef HAVE_XCACHE_COVERAGER
-	xc_coverager_module_init(module_number TSRMLS_CC);
-#endif
-
 	return SUCCESS;
 
@@ -3932,7 +3826,4 @@
 static PHP_MSHUTDOWN_FUNCTION(xcache)
 {
-#ifdef HAVE_XCACHE_COVERAGER
-	xc_coverager_module_shutdown();
-#endif
 	xc_sandbox_module_shutdown();
 
@@ -3964,19 +3855,6 @@
 #endif
 
-	if (xc_zend_extension_faked) {
-		zend_extension *ext = zend_get_extension(XCACHE_NAME);
-		if (ext) {
-			if (ext->shutdown) {
-				ext->shutdown(ext);
-			}
-			xc_zend_remove_extension(ext);
-		}
-	}
+	xcache_zend_extension_unregister(&zend_extension_entry);
 	UNREGISTER_INI_ENTRIES();
-
-	xc_module_gotup = 0;
-	xc_zend_extension_gotup = 0;
-	xc_zend_extension_faked = 0;
-
 	return SUCCESS;
 }
@@ -4005,5 +3883,5 @@
 /* }}} */
 /* {{{ module dependencies */
-#if ZEND_MODULE_API_NO >= 20050922
+#ifdef STANDARD_MODULE_HEADER_EX
 static zend_module_dep xcache_module_deps[] = {
 	ZEND_MOD_REQUIRED("standard")
@@ -4011,16 +3889,11 @@
 	ZEND_MOD_CONFLICTS("eAccelerator")
 	ZEND_MOD_CONFLICTS("Turck MMCache")
-#ifdef ZEND_MOD_END
 	ZEND_MOD_END
-#else
-	{NULL, NULL, NULL, 0}
-#endif
 };
 #endif
 /* }}} */ 
 /* {{{ module definition structure */
-
 zend_module_entry xcache_module_entry = {
-#if ZEND_MODULE_API_NO >= 20050922
+#ifdef STANDARD_MODULE_HEADER_EX
 	STANDARD_MODULE_HEADER_EX,
 	NULL,
@@ -4059,113 +3932,2 @@
 #endif
 /* }}} */
-static startup_func_t xc_last_ext_startup;
-static int xc_zend_startup_last(zend_extension *extension) /* {{{ */
-{
-	zend_extension *ext = zend_get_extension(XCACHE_NAME);
-	if (ext) {
-		zend_error(E_WARNING, "Module '" XCACHE_NAME "' already loaded");
-	}
-	/* restore */
-	extension->startup = xc_last_ext_startup;
-	if (extension->startup) {
-		if (extension->startup(extension) != SUCCESS) {
-			return FAILURE;
-		}
-	}
-	assert(xc_llist_zend_extension);
-	xc_llist_prepend(&zend_extensions, xc_llist_zend_extension);
-	if (!xc_module_gotup) {
-		return zend_startup_module(&xcache_module_entry);
-	}
-	return SUCCESS;
-}
-/* }}} */
-ZEND_DLEXPORT int xcache_zend_startup(zend_extension *extension) /* {{{ */
-{
-	xc_zend_extension_gotup = 1;
-
-	if (!origin_compile_file) {
-		origin_compile_file = zend_compile_file;
-		zend_compile_file = xc_check_initial_compile_file;
-	}
-
-	if (zend_llist_count(&zend_extensions) > 1) {
-		zend_llist_position lpos;
-		zend_extension *ext;
-
-		xc_llist_zend_extension = xc_llist_get_element_by_zend_extension(&zend_extensions, XCACHE_NAME);
-		if (xc_llist_zend_extension != zend_extensions.head) {
-			zend_error(E_WARNING, "XCache must be loaded as the first zend_extension for maximum compatibility");
-		}
-		/* hide myself */
-		xc_llist_unlink(&zend_extensions, xc_llist_zend_extension);
-
-		ext = (zend_extension *) zend_llist_get_last_ex(&zend_extensions, &lpos);
-		assert(ext && ext != (zend_extension *) xc_llist_zend_extension->data);
-		xc_last_ext_startup = ext->startup;
-		ext->startup = xc_zend_startup_last;
-	}
-	else if (!xc_module_gotup) {
-		return zend_startup_module(&xcache_module_entry);
-	}
-	return SUCCESS;
-}
-/* }}} */
-ZEND_DLEXPORT void xcache_zend_shutdown(zend_extension *extension) /* {{{ */
-{
-	/* empty */
-}
-/* }}} */
-ZEND_DLEXPORT void xcache_statement_handler(zend_op_array *op_array) /* {{{ */
-{
-#ifdef HAVE_XCACHE_COVERAGER
-	xc_coverager_handle_ext_stmt(op_array, ZEND_EXT_STMT);
-#endif
-}
-/* }}} */
-ZEND_DLEXPORT void xcache_fcall_begin_handler(zend_op_array *op_array) /* {{{ */
-{
-#if 0
-	xc_coverager_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_coverager_handle_ext_stmt(op_array, ZEND_EXT_FCALL_END);
-#endif
-}
-/* }}} */
-/* {{{ zend extension definition structure */
-ZEND_DLEXPORT zend_extension zend_extension_entry = {
-	XCACHE_NAME,
-	XCACHE_VERSION,
-	XCACHE_AUTHOR,
-	XCACHE_URL,
-	XCACHE_COPYRIGHT,
-	xcache_zend_startup,
-	xcache_zend_shutdown,
-	NULL,           /* activate_func_t */
-	NULL,           /* deactivate_func_t */
-	NULL,           /* message_handler_func_t */
-#ifdef HAVE_XCACHE_OPTIMIZER
-	xc_optimizer_op_array_handler,
-#else
-	NULL,           /* op_array_handler_func_t */
-#endif
-	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
-};
-
-#ifndef ZEND_EXT_API
-#	define ZEND_EXT_API ZEND_DLEXPORT
-#endif
-#if COMPILE_DL_XCACHE
-ZEND_EXTENSION();
-#endif
-/* }}} */
Index: /trunk/config.w32
===================================================================
--- /trunk/config.w32	(revision 1011)
+++ /trunk/config.w32	(revision 1026)
@@ -19,6 +19,8 @@
 
 	ADD_SOURCES(configure_module_dirname + "/xcache", " \
+xc_compatibility.c \
 xc_const_string.c \
-xc_compatibility.c \
+xc_extension.c \
+xc_ini.c \
 xc_lock.c \
 xc_mem.c \
Index: /trunk/Makefile.frag.deps
===================================================================
--- /trunk/Makefile.frag.deps	(revision 1018)
+++ /trunk/Makefile.frag.deps	(revision 1026)
@@ -1,14 +1,16 @@
 $(XCACHE_INCLUDES_I) $(builddir)/includes.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h
 $(builddir)/mod_assembler/xc_assembler.lo:
-$(builddir)/mod_coverager/xc_coverager.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache_globals.h $(srcdir)/util/xc_stack.h $(srcdir)/mod_coverager/xc_coverager.h $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache/xc_compatibility.h
+$(builddir)/mod_coverager/xc_coverager.lo: $(srcdir)/mod_coverager/xc_coverager.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache_globals.h $(srcdir)/util/xc_stack.h
 $(builddir)/mod_decoder/xc_decoder.lo:
 $(builddir)/mod_disassembler/xc_disassembler.lo: $(srcdir)/mod_disassembler/xc_disassembler.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_sandbox.h $(srcdir)/xcache/xc_compatibility.h $(XCACHE_PROC_H)
 $(builddir)/mod_encoder/xc_encoder.lo:
-$(builddir)/mod_optimizer/xc_optimizer.lo: $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/mod_optimizer/xc_optimizer.h $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache_globals.h $(srcdir)/util/xc_stack.h
+$(builddir)/mod_optimizer/xc_optimizer.lo: $(srcdir)/mod_optimizer/xc_optimizer.h $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/util/xc_stack.h $(srcdir)/util/xc_trace.h $(srcdir)/xcache_globals.h $(srcdir)/util/xc_stack.h
 $(builddir)/util/xc_stack.lo: $(srcdir)/util/xc_trace.h $(srcdir)/util/xc_stack.h
 $(builddir)/util/xc_trace.lo: $(srcdir)/util/xc_trace.h
-$(builddir)/xcache.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache_globals.h $(srcdir)/util/xc_stack.h $(XCACHE_PROC_H) $(srcdir)/xcache/xc_const_string.h $(srcdir)/xcache/xc_opcode_spec.h $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_sandbox.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/util/xc_align.h $(srcdir)/util/xc_vector.h $(srcdir)/util/xc_trace.h $(srcdir)/util/xc_foreachcoresig.h
+$(builddir)/xcache.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache_globals.h $(srcdir)/util/xc_stack.h $(XCACHE_PROC_H) $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache/xc_ini.h $(srcdir)/xcache/xc_const_string.h $(srcdir)/xcache/xc_opcode_spec.h $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_sandbox.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/util/xc_align.h $(srcdir)/util/xc_vector.h $(srcdir)/util/xc_trace.h $(srcdir)/util/xc_foreachcoresig.h
 $(builddir)/xcache/xc_compatibility.lo: $(srcdir)/xcache/xc_compatibility.h
 $(builddir)/xcache/xc_const_string.lo: $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_const_string.h $(srcdir)/xcache/xc_const_string_opcodes_php5.4.h
+$(builddir)/xcache/xc_extension.lo: $(srcdir)/xcache/xc_extension.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/util/xc_trace.h
+$(builddir)/xcache/xc_ini.lo: $(srcdir)/xcache/xc_ini.h
 $(builddir)/xcache/xc_lock.lo: $(srcdir)/xcache/xc_lock.h
 $(builddir)/xcache/xc_malloc.lo: $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_mem.h $(srcdir)/xcache/xc_utils.h $(srcdir)/xcache.h $(srcdir)/xcache/xc_shm.h $(srcdir)/xcache/xc_lock.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/xcache/xc_compatibility.h $(srcdir)/util/xc_align.h
Index: /trunk/xcache-zh-gb2312.ini
===================================================================
--- /trunk/xcache-zh-gb2312.ini	(revision 927)
+++ /trunk/xcache-zh-gb2312.ini	(revision 1026)
@@ -1,15 +1,8 @@
 ;; ���ļ�ֻ������, ���� php.ini �������Ա���Ч
 [xcache-common]
-;; ����: zend_extension* = *xcache* ���������� zend_extension*=* ֮�е�һ������
-;; ��װ�� zend extension, ·��һ���� "$extension_dir/xcache.so"
-;; ���Ƽ�ʹ�� extension=xcache.so
-
-;; �� windows ����
-;; install as zend extension, normally "$extension_dir/xcache.so"
-zend_extension = /usr/local/lib/php/extensions/non-debug-non-zts-xxx/xcache.so
+;; �� windows ����:
+extension = xcache.so
 ;; Windows ϵͳ����:
-zend_extension_ts = c:/php/extensions/php_xcache.dll
-;; �����°汾 PHP, _ts ��׺�Ѿ��Ƴ�, ��ʹ����������
-zend_extension = c:/php/extensions/php_xcache.dll
+; extension = php_xcache.dll
 
 [xcache.admin]
Index: /trunk/xcache-test.ini
===================================================================
--- /trunk/xcache-test.ini	(revision 870)
+++ /trunk/xcache-test.ini	(revision 1026)
@@ -3,8 +3,6 @@
 
 [xcache]
-zend_extension_debug_ts=./modules/xcache.so
-zend_extension_debug=./modules/xcache.so
-zend_extension_ts=./modules/xcache.so
-zend_extension=./modules/xcache.so
+extension_dir="./modules/"
+extension=xcache.so
 xcache.cacher = On
 xcache.test = 1
