diff options
author | Andi Gutmans <andi@php.net> | 1999-12-15 09:10:22 +0000 |
---|---|---|
committer | Andi Gutmans <andi@php.net> | 1999-12-15 09:10:22 +0000 |
commit | 4e1a9625c61098bdd209a9a6015f592485d15a91 (patch) | |
tree | 8db7cd385569282e7c40fd71a6e641c030443c29 | |
parent | 05f8c04928a53ad64f43ed78eddae684f513aefa (diff) | |
download | php-git-4e1a9625c61098bdd209a9a6015f592485d15a91.tar.gz |
- Preliminary return ref patch. It breaks libzend so don't use this branch
right now.
-rw-r--r-- | Zend/zend-parser.y | 16 | ||||
-rw-r--r-- | Zend/zend_compile.c | 8 | ||||
-rw-r--r-- | Zend/zend_compile.h | 8 | ||||
-rw-r--r-- | Zend/zend_execute.c | 5 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 2 |
5 files changed, 26 insertions, 13 deletions
diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y index 81e9408718..da95f04f97 100644 --- a/Zend/zend-parser.y +++ b/Zend/zend-parser.y @@ -179,9 +179,8 @@ statement: | T_BREAK expr ';' { do_brk_cont(ZEND_BRK, &$2 CLS_CC); } | T_CONTINUE ';' { do_brk_cont(ZEND_CONT, NULL CLS_CC); } | T_CONTINUE expr ';' { do_brk_cont(ZEND_CONT, &$2 CLS_CC); } - | T_RETURN ';' { do_return(NULL, 0 CLS_CC); } - | T_RETURN expr ';' { do_return(&$2, 0 CLS_CC); } - | T_RETURN '&' w_cvar ';' { do_return(&$3, 1 CLS_CC); } + | T_RETURN ';' { do_return(NULL CLS_CC); } + | T_RETURN expr ';' { do_return(&$2 CLS_CC); } | T_GLOBAL global_var_list | T_STATIC static_var_list | T_ECHO echo_expr_list ';' @@ -202,9 +201,9 @@ use_filename: declaration_statement: - T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } T_STRING { do_begin_function_declaration(&$1, &$3, 0 CLS_CC); } + T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 0, $3.op_type CLS_CC); } '(' parameter_list ')' '{' inner_statement_list '}' { do_end_function_declaration(&$1 CLS_CC); } - | T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } T_STRING { do_begin_function_declaration(&$1, &$3, 0 CLS_CC); } + | T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 0, $3.op_type CLS_CC); } parameter_list '(' inner_statement_list ')' ';' { do_end_function_declaration(&$1 CLS_CC); } | T_CLASS T_STRING { do_begin_class_declaration(&$2, NULL CLS_CC); } '{' class_statement_list '}' { do_end_class_declaration(CLS_C); } | T_CLASS T_STRING T_EXTENDS T_STRING { do_begin_class_declaration(&$2, &$4 CLS_CC); } '{' class_statement_list '}' { do_end_class_declaration(CLS_C); } @@ -348,13 +347,16 @@ class_statement_list: class_statement: T_VAR class_variable_decleration ';' - | T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } T_STRING { do_begin_function_declaration(&$1, &$3, 1 CLS_CC); } '(' + | T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 1, $3.op_type CLS_CC); } '(' parameter_list ')' '{' inner_statement_list '}' { do_end_function_declaration(&$1 CLS_CC); } - | T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } T_STRING { do_begin_function_declaration(&$1, &$3, 1 CLS_CC); } + | T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 1, $3.op_type CLS_CC); } parameter_list '(' inner_statement_list ')' ';' { do_end_function_declaration(&$1 CLS_CC); } ; +is_reference: + /* empty */ { $$.op_type = ZEND_RETURN_VAL; } + | '&' { $$.op_type = ZEND_RETURN_REF; } class_variable_decleration: class_variable_decleration ',' T_VARIABLE { do_declare_property(&$3, NULL CLS_CC); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9922466aa6..539bfaa613 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -667,7 +667,7 @@ void do_free(znode *op1 CLS_DC) } -void do_begin_function_declaration(znode *function_token, znode *function_name, int is_method CLS_DC) +void do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference CLS_DC) { zend_op_array op_array; char *name = function_name->u.constant.value.str.val; @@ -678,8 +678,10 @@ void do_begin_function_declaration(znode *function_token, znode *function_name, zend_str_tolower(name, name_len); init_op_array(&op_array, INITIAL_OP_ARRAY_SIZE); + op_array.function_name = name; op_array.arg_types = NULL; + op_array.return_reference = return_reference; if (is_method) { zend_hash_update(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)); @@ -948,7 +950,7 @@ static int generate_free_foreach_copy(znode *foreach_copy CLS_DC) return 0; } -void do_return(znode *expr, int return_reference CLS_DC) +void do_return(znode *expr CLS_DC) { zend_op *opline; @@ -963,7 +965,7 @@ void do_return(znode *expr, int return_reference CLS_DC) opline = get_next_op(CG(active_op_array) CLS_CC); opline->opcode = ZEND_RETURN; - opline->extended_value = return_reference; + if (expr) { opline->op1 = *expr; } else { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f8a1d6abdc..a026b2c4b0 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -115,6 +115,7 @@ struct _zend_op_array { int last_executed_op_number; int backpatch_count; #endif + zend_bool return_reference; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; @@ -260,14 +261,14 @@ void do_add_char(znode *result, znode *op1, znode *op2 CLS_DC); void do_add_string(znode *result, znode *op1, znode *op2 CLS_DC); void do_add_variable(znode *result, znode *op1, znode *op2 CLS_DC); -void do_begin_function_declaration(znode *function_token, znode *function_name, int is_method CLS_DC); +void do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference CLS_DC); void do_end_function_declaration(znode *function_token CLS_DC); void do_receive_arg(int op, znode *var, znode *offset, znode *initialization, unsigned char pass_type CLS_DC); int do_begin_function_call(znode *function_name CLS_DC); void do_begin_dynamic_function_call(znode *function_name CLS_DC); void do_begin_class_member_function_call(znode *class_name, znode *function_name CLS_DC); void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall CLS_DC); -void do_return(znode *expr, int return_reference CLS_DC); +void do_return(znode *expr CLS_DC); ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table, int compile_time); void do_early_binding(CLS_D); @@ -612,4 +613,7 @@ int zendlex(znode *zendlval CLS_DC); ) \ ) +#define ZEND_RETURN_VAL 0 +#define ZEND_RETURN_REF 1 + #endif /* _COMPILE_H */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 59918742ed..9ba08a857c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1549,7 +1549,10 @@ do_fcall_common: zval *retval_ptr; zval **retval_ptr_ptr; - if (opline->extended_value) { + if ((EG(active_op_array)->return_reference == ZEND_RETURN_REF) && + (opline->op1.op_type != IS_CONST) && + (opline->op1.op_type != IS_TMP_VAR)) { + retval_ptr_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R); if (!PZVAL_IS_REF(*retval_ptr_ptr)) { diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 5aa107305b..53d066ac09 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -99,6 +99,8 @@ void init_op_array(zend_op_array *op_array, int initial_ops_size) op_array->uses_globals = 0; + op_array->return_reference = 0; + zend_llist_apply_with_argument(&zend_extensions, (void (*)(void *, void *)) zend_extension_op_array_ctor_handler, op_array); } |