]> granicus.if.org Git - php/commitdiff
- Fix issues with $this when using it by itself without indirection such as
authorAndi Gutmans <andi@php.net>
Fri, 15 Mar 2002 15:09:46 +0000 (15:09 +0000)
committerAndi Gutmans <andi@php.net>
Fri, 15 Mar 2002 15:09:46 +0000 (15:09 +0000)
- $this->foo.

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_opcode.c

index 235fc5cd0d0d6c31e1c9b81a9945cb4560f8782d..674aa0c429d1525b24f6442c194881ff4635e33d 100644 (file)
@@ -285,14 +285,7 @@ void fetch_simple_variable_ex(znode *result, znode *varname, int bp, int op TSRM
        *result = opline_ptr->result;
        SET_UNUSED(opline_ptr->op2);
 
-       if ((opline_ptr->op1.op_type == IS_CONST) && (opline_ptr->op1.u.constant.type == IS_STRING) &&
-               (opline_ptr->op1.u.constant.value.str.len == (sizeof("this")-1)) &&
-               !memcmp(opline_ptr->op1.u.constant.value.str.val, "this", sizeof("this"))) {
-               opline_ptr->op2.u.EA.type = ZEND_FETCH_THIS;
-               efree(varname->u.constant.value.str.val);
-               memset(&opline_ptr->op1, 0, sizeof(znode));
-               SET_UNUSED(opline_ptr->op1);
-       } else if (varname->op_type == IS_CONST && varname->u.constant.type == IS_STRING
+       if (varname->op_type == IS_CONST && varname->u.constant.type == IS_STRING
                && zend_hash_exists(CG(auto_globals), varname->u.constant.value.str.val, varname->u.constant.value.str.len+1)) {
                opline_ptr->op2.u.EA.type = ZEND_FETCH_GLOBAL;
        } else {
@@ -722,6 +715,7 @@ void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC)
        zend_llist *fetch_list_ptr;
        zend_llist_element *le;
        zend_op *opline, *opline_ptr;
+       int num_of_created_opcodes = 0;
 
        /*
        if (zend_variable_buffer_empty(TSRMLS_C) && (type == BP_VAR_W || type == BP_VAR_RW)) {
@@ -763,7 +757,17 @@ void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC)
                                break;
                }
                le = le->next;
+               num_of_created_opcodes++;
+       }
+
+       if (num_of_created_opcodes == 1) {
+               if ((opline_ptr->op1.op_type == IS_CONST) && (opline_ptr->op1.u.constant.type == IS_STRING) &&
+               (opline_ptr->op1.u.constant.value.str.len == (sizeof("this")-1)) &&
+               !memcmp(opline_ptr->op1.u.constant.value.str.val, "this", sizeof("this"))) {
+                       CG(active_op_array)->uses_this = 1;
+               }
        }
+
        zend_llist_destroy(fetch_list_ptr);
        zend_stack_del_top(&CG(bp_stack));
 }
@@ -2202,7 +2206,10 @@ void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS
 
                le = fetch_list_ptr->head;
                opline_ptr = (zend_op *) le->data;
-               if (opline_ptr->op1.op_type == IS_UNUSED && opline_ptr->op2.u.EA.type == ZEND_FETCH_THIS) {
+               if ((opline_ptr->op1.op_type == IS_CONST) && (opline_ptr->op1.u.constant.type == IS_STRING) &&
+               (opline_ptr->op1.u.constant.value.str.len == (sizeof("this")-1)) &&
+               !memcmp(opline_ptr->op1.u.constant.value.str.val, "this", sizeof("this"))) {
+                       efree(opline_ptr->op1.u.constant.value.str.val);
                        opline_ptr->op1 = *property;
                        SET_UNUSED(opline_ptr->op2);
                        opline_ptr->op2.u.EA.type = ZEND_FETCH_FROM_THIS;
index 330bad464c62c8cd572e56dab8701d5b72e8a948..4dc3a1726198279bef19b220283bc430e2d3a13a 100644 (file)
@@ -103,6 +103,7 @@ struct _zend_op_array {
 
        zend_bool return_reference;
        zend_bool done_pass_two;
+       zend_bool uses_this;
 
        char *filename;
 
@@ -589,7 +590,6 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_FETCH_STATIC                      2
 #define ZEND_FETCH_STATIC_MEMBER       3
 #define ZEND_FETCH_FROM_THIS           4
-#define ZEND_FETCH_THIS                                5
 
 /* class fetches */
 #define ZEND_FETCH_CLASS_DEFAULT       0
index 3eba1da4f834a9502b82eb1449a6cb031b7f1c0e..ed3a25bc4044435e880613ffbf7eefc2728dbbc1 100644 (file)
@@ -635,22 +635,6 @@ static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_vari
                        /* HACK!! 'this' should be always zend_object */
                        return Z_OBJPROP_P(EG(This));
                        break;
-               case ZEND_FETCH_THIS:
-                       {
-                               if (!EG(This)) {
-                                       zend_error(E_ERROR, "Using $this when not in object context");
-                               }
-                               /* FIXME: Put this error back.
-                               //if (type == BP_VAR_RW || type == BP_VAR_W) {
-                               //      zend_error(E_ERROR, "Can't overwrite $this");
-                               //}
-                               */
-                               Ts[opline->result.u.var].var.ptr_ptr = &EG(This);
-                               SELECTIVE_PZVAL_LOCK(EG(This), &opline->result);
-                               AI_USE_PTR(Ts[opline->result.u.var].var);
-                               return NULL;
-                               break;
-                       }
                EMPTY_SWITCH_DEFAULT_CASE()
        }
        return NULL;
@@ -1179,6 +1163,13 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
                EX(opline) = op_array->opcodes;
        }
 
