ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
{
vm_frame_kind frame_kind = EX(frame_kind);
+ zend_execute_data *prev_nested_call;
EG(current_execute_data) = EX(prev_execute_data);
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_clean_and_cache_symbol_table(EX(symbol_table) TSRMLS_CC);
}
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(op_array)->prototype) {
- zval_ptr_dtor((zval*)EX(op_array)->prototype);
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
+ zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
- zend_vm_stack_free((char*)execute_data TSRMLS_CC);
+ prev_nested_call = EX(prev_nested_call);
+ zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
+ zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
execute_data = EG(current_execute_data);
+ EX(call) = prev_nested_call;
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->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(opline)->op1.num & ZEND_CALL_CTOR)) {
+ if (!(EX(opline)->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
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);
-
if (UNEXPECTED(EG(exception) != NULL)) {
zend_op *opline = EX(opline);
zend_throw_exception_internal(NULL TSRMLS_CC);
ZEND_VM_LEAVE();
} else if (frame_kind == VM_FRAME_NESTED_CODE) {
zend_detach_symbol_table(execute_data);
- destroy_op_array(EX(op_array) TSRMLS_CC);
- efree(EX(op_array));
- zend_vm_stack_free((char*)execute_data TSRMLS_CC);
+ destroy_op_array(&EX(func)->op_array TSRMLS_CC);
+ efree(EX(func));
+ prev_nested_call = EX(prev_nested_call);
+ zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
execute_data = EG(current_execute_data);
+ EX(call) = prev_nested_call;
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);
+ EG(active_op_array) = &EX(func)->op_array;
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
} else {
if (frame_kind == VM_FRAME_TOP_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
+ zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
} else /* if (frame_kind == VM_FRAME_TOP_CODE) */ {
zend_array *symbol_table = EX(symbol_table);
zend_execute_data *old_execute_data;
zend_detach_symbol_table(execute_data);
old_execute_data = EX(prev_execute_data);
while (old_execute_data) {
- if (old_execute_data->op_array) {
+ if (old_execute_data->func && ZEND_USER_CODE(old_execute_data->func->op_array.type)) {
if (old_execute_data->symbol_table == symbol_table) {
zend_attach_symbol_table(old_execute_data);
}
old_execute_data = old_execute_data->prev_execute_data;
}
}
- if ((EX(op_array)->fn_flags & ZEND_ACC_CLOSURE) && EX(op_array)->prototype) {
- zval_ptr_dtor((zval*)EX(op_array)->prototype);
+ if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
+ zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
+ }
+ prev_nested_call = EX(prev_nested_call);
+ zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
+
+ if (EG(current_execute_data)) {
+ EG(current_execute_data)->call = prev_nested_call;
}
- zend_vm_stack_free((char*)execute_data TSRMLS_CC);
EG(opline_ptr) = NULL;
ZEND_VM_RETURN();
}
}
-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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object 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;
-
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
FREE_OP2();
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (OP2_TYPE != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (OP1_TYPE != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 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
- zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_function *fbc;
+ zval *function_name, *func;
if (OP2_TYPE == IS_CONST) {
- function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
+ 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, opline->extended_value, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
zend_string *lcname;
zend_free_op free_op2;
+ zend_class_entry *called_scope;
+ zend_object *object;
+ zval *function_name_ptr;
SAVE_OPLINE();
function_name_ptr = function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
}
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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
} 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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else if (OP2_TYPE != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
}
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;
-
FREE_OP2();
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, opline->extended_value, 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, opline->extended_value, 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, opline->extended_value, 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_execute_data *call = EX(call);
+ zend_function *fbc = call->func;
+
+ SAVE_OPLINE();
+ call->flags = ZEND_CALL_DONE;
+ 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) &&
+ !call->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);
+ }
+ }
+
+ LOAD_OPLINE();
+
+ if (UNEXPECTED(fbc->type == ZEND_INTERNAL_FUNCTION)) {
+ int should_change_scope = 0;
+ zval *ret;
+
+ if (fbc->common.scope) {
+ should_change_scope = 1;
+ Z_OBJ(EG(This)) = call->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) = (call->object) ? NULL : fbc->common.scope;
+#else
+ EG(scope) = fbc->common.scope;
+#endif
+ EG(called_scope) = call->called_scope;
+ }
+
+ if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
+ zend_uint i;
+ zval *p = ZEND_CALL_ARG(call, 1);
+
+ for (i = 0; i < call->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(call->num_args, ret TSRMLS_CC);
+ } else {
+ zend_execute_internal(execute_data, NULL TSRMLS_CC);
+ }
+
+ zend_vm_stack_free_args(call TSRMLS_CC);
+
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+
+ if (!RETURN_VALUE_USED(opline)) {
+ zval_ptr_dtor(ret);
+ }
- ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
+ if (UNEXPECTED(should_change_scope)) {
+ ZEND_VM_C_GOTO(fcall_end_change_scope);
+ } else {
+ ZEND_VM_C_GOTO(fcall_end);
+ }
+ } else if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+ zval *return_value = NULL;
+
+ Z_OBJ(EG(This)) = call->object;
+ EG(scope) = fbc->common.scope;
+ EG(called_scope) = 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((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (RETURN_VALUE_USED(opline)) {
+ zend_generator_create_zval(&fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
+ }
+
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+ } else {
+ call->prev_execute_data = EG(current_execute_data);
+ i_init_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
+
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
+ ZEND_VM_ENTER();
+ } else {
+ execute_ex(call TSRMLS_CC);
+ }
+ }
+
+ EG(opline_ptr) = &EX(opline);
+ EG(active_op_array) = &EX(func)->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)) = call->object;
+//??? EG(scope) = NULL;
+ EG(scope) = fbc->common.scope;
+ EG(called_scope) = 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(call->object != NULL)) {
+ call->object->handlers->call_method(fbc->common.function_name, call->object, call->num_args, EX_VAR(opline->result.var) TSRMLS_CC);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
+ }
+
+ zend_vm_stack_free_args(call TSRMLS_CC);
+
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+
+ 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) && (opline->op1.num & ZEND_CALL_CTOR)) {
+ if (!(opline->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
+ 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))) {
+ _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):
+ 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)
/* Check whether an exception has been thrown, if not, jump over code */
zend_exception_restore(TSRMLS_C);
if (EG(exception) == NULL) {
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]);
ZEND_VM_CONTINUE(); /* CHECK_ME */
}
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
}
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]);
ZEND_VM_CONTINUE(); /* CHECK_ME */
}
}
ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
{
USE_OPLINE
- zval *value, *top;
+ zval *value, *arg;
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);
}
}
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
- top = zend_vm_stack_top_inc(TSRMLS_C);
- ZVAL_COPY_VALUE(top, value);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, value);
if (OP1_TYPE == IS_CONST) {
- if (UNEXPECTED(Z_OPT_COPYABLE_P(top))) {
- zval_copy_ctor_func(top);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) {
+ zval_copy_ctor_func(arg);
}
}
ZEND_VM_NEXT_OPCODE();
ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY)
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
zend_free_op free_op1;
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (Z_ISREF_P(varptr)) {
- ZVAL_COPY(top, Z_REFVAL_P(varptr));
+ ZVAL_COPY(arg, Z_REFVAL_P(varptr));
FREE_OP1();
} else {
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
if (OP1_TYPE == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+ if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
}
ZEND_VM_NEXT_OPCODE();
{
USE_OPLINE
zend_free_op free_op1;
- zval *varptr, *top;
+ zval *varptr, *arg;
SAVE_OPLINE();
if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
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);
}
}
if (OP1_TYPE == IS_CV) {
Z_ADDREF_P(varptr);
}
- zend_vm_stack_push(varptr TSRMLS_CC);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, varptr);
} 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_COPY(top, varptr);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY(arg, varptr);
FREE_OP1_IF_VAR();
}
CHECK_EXCEPTION();
{
USE_OPLINE
zend_free_op free_op1;
- zval *varptr, *top;
+ zval *varptr, *arg;
SAVE_OPLINE();
varptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
}
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
- ZVAL_NEW_REF(top, &EG(uninitialized_zval));
+ ZVAL_NEW_REF(arg, &EG(uninitialized_zval));
ZEND_VM_NEXT_OPCODE();
}
if (Z_ISREF_P(varptr)) {
Z_ADDREF_P(varptr);
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
} else if (OP1_TYPE == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
- ZVAL_COPY_VALUE(top, varptr);
- ZVAL_MAKE_REF(top);
+ ZVAL_COPY_VALUE(arg, varptr);
+ ZVAL_MAKE_REF(arg);
} else {
ZVAL_MAKE_REF(varptr);
Z_ADDREF_P(varptr);
- ZVAL_REF(top, Z_REF_P(varptr));
+ ZVAL_REF(arg, Z_REF_P(varptr));
}
FREE_OP1_VAR_PTR();
ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
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);
}
}
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (Z_ISREF_P(varptr)) {
- ZVAL_COPY(top, Z_REFVAL_P(varptr));
+ ZVAL_COPY(arg, Z_REFVAL_P(varptr));
FREE_OP1();
} else {
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
if (OP1_TYPE == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+ if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
}
ZEND_VM_NEXT_OPCODE();
SAVE_OPLINE();
args = GET_OP1_ZVAL_PTR(BP_VAR_R);
- arg_num = opline->op2.num + EX(call)->num_additional_args + 1;
+ arg_num = EX(call)->num_args + 1;
ZEND_VM_C_LABEL(send_again):
switch (Z_TYPE_P(args)) {
zval *arg, *top;
zend_string *name;
- ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
+ zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht) TSRMLS_DC);
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
int i;
/* 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;
}
ZEND_VM_NEXT_OPCODE();
}
- top = zend_vm_stack_top_inc(TSRMLS_C);
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
+ top = ZEND_CALL_ARG(EX(call), 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_DUP(top, arg);
}
} else if (Z_ISREF_P(arg)) {
+//TODO: change into ZVAL_COPY()???
ZVAL_DUP(top, Z_REFVAL_P(arg));
} else {
ZVAL_COPY(top, arg);
}
- EX(call)->num_additional_args++;
+ EX(call)->num_args++;
arg_num++;
} ZEND_HASH_FOREACH_END();
}
for (; iter->funcs->valid(iter TSRMLS_CC) == SUCCESS; ++arg_num) {
- zval *arg;
+ zval *arg, *top;
if (UNEXPECTED(EG(exception) != NULL)) {
ZEND_VM_C_GOTO(unpack_iter_dtor);
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
);
}
if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
- ZEND_VM_STACK_GROW_IF_NEEDED(1);
- zend_vm_stack_push(arg TSRMLS_CC);
- EX(call)->num_additional_args++;
+ zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1 TSRMLS_DC);
+ top = ZEND_CALL_ARG(EX(call), arg_num);
+ ZVAL_COPY_VALUE(top, arg);
+ 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);
SAVE_OPLINE();
- if (UNEXPECTED(arg_num > arg_count)) {
+ if (UNEXPECTED(arg_num > EX(num_args))) {
zend_verify_missing_arg(execute_data, arg_num TSRMLS_CC);
- } else {
- zval *var_ptr;
- zval *param = arguments - arg_count + arg_num - 1;
+ CHECK_EXCEPTION();
+ } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+ zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- 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);
- }
- var_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- if (UNEXPECTED(Z_REFCOUNTED_P(var_ptr))) Z_DELREF_P(var_ptr);
- ZVAL_COPY(var_ptr, param);
+ zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ CHECK_EXCEPTION();
}
- CHECK_EXCEPTION();
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);
- zval *var_ptr;
+ zval *param;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- if (UNEXPECTED(Z_REFCOUNTED_P(var_ptr))) Z_DELREF_P(var_ptr);
- if (arg_num > arg_count) {
- ZVAL_COPY_VALUE(var_ptr, opline->op2.zv);
- if (Z_OPT_CONSTANT_P(var_ptr)) {
- zval_update_constant(var_ptr, 0 TSRMLS_CC);
+ param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
+ if (arg_num > EX(num_args)) {
+ ZVAL_COPY_VALUE(param, opline->op2.zv);
+ if (Z_OPT_CONSTANT_P(param)) {
+ zval_update_constant(param, 0 TSRMLS_CC);
} else {
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
- if (UNEXPECTED(Z_OPT_COPYABLE_P(var_ptr))) {
- zval_copy_ctor_func(var_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) {
+ zval_copy_ctor_func(param);
}
}
- } else {
- zval *param = arguments - arg_count + arg_num - 1;
- ZVAL_COPY(var_ptr, param);
}
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- zend_verify_arg_type((zend_function *) EX(op_array), arg_num, var_ptr, opline->extended_value TSRMLS_CC);
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+ zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
}
CHECK_EXCEPTION();
{
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(num_args);
zval *params;
SAVE_OPLINE();
params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- 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;
+
array_init_size(params, arg_count - arg_num + 1);
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- do {
- zend_verify_arg_type((zend_function *) EX(op_array), arg_num, param, opline->extended_value TSRMLS_CC);
+ param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+ do {
+ zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
param++;
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), execute_data TSRMLS_CC);
- ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
+ &EX(func)->op_array, execute_data TSRMLS_CC);
+ ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
}
ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), execute_data TSRMLS_CC);
- ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
+ &EX(func)->op_array, execute_data TSRMLS_CC);
+ ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
}
ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
- EX(op_array), execute_data TSRMLS_CC);
+ &EX(func)->op_array, execute_data TSRMLS_CC);
- brk_opline = EX(op_array)->opcodes + el->brk;
+ brk_opline = EX(func)->op_array.opcodes + el->brk;
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
}
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, opline->extended_value,
+ RETURN_VALUE_USED(opline) ?
+ ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED),
+ 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();
}
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, EG(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
+ EX(call)->prev_execute_data = EG(current_execute_data);
+ i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
- i_create_execute_data_from_op_array(new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array, return_value TSRMLS_CC);
+ execute_ex(EG(current_execute_data) TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->op_array;
destroy_op_array(new_op_array TSRMLS_CC);
efree(new_op_array);
if (UNEXPECTED(EG(exception) != NULL)) {
ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
{
SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name->val, EX(op_array)->function_name->val);
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name->val, EX(func)->op_array.function_name->val);
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
{
SAVE_OPLINE();
if (!EG(no_extensions)) {
- zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(op_array) TSRMLS_CC);
+ zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(func) TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
{
SAVE_OPLINE();
if (!EG(no_extensions)) {
- zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(op_array) TSRMLS_CC);
+ zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(func) TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
{
SAVE_OPLINE();
if (!EG(no_extensions)) {
- zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(op_array) TSRMLS_CC);
+ zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(func) TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
SAVE_OPLINE();
- Z_CE_P(EX_VAR(opline->result.var)) = do_bind_class(EX(op_array), opline, EG(class_table), 0 TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = do_bind_class(&EX(func)->op_array, opline, EG(class_table), 0 TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
USE_OPLINE
SAVE_OPLINE();
- Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(EX(op_array), opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
if ((zce = zend_hash_find(EG(class_table), Z_STR_P(opline->op2.zv))) == NULL ||
((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(opline->op1.zv))) != NULL &&
Z_CE_P(zce) != Z_CE_P(orig_zce))) {
- do_bind_inherited_class(EX(op_array), opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
+ do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
SAVE_OPLINE();
- do_bind_function(EX(op_array), opline, EG(function_table), 0);
+ do_bind_function(&EX(func)->op_array, opline, EG(function_table), 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
{
- zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
+ zend_uint op_num = EG(opline_before_exception) - EX(func)->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) {
+ for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
+ if (EX(func)->op_array.try_catch_array[i].try_op > op_num) {
/* further blocks will not be relevant... */
break;
}
- if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
+ if (op_num < EX(func)->op_array.try_catch_array[i].catch_op) {
+ catch_op_num = EX(func)->op_array.try_catch_array[i].catch_op;
}
- if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
+ if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) {
+ finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op;
}
- if (op_num >= EG(active_op_array)->try_catch_array[i].finally_op &&
- op_num < EG(active_op_array)->try_catch_array[i].finally_end) {
- finally_op_end = EG(active_op_array)->try_catch_array[i].finally_end;
+ if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
+ op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
+ finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
}
}
- if (EX(call) >= EX(call_slots)) {
- call_slot *call = EX(call);
+ if (EX(call)) {
+ zend_execute_data *call = EX(call);
do {
+ /* If the exception was thrown during a function call there might be
+ * arguments pushed to the stack that have to be dtor'ed. */
+ zend_vm_stack_free_args(EX(call) TSRMLS_CC);
+
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_UNUSED)) {
GC_REFCOUNT(call->object)--;
}
if (GC_REFCOUNT(call->object) == 1) {
}
OBJ_RELEASE(call->object);
}
- call--;
- } while (call >= EX(call_slots));
- EX(call) = NULL;
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+ call = EX(call);
+ } while (call);
}
- for (i=0; i<EX(op_array)->last_brk_cont; i++) {
- if (EX(op_array)->brk_cont_array[i].start < 0) {
+ for (i = 0; i < EX(func)->op_array.last_brk_cont; i++) {
+ if (EX(func)->op_array.brk_cont_array[i].start < 0) {
continue;
- } else if (EX(op_array)->brk_cont_array[i].start > op_num) {
+ } else if (EX(func)->op_array.brk_cont_array[i].start > op_num) {
/* further blocks will not be relevant... */
break;
- } else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
+ } else if (op_num < EX(func)->op_array.brk_cont_array[i].brk) {
if (!catch_op_num ||
- catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
- zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
+ catch_op_num >= EX(func)->op_array.brk_cont_array[i].brk) {
+ zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
EX(delayed_exception) = EG(exception);
EG(exception) = NULL;
EX(fast_ret) = NULL;
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
} else if (catch_op_num) {
if (finally_op_end && catch_op_num > finally_op_end) {
EX(delayed_exception) = NULL;
}
}
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
ZEND_VM_CONTINUE();
} else {
if (EX(delayed_exception)) {
zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
EX(delayed_exception) = NULL;
}
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
} else {
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
case ZEND_USER_OPCODE_CONTINUE:
ZEND_VM_CONTINUE();
case ZEND_USER_OPCODE_RETURN:
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
} else {
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
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 {
if (OP1_TYPE != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
if (opline->extended_value &&
UNEXPECTED(EG(prev_exception) != NULL)) {
/* in case of unhandled exception jump to catch block instead of finally */
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
}
EX(fast_ret) = opline + 1;
USE_OPLINE
if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) {
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
} else {
EG(exception) = EX(delayed_exception);
EX(delayed_exception) = NULL;
if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
- } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
} else {
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
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)
ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value TSRMLS_DC)
{
+ zend_execute_data *execute_data;
+
if (EG(exception) != NULL) {
return;
- }
- zend_execute_ex(i_create_execute_data_from_op_array(op_array, return_value, EG(active_symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC) TSRMLS_CC);
+ }
+
+ if (EG(current_execute_data) && EG(current_execute_data)->call) {
+ execute_data = EG(current_execute_data)->call;
+ } else {
+ execute_data = zend_vm_stack_push_call_frame(
+ (zend_function*)op_array, 0, 0, EG(called_scope), Z_OBJ(EG(This)), NULL TSRMLS_CC);
+ }
+ EX(prev_execute_data) = EG(current_execute_data);
+ i_init_execute_data(execute_data, op_array, return_value, EG(active_symbol_table) ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
+ zend_execute_ex(execute_data TSRMLS_CC);
}
static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
vm_frame_kind frame_kind = EX(frame_kind);
+ zend_execute_data *prev_nested_call;
EG(current_execute_data) = EX(prev_execute_data);
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_clean_and_cache_symbol_table(EX(symbol_table) TSRMLS_CC);
}
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(op_array)->prototype) {
- zval_ptr_dtor((zval*)EX(op_array)->prototype);
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
+ zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
}
- zend_vm_stack_free((char*)execute_data TSRMLS_CC);
+ prev_nested_call = EX(prev_nested_call);
+ zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
+ zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
execute_data = EG(current_execute_data);
+ EX(call) = prev_nested_call;
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->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(opline)->op1.num & ZEND_CALL_CTOR)) {
+ if (!(EX(opline)->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
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);
-
if (UNEXPECTED(EG(exception) != NULL)) {
zend_op *opline = EX(opline);
zend_throw_exception_internal(NULL TSRMLS_CC);
ZEND_VM_LEAVE();
} else if (frame_kind == VM_FRAME_NESTED_CODE) {
zend_detach_symbol_table(execute_data);
- destroy_op_array(EX(op_array) TSRMLS_CC);
- efree(EX(op_array));
- zend_vm_stack_free((char*)execute_data TSRMLS_CC);
+ destroy_op_array(&EX(func)->op_array TSRMLS_CC);
+ efree(EX(func));
+ prev_nested_call = EX(prev_nested_call);
+ zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
execute_data = EG(current_execute_data);
+ EX(call) = prev_nested_call;
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);
+ EG(active_op_array) = &EX(func)->op_array;
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
} else {
if (frame_kind == VM_FRAME_TOP_FUNCTION) {
i_free_compiled_variables(execute_data TSRMLS_CC);
+ zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
} else /* if (frame_kind == VM_FRAME_TOP_CODE) */ {
zend_array *symbol_table = EX(symbol_table);
zend_execute_data *old_execute_data;
zend_detach_symbol_table(execute_data);
old_execute_data = EX(prev_execute_data);
while (old_execute_data) {
- if (old_execute_data->op_array) {
+ if (old_execute_data->func && ZEND_USER_CODE(old_execute_data->func->op_array.type)) {
if (old_execute_data->symbol_table == symbol_table) {
zend_attach_symbol_table(old_execute_data);
}
old_execute_data = old_execute_data->prev_execute_data;
}
}
- if ((EX(op_array)->fn_flags & ZEND_ACC_CLOSURE) && EX(op_array)->prototype) {
- zval_ptr_dtor((zval*)EX(op_array)->prototype);
+ if ((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) && EX(func)->op_array.prototype) {
+ zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
+ }
+ prev_nested_call = EX(prev_nested_call);
+ zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
+
+ if (EG(current_execute_data)) {
+ EG(current_execute_data)->call = prev_nested_call;
}
- zend_vm_stack_free((char*)execute_data TSRMLS_CC);
EG(opline_ptr) = NULL;
ZEND_VM_RETURN();
}
}
-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_object *object;
- zend_uint num_args;
+
+ 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();
- object = EX(call)->object;
+ 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_execute_data *call = EX(call);
+ zend_function *fbc = call->func;
+
+ SAVE_OPLINE();
+ call->flags = ZEND_CALL_DONE;
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 (fbc->common.scope &&
!(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
- !object) {
+ !call->object) {
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
/* FIXME: output identifiers properly */
}
}
- 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) {
+ if (UNEXPECTED(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;
+ Z_OBJ(EG(This)) = call->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;
+ EG(scope) = (call->object) ? NULL : fbc->common.scope;
#else
EG(scope) = fbc->common.scope;
#endif
- EG(called_scope) = EX(call)->called_scope;
+ EG(called_scope) = call->called_scope;
}
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(call, 1);
- for (i = 0; i < num_args; ++i, ++p) {
+ for (i = 0; i < call->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)) {
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
- fbc->internal_function.handler(num_args, ret TSRMLS_CC);
+ fbc->internal_function.handler(call->num_args, ret TSRMLS_CC);
} else {
zend_execute_internal(execute_data, NULL TSRMLS_CC);
}
+ zend_vm_stack_free_args(call TSRMLS_CC);
+
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+
if (!RETURN_VALUE_USED(opline)) {
zval_ptr_dtor(ret);
}
} else {
goto fcall_end;
}
- } else if (fbc->type == ZEND_USER_FUNCTION) {
+ } else if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
zval *return_value = NULL;
- Z_OBJ(EG(This)) = object;
+ Z_OBJ(EG(This)) = call->object;
EG(scope) = fbc->common.scope;
- EG(called_scope) = EX(call)->called_scope;
+ EG(called_scope) = call->called_scope;
EG(active_symbol_table) = NULL;
EG(active_op_array) = &fbc->op_array;
if (RETURN_VALUE_USED(opline)) {
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 (UNEXPECTED((fbc->common.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);
+ zend_generator_create_zval(&fbc->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);
+
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+ } else {
+ call->prev_execute_data = EG(current_execute_data);
+ i_init_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
+
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
+ } else {
+ execute_ex(call TSRMLS_CC);
}
- } else {
- zend_execute(EG(active_op_array), return_value TSRMLS_CC);
}
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->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;
+ Z_OBJ(EG(This)) = call->object;
//??? EG(scope) = NULL;
EG(scope) = fbc->common.scope;
- EG(called_scope) = EX(call)->called_scope;
+ EG(called_scope) = 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);
+ if (EXPECTED(call->object != NULL)) {
+ call->object->handlers->call_method(fbc->common.function_name, call->object, call->num_args, EX_VAR(opline->result.var) TSRMLS_CC);
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
+ zend_vm_stack_free_args(call TSRMLS_CC);
+
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
STR_RELEASE(fbc->common.function_name);
}
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) && (opline->op1.num & ZEND_CALL_CTOR)) {
+ if (!(opline->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
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;
_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);
-
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
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 = EX(call)->num_args + 1;
send_again:
switch (Z_TYPE_P(args)) {
zval *arg, *top;
zend_string *name;
- ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
+ zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht) TSRMLS_DC);
if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
int i;
/* 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;
}
ZEND_VM_NEXT_OPCODE();
}
- top = zend_vm_stack_top_inc(TSRMLS_C);
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) {
+ top = ZEND_CALL_ARG(EX(call), 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_DUP(top, arg);
}
} else if (Z_ISREF_P(arg)) {
+//TODO: change into ZVAL_COPY()???
ZVAL_DUP(top, Z_REFVAL_P(arg));
} else {
ZVAL_COPY(top, arg);
}
- EX(call)->num_additional_args++;
+ EX(call)->num_args++;
arg_num++;
} ZEND_HASH_FOREACH_END();
}
for (; iter->funcs->valid(iter TSRMLS_CC) == SUCCESS; ++arg_num) {
- zval *arg;
+ zval *arg, *top;
if (UNEXPECTED(EG(exception) != NULL)) {
goto unpack_iter_dtor;
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
);
}
if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
- ZEND_VM_STACK_GROW_IF_NEEDED(1);
- zend_vm_stack_push(arg TSRMLS_CC);
- EX(call)->num_additional_args++;
+ zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1 TSRMLS_DC);
+ top = ZEND_CALL_ARG(EX(call), arg_num);
+ ZVAL_COPY_VALUE(top, arg);
+ 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);
SAVE_OPLINE();
- if (UNEXPECTED(arg_num > arg_count)) {
+ if (UNEXPECTED(arg_num > EX(num_args))) {
zend_verify_missing_arg(execute_data, arg_num TSRMLS_CC);
- } else {
- zval *var_ptr;
- zval *param = arguments - arg_count + arg_num - 1;
+ CHECK_EXCEPTION();
+ } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+ zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- 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);
- }
- var_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- if (UNEXPECTED(Z_REFCOUNTED_P(var_ptr))) Z_DELREF_P(var_ptr);
- ZVAL_COPY(var_ptr, param);
+ zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ CHECK_EXCEPTION();
}
- CHECK_EXCEPTION();
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(num_args);
zval *params;
SAVE_OPLINE();
params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- 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;
+
array_init_size(params, arg_count - arg_num + 1);
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+ param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
- zend_verify_arg_type((zend_function *) EX(op_array), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
param++;
}
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, opline->extended_value,
+ RETURN_VALUE_USED(opline) ?
+ ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED),
+ 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();
}
static int ZEND_FASTCALL ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name->val, EX(op_array)->function_name->val);
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name->val, EX(func)->op_array.function_name->val);
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
{
SAVE_OPLINE();
if (!EG(no_extensions)) {
- zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(op_array) TSRMLS_CC);
+ zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(func) TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
{
SAVE_OPLINE();
if (!EG(no_extensions)) {
- zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(op_array) TSRMLS_CC);
+ zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(func) TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
{
SAVE_OPLINE();
if (!EG(no_extensions)) {
- zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(op_array) TSRMLS_CC);
+ zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(func) TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
SAVE_OPLINE();
- Z_CE_P(EX_VAR(opline->result.var)) = do_bind_class(EX(op_array), opline, EG(class_table), 0 TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = do_bind_class(&EX(func)->op_array, opline, EG(class_table), 0 TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
USE_OPLINE
SAVE_OPLINE();
- Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(EX(op_array), opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
if ((zce = zend_hash_find(EG(class_table), Z_STR_P(opline->op2.zv))) == NULL ||
((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(opline->op1.zv))) != NULL &&
Z_CE_P(zce) != Z_CE_P(orig_zce))) {
- do_bind_inherited_class(EX(op_array), opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
+ do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
SAVE_OPLINE();
- do_bind_function(EX(op_array), opline, EG(function_table), 0);
+ do_bind_function(&EX(func)->op_array, opline, EG(function_table), 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
+ zend_uint op_num = EG(opline_before_exception) - EX(func)->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) {
+ for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
+ if (EX(func)->op_array.try_catch_array[i].try_op > op_num) {
/* further blocks will not be relevant... */
break;
}
- if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
+ if (op_num < EX(func)->op_array.try_catch_array[i].catch_op) {
+ catch_op_num = EX(func)->op_array.try_catch_array[i].catch_op;
}
- if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
+ if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) {
+ finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op;
}
- if (op_num >= EG(active_op_array)->try_catch_array[i].finally_op &&
- op_num < EG(active_op_array)->try_catch_array[i].finally_end) {
- finally_op_end = EG(active_op_array)->try_catch_array[i].finally_end;
+ if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
+ op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
+ finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
}
}
- if (EX(call) >= EX(call_slots)) {
- call_slot *call = EX(call);
+ if (EX(call)) {
+ zend_execute_data *call = EX(call);
do {
+ /* If the exception was thrown during a function call there might be
+ * arguments pushed to the stack that have to be dtor'ed. */
+ zend_vm_stack_free_args(EX(call) TSRMLS_CC);
+
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_UNUSED)) {
GC_REFCOUNT(call->object)--;
}
if (GC_REFCOUNT(call->object) == 1) {
}
OBJ_RELEASE(call->object);
}
- call--;
- } while (call >= EX(call_slots));
- EX(call) = NULL;
+ EX(call) = call->prev_nested_call;
+ zend_vm_stack_free_call_frame(call TSRMLS_CC);
+ call = EX(call);
+ } while (call);
}
- for (i=0; i<EX(op_array)->last_brk_cont; i++) {
- if (EX(op_array)->brk_cont_array[i].start < 0) {
+ for (i = 0; i < EX(func)->op_array.last_brk_cont; i++) {
+ if (EX(func)->op_array.brk_cont_array[i].start < 0) {
continue;
- } else if (EX(op_array)->brk_cont_array[i].start > op_num) {
+ } else if (EX(func)->op_array.brk_cont_array[i].start > op_num) {
/* further blocks will not be relevant... */
break;
- } else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
+ } else if (op_num < EX(func)->op_array.brk_cont_array[i].brk) {
if (!catch_op_num ||
- catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
- zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
+ catch_op_num >= EX(func)->op_array.brk_cont_array[i].brk) {
+ zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
EX(delayed_exception) = EG(exception);
EG(exception) = NULL;
EX(fast_ret) = NULL;
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
} else if (catch_op_num) {
if (finally_op_end && catch_op_num > finally_op_end) {
EX(delayed_exception) = NULL;
}
}
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
ZEND_VM_CONTINUE();
} else {
if (EX(delayed_exception)) {
zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
EX(delayed_exception) = NULL;
}
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
case ZEND_USER_OPCODE_CONTINUE:
ZEND_VM_CONTINUE();
case ZEND_USER_OPCODE_RETURN:
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
if (opline->extended_value &&
UNEXPECTED(EG(prev_exception) != NULL)) {
/* in case of unhandled exception jump to catch block instead of finally */
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
}
EX(fast_ret) = opline + 1;
USE_OPLINE
if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) {
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
} else {
EG(exception) = EX(delayed_exception);
EX(delayed_exception) = NULL;
if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
ZEND_VM_CONTINUE();
- } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_function *fbc;
+ zval *function_name, *func;
if (IS_CONST == IS_CONST) {
- function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
+ 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, opline->extended_value, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
zend_string *lcname;
+ zend_class_entry *called_scope;
+ zend_object *object;
+ zval *function_name_ptr;
SAVE_OPLINE();
function_name_ptr = function_name = opline->op2.zv;
}
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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
} 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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
}
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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, opline->extended_value, 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);
+ }
+
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, opline->extended_value, 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);
}
- 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, opline->extended_value, 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);
- zval *var_ptr;
+ zval *param;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- if (UNEXPECTED(Z_REFCOUNTED_P(var_ptr))) Z_DELREF_P(var_ptr);
- if (arg_num > arg_count) {
- ZVAL_COPY_VALUE(var_ptr, opline->op2.zv);
- if (Z_OPT_CONSTANT_P(var_ptr)) {
- zval_update_constant(var_ptr, 0 TSRMLS_CC);
+ param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
+ if (arg_num > EX(num_args)) {
+ ZVAL_COPY_VALUE(param, opline->op2.zv);
+ if (Z_OPT_CONSTANT_P(param)) {
+ zval_update_constant(param, 0 TSRMLS_CC);
} else {
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
- if (UNEXPECTED(Z_OPT_COPYABLE_P(var_ptr))) {
- zval_copy_ctor_func(var_ptr);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) {
+ zval_copy_ctor_func(param);
}
}
- } else {
- zval *param = arguments - arg_count + arg_num - 1;
- ZVAL_COPY(var_ptr, param);
}
- if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- zend_verify_arg_type((zend_function *) EX(op_array), arg_num, var_ptr, opline->extended_value TSRMLS_CC);
+ if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+ zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
}
CHECK_EXCEPTION();
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), execute_data TSRMLS_CC);
- ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
+ &EX(func)->op_array, execute_data TSRMLS_CC);
+ ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
}
static int ZEND_FASTCALL ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), execute_data TSRMLS_CC);
- ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
+ &EX(func)->op_array, execute_data TSRMLS_CC);
+ ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
}
static int ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
- EX(op_array), execute_data TSRMLS_CC);
+ &EX(func)->op_array, execute_data TSRMLS_CC);
- brk_opline = EX(op_array)->opcodes + el->brk;
+ brk_opline = EX(func)->op_array.opcodes + el->brk;
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_function *fbc;
+ zval *function_name, *func;
if (IS_TMP_VAR == IS_CONST) {
- function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
+ 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, opline->extended_value, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
zend_string *lcname;
zend_free_op free_op2;
+ zend_class_entry *called_scope;
+ zend_object *object;
+ zval *function_name_ptr;
SAVE_OPLINE();
function_name_ptr = function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
}
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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
} 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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
}
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;
-
zval_dtor(free_op2.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, opline->extended_value, 0, called_scope, object, EX(call) TSRMLS_CC);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
}
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_function *fbc;
+ zval *function_name, *func;
if (IS_VAR == IS_CONST) {
- function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
+ 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, opline->extended_value, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
zend_string *lcname;
zend_free_op free_op2;
+ zend_class_entry *called_scope;
+ zend_object *object;
+ zval *function_name_ptr;
SAVE_OPLINE();
function_name_ptr = function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
}
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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
} 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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
}
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;
-
zval_ptr_dtor_nogc(free_op2.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, opline->extended_value, 0, called_scope, object, EX(call) TSRMLS_CC);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
}
static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *function_name_ptr, *function_name, *func;
- call_slot *call = EX(call_slots) + opline->result.num;
+ zend_function *fbc;
+ zval *function_name, *func;
if (IS_CV == IS_CONST) {
- function_name_ptr = function_name = (zval*)(opline->op2.zv+1);
+ 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, opline->extended_value, 0, NULL, NULL, EX(call) TSRMLS_CC);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
zend_string *lcname;
+ zend_class_entry *called_scope;
+ zend_object *object;
+ zval *function_name_ptr;
SAVE_OPLINE();
function_name_ptr = function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
}
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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
} 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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
}
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;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(
+ fbc, opline->extended_value, 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
static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *value, *top;
+ zval *value, *arg;
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);
}
}
value = opline->op1.zv;
- top = zend_vm_stack_top_inc(TSRMLS_C);
- ZVAL_COPY_VALUE(top, value);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, value);
if (IS_CONST == IS_CONST) {
- if (UNEXPECTED(Z_OPT_COPYABLE_P(top))) {
- zval_copy_ctor_func(top);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) {
+ zval_copy_ctor_func(arg);
}
}
ZEND_VM_NEXT_OPCODE();
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, EG(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
+ EX(call)->prev_execute_data = EG(current_execute_data);
+ i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
- i_create_execute_data_from_op_array(new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array, return_value TSRMLS_CC);
+ execute_ex(EG(current_execute_data) TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->op_array;
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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_CONST != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_CONST != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_CONST != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_CONST != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_CONST != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_CONST != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_CONST != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 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 {
if (IS_CONST != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_CONST != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
/* Check whether an exception has been thrown, if not, jump over code */
zend_exception_restore(TSRMLS_C);
if (EG(exception) == NULL) {
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]);
ZEND_VM_CONTINUE(); /* CHECK_ME */
}
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
}
- ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
+ ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]);
ZEND_VM_CONTINUE(); /* CHECK_ME */
}
}
if (IS_CONST != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *value, *top;
+ zval *value, *arg;
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);
}
}
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- top = zend_vm_stack_top_inc(TSRMLS_C);
- ZVAL_COPY_VALUE(top, value);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, value);
if (IS_TMP_VAR == IS_CONST) {
- if (UNEXPECTED(Z_OPT_COPYABLE_P(top))) {
- zval_copy_ctor_func(top);
+ if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) {
+ zval_copy_ctor_func(arg);
}
}
ZEND_VM_NEXT_OPCODE();
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, EG(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
+ EX(call)->prev_execute_data = EG(current_execute_data);
+ i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
- i_create_execute_data_from_op_array(new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array, return_value TSRMLS_CC);
+ execute_ex(EG(current_execute_data) TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->op_array;
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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
- 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;
+ HANDLE_EXCEPTION();
+ }
+ 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 (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- /* 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));
- }
- 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);
- }
+ if (IS_CONST != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_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;
-
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object 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;
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_dtor(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_TMP_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_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;
-
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object 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;
-
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
- 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;
+ HANDLE_EXCEPTION();
+ }
+ 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 (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- /* 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));
- }
- 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);
- }
+ if (IS_CV != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
zend_free_op free_op1;
varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (Z_ISREF_P(varptr)) {
- ZVAL_COPY(top, Z_REFVAL_P(varptr));
+ ZVAL_COPY(arg, Z_REFVAL_P(varptr));
zval_ptr_dtor_nogc(free_op1.var);
} else {
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
if (IS_VAR == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+ if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
}
ZEND_VM_NEXT_OPCODE();
{
USE_OPLINE
zend_free_op free_op1;
- zval *varptr, *top;
+ zval *varptr, *arg;
SAVE_OPLINE();
if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
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);
}
}
if (IS_VAR == IS_CV) {
Z_ADDREF_P(varptr);
}
- zend_vm_stack_push(varptr TSRMLS_CC);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, varptr);
} 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_COPY(top, varptr);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY(arg, varptr);
zval_ptr_dtor_nogc(free_op1.var);
}
CHECK_EXCEPTION();
{
USE_OPLINE
zend_free_op free_op1;
- zval *varptr, *top;
+ zval *varptr, *arg;
SAVE_OPLINE();
varptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
}
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (IS_VAR == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
- ZVAL_NEW_REF(top, &EG(uninitialized_zval));
+ ZVAL_NEW_REF(arg, &EG(uninitialized_zval));
ZEND_VM_NEXT_OPCODE();
}
if (Z_ISREF_P(varptr)) {
Z_ADDREF_P(varptr);
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
} else if (IS_VAR == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
- ZVAL_COPY_VALUE(top, varptr);
- ZVAL_MAKE_REF(top);
+ ZVAL_COPY_VALUE(arg, varptr);
+ ZVAL_MAKE_REF(arg);
} else {
ZVAL_MAKE_REF(varptr);
Z_ADDREF_P(varptr);
- ZVAL_REF(top, Z_REF_P(varptr));
+ ZVAL_REF(arg, Z_REF_P(varptr));
}
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
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);
}
}
varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (Z_ISREF_P(varptr)) {
- ZVAL_COPY(top, Z_REFVAL_P(varptr));
+ ZVAL_COPY(arg, Z_REFVAL_P(varptr));
zval_ptr_dtor_nogc(free_op1.var);
} else {
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
if (IS_VAR == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+ if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
}
ZEND_VM_NEXT_OPCODE();
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, EG(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
+ EX(call)->prev_execute_data = EG(current_execute_data);
+ i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
- i_create_execute_data_from_op_array(new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array, return_value TSRMLS_CC);
+ execute_ex(EG(current_execute_data) TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->op_array;
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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
- 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;
+ HANDLE_EXCEPTION();
+ }
+ 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 (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- /* 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));
- }
- 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);
- }
+ if (IS_CONST != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_VAR != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_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_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = 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 (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;
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_dtor(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_TMP_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_VAR != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_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_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = 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 (IS_VAR != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
-
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_VAR != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_VAR != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_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_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- call->object = 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 (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
- 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;
+ HANDLE_EXCEPTION();
+ }
+ 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 (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- /* 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));
- }
- 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);
- }
+ if (IS_CV != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 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();
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
}
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;
- } 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);
- } 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);
+ object = NULL;
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (Z_OBJ(EG(This))) {
+ if (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 (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", fbc->common.scope->name->val, fbc->common.function_name->val);
+ }
}
+ object = Z_OBJ(EG(This));
+ GC_REFCOUNT(object)++;
}
- call->object = Z_OBJ(EG(This));
- if (call->object) {
- GC_REFCOUNT(call->object)++;
+ }
+
+ if (IS_VAR != IS_CONST) {
+ /* previous opcode is ZEND_FETCH_CLASS */
+ if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->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, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
- 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;
+ HANDLE_EXCEPTION();
+ }
+ 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 (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- /* 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));
- }
- 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);
- }
+ if (IS_CONST != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
if (IS_UNUSED != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_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;
-
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object 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;
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_dtor(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_TMP_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_UNUSED != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_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;
-
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object 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;
-
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
if (IS_UNUSED != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
- 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;
+ HANDLE_EXCEPTION();
+ }
+ 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 (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- /* 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));
- }
- 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);
- }
+ if (IS_CV != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
if (IS_UNUSED != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (Z_ISREF_P(varptr)) {
- ZVAL_COPY(top, Z_REFVAL_P(varptr));
+ ZVAL_COPY(arg, Z_REFVAL_P(varptr));
} else {
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
if (IS_CV == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+ if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
}
ZEND_VM_NEXT_OPCODE();
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
SAVE_OPLINE();
if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
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);
}
}
if (IS_CV == IS_CV) {
Z_ADDREF_P(varptr);
}
- zend_vm_stack_push(varptr TSRMLS_CC);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY_VALUE(arg, varptr);
} 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_COPY(top, varptr);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
+ ZVAL_COPY(arg, varptr);
}
CHECK_EXCEPTION();
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
SAVE_OPLINE();
varptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
}
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (IS_CV == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) {
- ZVAL_NEW_REF(top, &EG(uninitialized_zval));
+ ZVAL_NEW_REF(arg, &EG(uninitialized_zval));
ZEND_VM_NEXT_OPCODE();
}
if (Z_ISREF_P(varptr)) {
Z_ADDREF_P(varptr);
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
} else if (IS_CV == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
- ZVAL_COPY_VALUE(top, varptr);
- ZVAL_MAKE_REF(top);
+ ZVAL_COPY_VALUE(arg, varptr);
+ ZVAL_MAKE_REF(arg);
} else {
ZVAL_MAKE_REF(varptr);
Z_ADDREF_P(varptr);
- ZVAL_REF(top, Z_REF_P(varptr));
+ ZVAL_REF(arg, Z_REF_P(varptr));
}
ZEND_VM_NEXT_OPCODE();
static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zval *varptr, *top;
+ zval *varptr, *arg;
- 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);
}
}
varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- top = zend_vm_stack_top_inc(TSRMLS_C);
+ arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
+ EX(call)->num_args = opline->op2.num;
if (Z_ISREF_P(varptr)) {
- ZVAL_COPY(top, Z_REFVAL_P(varptr));
+ ZVAL_COPY(arg, Z_REFVAL_P(varptr));
} else {
- ZVAL_COPY_VALUE(top, varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
if (IS_CV == IS_CV) {
- if (Z_OPT_REFCOUNTED_P(varptr)) Z_ADDREF_P(varptr);
+ if (Z_OPT_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
}
}
ZEND_VM_NEXT_OPCODE();
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, EG(called_scope), Z_OBJ(EG(This)), EX(call) TSRMLS_CC);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
+ EX(call)->prev_execute_data = EG(current_execute_data);
+ i_init_execute_data(EX(call), new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
- i_create_execute_data_from_op_array(new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
ZEND_VM_ENTER();
} else {
- zend_execute(new_op_array, return_value TSRMLS_CC);
+ execute_ex(EG(current_execute_data) TSRMLS_CC);
}
- EX(function_state).function = (zend_function *) EX(op_array);
-
EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
+ EG(active_op_array) = &EX(func)->op_array;
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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
+ 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 (IS_CONST != IS_CONST ||
- (call->fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), call->called_scope)) == NULL) {
- zend_object *object = call->object;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- if (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ if (IS_CONST != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
- /* 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));
- }
- 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);
- }
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
if (IS_CV != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_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;
-
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object 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;
-
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_dtor(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_TMP_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_CV != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_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;
-
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object 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;
-
- if (UNEXPECTED(object->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));
- }
- 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);
- }
- }
- } else {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor_nogc(free_op2.var);
HANDLE_EXCEPTION();
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;
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
+
+ if (IS_VAR != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
+ }
+
+ /* First, locate the function. */
+ 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(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);
+ }
+ }
+
+ 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
if (IS_CV != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_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;
- if (EXPECTED(call->object != NULL)) {
- call->called_scope = zend_get_class_entry(call->object TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
- 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;
+ HANDLE_EXCEPTION();
+ }
+ 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 (UNEXPECTED(object->handlers->get_method == NULL)) {
- zend_error_noreturn(E_ERROR, "Object does not support method calls");
- }
+ obj = Z_OBJ_P(object);
+ called_scope = zend_get_class_entry(obj TSRMLS_CC);
- /* 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));
- }
- 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);
- }
+ if (IS_CV != IS_CONST ||
+ (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL) {
+ zend_object *orig_obj = obj;
+
+ if (UNEXPECTED(obj->handlers->get_method == NULL)) {
+ zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
- } else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ /* First, locate the function. */
+ 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(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);
}
- 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, opline->extended_value, 0, called_scope, obj, EX(call) TSRMLS_CC);
CHECK_EXCEPTION();
if (IS_CV != IS_UNUSED) {
- if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice. */
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
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);
}