Skip to content

Commit b3a10d8

Browse files
committed
Test use and def
1 parent 5602690 commit b3a10d8

File tree

6 files changed

+82
-89
lines changed

6 files changed

+82
-89
lines changed

Zend/Optimizer/zend_optimizer.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,24 @@ static void propagate_ssa_inferred_types_to_oplines(zend_op_array *op_array, voi
14851485
zend_ssa_var_info *var_info = &ssa->var_info[i];
14861486
if (var->definition > 0) {
14871487
zend_op *opline = &op_array->opcodes[var->definition];
1488-
opline->result_inferred_type = var_info->type;
1488+
zend_ssa_op *ssa_op = &ssa->ops[var->definition];
1489+
if (ssa_op->op1_use == i) {
1490+
if (!opline->swapped_operands) {
1491+
opline->op1_def_type = var_info->type;
1492+
} else {
1493+
opline->op2_def_type = var_info->type;
1494+
}
1495+
}
1496+
if (ssa_op->op2_def == i) {
1497+
if (!opline->swapped_operands) {
1498+
opline->op2_def_type = var_info->type;
1499+
} else {
1500+
opline->op2_def_type = var_info->type;
1501+
}
1502+
}
1503+
if (ssa_op->result_def == i) {
1504+
opline->result_def_type = var_info->type;
1505+
}
14891506
}
14901507

14911508
int use;
@@ -1494,18 +1511,21 @@ static void propagate_ssa_inferred_types_to_oplines(zend_op_array *op_array, voi
14941511
zend_ssa_op *ssa_op = &ssa->ops[use];
14951512
if (ssa_op->op1_use == i) {
14961513
if (!opline->swapped_operands) {
1497-
opline->op1_inferred_type = var_info->type;
1514+
opline->op1_use_type = var_info->type;
14981515
} else {
1499-
opline->op2_inferred_type = var_info->type;
1516+
opline->op2_use_type = var_info->type;
15001517
}
15011518
}
15021519
if (ssa_op->op2_use == i) {
15031520
if (!opline->swapped_operands) {
1504-
opline->op2_inferred_type = var_info->type;
1521+
opline->op2_use_type = var_info->type;
15051522
} else {
1506-
opline->op1_inferred_type = var_info->type;
1523+
opline->op2_use_type = var_info->type;
15071524
}
15081525
}
1526+
if (ssa_op->result_use == i) {
1527+
opline->result_use_type = var_info->type;
1528+
}
15091529
} FOREACH_USE_END();
15101530
}
15111531
}

Zend/zend_compile.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,12 @@ static void init_op(zend_op *op)
125125
op->extended_value = 0;
126126
op->lineno = CG(zend_lineno);
127127
#ifdef ZEND_VERIFY_TYPE_INFERENCE
128-
op->result_inferred_type = 0;
129-
op->op1_inferred_type = 0;
130-
op->op2_inferred_type = 0;
128+
op->op1_use_type = 0;
129+
op->op2_use_type = 0;
130+
op->result_use_type = 0;
131+
op->op1_def_type = 0;
132+
op->op2_def_type = 0;
133+
op->result_def_type = 0;
131134
op->swapped_operands = false;
132135
#endif
133136
}

Zend/zend_compile.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,12 @@ struct _zend_op {
144144
uint8_t op2_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */
145145
uint8_t result_type; /* IS_UNUSED, IS_CONST, IS_TMP_VAR, IS_VAR, IS_CV */
146146
#ifdef ZEND_VERIFY_TYPE_INFERENCE
147-
uint32_t op1_inferred_type;
148-
uint32_t op2_inferred_type;
149-
uint32_t result_inferred_type;
147+
uint32_t op1_use_type;
148+
uint32_t op2_use_type;
149+
uint32_t result_use_type;
150+
uint32_t op1_def_type;
151+
uint32_t op2_def_type;
152+
uint32_t result_def_type;
150153
bool swapped_operands;
151154
#endif
152155
};

Zend/zend_execute.c

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5378,8 +5378,13 @@ static bool zend_verify_type_inference(uint32_t type_mask, zval *value)
53785378
return true;
53795379
}
53805380

