summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2004-10-05 18:36:46 +0000
committerMarcus Boerger <helly@php.net>2004-10-05 18:36:46 +0000
commitf916d603efc4749895c49e1c3d6c9cc05044d1b8 (patch)
tree9bd9f0dea1edc6f606c0b828eb20e3b9dd75485a
parentfb6072e10dac347cdcdeae3827cbcd46bd0b642a (diff)
downloadphp-git-f916d603efc4749895c49e1c3d6c9cc05044d1b8.tar.gz
- Add arginfo ZEND_ARG_SEND_AUTOMATIC which lets the compiler automatically
determine whether pass by ref is possible or pass by value is needed. # This is usefull when functions take array or string parameters as # expressions. In such a case force by ref is not applicable and the # executor would copy the variable unnecessarily as soon as it is at least # once referenced.
-rw-r--r--Zend/zend_compile.c8
-rw-r--r--Zend/zend_compile.h14
-rw-r--r--Zend/zend_vm_handlers.h2
3 files changed, 18 insertions, 6 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 2f34969a02..dccafb7741 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1454,7 +1454,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC)
}
if (function_ptr) {
- send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0;
+ send_by_reference = ARG_SEND_TYPE(function_ptr, (zend_uint) offset);
} else {
send_by_reference = 0;
}
@@ -1466,7 +1466,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC)
op = ZEND_SEND_VAR_NO_REF;
}
- if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference==ZEND_ARG_SEND_BY_REF) {
+ if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference!=0) {
/* change to passing by reference */
switch (param->op_type) {
case IS_VAR:
@@ -1474,7 +1474,9 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC)
op = ZEND_SEND_REF;
break;
default:
- zend_error(E_COMPILE_ERROR, "Only variables can be passed by reference");
+ if (send_by_reference==ZEND_ARG_SEND_BY_REF) {
+ zend_error(E_COMPILE_ERROR, "Only variables can be passed by reference");
+ }
break;
}
}
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 3fab70f746..e99c866ffe 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -812,6 +812,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_ARG_SEND_BY_REF (1<<0)
#define ZEND_ARG_COMPILE_TIME_BOUND (1<<1)
+#define ZEND_ARG_SEND_AUTOMATIC (1<<2)
/* Lost In Stupid Parentheses */
#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
@@ -822,15 +823,24 @@ int zendlex(znode *zendlval TSRMLS_DC);
( \
( \
arg_num<=((zend_function *) zf)->common.num_args \
- && ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference \
+ && ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference == ZEND_ARG_SEND_BY_REF \
) \
|| ( \
arg_num>((zend_function *) zf)->common.num_args \
- && ((zend_function *) zf)->common.pass_rest_by_reference \
+ && ((zend_function *) zf)->common.pass_rest_by_reference == ZEND_ARG_SEND_BY_REF \
) \
) \
)
+#define ARG_SEND_TYPE(zf, arg_num) \
+ ( \
+ !zf || !((zend_function *) zf)->common.arg_info \
+ ? 0 \
+ : ( arg_num<=((zend_function *) zf)->common.num_args \
+ ? ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference \
+ : ((zend_function *) zf)->common.pass_rest_by_reference \
+ ) \
+ )
#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1
diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h
index 0f2c312f12..04b2af5bcf 100644
--- a/Zend/zend_vm_handlers.h
+++ b/Zend/zend_vm_handlers.h
@@ -2550,7 +2550,7 @@ ZEND_VM_HANDLER(ZEND_SEND_VAR_NO_REF)
{
zend_op *opline = EX(opline);
if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
- if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
+ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF) && !(opline->extended_value & ZEND_ARG_SEND_AUTOMATIC)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}
} else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {