}
+zend_bool zend_variable_buffer_empty(TSRMLS_D)
+{
+ zend_llist *fetch_list_ptr;
+
+ zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
+ return !fetch_list_ptr->head;
+}
+
+
void zend_do_begin_variable_parse(TSRMLS_D)
{
zend_llist fetch_list;
}
-static zend_bool is_method_call(TSRMLS_D)
-{
- zend_llist *fetch_list_ptr;
- zend_llist_element *cur;
- zend_op *cur_opline;
-
- zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
-
- cur = fetch_list_ptr->head;
- /* There is always at least one node in the list */
- while (cur->next) {
- cur = cur->next;
- }
- cur_opline = (zend_op *)cur->data;
- if (cur_opline->opcode == ZEND_FETCH_OBJ_W) {
- return 1;
- }
- return 0;
-}
-
-
void zend_do_init_string(znode *result TSRMLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
}
-void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC)
+
+void zend_do_begin_method_call(znode *object, znode *function_name TSRMLS_DC)
{
+ zend_op *opline;
unsigned char *ptr = NULL;
- int last_op_number;
- zend_op *last_op;
- if (function_name->op_type != IS_CONST && is_method_call(TSRMLS_C)) {
- zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
- last_op_number = get_next_op_number(CG(active_op_array))-1;
- last_op = &CG(active_op_array)->opcodes[last_op_number];
- last_op->opcode = ZEND_INIT_FCALL_BY_NAME;
- last_op->extended_value = ZEND_MEMBER_FUNC_CALL;
- } else {
- zend_op *opline;
-
- if (function_name->op_type != IS_CONST) {
- zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC);
- }
+ zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+ zend_do_begin_variable_parse(TSRMLS_C);
+
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+ opline->extended_value = ZEND_MEMBER_FUNC_CALL;
+ opline->op1 = *object;
+ opline->op2 = *function_name;
+ opline->result.u.var = get_temporary_variable(CG(active_op_array));
+ opline->result.op_type = IS_VAR;
+
- opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_INIT_FCALL_BY_NAME;
- opline->op2 = *function_name;
- opline->extended_value = 0;
- SET_UNUSED(opline->op1);
+ *function_name = opline->result;
+/*
+ if (function_name->op_type == IS_CONST) {
+ zval_copy_ctor(&function_name->u.constant);
}
+*/
+
+ zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
+ zend_do_extended_fcall_begin(TSRMLS_C);
+}
+
+
+void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC)
+{
+ unsigned char *ptr = NULL;
+ zend_op *opline;
+
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+ opline->op2 = *function_name;
+ opline->extended_value = 0;
+ SET_UNUSED(opline->op1);
+
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
zend_do_extended_fcall_begin(TSRMLS_C);
}
send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(offset, 1, arg_types)?ZEND_ARG_SEND_BY_REF:0;
- if (op == ZEND_SEND_VAL && param->op_type == IS_VAR) {
- op = ZEND_SEND_VAR_NO_REF;
+
+ if (op == ZEND_SEND_VAR && zend_variable_buffer_empty(TSRMLS_C)) {
+ /* Method call */
+ op = ZEND_SEND_VAR_NO_REF;
+ } else if (op == ZEND_SEND_VAL && param->op_type == IS_VAR) {
+ op = ZEND_SEND_VAR_NO_REF;
}
if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference == ZEND_ARG_SEND_BY_REF) {
void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token, int variable TSRMLS_DC)
{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ zend_op *opline;
+ zend_bool is_variable;
+
+ if (variable) {
+ if (zend_variable_buffer_empty(TSRMLS_C)) {
+ is_variable = 0;
+ } else {
+ is_variable = 1;
+ }
+ zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
+ } else {
+ is_variable = 0;
+ }
+
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
/* Preform array reset */
opline->opcode = ZEND_FE_RESET;
opline->result.u.var = get_temporary_variable(CG(active_op_array));
opline->op1 = *array;
SET_UNUSED(opline->op2);
- if (variable) {
- opline->extended_value = 1;
- } else {
- opline->extended_value = 0;
- }
+ opline->extended_value = is_variable;
*open_brackets_token = opline->result;
zend_stack_push(&CG(foreach_copy_stack), (void *) &opline->result, sizeof(znode));
| expr ';' { zend_do_free(&$1 TSRMLS_CC); }
| T_USE use_filename ';' { zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()"); zval_dtor(&$2.u.constant); }
| T_UNSET '(' unset_variables ')' ';'
- | T_FOREACH '(' w_cvar T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 1 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
+ | T_FOREACH '(' cvar T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 1 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
| T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 0 TSRMLS_CC); } w_cvar foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
| T_DECLARE { zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(TSRMLS_C); }
| ';' /* empty statement */
T_STRING '(' { $2.u.opline_num = zend_do_begin_function_call(&$1 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
- | cvar '(' { zend_do_begin_dynamic_function_call(&$1 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| T_STRING T_PAAMAYIM_NEKUDOTAYIM static_or_variable_string '(' { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(&$3, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ | cvar_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1 TSRMLS_CC); }
+ function_call_parameter_list ')'
+ { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+
;
object_property:
object_dim_list { $$ = $1; }
| cvar_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);}
+ | cvar_without_objects '(' { znode tmp_znode; zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_pop_object(&tmp_znode TSRMLS_CC); zend_do_begin_method_call(&tmp_znode, &$1 TSRMLS_CC); }
+ function_call_parameter_list ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ | variable_name '(' { znode tmp_znode; zend_do_pop_object(&tmp_znode TSRMLS_CC); zend_do_begin_method_call(&tmp_znode, &$1 TSRMLS_CC); }
+ function_call_parameter_list ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+
;
object_dim_list: