Browse Source

Micro-optimization (condition reordering)

pull/3506/merge
Dmitry Stogov 8 years ago
parent
commit
e1ef054be5
  1. 152
      Zend/zend_object_handlers.c

152
Zend/zend_object_handlers.c

@ -344,30 +344,6 @@ static zend_never_inline int is_protected_compatible_scope(zend_class_entry *ce,
}
/* }}} */
static zend_always_inline int zend_verify_property_access(zend_property_info *property_info, zend_class_entry *ce) /* {{{ */
{
zend_class_entry *scope;
if (property_info->flags & ZEND_ACC_PUBLIC) {
return 1;
} else {
if (UNEXPECTED(EG(fake_scope))) {
scope = EG(fake_scope);
} else {
scope = zend_get_executed_scope();
}
if (property_info->ce == scope) {
return 1;
} else if (property_info->flags & ZEND_ACC_PRIVATE) {
return 0;
} else {
ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
return is_protected_compatible_scope(property_info->ce, scope);
}
}
}
/* }}} */
static zend_never_inline zend_property_info *zend_get_parent_private_property(zend_class_entry *scope, zend_class_entry *ce, zend_string *member) /* {{{ */
{
zval *zv;
@ -421,19 +397,19 @@ dynamic:
} else {
scope = zend_get_executed_scope();
}
if (flags & ZEND_ACC_CHANGED) {
zend_property_info *p = zend_get_parent_private_property(scope, ce, member);
if (p) {
property_info = p;
flags = property_info->flags;
goto found;
} else if (flags & ZEND_ACC_PUBLIC) {
goto found;
}
}
if (property_info->ce != scope) {
if (flags & ZEND_ACC_CHANGED) {
zend_property_info *p = zend_get_parent_private_property(scope, ce, member);
if (p) {
property_info = p;
flags = property_info->flags;
goto found;
} else if (flags & ZEND_ACC_PUBLIC) {
goto found;
}
}
if (flags & ZEND_ACC_PRIVATE) {
if (property_info->ce != ce) {
goto dynamic;
@ -496,19 +472,18 @@ dynamic:
} else {
scope = zend_get_executed_scope();
}
if (flags & ZEND_ACC_CHANGED) {
zend_property_info *p = zend_get_parent_private_property(scope, ce, member);
if (p) {
property_info = p;
flags = property_info->flags;
goto found;
} else if (flags & ZEND_ACC_PUBLIC) {
goto found;
}
}
if (property_info->ce != scope) {
if (flags & ZEND_ACC_CHANGED) {
zend_property_info *p = zend_get_parent_private_property(scope, ce, member);
if (p) {
property_info = p;
flags = property_info->flags;
goto found;
} else if (flags & ZEND_ACC_PUBLIC) {
goto found;
}
}
if (flags & ZEND_ACC_PRIVATE) {
if (property_info->ce != ce) {
goto dynamic;
@ -1251,23 +1226,20 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
/* Check access level */
if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
scope = zend_get_executed_scope();
if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
zend_function *updated_fbc = zend_get_parent_private_method(scope, zobj->ce, lc_method_name);
if (EXPECTED(updated_fbc != NULL)) {
fbc = updated_fbc;
goto exit;
} else if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) {
goto exit;
}
}
if (fbc->common.scope != scope) {
if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
zend_function *updated_fbc = zend_get_parent_private_method(scope, zobj->ce, lc_method_name);
if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
* If we're not and __call() handler exists, invoke it, otherwise error out.
*/
if (fbc->common.scope != scope) {
not_found:
if (EXPECTED(updated_fbc != NULL)) {
fbc = updated_fbc;
goto exit;
} else if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) {
goto exit;
}
}
if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
if (zobj->ce->__call) {
fbc = zend_get_user_call_function(zobj->ce, method_name);
} else {
@ -1275,11 +1247,6 @@ not_found:
fbc = NULL;
}
}
} else {
ZEND_ASSERT(fbc->op_array.fn_flags & ZEND_ACC_PROTECTED);
if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
goto not_found;
}
}
}
@ -1356,11 +1323,9 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
#endif
if (!(fbc->op_array.fn_flags & ZEND_ACC_PUBLIC)) {
scope = zend_get_executed_scope();
if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
if (UNEXPECTED(fbc->common.scope != scope)) {
incompatible:
if (UNEXPECTED(fbc->common.scope != scope)) {
if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
if (ce->__callstatic) {
fbc = zend_get_user_callstatic_function(ce, function_name);
} else {
@ -1368,13 +1333,6 @@ incompatible:
fbc = NULL;
}
}
} else {
ZEND_ASSERT(fbc->common.fn_flags & ZEND_ACC_PROTECTED);
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
goto incompatible;
}
}
}
@ -1417,17 +1375,28 @@ static void zend_intenal_class_init_statics(zend_class_entry *class_type) /* {{{
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent) /* {{{ */
{
zend_property_info *property_info = zend_hash_find_ptr(&ce->properties_info, property_name);
zend_class_entry *scope;
zval *ret;
if (UNEXPECTED(property_info == NULL)) {
goto undeclared_property;
}
if (UNEXPECTED(!zend_verify_property_access(property_info, ce))) {
if (!silent) {
zend_throw_error(NULL, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ZSTR_VAL(ce->name), ZSTR_VAL(property_name));
if (!(property_info->flags & ZEND_ACC_PUBLIC)) {
if (UNEXPECTED(EG(fake_scope))) {
scope = EG(fake_scope);
} else {
scope = zend_get_executed_scope();
}
if (property_info->ce != scope) {
if (UNEXPECTED(property_info->flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) {
if (!silent) {
zend_throw_error(NULL, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ZSTR_VAL(ce->name), ZSTR_VAL(property_name));
}
return NULL;
}
}
return NULL;
}
if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) {
@ -1488,23 +1457,12 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
} else {
scope = zend_get_executed_scope();
}
if (constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
if (UNEXPECTED(constructor->common.scope != scope)) {
incompatible:
if (UNEXPECTED(constructor->common.scope != scope)) {
if (UNEXPECTED(constructor->op_array.fn_flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
zend_incompatible_constructor(constructor, scope);
constructor = NULL;
}
} else {
ZEND_ASSERT(constructor->common.fn_flags & ZEND_ACC_PROTECTED);
/* Ensure that if we're calling a protected function, we're allowed to do so.
* Constructors only have prototype if they are defined by an interface but
* it is the compilers responsibility to take care of the prototype.
*/
if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
goto incompatible;
}
}
}
}

Loading…
Cancel
Save