+       if (op_array->uses_this && EG(This)) {
+               EG(This)->refcount++; /* For $this pointer */
+               if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
+                       EG(This)->refcount--;
+               }
+       }
+
        EG(opline_ptr) = &EX(opline);
 
        EX(function_state).function = (zend_function *) op_array;
@@ -2815,42 +2806,27 @@ send_by_ref:
 
                        
                                        unset_object = (EX(opline)->extended_value == ZEND_UNSET_OBJ);
-                                       if (EX(opline)->op2.u.EA.type == ZEND_FETCH_THIS) {
-                                               if (!EG(This)) {
-                                                       zend_error(E_WARNING, "Using $this in non-object context");
-                                               } else {
-                                                       object = &EG(This);
-                                                       if(unset_object) {
-                                                               Z_OBJ_HT_PP(object)->delete_obj((*object));
-                                                               zval_ptr_dtor(&EG(This));
-                                                               EG(This) = NULL;
-                                                       } else {
-                                                               zend_error(E_WARNING, "$this cannot be unset");
-                                                       }
-                                               }
-                                       } else {
-                                               if (variable->type != IS_STRING) {
-                                                       tmp = *variable;
-                                                       zval_copy_ctor(&tmp);
-                                                       convert_to_string(&tmp);
-                                                       variable = &tmp;
-                                               }
+                                       if (variable->type != IS_STRING) {
+                                               tmp = *variable;
+                                               zval_copy_ctor(&tmp);
+                                               convert_to_string(&tmp);
+                                               variable = &tmp;
+                                       }
 
-                                               if (unset_object) {
-                                                       if (zend_hash_find(EG(active_symbol_table), variable->value.str.val, variable->value.str.len+1, (void **)&object) == FAILURE) {
-                                                               zend_error(E_ERROR, "Cannot delete non-existing object");
-                                                       }
-                                                       if (Z_TYPE_PP(object) != IS_OBJECT) {
-                                                       zend_error(E_ERROR, "Cannot call delete on non-object type");
-                                                       }
-                                                       Z_OBJ_HT_PP(object)->delete_obj((*object));
+                                       if (unset_object) {
+                                               if (zend_hash_find(EG(active_symbol_table), variable->value.str.val, variable->value.str.len+1, (void **)&object) == FAILURE) {
+                                                       zend_error(E_ERROR, "Cannot delete non-existing object");
                                                }
+                                               if (Z_TYPE_PP(object) != IS_OBJECT) {
+                                               zend_error(E_ERROR, "Cannot call delete on non-object type");
+                                               }
+                                               Z_OBJ_HT_PP(object)->delete_obj((*object));
+                                       }
 
-                                               zend_hash_del(EG(active_symbol_table), variable->value.str.val, variable->value.str.len+1);
+                                       zend_hash_del(EG(active_symbol_table), variable->value.str.val, variable->value.str.len+1);
 
-                                               if (variable == &tmp) {
-                                                       zval_dtor(&tmp);
-                                               }
+                                       if (variable == &tmp) {
+                                               zval_dtor(&tmp);
                                        }
                                        FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
                                }
@@ -3048,28 +3024,19 @@ send_by_ref:
                                        zend_bool isset = 1;
                                        HashTable *target_symbol_table;
                
-                                       if (EX(opline)->op2.u.EA.type == ZEND_FETCH_THIS) {
-                                               if (!EG(This)) {
-                                                       isset = 0;
-                                               } else {
-                                                       isset = 1;
-                                                       value = &EG(This);
-                                               }
-                                       } else {
-                                               target_symbol_table = zend_get_target_symbol_table(EX(opline), EX(Ts), BP_VAR_IS TSRMLS_CC);
+                                       target_symbol_table = zend_get_target_symbol_table(EX(opline), EX(Ts), BP_VAR_IS TSRMLS_CC);
 
-                                               if (variable->type != IS_STRING) {
-                                                       tmp = *variable;
-                                                       zval_copy_ctor(&tmp);
-                                                       convert_to_string(&tmp);
-                                                       variable = &tmp;
-                                               }
-                                               
-                                               if (zend_hash_find(target_symbol_table, variable->value.str.val, variable->value.str.len+1, (void **) &value) == FAILURE) {
-                                                       isset = 0;
-                                               }
+                                       if (variable->type != IS_STRING) {
+                                               tmp = *variable;
+                                               zval_copy_ctor(&tmp);
+                                               convert_to_string(&tmp);
+                                               variable = &tmp;
                                        }
-                                               
+                                       
+                                       if (zend_hash_find(target_symbol_table, variable->value.str.val, variable->value.str.len+1, (void **) &value) == FAILURE) {
+                                               isset = 0;
+                                       }
+                                       
                                        EX(Ts)[EX(opline)->result.u.var].tmp_var.type = IS_BOOL;
 
                                        switch (EX(opline)->extended_value) {
index ed10615c83a8df5d11e1a264f19a5a4b858ff7bc..221dee43ae52bcdfd384ee89d2fd04a878a7f760 100644 (file)
@@ -87,6 +87,8 @@ void init_op_array(zend_op_array *op_array, int type, int initial_ops_size TSRML
        op_array->return_reference = 0;
        op_array->done_pass_two = 0;
 
+       op_array->uses_this = 0;
+
        op_array->start_op = NULL;
 
        zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);