mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
- Fix issues with $this when using it by itself without indirection such as
- $this->foo.
This commit is contained in:
parent
fb624cb77a
commit
0ce019f715
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,20 +2806,6 @@ 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);
|
||||
@ -2851,7 +2828,6 @@ send_by_ref:
|
||||
if (variable == &tmp) {
|
||||
zval_dtor(&tmp);
|
||||
}
|
||||
}
|
||||
FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
|
||||
}
|
||||
NEXT_OPCODE();
|
||||
@ -3048,14 +3024,6 @@ 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);
|
||||
|
||||
if (variable->type != IS_STRING) {
|
||||
@ -3068,7 +3036,6 @@ send_by_ref:
|
||||
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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user