Re: Re: #20993 [Ver]:Elementvaluechangeswithoutasking
| From: | Melvyn Sopacua | Date: | Sat, 21 Dec 2002 16:24:21 +0000 |
| Subject: | Re: Re: #20993 [Ver]:Elementvaluechangeswithoutasking | ||
| References: | 1 2 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-92747@lists.php.net to get a copy of this message | ||
At 17:16 18-12-2002, Moriyoshi Koizumi wrote:
>Melvyn Sopacua <msopacua@php.net> wrote:
>
>--snip
> > > > OK so that's a deep copy. As much as I understand the motivation I
> don't
> > > > think this should be done. It'll slow down lots of things in PHP. I
> think
> > > > this should be solved by documentation.
> > >
> > >Yes, according to my trivial benchmark, my patch puts a considerable
> > >weight on the ZendEngine, to run twice as slowly as the current runtime in
> > >the worst case. Seems no way, but I suppose it also sounds a reasonable
> > >penalty of using references.
> >
> > Actually - the natural 'feeling' with references is speed increases - not
> > slowdowns,
> > since one expects a 'pointer', rather than a copy.
> >
> > Is there a way to warn when such a refstatement is detected, without
> > causing slowdowns?
>
>Then try the new patch. It prints out notices in such cases.
Attached is a slightly revised version against PHP_4_3 branch - just an
'english'
fix.
If there are no objections, can somebody commit it?
I'll fix the test accordingly.
With kind regards,
Melvyn Sopacua
<?php include("not_reflecting_employers_views.txt"); ?>
Index: Zend/zend_execute.c =================================================================== RCS file: /repository/Zend/zend_execute.c,v retrieving revision 1.316.2.2 diff -u -r1.316.2.2 zend_execute.c --- Zend/zend_execute.c 17 Nov 2002 22:00:32 -0000 1.316.2.2 +++ Zend/zend_execute.c 21 Dec 2002 15:42:06 -0000 @@ -65,6 +65,7 @@ static void zend_extension_statement_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC); static void zend_extension_fcall_begin_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC); static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC); +static int check_array_contains_ref(zval **ppz); #define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED)) @@ -1816,6 +1817,9 @@ } else if (PZVAL_IS_REF(*param)) { zend_assign_to_variable_reference(NULL, get_zval_ptr_ptr(&EX(opline)->result, EX(Ts), BP_VAR_W), param, NULL TSRMLS_CC); } else { + if (check_array_contains_ref(param)) { + zend_error(E_NOTICE, "Array passed to %s() (argument #%d) contains referenced element(s) which may result in unexpected behavior.", get_active_function_name(TSRMLS_C), EX(opline)->op1.u.constant.value.lval); + } zend_assign_to_variable(NULL, &EX(opline)->result, NULL, *param, IS_VAR, EX(Ts) TSRMLS_CC); } } @@ -2480,4 +2484,23 @@ } } zend_error(E_ERROR, "Arrived at end of main loop which shouldn't happen"); +} + +static int _zval_ref_check(zval **p, void *flag) +{ + if ((*p)->is_ref) { + *(int *)flag = 1; + } else { + *(int *)flag = check_array_contains_ref(p); + } + return ZEND_HASH_APPLY_KEEP; +} + +static int check_array_contains_ref(zval **ppz) +{ + int flag = 0; + if ((*ppz)->type == IS_ARRAY) { + zend_hash_apply_with_argument((*ppz)->value.ht, (apply_func_arg_t) _zval_ref_check, (void *)&flag TSRMLS_CC); + } + return flag; }
Index: Zend/zend_execute.c =================================================================== RCS file: /repository/Zend/zend_execute.c,v retrieving revision 1.316.2.2 diff -u -r1.316.2.2 zend_execute.c --- Zend/zend_execute.c 17 Nov 2002 22:00:32 -0000 1.316.2.2 +++ Zend/zend_execute.c 21 Dec 2002 15:42:06 -0000 @@ -65,6 +65,7 @@ static void zend_extension_statement_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC); static void zend_extension_fcall_begin_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC); static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC); +static int check_array_contains_ref(zval **ppz); #define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED)) @@ -1816,6 +1817,9 @@ } else if (PZVAL_IS_REF(*param)) { zend_assign_to_variable_reference(NULL, get_zval_ptr_ptr(&EX(opline)->result, EX(Ts), BP_VAR_W), param, NULL TSRMLS_CC); } else { + if (check_array_contains_ref(param)) { + zend_error(E_NOTICE, "Array passed to %s() (argument #%d) contains referenced element(s) which may result in unexpected behavior.", get_active_function_name(TSRMLS_C), EX(opline)->op1.u.constant.value.lval); + } zend_assign_to_variable(NULL, &EX(opline)->result, NULL, *param, IS_VAR, EX(Ts) TSRMLS_CC); } } @@ -2480,4 +2484,23 @@ } } zend_error(E_ERROR, "Arrived at end of main loop which shouldn't happen"); +} + +static int _zval_ref_check(zval **p, void *flag) +{ + if ((*p)->is_ref) { + *(int *)flag = 1; + } else { + *(int *)flag = check_array_contains_ref(p); + } + return ZEND_HASH_APPLY_KEEP; +} + +static int check_array_contains_ref(zval **ppz) +{ + int flag = 0; + if ((*ppz)->type == IS_ARRAY) { + zend_hash_apply_with_argument((*ppz)->value.ht, (apply_func_arg_t) _zval_ref_check, (void *)&flag TSRMLS_CC); + } + return flag; }