Skip to content

Commit bbd4833

Browse files
committed
Zend: store pure type mask in opline->extended_value
1 parent 9d4e9d3 commit bbd4833

4 files changed

Lines changed: 63 additions & 34 deletions

File tree

Zend/zend_compile.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,6 +2699,8 @@ static void zend_emit_return_type_check(
26992699
}
27002700

27012701
opline = zend_emit_op(NULL, ZEND_VERIFY_RETURN_TYPE, expr, NULL);
2702+
/* Store pure type mask in extended_value */
2703+
opline->extended_value = ZEND_TYPE_PURE_MASK(type);
27022704
if (expr && expr->op_type == IS_CONST) {
27032705
opline->result_type = expr->op_type = IS_TMP_VAR;
27042706
opline->result.var = expr->u.op.var = get_temporary_variable();

Zend/zend_types.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,11 @@ typedef struct {
272272
#define ZEND_TYPE_PURE_MASK_WITHOUT_NULL(t) \
273273
((t).type_mask & _ZEND_TYPE_MAY_BE_MASK & ~_ZEND_TYPE_NULLABLE_BIT)
274274

275+
#define ZEND_TYPE_MASK_CONTAINS_CODE(mask, code) \
276+
(((mask) & (1u << (code))) != 0)
277+
275278
#define ZEND_TYPE_CONTAINS_CODE(t, code) \
276-
(((t).type_mask & (1u << (code))) != 0)
279+
ZEND_TYPE_MASK_CONTAINS_CODE((t).type_mask, code)
277280

278281
#define ZEND_TYPE_ALLOW_NULL(t) \
279282
(((t).type_mask & _ZEND_TYPE_NULLABLE_BIT) != 0)

Zend/zend_vm_def.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* php zend_vm_gen.php
2424
*/
2525

26+
#include <stdint.h>
27+
2628
ZEND_VM_HELPER(zend_add_helper, ANY, ANY, zval *op_1, zval *op_2)
2729
{
2830
USE_OPLINE
@@ -4471,7 +4473,6 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
44714473
#if !ZEND_VM_SPEC || (OP1_TYPE != IS_UNUSED)
44724474
USE_OPLINE
44734475
zval *retval_ref, *retval_ptr;
4474-
zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
44754476
retval_ref = retval_ptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
44764477

44774478
if (OP1_TYPE == IS_CONST) {
@@ -4486,7 +4487,8 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
44864487
ZVAL_DEREF(retval_ptr);
44874488
}
44884489

4489-
if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
4490+
uint32_t pure_type_mask = opline->extended_value;
4491+
if (EXPECTED(ZEND_TYPE_MASK_CONTAINS_CODE(pure_type_mask, Z_TYPE_P(retval_ptr)))) {
44904492
ZEND_VM_NEXT_OPCODE();
44914493
}
44924494

@@ -4496,7 +4498,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
44964498
if (UNEXPECTED(EG(exception))) {
44974499
HANDLE_EXCEPTION();
44984500
}
4499-
if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
4501+
if (pure_type_mask & MAY_BE_NULL) {
45004502
ZEND_VM_NEXT_OPCODE();
45014503
}
45024504
}
@@ -4517,6 +4519,8 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
45174519
}
45184520
}
45194521

4522+
/* Fetch full return type info from function arg_info */
4523+
const zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
45204524
SAVE_OPLINE();
45214525
if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) {
45224526
zend_verify_return_error(EX(func), retval_ptr);

0 commit comments

Comments
 (0)