1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Make zend_type a 2-field struct

We now store the pointer payload and the type mask separately. This
is in preparation for union types, where we will be using both at
the same time.

To avoid increasing the size of arginfo structures, the
pass_by_reference and is_variadic fields are now stored as part of
the type_mask (8-bit are reserved for custom use).

Different types of pointer payloads are distinguished based on bits
in the type_mask.
This commit is contained in:
Nikita Popov
2019-09-20 17:01:19 +02:00
parent a555cc0b3d
commit ac4e0f0852
28 changed files with 264 additions and 267 deletions

View File

@@ -594,10 +594,7 @@ static void function_copy_ctor(zval *zv) /* {{{ */
for (i = 0 ; i < num_args; i++) {
if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
new_arg_info[i].type =
ZEND_TYPE_ENCODE_CLASS(
name, ZEND_TYPE_ALLOW_NULL(arg_info[i].type));
ZEND_TYPE_SET_PTR(new_arg_info[i].type, name);
}
}
func->common.arg_info = new_arg_info + 1;
@@ -968,7 +965,7 @@ static void zend_resolve_property_types(void) /* {{{ */
zend_class_entry *prop_ce = zend_hash_find_ptr(CG(class_table), lc_type_name);
ZEND_ASSERT(prop_ce && prop_ce->type == ZEND_INTERNAL_CLASS);
prop_info->type = ZEND_TYPE_ENCODE_CE(prop_ce, ZEND_TYPE_ALLOW_NULL(prop_info->type));
prop_info->type = (zend_type) ZEND_TYPE_INIT_CE(prop_ce, ZEND_TYPE_ALLOW_NULL(prop_info->type), 0);
zend_string_release(lc_type_name);
zend_string_release(type_name);
}

View File

@@ -2045,21 +2045,17 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
} else {
internal_function->required_num_args = info->required_num_args;
}
if (info->return_reference) {
if (ZEND_ARG_SEND_MODE(info)) {
internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE;
}
if (ptr->arg_info[ptr->num_args].is_variadic) {
if (ZEND_ARG_IS_VARIADIC(&ptr->arg_info[ptr->num_args])) {
internal_function->fn_flags |= ZEND_ACC_VARIADIC;
/* Don't count the variadic argument */
internal_function->num_args--;
}
if (ZEND_TYPE_IS_SET(info->type)) {
if (ZEND_TYPE_IS_CLASS(info->type)) {
const char *type_name = (const char*)info->type;
if (type_name[0] == '?') {
type_name++;
}
const char *type_name = ZEND_TYPE_LITERAL_NAME(info->type);
if (!scope && (!strcasecmp(type_name, "self") || !strcasecmp(type_name, "parent"))) {
zend_error_noreturn(E_CORE_ERROR, "Cannot declare a return type of %s outside of a class scope", type_name);
}
@@ -2140,16 +2136,9 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
reg_function->common.arg_info = new_arg_info + 1;
for (i = 0; i < num_args; i++) {
if (ZEND_TYPE_IS_CLASS(new_arg_info[i].type)) {
const char *class_name = (const char*)new_arg_info[i].type;
zend_bool allow_null = 0;
zend_string *str;
if (class_name[0] == '?') {
class_name++;
allow_null = 1;
}
str = zend_string_init_interned(class_name, strlen(class_name), 1);
new_arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(str, allow_null);
const char *class_name = ZEND_TYPE_LITERAL_NAME(new_arg_info[i].type);
ZEND_TYPE_SET_PTR(new_arg_info[i].type,
zend_string_init_interned(class_name, strlen(class_name), 1));
}
}
}
@@ -3715,7 +3704,7 @@ ZEND_API int zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval *zv, ze
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
{
return zend_declare_typed_property(ce, name, property, access_type, doc_comment, ZEND_TYPE_ENCODE_NONE());
return zend_declare_typed_property(ce, name, property, access_type, doc_comment, (zend_type) ZEND_TYPE_INIT_NONE(0));
}
/* }}} */

View File

@@ -96,34 +96,45 @@ typedef struct _zend_fcall_info_cache {
#define ZEND_FE_END { NULL, NULL, NULL, 0, 0 }
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, 0, pass_by_ref, 0},
#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, pass_by_ref, 0},
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, ZEND_TYPE_ENCODE_CLASS_CONST(#classname, allow_null), pass_by_ref, 0 },
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, ZEND_TYPE_ENCODE_CODE(IS_ARRAY, allow_null), pass_by_ref, 0 },
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) { #name, ZEND_TYPE_ENCODE_CODE(IS_CALLABLE, allow_null), pass_by_ref, 0 },
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, ZEND_TYPE_ENCODE_CODE(type_hint, allow_null), pass_by_ref, 0 },
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) { #name, 0, pass_by_ref, 1 },
#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, ZEND_TYPE_ENCODE_CODE(type_hint, allow_null), pass_by_ref, 1 },
#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, ZEND_TYPE_ENCODE_CLASS_CONST(#classname, allow_null), pass_by_ref, 1 },
#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic) \
(((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0))
#define ZEND_ARG_INFO(pass_by_ref, name) \
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0))},
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) \
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
static const zend_internal_arg_info name[] = { \
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE_CLASS_CONST(#class_name, allow_null), return_reference, 0 },
{ (const char*)(zend_uintptr_t)(required_num_args), \
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO(name, class_name, allow_null) \
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, 0, -1, class_name, allow_null)
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
static const zend_internal_arg_info name[] = { \
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE_CODE(type, allow_null), return_reference, 0 },
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(name, type, allow_null) \
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, -1, type, allow_null)
#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \
static const zend_internal_arg_info name[] = { \
{ (const char*)(zend_uintptr_t)(required_num_args), 0, return_reference, 0 },
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
#define ZEND_BEGIN_ARG_INFO(name, _unused) \
ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, -1)
ZEND_BEGIN_ARG_INFO_EX(name, {}, ZEND_RETURN_VALUE, -1)
#define ZEND_END_ARG_INFO() };
/* Name macros */

View File

@@ -557,16 +557,16 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp)
if (arg_info->name) {
if (zstr_args) {
name = zend_strpprintf(0, "%s$%s",
arg_info->pass_by_reference ? "&" : "",
ZEND_ARG_SEND_MODE(arg_info) ? "&" : "",
ZSTR_VAL(arg_info->name));
} else {
name = zend_strpprintf(0, "%s$%s",
arg_info->pass_by_reference ? "&" : "",
ZEND_ARG_SEND_MODE(arg_info) ? "&" : "",
((zend_internal_arg_info*)arg_info)->name);
}
} else {
name = zend_strpprintf(0, "%s$param%d",
arg_info->pass_by_reference ? "&" : "",
ZEND_ARG_SEND_MODE(arg_info) ? "&" : "",
i + 1);
}
ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));

View File

