Skip to content

Commit 6632874

Browse files
committed
Merge branch 'PHP-8.0'
* PHP-8.0: Fixed bug #81249 (Intermittent property assignment failure with JIT enabled)
2 parents a837d35 + c0e4932 commit 6632874

File tree

3 files changed

+135
-2
lines changed

3 files changed

+135
-2
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ PHP NEWS
99
- Opcache:
1010
. Fixed bug #81225 (Wrong result with pow operator with JIT enabled).
1111
(Dmitry)
12+
. Fixed bug #81249 (Intermittent property assignment failure with JIT
13+
enabled). (Dmitry)
1214

1315
- Reflection:
1416
. Fixed bug #80097 (ReflectionAttribute is not a Reflector). (beberlei)

ext/opcache/jit/zend_jit_trace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3556,12 +3556,12 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o
35563556
|| prev_opcode == ZEND_IS_NOT_IDENTICAL
35573557
|| prev_opcode == ZEND_CASE_STRICT) {
35583558
if (ssa_op->op1_use < 0) {
3559-
if (opline->op1.constant != ssa_opcodes[prev_ssa_op - ssa->ops]->op1.constant) {
3559+
if (RT_CONSTANT(opline, opline->op1) != RT_CONSTANT(&ssa_opcodes[prev_ssa_op - ssa->ops], ssa_opcodes[prev_ssa_op - ssa->ops]->op1)) {
35603560
return 0;
35613561
}
35623562
}
35633563
if (ssa_op->op2_use < 0) {
3564-
if (opline->op2.constant != ssa_opcodes[prev_ssa_op - ssa->ops]->op2.constant) {
3564+
if (RT_CONSTANT(opline, opline->op2) != RT_CONSTANT(&ssa_opcodes[prev_ssa_op - ssa->ops], ssa_opcodes[prev_ssa_op - ssa->ops]->op2)) {
35653565
return 0;
35663566
}
35673567
}

ext/opcache/tests/jit/bug81249.phpt

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
--TEST--
2+
Bug #81249: Intermittent property assignment failure with JIT enabled
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.jit_buffer_size=1M
9+
opcache.jit=tracing
10+
--SKIPIF--
11+
<?php if (PHP_INT_SIZE != 8) die("skip: 64-bit only"); ?>
12+
--FILE--
13+
<?php
14+
15+
declare(strict_types=1);
16+
17+
final class EucJpDecoder
18+
{
19+
private const JIS0212_INDEX = [108 => 728];
20+
private const JIS0208_INDEX = [];
21+
22+
private const CONTINUE = -1;
23+
private const FINISHED = -2;
24+
private const ERROR = -3;
25+
26+
/**
27+
* @var int
28+
*/
29+
private $lead;
30+
31+
/**
32+
* @var bool
33+
*/
34+
private $isJis0212;
35+
36+
public function __construct()
37+
{
38+
$this->lead = 0x00;
39+
$this->isJis0212 = false;
40+
}
41+
42+
public function handle(array &$ioQueue, string $byte): int
43+
{
44+
if ($byte === '') {
45+
if ($this->lead !== 0x00) {
46+
$this->lead = 0x00;
47+
48+
return self::ERROR;
49+
}
50+
51+
return self::FINISHED;
52+
}
53+
54+
$byte = ord($byte);
55+
56+
if ($this->lead === 0x8E && ($byte >= 0xA1 && $byte <= 0xDF)) {
57+
$this->lead = 0x00;
58+
59+
return 0xFF61 - 0xA1 + $byte;
60+
}
61+
62+
if ($this->lead === 0x8F && ($byte >= 0xA1 && $byte <= 0xFE)) {
63+
$this->isJis0212 = true;
64+
$this->lead = $byte;
65+
66+
return self::CONTINUE;
67+
}
68+
69+
if ($this->lead !== 0x00) {
70+
$lead = $this->lead;
71+
$this->lead = 0x00;
72+
$codePoint = null;
73+
74+
if (($lead >= 0xA1 && $lead <= 0xFE) && ($byte >= 0xA1 && $byte <= 0xFE)) {
75+
$index = self::JIS0208_INDEX;
76+
77+
if ($this->isJis0212) {
78+
$index = self::JIS0212_INDEX;
79+
}
80+
81+
$codePoint = $index[($lead - 0xA1) * 94 + $byte - 0xA1] ?? null;
82+
}
83+
84+
$this->isJis0212 = false;
85+
86+
if ($codePoint !== null) {
87+
return $codePoint;
88+
}
89+
90+
if ($byte <= 0x7F) {
91+
array_unshift($ioQueue, chr($byte));
92+
}
93+
94+
return self::ERROR;
95+
}
96+
97+
if ($byte <= 0x7F) {
98+
return $byte;
99+
}
100+
101+
if ($byte === 0x8E || $byte === 0x8F || ($byte >= 0xA1 && $byte <= 0xFE)) {
102+
$this->lead = $byte;
103+
104+
return self::CONTINUE;
105+
}
106+
107+
return self::ERROR;
108+
}
109+
}
110+
111+
for ($i = 0; $i < 2000; ++$i) {
112+
$decoder = new EucJpDecoder();
113+
114+
$bytes = ["\x8F", "\xA2", "\xAF", ''];
115+
$out = null;
116+
117+
foreach ($bytes as $byte) {
118+
$result = $decoder->handle($bytes, $byte);
119+
120+
if ($result >= 0) {
121+
$out = $result;
122+
}
123+
}
124+
125+
// $bytes array should be decoded to U+2D8, decimal 728
126+
assert($out === 728);
127+
}
128+
?>
129+
OK
130+
--EXPECT--
131+
OK

0 commit comments

Comments
 (0)