ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
{
vm_frame_kind frame_kind = EX(frame_kind);
+ zend_call_frame *call;
EG(current_execute_data) = EX(prev_execute_data);
EG(active_op_array) = EX(op_array);
EG(active_symbol_table) = EX(symbol_table);
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
-
if (Z_OBJ(EG(This))) {
- if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
- if (EX(call)->is_ctor_result_used) {
+ if (UNEXPECTED(EG(exception) != NULL) && (EX(call)->flags & ZEND_CALL_CTOR)) {
+ if (EX(call)->flags & ZEND_CALL_CTOR_RESULT_USED) {
Z_DELREF(EG(This));
}
if (Z_REFCOUNT(EG(This)) == 1) {
EG(scope) = EX(scope);
EG(called_scope) = EX(called_scope);
- EX(call)--;
-
- zend_vm_stack_clear_multiple(1 TSRMLS_CC);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free_call_frame(call, 1 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_op *opline = EX(opline);
execute_data = EG(current_execute_data);
zend_attach_symbol_table(execute_data);
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free((zval*)call TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
}
}
-ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
-{
- USE_OPLINE
- zend_function *fbc = EX(function_state).function;
- zend_object *object;
- zend_uint num_args;
-
- SAVE_OPLINE();
- object = EX(call)->object;
- if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
- if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
- }
- if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
- zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
- fbc->common.scope ? fbc->common.scope->name->val : "",
- fbc->common.scope ? "::" : "",
- fbc->common.function_name->val);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
- }
- }
- if (fbc->common.scope &&
- !(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
- !object) {
-
- if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- /* FIXME: output identifiers properly */
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name->val, fbc->common.function_name->val);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
- } else {
- /* FIXME: output identifiers properly */
- /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name->val, fbc->common.function_name->val);
- }
- }
-
- if (EXPECTED(EX(call)->num_additional_args == 0)) {
- num_args = opline->extended_value;
- EX(function_state).arguments = zend_vm_stack_top_inc(TSRMLS_C);
- ZVAL_LONG(EX(function_state).arguments, num_args);
- } else {
- num_args = opline->extended_value + EX(call)->num_additional_args;
- EX(function_state).arguments = zend_vm_stack_push_args(num_args TSRMLS_CC);
- }
- LOAD_OPLINE();
-
- if (fbc->type == ZEND_INTERNAL_FUNCTION) {
- int should_change_scope = 0;
- zval *ret;
-
- if (fbc->common.scope) {
- should_change_scope = 1;
- Z_OBJ(EG(This)) = object;
- /* TODO: we don't set scope if we call an object method ??? */
- /* See: ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt */
-#if 1
- EG(scope) = (object) ? NULL : fbc->common.scope;
-#else
- EG(scope) = fbc->common.scope;
-#endif
- EG(called_scope) = EX(call)->called_scope;
- }
-
- if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
- zend_uint i;
- zval *p = EX(function_state).arguments - num_args;
-
- for (i = 0; i < num_args; ++i, ++p) {
- zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
- }
- if (UNEXPECTED(EG(exception) != NULL)) {
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- }
- if (UNEXPECTED(should_change_scope)) {
- ZEND_VM_C_GOTO(fcall_end_change_scope);
- } else {
- ZEND_VM_C_GOTO(fcall_end);
- }
- }
- }
-
- ret = EX_VAR(opline->result.var);
- ZVAL_NULL(ret);
- Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
-
- if (!zend_execute_internal) {
- /* saves one function call if zend_execute_internal is not used */
- fbc->internal_function.handler(num_args, ret TSRMLS_CC);
- } else {
- zend_execute_internal(execute_data, NULL TSRMLS_CC);
- }
-
- if (!RETURN_VALUE_USED(opline)) {
- zval_ptr_dtor(ret);
- }
-
- if (UNEXPECTED(should_change_scope)) {
- ZEND_VM_C_GOTO(fcall_end_change_scope);
- } else {
- ZEND_VM_C_GOTO(fcall_end);
- }
- } else if (fbc->type == ZEND_USER_FUNCTION) {
- zval *return_value = NULL;
-
- Z_OBJ(EG(This)) = object;
- EG(scope) = fbc->common.scope;
- EG(called_scope) = EX(call)->called_scope;
- EG(active_symbol_table) = NULL;
- EG(active_op_array) = &fbc->op_array;
- if (RETURN_VALUE_USED(opline)) {
- return_value = EX_VAR(opline->result.var);
-
- ZVAL_NULL(return_value);
- Z_VAR_FLAGS_P(return_value) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
- }
-
- if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
- if (RETURN_VALUE_USED(opline)) {
- zend_generator_create_zval(EG(active_op_array), EX_VAR(opline->result.var) TSRMLS_CC);
- }
- } else if (EXPECTED(zend_execute_ex == execute_ex)) {
- if (EXPECTED(EG(exception) == NULL)) {
- i_create_execute_data_from_op_array(EG(active_op_array), return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
- ZEND_VM_ENTER();
- }
- } else {
- zend_execute(EG(active_op_array), return_value TSRMLS_CC);
- }
-
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
- if (UNEXPECTED(EG(active_symbol_table) != NULL)) {
- zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
- }
- EG(active_symbol_table) = EX(symbol_table);
- } else { /* ZEND_OVERLOADED_FUNCTION */
- Z_OBJ(EG(This)) = object;
-//??? EG(scope) = NULL;
- EG(scope) = fbc->common.scope;
- EG(called_scope) = EX(call)->called_scope;
-
- ZVAL_NULL(EX_VAR(opline->result.var));
-
- /* Not sure what should be done here if it's a static method */
- if (EXPECTED(object != NULL)) {
- object->handlers->call_method(fbc->common.function_name, object, num_args, EX_VAR(opline->result.var) TSRMLS_CC);
- } else {
- zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
- }
-
- if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
- STR_RELEASE(fbc->common.function_name);
- }
- efree(fbc);
-
- if (!RETURN_VALUE_USED(opline)) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
- } else {
-//??? Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
-//??? Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
- Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0;
- }
- }
-
-ZEND_VM_C_LABEL(fcall_end_change_scope):
- if (Z_OBJ(EG(This))) {
- if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
- if (EX(call)->is_ctor_result_used) {
- Z_DELREF(EG(This));
- }
- if (Z_REFCOUNT(EG(This)) == 1) {
- zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC);
- }
- }
- if (!Z_DELREF(EG(This))) {
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
- _zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC);
- } else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) {
- gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC);
- }
- }
- Z_OBJ(EG(This)) = EX(object);
- EG(scope) = EX(scope);
- EG(called_scope) = EX(called_scope);
-
-ZEND_VM_C_LABEL(fcall_end):
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
- EX(call)--;
-
- zend_vm_stack_clear_multiple(1 TSRMLS_CC);
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- zend_throw_exception_internal(NULL TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
- }
- HANDLE_EXCEPTION();
- }
-
- ZEND_VM_NEXT_OPCODE();
-}
-
ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
{
USE_OPLINE
USE_OPLINE
zval *function_name;
zend_free_op free_op1, free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (OP2_TYPE != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (OP2_TYPE == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
FREE_OP2();
FREE_OP1_IF_VAR();
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (OP1_TYPE == IS_CONST &&
OP2_TYPE == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (OP1_TYPE != IS_CONST &&
OP2_TYPE == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (OP2_TYPE != IS_UNUSED) {
zend_free_op free_op2;
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (OP2_TYPE == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (OP1_TYPE == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (OP2_TYPE != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ }
+
+ if (OP1_TYPE != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
{
USE_OPLINE
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *object;
zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
if (OP2_TYPE == IS_CONST) {
function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
STR_FREE(lcname);
FREE_OP2();
- call->fbc = Z_FUNC_P(func);
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ Z_FUNC_P(func), 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (OP2_TYPE != IS_CONST && OP2_TYPE != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object TSRMLS_CC) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
}
if (OP2_TYPE == IS_VAR && OP2_FREE && Z_REFCOUNT_P(function_name) == 1 &&
- call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
+ fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- call->fbc->common.prototype = (zend_function*)function_name_ptr;
+ fbc->common.prototype = (zend_function*)function_name_ptr;
} else {
FREE_OP2();
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
if (Z_TYPE_P(obj) == IS_STRING) {
- call->object = NULL;
- call->called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(call->called_scope == NULL)) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
+ if (UNEXPECTED(called_scope == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
- if (call->called_scope->get_static_method) {
- call->fbc = call->called_scope->get_static_method(call->called_scope, Z_STR_P(method) TSRMLS_CC);
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(call->called_scope, Z_STR_P(method), NULL TSRMLS_CC);
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", call->called_scope->name->val, Z_STRVAL_P(method));
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
}
} else {
- call->called_scope = Z_OBJCE_P(obj);
- call->object = Z_OBJ_P(obj);
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
- call->fbc = Z_OBJ_HT_P(obj)->get_method(&call->object, Z_STR_P(method), NULL TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(method));
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(object), Z_STRVAL_P(method));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(object)++; /* For $this pointer */
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
FREE_OP2();
CHECK_EXCEPTION();
USE_OPLINE
zval *func_name;
zval *func;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_function *fbc;
func_name = opline->op2.zv + 1;
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if ((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL) {
func_name++;
if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(61, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
-{
- EX(function_state).function = EX(call)->fbc;
- ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
-}
-
-ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
+ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST)
{
USE_OPLINE
- zend_free_op free_op1;
- zval *fname = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ zend_free_op free_op2;
+ zval *fname = GET_OP2_ZVAL_PTR(BP_VAR_R);
zval *func;
- call_slot *call = EX(call_slots) + opline->op2.num;
+ zend_function *fbc;
if (CACHED_PTR(Z_CACHE_SLOT_P(fname))) {
- EX(function_state).function = CACHED_PTR(Z_CACHE_SLOT_P(fname));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname));
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(fname))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(fname));
} else {
- EX(function_state).function = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(fname), EX(function_state).function);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc);
}
- call->fbc = EX(function_state).function;
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
- FREE_OP1();
+ FREE_OP2();
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
+ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
+{
+ USE_OPLINE
+ zend_function *fbc = EX(call)->func;
+ zend_object *object;
+ zend_uint num_args;
+ zend_call_frame *call;
+
+ SAVE_OPLINE();
+ EX(call)->flags |= ZEND_CALL_DONE;
+ object = EX(call)->object;
+ if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
+ if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
+ if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
+ zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
+ fbc->common.scope ? fbc->common.scope->name->val : "",
+ fbc->common.scope ? "::" : "",
+ fbc->common.function_name->val);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ }
+ }
+ if (fbc->common.scope &&
+ !(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
+ !object) {
+
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ /* FIXME: output identifiers properly */
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name->val, fbc->common.function_name->val);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ } else {
+ /* FIXME: output identifiers properly */
+ /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
+ }
+
+ if (EXPECTED(EX(call)->num_args == 0)) {
+ EX(call)->num_args = num_args = opline->extended_value;
+ } else {
+ EX(call)->num_args += opline->extended_value;
+ num_args = EX(call)->num_args;
+ zend_vm_stack_adjust_call_frame(&EX(call) TSRMLS_CC);
+ }
+ LOAD_OPLINE();
+
+ if (fbc->type == ZEND_INTERNAL_FUNCTION) {
+ int should_change_scope = 0;
+ zval *ret;
+
+ if (fbc->common.scope) {
+ should_change_scope = 1;
+ Z_OBJ(EG(This)) = object;
+ /* TODO: we don't set scope if we call an object method ??? */
+ /* See: ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt */
+#if 1
+ EG(scope) = (object) ? NULL : fbc->common.scope;
+#else
+ EG(scope) = fbc->common.scope;
+#endif
+ EG(called_scope) = EX(call)->called_scope;
+ }
+
+ if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
+ zend_uint i;
+ zval *p = ZEND_CALL_ARG(EX(call), 1);
+
+ for (i = 0; i < num_args; ++i) {
+ zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
+ p++;
+ }
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
+ }
+ if (UNEXPECTED(should_change_scope)) {
+ ZEND_VM_C_GOTO(fcall_end_change_scope);
+ } else {
+ ZEND_VM_C_GOTO(fcall_end);
+ }
+ }
+ }
+
+ ret = EX_VAR(opline->result.var);
+ ZVAL_NULL(ret);
+ Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
+
+ if (!zend_execute_internal) {
+ /* saves one function call if zend_execute_internal is not used */
+ fbc->internal_function.handler(num_args, ret TSRMLS_CC);
+ } else {
+ zend_execute_internal(execute_data, NULL TSRMLS_CC);
+ }
+
+ if (!RETURN_VALUE_USED(opline)) {
+ zval_ptr_dtor(ret);
+ }
+
+ if (UNEXPECTED(should_change_scope)) {
+ ZEND_VM_C_GOTO(fcall_end_change_scope);
+ } else {
+ ZEND_VM_C_GOTO(fcall_end);
+ }
+ } else if (fbc->type == ZEND_USER_FUNCTION) {
+ zval *return_value = NULL;
+
+ Z_OBJ(EG(This)) = object;
+ EG(scope) = fbc->common.scope;
+ EG(called_scope) = EX(call)->called_scope;
+ EG(active_symbol_table) = NULL;
+ EG(active_op_array) = &fbc->op_array;
+ if (RETURN_VALUE_USED(opline)) {
+ return_value = EX_VAR(opline->result.var);
+
+ ZVAL_NULL(return_value);
+ Z_VAR_FLAGS_P(return_value) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
+ }
+
+ if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (RETURN_VALUE_USED(opline)) {
+ zend_generator_create_zval(EG(active_op_array), EX_VAR(opline->result.var) TSRMLS_CC);
+ }
+ } else if (EXPECTED(zend_execute_ex == execute_ex)) {
+ if (EXPECTED(EG(exception) == NULL)) {
+ i_create_execute_data_from_op_array(EG(active_op_array), return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
+ ZEND_VM_ENTER();
+ }
+ } else {
+ zend_execute(EG(active_op_array), return_value TSRMLS_CC);
+ }
+
+ EG(opline_ptr) = &EX(opline);
+ EG(active_op_array) = EX(op_array);
+ if (UNEXPECTED(EG(active_symbol_table) != NULL)) {
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
+ }
+ EG(active_symbol_table) = EX(symbol_table);
+ } else { /* ZEND_OVERLOADED_FUNCTION */
+ Z_OBJ(EG(This)) = object;
+//??? EG(scope) = NULL;
+ EG(scope) = fbc->common.scope;
+ EG(called_scope) = EX(call)->called_scope;
- ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
+ ZVAL_NULL(EX_VAR(opline->result.var));
+
+ /* Not sure what should be done here if it's a static method */
+ if (EXPECTED(object != NULL)) {
+ object->handlers->call_method(fbc->common.function_name, object, num_args, EX_VAR(opline->result.var) TSRMLS_CC);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
+ }
+
+ if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
+ STR_RELEASE(fbc->common.function_name);
+ }
+ efree(fbc);
+
+ if (!RETURN_VALUE_USED(opline)) {
+ zval_ptr_dtor(EX_VAR(opline->result.var));
+ } else {
+//??? Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
+//??? Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
+ Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0;
+ }
+ }
+
+ZEND_VM_C_LABEL(fcall_end_change_scope):
+ if (Z_OBJ(EG(This))) {
+ if (UNEXPECTED(EG(exception) != NULL) && (EX(call)->flags & ZEND_CALL_CTOR)) {
+ if (EX(call)->flags & ZEND_CALL_CTOR_RESULT_USED) {
+ Z_DELREF(EG(This));
+ }
+ if (Z_REFCOUNT(EG(This)) == 1) {
+ zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC);
+ }
+ }
+ if (!Z_DELREF(EG(This))) {
+ EX(call)->flags &= ~ZEND_CALL_DONE;
+ _zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC);
+ } else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) {
+ gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC);
+ }
+ }
+ Z_OBJ(EG(This)) = EX(object);
+ EG(scope) = EX(scope);
+ EG(called_scope) = EX(called_scope);
+
+ZEND_VM_C_LABEL(fcall_end):
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free_call_frame(call, 1 TSRMLS_CC);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_throw_exception_internal(NULL TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ zval_ptr_dtor(EX_VAR(opline->result.var));
+ }
+ HANDLE_EXCEPTION();
+ }
+
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
zend_free_op free_op1;
SAVE_OPLINE();
- if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
- if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) {
+ if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num);
}
}
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}
} else {
- if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}
}
} else {
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
- !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
top = zend_vm_stack_top_inc(TSRMLS_C);
zval *varptr, *top;
zend_free_op free_op1;
- if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
}
}
SAVE_OPLINE();
args = GET_OP1_ZVAL_PTR(BP_VAR_R);
- arg_num = opline->op2.num + EX(call)->num_additional_args + 1;
+ arg_num = opline->op2.num + EX(call)->num_args + 1;
ZEND_VM_C_LABEL(send_again):
switch (Z_TYPE_P(args)) {
/* check if any of arguments are going to be passed by reference */
for (i = 0; i < zend_hash_num_elements(ht); i++) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num + i)) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
separate = 1;
break;
}
}
top = zend_vm_stack_top_inc(TSRMLS_C);
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
if (!Z_IMMUTABLE_P(args)) {
ZVAL_MAKE_REF(arg);
Z_ADDREF_P(arg);
ZVAL_COPY(top, arg);
}
- EX(call)->num_additional_args++;
+ EX(call)->num_args++;
arg_num++;
} ZEND_HASH_FOREACH_END();
zval_dtor(&key);
}
- if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
+ if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
zend_error(
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
" by unpacking a Traversable, passing by-value instead", arg_num,
- EX(call)->fbc->common.scope ? EX(call)->fbc->common.scope->name->val : "",
- EX(call)->fbc->common.scope ? "::" : "",
- EX(call)->fbc->common.function_name->val
+ EX(call)->func->common.scope ? EX(call)->func->common.scope->name->val : "",
+ EX(call)->func->common.scope ? "::" : "",
+ EX(call)->func->common.function_name->val
);
}
ZEND_VM_STACK_GROW_IF_NEEDED(1);
zend_vm_stack_push(arg TSRMLS_CC);
- EX(call)->num_additional_args++;
+ EX(call)->num_args++;
iter->funcs->move_forward(iter TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
{
USE_OPLINE
zend_uint arg_num = opline->op1.num;
- zval *arguments = EX(prev_execute_data)->function_state.arguments;
- zend_uint arg_count = Z_LVAL_P(arguments);
+ zend_uint arg_count = EX(prev_execute_data)->call->num_args;
SAVE_OPLINE();
if (UNEXPECTED(arg_num > arg_count)) {
zend_verify_missing_arg(execute_data, arg_num TSRMLS_CC);
} else {
zval *var_ptr;
- zval *param = arguments - arg_count + arg_num - 1;
+ zval *param = ZEND_CALL_ARG(EX(prev_execute_data)->call, arg_num);
if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zend_verify_arg_type((zend_function *) EX(op_array), arg_num, param, opline->extended_value TSRMLS_CC);
{
USE_OPLINE
zend_uint arg_num = opline->op1.num;
- zval *arguments = EX(prev_execute_data)->function_state.arguments;
- zend_uint arg_count = Z_LVAL_P(arguments);
+ zend_uint arg_count = EX(prev_execute_data)->call->num_args;
zval *var_ptr;
SAVE_OPLINE();
}
}
} else {
- zval *param = arguments - arg_count + arg_num - 1;
+ zval *param = ZEND_CALL_ARG(EX(prev_execute_data)->call, arg_num);
ZVAL_COPY(var_ptr, param);
}
{
USE_OPLINE
zend_uint arg_num = opline->op1.num;
- zval *arguments = EX(prev_execute_data)->function_state.arguments;
- zend_uint arg_count = Z_LVAL_P(arguments);
+ zend_uint arg_count = EX(prev_execute_data)->call->num_args;
zval *params;
SAVE_OPLINE();
if (UNEXPECTED(Z_REFCOUNTED_P(params))) Z_DELREF_P(params);
if (arg_num <= arg_count) {
- zval *param = arguments - arg_count + arg_num - 1;
+ zval *param = ZEND_CALL_ARG(EX(prev_execute_data)->call, arg_num);
array_init_size(params, arg_count - arg_num + 1);
if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
}
ZEND_VM_JMP(opline->op2.jmp_addr);
} else {
- call_slot *call = EX(call_slots) + opline->extended_value;
+ /* We are not handling overloaded classes right now */
+ EX(call) = zend_vm_stack_push_call_frame(
+ constructor, 0,
+ RETURN_VALUE_USED(opline) ?
+ (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_USED) : ZEND_CALL_CTOR,
+ Z_CE_P(EX_VAR(opline->op1.var)),
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
}
- /* We are not handling overloaded classes right now */
- call->fbc = constructor;
- call->object = Z_OBJ(object_zval);
- call->called_scope = Z_CE_P(EX_VAR(opline->op1.var));
- call->num_additional_args = 0;
- call->is_ctor_call = 1;
- call->is_ctor_result_used = RETURN_VALUE_USED(opline);
- EX(call) = call;
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
+ zend_call_frame *call;
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
- EX(function_state).function = (zend_function *) new_op_array;
+ EX(call) = zend_vm_stack_push_call_frame(
+ (zend_function*)new_op_array, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
zend_execute(new_op_array, return_value TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free((zval*)call TSRMLS_CC);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
int i;
zend_uint catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
- zval *stack_frame;
-
- /* Figure out where the next stack frame (which maybe contains pushed
- * arguments that have to be dtor'ed) starts */
- stack_frame = zend_vm_stack_frame_base(execute_data);
-
- /* If the exception was thrown during a function call there might be
- * arguments pushed to the stack that have to be dtor'ed. */
- while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
- zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
- zval_ptr_dtor(stack_zval_p);
- }
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
}
}
- if (EX(call) >= EX(call_slots)) {
- call_slot *call = EX(call);
+ if (EX(call)) {
+ zend_call_frame *call = EX(call);
do {
+ zval *args = ZEND_CALL_ARG(call, 1);
+
+ /* If the exception was thrown during a function call there might be
+ * arguments pushed to the stack that have to be dtor'ed. */
+ while (zend_vm_stack_top(TSRMLS_C) != args) {
+ zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
+ zval_ptr_dtor(stack_zval_p);
+ }
if (call->object) {
- if (call->is_ctor_call) {
- if (call->is_ctor_result_used) {
+ if (call->flags & ZEND_CALL_CTOR) {
+ if (call->flags & ZEND_CALL_CTOR_RESULT_USED) {
GC_REFCOUNT(call->object)--;
}
if (GC_REFCOUNT(call->object) == 1) {
}
OBJ_RELEASE(call->object);
}
- call--;
- } while (call >= EX(call_slots));
+ EG(argument_stack)->top = (zval*)call;
+ call = call->prev;
+ } while (call);
EX(call) = NULL;
}
}
closure_is_static = Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC;
- closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC;
+ closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->call->func->common.fn_flags & ZEND_ACC_STATIC;
if (closure_is_static || closure_is_being_defined_inside_static_context) {
zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(called_scope), NULL TSRMLS_CC);
} else {
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
+ZEND_VM_EXPORT_HANDLER(zend_do_fcall, ZEND_DO_FCALL)
static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
vm_frame_kind frame_kind = EX(frame_kind);
+ zend_call_frame *call;
EG(current_execute_data) = EX(prev_execute_data);
EG(active_op_array) = EX(op_array);
EG(active_symbol_table) = EX(symbol_table);
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
-
if (Z_OBJ(EG(This))) {
- if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
- if (EX(call)->is_ctor_result_used) {
+ if (UNEXPECTED(EG(exception) != NULL) && (EX(call)->flags & ZEND_CALL_CTOR)) {
+ if (EX(call)->flags & ZEND_CALL_CTOR_RESULT_USED) {
Z_DELREF(EG(This));
}
if (Z_REFCOUNT(EG(This)) == 1) {
EG(scope) = EX(scope);
EG(called_scope) = EX(called_scope);
- EX(call)--;
-
- zend_vm_stack_clear_multiple(1 TSRMLS_CC);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free_call_frame(call, 1 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_op *opline = EX(opline);
execute_data = EG(current_execute_data);
zend_attach_symbol_table(execute_data);
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free((zval*)call TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
}
}
-static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_function *fbc = EX(function_state).function;
+
+ ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
+ ZEND_VM_CONTINUE();
+}
+
+static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *tmp = EX_VAR(opline->result.var);
+
+ SAVE_OPLINE();
+ ZVAL_EMPTY_STRING(tmp);
+ /*CHECK_EXCEPTION();*/
+ ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_function *fbc = EX(call)->func;
zend_object *object;
zend_uint num_args;
+ zend_call_frame *call;
SAVE_OPLINE();
+ EX(call)->flags |= ZEND_CALL_DONE;
object = EX(call)->object;
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
}
}
- if (EXPECTED(EX(call)->num_additional_args == 0)) {
- num_args = opline->extended_value;
- EX(function_state).arguments = zend_vm_stack_top_inc(TSRMLS_C);
- ZVAL_LONG(EX(function_state).arguments, num_args);
+ if (EXPECTED(EX(call)->num_args == 0)) {
+ EX(call)->num_args = num_args = opline->extended_value;
} else {
- num_args = opline->extended_value + EX(call)->num_additional_args;
- EX(function_state).arguments = zend_vm_stack_push_args(num_args TSRMLS_CC);
+ EX(call)->num_args += opline->extended_value;
+ num_args = EX(call)->num_args;
+ zend_vm_stack_adjust_call_frame(&EX(call) TSRMLS_CC);
}
LOAD_OPLINE();
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_uint i;
- zval *p = EX(function_state).arguments - num_args;
+ zval *p = ZEND_CALL_ARG(EX(call), 1);
- for (i = 0; i < num_args; ++i, ++p) {
+ for (i = 0; i < num_args; ++i) {
zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
+ p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
if (RETURN_VALUE_USED(opline)) {
fcall_end_change_scope:
if (Z_OBJ(EG(This))) {
- if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
- if (EX(call)->is_ctor_result_used) {
+ if (UNEXPECTED(EG(exception) != NULL) && (EX(call)->flags & ZEND_CALL_CTOR)) {
+ if (EX(call)->flags & ZEND_CALL_CTOR_RESULT_USED) {
Z_DELREF(EG(This));
}
if (Z_REFCOUNT(EG(This)) == 1) {
}
}
if (!Z_DELREF(EG(This))) {
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
+ EX(call)->flags &= ~ZEND_CALL_DONE;
_zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC);
} else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) {
gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC);
EG(called_scope) = EX(called_scope);
fcall_end:
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
- EX(call)--;
-
- zend_vm_stack_clear_multiple(1 TSRMLS_CC);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free_call_frame(call, 1 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
-
- ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
- ZEND_VM_CONTINUE();
-}
-
-static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zval *tmp = EX_VAR(opline->result.var);
-
- SAVE_OPLINE();
- ZVAL_EMPTY_STRING(tmp);
- /*CHECK_EXCEPTION();*/
- ZEND_VM_NEXT_OPCODE();
-}
-
-static int ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- EX(function_state).function = EX(call)->fbc;
- return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-}
-
static int ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
/* The generator object is stored in EX(return_value) */
SAVE_OPLINE();
args = get_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, BP_VAR_R);
- arg_num = opline->op2.num + EX(call)->num_additional_args + 1;
+ arg_num = opline->op2.num + EX(call)->num_args + 1;
send_again:
switch (Z_TYPE_P(args)) {
/* check if any of arguments are going to be passed by reference */
for (i = 0; i < zend_hash_num_elements(ht); i++) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num + i)) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
separate = 1;
break;
}
}
top = zend_vm_stack_top_inc(TSRMLS_C);
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
if (!Z_IMMUTABLE_P(args)) {
ZVAL_MAKE_REF(arg);
Z_ADDREF_P(arg);
ZVAL_COPY(top, arg);
}
- EX(call)->num_additional_args++;
+ EX(call)->num_args++;
arg_num++;
} ZEND_HASH_FOREACH_END();
zval_dtor(&key);
}
- if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
+ if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
zend_error(
E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
" by unpacking a Traversable, passing by-value instead", arg_num,
- EX(call)->fbc->common.scope ? EX(call)->fbc->common.scope->name->val : "",
- EX(call)->fbc->common.scope ? "::" : "",
- EX(call)->fbc->common.function_name->val
+ EX(call)->func->common.scope ? EX(call)->func->common.scope->name->val : "",
+ EX(call)->func->common.scope ? "::" : "",
+ EX(call)->func->common.function_name->val
);
}
ZEND_VM_STACK_GROW_IF_NEEDED(1);
zend_vm_stack_push(arg TSRMLS_CC);
- EX(call)->num_additional_args++;
+ EX(call)->num_args++;
iter->funcs->move_forward(iter TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
{
USE_OPLINE
zend_uint arg_num = opline->op1.num;
- zval *arguments = EX(prev_execute_data)->function_state.arguments;
- zend_uint arg_count = Z_LVAL_P(arguments);
+ zend_uint arg_count = EX(prev_execute_data)->call->num_args;
SAVE_OPLINE();
if (UNEXPECTED(arg_num > arg_count)) {
zend_verify_missing_arg(execute_data, arg_num TSRMLS_CC);
} else {
zval *var_ptr;
- zval *param = arguments - arg_count + arg_num - 1;
+ zval *param = ZEND_CALL_ARG(EX(prev_execute_data)->call, arg_num);
if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zend_verify_arg_type((zend_function *) EX(op_array), arg_num, param, opline->extended_value TSRMLS_CC);
{
USE_OPLINE
zend_uint arg_num = opline->op1.num;
- zval *arguments = EX(prev_execute_data)->function_state.arguments;
- zend_uint arg_count = Z_LVAL_P(arguments);
+ zend_uint arg_count = EX(prev_execute_data)->call->num_args;
zval *params;
SAVE_OPLINE();
if (UNEXPECTED(Z_REFCOUNTED_P(params))) Z_DELREF_P(params);
if (arg_num <= arg_count) {
- zval *param = arguments - arg_count + arg_num - 1;
+ zval *param = ZEND_CALL_ARG(EX(prev_execute_data)->call, arg_num);
array_init_size(params, arg_count - arg_num + 1);
if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
}
ZEND_VM_JMP(opline->op2.jmp_addr);
} else {
- call_slot *call = EX(call_slots) + opline->extended_value;
+ /* We are not handling overloaded classes right now */
+ EX(call) = zend_vm_stack_push_call_frame(
+ constructor, 0,
+ RETURN_VALUE_USED(opline) ?
+ (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_USED) : ZEND_CALL_CTOR,
+ Z_CE_P(EX_VAR(opline->op1.var)),
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
}
- /* We are not handling overloaded classes right now */
- call->fbc = constructor;
- call->object = Z_OBJ(object_zval);
- call->called_scope = Z_CE_P(EX_VAR(opline->op1.var));
- call->num_additional_args = 0;
- call->is_ctor_call = 1;
- call->is_ctor_result_used = RETURN_VALUE_USED(opline);
- EX(call) = call;
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
int i;
zend_uint catch_op_num = 0, finally_op_num = 0, finally_op_end = 0;
- zval *stack_frame;
-
- /* Figure out where the next stack frame (which maybe contains pushed
- * arguments that have to be dtor'ed) starts */
- stack_frame = zend_vm_stack_frame_base(execute_data);
-
- /* If the exception was thrown during a function call there might be
- * arguments pushed to the stack that have to be dtor'ed. */
- while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
- zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
- zval_ptr_dtor(stack_zval_p);
- }
for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
}
}
- if (EX(call) >= EX(call_slots)) {
- call_slot *call = EX(call);
+ if (EX(call)) {
+ zend_call_frame *call = EX(call);
do {
+ zval *args = ZEND_CALL_ARG(call, 1);
+
+ /* If the exception was thrown during a function call there might be
+ * arguments pushed to the stack that have to be dtor'ed. */
+ while (zend_vm_stack_top(TSRMLS_C) != args) {
+ zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
+ zval_ptr_dtor(stack_zval_p);
+ }
if (call->object) {
- if (call->is_ctor_call) {
- if (call->is_ctor_result_used) {
+ if (call->flags & ZEND_CALL_CTOR) {
+ if (call->flags & ZEND_CALL_CTOR_RESULT_USED) {
GC_REFCOUNT(call->object)--;
}
if (GC_REFCOUNT(call->object) == 1) {
}
OBJ_RELEASE(call->object);
}
- call--;
- } while (call >= EX(call_slots));
+ EG(argument_stack)->top = (zval*)call;
+ call = call->prev;
+ } while (call);
EX(call) = NULL;
}
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *object;
zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
if (IS_CONST == IS_CONST) {
function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
}
STR_FREE(lcname);
- call->fbc = Z_FUNC_P(func);
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ Z_FUNC_P(func), 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != IS_CONST && IS_CONST != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object TSRMLS_CC) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
}
if (IS_CONST == IS_VAR && 0 && Z_REFCOUNT_P(function_name) == 1 &&
- call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
+ fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- call->fbc->common.prototype = (zend_function*)function_name_ptr;
+ fbc->common.prototype = (zend_function*)function_name_ptr;
} else {
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
if (Z_TYPE_P(obj) == IS_STRING) {
- call->object = NULL;
- call->called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(call->called_scope == NULL)) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
+ if (UNEXPECTED(called_scope == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
- if (call->called_scope->get_static_method) {
- call->fbc = call->called_scope->get_static_method(call->called_scope, Z_STR_P(method) TSRMLS_CC);
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(call->called_scope, Z_STR_P(method), NULL TSRMLS_CC);
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", call->called_scope->name->val, Z_STRVAL_P(method));
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
}
} else {
- call->called_scope = Z_OBJCE_P(obj);
- call->object = Z_OBJ_P(obj);
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
- call->fbc = Z_OBJ_HT_P(obj)->get_method(&call->object, Z_STR_P(method), NULL TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(method));
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(object), Z_STRVAL_P(method));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(object)++; /* For $this pointer */
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *func_name;
zval *func;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_function *fbc;
func_name = opline->op2.zv + 1;
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if ((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL) {
func_name++;
if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *fname = opline->op2.zv;
+ zval *func;
+ zend_function *fbc;
+
+ if (CACHED_PTR(Z_CACHE_SLOT_P(fname))) {
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname));
+ } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(fname))) == NULL)) {
+ SAVE_OPLINE();
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(fname));
+ } else {
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc);
+ }
+
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
ZEND_VM_NEXT_OPCODE();
}
{
USE_OPLINE
zend_uint arg_num = opline->op1.num;
- zval *arguments = EX(prev_execute_data)->function_state.arguments;
- zend_uint arg_count = Z_LVAL_P(arguments);
+ zend_uint arg_count = EX(prev_execute_data)->call->num_args;
zval *var_ptr;
SAVE_OPLINE();
}
}
} else {
- zval *param = arguments - arg_count + arg_num - 1;
+ zval *param = ZEND_CALL_ARG(EX(prev_execute_data)->call, arg_num);
ZVAL_COPY(var_ptr, param);
}
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *object;
zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
if (IS_TMP_VAR == IS_CONST) {
function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
STR_FREE(lcname);
zval_dtor(free_op2.var);
- call->fbc = Z_FUNC_P(func);
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ Z_FUNC_P(func), 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object TSRMLS_CC) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
}
if (IS_TMP_VAR == IS_VAR && 1 && Z_REFCOUNT_P(function_name) == 1 &&
- call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
+ fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- call->fbc->common.prototype = (zend_function*)function_name_ptr;
+ fbc->common.prototype = (zend_function*)function_name_ptr;
} else {
zval_dtor(free_op2.var);
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
if (Z_TYPE_P(obj) == IS_STRING) {
- call->object = NULL;
- call->called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(call->called_scope == NULL)) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
+ if (UNEXPECTED(called_scope == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
- if (call->called_scope->get_static_method) {
- call->fbc = call->called_scope->get_static_method(call->called_scope, Z_STR_P(method) TSRMLS_CC);
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(call->called_scope, Z_STR_P(method), NULL TSRMLS_CC);
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", call->called_scope->name->val, Z_STRVAL_P(method));
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
}
} else {
- call->called_scope = Z_OBJCE_P(obj);
- call->object = Z_OBJ_P(obj);
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
- call->fbc = Z_OBJ_HT_P(obj)->get_method(&call->object, Z_STR_P(method), NULL TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(method));
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(object), Z_STRVAL_P(method));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(object)++; /* For $this pointer */
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *object;
zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
if (IS_VAR == IS_CONST) {
function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
STR_FREE(lcname);
zval_ptr_dtor_nogc(free_op2.var);
- call->fbc = Z_FUNC_P(func);
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ Z_FUNC_P(func), 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != IS_CONST && IS_VAR != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object TSRMLS_CC) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
}
if (IS_VAR == IS_VAR && (free_op2.var != NULL) && Z_REFCOUNT_P(function_name) == 1 &&
- call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
+ fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- call->fbc->common.prototype = (zend_function*)function_name_ptr;
+ fbc->common.prototype = (zend_function*)function_name_ptr;
} else {
zval_ptr_dtor_nogc(free_op2.var);
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
if (Z_TYPE_P(obj) == IS_STRING) {
- call->object = NULL;
- call->called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(call->called_scope == NULL)) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
+ if (UNEXPECTED(called_scope == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
- if (call->called_scope->get_static_method) {
- call->fbc = call->called_scope->get_static_method(call->called_scope, Z_STR_P(method) TSRMLS_CC);
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(call->called_scope, Z_STR_P(method), NULL TSRMLS_CC);
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", call->called_scope->name->val, Z_STRVAL_P(method));
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
}
} else {
- call->called_scope = Z_OBJCE_P(obj);
- call->object = Z_OBJ_P(obj);
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
- call->fbc = Z_OBJ_HT_P(obj)->get_method(&call->object, Z_STR_P(method), NULL TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(method));
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(object), Z_STRVAL_P(method));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(object)++; /* For $this pointer */
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *object;
zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
if (IS_CV == IS_CONST) {
function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- call->fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), call->fbc);
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
}
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
}
STR_FREE(lcname);
- call->fbc = Z_FUNC_P(func);
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ Z_FUNC_P(func), 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != IS_CONST && IS_CV != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object TSRMLS_CC) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
}
if (IS_CV == IS_VAR && 0 && Z_REFCOUNT_P(function_name) == 1 &&
- call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
+ fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- call->fbc->common.prototype = (zend_function*)function_name_ptr;
+ fbc->common.prototype = (zend_function*)function_name_ptr;
} else {
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
if (Z_TYPE_P(obj) == IS_STRING) {
- call->object = NULL;
- call->called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(call->called_scope == NULL)) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0 TSRMLS_CC);
+ if (UNEXPECTED(called_scope == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
- if (call->called_scope->get_static_method) {
- call->fbc = call->called_scope->get_static_method(call->called_scope, Z_STR_P(method) TSRMLS_CC);
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(call->called_scope, Z_STR_P(method), NULL TSRMLS_CC);
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", call->called_scope->name->val, Z_STRVAL_P(method));
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
}
} else {
- call->called_scope = Z_OBJCE_P(obj);
- call->object = Z_OBJ_P(obj);
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
- call->fbc = Z_OBJ_HT_P(obj)->get_method(&call->object, Z_STR_P(method), NULL TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(method));
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(object), Z_STRVAL_P(method));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(object)++; /* For $this pointer */
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
ZEND_VM_JMP(opline);
}
-static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
-
- zval *fname = opline->op1.zv;
- zval *func;
- call_slot *call = EX(call_slots) + opline->op2.num;
-
- if (CACHED_PTR(Z_CACHE_SLOT_P(fname))) {
- EX(function_state).function = CACHED_PTR(Z_CACHE_SLOT_P(fname));
- } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(fname))) == NULL)) {
- SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(fname));
- } else {
- EX(function_state).function = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(fname), EX(function_state).function);
- }
-
- call->fbc = EX(function_state).function;
- call->object = NULL;
- call->called_scope = NULL;
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
-
- return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-}
-
static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
SAVE_OPLINE();
- if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
- if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) {
+ if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num);
}
}
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
+ zend_call_frame *call;
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
- EX(function_state).function = (zend_function *) new_op_array;
+ EX(call) = zend_vm_stack_push_call_frame(
+ (zend_function*)new_op_array, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
zend_execute(new_op_array, return_value TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free((zval*)call TSRMLS_CC);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_CONST == IS_CONST &&
IS_CONST == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_CONST != IS_CONST &&
IS_CONST == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_CONST != IS_UNUSED) {
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_CONST == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_CONST != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ if (IS_CONST != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
+ }
+ }
+
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_CONST == IS_CONST &&
IS_TMP_VAR == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_CONST != IS_CONST &&
IS_TMP_VAR == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_TMP_VAR != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ if (IS_CONST != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
+ }
+ }
+
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_CONST == IS_CONST &&
IS_VAR == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_CONST != IS_CONST &&
IS_VAR == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_VAR != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ if (IS_CONST != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
+ }
+ }
+
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_CONST == IS_CONST &&
IS_UNUSED == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_CONST != IS_CONST &&
IS_UNUSED == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_UNUSED != IS_UNUSED) {
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_UNUSED == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_UNUSED != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ }
+
+ if (IS_CONST != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
closure_is_static = Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC;
- closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC;
+ closure_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->call->func->common.fn_flags & ZEND_ACC_STATIC;
if (closure_is_static || closure_is_being_defined_inside_static_context) {
zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(called_scope), NULL TSRMLS_CC);
} else {
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_CONST == IS_CONST &&
IS_CV == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_CONST != IS_CONST &&
IS_CV == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_CV != IS_UNUSED) {
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_CV == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_CV != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ }
+
+ if (IS_CONST != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
zend_free_op free_op1;
SAVE_OPLINE();
- if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
- if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) {
+ if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num);
}
}
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
+ zend_call_frame *call;
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
- EX(function_state).function = (zend_function *) new_op_array;
+ EX(call) = zend_vm_stack_push_call_frame(
+ (zend_function*)new_op_array, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
zend_execute(new_op_array, return_value TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free((zval*)call TSRMLS_CC);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
USE_OPLINE
zval *function_name;
zend_free_op free_op1;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CONST != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CONST == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
USE_OPLINE
zval *function_name;
zend_free_op free_op1, free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
USE_OPLINE
zval *function_name;
zend_free_op free_op1, free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
USE_OPLINE
zval *function_name;
zend_free_op free_op1;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CV != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CV == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
} else {
- if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
}
} else {
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
- !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
top = zend_vm_stack_top_inc(TSRMLS_C);
zval *varptr, *top;
zend_free_op free_op1;
- if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
}
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
+ zend_call_frame *call;
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
- EX(function_state).function = (zend_function *) new_op_array;
+ EX(call) = zend_vm_stack_push_call_frame(
+ (zend_function*)new_op_array, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
zend_execute(new_op_array, return_value TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free((zval*)call TSRMLS_CC);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
USE_OPLINE
zval *function_name;
zend_free_op free_op1;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CONST != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CONST == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op1.var);
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_VAR == IS_CONST &&
IS_CONST == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_VAR != IS_CONST &&
IS_CONST == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_CONST != IS_UNUSED) {
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_CONST == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_CONST != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ }
+
+ if (IS_VAR != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
zend_free_op free_op1, free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
zval_ptr_dtor_nogc(free_op1.var);
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_VAR == IS_CONST &&
IS_TMP_VAR == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_VAR != IS_CONST &&
IS_TMP_VAR == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_TMP_VAR != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ if (IS_VAR != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
+ }
+ }
+
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
zend_free_op free_op1, free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
zval_ptr_dtor_nogc(free_op1.var);
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_VAR == IS_CONST &&
IS_VAR == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_VAR != IS_CONST &&
IS_VAR == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_VAR != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ }
+
+ if (IS_VAR != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_VAR == IS_CONST &&
IS_UNUSED == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_VAR != IS_CONST &&
IS_UNUSED == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_UNUSED != IS_UNUSED) {
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_UNUSED == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_UNUSED != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ }
+
+ if (IS_VAR != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
zend_free_op free_op1;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CV != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CV == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op1.var);
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_object *object;
+ zend_function *fbc;
SAVE_OPLINE();
}
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
}
- call->called_scope = ce;
} else {
ce = Z_CE_P(EX_VAR(opline->op1.var));
-
- if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- call->called_scope = EG(called_scope);
- } else {
- call->called_scope = ce;
- }
}
if (IS_VAR == IS_CONST &&
IS_CV == IS_CONST &&
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
- call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else if (IS_VAR != IS_CONST &&
IS_CV == IS_CONST &&
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
/* do nothing */
} else if (IS_CV != IS_UNUSED) {
}
if (ce->get_static_method) {
- call->fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
+ fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
} else {
- call->fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(call->fbc == NULL)) {
+ if (UNEXPECTED(fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
}
if (IS_CV == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(Z_CACHE_SLOT_P(function_name), call->fbc);
+ CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc);
} else {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, call->fbc);
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc);
}
}
if (IS_CV != IS_CONST) {
if (Z_OBJ(EG(This)) && Z_OBJCE(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name->val);
}
- call->fbc = ce->constructor;
+ fbc = ce->constructor;
}
- if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
- call->object = NULL;
+ if (fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ object = NULL;
} else {
if (Z_OBJ(EG(This)) &&
Z_OBJ_HT(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name->val, call->fbc->common.function_name->val);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ object = Z_OBJ(EG(This));
+ if (object) {
+ GC_REFCOUNT(object)++;
}
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ if (IS_VAR != IS_CONST) {
+ if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
+ ce = EG(called_scope);
+ }
+ }
+
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zval *function_name;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_obj_zval_ptr_unused(TSRMLS_C);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CONST != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CONST == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
USE_OPLINE
zval *function_name;
zend_free_op free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_obj_zval_ptr_unused(TSRMLS_C);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
USE_OPLINE
zval *function_name;
zend_free_op free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_obj_zval_ptr_unused(TSRMLS_C);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
USE_OPLINE
zval *function_name;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_obj_zval_ptr_unused(TSRMLS_C);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CV != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CV == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
} else {
- if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
}
} else {
if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ?
!(opline->extended_value & ZEND_ARG_SEND_SILENT) :
- !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
top = zend_vm_stack_top_inc(TSRMLS_C);
zval *varptr, *top;
- if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.num)) {
+ if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {
return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
}
HANDLE_EXCEPTION();
} else if (EXPECTED(new_op_array != NULL)) {
zval *return_value = NULL;
+ zend_call_frame *call;
EG(active_op_array) = new_op_array;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
}
- EX(function_state).function = (zend_function *) new_op_array;
+ EX(call) = zend_vm_stack_push_call_frame(
+ (zend_function*)new_op_array, 0, 0, NULL, NULL, EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
zend_execute(new_op_array, return_value TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
+ call = EX(call);
+ EX(call) = EX(call)->prev;
+ zend_vm_stack_free((zval*)call TSRMLS_CC);
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
USE_OPLINE
zval *function_name;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CONST != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CONST == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
USE_OPLINE
zval *function_name;
zend_free_op free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
USE_OPLINE
zval *function_name;
zend_free_op free_op2;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_VAR == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_VAR == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
USE_OPLINE
zval *function_name;
- call_slot *call = EX(call_slots) + opline->result.num;
zval *object;
+ zend_function *fbc;
+ zend_class_entry *called_scope;
+ zend_object *obj;
SAVE_OPLINE();
}
object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- call->object = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
+ obj = Z_TYPE_P(object) == IS_OBJECT ? Z_OBJ_P(object) : NULL;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (EXPECTED(obj != NULL)) {
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
if (IS_CV != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- call->fbc = object->handlers->get_method(&call->object, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(call->fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_P(function_name));
+ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(obj), Z_STRVAL_P(function_name));
}
if (IS_CV == IS_CONST &&
- EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(call->object == object)) {
- CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope, call->fbc);
+ EXPECTED(fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(obj == orig_obj)) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc);
}
}
} else {
zend_error_noreturn(E_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object)));
}
- if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- call->object = NULL;
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ obj = NULL;
} else {
- GC_REFCOUNT(call->object)++; /* For $this pointer */
+ GC_REFCOUNT(obj)++; /* For $this pointer */
}
- call->num_additional_args = 0;
- call->is_ctor_call = 0;
- EX(call) = call;
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, 0, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
- ZEND_DO_FCALL_SPEC_CONST_HANDLER,
- ZEND_DO_FCALL_SPEC_CONST_HANDLER,
- ZEND_DO_FCALL_SPEC_CONST_HANDLER,
- ZEND_DO_FCALL_SPEC_CONST_HANDLER,
- ZEND_DO_FCALL_SPEC_CONST_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_DO_FCALL_SPEC_HANDLER,
+ ZEND_INIT_FCALL_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_FCALL_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_FCALL_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_FCALL_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_FCALL_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
- ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
ZEND_RETURN_SPEC_CONST_HANDLER,
ZEND_RETURN_SPEC_CONST_HANDLER,
ZEND_RETURN_SPEC_CONST_HANDLER,
ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS)
{
- return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}