@@ -1135,7 +1135,7 @@ zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scop
} else if (ZEND_TYPE_IS_CE(type)) {
str = zend_string_copy(ZEND_TYPE_CE(type)->name);
} else {
uint32_t type_mask = ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(type));
uint32_t type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(type);
switch (type_mask) {
case MAY_BE_FALSE|MAY_BE_TRUE:
str = ZSTR_KNOWN(ZEND_STR_BOOL);
@@ -1199,7 +1199,7 @@ static void zend_mark_function_as_generator() /* {{{ */
|| zend_string_equals_literal_ci(name, "Iterator")
|| zend_string_equals_literal_ci(name, "Generator");
} else {
valid_type = (ZEND_TYPE_MASK(return_info.type) & MAY_BE_ITERABLE) != 0;
valid_type = (ZEND_TYPE_FULL_MASK(return_info.type) & MAY_BE_ITERABLE) != 0;
}
if (!valid_type) {
@@ -2175,7 +2175,7 @@ static void zend_emit_return_type_check(
zend_op *opline;
/* `return ...;` is illegal in a void function (but `return;` isn't) */
if (ZEND_TYPE_IS_MASK(type) && ZEND_TYPE_CONTAINS_CODE(type, IS_VOID)) {
if (ZEND_TYPE_CONTAINS_CODE(type, IS_VOID)) {
if (expr) {
if (expr->op_type == IS_CONST && Z_TYPE(expr->u.constant) == IS_NULL) {
zend_error_noreturn(E_COMPILE_ERROR,
@@ -2201,8 +2201,7 @@ static void zend_emit_return_type_check(
}
if (expr && expr->op_type == IS_CONST) {
if (ZEND_TYPE_IS_MASK(type)
&& ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE(expr->u.constant))) {
if (ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE(expr->u.constant))) {
/* we don't need run-time check */
return;
}
@@ -5359,11 +5358,11 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */
n = MIN(func->common.num_args, MAX_ARG_FLAG_NUM);
i = 0;
while (i < n) {
ZEND_SET_ARG_FLAG(func, i + 1, func->common.arg_info[i].pass_by_reference);
ZEND_SET_ARG_FLAG(func, i + 1, ZEND_ARG_SEND_MODE(&func->common.arg_info[i]));
i++;
}
if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_VARIADIC && func->common.arg_info[i].pass_by_reference)) {
uint32_t pass_by_reference = func->common.arg_info[i].pass_by_reference;
if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_VARIADIC && ZEND_ARG_SEND_MODE(&func->common.arg_info[i]))) {
uint32_t pass_by_reference = ZEND_ARG_SEND_MODE(&func->common.arg_info[i]);
while (i < MAX_ARG_FLAG_NUM) {
ZEND_SET_ARG_FLAG(func, i + 1, pass_by_reference);
i++;
@@ -5382,7 +5381,7 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null
}
if (ast->kind == ZEND_AST_TYPE) {
return ZEND_TYPE_ENCODE_CODE(ast->attr, allow_null);
return (zend_type) ZEND_TYPE_INIT_CODE(ast->attr, allow_null, 0);
} else {
zend_string *class_name = zend_ast_get_str(ast);
zend_uchar type = zend_lookup_builtin_type_by_name(class_name);
@@ -5396,7 +5395,7 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null
if (type == IS_VOID && allow_null) {
zend_error_noreturn(E_COMPILE_ERROR, "Void type cannot be nullable");
}
return ZEND_TYPE_ENCODE_CODE(type, allow_null);
return (zend_type) ZEND_TYPE_INIT_CODE(type, allow_null, 0);
} else {
const char *correct_name;
zend_string *orig_name = zend_ast_get_str(ast);
@@ -5428,7 +5427,7 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null
}
}
return ZEND_TYPE_ENCODE_CLASS(class_name, allow_null);
return (zend_type) ZEND_TYPE_INIT_CLASS(class_name, allow_null, 0);
}
}
}
@@ -5448,12 +5447,12 @@ static zend_bool zend_is_valid_default_value(zend_type type, zval *value)
if (ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE_P(value))) {
return 1;
}
if ((ZEND_TYPE_MASK(type) & MAY_BE_DOUBLE) && Z_TYPE_P(value) == IS_LONG) {
if ((ZEND_TYPE_FULL_MASK(type) & MAY_BE_DOUBLE) && Z_TYPE_P(value) == IS_LONG) {
/* Integers are allowed as initializers for floating-point values. */
convert_to_double(value);
return 1;
}
if ((ZEND_TYPE_MASK(type) & MAY_BE_ITERABLE) && Z_TYPE_P(value) == IS_ARRAY) {
if ((ZEND_TYPE_FULL_MASK(type) & MAY_BE_ITERABLE) && Z_TYPE_P(value) == IS_ARRAY) {
return 1;
}
return 0;
@@ -5470,9 +5469,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
/* Use op_array->arg_info[-1] for return type */
arg_infos = safe_emalloc(sizeof(zend_arg_info), list->children + 1, 0);
arg_infos->name = NULL;
arg_infos->pass_by_reference = (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
arg_infos->is_variadic = 0;
arg_infos->type = zend_compile_typename(return_type_ast, 0);
ZEND_TYPE_FULL_MASK(arg_infos->type) |= _ZEND_ARG_INFO_FLAGS(
(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0);
arg_infos++;
op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
} else {
@@ -5540,23 +5539,18 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
arg_info = &arg_infos[i];
arg_info->name = zend_string_copy(name);
arg_info->pass_by_reference = is_ref;
arg_info->is_variadic = is_variadic;
arg_info->type = ZEND_TYPE_ENCODE_NONE();
arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0);
if (type_ast) {
uint32_t default_type = default_ast ? Z_TYPE(default_node.u.constant) : IS_UNDEF;
uint32_t arg_type;
zend_bool is_class;
op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
arg_info->type = zend_compile_typename(type_ast, default_type == IS_NULL);
is_class = ZEND_TYPE_IS_CLASS(arg_info->type);
arg_type = !is_class ? ZEND_TYPE_MASK(arg_info->type) : 0;
if (arg_type & MAY_BE_VOID) {
if (!is_class && (ZEND_TYPE_FULL_MASK(arg_info->type) & MAY_BE_VOID)) {
zend_error_noreturn(E_COMPILE_ERROR, "void cannot be used as a parameter type");
}
@@ -5580,6 +5574,8 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
opline->extended_value = zend_alloc_cache_slot();
}
}
ZEND_TYPE_FULL_MASK(arg_info->type) |= _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic);
}
/* These are assigned at the end to avoid uninitialized memory in case of an error */
@@ -6079,13 +6075,12 @@ void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t flags) /
zend_string *name = zval_make_interned_string(zend_ast_get_zval(name_ast));
zend_string *doc_comment = NULL;
zval value_zv;
zend_type type = ZEND_TYPE_ENCODE_NONE();
zend_type type = ZEND_TYPE_INIT_NONE(0);
if (type_ast) {
type = zend_compile_typename(type_ast, 0);
if (ZEND_TYPE_IS_MASK(type)
&& (ZEND_TYPE_MASK(type) & (MAY_BE_VOID|MAY_BE_CALLABLE))) {
if (ZEND_TYPE_FULL_MASK(type) & (MAY_BE_VOID|MAY_BE_CALLABLE)) {
zend_string *str = zend_type_to_string(type);
zend_error_noreturn(E_COMPILE_ERROR,
"Property %s::$%s cannot have type %s",

View File

@@ -383,16 +383,12 @@ typedef struct _zend_class_constant {
typedef struct _zend_internal_arg_info {
const char *name;
zend_type type;
zend_uchar pass_by_reference;
zend_bool is_variadic;
} zend_internal_arg_info;
/* arg_info for user functions */
typedef struct _zend_arg_info {
zend_string *name;
zend_type type;
zend_uchar pass_by_reference;
zend_bool is_variadic;
} zend_arg_info;
/* the following structure repeats the layout of zend_internal_arg_info,
@@ -403,8 +399,6 @@ typedef struct _zend_arg_info {
typedef struct _zend_internal_function_info {
zend_uintptr_t required_num_args;
zend_type type;
zend_bool return_reference;
zend_bool _is_variadic;
} zend_internal_function_info;
struct _zend_op_array {
@@ -934,6 +928,14 @@ zend_string *zend_type_to_string(zend_type type);
#define ZEND_SEND_BY_REF 1u
#define ZEND_SEND_PREFER_REF 2u
/* The send mode and is_variadic flag are stored as part of zend_type */
#define _ZEND_SEND_MODE_SHIFT _ZEND_TYPE_EXTRA_FLAGS_SHIFT
#define _ZEND_IS_VARIADIC_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 2))
#define ZEND_ARG_SEND_MODE(arg_info) \
((ZEND_TYPE_FULL_MASK((arg_info)->type) >> _ZEND_SEND_MODE_SHIFT) & 3)
#define ZEND_ARG_IS_VARIADIC(arg_info) \
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_VARIADIC_BIT) != 0)
#define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce */
#define ZEND_DIM_ALTERNATIVE_SYNTAX (1 << 1) /* deprecated curly brace usage */
@@ -950,7 +952,7 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
}
arg_num = zf->common.num_args;
}
return UNEXPECTED((zf->common.arg_info[arg_num].pass_by_reference & mask) != 0);
return UNEXPECTED((ZEND_ARG_SEND_MODE(&zf->common.arg_info[arg_num]) & mask) != 0);
}
#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \

