diff --git a/Zend/Makefile.am b/Zend/Makefile.am
index 65c4113497ba5..cddcea47b1dfe 100644
--- a/Zend/Makefile.am
+++ b/Zend/Makefile.am
@@ -18,7 +18,7 @@ libZend_la_SOURCES=\
 	zend_default_classes.c \
 	zend_iterators.c zend_interfaces.c zend_exceptions.c \
 	zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
-	zend_generators.c zend_virtual_cwd.c zend_ast.c
+	zend_generators.c zend_autoload.c zend_virtual_cwd.c zend_ast.c
 
 libZend_la_LDFLAGS =
 libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
diff --git a/Zend/tests/bug61011.phpt b/Zend/tests/bug61011.phpt
index bce0e33209b3a..4efefc2ff5e21 100644
--- a/Zend/tests/bug61011.phpt
+++ b/Zend/tests/bug61011.phpt
@@ -5,7 +5,7 @@ Bug #61011 (Crash when an exception is thrown by __autoload accessing a static p
 function __autoload($name) {
 	throw new Exception($name);
 }
-try { 
+try {
 	echo AAA::$a; //zend_fetch_var_address_helper
 } catch (Exception $e) {
 	try {
diff --git a/Zend/tests/function_exists_error.phpt b/Zend/tests/function_exists_error.phpt
index cbc3908f12b30..f3f2f6f89cbde 100644
--- a/Zend/tests/function_exists_error.phpt
+++ b/Zend/tests/function_exists_error.phpt
@@ -3,7 +3,7 @@ Test function_exists() function : error conditions
 --FILE--
 <?php
 /* 
- * proto bool function_exists(string function_name)
+ * proto bool function_exists(string function_name [, boolean autoload = true])
  * Function is implemented in Zend/zend_builtin_functions.c
 */ 
 
@@ -13,7 +13,7 @@ $arg_0 = "ABC";
 $extra_arg = 1;
 
 echo "\nToo many arguments\n";
-var_dump(function_exists($arg_0, $extra_arg));
+var_dump(function_exists($arg_0, true, $extra_arg));
 
 echo "\nToo few arguments\n";
 var_dump(function_exists());
@@ -25,12 +25,12 @@ var_dump(function_exists());
 
 Too many arguments
 
-Warning: function_exists() expects exactly 1 parameter, 2 given in %s on line %d
+Warning: function_exists() expects at most 2 parameters, 3 given in %s on line %d
 NULL
 
 Too few arguments
 
-Warning: function_exists() expects exactly 1 parameter, 0 given in %s on line %d
+Warning: function_exists() expects at least 1 parameter, 0 given in %s on line %d
 NULL
 ===Done===
 
diff --git a/Zend/zend.c b/Zend/zend.c
index ad45028d4be85..bd71269cd4ef0 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -581,6 +581,8 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS
 #endif
 	EG(saved_fpu_cw_ptr) = NULL;
 	EG(active) = 0;
+	EG(autoload_legacy) = NULL;
+	EG(autoload_stack) = NULL;
 }
 /* }}} */
 
diff --git a/Zend/zend.h b/Zend/zend.h
index f60ef687f61cf..bd918226ec50e 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -599,6 +599,7 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
 #define IS_LEXICAL_VAR				0x020
 #define IS_LEXICAL_REF				0x040
 #define IS_CONSTANT_IN_NAMESPACE	0x100
+#define IS_CONSTANT_IN_AUTOLOAD		0x200
 
 #define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST)
 
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 3de56114387f1..68a7504f428b8 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -2770,7 +2770,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
 		}
 		/* Check if function with given name exists.
 		 * This may be a compound name that includes namespace name */
-		if (zend_hash_find(EG(function_table), lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) {
+		if (ZEND_LOOKUP_FUNCTION_BY_NAME(lmname, mlen, &fcc->function_handler)) {
 			efree(lmname);
 			return 1;
 		}
diff --git a/Zend/zend_autoload.c b/Zend/zend_autoload.c
new file mode 100644
index 0000000000000..5226769099947
--- /dev/null
+++ b/Zend/zend_autoload.c
@@ -0,0 +1,284 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.00 of the Zend license,     |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.zend.com/license/2_00.txt.                                |
+   | If you did not receive a copy of the Zend license and are unable to  |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@zend.com so we can mail you a copy immediately.              |
+   +----------------------------------------------------------------------+
+   | Authors: Anthony Ferrara <ircmaxell@php.net>                         |
+   | Authors: Joe Watkins <krakjoe@php.net>                               |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "zend.h"
+#include "zend_API.h"
+#include "zend_execute.h"
+#include "zend_globals.h"
+#include "zend_globals_macros.h"
+#include "zend_autoload.h"
+#include "zend_hash.h"
+#include "zend_execute.h"
+#include "zend_interfaces.h"
+#include "zend_exceptions.h"
+
+static char* zend_autoload_get_name_key(zend_fcall_info *fci, zend_fcall_info_cache *fcc, int *length, zend_bool *do_free TSRMLS_DC);
+static void zend_autoload_func_dtor(zend_autoload_func *func);
+
+int zend_autoload_call(const zval* name, long type TSRMLS_DC)
+{
+	zval *ztype, *retval = NULL;
+	char *lc_name;
+	int lc_length;
+	HashTable *symbol_table;
+	HashPosition function_pos;
+	zend_autoload_func *func_info;
+	char dummy = 1;
+
+	if (Z_TYPE_P(name) != IS_STRING) {
+		return FAILURE;
+	}
+
+	switch (type) {
+		case ZEND_AUTOLOAD_CLASS:
+			symbol_table = EG(class_table);
+			break;
+		case ZEND_AUTOLOAD_FUNCTION:
+			symbol_table = EG(function_table);
+			break;
+		case ZEND_AUTOLOAD_CONSTANT:
+			symbol_table = EG(zend_constants);
+			break;
+		default:
+			return FAILURE;
+	}
+
+	lc_length = Z_STRLEN_P(name);
+	lc_name = zend_str_tolower_dup(Z_STRVAL_P(name), lc_length);
+
+	/* run legacy autoloader */
+	{
+		zend_bool loaded = 0;
+		
+		if (EG(autoload_funcs) == NULL || EG(autoload_funcs)->nNumOfElements == 0) {
+			if (type == ZEND_AUTOLOAD_CLASS
+				&& (	
+					EG(autoload_legacy) != NULL
+					|| zend_lookup_function_ex(ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME), NULL, 0, &EG(autoload_legacy) TSRMLS_CC) == SUCCESS
+				)
+			) {
+				zend_call_method_with_1_params(NULL, NULL, &EG(autoload_legacy), ZEND_AUTOLOAD_FUNC_NAME, &retval, (zval*) name);
+				loaded = zend_hash_exists(
+					symbol_table, lc_name, lc_length + 1);
+				if (retval) {
+					zval_ptr_dtor(&retval);
+				}
+			}
+			efree(lc_name);
+			
+			return (loaded) ? SUCCESS : FAILURE;
+		}
+	}
+	
+	if (EG(autoload_stack) == NULL) {
+		ALLOC_HASHTABLE(EG(autoload_stack));
+		zend_hash_init(EG(autoload_stack), 0, NULL, NULL, 0);
+	}
+
+	if (zend_hash_add(EG(autoload_stack), lc_name, lc_length+1, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
+		efree(lc_name);
+		return FAILURE;
+	}
+
+	MAKE_STD_ZVAL(ztype);
+	ZVAL_LONG(ztype, type);
+
+	zend_hash_internal_pointer_reset_ex(EG(autoload_funcs), &function_pos);
+	while(zend_hash_has_more_elements_ex(EG(autoload_funcs), &function_pos) == SUCCESS) {
+		zend_hash_get_current_data_ex(EG(autoload_funcs), (void **) &func_info, &function_pos);
+		if (func_info->type & type) {
+			func_info->fci.retval_ptr_ptr = &retval;
+			zend_fcall_info_argn(&func_info->fci TSRMLS_CC, 2, &name, &ztype);
+			zend_call_function(&func_info->fci, &func_info->fcc TSRMLS_CC);
+			zend_exception_save(TSRMLS_C);
+			if (retval) {
+				zval_ptr_dtor(&retval);
+				retval = NULL;
+			}
+			if (zend_hash_exists(symbol_table, lc_name, lc_length + 1)) {
+				break;
+			}
+		}
+		zend_hash_move_forward_ex(EG(autoload_funcs), &function_pos);
+	}
+	zend_fcall_info_args_clear(&func_info->fci, 1);
+	zend_exception_restore(TSRMLS_C);
+
+	zval_ptr_dtor(&ztype);
+	zend_hash_del(EG(autoload_stack), lc_name, lc_length);
+	efree(lc_name);
+	return SUCCESS;
+}
+
+#define HT_MOVE_TAIL_TO_HEAD(ht)                            \
+    (ht)->pListTail->pListNext = (ht)->pListHead;           \
+    (ht)->pListHead = (ht)->pListTail;                      \
+    (ht)->pListTail = (ht)->pListHead->pListLast;           \
+    (ht)->pListHead->pListNext->pListLast = (ht)->pListHead;\
+    (ht)->pListTail->pListNext = NULL;                      \
+    (ht)->pListHead->pListLast = NULL;
+
+static char* zend_autoload_get_name_key(zend_fcall_info *fci, zend_fcall_info_cache *fcc, int *length, zend_bool *do_free TSRMLS_DC) {
+	char *name;
+	switch (Z_TYPE_P(fci->function_name)) {
+		case IS_STRING:
+			*length = Z_STRLEN_P(fci->function_name);
+			return Z_STRVAL_P(fci->function_name);
+			break;
+		case IS_OBJECT:
+			*length = sizeof(zend_object_handle);
+			name = emalloc(*length + 1);
+			*do_free = 1;
+			memcpy(name, &Z_OBJ_HANDLE_P(fci->function_name), *length);
+			name[*length] = '\0';
+			return name;
+			break;
+		case IS_ARRAY:
+			if (fcc->function_handler->common.scope) {
+				zend_function *func = fcc->function_handler;
+				zend_class_entry *ce = func->common.scope;
+				
+				*do_free = 1;
+				if (ce) {
+					*length = strlen(func->common.function_name) + ce->name_length + 2;
+					name = emalloc(*length + 1);
+					memcpy(name, ce->name, ce->name_length);
+					memcpy(&name[ce->name_length], "::", sizeof("::")-1);
+					memcpy(&name[ce->name_length+sizeof("::")-1], 
+						func->common.function_name, strlen(func->common.function_name));
+					name[*length] = 0;
+					return name;
+				}
+			}
+			break;
+		default:
+			return 0;
+	}
+	
+	return 0;
+}
+
+static void zend_autoload_func_dtor(zend_autoload_func *func) {
+	if (func->callable) {
+		zval_ptr_dtor(&func->callable);
+	}
+}
+
+int zend_autoload_register(zend_autoload_func *func, zend_bool prepend TSRMLS_DC)
+{
+	char *lc_name;
+	zend_bool do_free = 0;
+	int lc_length, status = SUCCESS;
+
+	lc_name = zend_autoload_get_name_key(&func->fci, &func->fcc, &lc_length, &do_free TSRMLS_CC);
+	if (lc_name == 0) {
+		zend_error_noreturn(E_ERROR, "Unknown Function Name Type Provided");
+	}
+
+	if (!EG(autoload_funcs)) {
+		ALLOC_HASHTABLE(EG(autoload_funcs));
+		zend_hash_init(EG(autoload_funcs), 1, NULL, (dtor_func_t) zend_autoload_func_dtor, 0);
+	} else if (zend_hash_exists(EG(autoload_funcs), lc_name, lc_length + 1)) {
+		if (do_free) {
+			efree(lc_name);
+		}
+		return FAILURE;
+	}
+
+	if (zend_hash_add(EG(autoload_funcs), lc_name, lc_length + 1, (void**) func, sizeof(zend_autoload_func), NULL) == FAILURE) {
+		status = FAILURE;
+	} else if (prepend) {
+		HT_MOVE_TAIL_TO_HEAD(EG(autoload_funcs));
+	}
+	if (do_free) {
+		efree(lc_name);
+	}
+	return status;
+}
+
+int zend_autoload_unregister(zval *callable TSRMLS_DC)
+{
+	zend_fcall_info fci;
+	zend_fcall_info_cache fcc;
+	char *lc_name;
+	zend_bool do_free = 0;
+	int lc_length;
+
+	if (zend_fcall_info_init(callable, 0, &fci, &fcc, NULL, NULL TSRMLS_CC) == FAILURE) {
+		return FAILURE;
+	}
+
+	lc_name = zend_autoload_get_name_key(&fci, &fcc, &lc_length, &do_free TSRMLS_CC);
+	if (lc_name == 0) {
+		return FAILURE;
+	}
+
+	zend_hash_del(EG(autoload_funcs), lc_name, lc_length);
+	if (do_free) {
+		efree(lc_name);
+	}
+
+	return SUCCESS;
+}
+
+ZEND_FUNCTION(autoload_register)
+{
+	zval *callable;
+	zend_autoload_func *func;
+	zend_bool prepend = 0;
+	long type = 0;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|lb", &callable, &type, &prepend) == FAILURE) {
+		return;
+	}
+
+	func = emalloc(sizeof(zend_autoload_func));
+
+	if (zend_fcall_info_init(callable, 0, &func->fci, &func->fcc, NULL, NULL TSRMLS_CC) == FAILURE) {
+		efree(func);
+		zend_error_noreturn(E_ERROR, "Expecting a valid callback");
+	}
+
+	func->callable = callable;
+	Z_ADDREF_P(callable);
+
+	if (!type) {
+		func->type = ZEND_AUTOLOAD_ALL;
+	} else {
+		func->type = type;
+	}
+
+	if (zend_autoload_register(func, prepend TSRMLS_CC) == FAILURE) {
+		zval_ptr_dtor(&callable);
+	}
+	efree(func);
+}
+
+ZEND_FUNCTION(autoload_unregister)
+{
+	zval *callable;
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callable) == FAILURE) {
+		return;
+	}
+	RETVAL_BOOL(zend_autoload_unregister(callable TSRMLS_CC) == SUCCESS);
+}
+
diff --git a/Zend/zend_autoload.h b/Zend/zend_autoload.h
new file mode 100644
index 0000000000000..de6134cda5ddc
--- /dev/null
+++ b/Zend/zend_autoload.h
@@ -0,0 +1,41 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.00 of the Zend license,     |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.zend.com/license/2_00.txt.                                |
+   | If you did not receive a copy of the Zend license and are unable to  |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@zend.com so we can mail you a copy immediately.              |
+   +----------------------------------------------------------------------+
+   | Authors: Anthony Ferrara <ircmaxell@php.net>                         |
+   | Authors: Joe Watkins <krakjoe@php.net>                               |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+#include "zend.h"
+#include "zend_API.h"
+   
+ZEND_FUNCTION(autoload_register);
+ZEND_FUNCTION(autoload_unregister);
+
+typedef struct {
+   zend_fcall_info fci;
+   zend_fcall_info_cache fcc;
+   zval *callable;
+   long type;
+} zend_autoload_func;
+
+int zend_autoload_call(const zval* name, long type TSRMLS_DC);
+int zend_autoload_register(zend_autoload_func* func, zend_bool prepend TSRMLS_DC);
+int zend_autoload_unregister(zval *callable TSRMLS_DC);
+
+#define ZEND_AUTOLOAD_CLASS    1
+#define ZEND_AUTOLOAD_FUNCTION 2
+#define ZEND_AUTOLOAD_CONSTANT 4
+#define ZEND_AUTOLOAD_ALL      (~0)
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 0a478a7532912..0e0f729596f14 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -22,6 +22,7 @@
 #include "zend.h"
 #include "zend_API.h"
 #include "zend_builtin_functions.h"
