Skip to content

Commit aedbdb0

Browse files
committed
Allowed return by refrence from internal functions
1 parent 43aa692 commit aedbdb0

13 files changed

+18
-19
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? Jun 2005, PHP 5.1 Beta 2
4+
- Allowed return by refrence from internal functions. (Marcus, Andi, Dmitry)
45
- Added bindto socket context option. (Ilia)
56
- Rewrote strtotime() with support for timezones and tons of new formats.
67
(Derick)

Zend/zend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ char *alloca ();
247247
#include "zend_ts_hash.h"
248248
#include "zend_llist.h"
249249

250-
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval *this_ptr, int return_value_used TSRMLS_DC
251-
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, this_ptr, return_value_used TSRMLS_CC
250+
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
251+
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC
252252

253253
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(DARWIN)
254254
# define ZEND_VM_ALWAYS_INLINE __attribute__ ((always_inline))

Zend/zend_API.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ typedef struct _zend_function_entry {
6565
zend_arg_info name[] = { \
6666
{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
6767
#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \
68-
ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_REFERENCE_AGNOSTIC, -1)
68+
ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1)
6969
#define ZEND_END_ARG_INFO() };
7070

7171
/* Name macros */

Zend/zend_compile.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,12 +1855,8 @@ static zend_bool zend_do_perform_implementation_check(zend_function *fe, zend_fu
18551855
return 0;
18561856
}
18571857

1858-
if (proto->common.return_reference != ZEND_RETURN_REFERENCE_AGNOSTIC
1859-
&& fe->common.return_reference != proto->common.return_reference) {
1860-
/* atm we cannot let internal function return by ref */
1861-
if (fe->type == proto->type || fe->type != ZEND_INTERNAL_FUNCTION) {
1862-
return 0;
1863-
}
1858+
if (fe->common.return_reference != proto->common.return_reference) {
1859+
return 0;
18641860
}
18651861

18661862
for (i=0; i < proto->common.num_args; i++) {

Zend/zend_compile.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ struct _zend_op_array {
219219

220220
#define ZEND_RETURN_VALUE 0
221221
#define ZEND_RETURN_REFERENCE 1
222-
#define ZEND_RETURN_REFERENCE_AGNOSTIC 2
223222

224223
typedef struct _zend_internal_function {
225224
/* Common elements */

Zend/zend_execute.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,8 @@ ZEND_API opcode_handler_t *zend_opcode_handlers;
12911291

12921292
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
12931293
{
1294-
((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);
1294+
zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr;
1295+
((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);
12951296
}
12961297

12971298
#define ZEND_VM_NEXT_OPCODE() \

Zend/zend_execute_API.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
864864
if (EX(function_state).function->common.scope) {
865865
EG(scope) = EX(function_state).function->common.scope;
866866
}
867-
((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);
867+
((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);
868868
INIT_PZVAL(*fci->retval_ptr_ptr);
869869
}
870870
zend_ptr_stack_clear_multiple(TSRMLS_C);

Zend/zend_extensions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
/* The first number is the engine version and the rest is the date.
2828
* This way engine 2 API no. is always greater than engine 1 API no..
2929
*/
30-
#define ZEND_EXTENSION_API_NO 220050610
30+
#define ZEND_EXTENSION_API_NO 220050615
3131

3232
typedef struct _zend_extension_version_info {
3333
int zend_extension_api_no;

Zend/zend_modules.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extern struct _zend_arg_info third_arg_force_ref[4];
3838
extern struct _zend_arg_info fourth_arg_force_ref[5];
3939
extern struct _zend_arg_info all_args_by_ref[1];
4040

41-
#define ZEND_MODULE_API_NO 20041031
41+
#define ZEND_MODULE_API_NO 20050615
4242
#ifdef ZTS
4343
#define USING_ZTS 1
4444
#else

Zend/zend_object_handlers.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,8 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
658658
call_user_call->scope = zobj->ce;
659659
call_user_call->fn_flags = 0;
660660
call_user_call->function_name = estrndup(method_name, method_len);
661+
call_user_call->pass_rest_by_reference = 0;
662+
call_user_call->return_reference = ZEND_RETURN_VALUE;
661663

662664
return (union _zend_function *)call_user_call;
663665
} else {

Zend/zend_vm_def.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,7 +1830,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
18301830
}
18311831
if (!zend_execute_internal) {
18321832
/* saves one function call if zend_execute_internal is not used */
1833-
((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);
1833+
((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);
18341834
} else {
18351835
zend_execute_internal(EXECUTE_DATA, return_value_used TSRMLS_CC);
18361836
}
@@ -1890,7 +1890,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
18901890

18911891
/* Not sure what should be done here if it's a static method */
18921892
if (EX(object)) {
1893-
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);
1893+
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);
18941894
} else {
18951895
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
18961896
}

Zend/zend_vm_execute.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
181181
}
182182
if (!zend_execute_internal) {
183183
/* saves one function call if zend_execute_internal is not used */
184-
((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);
184+
((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);
185185
} else {
186186
zend_execute_internal(execute_data, return_value_used TSRMLS_CC);
187187
}
@@ -241,7 +241,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
241241

242242
/* Not sure what should be done here if it's a static method */
243243
if (EX(object)) {
244-
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);
244+
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);
245245
} else {
246246
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
247247
}

ext/spl/spl_iterators.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ SPL_METHOD(CachingRecursiveIterator, getChildren)
14991499
} /* }}} */
15001500

15011501
static
1502-
ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_REFERENCE_AGNOSTIC, 2)
1502+
ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_VALUE, 2)
15031503
ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0)
15041504
ZEND_ARG_INFO(0, flags)
15051505
ZEND_END_ARG_INFO();

0 commit comments

Comments
 (0)