View File

@@ -676,8 +676,8 @@ static ZEND_COLD void zend_verify_type_error_common(
*need_kind = ZSTR_VAL(ZEND_TYPE_NAME(arg_info->type));
}
} else {
zend_type type = ZEND_TYPE_WITHOUT_NULL(arg_info->type);
switch (ZEND_TYPE_MASK(type)) {
uint32_t type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(arg_info->type);
switch (type_mask) {
case MAY_BE_OBJECT:
*need_msg = "be an ";
*need_kind = "object";
@@ -691,11 +691,15 @@ static ZEND_COLD void zend_verify_type_error_common(
*need_kind = "";
break;
default:
{
/* TODO: The zend_type_to_string() result is guaranteed interned here.
* It would be beter to switch all this code to use zend_string though. */
zend_type type = arg_info->type;
ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_NULL;
*need_msg = "be of the type ";
*need_kind = ZSTR_VAL(zend_type_to_string(type));
break;
}
}
}
@@ -904,7 +908,7 @@ static zend_bool zend_resolve_class_type(zend_type *type, zend_class_entry *self
}
zend_string_release(name);
*type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(*type));
*type = (zend_type) ZEND_TYPE_INIT_CE(ce, ZEND_TYPE_ALLOW_NULL(*type), 0);
return 1;
}
@@ -924,13 +928,13 @@ static zend_always_inline zend_bool i_zend_check_property_type(zend_property_inf
return instanceof_function(Z_OBJCE_P(property), ZEND_TYPE_CE(info->type));
}
ZEND_ASSERT(!(ZEND_TYPE_MASK(info->type) & MAY_BE_CALLABLE));
ZEND_ASSERT(!(ZEND_TYPE_FULL_MASK(info->type) & MAY_BE_CALLABLE));
if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(info->type, Z_TYPE_P(property)))) {
return 1;
} else if (ZEND_TYPE_MASK(info->type) & MAY_BE_ITERABLE) {
} else if (ZEND_TYPE_FULL_MASK(info->type) & MAY_BE_ITERABLE) {
return zend_is_iterable(property);
} else {
return zend_verify_scalar_type_hint(ZEND_TYPE_MASK(info->type), property, strict, 0);
return zend_verify_scalar_type_hint(ZEND_TYPE_FULL_MASK(info->type), property, strict, 0);
}
}
@@ -996,7 +1000,7 @@ static zend_always_inline zend_bool zend_check_type(
return 1;
}
type_mask = ZEND_TYPE_MASK(type);
type_mask = ZEND_TYPE_FULL_MASK(type);
if (type_mask & MAY_BE_CALLABLE) {
return zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL);
} else if (type_mask & MAY_BE_ITERABLE) {
@@ -1184,7 +1188,7 @@ static int zend_verify_internal_return_type(zend_function *zf, zval *ret)
zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1;
void *dummy_cache_slot = NULL;
if (ZEND_TYPE_IS_MASK(ret_info->type) && (ZEND_TYPE_MASK(ret_info->type) & MAY_BE_VOID)) {
if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_VOID) {
if (UNEXPECTED(Z_TYPE_P(ret) != IS_NULL)) {
zend_verify_void_return_error(zf, zend_zval_type_name(ret), "");
return 0;
@@ -1216,6 +1220,7 @@ static ZEND_COLD int zend_verify_missing_return_type(const zend_function *zf, vo
zend_arg_info *ret_info = zf->common.arg_info - 1;
// TODO: Eliminate this!
zend_class_entry *ce = NULL;
if (ZEND_TYPE_IS_CLASS(ret_info->type)) {
if (UNEXPECTED(!*cache_slot)) {
zend_class_entry *ce = zend_fetch_class(ZEND_TYPE_NAME(ret_info->type), (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
@@ -1560,7 +1565,7 @@ static zend_property_info *zend_get_prop_not_accepting_double(zend_reference *re
{
zend_property_info *prop;
ZEND_REF_FOREACH_TYPE_SOURCES(ref, prop) {
if (!ZEND_TYPE_IS_MASK(prop->type) || !(ZEND_TYPE_MASK(prop->type) & MAY_BE_DOUBLE)) {
if (!(ZEND_TYPE_FULL_MASK(prop->type) & MAY_BE_DOUBLE)) {
return prop;
}
} ZEND_REF_FOREACH_TYPE_SOURCES_END();
@@ -2528,7 +2533,7 @@ static zend_always_inline zend_bool check_type_array_assignable(zend_type type)
if (!ZEND_TYPE_IS_SET(type)) {
return 1;
}
return ZEND_TYPE_IS_MASK(type) && (ZEND_TYPE_MASK(type) & (MAY_BE_ITERABLE|MAY_BE_ARRAY));
return (ZEND_TYPE_FULL_MASK(type) & (MAY_BE_ITERABLE|MAY_BE_ARRAY)) != 0;
}
/* Checks whether an array can be assigned to the reference. Throws error if not assignable. */
@@ -2959,7 +2964,7 @@ static zend_always_inline int i_zend_verify_type_assignable_zval(
return 1;
}
type_mask = ZEND_TYPE_MASK(type);
type_mask = ZEND_TYPE_FULL_MASK(type);
if (type_mask & MAY_BE_ITERABLE) {
return zend_is_iterable(zv);
}
@@ -3013,9 +3018,9 @@ ZEND_API zend_bool ZEND_FASTCALL zend_verify_ref_assignable_zval(zend_reference
if (!seen_prop) {
seen_prop = prop;
seen_type_mask = ZEND_TYPE_IS_CLASS(prop->type)
? MAY_BE_OBJECT : ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(prop->type));
? MAY_BE_OBJECT : ZEND_TYPE_PURE_MASK_WITHOUT_NULL(prop->type);
} else if (needs_coercion
&& seen_type_mask != ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(prop->type))) {
&& seen_type_mask != ZEND_TYPE_PURE_MASK_WITHOUT_NULL(prop->type)) {
zend_throw_conflicting_coercion_error(seen_prop, prop, zv);
return 0;
}
@@ -3082,13 +3087,13 @@ ZEND_API zend_bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref(zend_propert
if (result < 0) {
zend_property_info *ref_prop = ZEND_REF_FIRST_SOURCE(Z_REF_P(orig_val));
if (ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(prop_info->type))
!= ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(ref_prop->type))) {
if (ZEND_TYPE_PURE_MASK_WITHOUT_NULL(prop_info->type)
!= ZEND_TYPE_PURE_MASK_WITHOUT_NULL(ref_prop->type)) {
/* Invalid due to conflicting coercion */
zend_throw_ref_type_error_type(ref_prop, prop_info, val);
return 0;
}
if (zend_verify_weak_scalar_type_hint(ZEND_TYPE_MASK(prop_info->type), val)) {
if (zend_verify_weak_scalar_type_hint(ZEND_TYPE_FULL_MASK(prop_info->type), val)) {
return 1;
}
}

View File

@@ -350,7 +350,7 @@ static inheritance_status zend_perform_covariant_type_check(
}
return unlinked_instanceof(fe_ce, proto_ce) ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
} else if (ZEND_TYPE_MASK(proto_type) & MAY_BE_ITERABLE) {
} else if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_ITERABLE) {
if (ZEND_TYPE_IS_CLASS(fe_type)) {
zend_string *fe_class_name =
resolve_class_name(fe->common.scope, ZEND_TYPE_NAME(fe_type));
@@ -363,9 +363,9 @@ static inheritance_status zend_perform_covariant_type_check(
? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
}
return ZEND_TYPE_MASK(fe_type) & (MAY_BE_ARRAY|MAY_BE_ITERABLE)
return ZEND_TYPE_FULL_MASK(fe_type) & (MAY_BE_ARRAY|MAY_BE_ITERABLE)
? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
} else if (ZEND_TYPE_MASK(proto_type) & MAY_BE_OBJECT) {
} else if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_OBJECT) {
if (ZEND_TYPE_IS_CLASS(fe_type)) {
/* Currently, any class name would be allowed here. We still perform a class lookup
* for forward-compatibility reasons, as we may have named types in the future that
@@ -380,10 +380,10 @@ static inheritance_status zend_perform_covariant_type_check(
return INHERITANCE_SUCCESS;
}
return ZEND_TYPE_MASK(fe_type) & MAY_BE_OBJECT ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
return ZEND_TYPE_FULL_MASK(fe_type) & MAY_BE_OBJECT
? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
} else {
return ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(fe_type))
== ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(proto_type))
return ZEND_TYPE_PURE_MASK_WITHOUT_NULL(fe_type) == ZEND_TYPE_PURE_MASK_WITHOUT_NULL(proto_type)
? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
}
}
@@ -490,7 +490,7 @@ static inheritance_status zend_do_perform_implementation_check(
}
/* by-ref constraints on arguments are invariant */
if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) {
if (ZEND_ARG_SEND_MODE(fe_arg_info) != ZEND_ARG_SEND_MODE(proto_arg_info)) {
return INHERITANCE_ERROR;
}
}
@@ -561,11 +561,11 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
for (i = 0; i < num_args;) {
zend_append_type_hint(&str, fptr, arg_info, 0);
if (arg_info->pass_by_reference) {
if (ZEND_ARG_SEND_MODE(arg_info)) {
smart_str_appendc(&str, '&');
}
if (arg_info->is_variadic) {
if (ZEND_ARG_IS_VARIADIC(arg_info)) {
smart_str_appends(&str, "...");
}
@@ -582,7 +582,7 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
smart_str_append_unsigned(&str, i);
}
if (i >= required && !arg_info->is_variadic) {
if (i >= required && !ZEND_ARG_IS_VARIADIC(arg_info)) {
smart_str_appends(&str, " = ");
if (fptr->type == ZEND_USER_FUNCTION) {
zend_op *precv = NULL;
@@ -847,7 +847,8 @@ inheritance_status property_types_compatible(
const zend_property_info *parent_info, const zend_property_info *child_info) {
zend_string *parent_name, *child_name;
zend_class_entry *parent_type_ce, *child_type_ce;
if (parent_info->type == child_info->type) {
if (ZEND_TYPE_PURE_MASK(parent_info->type) == ZEND_TYPE_PURE_MASK(child_info->type)
&& ZEND_TYPE_NAME(parent_info->type) == ZEND_TYPE_NAME(child_info->type)) {
return INHERITANCE_SUCCESS;
}

View File

@@ -106,87 +106,106 @@ typedef void (*copy_ctor_func_t)(zval *pElement);
* It shouldn't be used directly. Only through ZEND_TYPE_* macros.
*
* ZEND_TYPE_IS_SET() - checks if type-hint exists
* ZEND_TYPE_IS_MASK() - checks if type-hint refer to standard type
* ZEND_TYPE_IS_ONLY_MASK() - checks if type-hint refer to standard type
* ZEND_TYPE_IS_CLASS() - checks if type-hint refer to some class
* ZEND_TYPE_IS_CE() - checks if type-hint refer to some class by zend_class_entry *
* ZEND_TYPE_IS_NAME() - checks if type-hint refer to some class by zend_string *
*
* ZEND_TYPE_NAME() - returns referenced class name
* ZEND_TYPE_CE() - returns referenced class entry
* ZEND_TYPE_MASK() - returns MAY_BE_* type mask
* ZEND_TYPE_PURE_MASK() - returns MAY_BE_* type mask
* ZEND_TYPE_FULL_MASK() - returns MAY_BE_* type mask together with other flags
*
* ZEND_TYPE_ALLOW_NULL() - checks if NULL is allowed
*
* ZEND_TYPE_ENCODE_*() should be used for construction.
* ZEND_TYPE_INIT_*() should be used for construction.
*/
typedef uintptr_t zend_type;
typedef struct {
/* Not using a union here, because there's no good way to initialize them
* in a way that is supported in both C and C++ (designated initializers
* are only supported since C++20). */
void *ptr;
uint32_t type_mask;
/* TODO: We could use the extra 32-bit of padding on 64-bit systems. */
} zend_type;
#define _ZEND_TYPE_CODE_MAX ((Z_L(1)<<(IS_VOID+1))-1)
#define _ZEND_TYPE_FLAG_MASK Z_L(0x3)
#define _ZEND_TYPE_CE_BIT Z_L(0x1)
#define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 24
#define _ZEND_TYPE_MASK ((1u << 24) - 1)
#define _ZEND_TYPE_MAY_BE_MASK ((1u << (IS_VOID+1)) - 1)
#define _ZEND_TYPE_CE_BIT (1u << 22)
#define _ZEND_TYPE_NAME_BIT (1u << 23)
/* Must have same value as MAY_BE_NULL */
#define _ZEND_TYPE_NULLABLE_BIT Z_L(0x2)
#define _ZEND_TYPE_NULLABLE_BIT 0x2
#define ZEND_TYPE_IS_SET(t) \
((t) != 0)
#define ZEND_TYPE_IS_MASK(t) \
((t) != 0 && (t) <= _ZEND_TYPE_CODE_MAX)
(((t).type_mask & _ZEND_TYPE_MASK) != 0)
#define ZEND_TYPE_IS_CLASS(t) \
((t) > _ZEND_TYPE_CODE_MAX)
(((t.type_mask) & (_ZEND_TYPE_NAME_BIT|_ZEND_TYPE_CE_BIT)) != 0)
#define ZEND_TYPE_IS_CE(t) \
(((t) & _ZEND_TYPE_CE_BIT) != 0)
(((t.type_mask) & _ZEND_TYPE_CE_BIT) != 0)
#define ZEND_TYPE_IS_NAME(t) \
(ZEND_TYPE_IS_CLASS(t) && !ZEND_TYPE_IS_CE(t))
(((t.type_mask) & _ZEND_TYPE_NAME_BIT) != 0)
#define ZEND_TYPE_IS_ONLY_MASK(t) \
(ZEND_TYPE_IS_SET(t) && (t).ptr == NULL)
#define ZEND_TYPE_NAME(t) \
((zend_string*)((t) & ~_ZEND_TYPE_FLAG_MASK))
((zend_string *) (t).ptr)
#define ZEND_TYPE_LITERAL_NAME(t) \
((const char *) (t).ptr)
#define ZEND_TYPE_CE(t) \
((zend_class_entry*)((t) & ~_ZEND_TYPE_FLAG_MASK))
((zend_class_entry *) (t).ptr)
#define ZEND_TYPE_MASK(t) \
(t)
#define ZEND_TYPE_SET_PTR(t, _ptr) \
((t).ptr = (_ptr))
/* FULL_MASK() includes the MAY_BE_* type mask, the CE/NAME bits, as well as extra reserved bits.
* The PURE_MASK() only includes the MAY_BE_* type mask. */
#define ZEND_TYPE_FULL_MASK(t) \
((t).type_mask)
#define ZEND_TYPE_PURE_MASK(t) \
((t).type_mask & _ZEND_TYPE_MAY_BE_MASK)
#define ZEND_TYPE_FULL_MASK_WITHOUT_NULL(t) \
((t).type_mask & ~_ZEND_TYPE_NULLABLE_BIT)
#define ZEND_TYPE_PURE_MASK_WITHOUT_NULL(t) \
((t).type_mask & _ZEND_TYPE_MAY_BE_MASK & ~_ZEND_TYPE_NULLABLE_BIT)
#define ZEND_TYPE_CONTAINS_CODE(t, code) \
(((t) & (1 << (code))) != 0)
(((t).type_mask & (1u << (code))) != 0)
#define ZEND_TYPE_ALLOW_NULL(t) \
(((t) & _ZEND_TYPE_NULLABLE_BIT) != 0)
(((t).type_mask & _ZEND_TYPE_NULLABLE_BIT) != 0)
#define ZEND_TYPE_WITHOUT_NULL(t) \
((t) & ~_ZEND_TYPE_NULLABLE_BIT)
#define ZEND_TYPE_INIT_NONE(extra_flags) \
{ NULL, (extra_flags) }
#define ZEND_TYPE_ENCODE_NONE() \
(0)
#define ZEND_TYPE_INIT_MASK(_type_mask) \
{ NULL, (_type_mask) }
#define ZEND_TYPE_ENCODE_MASK(maybe_code) \
(maybe_code)
#define ZEND_TYPE_INIT_CODE(code, allow_null, extra_flags) \
ZEND_TYPE_INIT_MASK(((code) == _IS_BOOL ? (MAY_BE_FALSE|MAY_BE_TRUE) : (1 << (code))) \
| ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags))
#define ZEND_TYPE_ENCODE_CODE(code, allow_null) \
(((code) == _IS_BOOL ? (MAY_BE_FALSE|MAY_BE_TRUE) : (1 << (code))) \
| ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : Z_L(0x0)))
#define ZEND_TYPE_INIT_CE(_ce, allow_null, extra_flags) \
{ (void *) (_ce), \
_ZEND_TYPE_CE_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) }
#define ZEND_TYPE_ENCODE_CE(ce, allow_null) \
(((uintptr_t)(ce)) | _ZEND_TYPE_CE_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : Z_L(0x0)))
#define ZEND_TYPE_INIT_CLASS(class_name, allow_null, extra_flags) \
{ (void *) (class_name), \
_ZEND_TYPE_NAME_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) }
#define ZEND_TYPE_ENCODE_CLASS(class_name, allow_null) \
(((uintptr_t)(class_name)) | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : Z_L(0x0)))
#define ZEND_TYPE_ENCODE_CLASS_CONST_0(class_name) \
((zend_type) class_name)
#define ZEND_TYPE_ENCODE_CLASS_CONST_1(class_name) \
((zend_type) "?" class_name)
#define ZEND_TYPE_ENCODE_CLASS_CONST_Q2(macro, class_name) \
macro(class_name)
#define ZEND_TYPE_ENCODE_CLASS_CONST_Q1(allow_null, class_name) \
ZEND_TYPE_ENCODE_CLASS_CONST_Q2(ZEND_TYPE_ENCODE_CLASS_CONST_ ##allow_null, class_name)
#define ZEND_TYPE_ENCODE_CLASS_CONST(class_name, allow_null) \
ZEND_TYPE_ENCODE_CLASS_CONST_Q1(allow_null, class_name)
#define ZEND_TYPE_INIT_CLASS_CONST(class_name, allow_null, extra_flags) \
{ (void *) (class_name), \
_ZEND_TYPE_NAME_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) }
typedef union _zend_value {
zend_long lval; /* long value */

View File

@@ -4109,7 +4109,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
}
if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
&& !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
&& !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
&& retval_ref != retval_ptr)

View File

@@ -8739,7 +8739,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP
}
if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
&& !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
&& !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
&& retval_ref != retval_ptr)
@@ -18669,7 +18669,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN
}
if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
&& !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
&& !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
&& retval_ref != retval_ptr)
@@ -26096,7 +26096,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN
}
if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
&& !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
&& !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
&& retval_ref != retval_ptr)
@@ -32718,7 +32718,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED
}
if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
&& !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
&& !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
&& retval_ref != retval_ptr)
@@ -44161,7 +44161,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
}
if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
&& !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
&& !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
&& !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
&& retval_ref != retval_ptr)