+#include "zend_autoload.h"
 #include "zend_constants.h"
 #include "zend_ini.h"
 #include "zend_exceptions.h"
@@ -238,6 +239,16 @@ ZEND_END_ARG_INFO()
 ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
 	ZEND_ARG_INFO(0, extension_name)
 ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_autoload_register, 0, 0, 1)
+	ZEND_ARG_INFO(0, callback)
+	ZEND_ARG_INFO(0, type)
+	ZEND_ARG_INFO(0, prepend)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_autoload_unregister, 0, 0, 1)
+	ZEND_ARG_INFO(0, callback)
+ZEND_END_ARG_INFO()
 /* }}} */
 
 static const zend_function_entry builtin_functions[] = { /* {{{ */
@@ -307,6 +318,8 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */
 	ZEND_FE(gc_enabled, 		arginfo_zend__void)
 	ZEND_FE(gc_enable, 			arginfo_zend__void)
 	ZEND_FE(gc_disable, 		arginfo_zend__void)
+	ZEND_NS_FE("php", autoload_register, arginfo_autoload_register)
+	ZEND_NS_FE("php", autoload_unregister, arginfo_autoload_unregister)
 	ZEND_FE_END
 };
 /* }}} */
@@ -316,7 +329,6 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */
 
 	INIT_CLASS_ENTRY(class_entry, "stdClass", NULL);
 	zend_standard_class_def = zend_register_internal_class(&class_entry TSRMLS_CC);
