From a8c1595012a59d5b4e8a8d0b90650f3075f02869 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 30 May 2014 22:33:03 +0200 Subject: [PATCH] LTR static member access --- Zend/tests/bug27669.phpt | 2 +- Zend/zend_compile.c | 74 ++++++++++--------------------------- Zend/zend_compile.h | 2 +- Zend/zend_language_parser.y | 18 +++++---- 4 files changed, 32 insertions(+), 64 deletions(-) diff --git a/Zend/tests/bug27669.phpt b/Zend/tests/bug27669.phpt index 4d513e91aa..43591a9386 100644 --- a/Zend/tests/bug27669.phpt +++ b/Zend/tests/bug27669.phpt @@ -10,7 +10,7 @@ Bug #27669 (PHP 5 didn't support all possibilities for calling static methods dy } } $y[0] = 'hello'; - A::$y[0](); + A::{$y[0]}(); ?> ===DONE=== --EXPECTF-- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 37649e7bb2..b6754d202b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -703,7 +703,7 @@ void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC) /* { } /* }}} */ -void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /* {{{ */ +void zend_do_fetch_static_member(znode *result, znode *class_name, znode *member_name TSRMLS_DC) /* {{{ */ { znode class_node; zend_llist *fetch_list_ptr; @@ -718,65 +718,29 @@ void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /* } else { zend_do_fetch_class(&class_node, class_name TSRMLS_CC); } + + zend_do_begin_variable_parse(TSRMLS_C); fetch_list_ptr = zend_stack_top(&CG(bp_stack)); - if (result->op_type == IS_CV) { - init_op(&opline TSRMLS_CC); + init_op(&opline TSRMLS_CC); - opline.opcode = ZEND_FETCH_W; - opline.result_type = IS_VAR; - opline.result.var = get_temporary_variable(CG(active_op_array)); - opline.op1_type = IS_CONST; - LITERAL_STR(opline.op1, STR_COPY(CG(active_op_array)->vars[EX_VAR_TO_NUM(result->u.op.var)])); + opline.opcode = ZEND_FETCH_W; + opline.result_type = IS_VAR; + opline.result.var = get_temporary_variable(CG(active_op_array)); + SET_NODE(opline.op1, member_name); + if (opline.op1_type == IS_CONST) { GET_POLYMORPHIC_CACHE_SLOT(opline.op1.constant); - if (class_node.op_type == IS_CONST) { - opline.op2_type = IS_CONST; - opline.op2.constant = - zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC); - } else { - SET_NODE(opline.op2, &class_node); - } - GET_NODE(result,opline.result); - opline.extended_value |= ZEND_FETCH_STATIC_MEMBER; - opline_ptr = &opline; - - zend_llist_add_element(fetch_list_ptr, &opline); + } + if (class_node.op_type == IS_CONST) { + opline.op2_type = IS_CONST; + opline.op2.constant = + zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC); } else { - le = fetch_list_ptr->head; - - opline_ptr = (zend_op *)le->data; - if (opline_ptr->opcode != ZEND_FETCH_W && opline_ptr->op1_type == IS_CV) { - init_op(&opline TSRMLS_CC); - opline.opcode = ZEND_FETCH_W; - opline.result_type = IS_VAR; - opline.result.var = get_temporary_variable(CG(active_op_array)); - opline.op1_type = IS_CONST; - LITERAL_STR(opline.op1, STR_COPY(CG(active_op_array)->vars[EX_VAR_TO_NUM(opline_ptr->op1.var)])); - GET_POLYMORPHIC_CACHE_SLOT(opline.op1.constant); - if (class_node.op_type == IS_CONST) { - opline.op2_type = IS_CONST; - opline.op2.constant = - zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC); - } else { - SET_NODE(opline.op2, &class_node); - } - opline.extended_value |= ZEND_FETCH_STATIC_MEMBER; - COPY_NODE(opline_ptr->op1, opline.result); - - zend_llist_prepend_element(fetch_list_ptr, &opline); - } else { - if (opline_ptr->op1_type == IS_CONST) { - GET_POLYMORPHIC_CACHE_SLOT(opline_ptr->op1.constant); - } - if (class_node.op_type == IS_CONST) { - opline_ptr->op2_type = IS_CONST; - opline_ptr->op2.constant = - zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC); - } else { - SET_NODE(opline_ptr->op2, &class_node); - } - opline_ptr->extended_value |= ZEND_FETCH_STATIC_MEMBER; - } + SET_NODE(opline.op2, &class_node); } + GET_NODE(result,opline.result); + opline.extended_value |= ZEND_FETCH_STATIC_MEMBER; + + zend_llist_add_element(fetch_list_ptr, &opline); } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 9f17b110d1..bb4142884d 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -464,7 +464,7 @@ void zend_do_fetch_global_variable(znode *varname, const znode *static_assignmen void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC); void fetch_array_dim(znode *result, znode *parent, znode *dim TSRMLS_DC); void fetch_string_offset(znode *result, znode *parent, znode *offset TSRMLS_DC); -void zend_do_fetch_static_member(znode *result, znode *class_znode TSRMLS_DC); +void zend_do_fetch_static_member(znode *result, znode *class_name, znode *member_name TSRMLS_DC); void zend_do_print(znode *result, znode *arg TSRMLS_DC); void zend_do_echo(znode *arg TSRMLS_DC); typedef int (*unary_op_type)(zval *, zval * TSRMLS_DC); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 08c3ffe7eb..d22d1c266d 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -898,13 +898,13 @@ function_call: function_call_parameter_list { zend_do_end_function_call(&$2, &$$, 0, $3.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); } | class_name T_PAAMAYIM_NEKUDOTAYIM variable_name { $$.u.op.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); } function_call_parameter_list { zend_do_end_function_call($4.u.op.opline_num?NULL:&$3, &$$, $4.u.op.opline_num, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} - | class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); } + | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { fetch_simple_variable_ex(&$$, &$3, 0, ZEND_FETCH_R TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$$ TSRMLS_CC); } function_call_parameter_list { zend_do_end_function_call(NULL, &$$, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_name { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); } function_call_parameter_list { zend_do_end_function_call(NULL, &$$, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} - | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); } + | variable_class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { fetch_simple_variable_ex(&$$, &$3, 0, ZEND_FETCH_R TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$$ TSRMLS_CC); } function_call_parameter_list { zend_do_end_function_call(NULL, &$$, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} - | variable_without_objects { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); } + | directly_callable_variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); } function_call_parameter_list { zend_do_end_function_call(&$1, &$$, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} ; @@ -1086,7 +1086,6 @@ variable: object_property { zend_do_push_object(&$4 TSRMLS_CC); } method_or_not { zend_do_pop_object(&$$ TSRMLS_CC); $$.EA = $6.EA; } | reference_variable { $$ = $1; $$.EA = ZEND_PARSED_VARIABLE; } - | static_member { $$ = $1; $$.EA = ZEND_PARSED_STATIC_MEMBER; } | array_function_dereference { $$ = $1; } | function_call { zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.EA = ZEND_PARSED_FUNCTION_CALL; } ; @@ -1116,8 +1115,8 @@ variable_without_objects: ; static_member: - class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $3; zend_do_fetch_static_member(&$$, &$1 TSRMLS_CC); } - | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $3; zend_do_fetch_static_member(&$$, &$1 TSRMLS_CC); } + class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { zend_do_fetch_static_member(&$$, &$1, &$3 TSRMLS_CC); } + | variable_class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { zend_do_fetch_static_member(&$$, &$1, &$3 TSRMLS_CC); } ; @@ -1131,12 +1130,17 @@ array_function_dereference: '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$4 TSRMLS_CC); } ; -reference_variable: +directly_callable_variable: reference_variable '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); } | reference_variable '{' expr '}' { fetch_string_offset(&$$, &$1, &$3 TSRMLS_CC); } | simple_variable { zend_do_begin_variable_parse(TSRMLS_C); fetch_simple_variable(&$$, &$1, 1 TSRMLS_CC); } ; +reference_variable: + directly_callable_variable { $$ = $1; } + | static_member { $$ = $1; } +; + simple_variable: T_VARIABLE { $$ = $1; } | '$' '{' expr '}' { $$ = $3; } -- 2.50.1