aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-05-18 14:28:46 +0900
committernsfisis <nsfisis@gmail.com>2024-05-18 14:28:46 +0900
commit829f6e531525fa82c5fa948e6bb96bb6469685a2 (patch)
tree2e1456e441910eb363c74dc0c81555070f883fbb
parentb5455751929d7f9a3581e27eb0adcf7ef9d01a0c (diff)
downloadphp-waddiwasi-829f6e531525fa82c5fa948e6bb96bb6469685a2.tar.gz
php-waddiwasi-829f6e531525fa82c5fa948e6bb96bb6469685a2.tar.zst
php-waddiwasi-829f6e531525fa82c5fa948e6bb96bb6469685a2.zip
fix: memory address should be treated as unsigned integer
-rw-r--r--src/Execution/Runtime.php42
-rw-r--r--tests/src/SpecTestsuites/SpecTestsuiteBase.php72
2 files changed, 40 insertions, 74 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php
index 90d05e6..bf010c9 100644
--- a/src/Execution/Runtime.php
+++ b/src/Execution/Runtime.php
@@ -1955,7 +1955,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI32_s32($ea);
if ($c === null) {
@@ -1970,7 +1970,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI32_s16($ea);
if ($c === null) {
@@ -1985,7 +1985,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI32_u16($ea);
if ($c === null) {
@@ -2000,7 +2000,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI32_s8($ea);
if ($c === null) {
@@ -2015,7 +2015,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI32_u8($ea);
if ($c === null) {
@@ -2031,7 +2031,7 @@ final class Runtime
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
$c = $this->stack->popInt();
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$ok = $mem->storeI32_s32($ea, $c);
if (!$ok) {
@@ -2046,7 +2046,7 @@ final class Runtime
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
$c = $this->stack->popInt();
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$ok = $mem->storeI32_s16($ea, $c);
if (!$ok) {
@@ -2061,7 +2061,7 @@ final class Runtime
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
$c = $this->stack->popInt();
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$ok = $mem->storeI32_s8($ea, $c);
if (!$ok) {
@@ -2075,7 +2075,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI64_s64($ea);
if ($c === null) {
@@ -2090,7 +2090,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI64_s16($ea);
if ($c === null) {
@@ -2105,7 +2105,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI64_u16($ea);
if ($c === null) {
@@ -2120,7 +2120,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI64_s32($ea);
if ($c === null) {
@@ -2135,7 +2135,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI64_u32($ea);
if ($c === null) {
@@ -2150,7 +2150,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI64_s8($ea);
if ($c === null) {
@@ -2165,7 +2165,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadI64_u8($ea);
if ($c === null) {
@@ -2181,7 +2181,7 @@ final class Runtime
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
$c = $this->stack->popInt();
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$ok = $mem->storeI64_s64($ea, $c);
if (!$ok) {
@@ -2196,7 +2196,7 @@ final class Runtime
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
$c = $this->stack->popInt();
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$ok = $mem->storeI64_s16($ea, $c);
if (!$ok) {
@@ -2211,7 +2211,7 @@ final class Runtime
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
$c = $this->stack->popInt();
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$ok = $mem->storeI64_s32($ea, $c);
if (!$ok) {
@@ -2226,7 +2226,7 @@ final class Runtime
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
$c = $this->stack->popInt();
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$ok = $mem->storeI64_s8($ea, $c);
if (!$ok) {
@@ -2457,7 +2457,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadF32($ea);
if ($c === null) {
@@ -2471,7 +2471,7 @@ final class Runtime
$f = $this->stack->currentFrame();
$a = $f->module->memAddrs[0];
$mem = $this->store->mems[$a];
- $i = $this->stack->popInt();
+ $i = self::wasmI32ToPhpInt($this->stack->popInt());
$ea = $i + $offset;
$c = $mem->loadF64($ea);
if ($c === null) {
diff --git a/tests/src/SpecTestsuites/SpecTestsuiteBase.php b/tests/src/SpecTestsuites/SpecTestsuiteBase.php
index 9939196..0fc7e2e 100644
--- a/tests/src/SpecTestsuites/SpecTestsuiteBase.php
+++ b/tests/src/SpecTestsuites/SpecTestsuiteBase.php
@@ -147,17 +147,17 @@ abstract class SpecTestsuiteBase extends TestCase
/**
* @param array{type: string, value: string} $arg
*/
- private function toWasmArg(array $arg): int|float|Ref
+ private static function wastValueToInternalValue(array $arg): int|float|RefExtern
{
$type = $arg['type'];
$value = $arg['value'];
return match ($type) {
- 'i32' => (int)$value,
- 'i64' => (int)$value,
+ 'i32' => unpack('l', pack('l', (int)$value))[1],
+ 'i64' => unpack('q', self::convertInt64ToBinary($value))[1],
'f32' => unpack('g', pack('l', (int)$value))[1],
- 'f64' => unpack('e', pack('q', (int)$value))[1],
+ 'f64' => unpack('e', self::convertInt64ToBinary($value))[1],
'externref' => Ref::RefExtern((int)$value),
- default => $this->assertTrue(false, "unknown arg type: $type"),
+ default => throw new \RuntimeException("unknown type: $type"),
};
}
@@ -174,7 +174,7 @@ abstract class SpecTestsuiteBase extends TestCase
$runtime = self::$runtimes[$targetModuleName];
return $runtime->invoke(
$actionField,
- array_map($this->toWasmArg(...), $actionArgs),
+ array_map(self::wastValueToInternalValue(...), $actionArgs),
);
} else {
$this->assertTrue(false, "unknown action: $actionType");
@@ -201,65 +201,31 @@ abstract class SpecTestsuiteBase extends TestCase
for ($i = 0; $i < count($expectedResults); $i++) {
$expectedResult = $expectedResults[$i];
+ $expectedValue = self::wastValueToInternalValue($expectedResult);
$actualResult = $actualResults[$i];
- if ($expectedResult['type'] === 'i32') {
- $expectedValue = unpack('l', pack('l', (int)$expectedResult['value']))[1];
- $this->assertSame(
- $expectedValue,
- $actualResult,
- "result $i mismatch" . $message,
+ if (is_float($expectedValue) && is_nan($expectedValue)) {
+ // @todo check NaN bit pattern.
+ $this->assertTrue(
+ is_nan($actualResult),
+ "result $i is not NaN" . $message,
);
- } elseif ($expectedResult['type'] === 'i64') {
- $expectedValue = unpack('q', self::convertInt64ToBinary($expectedResult['value']))[1];
- $this->assertSame(
- $expectedValue,
- $actualResult,
- "result $i mismatch" . $message,
- );
- } elseif ($expectedResult['type'] === 'f32') {
- $expectedValue = unpack('g', pack('l', (int)$expectedResult['value']))[1];
- if (is_nan($expectedValue)) {
- // @todo check NaN bit pattern.
- $this->assertTrue(
- is_nan($actualResult),
- "result $i is not NaN" . $message,
- );
- } else {
- $this->assertSame(
- $expectedValue,
- $actualResult,
- "result $i mismatch" . $message,
- );
- }
- } elseif ($expectedResult['type'] === 'f64') {
- $expectedValue = unpack('e', self::convertInt64ToBinary($expectedResult['value']))[1];
- if (is_nan($expectedValue)) {
- // @todo check NaN bit pattern.
- $this->assertTrue(
- is_nan($actualResult),
- "result $i is not NaN" . $message,
- );
- } else {
- $this->assertSame(
- $expectedValue,
- $actualResult,
- "result $i mismatch" . $message,
- );
- }
- } elseif ($expectedResult['type'] === 'externref') {
- $expectedValue = (int)$expectedResult['value'];
+ } else if ($expectedValue instanceof RefExtern) {
$this->assertInstanceOf(
RefExtern::class,
$actualResult,
"result $i is not an externref" . $message,
);
$this->assertSame(
- $expectedValue,
+ $expectedValue->addr,
$actualResult->addr,
"result $i mismatch" . $message,
);
} else {
- $this->assertTrue(false, "unknown result type: {$expectedResult['type']}");
+ $this->assertSame(
+ $expectedValue,
+ $actualResult,
+ "result $i mismatch" . $message,
+ );
}
}
}