From: Andi Gutmans Date: Sat, 5 Jan 2002 19:59:09 +0000 (+0000) Subject: - Allow passing of $this as function arguments. X-Git-Tag: PRE_ISSET_PATCH~281 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e56fb1639b9c5da4f4d6b6b7b9c99888bfdd045b;p=php - Allow passing of $this as function arguments. - Fix a bug which I introduced a couple of months ago --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ca8dba8152..2cab42e070 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 996300f629..e2a2efa0fc 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 9f9cceb973..7abee8c252 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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"); }