]> granicus.if.org Git - php/commitdiff
- Preliminary patch for method() dereferencing
authorAndi Gutmans <andi@php.net>
Wed, 8 Aug 2001 15:07:11 +0000 (15:07 +0000)
committerAndi Gutmans <andi@php.net>
Wed, 8 Aug 2001 15:07:11 +0000 (15:07 +0000)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y

index b34e6ff93a25c00fa293c2b203e772a7063862d3..c0f068a4099d2a1526691098b3f111d61460c794 100644 (file)
@@ -508,6 +508,15 @@ void zend_do_if_end(TSRMLS_D)
 }
 
 
+zend_bool zend_variable_buffer_empty(TSRMLS_D)
+{
+       zend_llist *fetch_list_ptr;
+
+       zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
+       return !fetch_list_ptr->head;
+}
+
+
 void zend_do_begin_variable_parse(TSRMLS_D)
 {
        zend_llist fetch_list;
@@ -561,27 +570,6 @@ void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC)
 }
 
 
-static zend_bool is_method_call(TSRMLS_D)
-{
-       zend_llist *fetch_list_ptr;
-       zend_llist_element *cur;
-       zend_op *cur_opline;
-
-       zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
-
-       cur = fetch_list_ptr->head;
-       /* There is always at least one node in the list */
-       while (cur->next) {
-               cur = cur->next;
-       }
-       cur_opline = (zend_op *)cur->data;
-       if (cur_opline->opcode == ZEND_FETCH_OBJ_W) {
-               return 1;
-       }
-       return 0;
-}
-
-
 void zend_do_init_string(znode *result TSRMLS_DC)
 {
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
@@ -837,31 +825,47 @@ int zend_do_begin_function_call(znode *function_name TSRMLS_DC)
 }
 
 
-void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC)
+
+void zend_do_begin_method_call(znode *object, znode *function_name TSRMLS_DC)
 {
+       zend_op *opline;
        unsigned char *ptr = NULL;
-       int last_op_number;
-       zend_op *last_op;
 
-       if (function_name->op_type != IS_CONST && is_method_call(TSRMLS_C)) {
-               zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
-               last_op_number = get_next_op_number(CG(active_op_array))-1;
-               last_op = &CG(active_op_array)->opcodes[last_op_number];
-               last_op->opcode = ZEND_INIT_FCALL_BY_NAME;
-               last_op->extended_value = ZEND_MEMBER_FUNC_CALL;
-       } else {
-               zend_op *opline;
-
-               if (function_name->op_type != IS_CONST) {
-                       zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC);
-               }
+       zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+       zend_do_begin_variable_parse(TSRMLS_C);
+       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+       opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+       opline->extended_value = ZEND_MEMBER_FUNC_CALL;
+       opline->op1 = *object;
+       opline->op2 = *function_name;
+       opline->result.u.var = get_temporary_variable(CG(active_op_array));
+       opline->result.op_type = IS_VAR;
 
-               opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-               opline->opcode = ZEND_INIT_FCALL_BY_NAME;
-               opline->op2 = *function_name;
-               opline->extended_value = 0;
-               SET_UNUSED(opline->op1);
+       *function_name = opline->result;
+/*
+       if (function_name->op_type == IS_CONST) {
+               zval_copy_ctor(&function_name->u.constant);
        }
+*/
+
+       zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
+       zend_do_extended_fcall_begin(TSRMLS_C); 
+}
+void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC)
+{
+       unsigned char *ptr = NULL;
+       zend_op *opline;
+
+       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+       opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+       opline->op2 = *function_name;
+       opline->extended_value = 0;
+       SET_UNUSED(opline->op1);
+
        zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
        zend_do_extended_fcall_begin(TSRMLS_C); 
 }
@@ -941,8 +945,12 @@ void zend_do_pass_param(znode *param, int op, int offset TSRMLS_DC)
 
        send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(offset, 1, arg_types)?ZEND_ARG_SEND_BY_REF:0;
 
