Index: /trunk/config.m4
===================================================================
--- /trunk/config.m4	(revision 985)
+++ /trunk/config.m4	(revision 986)
@@ -30,4 +30,5 @@
                   main/xc_opcode_spec.c \
                   main/xc_processor.c \
+                  main/xc_sandbox.c \
                   main/xc_shm.c \
                   main/xc_shm_mmap.c \
Index: /trunk/config.w32
===================================================================
--- /trunk/config.w32	(revision 985)
+++ /trunk/config.w32	(revision 986)
@@ -18,4 +18,5 @@
 	                      main/xc_mem.c \
 	                      main/xc_opcode_spec.c \
+	                      main/xc_sandbox.c \
 	                      main/xc_shm.c \
 	                      main/xc_shm_mmap.c \
Index: /trunk/main/xc_sandbox.c
===================================================================
--- /trunk/main/xc_sandbox.c	(revision 986)
+++ /trunk/main/xc_sandbox.c	(revision 986)
@@ -0,0 +1,518 @@
+
+#include "xcache.h"
+#include "xc_sandbox.h"
+#include "xc_utils.h"
+#include "xcache_globals.h"
+
+/* utilities used by sandbox */
+static void (*old_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) = NULL;
+static void call_old_zend_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, ...) /* {{{ */
+{
+	va_list args;
+	va_start(args, format);
+	old_zend_error_cb(type, error_filename, error_lineno, format, args);
+}
+/* }}} */
+#ifdef ZEND_ENGINE_2_1
+static zend_bool xc_auto_global_callback(ZEND_24(NOTHING, const) char *name, uint name_len TSRMLS_DC) /* {{{ */
+{
+	return 0;
+}
+/* }}} */
+static int xc_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
+{
+	if (auto_global->auto_global_callback) {
+		auto_global->armed = 1;
+		auto_global->auto_global_callback = xc_auto_global_callback;
+	}
+	else {
+		auto_global->armed = 0;
+	}
+	return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
+#endif
+
+#ifdef HAVE_XCACHE_CONSTANT
+static void xc_free_zend_constant(zend_constant *c) /* {{{ */
+{
+	if (!(c->flags & CONST_PERSISTENT)) {
+		zval_dtor(&c->value);
+	}
+	free(ZSTR_V(c->name));
+}
+/* }}} */
+#endif
+
+typedef struct { /* sandbox {{{ */
+	ZEND_24(NOTHING, const) char *filename;
+
+	HashTable orig_included_files;
+	HashTable *tmp_included_files;
+
+#ifdef HAVE_XCACHE_CONSTANT
+	HashTable *orig_zend_constants;
+	HashTable tmp_zend_constants;
+#endif
+	HashTable *orig_function_table;
+	HashTable *orig_class_table;
+	HashTable *orig_auto_globals;
+	HashTable tmp_function_table;
+	HashTable tmp_class_table;
+	HashTable tmp_auto_globals;
+#ifdef HAVE_XCACHE_CONSTANT
+	Bucket    *tmp_internal_constant_tail;
+#endif
+	Bucket    *tmp_internal_function_tail;
+	Bucket    *tmp_internal_class_tail;
+
+#ifdef XCACHE_ERROR_CACHING
+	int orig_user_error_handler_error_reporting;
+	zend_uint compilererror_cnt;
+	zend_uint compilererror_size;
+	xc_compilererror_t *compilererrors;
+#endif
+
+#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
+	zend_uint orig_compiler_options;
+#endif
+} xc_sandbox_t;
+
+#undef TG
+#undef OG
+#define TG(x) (sandbox->tmp_##x)
+#define OG(x) (sandbox->orig_##x)
+/* }}} */
+#ifdef XCACHE_ERROR_CACHING
+static void xc_sandbox_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) /* {{{ */
+{
+	xc_compilererror_t *compilererror;
+	xc_sandbox_t *sandbox;
+	TSRMLS_FETCH();
+
+	sandbox = (xc_sandbox_t *) XG(sandbox);
+	if (!sandbox) {
+		old_zend_error_cb(type, error_filename, error_lineno, format, args);
+		return;
+	}
+
+	switch (type) {
+#ifdef E_STRICT
+	case E_STRICT:
+#endif
+#ifdef E_DEPRECATED
+	case E_DEPRECATED:
+#endif
+		if (sandbox->compilererror_cnt <= sandbox->compilererror_size) {
+			if (sandbox->compilererror_size) {
+				sandbox->compilererror_size += 16;
+				sandbox->compilererrors = erealloc(sandbox->compilererrors, sandbox->compilererror_size * sizeof(sandbox->compilererrors));
+			}
+			else {
+				sandbox->compilererror_size = 16;
+				sandbox->compilererrors = emalloc(sandbox->compilererror_size * sizeof(sandbox->compilererrors));
+			}
+		}
+		compilererror = &sandbox->compilererrors[sandbox->compilererror_cnt++];
+		compilererror->type = type;
+		compilererror->lineno = error_lineno;
+		compilererror->error_len = vspprintf(&compilererror->error, 0, format, args);
+		break;
+
+	default: {
+		/* give up, and user handler is not supported in this case */
+		zend_uint i;
+		zend_uint old_lineno = CG(zend_lineno);
+
+		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
+			compilererror = &sandbox->compilererrors[i];
+			CG(zend_lineno) = compilererror->lineno;
+			call_old_zend_error_cb(compilererror->type, error_filename, error_lineno, "%s", compilererror->error);
+			efree(compilererror->error);
+		}
+		if (sandbox->compilererrors) {
+			efree(sandbox->compilererrors);
+			sandbox->compilererrors = NULL;
+		}
+		sandbox->compilererror_cnt  = 0;
+		sandbox->compilererror_size = 0;
+
+		CG(zend_lineno) = old_lineno;
+		old_zend_error_cb(type, error_filename, error_lineno, format, args);
+		break;
+	}
+	}
+}
+/* }}} */
+#endif
+
+static xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
+{
+	HashTable *h;
+
+	assert(sandbox);
+	memset(sandbox, 0, sizeof(sandbox[0]));
+
+	memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files)));
+
+#ifdef HAVE_XCACHE_CONSTANT
+	OG(zend_constants) = EG(zend_constants);
+	EG(zend_constants) = &TG(zend_constants);
+#endif
+
+	OG(function_table) = CG(function_table);
+	CG(function_table) = &TG(function_table);
+
+	OG(class_table) = CG(class_table);
+	CG(class_table) = &TG(class_table);
+	EG(class_table) = CG(class_table);
+
+#ifdef ZEND_ENGINE_2_1
+	OG(auto_globals) = CG(auto_globals);
+	CG(auto_globals) = &TG(auto_globals);
+#endif
+
+	TG(included_files) = &EG(included_files);
+
+	zend_hash_init_ex(TG(included_files), 5, NULL, NULL, 0, 1);
+#ifdef HAVE_XCACHE_CONSTANT
+	h = OG(zend_constants);
+	zend_hash_init_ex(&TG(zend_constants),  20, NULL, (dtor_func_t) xc_free_zend_constant, h->persistent, h->bApplyProtection);
+	xc_copy_internal_zend_constants(&TG(zend_constants), &XG(internal_constant_table));
+	TG(internal_constant_tail) = TG(zend_constants).pListTail;
+#endif
+	h = OG(function_table);
+	zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, h->persistent, h->bApplyProtection);
+	{
+		zend_function tmp_func;
+		zend_hash_copy(&TG(function_table), &XG(internal_function_table), NULL, (void *) &tmp_func, sizeof(tmp_func));
+	}
+	TG(internal_function_tail) = TG(function_table).pListTail;
+
+	h = OG(class_table);
+	zend_hash_init_ex(&TG(class_table),     16, NULL, ZEND_CLASS_DTOR, h->persistent, h->bApplyProtection);
+#if 0 && TODO
+	{
+		xc_cest_t tmp_cest;
+		zend_hash_copy(&TG(class_table), &XG(internal_class_table), NULL, (void *) &tmp_cest, sizeof(tmp_cest));
+	}
+#endif
+	TG(internal_class_tail) = TG(class_table).pListTail;
+
+#ifdef ZEND_ENGINE_2_1
+	/* shallow copy, don't destruct */
+	h = OG(auto_globals);
+	zend_hash_init_ex(&TG(auto_globals),     8, NULL,           NULL, h->persistent, h->bApplyProtection);
+	{
+		zend_auto_global tmp_autoglobal;
+
+		zend_hash_copy(&TG(auto_globals), OG(auto_globals), NULL, (void *) &tmp_autoglobal, sizeof(tmp_autoglobal));
+		zend_hash_apply(&TG(auto_globals), (apply_func_t) xc_auto_global_arm TSRMLS_CC);
+	}
+#endif
+
+	sandbox->filename = filename;
+
+#ifdef XCACHE_ERROR_CACHING
+	sandbox->orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting);
+	EG(user_error_handler_error_reporting) = 0;
+
+	sandbox->compilererror_cnt  = 0;
+	sandbox->compilererror_size = 0;
+#endif
+
+#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
+	sandbox->orig_compiler_options = CG(compiler_options);
+	/* Using ZEND_COMPILE_IGNORE_INTERNAL_CLASSES for ZEND_FETCH_CLASS_RT_NS_CHECK
+	 */
+	CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES | ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_DELAYED_BINDING;
+#endif
+
+	XG(sandbox) = (void *) sandbox;
+	return sandbox;
+}
+/* }}} */
+
+#ifndef ZEND_COMPILE_DELAYED_BINDING
+static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) data;
+	xc_do_early_binding(CG(active_op_array), OG(class_table), oplineno TSRMLS_CC);
+}
+/* }}} */
+#endif
+static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
+{
+	zend_uint i;
+	Bucket *b;
+
+#ifdef HAVE_XCACHE_CONSTANT
+	for (b = TG(zend_constants).pListHead; b != NULL && b != TG(internal_constant_tail); b = b->pListNext) {
+		zend_constant *c = (zend_constant*) b->pData;
+		xc_free_zend_constant(c);
+	}
+
+	b = TG(internal_constant_tail) ? TG(internal_constant_tail)->pListNext : 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), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
+		b = b->pListNext;
+	}
+#endif
+
+	b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
+	/* install function */
+	while (b != NULL) {
+		zend_function *func = (zend_function*) b->pData;
+		xc_install_function(sandbox->filename, func,
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
+		b = b->pListNext;
+	}
+
+	b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
+	/* install class */
+	while (b != NULL) {
+		xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, -1,
+				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
+		b = b->pListNext;
+	}
+
+#ifdef ZEND_ENGINE_2_1
+	/* trigger auto_globals jit */
+	for (b = TG(auto_globals).pListHead; b != NULL; b = b->pListNext) {
+		zend_auto_global *auto_global = (zend_auto_global *) b->pData;
+		/* check if actived */
+		if (auto_global->auto_global_callback && !auto_global->armed) {
+			zend_u_is_auto_global(BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), auto_global->name_len TSRMLS_CC);
+		}
+	}
+#endif
+
+#ifdef ZEND_COMPILE_DELAYED_BINDING
+	zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC);
+#else
+	xc_undo_pass_two(CG(active_op_array) TSRMLS_CC);
+	xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC);
+	xc_redo_pass_two(CG(active_op_array) TSRMLS_CC);
+#endif
+
+#ifdef XCACHE_ERROR_CACHING
+	/* restore trigger errors */
+	for (i = 0; i < sandbox->compilererror_cnt; i ++) {
+		xc_compilererror_t *error = &sandbox->compilererrors[i];
+		CG(zend_lineno) = error->lineno;
+		zend_error(error->type, "%s", error->error);
+	}
+	CG(zend_lineno) = 0;
+#endif
+
+	i = 1;
+	/* still needed because in zend_language_scanner.l, require()/include() check file_handle.handle.stream.handle */
+	zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL);
+}
+/* }}} */
+static void xc_sandbox_free(xc_sandbox_t *sandbox, zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+	XG(sandbox) = NULL;
+#ifdef XCACHE_ERROR_CACHING
+	EG(user_error_handler_error_reporting) = sandbox->orig_user_error_handler_error_reporting;
+#endif
+
+	/* 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);
+	EG(class_table)    = CG(class_table);
+#ifdef ZEND_ENGINE_2_1
+	CG(auto_globals)   = OG(auto_globals);
+#endif
+
+	if (op_array) {
+		zend_op_array *old_active_op_array = CG(active_op_array);
+		CG(in_compilation)    = 1;
+		CG(compiled_filename) = ZEND_24(NOTHING, (char *)) sandbox->filename;
+		CG(zend_lineno)       = 0;
+
+		CG(active_op_array) = op_array;
+		xc_sandbox_install(sandbox TSRMLS_CC);
+		CG(active_op_array) = old_active_op_array;
+
+		CG(in_compilation)    = 0;
+		CG(compiled_filename) = NULL;
+
+		/* 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;
+	}
+
+	/* 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));
+#ifdef ZEND_ENGINE_2_1
+	zend_hash_destroy(&TG(auto_globals));
+#endif
+	zend_hash_destroy(TG(included_files));
+
+	/* restore orig here, as EG/CG holded tmp before */
+	memcpy(&EG(included_files), &OG(included_files), sizeof(EG(included_files)));
+
+#ifdef XCACHE_ERROR_CACHING
+	if (sandbox->compilererrors) {
+		zend_uint i;
+		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
+			efree(sandbox->compilererrors[i].error);
+		}
+		efree(sandbox->compilererrors);
+	}
+#endif
+
+#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
+	CG(compiler_options) = sandbox->orig_compiler_options;
+#endif
+}
+/* }}} */
+zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
+{
+	xc_sandbox_t sandbox;
+	zend_op_array *op_array = NULL;
+	zend_bool catched = 0;
+
+	memset(&sandbox, 0, sizeof(sandbox));
+	zend_try {
+		xc_sandbox_init(&sandbox, filename TSRMLS_CC);
+		op_array = sandboxed_func(data TSRMLS_CC);
+	} zend_catch {
+		catched = 1;
+	} zend_end_try();
+
+	xc_sandbox_free(&sandbox, op_array TSRMLS_CC);
+	if (catched) {
+		zend_bailout();
+	}
+	return op_array;
+}
+/* {{{ */
+const Bucket *xc_sandbox_user_function_begin(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
+}
+/* {{{ */
+const Bucket *xc_sandbox_user_class_begin(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
+}
+/* {{{ */
+#ifdef XCACHE_ERROR_CACHING
+xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return sandbox->compilererrors;
+}
+/* }}} */
+zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D) /* {{{ */
+{
+	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
+	assert(sandbox);
+	return sandbox->compilererror_cnt;
+}
+/* }}} */
+#endif
+
+int xc_vtrace(const char *fmt, va_list args) /* {{{ */
+{
+	return vfprintf(stderr, fmt, args);
+}
+/* }}} */
+int xc_trace(const char *fmt, ...) /* {{{ */
+{
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	ret = xc_vtrace(fmt, args);
+	va_end(args);
+	return ret;
+}
+/* }}} */
+
+#ifndef ZEND_ENGINE_2_3
+#include "ext/standard/php_string.h"
+size_t xc_dirname(char *path, size_t len) /* {{{ */
+{
+#ifdef ZEND_ENGINE_2
+	return php_dirname(path, len);
+#else
+	php_dirname(path, len);
+	return strlen(path);
+#endif
+}
+/* }}} */
+
+long xc_atol(const char *str, int str_len) /* {{{ */
+{
+	long retval;
+
+	if (!str_len) {
+		str_len = strlen(str);
+	}
+
+	retval = strtol(str, NULL, 0);
+	if (str_len > 0) {
+		switch (str[str_len - 1]) {
+		case 'g':
+		case 'G':
+			retval *= 1024;
+			/* break intentionally missing */
+		case 'm':
+		case 'M':
+			retval *= 1024;
+			/* break intentionally missing */
+		case 'k':
+		case 'K':
+			retval *= 1024;
+			break;
+		}
+	}
+
+	return retval;
+}
+/* }}} */
+
+#endif
+
+/* init/destroy */
+int xc_util_init(int module_number TSRMLS_DC) /* {{{ */
+{
+#ifdef XCACHE_ERROR_CACHING
+	old_zend_error_cb = zend_error_cb;
+	zend_error_cb = xc_sandbox_error_cb;
+#endif
+
+	return SUCCESS;
+}
+/* }}} */
+void xc_util_destroy() /* {{{ */
+{
+#ifdef XCACHE_ERROR_CACHING
+	if (zend_error_cb == xc_sandbox_error_cb) {
+		zend_error_cb = old_zend_error_cb;
+	}
+#endif
+}
+/* }}} */
+
Index: /trunk/main/xc_sandbox.h
===================================================================
--- /trunk/main/xc_sandbox.h	(revision 986)
+++ /trunk/main/xc_sandbox.h	(revision 986)
@@ -0,0 +1,19 @@
+#ifndef _22077CFAC35518969B4416944ACBA159
+#define _22077CFAC35518969B4416944ACBA159
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+/* return op_array to install */
+typedef zend_op_array *(*xc_sandboxed_func_t)(void *data TSRMLS_DC);
+zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC);
+const Bucket *xc_sandbox_user_function_begin(TSRMLS_D);
+const Bucket *xc_sandbox_user_class_begin(TSRMLS_D);
+zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
+#ifdef XCACHE_ERROR_CACHING
+xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D);
+zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
+#endif
+
+#endif /* _22077CFAC35518969B4416944ACBA159 */
Index: /trunk/main/xc_utils.c
===================================================================
--- /trunk/main/xc_utils.c	(revision 985)
+++ /trunk/main/xc_utils.c	(revision 986)
@@ -27,11 +27,4 @@
 #endif
 