-
 	zend_register_default_classes(TSRMLS_C);
 
 	return SUCCESS;
@@ -1354,8 +1366,8 @@ ZEND_FUNCTION(trait_exists)
 /* }}} */
 
 
-/* {{{ proto bool function_exists(string function_name) 
-   Checks if the function exists */
+/* {{{ proto bool function_exists(string function_name [, boolean autoload = true]) 
+   Checks if the function exists, optionally and by default invoking autoloaders */
 ZEND_FUNCTION(function_exists)
 {
 	char *name;
@@ -1363,8 +1375,9 @@ ZEND_FUNCTION(function_exists)
 	zend_function *func;
 	char *lcname;
 	zend_bool retval;
+	zend_bool autoload = 1;
 	
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &name, &name_len, &autoload) == FAILURE) {
 		return;
 	}
 
@@ -1377,7 +1390,7 @@ ZEND_FUNCTION(function_exists)
 		name_len--;
 	}
 
-	retval = (zend_hash_find(EG(function_table), name, name_len+1, (void **)&func) == SUCCESS);
+	retval = (zend_lookup_function_ex(name, name_len+1, NULL, (int) autoload, &func TSRMLS_CC) == SUCCESS);
 	
 	efree(lcname);
 
@@ -1834,7 +1847,7 @@ ZEND_FUNCTION(create_function)
 	if (retval==SUCCESS) {
 		zend_function new_function, *func;
 
-		if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
+		if (zend_lookup_function_ex(LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), NULL, 0, &func TSRMLS_CC)==FAILURE) {
 			zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
 			RETURN_FALSE;
 		}
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index a53af497cc8d4..f5af3a370800e 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -20,6 +20,7 @@
 /* $Id$ */
 
 #include "zend.h"
+#include "zend_autoload.h"
 #include "zend_constants.h"
 #include "zend_execute.h"
 #include "zend_variables.h"
@@ -123,6 +124,13 @@ void zend_register_standard_constants(TSRMLS_D)
 		REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS);
 	}
 	REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT | CONST_CT_SUBST);
+
+	REGISTER_MAIN_LONG_CONSTANT(ZEND_NS_NAME("php", "AUTOLOAD_CLASS"), ZEND_AUTOLOAD_CLASS, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT(ZEND_NS_NAME("php", "AUTOLOAD_FUNCTION"), ZEND_AUTOLOAD_FUNCTION, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT(ZEND_NS_NAME("php", "AUTOLOAD_CONSTANT"), ZEND_AUTOLOAD_CONSTANT, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT(ZEND_NS_NAME("php", "AUTOLOAD_ALL"), ZEND_AUTOLOAD_ALL, CONST_CS | CONST_PERSISTENT);
+
+
 }
 
 
@@ -452,6 +460,9 @@ zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRM
 
 						key--;
 						if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
+							if (!(flags & IS_CONSTANT_IN_AUTOLOAD) && zend_autoload_call(&key->constant, ZEND_AUTOLOAD_CONSTANT TSRMLS_CC) == SUCCESS) {
+								return zend_quick_get_constant(key, flags | IS_CONSTANT_IN_AUTOLOAD TSRMLS_CC);
+							}
 							return NULL;
 						}
 					}
