aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-05-01 23:17:58 +0900
committernsfisis <nsfisis@gmail.com>2024-05-01 23:17:58 +0900
commitabdad356462b4b84cba771af742d1b6ecfaabc2d (patch)
tree40a763ad15af318cfcbc00515a32d3c0970f0df2
parentbd72d3c4acde3f5e79bd494d4678a6e72e92e313 (diff)
downloadphp-waddiwasi-abdad356462b4b84cba771af742d1b6ecfaabc2d.tar.gz
php-waddiwasi-abdad356462b4b84cba771af742d1b6ecfaabc2d.tar.zst
php-waddiwasi-abdad356462b4b84cba771af742d1b6ecfaabc2d.zip
test: define more trap kind
-rw-r--r--src/Execution/Runtime.php12
-rw-r--r--src/Execution/Stack.php19
-rw-r--r--src/Execution/TrapKind.php1
-rw-r--r--tests/src/SpecTestsuites/SpecTestsuiteBase.php3
4 files changed, 25 insertions, 10 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php
index 9d7c367..08600e5 100644
--- a/src/Execution/Runtime.php
+++ b/src/Execution/Runtime.php
@@ -1756,7 +1756,7 @@ final class Runtime
$s = $this->stack->popInt();
$d = $this->stack->popInt();
if (count($tabX->elem) < $d + $n || count($tabY->elem) < $s + $n) {
- throw new TrapException("table.copy: out of bounds");
+ throw new TrapException("table.copy: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess);
}
if ($n === 0 || ($x === $y && $d === $s)) {
return;
@@ -1779,7 +1779,7 @@ final class Runtime
$val = $this->stack->popRef();
$i = $this->stack->popInt();
if (count($tab->elem) < $i + $n) {
- throw new TrapException("table.fill: out of bounds");
+ throw new TrapException("table.fill: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess);
}
for ($k = 0; $k < $n; $k++) {
// @phpstan-ignore-next-line
@@ -1795,7 +1795,7 @@ final class Runtime
$tab = $this->store->tables[$a];
$i = $this->stack->popInt();
if (count($tab->elem) <= $i) {
- throw new TrapException("table.get: out of bounds");
+ throw new TrapException("table.get: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess);
}
$val = $tab->elem[$i];
$this->stack->pushValue($val);
@@ -1845,10 +1845,10 @@ final class Runtime
$s = $this->stack->popInt();
$d = $this->stack->popInt();
if (count($elem->elem) < $s + $n) {
- throw new TrapException("table.init: out of bounds");
+ throw new TrapException("table.init: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess);
}
if (count($tab->elem) < $d + $n) {
- throw new TrapException("table.init: out of bounds");
+ throw new TrapException("table.init: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess);
}
for ($i = 0; $i < $n; $i++) {
// @phpstan-ignore-next-line
@@ -1865,7 +1865,7 @@ final class Runtime
$val = $this->stack->popRef();
$i = $this->stack->popInt();
if (count($tab->elem) <= $i) {
- throw new TrapException("table.set: out of bounds");
+ throw new TrapException("table.set: out of bounds", trapKind: TrapKind::OutOfBoundsTableAccess);
}
// @phpstan-ignore-next-line
$tab->elem[$i] = $val;
diff --git a/src/Execution/Stack.php b/src/Execution/Stack.php
index be4e7ec..424f8c6 100644
--- a/src/Execution/Stack.php
+++ b/src/Execution/Stack.php
@@ -9,6 +9,7 @@ use function assert;
use function count;
use function is_float;
use function is_int;
+use function is_null;
final class Stack
{
@@ -102,7 +103,7 @@ final class Stack
public function popInt(): int
{
$v = $this->popValue();
- assert(is_int($v));
+ assert(is_int($v), "Expected an int on top of the stack, but got " . self::getValueTypeName($v));
return $v;
}
@@ -112,14 +113,14 @@ final class Stack
public function popFloat(): float
{
$v = $this->popValue();
- assert(is_float($v));
+ assert(is_float($v), "Expected a float on top of the stack, but got " . self::getValueTypeName($v));
return $v;
}
public function popRef(): Ref
{
$v = $this->popValue();
- assert($v instanceof Ref);
+ assert($v instanceof Ref, "Expected a Ref on top of the stack, but got " . self::getValueTypeName($v));
return $v;
}
@@ -187,4 +188,16 @@ final class Stack
{
return array_pop($this->entries);
}
+
+ private static function getValueTypeName(int|float|Ref|Frame|Label|null $value): string
+ {
+ return match (true) {
+ is_null($value) => 'null',
+ is_int($value) => 'int',
+ is_float($value) => 'float',
+ $value instanceof Ref => 'Ref',
+ $value instanceof Frame => 'Frame',
+ $value instanceof Label => 'Label',
+ };
+ }
}
diff --git a/src/Execution/TrapKind.php b/src/Execution/TrapKind.php
index 47c1c77..b1c00ef 100644
--- a/src/Execution/TrapKind.php
+++ b/src/Execution/TrapKind.php
@@ -8,4 +8,5 @@ enum TrapKind
{
case Unknown;
case OutOfBoundsMemoryAccess;
+ case OutOfBoundsTableAccess;
}
diff --git a/tests/src/SpecTestsuites/SpecTestsuiteBase.php b/tests/src/SpecTestsuites/SpecTestsuiteBase.php
index f5cc39a..f2b0206 100644
--- a/tests/src/SpecTestsuites/SpecTestsuiteBase.php
+++ b/tests/src/SpecTestsuites/SpecTestsuiteBase.php
@@ -249,8 +249,9 @@ abstract class SpecTestsuiteBase extends TestCase
$message = " ($message)";
}
$actualErrorMessage = match ($kind) {
- TrapKind::OutOfBoundsMemoryAccess => 'out of bounds memory access',
TrapKind::Unknown => 'unknown',
+ TrapKind::OutOfBoundsMemoryAccess => 'out of bounds memory access',
+ TrapKind::OutOfBoundsTableAccess => 'out of bounds table access',
};
$this->assertSame(
$expectedErrorMessage,