View File

@@ -496,7 +496,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
if (f->arg_info) {
for (i = 0; i < nargs; i++) {
if (f->arg_info[nargs - i - 1].pass_by_reference) {
if (ZEND_ARG_SEND_MODE(&f->arg_info[nargs - i - 1])) {
byref_count++;
}
}
@@ -505,7 +505,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
if (byref_count) {
byref_vals = (VARIANT*)safe_emalloc(sizeof(VARIANT), byref_count, 0);
for (j = 0, i = 0; i < nargs; i++) {
if (f->arg_info[nargs - i - 1].pass_by_reference) {
if (ZEND_ARG_SEND_MODE(&f->arg_info[nargs - i - 1])) {
/* put the value into byref_vals instead */
php_com_variant_from_zval(&byref_vals[j], &args[nargs - i - 1], obj->code_page);
@@ -552,7 +552,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
if (f && f->arg_info) {
for (i = 0, j = 0; i < nargs; i++) {
/* if this was byref, update the zval */
if (f->arg_info[nargs - i - 1].pass_by_reference) {
if (ZEND_ARG_SEND_MODE(&f->arg_info[nargs - i - 1])) {
zval *arg = &args[nargs - i - 1];
ZVAL_DEREF(arg);

View File

@@ -327,10 +327,8 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name
f.arg_info = ecalloc(bindptr.lpfuncdesc->cParams, sizeof(zend_arg_info));
for (i = 0; i < bindptr.lpfuncdesc->cParams; i++) {
f.arg_info[i].type = ZEND_TYPE_ENCODE_NONE();
if (bindptr.lpfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOUT) {
f.arg_info[i].pass_by_reference = ZEND_SEND_BY_REF;
}
zend_bool by_ref = (bindptr.lpfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOUT) != 0;
f.arg_info[i].type = (zend_type) ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(by_ref, 0));
}
f.num_args = bindptr.lpfuncdesc->cParams;

View File

@@ -307,8 +307,7 @@ static inline zend_bool can_elide_return_type_check(
}
/* These types are not represented exactly */
if (ZEND_TYPE_IS_MASK(info->type)
&& (ZEND_TYPE_MASK(info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))) {
if (ZEND_TYPE_FULL_MASK(info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE)) {
return 0;
}

View File

@@ -116,7 +116,7 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
for (i = 0; i < num_args; i++) {
/* Don't inline functions with by-reference arguments. This would require
* correct handling of INDIRECT arguments. */
if (func->op_array.arg_info[i].pass_by_reference) {
if (ZEND_ARG_SEND_MODE(&func->op_array.arg_info[i])) {
return;
}
}

View File

@@ -1420,21 +1420,19 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
} else if (op_array->arg_info &&
opline->op1.num <= op_array->num_args) {
zend_type type = op_array->arg_info[opline->op1.num-1].type;
if (ZEND_TYPE_IS_MASK(type)) {
uint32_t mask = ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(type));
if (mask == MAY_BE_LONG) {
tmp->underflow = 0;
tmp->min = ZEND_LONG_MIN;
tmp->max = ZEND_LONG_MAX;
tmp->overflow = 0;
return 1;
} else if (mask == (MAY_BE_FALSE|MAY_BE_TRUE)) {
tmp->underflow = 0;
tmp->min = 0;
tmp->max = 1;
tmp->overflow = 0;
return 1;
}
uint32_t mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(type);
if (mask == MAY_BE_LONG) {
tmp->underflow = 0;
tmp->min = ZEND_LONG_MIN;
tmp->max = ZEND_LONG_MAX;
tmp->overflow = 0;
return 1;
} else if (mask == (MAY_BE_FALSE|MAY_BE_TRUE)) {
tmp->underflow = 0;
tmp->min = 0;
tmp->max = 1;
tmp->overflow = 0;
return 1;
}
}
}
@@ -2231,42 +2229,36 @@ static inline zend_class_entry *get_class_entry(const zend_script *script, zend_
}
static uint32_t zend_convert_type_declaration_mask(uint32_t type_mask) {
uint32_t result_mask = type_mask & MAY_BE_ANY;
if (type_mask & MAY_BE_VOID) {
type_mask &= ~MAY_BE_VOID;
type_mask |= MAY_BE_NULL;
result_mask |= MAY_BE_NULL;
}
if (type_mask & MAY_BE_CALLABLE) {
type_mask &= ~MAY_BE_CALLABLE;
type_mask |= MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
result_mask |= MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
}
if (type_mask & MAY_BE_ITERABLE) {
type_mask &= ~MAY_BE_ITERABLE;
type_mask |= MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
result_mask |= MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
}
if (type_mask & MAY_BE_ARRAY) {
type_mask |= MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
result_mask |= MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
}
return type_mask;
return result_mask;
}
uint32_t zend_fetch_arg_info_type(const zend_script *script, zend_arg_info *arg_info, zend_class_entry **pce)
{
uint32_t tmp = 0;
uint32_t tmp;
if (!ZEND_TYPE_IS_SET(arg_info->type)) {
return MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_RC1|MAY_BE_RCN;
}
tmp = zend_convert_type_declaration_mask(ZEND_TYPE_PURE_MASK(arg_info->type));
*pce = NULL;
if (ZEND_TYPE_IS_CLASS(arg_info->type)) {
// class type hinting...
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(arg_info->type));
tmp |= MAY_BE_OBJECT;
*pce = get_class_entry(script, lcname);
zend_string_release_ex(lcname, 0);
} else if (ZEND_TYPE_IS_MASK(arg_info->type)) {
tmp |= zend_convert_type_declaration_mask(ZEND_TYPE_MASK(arg_info->type));
} else {
tmp |= MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
}
if (ZEND_TYPE_ALLOW_NULL(arg_info->type)) {
tmp |= MAY_BE_NULL;
}
if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
@@ -2365,7 +2357,7 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, zend_property_in
if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
uint32_t type = ZEND_TYPE_IS_CLASS(prop_info->type)
? MAY_BE_OBJECT
: zend_convert_type_declaration_mask(ZEND_TYPE_MASK(prop_info->type));
: zend_convert_type_declaration_mask(ZEND_TYPE_PURE_MASK(prop_info->type));
if (ZEND_TYPE_ALLOW_NULL(prop_info->type)) {
type |= MAY_BE_NULL;
@@ -3097,7 +3089,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
ce = NULL;
if (arg_info) {
tmp = zend_fetch_arg_info_type(script, arg_info, &ce);
if (arg_info->pass_by_reference) {
if (ZEND_ARG_SEND_MODE(arg_info)) {
tmp |= MAY_BE_REF;
}
} else {

View File

@@ -652,9 +652,7 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
}
case ZEND_VERIFY_RETURN_TYPE: {
zend_arg_info *ret_info = op_array->arg_info - 1;
if (ZEND_TYPE_IS_CLASS(ret_info->type)
|| (ZEND_TYPE_IS_MASK(ret_info->type)
&& !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(val)))
if (!ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(val))
|| (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
return 0;
}

View File

@@ -602,8 +602,8 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int
}
for (i = 0 ; i < num_args; i++) {
if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(arg_info[i].type);
arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(new_interned_string(ZEND_TYPE_NAME(arg_info[i].type)), allow_null);
ZEND_TYPE_SET_PTR(arg_info[i].type,
new_interned_string(ZEND_TYPE_NAME(arg_info[i].type)));
}
}
}
@@ -3580,7 +3580,7 @@ static zend_bool preload_try_resolve_property_types(zend_class_entry *ce)
}
zend_string_release(name);
prop->type = ZEND_TYPE_ENCODE_CE(p, ZEND_TYPE_ALLOW_NULL(prop->type));
prop->type = (zend_type) ZEND_TYPE_INIT_CE(p, ZEND_TYPE_ALLOW_NULL(prop->type), 0);
} ZEND_HASH_FOREACH_END();
}

View File

@@ -1177,7 +1177,7 @@ static void ZEND_FASTCALL zend_jit_verify_arg_slow(zval *arg, const zend_op_arra
goto err;
}
type_mask = ZEND_TYPE_MASK(arg_info->type);
type_mask = ZEND_TYPE_FULL_MASK(arg_info->type);
if (type_mask & MAY_BE_CALLABLE) {
if (zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) == 0) {
goto err;
@@ -1188,7 +1188,7 @@ static void ZEND_FASTCALL zend_jit_verify_arg_slow(zval *arg, const zend_op_arra
}
} else {
if (Z_ISUNDEF_P(arg) ||
zend_verify_scalar_type_hint(ZEND_TYPE_MASK(arg_info->type), arg, ZEND_ARG_USES_STRICT_TYPES(), /* is_internal */ 0) == 0) {
zend_verify_scalar_type_hint(type_mask, arg, ZEND_ARG_USES_STRICT_TYPES(), /* is_internal */ 0) == 0) {
goto err;
}
}
@@ -1345,7 +1345,7 @@ static zend_property_info *zend_jit_get_prop_not_accepting_double(zend_reference
{
zend_property_info *prop;
ZEND_REF_FOREACH_TYPE_SOURCES(ref, prop) {
if (!ZEND_TYPE_IS_MASK(prop->type) || !(ZEND_TYPE_MASK(prop->type) & MAY_BE_DOUBLE)) {
if (!(ZEND_TYPE_FULL_MASK(prop->type) & MAY_BE_DOUBLE)) {
return prop;
}
} ZEND_REF_FOREACH_TYPE_SOURCES_END();

View File

@@ -7102,8 +7102,8 @@ static uint32_t skip_valid_arguments(const zend_op_array *op_array, zend_ssa *ss
zend_arg_info *arg_info = func->op_array.arg_info + num_args;
if (ZEND_TYPE_IS_SET(arg_info->type)) {
if (ZEND_TYPE_IS_MASK(arg_info->type)) {
uint32_t type_mask = ZEND_TYPE_MASK(arg_info->type);
if (ZEND_TYPE_IS_ONLY_MASK(arg_info->type)) {
uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type);
uint32_t info = _ssa_op1_info(op_array, ssa, call_info->arg_info[num_args].opline);
if ((info & (MAY_BE_ANY|MAY_BE_UNDEF)) & ~type_mask) {
break;
@@ -9032,12 +9032,12 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_
zend_jit_addr res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, NULL, -1);
| LOAD_ZVAL_ADDR r0, res_addr
if (arg_info->pass_by_reference) {
if (ZEND_ARG_SEND_MODE(arg_info)) {
| GET_Z_PTR r0, r0
| add r0, offsetof(zend_reference, val)
}
if (!ZEND_TYPE_IS_CLASS(type)) {
uint32_t type_mask = ZEND_TYPE_MASK(type);
uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
if (is_power_of_two(type_mask)) {
uint32_t type_code = concrete_type(type_mask);
| cmp byte [r0 + 8], type_code
@@ -9186,7 +9186,7 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen
| LOAD_ZVAL_ADDR r0, res_addr
| ZVAL_DEREF r0, MAY_BE_REF
if (!ZEND_TYPE_IS_CLASS(arg_info->type)) {
uint32_t type_mask = ZEND_TYPE_MASK(arg_info->type);
uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type);
if (is_power_of_two(type_mask)) {
uint32_t type_code = concrete_type(type_mask);
| cmp byte [r0 + 8], type_code

View File

@@ -237,7 +237,7 @@ static void zend_hash_clone_prop_info(HashTable *ht)
zend_class_entry *ce = ZEND_TYPE_CE(prop_info->type);
if (IN_ARENA(ce)) {
ce = ARENA_REALLOC(ce);
prop_info->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop_info->type));
ZEND_TYPE_SET_PTR(prop_info->type, ce);
}
}
}

View File

@@ -499,14 +499,9 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
SERIALIZE_STR(p->name);
}
if (ZEND_TYPE_IS_CLASS(p->type)) {
zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(p->type);
zend_string *type_name = ZEND_TYPE_NAME(p->type);
SERIALIZE_STR(type_name);
p->type =
(Z_UL(1) << (sizeof(zend_type)*8-1)) | /* type is class */
(allow_null ? (Z_UL(1) << (sizeof(zend_type)*8-2)) : Z_UL(0)) | /* type allow null */
(zend_type)type_name;
ZEND_TYPE_SET_PTR(p->type, type_name);
}
p++;
}
@@ -577,16 +572,14 @@ static void zend_file_cache_serialize_prop_info(zval *zv,
SERIALIZE_STR(prop->doc_comment);
}
}
if (prop->type) {
if (ZEND_TYPE_IS_NAME(prop->type)) {
zend_string *name = ZEND_TYPE_NAME(prop->type);
SERIALIZE_STR(name);
prop->type = ZEND_TYPE_ENCODE_CLASS(name, ZEND_TYPE_ALLOW_NULL(prop->type));
} else if (ZEND_TYPE_IS_CE(prop->type)) {
zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
SERIALIZE_PTR(ce);
prop->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop->type));
}
if (ZEND_TYPE_IS_NAME(prop->type)) {
zend_string *name = ZEND_TYPE_NAME(prop->type);
SERIALIZE_STR(name);
ZEND_TYPE_SET_PTR(prop->type, name);
} else if (ZEND_TYPE_IS_CE(prop->type)) {
zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
SERIALIZE_PTR(ce);
ZEND_TYPE_SET_PTR(prop->type, ce);
}
}
}
@@ -1202,12 +1195,10 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
if (!IS_UNSERIALIZED(p->name)) {
UNSERIALIZE_STR(p->name);
}
if (p->type & (Z_UL(1) << (sizeof(zend_type)*8-1))) { /* type is class */
zend_bool allow_null = (p->type & (Z_UL(1) << (sizeof(zend_type)*8-2))) != 0; /* type allow null */
zend_string *type_name = (zend_string*)(p->type & ~(((Z_UL(1) << (sizeof(zend_type)*8-1))) | ((Z_UL(1) << (sizeof(zend_type)*8-2)))));
if (ZEND_TYPE_IS_CLASS(p->type)) {
zend_string *type_name = ZEND_TYPE_NAME(p->type);
UNSERIALIZE_STR(type_name);
p->type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null);
ZEND_TYPE_SET_PTR(p->type, type_name);
}
p++;
}
@@ -1278,16 +1269,14 @@ static void zend_file_cache_unserialize_prop_info(zval *zv,
UNSERIALIZE_STR(prop->doc_comment);
}
}
if (prop->type) {
if (ZEND_TYPE_IS_NAME(prop->type)) {
zend_string *name = ZEND_TYPE_NAME(prop->type);
UNSERIALIZE_STR(name);
prop->type = ZEND_TYPE_ENCODE_CLASS(name, ZEND_TYPE_ALLOW_NULL(prop->type));
} else if (ZEND_TYPE_IS_CE(prop->type)) {
zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
UNSERIALIZE_PTR(ce);
prop->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop->type));
}
if (ZEND_TYPE_IS_NAME(prop->type)) {
zend_string *name = ZEND_TYPE_NAME(prop->type);
UNSERIALIZE_STR(name);
ZEND_TYPE_SET_PTR(prop->type, name);
} else if (ZEND_TYPE_IS_CE(prop->type)) {
zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
UNSERIALIZE_PTR(ce);
ZEND_TYPE_SET_PTR(prop->type, ce);
}
}
}

View File

@@ -501,10 +501,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
}
if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
zend_string *type_name = ZEND_TYPE_NAME(arg_info[i].type);
zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(arg_info[i].type);
zend_accel_store_interned_string(type_name);
arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null);
ZEND_TYPE_SET_PTR(arg_info[i].type, type_name);
}
}
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
@@ -664,7 +662,7 @@ static void zend_persist_property_info(zval *zv)
if (ZEND_TYPE_IS_NAME(prop->type)) {
zend_string *class_name = ZEND_TYPE_NAME(prop->type);
zend_accel_store_interned_string(class_name);
prop->type = ZEND_TYPE_ENCODE_CLASS(class_name, ZEND_TYPE_ALLOW_NULL(prop->type));
ZEND_TYPE_SET_PTR(prop->type, class_name);
}
}
@@ -944,7 +942,7 @@ static void zend_update_parent_ce(zend_class_entry *ce)
if (ce->type == ZEND_USER_CLASS) {
ce = zend_shared_alloc_get_xlat_entry(ce);
if (ce) {
prop->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop->type));
ZEND_TYPE_SET_PTR(prop->type, ce);
}
}
}