@@ -459,6 +470,9 @@ zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRM
 			} else {
 				key--;
 				if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
+					if (!(flags & IS_CONSTANT_IN_AUTOLOAD) && zend_autoload_call(&key->constant, ZEND_AUTOLOAD_CONSTANT TSRMLS_CC) == SUCCESS) {
+						return zend_quick_get_constant(key, flags | IS_CONSTANT_IN_AUTOLOAD TSRMLS_CC);
+					}
 					return NULL;
 				}
 			}
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 4802f0a19dde0..19b56e72aa7d4 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -63,6 +63,12 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, struct _zend
 ZEND_API int zend_is_true(zval *op TSRMLS_DC);
 ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
 ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
+ZEND_API int zend_lookup_function(const char *name, int name_length, zend_function **fbc TSRMLS_DC);
+ZEND_API int zend_lookup_function_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_function **fbc TSRMLS_DC);
+
+#define ZEND_LOOKUP_FUNCTION_BY_NAME(name, name_length, fbc) (zend_hash_find(EG(function_table), (name), (name_length) + 1, (void**) (fbc)) == SUCCESS || zend_lookup_function((name), (name_length), (fbc) TSRMLS_CC) == SUCCESS)
+#define ZEND_LOOKUP_FUNCTION_BY_LITERAL(name, name_length, literal, fbc) (zend_hash_quick_find(EG(function_table), (name), (name_length) + 1, Z_HASH_P(literal), (void**) (fbc)) == SUCCESS || zend_lookup_function_ex((name), (name_length), (zend_literal*) (literal), 1, (fbc) TSRMLS_CC) == SUCCESS)
+
 ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
 ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC);
 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 9c57300c84205..796f40be2c619 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -32,6 +32,7 @@
 #include "zend_exceptions.h"
 #include "zend_closures.h"
 #include "zend_generators.h"
+#include "zend_autoload.h"
 #include "zend_vm.h"
 #include "zend_float.h"
 #ifdef HAVE_SYS_TIME_H
@@ -151,8 +152,8 @@ void init_executor(TSRMLS_D) /* {{{ */
 	EG(class_table) = CG(class_table);
 
 	EG(in_execution) = 0;
-	EG(in_autoload) = NULL;
-	EG(autoload_func) = NULL;
+	EG(autoload_funcs) = NULL;
+	EG(autoload_stack) = NULL;
 	EG(error_handling) = EH_NORMAL;
 
 	zend_vm_stack_init(TSRMLS_C);
@@ -325,10 +326,27 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
 		zend_ptr_stack_destroy(&EG(user_error_handlers));
 		zend_ptr_stack_destroy(&EG(user_exception_handlers));
 		zend_objects_store_destroy(&EG(objects_store));
+		
+	} zend_end_try();
+	
+	zend_try {
+		/* shutdown autoload */
+		if (EG(autoload_stack)) {
+			zend_hash_destroy(EG(autoload_stack));
+			FREE_HASHTABLE(EG(autoload_stack));
+			EG(autoload_stack) = NULL;
+		}
+		if (EG(autoload_funcs)) {
+			zend_hash_destroy(EG(autoload_funcs));
+			FREE_HASHTABLE(EG(autoload_funcs));
+			EG(autoload_funcs) = NULL;
+		}
 		if (EG(in_autoload)) {
 			zend_hash_destroy(EG(in_autoload));
 			FREE_HASHTABLE(EG(in_autoload));
+			EG(in_autoload) = NULL;
 		}
+		EG(autoload_legacy) = NULL;
 	} zend_end_try();
 
 	zend_shutdown_fpu(TSRMLS_C);
@@ -1023,18 +1041,70 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
 }
 /* }}} */
 
+ZEND_API int zend_lookup_function(const char *name, int name_length, zend_function **fbc TSRMLS_DC) /* {{{ */
+{
+	return zend_lookup_function_ex(name, name_length, NULL, 1, fbc TSRMLS_CC);
+}
+
+ZEND_API int zend_lookup_function_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_function **fbc TSRMLS_DC)
+{
+	char *lc_name;
+	int lc_length;
+	int retval = FAILURE;
+	zend_ulong hash;
+	zval *function_name_ptr;
+
+
+	if (key) {
+		lc_name = Z_STRVAL(key->constant);
+		lc_length = Z_STRLEN(key->constant) + 1;
+		hash = key->hash_value;
+	} else {
+		if (name == NULL || !name_length) {
+			return FAILURE;
+		}
+		lc_name = name;
+		lc_length = name_length;
+		hash = zend_inline_hash_func(lc_name, lc_length);
+	}
+	
+	if (zend_hash_quick_find(EG(function_table), lc_name, lc_length, hash, (void **) fbc) == SUCCESS) {
+		return SUCCESS;
+	}
+
+	/* The compiler is not-reentrant. Make sure we __autoload_function() only during run-time
+	 * (doesn't impact functionality of __autoload_function()
+	*/
+	if (!use_autoload || zend_is_compiling(TSRMLS_C)) {
+		return FAILURE;
+	}
+
+	ALLOC_INIT_ZVAL(function_name_ptr);
+	if (name[0] == '\\') {
+		ZVAL_STRINGL(function_name_ptr, name+1, name_length-1, 1);
+	} else {
+		ZVAL_STRINGL(function_name_ptr, name, name_length, 1);
+	}
+	
+	if (zend_autoload_call(function_name_ptr, ZEND_AUTOLOAD_FUNCTION TSRMLS_CC) != SUCCESS) {
+		/* do something, or not */
+	}
+	
+	retval = zend_hash_quick_find(
+		EG(function_table), lc_name, lc_length, hash, (void **) fbc);
+	zval_ptr_dtor(&function_name_ptr);
+
+	return retval;
+
+}
+
 ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
 {
-	zval **args[1];
 	zval autoload_function;
 	zval *class_name_ptr;
-	zval *retval_ptr = NULL;
-	int retval, lc_length;
+	int lc_length, retval = FAILURE;
 	char *lc_name;
 	char *lc_free;
-	zend_fcall_info fcall_info;
-	zend_fcall_info_cache fcall_cache;
-	char dummy = 1;
 	ulong hash;
 	ALLOCA_FLAG(use_heap)
 
@@ -1083,18 +1153,24 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_
 		}
 		return FAILURE;
 	}
-	
+
 	if (EG(in_autoload) == NULL) {
 		ALLOC_HASHTABLE(EG(in_autoload));
 		zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0);
 	}
 
