summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Gutmans <andi@php.net>2002-01-05 19:59:09 +0000
committerAndi Gutmans <andi@php.net>2002-01-05 19:59:09 +0000
commite56fb1639b9c5da4f4d6b6b7b9c99888bfdd045b (patch)
tree64ff7f0487aca2dc7667179ddeb9af1838134c8a
parent7f98b04296b917edd578e3901666cd11b4824594 (diff)
downloadphp-git-e56fb1639b9c5da4f4d6b6b7b9c99888bfdd045b.tar.gz
- Allow passing of $this as function arguments.
- Fix a bug which I introduced a couple of months ago
-rw-r--r--Zend/zend_compile.c35
-rw-r--r--Zend/zend_compile.h3
-rw-r--r--Zend/zend_execute.c28
3 files changed, 44 insertions, 22 deletions
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");
}