5381-
static void zend_verify_result_type_inference(zend_execute_data *execute_data, const zend_op *opline)
5381+
static void zend_verify_result_type_inference(zend_execute_data *execute_data, const zend_op *opline, uint32_t type)
53825382
{
5383+
if (!type) {
5384+
return;
5385+
}
5386+
5387+
// FIXME: RETURN_VALUE_USED inaccurate?
53835388
if (!RETURN_VALUE_USED(opline)
53845389
|| EG(exception)
53855390
|| opline->opcode == ZEND_ROPE_INIT
@@ -5398,13 +5403,17 @@ static void zend_verify_result_type_inference(zend_execute_data *execute_data, c
53985403
return;
53995404
}
54005405

5401-
if (RETURN_VALUE_USED(opline) && !zend_verify_type_inference(opline->result_inferred_type, value)) {
5406+
if (RETURN_VALUE_USED(opline) && !zend_verify_type_inference(type, value)) {
54025407
fprintf(stderr, "Return type inference verification failed\n");
54035408
fflush(stderr);
54045409
}
54055410
}
5406-
static void zend_verify_op1_type_inference(zend_execute_data *execute_data, const zend_op *opline)
5411+
static void zend_verify_op1_type_inference(zend_execute_data *execute_data, const zend_op *opline, uint32_t type)
54075412
{
5413+
if (!type) {
5414+
return;
5415+
}
5416+
54085417
if (opline->op1_type == IS_UNUSED) {
54095418
return;
54105419
}
@@ -5417,13 +5426,17 @@ static void zend_verify_op1_type_inference(zend_execute_data *execute_data, cons
54175426
? RT_CONSTANT(opline, opline->op1)
54185427
: EX_VAR(opline->op1.var);
54195428

5420-
if (!zend_verify_type_inference(opline->op1_inferred_type, value)) {
5429+
if (!zend_verify_type_inference(type, value)) {
54215430
fprintf(stderr, "OP1 type inference verification failed\n");
54225431
fflush(stderr);
54235432
}
54245433
}
5425-
static void zend_verify_op2_type_inference(zend_execute_data *execute_data, const zend_op *opline)
5434+
static void zend_verify_op2_type_inference(zend_execute_data *execute_data, const zend_op *opline, uint32_t type)
54265435
{
5436+
if (!type) {
5437+
return;
5438+
}
5439+
54275440
if (opline->op2_type == IS_UNUSED) {
54285441
return;
54295442
}
@@ -5432,33 +5445,40 @@ static void zend_verify_op2_type_inference(zend_execute_data *execute_data, cons
54325445
? RT_CONSTANT(opline, opline->op2)
54335446
: EX_VAR(opline->op2.var);
54345447

5435-
if (!zend_verify_type_inference(opline->op2_inferred_type, value)) {
5448+
if (!zend_verify_type_inference(type, value)) {
54365449
fprintf(stderr, "OP2 type inference verification failed\n");
54375450
fflush(stderr);
54385451
}
54395452
}
5440-
static void zend_verify_operand_type_inference(zend_execute_data *execute_data, const zend_op *opline)
5453+
static void zend_verify_inference_use(zend_execute_data *execute_data, const zend_op *opline)
5454+
{
5455+
zend_verify_op1_type_inference(execute_data, opline, opline->op1_use_type);
5456+
zend_verify_op2_type_inference(execute_data, opline, opline->op2_use_type);
5457+
zend_verify_result_type_inference(execute_data, opline, opline->result_use_type);
5458+
}
5459+
static void zend_verify_inference_def(zend_execute_data *execute_data, const zend_op *opline)
54415460
{
5442-
zend_verify_op1_type_inference(execute_data, opline);
5443-
zend_verify_op2_type_inference(execute_data, opline);
5461+
zend_verify_op1_type_inference(execute_data, opline, opline->op1_def_type);
5462+
zend_verify_op2_type_inference(execute_data, opline, opline->op2_def_type);
5463+
zend_verify_result_type_inference(execute_data, opline, opline->result_def_type);
54445464
}
5445-
# define ZEND_VERIFY_RESULT_TYPE_INFERENCE() zend_verify_result_type_inference(execute_data, OPLINE);
5446-
# define ZEND_VERIFY_OPERAND_TYPE_INFERENCE() zend_verify_operand_type_inference(execute_data, OPLINE);
5465+
# define ZEND_VERIFY_INFERENCE_USE() zend_verify_inference_use(execute_data, OPLINE);
5466+
# define ZEND_VERIFY_INFERENCE_DEF() zend_verify_inference_def(execute_data, OPLINE);
54475467
#else
5448-
# define ZEND_VERIFY_RESULT_TYPE_INFERENCE()
5449-
# define ZEND_VERIFY_OPERAND_TYPE_INFERENCE()
5468+
# define ZEND_VERIFY_INFERENCE_USE()
5469+
# define ZEND_VERIFY_INFERENCE_DEF()
54505470
#endif
54515471

54525472
#define ZEND_VM_NEXT_OPCODE_EX(check_exception, skip) \
5453-
ZEND_VERIFY_RESULT_TYPE_INFERENCE() \
5473+
ZEND_VERIFY_INFERENCE_DEF() \
54545474
CHECK_SYMBOL_TABLES() \
54555475
if (check_exception) { \
54565476
OPLINE = EX(opline) + (skip); \
54575477
} else { \
54585478
ZEND_ASSERT(!EG(exception)); \
54595479
OPLINE = opline + (skip); \
54605480
} \
5461-
ZEND_VERIFY_OPERAND_TYPE_INFERENCE() \
5481+
ZEND_VERIFY_INFERENCE_USE() \
54625482
ZEND_VM_CONTINUE()
54635483

54645484
#define ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION() \

Zend/zend_vm_def.h

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3422,11 +3422,11 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMPVAR|UNUSED|C
34223422
USE_OPLINE
34233423

34243424
SAVE_OPLINE();
3425-
if (OP2_TYPE == IS_UNUSED) {
3426-
Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
34273425
#ifdef ZEND_VERIFY_TYPE_INFERENCE
34283426
Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = IS_PTR;
34293427
#endif
3428+
if (OP2_TYPE == IS_UNUSED) {
3429+
Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
34303430
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
34313431
} else if (OP2_TYPE == IS_CONST) {
34323432
zend_class_entry *ce = CACHED_PTR(opline->extended_value);
@@ -3437,22 +3437,13 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMPVAR|UNUSED|C
34373437
CACHE_PTR(opline->extended_value, ce);
34383438
}
34393439
Z_CE_P(EX_VAR(opline->result.var)) = ce;
3440-
#ifdef ZEND_VERIFY_TYPE_INFERENCE
3441-
Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = IS_PTR;
3442-
#endif
34433440
} else {
34443441
class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
34453442
ZEND_VM_C_LABEL(try_class_name):
34463443
if (Z_TYPE_P(class_name) == IS_OBJECT) {
34473444
Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
3448-
#ifdef ZEND_VERIFY_TYPE_INFERENCE
3449-
Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = IS_PTR;
3450-
#endif
34513445
} else if (Z_TYPE_P(class_name) == IS_STRING) {
34523446
Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num);
3453-
#ifdef ZEND_VERIFY_TYPE_INFERENCE
3454-
Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = IS_PTR;
3455-
#endif
34563447
} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
34573448
class_name = Z_REFVAL_P(class_name);
34583449
ZEND_VM_C_GOTO(try_class_name);
@@ -5907,10 +5898,6 @@ ZEND_VM_HOT_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST, CACHE_SL
59075898
if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
59085899
ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
59095900
ZEND_VM_NEXT_OPCODE();
5910-
} else {
5911-
#ifdef ZEND_VERIFY_TYPE_INFERENCE
5912-
ZVAL_UNDEF(EX_VAR(opline->result.var));
5913-
#endif
59145901
}
59155902

59165903
SAVE_OPLINE();

Zend/zend_vm_execute.h

Lines changed: 8 additions & 48 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)