-	if (zend_hash_quick_add(EG(in_autoload), lc_name, lc_length, hash, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
-		if (!key) {
-			free_alloca(lc_free, use_heap);
+	
+	{	
+		char unused = 1;
+		
+		if (zend_hash_quick_add(EG(in_autoload), lc_name, lc_length, hash, (void**)&unused, sizeof(char), NULL) == FAILURE) {
+			if (!key) {
+				free_alloca(lc_free, use_heap);
+			}
+			return FAILURE;
 		}
-		return FAILURE;
 	}
+	
 
 	ZVAL_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1, 0);
 
@@ -1105,42 +1181,13 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_
 	} else {
 		ZVAL_STRINGL(class_name_ptr, name, name_length, 1);
 	}
-
-	args[0] = &class_name_ptr;
-
-	fcall_info.size = sizeof(fcall_info);
-	fcall_info.function_table = EG(function_table);
-	fcall_info.function_name = &autoload_function;
-	fcall_info.symbol_table = NULL;
-	fcall_info.retval_ptr_ptr = &retval_ptr;
-	fcall_info.param_count = 1;
-	fcall_info.params = args;
-	fcall_info.object_ptr = NULL;
-	fcall_info.no_separation = 1;
-
-	fcall_cache.initialized = EG(autoload_func) ? 1 : 0;
-	fcall_cache.function_handler = EG(autoload_func);
-	fcall_cache.calling_scope = NULL;
-	fcall_cache.called_scope = NULL;
-	fcall_cache.object_ptr = NULL;
-
-	zend_exception_save(TSRMLS_C);
-	retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC);
-	zend_exception_restore(TSRMLS_C);
-
-	EG(autoload_func) = fcall_cache.function_handler;
-
-	zval_ptr_dtor(&class_name_ptr);
-
-	zend_hash_quick_del(EG(in_autoload), lc_name, lc_length, hash);
-
-	if (retval_ptr) {
-		zval_ptr_dtor(&retval_ptr);
-	}
-
-	if (retval == SUCCESS) {
-		retval = zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce);
+	if (zend_autoload_call(class_name_ptr, ZEND_AUTOLOAD_CLASS TSRMLS_CC) == SUCCESS &&
+		zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce) == SUCCESS) {
+		retval = SUCCESS;
 	}
+	zval_ptr_dtor(&class_name_ptr);
+	zend_hash_del(EG(in_autoload), lc_name, lc_length);
+	
 	if (!key) {
 		free_alloca(lc_free, use_heap);
 	}
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 27d471fa069a7..04ce8b4a7109b 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -205,8 +205,11 @@ struct _zend_executor_globals {
 	int ticks_count;
 
 	zend_bool in_execution;
+	HashTable *autoload_stack;
+	HashTable *autoload_funcs;
 	HashTable *in_autoload;
-	zend_function *autoload_func;
+	zend_function *autoload_legacy;
+
 	zend_bool full_tables_cleanup;
 
 	/* for extended information support */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 58a7b33a0a3e7..7f9801f1d5efd 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2619,7 +2619,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
 		function_name = (zval*)(opline->op2.literal+1);
 		if (CACHED_PTR(opline->op2.literal->cache_slot)) {
 			call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
-		} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
+		} else if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), function_name, &call->fbc))) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		} else {
@@ -2648,7 +2648,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
 			} else {
 				lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
 			}
-			if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
+			if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_NAME(lcname, function_name_strlen, &call->fbc))) {
 				zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
 			}
 			efree(lcname);
@@ -2765,9 +2765,9 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
 	func_name = opline->op2.literal + 1;
 	if (CACHED_PTR(opline->op2.literal->cache_slot)) {
 		call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
-	} else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE) {
+	} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant) + 1, func_name->hash_value, (void**) &call->fbc) == FAILURE)) {
 		func_name++;
-		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE)) {
+		if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant), func_name, &call->fbc))) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		} else {
@@ -2799,7 +2799,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
 
 	if (CACHED_PTR(opline->op1.literal->cache_slot)) {
 		EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot);
-	} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(fname), Z_STRLEN_P(fname)+1, Z_HASH_P(fname), (void **) &EX(function_state).function)==FAILURE)) {
+	} else if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL_P(fname), Z_STRLEN_P(fname), fname, &EX(function_state).function))) {
 	    SAVE_OPLINE();
 		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
 	} else {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c0378dcbc06b8..bdbb8f4826e78 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1279,7 +1279,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
 		function_name = (zval*)(opline->op2.literal+1);
 		if (CACHED_PTR(opline->op2.literal->cache_slot)) {
 			call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
-		} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
+		} else if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), function_name, &call->fbc))) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		} else {
@@ -1308,7 +1308,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
 			} else {
 				lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
 			}
-			if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
+			if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_NAME(lcname, function_name_strlen, &call->fbc))) {
 				zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
 			}
 			efree(lcname);
@@ -1425,9 +1425,9 @@ static int ZEND_FASTCALL  ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPC
 	func_name = opline->op2.literal + 1;
 	if (CACHED_PTR(opline->op2.literal->cache_slot)) {
 		call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
-	} else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE) {
+	} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant) + 1, func_name->hash_value, (void**) &call->fbc) == FAILURE)) {
 		func_name++;
-		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE)) {
+		if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant), func_name, &call->fbc))) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		} else {
@@ -1603,7 +1603,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
 		function_name = (zval*)(opline->op2.literal+1);
 		if (CACHED_PTR(opline->op2.literal->cache_slot)) {
 			call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
-		} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
+		} else if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), function_name, &call->fbc))) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		} else {
@@ -1632,7 +1632,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
 			} else {
 				lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
 			}
-			if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
+			if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_NAME(lcname, function_name_strlen, &call->fbc))) {
 				zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
 			}
 			efree(lcname);
@@ -1790,7 +1790,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
 		function_name = (zval*)(opline->op2.literal+1);
 		if (CACHED_PTR(opline->op2.literal->cache_slot)) {
 			call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
-		} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
+		} else if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), function_name, &call->fbc))) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		} else {
@@ -1819,7 +1819,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
 			} else {
 				lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
 			}
-			if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
+			if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_NAME(lcname, function_name_strlen, &call->fbc))) {
 				zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
 			}
 			efree(lcname);
@@ -2015,7 +2015,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
 		function_name = (zval*)(opline->op2.literal+1);
 		if (CACHED_PTR(opline->op2.literal->cache_slot)) {
 			call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
-		} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
+		} else if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), function_name, &call->fbc))) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		} else {
@@ -2044,7 +2044,7 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
 			} else {
 				lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
 			}
-			if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
+			if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_NAME(lcname, function_name_strlen, &call->fbc))) {
 				zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
 			}
 			efree(lcname);
@@ -2369,7 +2369,7 @@ static int ZEND_FASTCALL  ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
 
 	if (CACHED_PTR(opline->op1.literal->cache_slot)) {
 		EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot);
-	} else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(fname), Z_STRLEN_P(fname)+1, Z_HASH_P(fname), (void **) &EX(function_state).function)==FAILURE)) {
+	} else if (UNEXPECTED(!ZEND_LOOKUP_FUNCTION_BY_LITERAL(Z_STRVAL_P(fname), Z_STRLEN_P(fname), fname, &EX(function_state).function))) {
 	    SAVE_OPLINE();
 		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
 	} else {
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index d334e45136643..ed02663c46c0c 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -171,4 +171,4 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
 #define ZEND_FAST_RET                        163
 #define ZEND_RECV_VARIADIC                   164
 
-#endif
\ No newline at end of file
+#endif
diff --git a/configure.in b/configure.in
index 8781cbc459546..389e443dfb592 100644
--- a/configure.in
+++ b/configure.in
@@ -171,7 +171,7 @@ if test -n "$with_apxs2filter" && test -n "$with_apxs2"; then
   AC_MSG_ERROR([--with-apxs2filter and --with-apxs2 cannot be used together])
 fi
 
-  
+
 dnl Settings we want to make before the checks.
 dnl -------------------------------------------------------------------------
 
@@ -697,7 +697,7 @@ dnl Check for getaddrinfo, should be a better way, but...
 dnl Also check for working getaddrinfo
 AC_CACHE_CHECK([for getaddrinfo], ac_cv_func_getaddrinfo,
 [AC_TRY_LINK([#include <netdb.h>],
-                [struct addrinfo *g,h;g=&h;getaddrinfo("","",g,&g);], 
+                [struct addrinfo *g,h;g=&h;getaddrinfo("","",g,&g);],
   AC_TRY_RUN([
 #include <netdb.h>
 #include <sys/types.h>
@@ -719,7 +719,7 @@ int main(void) {
   }
 
   pai = ai;
-  
+
   while (pai) {
     if (pai->ai_family != AF_INET) {
       /* 127.0.0.1/NUMERICHOST should only resolve ONE way */
@@ -776,7 +776,7 @@ if test "$PHP_GCOV" = "yes"; then
   if test "$GCC" != "yes"; then
     AC_MSG_ERROR([GCC is required for --enable-gcov])
   fi
-  
+
   dnl Check if ccache is being used
   case `$php_shtool path $CC` in
     *ccache*[)] gcc_ccache=yes;;
@@ -786,7 +786,7 @@ if test "$PHP_GCOV" = "yes"; then
   if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
     AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
   fi
-  
+
   ltp_version_list="1.5 1.6 1.7 1.9 1.10"
 
   AC_CHECK_PROG(LTP, lcov, lcov)
@@ -805,7 +805,7 @@ if test "$PHP_GCOV" = "yes"; then
       done
     ])
   else
-    ltp_msg="To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list"      
+    ltp_msg="To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list"
     AC_MSG_ERROR([$ltp_msg])
   fi
 
@@ -895,7 +895,7 @@ fi
 AC_MSG_CHECKING([where to scan for configuration files])
 PHP_ARG_WITH(config-file-scan-dir,,
 [  --with-config-file-scan-dir=PATH
-                          Set the path where to scan for configuration files], DEFAULT, no) 
+                          Set the path where to scan for configuration files], DEFAULT, no)
 if test "$PHP_CONFIG_FILE_SCAN_DIR" = "DEFAULT"; then
   PHP_CONFIG_FILE_SCAN_DIR=
 fi
@@ -993,7 +993,7 @@ dnl -------------------------------------------------------------------------
 PHP_HELP_SEPARATOR([Extensions:
 
   --with-EXTENSION=[shared[,PATH]]
-  
+
     NOTE: Not all extensions can be build as 'shared'.
 
     Example: --with-foobar=shared,/usr/local/foobar/
@@ -1080,13 +1080,13 @@ if test "$PHP_PEAR" != "no"; then
   dnl PEAR dependancies
   dnl
   if test "$PHP_XML" = "no"; then
-    pear_error_msg="$pear_error_msg 
+    pear_error_msg="$pear_error_msg
                     PEAR requires XML to be enabled.     Add --enable-xml to the configure line. (or --without-pear)"
   fi
 
 dnl
 dnl  if test "$PHP_XMLRPC" = "no"; then
-dnl    pear_error_msg="$pear_error_msg 
+dnl    pear_error_msg="$pear_error_msg
 dnl                    PEAR requires XML-RPC to be enabled. Add --with-xmlrpc to the configure line. (or --without-pear)"
 dnl  fi
 dnl
@@ -1199,7 +1199,7 @@ if test -z "$EXTENSION_DIR"; then
     if test "$enable_maintainer_zts" = "yes"; then
       extbasedir=$extbasedir-zts
     fi
-    
+
     if test "$PHP_DEBUG" = "1"; then
       extbasedir=$extbasedir-debug
     fi
@@ -1476,7 +1476,7 @@ PHP_ADD_SOURCES(Zend, \
     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
     zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
     zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c \
-    zend_virtual_cwd.c zend_ast.c)
+    zend_autoload.c zend_virtual_cwd.c zend_ast.c)
 
 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
   PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index 716990d80f02a..82017127c7d8a 100644
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -39,6 +39,7 @@
 #include "spl_heap.h"
 #include "zend_exceptions.h"
 #include "zend_interfaces.h"
+#include "zend_autoload.h"
 #include "ext/standard/php_rand.h"
 #include "ext/standard/php_lcg.h"
 #include "main/snprintf.h"
@@ -391,65 +392,20 @@ PHP_FUNCTION(spl_autoload_extensions)
 	}
 } /* }}} */
 
-typedef struct {
-	zend_function *func_ptr;
-	zval *obj;
-	zval *closure;
-	zend_class_entry *ce;
-} autoload_func_info;
-
-static void autoload_func_info_dtor(autoload_func_info *alfi)
-{
-	if (alfi->obj) {
-		zval_ptr_dtor(&alfi->obj);
-	}
-	if (alfi->closure) {
-		zval_ptr_dtor(&alfi->closure);
-	}
-}
-
 /* {{{ proto void spl_autoload_call(string class_name)
  Try all registerd autoload function to load the requested class */
 PHP_FUNCTION(spl_autoload_call)
 {
-	zval *class_name, *retval = NULL;
-	int class_name_len;
-	char *func_name, *lc_name;
-	uint func_name_len;
-	ulong dummy;
-	HashPosition function_pos;
-	autoload_func_info *alfi;
+	zval *class_name;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name) == FAILURE || Z_TYPE_P(class_name) != IS_STRING) {
 		return;
 	}
 
-	if (SPL_G(autoload_functions)) {
-		int l_autoload_running = SPL_G(autoload_running);
-		SPL_G(autoload_running) = 1;
-		class_name_len = Z_STRLEN_P(class_name);
-		lc_name = zend_str_tolower_dup(Z_STRVAL_P(class_name), class_name_len);
-		zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos);
-		while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS) {
-			zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &func_name_len, &dummy, 0, &function_pos);
-			zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi, &function_pos);
-			zend_call_method(alfi->obj ? &alfi->obj : NULL, alfi->ce, &alfi->func_ptr, func_name, func_name_len, &retval, 1, class_name, NULL TSRMLS_CC);
-			zend_exception_save(TSRMLS_C);
-			if (retval) {
-				zval_ptr_dtor(&retval);
-				retval = NULL;
-			}
-			if (zend_hash_exists(EG(class_table), lc_name, class_name_len + 1)) {
-				break;
-			}
-			zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos);
-		}
-		zend_exception_restore(TSRMLS_C);
-		efree(lc_name);
-		SPL_G(autoload_running) = l_autoload_running;
-	} else {
-		/* do not use or overwrite &EG(autoload_func) here */
+	if (EG(autoload_funcs) == NULL) {
 		zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload", NULL, class_name);
+	} else {
+		zend_autoload_call(class_name, ZEND_AUTOLOAD_CLASS TSRMLS_CC);
 	}
 } /* }}} */
 
