Skip to content

Commit d8b0337

Browse files
committed
Fix register allocation on x86
Fixes oss-fuzz #43119
1 parent d7db5f6 commit d8b0337

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6039,6 +6039,7 @@ static int zend_jit_simple_assign(dasm_State **Dst,
60396039
val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 0);
60406040
} else {
60416041
zend_jit_addr ref_addr;
6042+
zend_reg type_reg = tmp_reg;
60426043

60436044
if (in_cold) {
60446045
| IF_NOT_ZVAL_TYPE val_addr, IS_REFERENCE, >1
@@ -6047,21 +6048,24 @@ static int zend_jit_simple_assign(dasm_State **Dst,
60476048
|.cold_code
60486049
|1:
60496050
}
6050-
if (Z_REG(val_addr) == ZREG_R2) {
6051-
| mov aword T1, r2 // save
6052-
}
60536051
| // zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
60546052
| GET_ZVAL_PTR r2, val_addr
60556053
| GC_DELREF r2
60566054
| // ZVAL_COPY_VALUE(return_value, &ref->value);
60576055
ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 8);
60586056
if (!res_addr) {
6059-
| ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, tmp_reg
6057+
| ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, type_reg, tmp_reg
60606058
} else {
6061-
| ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, tmp_reg
6059+
| ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, type_reg, tmp_reg
60626060
}
60636061
| je >2
6064-
| IF_NOT_REFCOUNTED dh, >3
6062+
if (tmp_reg == ZREG_R0) {
6063+
| IF_NOT_REFCOUNTED ah, >3
6064+
} else {
6065+
| IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >3
6066+
}
6067+
| GET_ZVAL_PTR Ra(tmp_reg), var_addr
6068+
60656069
if (!res_addr) {
60666070
| GC_ADDREF Ra(tmp_reg)
60676071
} else {
@@ -6070,17 +6074,19 @@ static int zend_jit_simple_assign(dasm_State **Dst,
60706074
| jmp >3
60716075
|2:
60726076
if (res_addr) {
6073-
| IF_NOT_REFCOUNTED dh, >2
6077+
if (tmp_reg == ZREG_R0) {
6078+
| IF_NOT_REFCOUNTED ah, >2
6079+
} else {
6080+
| IF_NOT_FLAGS Rd(tmp_reg), IS_TYPE_REFCOUNTED, >2
6081+
}
6082+
| GET_ZVAL_PTR Ra(tmp_reg), var_addr
60746083
| GC_ADDREF Ra(tmp_reg)
60756084
|2:
60766085
}
6077-
if (Z_REG(val_addr) == ZREG_R2) {
6078-
| mov r2, aword T1 // restore
6079-
}
60806086
if (save_r1) {
60816087
| mov aword T1, FCARG1a // save
60826088
}
6083-
| EFREE_REFERENCE aword [Ra(Z_REG(val_addr))+Z_OFFSET(val_addr)]
6089+
| EFREE_REFERENCE r2
60846090
if (save_r1) {
60856091
| mov FCARG1a, aword T1 // restore
60866092
}

ext/opcache/tests/jit/assign_049.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
JIT ASSIGN: register allocation on x86
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
--FILE--
10+
<?php
11+
function &a($i) {
12+
$a = "str". $i;
13+
return $a;
14+
}
15+
16+
class A {
17+
public $a;
18+
public function test() {
19+
$this->a = a(1);
20+
}
21+
}
22+
23+
$a = new A;
24+
$a->test();
25+
$a->test();
26+
?>
27+
DONE
28+
--EXPECT--
29+
DONE

0 commit comments

Comments
 (0)