void do_begin_function_call(znode *function_name CLS_DC)
{
- zend_op *opline ;
zend_function *function;
zend_str_tolower(function_name->u.constant.value.str.val, function_name->u.constant.value.str.len);
return;
}
- opline = get_next_op(CG(active_op_array) CLS_CC);
-
switch (function->type) {
case ZEND_USER_FUNCTION: {
zend_op_array *op_array = (zend_op_array *) function;
}
break;
}
- opline->opcode = ZEND_INIT_FCALL;
- SET_UNUSED(opline->op1);
- SET_UNUSED(opline->op2);
}
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
ELS_FETCH();
- opline->opcode = ZEND_DO_FCALL;
+ if (function_name->op_type==IS_CONST && !is_method) {
+ opline->opcode = ZEND_DO_FCALL;
+ } else {
+ opline->opcode = ZEND_DO_FCALL_BY_NAME;
+ }
opline->op1 = *function_name;
opline->result.u.var = get_temporary_variable(CG(active_op_array));
opline->result.op_type = IS_TMP_VAR;
function_ptr = *function_ptr_ptr;
if (function_ptr) {
arg_types = function_ptr->common.arg_types;
+ opline->extended_value = ZEND_DO_FCALL;
} else {
arg_types = NULL;
+ opline->extended_value = ZEND_DO_FCALL_BY_NAME;
}
if (op == ZEND_SEND_VAL) {
{
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
- opline->opcode = ZEND_INIT_FCALL;
- SET_UNUSED(opline->op1);
- SET_UNUSED(opline->op2);
-
- opline = get_next_op(CG(active_op_array) CLS_CC);
switch (cmd->op_type) {
case IS_TMP_VAR:
opline->opcode = ZEND_SEND_VAL;
}
opline->op1 = *cmd;
opline->op2.u.opline_num = 0;
+ opline->extended_value = ZEND_DO_FCALL;
SET_UNUSED(opline->op2);
opline = get_next_op(CG(active_op_array) CLS_CC);
HashTable *active_function_table;
zval tmp;
+ zend_ptr_stack_push(&EG(arg_types_stack), function_being_called);
+ zend_ptr_stack_push(&EG(arg_types_stack), object_ptr);
+
if (opline->extended_value & ZEND_CTOR_CALL) {
/* constructor call */
EG(AiCount)++; /* for op1 */
zval_dtor(&tmp);
function_being_called = function;
overloaded_function_call_cont:
- zend_ptr_stack_push(&EG(arg_types_stack), function_being_called);
FREE_OP(&opline->op2, free_op2);
}
break;
- case ZEND_INIT_FCALL:
- object_ptr=NULL;
- function_being_called=NULL;
- break;
+ case ZEND_DO_FCALL_BY_NAME:
+ function_state.function = function_being_called;
+ goto do_fcall_common;
case ZEND_DO_FCALL: {
- zval *original_return_value;
+ zval *fname = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R);
- if (function_being_called) {
- function_being_called = zend_ptr_stack_pop(&EG(arg_types_stack));
- function_state.function = function_being_called;
- } else {
- zval *fname = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R);
-
- if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &function_state.function)==FAILURE) {
- zend_error(E_ERROR, "Unknown function: %s()\n", fname->value.str.val);
- }
- FREE_OP(&opline->op1, free_op1);
+ if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &function_state.function)==FAILURE) {
+ zend_error(E_ERROR, "Unknown function: %s()\n", fname->value.str.val);
}
+ FREE_OP(&opline->op1, free_op1);
+ goto do_fcall_common;
+ }
+do_fcall_common:
+ {
+ zval *original_return_value;
+
zend_ptr_stack_push(&EG(argument_stack), (void *) opline->extended_value);
if (function_state.function->type==ZEND_INTERNAL_FUNCTION) {
var_uninit(&Ts[opline->result.u.var].tmp_var);
}
calling_symbol_table = EG(active_symbol_table);
EG(active_symbol_table) = function_state.function_symbol_table;
- if (object_ptr && function_being_called && function_being_called->type!=ZEND_OVERLOADED_FUNCTION) {
+ if (opline->opcode==ZEND_DO_FCALL_BY_NAME
+ && object_ptr
+ && function_being_called->type!=ZEND_OVERLOADED_FUNCTION) {
zval *dummy = (zval *) emalloc(sizeof(zval)), **this_ptr;
var_uninit(dummy);
call_overloaded_function(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list) ELS_CC);
efree(function_being_called);
}
- function_being_called = NULL;
+ if (opline->opcode == ZEND_DO_FCALL_BY_NAME) {
+ object_ptr = zend_ptr_stack_pop(&EG(arg_types_stack));
+ function_being_called = zend_ptr_stack_pop(&EG(arg_types_stack));
+ }
function_state.function = (zend_function *) op_array;
EG(function_state_ptr) = &function_state;
zend_ptr_stack_clear_multiple(ELS_C);
}
break;
case ZEND_SEND_VAL:
- if (function_being_called
+ if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
+ && function_being_called
&& function_being_called->common.arg_types
&& opline->op2.u.opline_num<=function_being_called->common.arg_types[0]
&& function_being_called->common.arg_types[opline->op2.u.opline_num]==BYREF_FORCE) {
}
break;
case ZEND_SEND_VAR:
- if (function_being_called
+ if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
+ && function_being_called
&& function_being_called->common.arg_types
&& opline->op2.u.opline_num<=function_being_called->common.arg_types[0]
&& function_being_called->common.arg_types[opline->op2.u.opline_num]==BYREF_FORCE) {