@@ -465,160 +421,80 @@ PHP_FUNCTION(spl_autoload_call)
  Register given function as __autoload() implementation */
 PHP_FUNCTION(spl_autoload_register)
 {
-	char *func_name, *error = NULL;
-	int  func_name_len;
-	char *lc_name = NULL;
+	char *error = NULL;
 	zval *zcallable = NULL;
 	zend_bool do_throw = 1;
 	zend_bool prepend  = 0;
-	zend_function *spl_func_ptr;
-	autoload_func_info alfi;
-	zval *obj_ptr;
-	zend_fcall_info_cache fcc;
+	zend_autoload_func *func;
 
 	if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|zbb", &zcallable, &do_throw, &prepend) == FAILURE) {
 		return;
 	}
 
-	if (ZEND_NUM_ARGS()) {
-		if (Z_TYPE_P(zcallable) == IS_STRING) {
-			if (Z_STRLEN_P(zcallable) == sizeof("spl_autoload_call") - 1) {
-				if (!zend_binary_strcasecmp(Z_STRVAL_P(zcallable), sizeof("spl_autoload_call"), "spl_autoload_call", sizeof("spl_autoload_call"))) {
-					if (do_throw) {
-						zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function spl_autoload_call() cannot be registered");
-					}
-					RETURN_FALSE;
-				}
-			}
-		}
-	
-		if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_STRICT, &func_name, &func_name_len, &fcc, &error TSRMLS_CC)) {
-			alfi.ce = fcc.calling_scope;
-			alfi.func_ptr = fcc.function_handler;
-			obj_ptr = fcc.object_ptr;
-			if (Z_TYPE_P(zcallable) == IS_ARRAY) {
-				if (!obj_ptr && alfi.func_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
-					if (do_throw) {
-						zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array specifies a non static method but no object (%s)", error);
-					}
-					if (error) {
-						efree(error);
-					}
-					efree(func_name);
-					RETURN_FALSE;
-				}
-				else if (do_throw) {
-					zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array does not specify %s %smethod (%s)", alfi.func_ptr ? "a callable" : "an existing", !obj_ptr ? "static " : "", error);
-				}
-				if (error) {
-					efree(error);
-				}
-				efree(func_name);
-				RETURN_FALSE;
-			} else if (Z_TYPE_P(zcallable) == IS_STRING) {
-				if (do_throw) {
-					zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function '%s' not %s (%s)", func_name, alfi.func_ptr ? "callable" : "found", error);
-				}
-				if (error) {
-					efree(error);
-				}
-				efree(func_name);
-				RETURN_FALSE;
-			} else {
+	func = emalloc(sizeof(zend_autoload_func));
+	func->type = ZEND_AUTOLOAD_CLASS;
+
+	if (!ZEND_NUM_ARGS()) {
+		MAKE_STD_ZVAL(zcallable);
+		ZVAL_STRING(zcallable, "spl_autoload", 1);
+	}
+
+	if (zend_fcall_info_init(zcallable, IS_CALLABLE_STRICT, &func->fci, &func->fcc, NULL, &error TSRMLS_CC) == FAILURE) {
+		if (Z_TYPE_P(zcallable) == IS_ARRAY) {
+			if (!func->fcc.object_ptr && func->fcc.function_handler && !(func->fcc.function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
 				if (do_throw) {
-					zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Illegal value passed (%s)", error);
+					zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array specifies a non static method but no object (%s)", error);
 				}
+				efree(func);
 				if (error) {
 					efree(error);
 				}
-				efree(func_name);
 				RETURN_FALSE;
 			}
-		}
-		alfi.closure = NULL;
-		alfi.ce = fcc.calling_scope;
-		alfi.func_ptr = fcc.function_handler;
-		obj_ptr = fcc.object_ptr;
-		if (error) {
-			efree(error);
-		}
-	
-		lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1);
-		zend_str_tolower_copy(lc_name, func_name, func_name_len);
-		efree(func_name);
-
-		if (Z_TYPE_P(zcallable) == IS_OBJECT) {
-			alfi.closure = zcallable;
-			Z_ADDREF_P(zcallable);
-
-			lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
-			memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(zcallable),
-				sizeof(zend_object_handle));
-			func_name_len += sizeof(zend_object_handle);
-			lc_name[func_name_len] = '\0';
-		}
-
-		if (SPL_G(autoload_functions) && zend_hash_exists(SPL_G(autoload_functions), (char*)lc_name, func_name_len+1)) {
-			if (alfi.closure) {
-				Z_DELREF_P(zcallable);
+			else if (do_throw) {
+				zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array does not specify %s %smethod (%s)", func->fcc.function_handler ? "a callable" : "an existing", !func->fcc.object_ptr ? "static " : "", error);
 			}
-			goto skip;
-		}
-
-		if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
-			/* add object id to the hash to ensure uniqueness, for more reference look at bug #40091 */
-			lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
-			memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle));
-			func_name_len += sizeof(zend_object_handle);
-			lc_name[func_name_len] = '\0';
-			alfi.obj = obj_ptr;
-			Z_ADDREF_P(alfi.obj);
+			efree(func);
+			if (error) {
+				efree(error);
+			}
+			RETURN_FALSE;
+		} else if (Z_TYPE_P(zcallable) == IS_STRING) {
+			if (do_throw) {
+				zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function '%s' not %s (%s)", Z_STRVAL_P(zcallable), func->fcc.function_handler ? "callable" : "found", error);
+			}
+			efree(func);
+			if (error) {
+				efree(error);
+			}
+			RETURN_FALSE;
 		} else {
-			alfi.obj = NULL;
-		}
-
-		if (!SPL_G(autoload_functions)) {
-			ALLOC_HASHTABLE(SPL_G(autoload_functions));
-			zend_hash_init(SPL_G(autoload_functions), 1, NULL, (dtor_func_t) autoload_func_info_dtor, 0);
-		}
-
-		zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &spl_func_ptr);
-
-		if (EG(autoload_func) == spl_func_ptr) { /* registered already, so we insert that first */
-			autoload_func_info spl_alfi;
-
-			spl_alfi.func_ptr = spl_func_ptr;
-			spl_alfi.obj = NULL;
-			spl_alfi.ce = NULL;
-			spl_alfi.closure = NULL;
-			zend_hash_add(SPL_G(autoload_functions), "spl_autoload", sizeof("spl_autoload"), &spl_alfi, sizeof(autoload_func_info), NULL);
-			if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) {
-				/* Move the newly created element to the head of the hashtable */
-				HT_MOVE_TAIL_TO_HEAD(SPL_G(autoload_functions));
+			if (do_throw) {
+				zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Illegal value passed (%s)", error);
 			}
-		}
-
-		if (zend_hash_add(SPL_G(autoload_functions), lc_name, func_name_len+1, &alfi.func_ptr, sizeof(autoload_func_info), NULL) == FAILURE) {
-			if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
-				Z_DELREF_P(alfi.obj);
-			}				
-			if (alfi.closure) {
-				Z_DELREF_P(alfi.closure);
+			efree(func);
+			if (error) {
+				efree(error);
 			}
+			RETURN_FALSE;
 		}
