They need quite seldom and it's cheaper to get them from corresponfing upper stack frame.
if (!EG(scope)) {
if (error) *error = estrdup("cannot access self:: when no class scope is active");
} else {
- fcc->called_scope = EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL;
+ fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
fcc->calling_scope = EG(scope);
- if (!fcc->object && EG(current_execute_data) && Z_OBJ(EG(current_execute_data)->This)) {
- fcc->object = Z_OBJ(EG(current_execute_data)->This);
+ if (!fcc->object) {
+ fcc->object = zend_get_this_object(EG(current_execute_data));
}
ret = 1;
}
} else if (!EG(scope)->parent) {
if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
} else {
- fcc->called_scope = EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL;
+ fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
fcc->calling_scope = EG(scope)->parent;
- if (!fcc->object && EG(current_execute_data) && Z_OBJ(EG(current_execute_data)->This)) {
- fcc->object = Z_OBJ(EG(current_execute_data)->This);
+ if (!fcc->object) {
+ fcc->object = zend_get_this_object(EG(current_execute_data));
}
*strict_class = 1;
ret = 1;
}
} else if (zend_string_equals_literal(lcname, "static")) {
- if (!EG(current_execute_data) || !EG(current_execute_data)->called_scope) {
+ zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
+
+ if (!called_scope) {
if (error) *error = estrdup("cannot access static:: when no class scope is active");
} else {
- fcc->called_scope = EG(current_execute_data)->called_scope;
- fcc->calling_scope = EG(current_execute_data)->called_scope;
- if (!fcc->object && Z_OBJ(EG(current_execute_data)->This)) {
- fcc->object = Z_OBJ(EG(current_execute_data)->This);
+ fcc->called_scope = called_scope;
+ fcc->calling_scope = called_scope;
+ if (!fcc->object) {
+ fcc->object = zend_get_this_object(EG(current_execute_data));
}
*strict_class = 1;
ret = 1;
}
scope = ex ? ex->func->common.scope : NULL;
fcc->calling_scope = ce;
- if (scope && !fcc->object && EG(current_execute_data) && Z_OBJ(EG(current_execute_data)->This) &&
- instanceof_function(Z_OBJCE(EG(current_execute_data)->This), scope) &&
- instanceof_function(scope, fcc->calling_scope)) {
- fcc->object = Z_OBJ(EG(current_execute_data)->This);
- fcc->called_scope = Z_OBJCE(EG(current_execute_data)->This);
+ if (scope && !fcc->object) {
+ zend_object *object = zend_get_this_object(EG(current_execute_data));
+
+ if (object &&
+ instanceof_function(object->ce, scope) &&
+ instanceof_function(scope, fcc->calling_scope)) {
+ fcc->object = object;
+ fcc->called_scope = object->ce;
+ } else {
+ fcc->called_scope = fcc->calling_scope;
+ }
} else {
fcc->called_scope = fcc->object ? fcc->object->ce : fcc->calling_scope;
}
if (fcc->function_handler) {
retval = 1;
call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
- if (call_via_handler && !fcc->object && EG(current_execute_data) && Z_OBJ(EG(current_execute_data)->This) &&
- instanceof_function(Z_OBJCE(EG(current_execute_data)->This), fcc->calling_scope)) {
- fcc->object = Z_OBJ(EG(current_execute_data)->This);
+ if (call_via_handler && !fcc->object) {
+ zend_object *object = zend_get_this_object(EG(current_execute_data));
+ if (object &&
+ instanceof_function(object->ce, fcc->calling_scope)) {
+ fcc->object = object;
+ }
}
}
}
Retrieves the "Late Static Binding" class name */
ZEND_FUNCTION(get_called_class)
{
+ zend_class_entry *called_scope;
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if (EX(called_scope)) {
- RETURN_STR_COPY(EX(called_scope)->name);
+ called_scope = zend_get_called_scope(execute_data);
+ if (called_scope) {
+ RETURN_STR_COPY(called_scope->name);
} else if (!EG(scope)) {
zend_error(E_WARNING, "get_called_class() called from outside a class");
}
/* $this may be passed into regular internal functions */
object = Z_OBJ(call->This);
- if (object &&
- call &&
- call->func->type == ZEND_INTERNAL_FUNCTION &&
- !call->func->common.scope) {
- object = NULL;
- }
if (call->func) {
func = call->func;
/* $this may be passed into regular internal functions */
object = call ? Z_OBJ(call->This) : NULL;
- if (object &&
- call->func &&
- call->func->type == ZEND_INTERNAL_FUNCTION &&
- !call->func->common.scope) {
- object = NULL;
- }
if (call && call->func) {
func = call->func;
}
} else if (class_name_len == sizeof("static")-1 &&
!memcmp(lcname, "static", sizeof("static")-1)) {
- if (UNEXPECTED(!EG(current_execute_data)) ||
- UNEXPECTED(!EG(current_execute_data)->called_scope)) {
+ ce = zend_get_called_scope(EG(current_execute_data));
+ if (UNEXPECTED(!ce)) {
zend_error(E_EXCEPTION | E_ERROR, "Cannot access static:: when no class scope is active");
return NULL;
}
- ce = EG(current_execute_data)->called_scope;
} else {
ce = zend_fetch_class(class_name, flags);
}
ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value);
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name);
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload);
+ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex);
+ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex);
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name);
ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name);
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions);
}
/* }}} */
+ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex) /* {{{ */
+{
+ while (ex) {
+ if (ex->called_scope) {
+ return ex->called_scope;
+ } else if (ex->func) {
+ if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
+ return ex->called_scope;
+ }
+ }
+ ex = ex->prev_execute_data;
+ }
+ return NULL;
+}
+/* }}} */
+
+ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex) /* {{{ */
+{
+ while (ex) {
+ if (Z_OBJ(ex->This)) {
+ return Z_OBJ(ex->This);
+ } else if (ex->func) {
+ if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
+ return Z_OBJ(ex->This);
+ }
+ }
+ ex = ex->prev_execute_data;
+ }
+ return NULL;
+}
+/* }}} */
+
ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name) /* {{{ */
{
zval pv;
}
return EG(scope)->parent;
case ZEND_FETCH_CLASS_STATIC:
- if (UNEXPECTED(!EG(current_execute_data)) || UNEXPECTED(!EG(current_execute_data)->called_scope)) {
+ ce = zend_get_called_scope(EG(current_execute_data));
+ if (UNEXPECTED(!ce)) {
int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ?
(E_EXCEPTION | E_ERROR) : E_ERROR;
zend_error(error_type, "Cannot access static:: when no class scope is active");
return NULL;
}
- return EG(current_execute_data)->called_scope;
+ return ce;
case ZEND_FETCH_CLASS_AUTO: {
fetch_sub_type = zend_get_class_fetch_type(class_name);
if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) {
fcic.calling_scope = obj_ce;
if (object) {
fcic.called_scope = Z_OBJCE_P(object);
- } else if (obj_ce &&
- !(EG(current_execute_data) &&
- EG(current_execute_data)->called_scope &&
- instanceof_function(EG(current_execute_data)->called_scope, obj_ce))) {
- fcic.called_scope = obj_ce;
} else {
- fcic.called_scope = EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL;
+ zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
+
+ if (obj_ce &&
+ (!called_scope ||
+ !instanceof_function(called_scope, obj_ce))) {
+ fcic.called_scope = obj_ce;
+ } else {
+ fcic.called_scope = called_scope;
+ }
}
fcic.object = object ? Z_OBJ_P(object) : NULL;
result = zend_call_function(&fci, &fcic);
zend_function *fbc = NULL;
char *lc_class_name;
zend_string *lc_function_name;
+ zend_object *object;
if (EXPECTED(key != NULL)) {
lc_function_name = Z_STR_P(key);
zend_string_release(lc_function_name);
}
if (ce->__call &&
- Z_OBJ(EG(current_execute_data)->This) &&
- instanceof_function(Z_OBJCE(EG(current_execute_data)->This), ce)) {
+ (object = zend_get_this_object(EG(current_execute_data))) != NULL &&
+ instanceof_function(object->ce, ce)) {
/* Call the top-level defined __call().
* see: tests/classes/__call_004.phpt */
- zend_class_entry *call_ce = Z_OBJCE(EG(current_execute_data)->This);
+ zend_class_entry *call_ce = object->ce;
while (!call_ce->__call) {
call_ce = call_ce->parent;
SAVE_OPLINE();
EX(call) = call->prev_execute_data;
- call->called_scope = EX(called_scope);
- Z_OBJ(call->This) = Z_OBJ(EX(This));
-
call->prev_execute_data = execute_data;
EG(current_execute_data) = call;
}
}
- call->called_scope = EX(called_scope);
- Z_OBJ(call->This) = Z_OBJ(EX(This));
-
call->prev_execute_data = execute_data;
EG(current_execute_data) = call;
if (fbc->common.scope) {
should_change_scope = 1;
EG(scope) = fbc->common.scope;
- } else {
- call->called_scope = EX(called_scope);
- Z_OBJ(call->This) = Z_OBJ(EX(This));
}
call->prev_execute_data = execute_data;
}
execute_data = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_CODE,
- (zend_function*)op_array, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, EG(current_execute_data) ? Z_OBJ(EG(current_execute_data)->This) : NULL);
+ (zend_function*)op_array, 0, zend_get_called_scope(EG(current_execute_data)), zend_get_this_object(EG(current_execute_data)));
if (EG(current_execute_data)) {
execute_data->symbol_table = zend_rebuild_symbol_table();
} else {
SAVE_OPLINE();
EX(call) = call->prev_execute_data;
- call->called_scope = EX(called_scope);
- Z_OBJ(call->This) = Z_OBJ(EX(This));
-
call->prev_execute_data = execute_data;
EG(current_execute_data) = call;
}
}
- call->called_scope = EX(called_scope);
- Z_OBJ(call->This) = Z_OBJ(EX(This));
-
call->prev_execute_data = execute_data;
EG(current_execute_data) = call;
if (fbc->common.scope) {
should_change_scope = 1;
EG(scope) = fbc->common.scope;
- } else {
- call->called_scope = EX(called_scope);
- Z_OBJ(call->This) = Z_OBJ(EX(This));
}
call->prev_execute_data = execute_data;
}
execute_data = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_CODE,
- (zend_function*)op_array, 0, EG(current_execute_data) ? EG(current_execute_data)->called_scope : NULL, EG(current_execute_data) ? Z_OBJ(EG(current_execute_data)->This) : NULL);
+ (zend_function*)op_array, 0, zend_get_called_scope(EG(current_execute_data)), zend_get_this_object(EG(current_execute_data)));
if (EG(current_execute_data)) {
execute_data->symbol_table = zend_rebuild_symbol_table();
} else {
zval retval;
zend_fcall_info fci;
zend_fcall_info_cache fci_cache;
+ zend_class_entry *called_scope;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &fci, &fci_cache, &fci.params, &fci.param_count) == FAILURE) {
return;
fci.retval = &retval;
- if (EX(called_scope) &&
- instanceof_function(EX(called_scope), fci_cache.calling_scope)) {
- fci_cache.called_scope = EX(called_scope);
+ called_scope = zend_get_called_scope(execute_data);
+ if (called_scope &&
+ instanceof_function(called_scope, fci_cache.calling_scope)) {
+ fci_cache.called_scope = called_scope;
}
if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
zval *params, retval;
zend_fcall_info fci;
zend_fcall_info_cache fci_cache;
+ zend_class_entry *called_scope;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "fa/", &fci, &fci_cache, ¶ms) == FAILURE) {
return;
zend_fcall_info_args(&fci, params);
fci.retval = &retval;
- if (EX(called_scope) &&
- instanceof_function(EX(called_scope), fci_cache.calling_scope)) {
- fci_cache.called_scope = EX(called_scope);
+ called_scope = zend_get_called_scope(execute_data);
+ if (called_scope &&
+ instanceof_function(called_scope, fci_cache.calling_scope)) {
+ fci_cache.called_scope = called_scope;
}
if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {