gen_execute_data->return_value = (zval*)generator;
call_info = Z_TYPE_INFO(EX(This));
if ((call_info & Z_TYPE_MASK) == IS_OBJECT
- && (!(call_info & ((ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS) << ZEND_CALL_INFO_SHIFT))
+ && (!(call_info & (ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS))
/* Bug #72523 */
|| UNEXPECTED(zend_execute_ex != execute_ex))) {
ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS);
zend_internal_type_error(EX_USES_STRICT_TYPES(), "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args)));
if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(call)->func));
- }
- if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
+ } else if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_RELEASE_THIS) {
OBJ_RELEASE(Z_OBJ(EX(call)->This));
}
EX(call)->func = (zend_function*)&zend_pass_function;
Z_OBJ(EX(call)->This) = NULL;
- ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
+ ZEND_CALL_INFO(EX(call)) &= ~(ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS);
FREE_UNFETCHED_OP(opline->op2_type, opline->op2.var);
} else {
uint32_t arg_num;
CACHE_PTR(opline->result.num, fbc);
}
call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, NULL, NULL);
+ fbc, opline->extended_value, NULL);
call->prev_execute_data = EX(call);
EX(call) = call;
}
call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, NULL, NULL);
+ fbc, opline->extended_value, NULL);
call->prev_execute_data = EX(call);
EX(call) = call;
call = zend_vm_stack_push_call_frame_ex(
opline->op1.num, ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, NULL, NULL);
+ fbc, opline->extended_value, NULL);
call->prev_execute_data = EX(call);
EX(call) = call;
new_op_array->scope = EX(func)->op_array.scope;
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+ call = zend_vm_stack_push_call_frame(
+ (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
(zend_function*)new_op_array, 0,
- Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL,
- Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL);
+ Z_PTR(EX(This)));
if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
call->symbol_table = EX(symbol_table);
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_CONST == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_CONST == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_CONST == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
zend_fcall_info_cache fcc;
char *error = NULL;
zend_function *func;
- zend_class_entry *called_scope;
- zend_object *object;
+ void *object_or_called_scope;
zend_execute_data *call;
uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
function_name = RT_CONSTANT(opline, opline->op2);
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
func = fcc.function_handler;
- called_scope = fcc.called_scope;
- object = fcc.object;
if (error) {
efree(error);
/* This is the only soft error is_callable() can generate */
HANDLE_EXCEPTION();
}
}
+ object_or_called_scope = fcc.called_scope;
if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
call_info |= ZEND_CALL_FAKE_CLOSURE;
}
- } else if (object) {
- call_info |= ZEND_CALL_RELEASE_THIS;
- GC_ADDREF(object); /* For $this pointer */
+ if (fcc.object) {
+ object_or_called_scope = fcc.object;
+ call_info |= ZEND_CALL_HAS_THIS;
+ }
+ } else if (fcc.object) {
+ GC_ADDREF(fcc.object); /* For $this pointer */
+ object_or_called_scope = fcc.object;
+ call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
}
if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
if (call_info & ZEND_CALL_CLOSURE) {
zend_object_release(ZEND_CLOSURE_OBJECT(func));
- }
- if (call_info & ZEND_CALL_RELEASE_THIS) {
- zend_object_release(object);
+ } else if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(fcc.object);
}
HANDLE_EXCEPTION();
}
HANDLE_EXCEPTION();
}
func = (zend_function*)&zend_pass_function;
- called_scope = NULL;
- object = NULL;
+ object_or_called_scope = NULL;
}
call = zend_vm_stack_push_call_frame(call_info,
- func, opline->extended_value, called_scope, object);
+ func, opline->extended_value, object_or_called_scope);
call->prev_execute_data = EX(call);
EX(call) = call;
zval_ptr_dtor_nogc(free_op2);
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_CONST == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_CONST == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_CONST == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
zend_fcall_info_cache fcc;
char *error = NULL;
zend_function *func;
- zend_class_entry *called_scope;
- zend_object *object;
+ void *object_or_called_scope;
zend_execute_data *call;
uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
func = fcc.function_handler;
- called_scope = fcc.called_scope;
- object = fcc.object;
if (error) {
efree(error);
/* This is the only soft error is_callable() can generate */
HANDLE_EXCEPTION();
}
}
+ object_or_called_scope = fcc.called_scope;
if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
call_info |= ZEND_CALL_FAKE_CLOSURE;
}
- } else if (object) {
- call_info |= ZEND_CALL_RELEASE_THIS;
- GC_ADDREF(object); /* For $this pointer */
+ if (fcc.object) {
+ object_or_called_scope = fcc.object;
+ call_info |= ZEND_CALL_HAS_THIS;
+ }
+ } else if (fcc.object) {
+ GC_ADDREF(fcc.object); /* For $this pointer */
+ object_or_called_scope = fcc.object;
+ call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
}
zval_ptr_dtor_nogc(free_op2);
if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
if (call_info & ZEND_CALL_CLOSURE) {
zend_object_release(ZEND_CLOSURE_OBJECT(func));
- }
- if (call_info & ZEND_CALL_RELEASE_THIS) {
- zend_object_release(object);
+ } else if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(fcc.object);
}
HANDLE_EXCEPTION();
}
HANDLE_EXCEPTION();
}
func = (zend_function*)&zend_pass_function;
- called_scope = NULL;
- object = NULL;
+ object_or_called_scope = NULL;
}
call = zend_vm_stack_push_call_frame(call_info,
- func, opline->extended_value, called_scope, object);
+ func, opline->extended_value, object_or_called_scope);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_CONST == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_CONST == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
/* Perform a dummy function call */
call = zend_vm_stack_push_call_frame(
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
- opline->extended_value, NULL, NULL);
+ opline->extended_value, NULL);
} else {
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
init_func_run_time_cache(&constructor->op_array);
}
/* We are not handling overloaded classes right now */
call = zend_vm_stack_push_call_frame(
- ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS,
+ ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS,
constructor,
opline->extended_value,
- ce,
Z_OBJ_P(result));
Z_ADDREF_P(result);
}
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_CONST == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_CONST == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_CONST == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
zend_fcall_info_cache fcc;
char *error = NULL;
zend_function *func;
- zend_class_entry *called_scope;
- zend_object *object;
+ void *object_or_called_scope;
zend_execute_data *call;
uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
function_name = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
func = fcc.function_handler;
- called_scope = fcc.called_scope;
- object = fcc.object;
if (error) {
efree(error);
/* This is the only soft error is_callable() can generate */
HANDLE_EXCEPTION();
}
}
+ object_or_called_scope = fcc.called_scope;
if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
call_info |= ZEND_CALL_FAKE_CLOSURE;
}
- } else if (object) {
- call_info |= ZEND_CALL_RELEASE_THIS;
- GC_ADDREF(object); /* For $this pointer */
+ if (fcc.object) {
+ object_or_called_scope = fcc.object;
+ call_info |= ZEND_CALL_HAS_THIS;
+ }
+ } else if (fcc.object) {
+ GC_ADDREF(fcc.object); /* For $this pointer */
+ object_or_called_scope = fcc.object;
+ call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
}
if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
if (call_info & ZEND_CALL_CLOSURE) {
zend_object_release(ZEND_CLOSURE_OBJECT(func));
- }
- if (call_info & ZEND_CALL_RELEASE_THIS) {
- zend_object_release(object);
+ } else if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(fcc.object);
}
HANDLE_EXCEPTION();
}
HANDLE_EXCEPTION();
}
func = (zend_function*)&zend_pass_function;
- called_scope = NULL;
- object = NULL;
+ object_or_called_scope = NULL;
}
call = zend_vm_stack_push_call_frame(call_info,
- func, opline->extended_value, called_scope, object);
+ func, opline->extended_value, object_or_called_scope);
call->prev_execute_data = EX(call);
EX(call) = call;
new_op_array->scope = EX(func)->op_array.scope;
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+ call = zend_vm_stack_push_call_frame(
+ (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
(zend_function*)new_op_array, 0,
- Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL,
- Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL);
+ Z_PTR(EX(This)));
if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
call->symbol_table = EX(symbol_table);
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
zval_ptr_dtor_nogc(free_op1);
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
zval_ptr_dtor_nogc(free_op1);
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
zval_ptr_dtor_nogc(free_op2);
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
zval_ptr_dtor_nogc(free_op1);
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
zval_ptr_dtor_nogc(free_op1);
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
zval_ptr_dtor_nogc(free_op1);
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
zval_ptr_dtor_nogc(free_op1);
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_VAR == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_VAR == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_VAR == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_VAR == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_VAR == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_VAR == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
/* Perform a dummy function call */
call = zend_vm_stack_push_call_frame(
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
- opline->extended_value, NULL, NULL);
+ opline->extended_value, NULL);
} else {
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
init_func_run_time_cache(&constructor->op_array);
}
/* We are not handling overloaded classes right now */
call = zend_vm_stack_push_call_frame(
- ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS,
+ ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS,
constructor,
opline->extended_value,
- ce,
Z_OBJ_P(result));
Z_ADDREF_P(result);
}
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_VAR == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_VAR == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_UNUSED == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_UNUSED == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_UNUSED == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
zval_ptr_dtor_nogc(free_op2);
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_UNUSED == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_UNUSED == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_UNUSED == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_UNUSED == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_UNUSED == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
/* Perform a dummy function call */
call = zend_vm_stack_push_call_frame(
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
- opline->extended_value, NULL, NULL);
+ opline->extended_value, NULL);
} else {
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
init_func_run_time_cache(&constructor->op_array);
}
/* We are not handling overloaded classes right now */
call = zend_vm_stack_push_call_frame(
- ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS,
+ ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS,
constructor,
opline->extended_value,
- ce,
Z_OBJ_P(result));
Z_ADDREF_P(result);
}
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_UNUSED == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
- zend_object *object;
+ uint32_t call_info;
zend_function *fbc;
zend_execute_data *call;
}
}
- object = NULL;
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
- object = Z_OBJ(EX(This));
- ce = object->ce;
+ ce = (zend_class_entry*)Z_OBJ(EX(This));
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
} else {
zend_non_static_method_call(fbc);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
+ goto check_parent_and_self;
}
- }
-
- if (IS_UNUSED == IS_UNUSED) {
+ } else {
+check_parent_and_self:
/* previous opcode is ZEND_FETCH_CLASS */
- if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
- (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
+ if (IS_UNUSED == IS_UNUSED
+ && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+ (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
ce = Z_OBJCE(EX(This));
} else {
ce = Z_CE(EX(This));
}
}
+ call_info = ZEND_CALL_NESTED_FUNCTION;
}
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, ce, object);
+ call = zend_vm_stack_push_call_frame(call_info,
+ fbc, opline->extended_value, ce);
call->prev_execute_data = EX(call);
EX(call) = call;
new_op_array->scope = EX(func)->op_array.scope;
- call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+ call = zend_vm_stack_push_call_frame(
+ (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
(zend_function*)new_op_array, 0,
- Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL,
- Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL);
+ Z_PTR(EX(This)));
if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
call->symbol_table = EX(symbol_table);
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_CV == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
zval_ptr_dtor_nogc(free_op2);
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_CV == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
}
- call_info = ZEND_CALL_NESTED_FUNCTION;
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
- obj = NULL;
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
+ /* call static method */
+ obj = (zend_object*)called_scope;
+ call_info = ZEND_CALL_NESTED_FUNCTION;
} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
- /* CV may be changed indirectly (e.g. when it's a reference) */
- call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
if (IS_CV == IS_CV) {
GC_ADDREF(obj); /* For $this pointer */
} else if (free_op1 != object) {
GC_ADDREF(obj); /* For $this pointer */
}
+ /* CV may be changed indirectly (e.g. when it's a reference) */
+ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
}
call = zend_vm_stack_push_call_frame(call_info,
- fbc, opline->extended_value, called_scope, obj);
+ fbc, opline->extended_value, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value)
{
zend_execute_data *execute_data;
+ void *object_or_called_scope;
+ uint32_t call_info;
if (EG(exception) != NULL) {
return;
}
- execute_data = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
- (zend_function*)op_array, 0, zend_get_called_scope(EG(current_execute_data)), zend_get_this_object(EG(current_execute_data)));
+ object_or_called_scope = zend_get_this_object(EG(current_execute_data));
+ if (EXPECTED(!object_or_called_scope)) {
+ object_or_called_scope = zend_get_called_scope(EG(current_execute_data));
+ call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE;
+ } else {
+ call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE | ZEND_CALL_HAS_THIS;
+ }
+ execute_data = zend_vm_stack_push_call_frame(call_info,
+ (zend_function*)op_array, 0, object_or_called_scope);
if (EG(current_execute_data)) {
execute_data->symbol_table = zend_rebuild_symbol_table();
} else {