-		if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) {
-			/* Move the newly created element to the head of the hashtable */
-			HT_MOVE_TAIL_TO_HEAD(SPL_G(autoload_functions));
-		}
-skip:
-		efree(lc_name);
+	}
+	func->callable = zcallable;
+	if (ZEND_NUM_ARGS()) {
+		Z_ADDREF_P(func->callable);
+	}
+	if (error) {
+		efree(error);
 	}
 
-	if (SPL_G(autoload_functions)) {
-		zend_hash_find(EG(function_table), "spl_autoload_call", sizeof("spl_autoload_call"), (void **) &EG(autoload_func));
-	} else {
-		zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &EG(autoload_func));
+	if (zend_autoload_register(func, prepend TSRMLS_CC) == FAILURE) {
+		if (ZEND_NUM_ARGS()) {
+			zval_ptr_dtor(&func->callable);
+		}
+		efree(func);
+		RETURN_FALSE;
 	}
+	efree(func);
 	RETURN_TRUE;
 } /* }}} */
 
@@ -628,11 +504,7 @@ PHP_FUNCTION(spl_autoload_unregister)
 {
 	char *func_name, *error = NULL;
 	int func_name_len;
-	char *lc_name = NULL;
 	zval *zcallable;
-	int success = FAILURE;
-	zend_function *spl_func_ptr;
-	zval *obj_ptr;
 	zend_fcall_info_cache fcc;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zcallable) == FAILURE) {
@@ -649,54 +521,11 @@ PHP_FUNCTION(spl_autoload_unregister)
 		}
 		RETURN_FALSE;
 	}
-	obj_ptr = fcc.object_ptr;
 	if (error) {
 		efree(error);
 	}
 
-	lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1);
-	zend_str_tolower_copy(lc_name, func_name, func_name_len);
-	efree(func_name);
-
-	if (Z_TYPE_P(zcallable) == IS_OBJECT) {
-		lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
-		memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(zcallable),
-			sizeof(zend_object_handle));
-		func_name_len += sizeof(zend_object_handle);
-		lc_name[func_name_len] = '\0';
-	}
-
-	if (SPL_G(autoload_functions)) {
-		if (func_name_len == sizeof("spl_autoload_call")-1 && !strcmp(lc_name, "spl_autoload_call")) {
-			/* remove all */
-			zend_hash_destroy(SPL_G(autoload_functions));
-			FREE_HASHTABLE(SPL_G(autoload_functions));
-			SPL_G(autoload_functions) = NULL;
-			EG(autoload_func) = NULL;
-			success = SUCCESS;
-		} else {
-			/* remove specific */
-			success = zend_hash_del(SPL_G(autoload_functions), lc_name, func_name_len+1);
-			if (success != SUCCESS && obj_ptr) {
-				lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
-				memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle));
-				func_name_len += sizeof(zend_object_handle);
-				lc_name[func_name_len] = '\0';
-				success = zend_hash_del(SPL_G(autoload_functions), lc_name, func_name_len+1);
-			}
-		}
-	} else if (func_name_len == sizeof("spl_autoload")-1 && !strcmp(lc_name, "spl_autoload")) {
-		/* register single spl_autoload() */
-		zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &spl_func_ptr);
-
-		if (EG(autoload_func) == spl_func_ptr) {
-			success = SUCCESS;
-			EG(autoload_func) = NULL;
-		}
-	}
-
-	efree(lc_name);
-	RETURN_BOOL(success == SUCCESS);
+	RETURN_BOOL(zend_autoload_unregister(zcallable TSRMLS_CC) == SUCCESS);
 } /* }}} */
 
 /* {{{ proto false|array spl_autoload_functions()
@@ -704,14 +533,12 @@ PHP_FUNCTION(spl_autoload_unregister)
 PHP_FUNCTION(spl_autoload_functions)
 {
 	zend_function *fptr;
-	HashPosition function_pos;
-	autoload_func_info *alfi;
 
 	if (zend_parse_parameters_none() == FAILURE) {
 		return;
 	}
 	
-	if (!EG(autoload_func)) {
+	if (!EG(autoload_funcs)) {
 		if (zend_hash_find(EG(function_table), ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME), (void **) &fptr) == SUCCESS) {
 			array_init(return_value);
 			add_next_index_stringl(return_value, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)-1, 1);
@@ -720,48 +547,8 @@ PHP_FUNCTION(spl_autoload_functions)
 		RETURN_FALSE;
 	}
 
-	zend_hash_find(EG(function_table), "spl_autoload_call", sizeof("spl_autoload_call"), (void **) &fptr);
-
-	if (EG(autoload_func) == fptr) {
-		array_init(return_value);
-		zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos);
-		while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS) {
-			zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi, &function_pos);
-			if (alfi->closure) {
-				Z_ADDREF_P(alfi->closure);
-				add_next_index_zval(return_value, alfi->closure);
-			} else if (alfi->func_ptr->common.scope) {
-				zval *tmp;
-				MAKE_STD_ZVAL(tmp);
-				array_init(tmp);
-
-				if (alfi->obj) {
-					Z_ADDREF_P(alfi->obj);
-					add_next_index_zval(tmp, alfi->obj);
-				} else {
-					add_next_index_string(tmp, alfi->ce->name, 1);
-				}
-				add_next_index_string(tmp, alfi->func_ptr->common.function_name, 1);
-				add_next_index_zval(return_value, tmp);
-			} else {
-				if (strncmp(alfi->func_ptr->common.function_name, "__lambda_func", sizeof("__lambda_func") - 1)) {
-					add_next_index_string(return_value, alfi->func_ptr->common.function_name, 1);
-				} else {
-				   char *key;
-				   uint len;
-				   long dummy;
-				   zend_hash_get_current_key_ex(SPL_G(autoload_functions), &key, &len, &dummy, 0, &function_pos); 
-				   add_next_index_stringl(return_value, key, len - 1, 1);
-				}
-			}
+	/* TODO: Update SPL Functions */
 
-			zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos);
-		}
-		return;
-	}
-
-	array_init(return_value);
-	add_next_index_string(return_value, EG(autoload_func)->common.function_name, 1);
 } /* }}} */
 
 /* {{{ proto string spl_object_hash(object obj)