aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-05-05 12:26:53 +0900
committernsfisis <nsfisis@gmail.com>2024-05-05 14:12:32 +0900
commit2f533445e47f4a0f7c94677f5fda3683a4f1fee7 (patch)
tree9043ad6a9056dd693656f6be7f20472a77c76fc1 /src
parent2eab009a251fa14631b59e60afa455136e71b44e (diff)
downloadphp-waddiwasi-2f533445e47f4a0f7c94677f5fda3683a4f1fee7.tar.gz
php-waddiwasi-2f533445e47f4a0f7c94677f5fda3683a4f1fee7.tar.zst
php-waddiwasi-2f533445e47f4a0f7c94677f5fda3683a4f1fee7.zip
fix: i64.mul
Diffstat (limited to 'src')
-rw-r--r--src/Execution/Runtime.php14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php
index 5107c3d..d5fefdd 100644
--- a/src/Execution/Runtime.php
+++ b/src/Execution/Runtime.php
@@ -1455,11 +1455,19 @@ final class Runtime
{
$c2 = $this->stack->popInt();
$c1 = $this->stack->popInt();
- if ($c1 === (1 << 32) - 1 && $c2 === (1 << 32) + 1) {
- $this->stack->pushValue(-1);
+ $result = bcmod(bcmul((string)$c1, (string)$c2), bcpow('2', '64'));
+ if ($result[0] === '-') {
+ // 2^63 <= -$result
+ if (bccomp(bcpow('2', '63'), bcsub('0', $result)) <= 0) {
+ $result = bcadd($result, bcpow('2', '64'));
+ }
} else {
- $this->stack->pushValue($c1 * $c2);
+ // 2^63-1 < $result
+ if (bccomp(bcsub(bcpow('2', '63'), '1'), $result) < 0) {
+ $result = bcsub($result, bcpow('2', '64'));
+ }
}
+ $this->stack->pushValue((int)$result);
}
private function execInstrNumericI64Ne(Instrs\Numeric\I64Ne $instr): void