-       if (op == ZEND_SEND_VAL && param->op_type == IS_VAR) {
-                       op = ZEND_SEND_VAR_NO_REF;
+
+       if (op == ZEND_SEND_VAR && zend_variable_buffer_empty(TSRMLS_C)) {
+               /* Method call */
+               op = ZEND_SEND_VAR_NO_REF;
+       } else if (op == ZEND_SEND_VAL && param->op_type == IS_VAR) {
+               op = ZEND_SEND_VAR_NO_REF;
        }
 
        if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference == ZEND_ARG_SEND_BY_REF) {
@@ -2060,7 +2068,21 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
 
 void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token, int variable TSRMLS_DC)
 {
-       zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+       zend_op *opline;
+       zend_bool is_variable;
+
+       if (variable) {
+               if (zend_variable_buffer_empty(TSRMLS_C)) {
+                       is_variable = 0;
+               } else {
+                       is_variable = 1;
+               }
+               zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+       } else {
+               is_variable = 0;
+       }
+
+       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
        /* Preform array reset */
        opline->opcode = ZEND_FE_RESET;
@@ -2068,11 +2090,7 @@ void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brack
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
        opline->op1 = *array;
        SET_UNUSED(opline->op2);
-       if (variable) {
-               opline->extended_value = 1;
-       } else {
-               opline->extended_value = 0;
-       }
+       opline->extended_value = is_variable;
        *open_brackets_token = opline->result;
 
        zend_stack_push(&CG(foreach_copy_stack), (void *) &opline->result, sizeof(znode));
index 3fd85e527a4a920930d227de8e9586852182c4ec..4089309d625ece078fcb7845c26a850b3cd76089 100644 (file)
@@ -275,6 +275,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
 void zend_do_end_function_declaration(znode *function_token TSRMLS_DC);
 void zend_do_receive_arg(int op, znode *var, znode *offset, znode *initialization, unsigned char pass_type TSRMLS_DC);
 int zend_do_begin_function_call(znode *function_name TSRMLS_DC);
+void zend_do_begin_method_call(znode *object, znode *function_name TSRMLS_DC);
 void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC);
 void zend_do_begin_class_member_function_call(znode *class_name, znode *function_name TSRMLS_DC);
 void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
index d5ea4d14f02e252ea84d37616814863f76dbbdf5..a3679d4677a982794d6c922c8b1463ec99f95d2e 100644 (file)
@@ -197,7 +197,7 @@ unticked_statement:
        |       expr ';'                                { zend_do_free(&$1 TSRMLS_CC); }
        |       T_USE use_filename ';'          { zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()");  zval_dtor(&$2.u.constant); }
        |       T_UNSET '(' unset_variables ')' ';'
-       |       T_FOREACH '(' w_cvar T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 1 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
+       |       T_FOREACH '(' cvar T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 1 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
        |       T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 0 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
        |       T_DECLARE { zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(TSRMLS_C); }
        |       ';'             /* empty statement */
@@ -490,12 +490,13 @@ 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); }
-       |       cvar '(' { 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);}
        |       T_STRING T_PAAMAYIM_NEKUDOTAYIM static_or_variable_string '(' { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); } 
                                                                                        function_call_parameter_list 
                                                                                        ')' { zend_do_end_function_call(&$3, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+       |       cvar_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);}
+
 ;
 
 
@@ -621,6 +622,11 @@ ref_list:
 object_property:
                object_dim_list { $$ = $1; }
        |       cvar_without_objects { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); } { znode tmp_znode;  zend_do_pop_object(&tmp_znode TSRMLS_CC);  zend_do_fetch_property(&$$, &tmp_znode, &$1 TSRMLS_CC);}
+       |       cvar_without_objects '(' { znode tmp_znode; zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_pop_object(&tmp_znode TSRMLS_CC); zend_do_begin_method_call(&tmp_znode, &$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);}
+       |       variable_name '(' { znode tmp_znode; zend_do_pop_object(&tmp_znode TSRMLS_CC); zend_do_begin_method_call(&tmp_znode, &$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);}
+
 ;
 
 object_dim_list: