summaryrefslogtreecommitdiff
path: root/Zend/zend_inheritance.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2017-01-13 11:37:46 +0300
committerDmitry Stogov <dmitry@zend.com>2017-01-13 11:37:46 +0300
commit141d1ba9801f742dc5d9ccd06e02b94284c4deb7 (patch)
treecc9d1730b73a2b147d14857bb967e6d55df5af90 /Zend/zend_inheritance.c
parent28391c30ca008013267592ab2a2eebce3da3f3b0 (diff)
downloadphp-git-141d1ba9801f742dc5d9ccd06e02b94284c4deb7.tar.gz
Introduced "zend_type" - an abstraction for type-hinting representation.
Diffstat (limited to 'Zend/zend_inheritance.c')
-rw-r--r--Zend/zend_inheritance.c69
1 files changed, 24 insertions, 45 deletions
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index fd1345f844..9f64162e81 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -169,11 +169,11 @@ char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
static zend_always_inline zend_bool zend_iterable_compatibility_check(zend_arg_info *arg_info) /* {{{ */
{
- if (arg_info->type_hint == IS_ARRAY) {
+ if (ZEND_TYPE_CODE(arg_info->type) == IS_ARRAY) {
return 1;
}
- if (arg_info->class_name && zend_string_equals_literal_ci(arg_info->class_name, "Traversable")) {
+ if (ZEND_TYPE_IS_CLASS(arg_info->type) && zend_string_equals_literal_ci(ZEND_TYPE_NAME(arg_info->type), "Traversable")) {
return 1;
}
@@ -183,47 +183,33 @@ static zend_always_inline zend_bool zend_iterable_compatibility_check(zend_arg_i
static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_info *fe_arg_info, const zend_function *proto, zend_arg_info *proto_arg_info) /* {{{ */
{
- if (ZEND_LOG_XOR(fe_arg_info->class_name, proto_arg_info->class_name)) {
+ if (ZEND_LOG_XOR(ZEND_TYPE_IS_CLASS(fe_arg_info->type), ZEND_TYPE_IS_CLASS(proto_arg_info->type))) {
/* Only one has a type declaration and the other one doesn't */
return 0;
}
- if (fe_arg_info->class_name) {
+ if (ZEND_TYPE_IS_CLASS(fe_arg_info->type)) {
zend_string *fe_class_name, *proto_class_name;
const char *class_name;
- if (fe->type == ZEND_INTERNAL_FUNCTION) {
- fe_class_name = NULL;
- class_name = ((zend_internal_arg_info*)fe_arg_info)->class_name;
- } else {
- fe_class_name = fe_arg_info->class_name;
- class_name = ZSTR_VAL(fe_arg_info->class_name);
- }
+ fe_class_name = ZEND_TYPE_NAME(fe_arg_info->type);
+ class_name = ZSTR_VAL(fe_class_name);
if (!strcasecmp(class_name, "parent") && proto->common.scope) {
fe_class_name = zend_string_copy(proto->common.scope->name);
} else if (!strcasecmp(class_name, "self") && fe->common.scope) {
fe_class_name = zend_string_copy(fe->common.scope->name);
- } else if (fe_class_name) {
- zend_string_addref(fe_class_name);
} else {
- fe_class_name = zend_string_init(class_name, strlen(class_name), 0);
+ zend_string_addref(fe_class_name);
}
- if (proto->type == ZEND_INTERNAL_FUNCTION) {
- proto_class_name = NULL;
- class_name = ((zend_internal_arg_info*)proto_arg_info)->class_name;
- } else {
- proto_class_name = proto_arg_info->class_name;
- class_name = ZSTR_VAL(proto_arg_info->class_name);
- }
+ proto_class_name = ZEND_TYPE_NAME(proto_arg_info->type);
+ class_name = ZSTR_VAL(proto_class_name);
if (!strcasecmp(class_name, "parent") && proto->common.scope && proto->common.scope->parent) {
proto_class_name = zend_string_copy(proto->common.scope->parent->name);
} else if (!strcasecmp(class_name, "self") && proto->common.scope) {
proto_class_name = zend_string_copy(proto->common.scope->name);
- } else if (proto_class_name) {
- zend_string_addref(proto_class_name);
} else {
- proto_class_name = zend_string_init(class_name, strlen(class_name), 0);
+ zend_string_addref(proto_class_name);
}
if (strcasecmp(ZSTR_VAL(fe_class_name), ZSTR_VAL(proto_class_name)) != 0) {
@@ -250,9 +236,7 @@ static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_inf
}
zend_string_release(proto_class_name);
zend_string_release(fe_class_name);
- }
-
- if (fe_arg_info->type_hint != proto_arg_info->type_hint) {
+ } else if (ZEND_TYPE_CODE(fe_arg_info->type) != ZEND_TYPE_CODE(proto_arg_info->type)) {
/* Incompatible type */
return 0;
}
@@ -330,7 +314,7 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
}
if (!zend_do_perform_type_hint_check(fe, fe_arg_info, proto, proto_arg_info)) {
- switch (fe_arg_info->type_hint) {
+ switch (ZEND_TYPE_CODE(fe_arg_info->type)) {
case IS_ITERABLE:
if (!zend_iterable_compatibility_check(proto_arg_info)) {
return 0;
@@ -343,7 +327,7 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
}
// This introduces BC break described at https://bugs.php.net/bug.php?id=72119
- if (proto_arg_info->type_hint && proto_arg_info->allow_null && !fe_arg_info->allow_null) {
+ if (ZEND_TYPE_IS_SET(proto_arg_info->type) && ZEND_TYPE_ALLOW_NULL(proto_arg_info->type) && !ZEND_TYPE_ALLOW_NULL(fe_arg_info->type)) {
/* incompatible nullability */
return 0;
}
@@ -363,7 +347,7 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
}
if (!zend_do_perform_type_hint_check(fe, fe->common.arg_info - 1, proto, proto->common.arg_info - 1)) {
- switch (proto->common.arg_info[-1].type_hint) {
+ switch (ZEND_TYPE_CODE(proto->common.arg_info[-1].type)) {
case IS_ITERABLE:
if (!zend_iterable_compatibility_check(fe->common.arg_info - 1)) {
return 0;
@@ -375,7 +359,7 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
}
}
- if (fe->common.arg_info[-1].allow_null && !proto->common.arg_info[-1].allow_null) {
+ if (ZEND_TYPE_ALLOW_NULL(fe->common.arg_info[-1].type) && !ZEND_TYPE_ALLOW_NULL(proto->common.arg_info[-1].type)) {
return 0;
}
}
@@ -386,21 +370,16 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
static ZEND_COLD void zend_append_type_hint(smart_str *str, const zend_function *fptr, zend_arg_info *arg_info, int return_hint) /* {{{ */
{
- if (arg_info->type_hint != IS_UNDEF && arg_info->allow_null) {
+ if (ZEND_TYPE_IS_SET(arg_info->type) && ZEND_TYPE_ALLOW_NULL(arg_info->type)) {
smart_str_appendc(str, '?');
}
- if (arg_info->class_name) {
+ if (ZEND_TYPE_IS_CLASS(arg_info->type)) {
const char *class_name;
size_t class_name_len;
- if (fptr->type == ZEND_INTERNAL_FUNCTION) {
- class_name = ((zend_internal_arg_info*)arg_info)->class_name;
- class_name_len = strlen(class_name);
- } else {
- class_name = ZSTR_VAL(arg_info->class_name);
- class_name_len = ZSTR_LEN(arg_info->class_name);
- }
+ class_name = ZSTR_VAL(ZEND_TYPE_NAME(arg_info->type));
+ class_name_len = ZSTR_LEN(ZEND_TYPE_NAME(arg_info->type));
if (!strcasecmp(class_name, "self") && fptr->common.scope) {
class_name = ZSTR_VAL(fptr->common.scope->name);
@@ -414,13 +393,13 @@ static ZEND_COLD void zend_append_type_hint(smart_str *str, const zend_function
if (!return_hint) {
smart_str_appendc(str, ' ');
}
- } else if (arg_info->type_hint) {
- if (arg_info->type_hint == IS_LONG) {
+ } else if (ZEND_TYPE_IS_CODE(arg_info->type)) {
+ if (ZEND_TYPE_CODE(arg_info->type) == IS_LONG) {
smart_str_appendl(str, "int", 3);
- } else if (arg_info->type_hint == _IS_BOOL) {
+ } else if (ZEND_TYPE_CODE(arg_info->type) == _IS_BOOL) {
smart_str_appendl(str, "bool", 4);
} else {
- const char *type_name = zend_get_type_by_const(arg_info->type_hint);
+ const char *type_name = zend_get_type_by_const(ZEND_TYPE_CODE(arg_info->type));
smart_str_appends(str, type_name);
}
if (!return_hint) {
@@ -628,7 +607,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
} else if ((parent->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) &&
(!(child->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
!zend_do_perform_type_hint_check(child, child->common.arg_info - 1, parent, parent->common.arg_info - 1) ||
- (child->common.arg_info[-1].allow_null && !parent->common.arg_info[-1].allow_null))) {
+ (ZEND_TYPE_ALLOW_NULL(child->common.arg_info[-1].type) && !ZEND_TYPE_ALLOW_NULL(parent->common.arg_info[-1].type)))) {
error_level = E_COMPILE_ERROR;
error_verb = "must";
} else {