- Added native support for asinh(), acosh(), atanh(), log1p() and expm1() (Kalle)
- Improved PHP runtime speed and memory usage:
+ . Use IS_CV for direct access to $this variable. (Dmitry)
. Use ZEND_FREE() opcode instead of ZEND_SWITCH_FREE(IS_TMP_VAR). (Dmitry)
. Lazy EG(active_symbol_table) initialization. (Dmitry)
. Optimized ZEND_RETURN opcode to not allocate and copy return value if it is
}
}
- zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(variable, BP_VAR_W, 0 TSRMLS_CC);
last_op_number = get_next_op_number(CG(active_op_array));
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- if (variable->op_type == IS_VAR) {
+ if (variable->op_type == IS_CV) {
+ if (variable->u.var == CG(active_op_array)->this_var) {
+ zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
+ }
+ } else if (variable->op_type == IS_VAR) {
int n = 0;
while (last_op_number - n > 0) {
void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC)
{
- int last_op_number = get_next_op_number(CG(active_op_array));
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- if (last_op_number > 0) {
- zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
+ zend_op *opline;
- if (lvar->op_type == IS_VAR &&
- opline_is_fetch_this(last_op TSRMLS_CC)) {
- zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
- }
- }
+ if (lvar->op_type == IS_CV) {
+ if (lvar->u.var == CG(active_op_array)->this_var) {
+ zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
+ }
+ } else if (lvar->op_type == IS_VAR) {
+ int last_op_number = get_next_op_number(CG(active_op_array));
+
+ if (last_op_number > 0) {
+ opline = &CG(active_op_array)->opcodes[last_op_number-1];
+ if (opline_is_fetch_this(opline TSRMLS_CC)) {
+ zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
+ }
+ }
+ }
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_ASSIGN_REF;
if (zend_is_function_or_method_call(rvar)) {
opline->extended_value = ZEND_RETURNS_FUNCTION;
}
-void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC)
+void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC)
{
zend_llist *fetch_list_ptr;
zend_llist_element *le;
- zend_op *opline, *opline_ptr=NULL;
+ zend_op *opline = NULL;
+ zend_op *opline_ptr;
+ zend_uint this_var = -1;
zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
if (le) {
opline_ptr = (zend_op *)le->data;
if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) {
- CG(active_op_array)->uses_this = 1;
+ /* convert to FETCH_?(this) into IS_CV */
+ if (CG(active_op_array)->last == 0 ||
+ CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE) {
+
+ this_var = opline_ptr->result.u.var;
+ if (CG(active_op_array)->this_var == -1) {
+ CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), Z_STRVAL(opline_ptr->op1.u.constant), Z_STRLEN(opline_ptr->op1.u.constant));
+ } else {
+ efree(Z_STRVAL(opline_ptr->op1.u.constant));
+ }
+ le = le->next;
+ if (variable->op_type == IS_VAR &&
+ variable->u.var == this_var) {
+ variable->op_type = IS_CV;
+ variable->u.var = CG(active_op_array)->this_var;
+ }
+ } else if (CG(active_op_array)->this_var == -1) {
+ CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), estrndup("this", sizeof("this")-1), sizeof("this")-1);
+ }
}
- while (1) {
+ while (le) {
+ opline_ptr = (zend_op *)le->data;
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
memcpy(opline, opline_ptr, sizeof(zend_op));
+ if (opline->op1.op_type == IS_VAR &&
+ opline->op1.u.var == this_var) {
+ opline->op1.op_type = IS_CV;
+ opline->op1.u.var = CG(active_op_array)->this_var;
+ }
switch (type) {
case BP_VAR_R:
if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2.op_type == IS_UNUSED) {
break;
}
le = le->next;
- if (le == NULL) break;
- opline_ptr = (zend_op *)le->data;
}
- if (type == BP_VAR_W && arg_offset) {
+ if (opline && type == BP_VAR_W && arg_offset) {
opline->extended_value = ZEND_FETCH_MAKE_REF;
}
}
return;
}
- if (CG(active_op_array)->scope &&
+ if (var->op_type == IS_CV &&
+ var->u.var == CG(active_op_array)->this_var &&
+ (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) {
+ zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
+ } else if (var->op_type == IS_VAR &&
+ CG(active_op_array)->scope &&
((CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) &&
(Z_TYPE(varname->u.constant) == IS_STRING) &&
(Z_STRLEN(varname->u.constant) == sizeof("this")-1) &&
int last_op_number;
unsigned char *ptr = NULL;
- zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(left_bracket, BP_VAR_R, 0 TSRMLS_CC);
zend_do_begin_variable_parse(TSRMLS_C);
last_op_number = get_next_op_number(CG(active_op_array))-1;
if (original_op == ZEND_SEND_VAR) {
switch (op) {
case ZEND_SEND_VAR_NO_REF:
- zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
break;
case ZEND_SEND_VAR:
if (function_ptr) {
- zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
} else {
- zend_do_end_variable_parse(BP_VAR_FUNC_ARG, offset TSRMLS_CC);
+ zend_do_end_variable_parse(param, BP_VAR_FUNC_ARG, offset TSRMLS_CC);
}
break;
case ZEND_SEND_REF:
- zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(param, BP_VAR_W, 0 TSRMLS_CC);
break;
}
}
if (do_end_vparse) {
if (CG(active_op_array)->return_reference && !zend_is_function_or_method_call(expr)) {
- zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);
} else {
- zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);
}
}
{
zend_op opline;
zend_llist *fetch_list_ptr;
- zend_op *opline_ptr=NULL;
zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
- if (fetch_list_ptr->count == 1) {
- zend_llist_element *le;
-
- le = fetch_list_ptr->head;
- opline_ptr = (zend_op *) le->data;
+ if (object->op_type == IS_CV) {
+ if (object->u.var == CG(active_op_array)->this_var) {
+ SET_UNUSED(*object); /* this means $this for objects */
+ }
+ } else if (fetch_list_ptr->count == 1) {
+ zend_llist_element *le = fetch_list_ptr->head;
+ zend_op *opline_ptr = (zend_op *) le->data;
if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) {
efree(Z_STRVAL(opline_ptr->op1.u.constant));
{
int i;
- zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(variable, BP_VAR_R, 0 TSRMLS_CC);
for (i=1; i<num_references->u.constant.value.lval; i++) {
fetch_simple_variable_ex(result, variable, 0, ZEND_FETCH_R TSRMLS_CC);
*variable = *result;
{
zend_op *last_op;
- zend_do_end_variable_parse(BP_VAR_IS, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(variable, BP_VAR_IS, 0 TSRMLS_CC);
zend_check_writable_variable(variable);
}
/* save the location of FETCH_W instruction(s) */
open_brackets_token->u.opline_num = get_next_op_number(CG(active_op_array));
- zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(array, BP_VAR_W, 0 TSRMLS_CC);
if (CG(active_op_array)->last > 0 &&
CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode == ZEND_FETCH_OBJ_W) {
/* Only lock the container if we are fetching from a real container and not $this */
value_node = opline->result;
if (assign_by_ref) {
- zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+ zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
/* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */
zend_do_assign_ref(NULL, value, &value_node TSRMLS_CC);
} else {
unsigned char return_reference;
/* END of common elements */
+ zend_bool done_pass_two;
+
zend_uint *refcount;
zend_op *opcodes;
zend_op *start_op;
int backpatch_count;
- zend_bool done_pass_two;
- zend_bool uses_this;
+ zend_uint this_var;
char *filename;
zend_uint line_start;
void zend_do_post_incdec(znode *result, znode *op1, zend_uchar op TSRMLS_DC);
void zend_do_begin_variable_parse(TSRMLS_D);
-void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC);
+void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC);
void zend_check_writable_variable(znode *variable);
}
if (EG(current_execute_data) && EG(current_execute_data)->op_array) {
EG(current_execute_data)->symbol_table = EG(active_symbol_table);
- if (EG(current_execute_data)->op_array->uses_this && EG(This)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
- Z_DELREF_P(EG(This));
- }
- }
+
+ if (EG(current_execute_data)->op_array->this_var != -1 &&
+ !EG(current_execute_data)->CVs[EG(current_execute_data)->op_array->this_var] &&
+ EG(This)) {
+ EG(current_execute_data)->CVs[EG(current_execute_data)->op_array->this_var] = (zval**)EG(current_execute_data)->CVs + EG(current_execute_data)->op_array->last_var + EG(current_execute_data)->op_array->this_var;
+ *EG(current_execute_data)->CVs[EG(current_execute_data)->op_array->this_var] = EG(This);
+ }
for (i = 0; i < EG(current_execute_data)->op_array->last_var; i++) {
if (EG(current_execute_data)->CVs[i]) {
zend_hash_quick_update(EG(active_symbol_table),
;
unset_variable:
- variable { zend_do_end_variable_parse(BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1 TSRMLS_CC); }
+ variable { zend_do_end_variable_parse(&$1, BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1 TSRMLS_CC); }
;
function_declaration_statement:
expr_without_variable:
T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); }
| variable '=' expr { zend_check_writable_variable(&$1); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
- | variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
- | variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
+ | variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$4, BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
+ | variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
| T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
- | variable T_PLUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_MINUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_MUL_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_DIV_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_DIV, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_CONCAT_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_CONCAT, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_MOD_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MOD, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_AND_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_AND, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_OR_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_OR, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_XOR_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_XOR, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_SL_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 TSRMLS_CC); }
- | variable T_SR_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_PLUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_MINUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_MUL_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_DIV_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_DIV, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_CONCAT_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_CONCAT, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_MOD_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MOD, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_AND_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_AND, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_OR_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_OR, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_XOR_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_BW_XOR, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_SL_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 TSRMLS_CC); }
+ | variable T_SR_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 TSRMLS_CC); }
| rw_variable T_INC { zend_do_post_incdec(&$$, &$1, ZEND_POST_INC TSRMLS_CC); }
| T_INC rw_variable { zend_do_pre_incdec(&$$, &$2, ZEND_PRE_INC TSRMLS_CC); }
| rw_variable T_DEC { zend_do_post_incdec(&$$, &$1, ZEND_POST_DEC TSRMLS_CC); }
| class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { $4.u.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call($4.u.opline_num?NULL:&$3, &$$, &$6, $4.u.opline_num, $4.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ | class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
+ | variable_without_objects '(' { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
function_call_parameter_list ')'
{ zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
;
class_name_reference:
class_name { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
- | dynamic_class_name_reference { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
+ | dynamic_class_name_reference { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
;
r_variable:
- variable { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); $$ = $1; }
+ variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); $$ = $1; }
;
w_variable:
- variable { zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); $$ = $1;
+ variable { zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); $$ = $1;
zend_check_writable_variable(&$1); }
;
rw_variable:
- variable { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); $$ = $1;
+ variable { zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); $$ = $1;
zend_check_writable_variable(&$1); }
;
;
variable_class_name:
- reference_variable { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); $$=$1;; }
+ reference_variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); $$=$1;; }
;
base_variable_with_function_calls:
object_property:
object_dim_list { $$ = $1; }
- | variable_without_objects { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); } { znode tmp_znode; zend_do_pop_object(&tmp_znode TSRMLS_CC); zend_do_fetch_property(&$$, &tmp_znode, &$1 TSRMLS_CC);}
+ | variable_without_objects { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); } { znode tmp_znode; zend_do_pop_object(&tmp_znode TSRMLS_CC); zend_do_fetch_property(&$$, &tmp_znode, &$1 TSRMLS_CC);}
;
object_dim_list:
;
encaps_list:
- encaps_list encaps_var { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, &$1, &$2 TSRMLS_CC); }
+ encaps_list encaps_var { zend_do_end_variable_parse(&$2, BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, &$1, &$2 TSRMLS_CC); }
| encaps_list T_ENCAPSED_AND_WHITESPACE { zend_do_add_string(&$$, &$1, &$2 TSRMLS_CC); }
| /* empty */ { zend_do_init_string(&$$ TSRMLS_CC); }
op_array->return_reference = 0;
op_array->done_pass_two = 0;
- op_array->uses_this = 0;
+ op_array->this_var = -1;
op_array->start_op = NULL;
} else {
zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.u.var);
zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value,
- &EG(exception), sizeof(zval *), NULL);
+ &EG(exception), sizeof(zval *), (void**)&EX(CVs)[opline->op2.u.var]);
}
EG(exception) = NULL;
ZEND_VM_NEXT_OPCODE();
ZEND_VM_SET_OPCODE(op_array->opcodes);
}
- if (op_array->uses_this && EG(This) && EG(active_symbol_table)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
- Z_DELREF_P(EG(This));
+ if (op_array->this_var != -1 && EG(This)) {
+ Z_ADDREF_P(EG(This)); /* For $this pointer */
+ if (!EG(active_symbol_table)) {
+ EX(CVs)[op_array->this_var] = (zval**)EX(CVs) + (op_array->last_var + op_array->this_var);
+ *EX(CVs)[op_array->this_var] = EG(This);
+ } else {
+ if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX(CVs)[op_array->this_var])==FAILURE) {
+ Z_DELREF_P(EG(This));
+ }
}
}
} else {
zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.u.var);
zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value,
- &EG(exception), sizeof(zval *), NULL);
+ &EG(exception), sizeof(zval *), (void**)&EX(CVs)[opline->op2.u.var]);
}
EG(exception) = NULL;
ZEND_VM_NEXT_OPCODE();
ZEND_VM_SET_OPCODE(op_array->opcodes);
}
- if (op_array->uses_this && EG(This) && EG(active_symbol_table)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
- Z_DELREF_P(EG(This));
+ if (op_array->this_var != -1 && EG(This)) {
+ Z_ADDREF_P(EG(This)); /* For $this pointer */
+ if (!EG(active_symbol_table)) {
+ EX(CVs)[op_array->this_var] = (zval**)EX(CVs) + (op_array->last_var + op_array->this_var);
+ *EX(CVs)[op_array->this_var] = EG(This);
+ } else {
+ if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX(CVs)[op_array->this_var])==FAILURE) {
+ Z_DELREF_P(EG(This));
+ }
}
}