View File

@@ -224,10 +224,8 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
}
if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
zend_string *type_name = ZEND_TYPE_NAME(arg_info[i].type);
zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(arg_info[i].type);
ADD_INTERNED_STRING(type_name);
arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null);
ZEND_TYPE_SET_PTR(arg_info[i].type, type_name);
}
}
}
@@ -307,7 +305,7 @@ static void zend_persist_property_info_calc(zval *zv)
if (ZEND_TYPE_IS_NAME(prop->type)) {
zend_string *class_name = ZEND_TYPE_NAME(prop->type);
ADD_INTERNED_STRING(class_name);
prop->type = ZEND_TYPE_ENCODE_CLASS(class_name, ZEND_TYPE_ALLOW_NULL(prop->type));
ZEND_TYPE_SET_PTR(prop->type, class_name);
}
if (ZCG(accel_directives).save_comments && prop->doc_comment) {
ADD_STRING(prop->doc_comment);

View File

@@ -1292,10 +1292,10 @@ int pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind)
} else {
func.required_num_args = info->required_num_args;
}
if (info->return_reference) {
if (ZEND_ARG_SEND_MODE(info)) {
func.fn_flags |= ZEND_ACC_RETURN_REFERENCE;
}
if (funcs->arg_info[funcs->num_args].is_variadic) {
if (ZEND_ARG_IS_VARIADIC(&funcs->arg_info[funcs->num_args])) {
func.fn_flags |= ZEND_ACC_VARIADIC;
/* Don't count the variadic argument */
func.num_args--;

View File

@@ -595,10 +595,10 @@ static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_
smart_str_append_printf(str, "%s ", ZSTR_VAL(type_str));
zend_string_release(type_str);
}
if (arg_info->pass_by_reference) {
if (ZEND_ARG_SEND_MODE(arg_info)) {
smart_str_appendc(str, '&');
}
if (arg_info->is_variadic) {
if (ZEND_ARG_IS_VARIADIC(arg_info)) {
smart_str_appends(str, "...");
}
if (arg_info->name) {
@@ -2572,15 +2572,15 @@ ZEND_METHOD(reflection_parameter, isArray)
{
reflection_object *intern;
parameter_reference *param;
zend_type type;
uint32_t type_mask;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
GET_REFLECTION_OBJECT_PTR(param);
type = ZEND_TYPE_WITHOUT_NULL(param->arg_info->type);
RETVAL_BOOL(ZEND_TYPE_MASK(type) == MAY_BE_ARRAY);
type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type);
RETVAL_BOOL(type_mask == MAY_BE_ARRAY);
}
/* }}} */
@@ -2590,15 +2590,15 @@ ZEND_METHOD(reflection_parameter, isCallable)
{
reflection_object *intern;
parameter_reference *param;
zend_type type;
uint32_t type_mask;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
GET_REFLECTION_OBJECT_PTR(param);
type = ZEND_TYPE_WITHOUT_NULL(param->arg_info->type);
RETVAL_BOOL(ZEND_TYPE_MASK(type) == MAY_BE_CALLABLE);
type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type);
RETVAL_BOOL(type_mask == MAY_BE_CALLABLE);
}
/* }}} */
@@ -2631,7 +2631,7 @@ ZEND_METHOD(reflection_parameter, isPassedByReference)
}
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->pass_by_reference);
RETVAL_BOOL(ZEND_ARG_SEND_MODE(param->arg_info));
}
/* }}} */
@@ -2648,7 +2648,7 @@ ZEND_METHOD(reflection_parameter, canBePassedByValue)
GET_REFLECTION_OBJECT_PTR(param);
/* true if it's ZEND_SEND_BY_VAL or ZEND_SEND_PREFER_REF */
RETVAL_BOOL(param->arg_info->pass_by_reference != ZEND_SEND_BY_REF);
RETVAL_BOOL(ZEND_ARG_SEND_MODE(param->arg_info) != ZEND_SEND_BY_REF);
}
/* }}} */
@@ -2809,7 +2809,7 @@ ZEND_METHOD(reflection_parameter, isVariadic)
}
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->is_variadic);
RETVAL_BOOL(ZEND_ARG_IS_VARIADIC(param->arg_info));
}
/* }}} */
@@ -2829,6 +2829,11 @@ ZEND_METHOD(reflection_type, allowsNull)
}
/* }}} */
static zend_string *zend_type_to_string_without_null(zend_type type) {
ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_NULL;
return zend_type_to_string(type);
}
/* {{{ proto public string ReflectionType::__toString()
Return the text of the type hint */
ZEND_METHOD(reflection_type, __toString)
@@ -2857,7 +2862,7 @@ ZEND_METHOD(reflection_named_type, getName)
}
GET_REFLECTION_OBJECT_PTR(param);
RETURN_STR(zend_type_to_string(ZEND_TYPE_WITHOUT_NULL(param->type)));
RETURN_STR(zend_type_to_string_without_null(param->type));
}
/* }}} */
@@ -2873,7 +2878,7 @@ ZEND_METHOD(reflection_named_type, isBuiltin)
}
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(ZEND_TYPE_IS_MASK(param->type));
RETVAL_BOOL(ZEND_TYPE_IS_ONLY_MASK(param->type));
}
/* }}} */

View File

@@ -237,7 +237,8 @@ PHP_MINIT_FUNCTION(zend_test)
zval val;
ZVAL_LONG(&val, 123);
zend_declare_typed_property(
zend_test_class, name, &val, ZEND_ACC_PUBLIC, NULL, ZEND_TYPE_ENCODE_CODE(IS_LONG, 0));
zend_test_class, name, &val, ZEND_ACC_PUBLIC, NULL,
(zend_type) ZEND_TYPE_INIT_CODE(IS_LONG, 0, 0));
zend_string_release(name);
}
@@ -248,7 +249,7 @@ PHP_MINIT_FUNCTION(zend_test)
ZVAL_NULL(&val);
zend_declare_typed_property(
zend_test_class, name, &val, ZEND_ACC_PUBLIC, NULL,
ZEND_TYPE_ENCODE_CLASS(class_name, 1));
(zend_type) ZEND_TYPE_INIT_CLASS(class_name, 1, 0));
zend_string_release(name);
}
@@ -258,7 +259,7 @@ PHP_MINIT_FUNCTION(zend_test)
ZVAL_LONG(&val, 123);
zend_declare_typed_property(
zend_test_class, name, &val, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC, NULL,
ZEND_TYPE_ENCODE_CODE(IS_LONG, 0));
(zend_type) ZEND_TYPE_INIT_CODE(IS_LONG, 0, 0));
zend_string_release(name);
}

View File

@@ -229,7 +229,7 @@ static void phpdbg_dump_prototype(zval *tmp) /* {{{ */
}
if (!is_variadic) {
is_variadic = arginfo ? arginfo[j].is_variadic : 0;
is_variadic = arginfo ? ZEND_ARG_IS_VARIADIC(&arginfo[j]) : 0;
}
phpdbg_xml(" variadic=\"%s\" name=\"%s\">", is_variadic ? "variadic" : "", arg_name ? arg_name : "");