summaryrefslogtreecommitdiff
path: root/ext/spl/php_spl.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl/php_spl.c')
-rw-r--r--ext/spl/php_spl.c82
1 files changed, 65 insertions, 17 deletions
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index 8db63910cb..1097a72e98 100644
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -184,7 +184,6 @@ PHP_FUNCTION(class_uses)
SPL_ADD_CLASS(BadMethodCallException, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(CallbackFilterIterator, z_list, sub, allow, ce_flags); \
- SPL_ADD_CLASS(Countable, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(DomainException, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(EmptyIterator, z_list, sub, allow, ce_flags); \
@@ -392,7 +391,7 @@ static void autoload_func_info_dtor(zval *element)
Try all registerd autoload function to load the requested class */
PHP_FUNCTION(spl_autoload_call)
{
- zval *class_name, *retval = NULL;
+ zval *class_name, retval;
zend_string *lc_name, *func_name;
autoload_func_info *alfi;
@@ -403,34 +402,64 @@ PHP_FUNCTION(spl_autoload_call)
if (SPL_G(autoload_functions)) {
HashPosition pos;
zend_ulong num_idx;
+ zend_function *func;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcic;
+ zend_class_entry *called_scope = zend_get_called_scope(execute_data);
int l_autoload_running = SPL_G(autoload_running);
+
SPL_G(autoload_running) = 1;
- lc_name = zend_string_alloc(Z_STRLEN_P(class_name), 0);
- zend_str_tolower_copy(ZSTR_VAL(lc_name), Z_STRVAL_P(class_name), Z_STRLEN_P(class_name));
+ lc_name = zend_string_tolower(Z_STR_P(class_name));
+
+ fci.size = sizeof(fci);
+ fci.retval = &retval;
+ fci.param_count = 1;
+ fci.params = class_name;
+ fci.no_separation = 1;
+
+ ZVAL_UNDEF(&fci.function_name); /* Unused */
+ fcic.initialized = 1;
+
zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &pos);
while (zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &num_idx, &pos) == HASH_KEY_IS_STRING) {
alfi = zend_hash_get_current_data_ptr_ex(SPL_G(autoload_functions), &pos);
- if (UNEXPECTED(alfi->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
- zend_function *copy = emalloc(sizeof(zend_op_array));
-
- memcpy(copy, alfi->func_ptr, sizeof(zend_op_array));
- copy->op_array.function_name = zend_string_copy(alfi->func_ptr->op_array.function_name);
- zend_call_method(Z_ISUNDEF(alfi->obj)? NULL : &alfi->obj, alfi->ce, &copy, ZSTR_VAL(func_name), ZSTR_LEN(func_name), retval, 1, class_name, NULL);
+ func = alfi->func_ptr;
+ if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+ func = emalloc(sizeof(zend_op_array));
+ memcpy(func, alfi->func_ptr, sizeof(zend_op_array));
+ zend_string_addref(func->op_array.function_name);
+ }
+ ZVAL_UNDEF(&retval);
+ fcic.function_handler = func;
+ if (Z_ISUNDEF(alfi->obj)) {
+ fci.object = NULL;
+ fcic.object = NULL;
+ fcic.calling_scope = alfi->ce;
+ if (alfi->ce &&
+ (!called_scope ||
+ !instanceof_function(called_scope, alfi->ce))) {
+ fcic.called_scope = alfi->ce;
+ } else {
+ fcic.called_scope = called_scope;
+ }
} else {
- zend_call_method(Z_ISUNDEF(alfi->obj)? NULL : &alfi->obj, alfi->ce, &alfi->func_ptr, ZSTR_VAL(func_name), ZSTR_LEN(func_name), retval, 1, class_name, NULL);
+ fci.object = Z_OBJ(alfi->obj);
+ fcic.object = Z_OBJ(alfi->obj);
+ fcic.called_scope = Z_OBJCE(alfi->obj);
}
+
+ zend_call_function(&fci, &fcic);
+
zend_exception_save();
- if (retval) {
- zval_ptr_dtor(retval);
- retval = NULL;
- }
- if (zend_hash_exists(EG(class_table), lc_name)) {
+ zval_ptr_dtor(&retval);
+ if (pos + 1 == SPL_G(autoload_functions)->nNumUsed ||
+ zend_hash_exists(EG(class_table), lc_name)) {
break;
}
zend_hash_move_forward_ex(SPL_G(autoload_functions), &pos);
}
zend_exception_restore();
- zend_string_free(lc_name);
+ zend_string_release(lc_name);
SPL_G(autoload_running) = l_autoload_running;
} else {
/* do not use or overwrite &EG(autoload_func) here */
@@ -777,6 +806,20 @@ PHP_FUNCTION(spl_object_hash)
}
/* }}} */
+/* {{{ proto int spl_object_id(object obj)
+ Returns the integer object handle for the given object */
+PHP_FUNCTION(spl_object_id)
+{
+ zval *obj;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJECT(obj)
+ ZEND_PARSE_PARAMETERS_END();
+
+ RETURN_LONG((zend_long)Z_OBJ_HANDLE_P(obj));
+}
+/* }}} */
+
PHPAPI zend_string *php_spl_object_hash(zval *obj) /* {{{*/
{
intptr_t hash_handle, hash_handlers;
@@ -898,6 +941,10 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_object_hash, 0, 0, 1)
ZEND_ARG_INFO(0, obj)
ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_object_id, 0, 0, 1)
+ ZEND_ARG_INFO(0, obj)
+ZEND_END_ARG_INFO()
/* }}} */
/* {{{ spl_functions
@@ -914,6 +961,7 @@ const zend_function_entry spl_functions[] = {
PHP_FE(class_implements, arginfo_class_implements)
PHP_FE(class_uses, arginfo_class_uses)
PHP_FE(spl_object_hash, arginfo_spl_object_hash)
+ PHP_FE(spl_object_id, arginfo_spl_object_id)
#ifdef SPL_ITERATORS_H
PHP_FE(iterator_to_array, arginfo_iterator_to_array)
PHP_FE(iterator_count, arginfo_iterator)