]> granicus.if.org Git - php/commitdiff
- Allow passing of $this as function arguments.
authorAndi Gutmans <andi@php.net>
Sat, 5 Jan 2002 19:59:09 +0000 (19:59 +0000)
committerAndi Gutmans <andi@php.net>
Sat, 5 Jan 2002 19:59:09 +0000 (19:59 +0000)
- Fix a bug which I introduced a couple of months ago

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

index ca8dba815283530a84d328445a6bc7a7158522e4..2cab42e07071d3d02af32342f9c8833f43eef365 100644 (file)
@@ -228,12 +228,18 @@ void fetch_simple_variable_ex(znode *result, znode *varname, int bp, int op TSRM
        *result = opline_ptr->result;
        SET_UNUSED(opline_ptr->op2);
 
-       if (varname->op_type == IS_CONST
-               && varname->u.constant.type == IS_STRING
+       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
                && zend_hash_exists(CG(auto_globals), varname->u.constant.value.str.val, varname->u.constant.value.str.len+1)) {
-               opline_ptr->extended_value = ZEND_FETCH_GLOBAL;
+               opline_ptr->op2.u.EA.type = ZEND_FETCH_GLOBAL;
        } else {
-               opline_ptr->extended_value = ZEND_FETCH_LOCAL;
+               opline_ptr->op2.u.EA.type = ZEND_FETCH_LOCAL;
        }
 
        if (bp) {
@@ -259,7 +265,7 @@ void zend_do_fetch_static_member(znode *class TSRMLS_DC)
 
        opline_ptr = (zend_op *)le->data;
        opline_ptr->op2 = *class;
-       opline_ptr->extended_value = ZEND_FETCH_STATIC_MEMBER;
+       opline_ptr->op2.u.EA.type = ZEND_FETCH_STATIC_MEMBER;
 }
 
 void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC)
@@ -918,9 +924,10 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC)
 
        last_op->opcode = ZEND_INIT_METHOD_CALL;
 
-       if (last_op->extended_value == ZEND_FETCH_THIS) {
-               last_op->op2 = last_op->op1;            
-               memset(&last_op->op1, 0, sizeof(znode));
+       if (last_op->op2.op_type == IS_UNUSED && last_op->op2.u.EA.type == ZEND_FETCH_FROM_THIS) {
+               last_op->op2 = last_op->op1;
+               memset(&last_op->op1, 0, sizeof(znode));  
+               last_op->extended_value = ZEND_FETCH_FROM_THIS;
        }
 
        zend_lowercase_znode_if_const(&last_op->op2);
@@ -1995,12 +2002,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_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);
+               if (opline_ptr->op1.op_type == IS_UNUSED && opline_ptr->op2.u.EA.type == ZEND_FETCH_THIS) {
                        opline_ptr->op1 = *property;
-                       opline_ptr->extended_value = ZEND_FETCH_THIS;
+                       SET_UNUSED(opline_ptr->op2);
+                       opline_ptr->op2.u.EA.type = ZEND_FETCH_FROM_THIS;
 
                        *result = opline_ptr->result;
                        return;
@@ -2013,7 +2018,7 @@ void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS
        opline.result.u.EA.type = 0;
        opline.result.u.var = get_temporary_variable(CG(active_op_array));
        opline.op1 = *object;
-       opline.op2 = *property;
+       opline. op2 = *property;
        *result = opline.result;
 
        zend_llist_add_element(fetch_list_ptr, &opline);
@@ -2335,7 +2340,7 @@ void zend_do_fetch_global_or_static_variable(znode *varname, znode *static_assig
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
        opline->op1 = *varname;
        SET_UNUSED(opline->op2);
-       opline->extended_value = fetch_type;
+       opline->op2.u.EA.type = fetch_type;
        result = opline->result;
 
        if (varname->op_type == IS_CONST) {
index 996300f6291c8e23429c2be595e532b4d1159984..e2a2efa0fc2f4352ef6bbcd4481c0679c8cbcb93 100644 (file)
@@ -559,7 +559,8 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_FETCH_LOCAL                       1
 #define ZEND_FETCH_STATIC                      2
 #define ZEND_FETCH_STATIC_MEMBER       3
-#define ZEND_FETCH_THIS                                4
+#define ZEND_FETCH_FROM_THIS           4
+#define ZEND_FETCH_THIS                                5
 
 /* class fetches */
 #define ZEND_FETCH_CLASS_DEFAULT       0
index 9f9cceb973ad40a71f3f14ed3cec60b6443e658a..7abee8c25238b5cedc151b4ea4debd4ab1dc75f3 100644 (file)
@@ -530,7 +530,7 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type
        zval tmp_varname;
        HashTable *target_symbol_table=0;
 
-       switch (opline->extended_value) {
+       switch (opline->op2.u.EA.type) {
                case ZEND_FETCH_LOCAL:
                        target_symbol_table = EG(active_symbol_table);
                        break;
@@ -550,16 +550,32 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type
                case ZEND_FETCH_STATIC_MEMBER:
                        target_symbol_table = Ts[opline->op2.u.var].EA.class_entry->static_members;
                        break;
-               case ZEND_FETCH_THIS:
+               case ZEND_FETCH_FROM_THIS:
                        if (!EG(this)) {
                                zend_error(E_ERROR, "Using $this when not in object context");
                        }
                        target_symbol_table = 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;
+                               break;
+                       }
                EMPTY_SWITCH_DEFAULT_CASE()
        }
 
-       if (varname->type != IS_STRING) {
+       if (varname->type != IS_STRING) {
                tmp_varname = *varname;
                zval_copy_ctor(&tmp_varname);
                convert_to_string(&tmp_varname);
@@ -586,9 +602,9 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type
                        EMPTY_SWITCH_DEFAULT_CASE()
                }
        }
-       if (opline->extended_value == ZEND_FETCH_LOCAL) {
+       if (opline->op2.u.EA.type == ZEND_FETCH_LOCAL) {
                FREE_OP(Ts, &opline->op1, free_op1);
-       } else if (opline->extended_value == ZEND_FETCH_STATIC || opline->extended_value == ZEND_FETCH_STATIC_MEMBER) {
+       } else if (opline->op2.u.EA.type == ZEND_FETCH_STATIC || opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
                zval_update_constant(retval, (void *) 1 TSRMLS_CC);
        }
 
@@ -1601,7 +1617,7 @@ binary_assign_op_addr: {
                                        
                                        EX(calling_namespace) = EG(namespace);
 
-                                       if (EX(opline)->extended_value == ZEND_FETCH_THIS) {
+                                       if (EX(opline)->extended_value == ZEND_FETCH_FROM_THIS) {
                                                if (!EG(this)) {
                                                        zend_error(E_ERROR, "Can't fetch $this as not in object context");
                                                }