Skip to content

Commit accc1e6

Browse files
committed
Invalidate "memory" type of zval if a register was stored in memory to call a helper function
1 parent 8fc3615 commit accc1e6

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4100,6 +4100,35 @@ static int zend_jit_spill_store(zend_jit_ctx *jit, zend_jit_addr src, zend_jit_a
41004100
return 1;
41014101
}
41024102

4103+
static int zend_jit_spill_store_inv(zend_jit_ctx *jit, zend_jit_addr src, zend_jit_addr dst, uint32_t info)
4104+
{
4105+
ZEND_ASSERT(Z_MODE(src) == IS_REG);
4106+
ZEND_ASSERT(Z_MODE(dst) == IS_MEM_ZVAL);
4107+
4108+
if ((info & MAY_BE_ANY) == MAY_BE_LONG) {
4109+
jit_set_Z_LVAL(jit, dst, zend_jit_use_reg(jit, src));
4110+
if (Z_REG(dst) != ZREG_FP || !JIT_G(current_frame)) {
4111+
jit_set_Z_TYPE_INFO(jit, dst, IS_LONG);
4112+
} else if (STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(Z_OFFSET(dst))) != IS_LONG) {
4113+
/* invalidate memory type */
4114+
STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(Z_OFFSET(dst))) = IS_UNKNOWN;
4115+
jit_set_Z_TYPE_INFO(jit, dst, IS_LONG);
4116+
}
4117+
} else if ((info & MAY_BE_ANY) == MAY_BE_DOUBLE) {
4118+
jit_set_Z_DVAL(jit, dst, zend_jit_use_reg(jit, src));
4119+
if (Z_REG(dst) != ZREG_FP || !JIT_G(current_frame)) {
4120+
jit_set_Z_TYPE_INFO(jit, dst, IS_DOUBLE);
4121+
} else if (STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(Z_OFFSET(dst))) != IS_DOUBLE) {
4122+
/* invalidate memory type */
4123+
STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(Z_OFFSET(dst))) = IS_UNKNOWN;
4124+
jit_set_Z_TYPE_INFO(jit, dst, IS_DOUBLE);
4125+
}
4126+
} else {
4127+
ZEND_UNREACHABLE();
4128+
}
4129+
return 1;
4130+
}
4131+
41034132
static int zend_jit_load_reg(zend_jit_ctx *jit, zend_jit_addr src, zend_jit_addr dst, uint32_t info)
41044133
{
41054134
ZEND_ASSERT(Z_MODE(src) == IS_MEM_ZVAL);
@@ -5233,14 +5262,14 @@ static int zend_jit_math_helper(zend_jit_ctx *jit,
52335262

52345263
if (Z_MODE(op1_addr) == IS_REG) {
52355264
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, op1.var);
5236-
if (!zend_jit_spill_store(jit, op1_addr, real_addr, op1_info, 1)) {
5265+
if (!zend_jit_spill_store_inv(jit, op1_addr, real_addr, op1_info)) {
52375266
return 0;
52385267
}
52395268
op1_addr = real_addr;
52405269
}
52415270
if (Z_MODE(op2_addr) == IS_REG) {
52425271
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, op2.var);
5243-
if (!zend_jit_spill_store(jit, op2_addr, real_addr, op2_info, 1)) {
5272+
if (!zend_jit_spill_store_inv(jit, op2_addr, real_addr, op2_info)) {
52445273
return 0;
52455274
}
52465275
op2_addr = real_addr;
@@ -5596,14 +5625,14 @@ static int zend_jit_long_math_helper(zend_jit_ctx *jit,
55965625

55975626
if (Z_MODE(op1_addr) == IS_REG) {
55985627
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, op1.var);
5599-
if (!zend_jit_spill_store(jit, op1_addr, real_addr, op1_info, 1)) {
5628+
if (!zend_jit_spill_store_inv(jit, op1_addr, real_addr, op1_info)) {
56005629
return 0;
56015630
}
56025631
op1_addr = real_addr;
56035632
}
56045633
if (Z_MODE(op2_addr) == IS_REG) {
56055634
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, op2.var);
5606-
if (!zend_jit_spill_store(jit, op2_addr, real_addr, op2_info, 1)) {
5635+
if (!zend_jit_spill_store_inv(jit, op2_addr, real_addr, op2_info)) {
56075636
return 0;
56085637
}
56095638
op2_addr = real_addr;
@@ -6174,7 +6203,7 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit,
61746203
if (Z_MODE(val_addr) == IS_REG) {
61756204
ZEND_ASSERT(opline->opcode == ZEND_ASSIGN);
61766205
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var);
6177-
if (!zend_jit_spill_store(jit, val_addr, real_addr, val_info, 1)) {
6206+
if (!zend_jit_spill_store_inv(jit, val_addr, real_addr, val_info)) {
61786207
return 0;
61796208
}
61806209
arg2 = jit_ZVAL_ADDR(jit, real_addr);
@@ -6836,14 +6865,14 @@ static int zend_jit_cmp(zend_jit_ctx *jit,
68366865

68376866
if (Z_MODE(op1_addr) == IS_REG) {
68386867
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var);
6839-
if (!zend_jit_spill_store(jit, op1_addr, real_addr, op1_info, 1)) {
6868+
if (!zend_jit_spill_store_inv(jit, op1_addr, real_addr, op1_info)) {
68406869
return 0;
68416870
}
68426871
op1_addr = real_addr;
68436872
}
68446873
if (Z_MODE(op2_addr) == IS_REG) {
68456874
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var);
6846-
if (!zend_jit_spill_store(jit, op2_addr, real_addr, op2_info, 1)) {
6875+
if (!zend_jit_spill_store_inv(jit, op2_addr, real_addr, op2_info)) {
68476876
return 0;
68486877
}
68496878
op2_addr = real_addr;
@@ -7066,7 +7095,7 @@ static int zend_jit_identical(zend_jit_ctx *jit,
70667095
if (opline->op1_type != IS_CONST) {
70677096
if (Z_MODE(op1_addr) == IS_REG) {
70687097
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var);
7069-
if (!zend_jit_spill_store(jit, op1_addr, real_addr, op1_info, 1)) {
7098+
if (!zend_jit_spill_store_inv(jit, op1_addr, real_addr, op1_info)) {
70707099
return 0;
70717100
}
70727101
op1_addr = real_addr;
@@ -7075,7 +7104,7 @@ static int zend_jit_identical(zend_jit_ctx *jit,
70757104
if (opline->op2_type != IS_CONST) {
70767105
if (Z_MODE(op2_addr) == IS_REG) {
70777106
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var);
7078-
if (!zend_jit_spill_store(jit, op2_addr, real_addr, op2_info, 1)) {
7107+
if (!zend_jit_spill_store_inv(jit, op2_addr, real_addr, op2_info)) {
70797108
return 0;
70807109
}
70817110
}
@@ -7092,14 +7121,14 @@ static int zend_jit_identical(zend_jit_ctx *jit,
70927121
} else {
70937122
if (Z_MODE(op1_addr) == IS_REG) {
70947123
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var);
7095-
if (!zend_jit_spill_store(jit, op1_addr, real_addr, op1_info, 1)) {
7124+
if (!zend_jit_spill_store_inv(jit, op1_addr, real_addr, op1_info)) {
70967125
return 0;
70977126
}
70987127
op1_addr = real_addr;
70997128
}
71007129
if (Z_MODE(op2_addr) == IS_REG) {
71017130
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var);
7102-
if (!zend_jit_spill_store(jit, op2_addr, real_addr, op2_info, 1)) {
7131+
if (!zend_jit_spill_store_inv(jit, op2_addr, real_addr, op2_info)) {
71037132
return 0;
71047133
}
71057134
op2_addr = real_addr;
@@ -10689,7 +10718,7 @@ static int zend_jit_return(zend_jit_ctx *jit, const zend_op *opline, const zend_
1068910718
if (Z_MODE(op1_addr) == IS_REG) {
1069010719
zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var);
1069110720

10692-
if (!zend_jit_spill_store(jit, op1_addr, dst, op1_info, 1)) {
10721+
if (!zend_jit_spill_store_inv(jit, op1_addr, dst, op1_info)) {
1069310722
return 0;
1069410723
}
1069510724
op1_addr = dst;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Register Alloction 019: Incorrect type assumption after spilling
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--FILE--
9+
<?php
10+
function test() {
11+
for($i = 0; $i < 10; $i++) {
12+
$x != $y;
13+
$x =- +$y;
14+
$x != $y;
15+
$x = $y;
16+
}
17+
}
18+
@test();
19+
?>
20+
DONE
21+
--EXPECTF--
22+
DONE

0 commit comments

Comments
 (0)