-static void (*old_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) = NULL;
-static void call_old_zend_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, ...) /* {{{ */
-{
-	va_list args;
-	va_start(args, format);
-	old_zend_error_cb(type, error_filename, error_lineno, format, args);
-}
 /* }}} */
 
@@ -579,125 +572,4 @@
 /* }}} */
 
-typedef struct { /* sandbox {{{ */
-	ZEND_24(NOTHING, const) char *filename;
-
-	HashTable orig_included_files;
-	HashTable *tmp_included_files;
-
-#ifdef HAVE_XCACHE_CONSTANT
-	HashTable *orig_zend_constants;
-	HashTable tmp_zend_constants;
-#endif
-	HashTable *orig_function_table;
-	HashTable *orig_class_table;
-	HashTable *orig_auto_globals;
-	HashTable tmp_function_table;
-	HashTable tmp_class_table;
-	HashTable tmp_auto_globals;
-#ifdef HAVE_XCACHE_CONSTANT
-	Bucket    *tmp_internal_constant_tail;
-#endif
-	Bucket    *tmp_internal_function_tail;
-	Bucket    *tmp_internal_class_tail;
-
-#ifdef XCACHE_ERROR_CACHING
-	int orig_user_error_handler_error_reporting;
-	zend_uint compilererror_cnt;
-	zend_uint compilererror_size;
-	xc_compilererror_t *compilererrors;
-#endif
-
-#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
-	zend_uint orig_compiler_options;
-#endif
-} xc_sandbox_t;
-
-#undef TG
-#undef OG
-#define TG(x) (sandbox->tmp_##x)
-#define OG(x) (sandbox->orig_##x)
-/* }}} */
-#ifdef XCACHE_ERROR_CACHING
-static void xc_sandbox_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) /* {{{ */
-{
-	xc_compilererror_t *compilererror;
-	xc_sandbox_t *sandbox;
-	TSRMLS_FETCH();
-
-	sandbox = (xc_sandbox_t *) XG(sandbox);
-	if (!sandbox) {
-		old_zend_error_cb(type, error_filename, error_lineno, format, args);
-		return;
-	}
-
-	switch (type) {
-#ifdef E_STRICT
-	case E_STRICT:
-#endif
-#ifdef E_DEPRECATED
-	case E_DEPRECATED:
-#endif
-		if (sandbox->compilererror_cnt <= sandbox->compilererror_size) {
-			if (sandbox->compilererror_size) {
-				sandbox->compilererror_size += 16;
-				sandbox->compilererrors = erealloc(sandbox->compilererrors, sandbox->compilererror_size * sizeof(sandbox->compilererrors));
-			}
-			else {
-				sandbox->compilererror_size = 16;
-				sandbox->compilererrors = emalloc(sandbox->compilererror_size * sizeof(sandbox->compilererrors));
-			}
-		}
-		compilererror = &sandbox->compilererrors[sandbox->compilererror_cnt++];
-		compilererror->type = type;
-		compilererror->lineno = error_lineno;
-		compilererror->error_len = vspprintf(&compilererror->error, 0, format, args);
-		break;
-
-	default: {
-		/* give up, and user handler is not supported in this case */
-		zend_uint i;
-		zend_uint old_lineno = CG(zend_lineno);
-
-		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
-			compilererror = &sandbox->compilererrors[i];
-			CG(zend_lineno) = compilererror->lineno;
-			call_old_zend_error_cb(compilererror->type, error_filename, error_lineno, "%s", compilererror->error);
-			efree(compilererror->error);
-		}
-		if (sandbox->compilererrors) {
-			efree(sandbox->compilererrors);
-			sandbox->compilererrors = NULL;
-		}
-		sandbox->compilererror_cnt  = 0;
-		sandbox->compilererror_size = 0;
-
-		CG(zend_lineno) = old_lineno;
-		old_zend_error_cb(type, error_filename, error_lineno, format, args);
-		break;
-	}
-	}
-}
-/* }}} */
-#endif
-#ifdef ZEND_ENGINE_2_1
-static zend_bool xc_auto_global_callback(ZEND_24(NOTHING, const) char *name, uint name_len TSRMLS_DC) /* {{{ */
-{
-	return 0;
-}
-/* }}} */
-static int xc_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
-{
-	if (auto_global->auto_global_callback) {
-		auto_global->armed = 1;
-		auto_global->auto_global_callback = xc_auto_global_callback;
-	}
-	else {
-		auto_global->armed = 0;
-	}
-	return ZEND_HASH_APPLY_KEEP;
-}
-/* }}} */
-#endif
-
 void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker) /* {{{ */
 {
@@ -746,12 +618,4 @@
 }
 /* }}} */
