]> granicus.if.org Git - php/commitdiff
Allowed return by refrence from internal functions
authorDmitry Stogov <dmitry@php.net>
Thu, 16 Jun 2005 14:56:13 +0000 (14:56 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 16 Jun 2005 14:56:13 +0000 (14:56 +0000)
13 files changed:
NEWS
Zend/zend.h
Zend/zend_API.h
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_extensions.h
Zend/zend_modules.h
Zend/zend_object_handlers.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/spl/spl_iterators.c

diff --git a/NEWS b/NEWS
index 934104396251029e29e269ff83760381056293c3..8e74bada9e1c1d74d935474161d7d2b05f91377d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? Jun 2005, PHP 5.1 Beta 2
+- Allowed return by refrence from internal functions. (Marcus, Andi, Dmitry)
 - Added bindto socket context option. (Ilia)
 - Rewrote strtotime() with support for timezones and tons of new formats.
   (Derick)
index 65a91f696d24468e17c04c63eada24d71c4fa059..eb06003029937609bc919b853209660031883efb 100644 (file)
@@ -247,8 +247,8 @@ char *alloca ();
 #include "zend_ts_hash.h"
 #include "zend_llist.h"
 
-#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval *this_ptr, int return_value_used TSRMLS_DC
-#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, this_ptr, return_value_used TSRMLS_CC
+#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
+#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC
 
 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(DARWIN)
 #  define ZEND_VM_ALWAYS_INLINE  __attribute__ ((always_inline))
index 9896e4f22f64218b7a5578ea101266d5bda1d976..06a29246b6e179ef625ed37b974a481057e0acd5 100644 (file)
@@ -65,7 +65,7 @@ typedef struct _zend_function_entry {
        zend_arg_info name[] = {                                                                                                                                                \
                { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
 #define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference)      \
-       ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_REFERENCE_AGNOSTIC, -1)
+       ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1)
 #define ZEND_END_ARG_INFO()            };
 
 /* Name macros */
index d569fa86088fb24663968ef8f7b2cf4bbe373d87..8d741604b22c6fff5d6d31f9e9f15e3bc8b5e5f3 100644 (file)
@@ -1855,12 +1855,8 @@ static zend_bool zend_do_perform_implementation_check(zend_function *fe, zend_fu
                return 0;
        }
 
-       if (proto->common.return_reference != ZEND_RETURN_REFERENCE_AGNOSTIC
-       && fe->common.return_reference != proto->common.return_reference) {
-               /* atm we cannot let internal function return by ref */
-               if (fe->type == proto->type || fe->type != ZEND_INTERNAL_FUNCTION) {
-                       return 0;
-               }
+       if (fe->common.return_reference != proto->common.return_reference) {
+               return 0;
        }
 
        for (i=0; i < proto->common.num_args; i++) {
index fe84bd3b3531a7f75b69acf3c0f58d5756da9ead..fe2bfe8163b63d330a33146c9c2785bac014618b 100644 (file)
@@ -219,7 +219,6 @@ struct _zend_op_array {
 
 #define ZEND_RETURN_VALUE                              0
 #define ZEND_RETURN_REFERENCE                  1
-#define ZEND_RETURN_REFERENCE_AGNOSTIC 2
 
 typedef struct _zend_internal_function {
        /* Common elements */
index 98547a1a1788417910754bad320e68d4a9b73429..9e79761f4f34fa6d8ffefebfece8a0f0d6f96c18 100644 (file)
@@ -1291,7 +1291,8 @@ ZEND_API opcode_handler_t *zend_opcode_handlers;
 
 ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
 {
-       ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr, execute_data_ptr->object, return_value_used TSRMLS_CC);
+       zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr;
+       ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, execute_data_ptr->function_state.function->common.return_reference?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC);
 }
 
 #define ZEND_VM_NEXT_OPCODE() \
index 597a89e2f23d7e8b5d5adcb80aab3de706795579..8c527ec591c70624c36927a7116a27a86c5672a8 100644 (file)
@@ -864,7 +864,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                if (EX(function_state).function->common.scope) {
                        EG(scope) = EX(function_state).function->common.scope;
                }
-               ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, (fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC);
+               ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, EX(function_state).function->common.return_reference?fci->retval_ptr_ptr:NULL, (fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC);
                INIT_PZVAL(*fci->retval_ptr_ptr);
        }
        zend_ptr_stack_clear_multiple(TSRMLS_C);
index a937430d88e17aa0d2f48f3d885a4289720e8243..19b091f48b899a3a08724ca8ec99774b5dd79a3a 100644 (file)
@@ -27,7 +27,7 @@
 /* The first number is the engine version and the rest is the date.
  * This way engine 2 API no. is always greater than engine 1 API no..
  */
-#define ZEND_EXTENSION_API_NO  220050610
+#define ZEND_EXTENSION_API_NO  220050615
 
 typedef struct _zend_extension_version_info {
        int zend_extension_api_no;
index ac2f0430c2b2ee67203b96a1ac48b59b478ab127..9223383fffff91ff1fe53f76b8f72c29fa0f24e4 100644 (file)
@@ -38,7 +38,7 @@ extern struct _zend_arg_info third_arg_force_ref[4];
 extern struct _zend_arg_info fourth_arg_force_ref[5];
 extern struct _zend_arg_info all_args_by_ref[1];
 
-#define ZEND_MODULE_API_NO 20041031
+#define ZEND_MODULE_API_NO 20050615
 #ifdef ZTS
 #define USING_ZTS 1
 #else
index dd86080e6d17c3315e2d7d175537d2f4b50fde3e..dd80e0d6ec4974a237f970f7b7e08b1f63c7d71a 100644 (file)
@@ -658,6 +658,8 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
                        call_user_call->scope = zobj->ce;
                        call_user_call->fn_flags = 0;
                        call_user_call->function_name = estrndup(method_name, method_len);
+                       call_user_call->pass_rest_by_reference = 0;
+                       call_user_call->return_reference = ZEND_RETURN_VALUE;
 
                        return (union _zend_function *)call_user_call;
                } else {
index 419098a6a354913d1ca6cfce8f29d552dc2523cb..03d983a1e8345c16a4aa741d2d8e486e85565ebe 100644 (file)
@@ -1830,7 +1830,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                }
                if (!zend_execute_internal) {
                        /* saves one function call if zend_execute_internal is not used */
-                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
+                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), return_value_used TSRMLS_CC);
                } else {
                        zend_execute_internal(EXECUTE_DATA, return_value_used TSRMLS_CC);
                }
@@ -1890,7 +1890,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
 
                        /* Not sure what should be done here if it's a static method */
                if (EX(object)) {
-                       Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
+                       Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
                } else {
                        zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
                }
index d91900a6f0e69c0b7bf8856318d075ce7b85adf5..44dd975743beaa36c75b5f37b0f44bd867771952 100644 (file)
@@ -181,7 +181,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                }
                if (!zend_execute_internal) {
                        /* saves one function call if zend_execute_internal is not used */
-                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
+                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), return_value_used TSRMLS_CC);
                } else {
                        zend_execute_internal(execute_data, return_value_used TSRMLS_CC);
                }
@@ -241,7 +241,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 
                        /* Not sure what should be done here if it's a static method */
                if (EX(object)) {
-                       Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
+                       Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
                } else {
                        zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
                }
index d8f672cc369fafabaf7ebb80286a23155a7db92b..71ad2fc9ee3a2a9ab243cb09d7fe95616f3e1694 100755 (executable)
@@ -1499,7 +1499,7 @@ SPL_METHOD(CachingRecursiveIterator, getChildren)
 } /* }}} */
 
 static
-ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_REFERENCE_AGNOSTIC, 2) 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_VALUE, 2) 
        ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0)
        ZEND_ARG_INFO(0, flags)
 ZEND_END_ARG_INFO();