From: Zeev Suraski Date: Sun, 9 Mar 2003 20:53:57 +0000 (+0000) Subject: Fix parsing rules of namespaces/classes X-Git-Tag: RELEASE_0_5~543 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8bc88d8df4710e76492af41189bf2e458dd47534;p=php Fix parsing rules of namespaces/classes --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 04b25eddf9..738ca8045b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1205,7 +1205,7 @@ void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC) } -void do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRMLS_DC) +void zend_do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRMLS_DC) { long fetch_class_op_number; zend_op *opline; @@ -1215,7 +1215,9 @@ void do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRM opline->opcode = ZEND_FETCH_CLASS; if (namespace_name) { - zend_str_tolower(namespace_name->u.constant.value.str.val, namespace_name->u.constant.value.str.len); + if (namespace_name->op_type == IS_CONST) { + zend_str_tolower(namespace_name->u.constant.value.str.val, namespace_name->u.constant.value.str.len); + } opline->op1 = *namespace_name; } else { SET_UNUSED(opline->op1); @@ -1235,11 +1237,6 @@ void do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRM SET_UNUSED(opline->op2); opline->extended_value = ZEND_FETCH_CLASS_PARENT; zval_dtor(&class_name->u.constant); - } else if ((class_name->u.constant.value.str.len == (sizeof("main") - 1)) && - !memcmp(class_name->u.constant.value.str.val, "main", sizeof("main"))) { - SET_UNUSED(opline->op2); - opline->extended_value = ZEND_FETCH_CLASS_MAIN; - zval_dtor(&class_name->u.constant); } else { opline->op2 = *class_name; } @@ -1256,7 +1253,7 @@ void do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRM } -void do_fetch_class_name(znode *result, znode *class_name_entry, znode *class_name, zend_bool case_sensitive TSRMLS_DC) +void zend_do_fetch_class_name(znode *result, znode *class_name_entry, znode *class_name, zend_bool case_sensitive TSRMLS_DC) { zend_uint length; @@ -1277,15 +1274,15 @@ void do_fetch_class_name(znode *result, znode *class_name_entry, znode *class_na result->u.constant.value.str.len = length; } -void zend_do_begin_class_member_function_call(znode *class_name, znode *function_name TSRMLS_DC) +void zend_do_begin_class_member_function_call(TSRMLS_D) { unsigned char *ptr = NULL; - zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + long fetch_const_op_number = get_next_op_number(CG(active_op_array)); + zend_op *opline = &CG(active_op_array)->opcodes[fetch_const_op_number-1]; + /* a tmp var is leaked here */ opline->opcode = ZEND_INIT_STATIC_METHOD_CALL; - opline->op1 = *class_name; - zend_lowercase_znode_if_const(function_name); - opline->op2 = *function_name; + zend_lowercase_znode_if_const(&opline->op2); zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); } @@ -1294,16 +1291,6 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *function void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC) { zend_op *opline; - - if (is_method && function_name && function_name->u.constant.value.lval == ZEND_CLONE) { - if (argument_list->u.constant.value.lval > 0) { - zend_error(E_COMPILE_ERROR, "Can't pass arguments to __clone()"); - } - /* FIXME: throw_list */ - zend_stack_del_top(&CG(function_call_stack)); - *result = CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1].result; - return; - } opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -2523,7 +2510,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con switch (mode) { case ZEND_CT: if (constant_container) { - do_fetch_class_name(NULL, constant_container, constant_name, 1 TSRMLS_CC); + zend_do_fetch_class_name(NULL, constant_container, constant_name, 1 TSRMLS_CC); *result = *constant_container; } else { *result = *constant_name; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b4d49b2920..c539ab49b4 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -316,9 +316,9 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia int zend_do_begin_function_call(znode *function_name TSRMLS_DC); void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC); void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC); -void do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRMLS_DC); -void do_fetch_class_name(znode *result, znode *class_entry, znode *class_name, zend_bool case_sensitive TSRMLS_DC); -void zend_do_begin_class_member_function_call(znode *class_name, znode *function_name TSRMLS_DC); +void zend_do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRMLS_DC); +void zend_do_fetch_class_name(znode *result, znode *class_entry, znode *class_name, zend_bool case_sensitive TSRMLS_DC); +void zend_do_begin_class_member_function_call(TSRMLS_D); void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC); void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index b80ae3f8fe..95eb185912 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -454,8 +454,8 @@ non_empty_parameter_list: optional_class_type: /* empty */ { $$.op_type = IS_UNUSED; } - | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } - | T_STRING { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } + | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } + | T_STRING { zend_do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } ; function_call_parameter_list: @@ -640,34 +640,28 @@ function_call: T_STRING '(' { $2.u.opline_num = zend_do_begin_function_call(&$1 TSRMLS_CC); } function_call_parameter_list ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); } - | parse_class_entry static_or_variable_string '(' { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_class_member_function_call(&$1, &$2 TSRMLS_CC); } + | class_or_namespace_constant '(' { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_class_member_function_call(TSRMLS_C); } function_call_parameter_list - ')' { zend_do_end_function_call(&$2, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} + ')' { zend_do_end_function_call(NULL, &$$, &$4, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} | variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1 TSRMLS_CC); } function_call_parameter_list ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} ; -parse_class_entry: - T_NAMESPACE_NAME T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } - | static_or_variable_string T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } - | T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, NULL TSRMLS_CC); } -; - fully_qualified_class_name: - namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } - | T_PAAMAYIM_NEKUDOTAYIM T_STRING { do_fetch_class(&$$, NULL, &$2 TSRMLS_CC); } - | T_STRING { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } + namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } + | T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$$, NULL, &$2 TSRMLS_CC); } + | T_STRING { zend_do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } ; import_namespace: - T_NAMESPACE_NAME { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } - | T_STRING { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } + T_NAMESPACE_NAME { zend_do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } + | T_STRING { zend_do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } ; new_class_entry: - namespace_name T_PAAMAYIM_NEKUDOTAYIM static_or_variable_string { do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } - | static_or_variable_string { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } + namespace_name T_PAAMAYIM_NEKUDOTAYIM static_or_variable_string { zend_do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } + | static_or_variable_string { zend_do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } ; namespace_name: @@ -681,8 +675,8 @@ static_or_variable_string: ; instanceof_expr: - namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } - | T_STRING { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } + namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } + | T_STRING { zend_do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } ; exit_expr: @@ -715,14 +709,14 @@ static_scalar: /* compile-time evaluated scalars */ | '+' static_scalar { $$ = $2; } | '-' static_scalar { zval minus_one; minus_one.type = IS_LONG; minus_one.value.lval = -1; mul_function(&$2.u.constant, &$2.u.constant, &minus_one TSRMLS_CC); $$ = $2; } | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; $$.u.constant.type = IS_CONSTANT_ARRAY; } - | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_CT TSRMLS_CC); } + | class_or_namespace_constant { /* FIXME */ } ; scalar: T_STRING { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT TSRMLS_CC); } | T_STRING_VARNAME { $$ = $1; } - | parse_class_entry T_STRING { zend_do_fetch_constant(&$$, &$1, &$2, ZEND_RT TSRMLS_CC); } + | class_or_namespace_constant { $$ = $1; } | common_scalar { $$ = $1; } | '"' encaps_list '"' { $$ = $2; } | '\'' encaps_list '\'' { $$ = $2; } @@ -804,7 +798,9 @@ variable_without_objects: ; static_member: - parse_class_entry variable_without_objects { $$ = $2; zend_do_fetch_static_member(&$1 TSRMLS_CC); } + T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $4; zend_do_fetch_class(&$1, NULL, &$2 TSRMLS_CC); zend_do_fetch_static_member(&$1 TSRMLS_CC); } + | namespace_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $3; zend_do_fetch_class(&$2, NULL, &$1 TSRMLS_CC); zend_do_fetch_static_member(&$2 TSRMLS_CC); } + | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $5; zend_do_fetch_class(&$4, &$1, &$3 TSRMLS_CC); zend_do_fetch_static_member(&$4 TSRMLS_CC); } ; @@ -933,6 +929,13 @@ isset_variables: | isset_variables ',' { zend_do_boolean_and_begin(&$1, &$2 TSRMLS_CC); } variable { znode tmp; zend_do_isset_or_isempty(ZEND_ISSET, &tmp, &$4 TSRMLS_CC); zend_do_boolean_and_end(&$$, &$1, &tmp, &$2 TSRMLS_CC); } ; +class_or_namespace_constant: + T_PAAMAYIM_NEKUDOTAYIM namespace_name { zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT TSRMLS_CC); } + | T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$1, NULL, &$2 TSRMLS_CC); zend_do_fetch_constant(&$$, &$1, &$4, ZEND_RT TSRMLS_CC); } + | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$2, NULL, &$1 TSRMLS_CC); zend_do_fetch_constant(&$$, &$2, &$3, ZEND_RT TSRMLS_CC); } + | namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$4, &$1, &$3 TSRMLS_CC); zend_do_fetch_constant(&$$, &$4, &$5, ZEND_RT TSRMLS_CC); } +; + %% /*