-static void xc_free_zend_constant(zend_constant *c) /* {{{ */
-{
-	if (!(c->flags & CONST_PERSISTENT)) {
-		zval_dtor(&c->value);
-	}
-	free(ZSTR_V(c->name));
-}
-/* }}} */
 void xc_copy_internal_zend_constants(HashTable *target, HashTable *source) /* {{{ */
 {
@@ -761,372 +625,2 @@
 /* }}} */
 #endif
-
-static xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
-{
-	HashTable *h;
-
-	assert(sandbox);
-	memset(sandbox, 0, sizeof(sandbox[0]));
-
-	memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files)));
-
-#ifdef HAVE_XCACHE_CONSTANT
-	OG(zend_constants) = EG(zend_constants);
-	EG(zend_constants) = &TG(zend_constants);
-#endif
-
-	OG(function_table) = CG(function_table);
-	CG(function_table) = &TG(function_table);
-
-	OG(class_table) = CG(class_table);
-	CG(class_table) = &TG(class_table);
-	EG(class_table) = CG(class_table);
-
-#ifdef ZEND_ENGINE_2_1
-	OG(auto_globals) = CG(auto_globals);
-	CG(auto_globals) = &TG(auto_globals);
-#endif
-
-	TG(included_files) = &EG(included_files);
-
-	zend_hash_init_ex(TG(included_files), 5, NULL, NULL, 0, 1);
-#ifdef HAVE_XCACHE_CONSTANT
-	h = OG(zend_constants);
-	zend_hash_init_ex(&TG(zend_constants),  20, NULL, (dtor_func_t) xc_free_zend_constant, h->persistent, h->bApplyProtection);
-	xc_copy_internal_zend_constants(&TG(zend_constants), &XG(internal_constant_table));
-	TG(internal_constant_tail) = TG(zend_constants).pListTail;
-#endif
-	h = OG(function_table);
-	zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, h->persistent, h->bApplyProtection);
-	{
-		zend_function tmp_func;
-		zend_hash_copy(&TG(function_table), &XG(internal_function_table), NULL, (void *) &tmp_func, sizeof(tmp_func));
-	}
-	TG(internal_function_tail) = TG(function_table).pListTail;
-
-	h = OG(class_table);
-	zend_hash_init_ex(&TG(class_table),     16, NULL, ZEND_CLASS_DTOR, h->persistent, h->bApplyProtection);
-#if 0 && TODO
-	{
-		xc_cest_t tmp_cest;
-		zend_hash_copy(&TG(class_table), &XG(internal_class_table), NULL, (void *) &tmp_cest, sizeof(tmp_cest));
-	}
-#endif
-	TG(internal_class_tail) = TG(class_table).pListTail;
-
-#ifdef ZEND_ENGINE_2_1
-	/* shallow copy, don't destruct */
-	h = OG(auto_globals);
-	zend_hash_init_ex(&TG(auto_globals),     8, NULL,           NULL, h->persistent, h->bApplyProtection);
-	{
-		zend_auto_global tmp_autoglobal;
-
-		zend_hash_copy(&TG(auto_globals), OG(auto_globals), NULL, (void *) &tmp_autoglobal, sizeof(tmp_autoglobal));
-		zend_hash_apply(&TG(auto_globals), (apply_func_t) xc_auto_global_arm TSRMLS_CC);
-	}
-#endif
-
-	sandbox->filename = filename;
-
-#ifdef XCACHE_ERROR_CACHING
-	sandbox->orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting);
-	EG(user_error_handler_error_reporting) = 0;
-
-	sandbox->compilererror_cnt  = 0;
-	sandbox->compilererror_size = 0;
-#endif
-
-#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
-	sandbox->orig_compiler_options = CG(compiler_options);
-	/* Using ZEND_COMPILE_IGNORE_INTERNAL_CLASSES for ZEND_FETCH_CLASS_RT_NS_CHECK
-	 */
-	CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES | ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_DELAYED_BINDING;
-#endif
-
-	XG(sandbox) = (void *) sandbox;
-	return sandbox;
-}
-/* }}} */
-#ifndef ZEND_COMPILE_DELAYED_BINDING
-static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) data;
-	xc_do_early_binding(CG(active_op_array), OG(class_table), oplineno TSRMLS_CC);
-}
-/* }}} */
-#endif
-static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
-{
-	zend_uint i;
-	Bucket *b;
-
-#ifdef HAVE_XCACHE_CONSTANT
-	for (b = TG(zend_constants).pListHead; b != NULL && b != TG(internal_constant_tail); b = b->pListNext) {
-		zend_constant *c = (zend_constant*) b->pData;
-		xc_free_zend_constant(c);
-	}
-
-	b = TG(internal_constant_tail) ? TG(internal_constant_tail)->pListNext : 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), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
-		b = b->pListNext;
-	}
-#endif
-
-	b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
-	/* install function */
-	while (b != NULL) {
-		zend_function *func = (zend_function*) b->pData;
-		xc_install_function(sandbox->filename, func,
-				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
-		b = b->pListNext;
-	}
-
-	b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
-	/* install class */
-	while (b != NULL) {
-		xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, -1,
-				BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);
-		b = b->pListNext;
-	}
-
-#ifdef ZEND_ENGINE_2_1
-	/* trigger auto_globals jit */
-	for (b = TG(auto_globals).pListHead; b != NULL; b = b->pListNext) {
-		zend_auto_global *auto_global = (zend_auto_global *) b->pData;
-		/* check if actived */
-		if (auto_global->auto_global_callback && !auto_global->armed) {
-			zend_u_is_auto_global(BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), auto_global->name_len TSRMLS_CC);
-		}
-	}
-#endif
-
-#ifdef ZEND_COMPILE_DELAYED_BINDING
-	zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC);
-#else
-	xc_undo_pass_two(CG(active_op_array) TSRMLS_CC);
-	xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC);
-	xc_redo_pass_two(CG(active_op_array) TSRMLS_CC);
-#endif
-
-#ifdef XCACHE_ERROR_CACHING
-	/* restore trigger errors */
-	for (i = 0; i < sandbox->compilererror_cnt; i ++) {
-		xc_compilererror_t *error = &sandbox->compilererrors[i];
-		CG(zend_lineno) = error->lineno;
-		zend_error(error->type, "%s", error->error);
-	}
-	CG(zend_lineno) = 0;
-#endif
-
-	i = 1;
-	/* still needed because in zend_language_scanner.l, require()/include() check file_handle.handle.stream.handle */
-	zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL);
-}
-/* }}} */
-static void xc_sandbox_free(xc_sandbox_t *sandbox, zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
-	XG(sandbox) = NULL;
-#ifdef XCACHE_ERROR_CACHING
-	EG(user_error_handler_error_reporting) = sandbox->orig_user_error_handler_error_reporting;
-#endif
-
-	/* 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);
-	EG(class_table)    = CG(class_table);
-#ifdef ZEND_ENGINE_2_1
-	CG(auto_globals)   = OG(auto_globals);
-#endif
-
-	if (op_array) {
-		zend_op_array *old_active_op_array = CG(active_op_array);
-		CG(in_compilation)    = 1;
-		CG(compiled_filename) = ZEND_24(NOTHING, (char *)) sandbox->filename;
-		CG(zend_lineno)       = 0;
-
-		CG(active_op_array) = op_array;
-		xc_sandbox_install(sandbox TSRMLS_CC);
-		CG(active_op_array) = old_active_op_array;
-
-		CG(in_compilation)    = 0;
-		CG(compiled_filename) = NULL;
-
-		/* 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;
-	}
-
-	/* 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));
-#ifdef ZEND_ENGINE_2_1
-	zend_hash_destroy(&TG(auto_globals));
-#endif
-	zend_hash_destroy(TG(included_files));
-
-	/* restore orig here, as EG/CG holded tmp before */
-	memcpy(&EG(included_files), &OG(included_files), sizeof(EG(included_files)));
-
-#ifdef XCACHE_ERROR_CACHING
-	if (sandbox->compilererrors) {
-		zend_uint i;
-		for (i = 0; i < sandbox->compilererror_cnt; i ++) {
-			efree(sandbox->compilererrors[i].error);
-		}
-		efree(sandbox->compilererrors);
-	}
-#endif
-
-#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES
-	CG(compiler_options) = sandbox->orig_compiler_options;
-#endif
-}
-/* }}} */
-zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */
-{
-	xc_sandbox_t sandbox;
-	zend_op_array *op_array = NULL;
-	zend_bool catched = 0;
-
-	memset(&sandbox, 0, sizeof(sandbox));
-	zend_try {
-		xc_sandbox_init(&sandbox, filename TSRMLS_CC);
-		op_array = sandboxed_func(data TSRMLS_CC);
-	} zend_catch {
-		catched = 1;
-	} zend_end_try();
-
-	xc_sandbox_free(&sandbox, op_array TSRMLS_CC);
-	if (catched) {
-		zend_bailout();
-	}
-	return op_array;
-}
-/* {{{ */
-const Bucket *xc_sandbox_user_function_begin(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
-}
-/* {{{ */
-const Bucket *xc_sandbox_user_class_begin(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
-}
-/* {{{ */
-#ifdef XCACHE_ERROR_CACHING
-xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return sandbox->compilererrors;
-}
-/* }}} */
-zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D) /* {{{ */
-{
-	xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);
-	assert(sandbox);
-	return sandbox->compilererror_cnt;
-}
-/* }}} */
-#endif
-
-int xc_vtrace(const char *fmt, va_list args) /* {{{ */
-{
-	return vfprintf(stderr, fmt, args);
-}
-/* }}} */
-int xc_trace(const char *fmt, ...) /* {{{ */
-{
-	va_list args;
-	int ret;
-
-	va_start(args, fmt);
-	ret = xc_vtrace(fmt, args);
-	va_end(args);
-	return ret;
-}
-/* }}} */
-
-#ifndef ZEND_ENGINE_2_3
-#include "ext/standard/php_string.h"
-size_t xc_dirname(char *path, size_t len) /* {{{ */
-{
-#ifdef ZEND_ENGINE_2
-	return php_dirname(path, len);
-#else
-	php_dirname(path, len);
-	return strlen(path);
-#endif
-}
-/* }}} */
-
-long xc_atol(const char *str, int str_len) /* {{{ */
-{
-	long retval;
-
-	if (!str_len) {
-		str_len = strlen(str);
-	}
-
-	retval = strtol(str, NULL, 0);
-	if (str_len > 0) {
-		switch (str[str_len - 1]) {
-		case 'g':
-		case 'G':
-			retval *= 1024;
-			/* break intentionally missing */
-		case 'm':
-		case 'M':
-			retval *= 1024;
-			/* break intentionally missing */
-		case 'k':
-		case 'K':
-			retval *= 1024;
-			break;
-		}
-	}
-
-	return retval;
-}
-/* }}} */
-
-#endif
-
-/* init/destroy */
-int xc_util_init(int module_number TSRMLS_DC) /* {{{ */
-{
-#ifdef XCACHE_ERROR_CACHING
-	old_zend_error_cb = zend_error_cb;
-	zend_error_cb = xc_sandbox_error_cb;
-#endif
-
-	return SUCCESS;
-}
-/* }}} */
-void xc_util_destroy() /* {{{ */
-{
-#ifdef XCACHE_ERROR_CACHING
-	if (zend_error_cb == xc_sandbox_error_cb) {
-		zend_error_cb = old_zend_error_cb;
-	}
-#endif
-}
-/* }}} */
-
Index: /trunk/main/xc_utils.h
===================================================================
--- /trunk/main/xc_utils.h	(revision 985)
+++ /trunk/main/xc_utils.h	(revision 986)
@@ -41,15 +41,4 @@
 #endif
 
-/* return op_array to install */
-typedef zend_op_array *(*xc_sandboxed_func_t)(void *data TSRMLS_DC);
-zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC);
-const Bucket *xc_sandbox_user_function_begin(TSRMLS_D);
-const Bucket *xc_sandbox_user_class_begin(TSRMLS_D);
-zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
-#ifdef XCACHE_ERROR_CACHING
-xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D);
-zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D);
-#endif
-
 void xc_zend_class_add_ref(zend_class_entry ZESW(*ce, **ce));
 
Index: /trunk/xcache.c
===================================================================
--- /trunk/xcache.c	(revision 985)
+++ /trunk/xcache.c	(revision 986)
@@ -35,4 +35,5 @@
 #include "xc_opcode_spec.h"
 #include "xc_utils.h"
+#include "xc_sandbox.h"
 #include "util/xc_align.h"
 #include "util/xc_stack.h"
