]> granicus.if.org Git - php/commitdiff
- Complex fix for solving a problem with objects & method calls.
authorAndi Gutmans <andi@php.net>
Thu, 6 Jul 2000 22:08:22 +0000 (22:08 +0000)
committerAndi Gutmans <andi@php.net>
Thu, 6 Jul 2000 22:08:22 +0000 (22:08 +0000)
- Previous version is tagged PRE_METHOD_CALL_SEPERATE_FIX_PATCH.
- I need to check this fix on a server so if it doesn't work I will revert
- it.

Zend/zend-parser.y
Zend/zend_compile.c
Zend/zend_execute.c

index 523bdc149ac8e4665a7e13392fa2e137414ec468..2d964f384417f60bdb8e18c5495bb48f55153e08 100644 (file)
@@ -489,10 +489,10 @@ expr_without_variable:
 
 
 function_call:
-               T_STRING        '(' { do_extended_fcall_begin(CLS_C); $2.u.opline_num = do_begin_function_call(&$1 CLS_CC); }
+               T_STRING        '(' { $2.u.opline_num = do_begin_function_call(&$1 CLS_CC); }
                                function_call_parameter_list
                                ')' { do_end_function_call(&$1, &$$, &$4, 0, $2.u.opline_num CLS_CC); do_extended_fcall_end(CLS_C); }
-       |       r_cvar '(' { do_extended_fcall_begin(CLS_C); do_begin_dynamic_function_call(&$1 CLS_CC); } 
+       |       cvar '(' { do_begin_dynamic_function_call(&$1 CLS_CC); } 
                                function_call_parameter_list 
                                ')' { do_end_function_call(&$1, &$$, &$4, 0, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
        |       T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_class_member_function_call(&$1, &$3 CLS_CC); } 
index abfc8d3723273ea9c2e0bb6596598f1493c2b7a1..3d8e576e81cf6d22639755baab51a2e7a4e0dde2 100644 (file)
@@ -567,6 +567,27 @@ void do_end_variable_parse(int type, int arg_offset CLS_DC)
 }
 
 
+zend_bool is_method_call(CLS_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_R) {
+                       return 1;
+       }
+       return 0;
+}
+
+
 void do_init_string(znode *result CLS_DC)
 {
        zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
@@ -815,6 +836,7 @@ int do_begin_function_call(znode *function_name CLS_DC)
                        }
                        break;
        }
+       do_extended_fcall_begin(CLS_C); 
        return 0;
 }
 
@@ -822,29 +844,28 @@ int do_begin_function_call(znode *function_name CLS_DC)
 void do_begin_dynamic_function_call(znode *function_name CLS_DC)
 {
        unsigned char *ptr = NULL;
-       int last_op_number = get_next_op_number(CG(active_op_array))-1;
-       zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number];
-
-       if ((last_op_number >= 1) && (last_op->opcode == ZEND_EXT_FCALL_BEGIN) && ((last_op-1)->opcode == ZEND_FETCH_OBJ_R)) {
-               zend_op tmp;
+       int last_op_number;
+       zend_op *last_op;
 
-               tmp = *last_op;
-               *last_op = *(last_op-1);
-               *(last_op-1) = tmp;
-               last_op->opcode = ZEND_INIT_FCALL_BY_NAME;
-                last_op->extended_value = ZEND_MEMBER_FUNC_CALL;
-       } else if (last_op_number>=0 && last_op->opcode == ZEND_FETCH_OBJ_R) {
+       if (function_name->op_type != IS_CONST && is_method_call(CLS_C)) {
+               do_end_variable_parse(BP_VAR_W, 0 CLS_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 = get_next_op(CG(active_op_array) CLS_CC);
-       
+               zend_op *opline;
+
+               do_end_variable_parse(BP_VAR_R, 0 CLS_CC);
+
+               opline = get_next_op(CG(active_op_array) CLS_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 *));
+       do_extended_fcall_begin(CLS_C); 
 }
 
 
index c3a08c27358589919f3b7a543b95ee452174bc17..7918e97e22d2b5a207389748b89a52caac3fa857 100644 (file)
@@ -65,12 +65,13 @@ static void zend_extension_statement_handler(zend_extension *extension, zend_op_
 static void zend_extension_fcall_begin_handler(zend_extension *extension, zend_op_array *op_array);
 static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_array *op_array);
 
-
+/*
 #define SEPARATE_ON_READ_OBJECT(obj, _type)    \
 if ((obj) && ((_type) == BP_VAR_R) && ((*(obj))->type == IS_OBJECT)) { \
                SEPARATE_ZVAL_IF_NOT_REF((obj));                        \
                (*(obj))->is_ref = 1;                   \
        }
+*/
 
 #define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED))
 
@@ -502,7 +503,7 @@ static void zend_fetch_var_address(znode *result, znode *op1, znode *op2, temp_v
                zval_dtor(varname);
        }
        Ts[result->u.var].var.ptr_ptr = retval;
-       SEPARATE_ON_READ_OBJECT(retval, type);
+//     SEPARATE_ON_READ_OBJECT(retval, type);
        SELECTIVE_PZVAL_LOCK(*retval, result);
 }
 
@@ -680,7 +681,7 @@ static void zend_fetch_dimension_address(znode *result, znode *op1, znode *op2,
                        } else {
                                *retval = zend_fetch_dimension_address_inner(container->value.ht, op2, Ts, type ELS_CC);
                        }
-                       SEPARATE_ON_READ_OBJECT(*retval, type);
+                       //SEPARATE_ON_READ_OBJECT(*retval, type);
                        SELECTIVE_PZVAL_LOCK(**retval, result);
                        break;
                case IS_NULL:
@@ -871,7 +872,7 @@ static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, t
                zendi_zval_copy_ctor(*container);
        }
        *retval = zend_fetch_property_address_inner(container->value.obj.properties, op2, Ts, type ELS_CC);
-       SEPARATE_ON_READ_OBJECT(*retval, type);
+       //SEPARATE_ON_READ_OBJECT(*retval, type);
        SELECTIVE_PZVAL_LOCK(**retval, result);
 }
 
@@ -1513,6 +1514,10 @@ binary_assign_op_addr: {
                                                        if (!object.ptr || object.ptr->type != IS_OBJECT) {
                                                                zend_error(E_ERROR, "Call to a member function on a non-object");
                                                        }
+                                                       if (!object.ptr->is_ref && object.ptr->refcount > 1) {
+                                                               zend_error(E_ERROR, "Bug: Problem in method call\n");
+                                                       }
+                                                       object.ptr->is_ref=1;
                                                        object.ptr->refcount++; /* For $this pointer */
                                                        active_function_table = &(object.ptr->value.obj.ce->function_table);
                                                }