summaryrefslogtreecommitdiff
path: root/Zend/zend_types.h
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_types.h')
-rw-r--r--Zend/zend_types.h111
1 files changed, 65 insertions, 46 deletions
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index b381eeff14..d77fbc68a3 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -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;
-
-#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)
+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_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)
-
-#define ZEND_TYPE_WITHOUT_NULL(t) \
- ((t) & ~_ZEND_TYPE_NULLABLE_BIT)
+ (((t).type_mask & _ZEND_TYPE_NULLABLE_BIT) != 0)
-#define ZEND_TYPE_ENCODE_NONE() \
- (0)
+#define ZEND_TYPE_INIT_NONE(extra_flags) \
+ { NULL, (extra_flags) }
-#define ZEND_TYPE_ENCODE_MASK(maybe_code) \
- (maybe_code)
+#define ZEND_TYPE_INIT_MASK(_type_mask) \
+ { NULL, (_type_mask) }
-#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_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_CE(ce, allow_null) \
- (((uintptr_t)(ce)) | _ZEND_TYPE_CE_BIT | ((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_CLASS(class_name, allow_null) \
- (((uintptr_t)(class_name)) | ((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_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 */