diff options
Diffstat (limited to 'src/WebAssembly/Execution')
| -rw-r--r-- | src/WebAssembly/Execution/ExporterInterface.php | 13 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/LinkErrorException.php | 11 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/Linker.php | 49 | ||||
| -rw-r--r-- | src/WebAssembly/Execution/Runtime.php | 28 |
4 files changed, 80 insertions, 21 deletions
diff --git a/src/WebAssembly/Execution/ExporterInterface.php b/src/WebAssembly/Execution/ExporterInterface.php new file mode 100644 index 0000000..9c2d965 --- /dev/null +++ b/src/WebAssembly/Execution/ExporterInterface.php @@ -0,0 +1,13 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\Waddiwasi\WebAssembly\Execution; + +interface ExporterInterface +{ + /** + * @return list<ExportInst> + */ + public function exports(): array; +} diff --git a/src/WebAssembly/Execution/LinkErrorException.php b/src/WebAssembly/Execution/LinkErrorException.php new file mode 100644 index 0000000..35db57f --- /dev/null +++ b/src/WebAssembly/Execution/LinkErrorException.php @@ -0,0 +1,11 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\Waddiwasi\WebAssembly\Execution; + +use RuntimeException; + +final class LinkErrorException extends RuntimeException +{ +} diff --git a/src/WebAssembly/Execution/Linker.php b/src/WebAssembly/Execution/Linker.php new file mode 100644 index 0000000..3c9c1d0 --- /dev/null +++ b/src/WebAssembly/Execution/Linker.php @@ -0,0 +1,49 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\Waddiwasi\WebAssembly\Execution; + +use Nsfisis\Waddiwasi\WebAssembly\Structure\Modules\Module; + +final class Linker +{ + /** + * @var array<string, array<string, ExternVal>> + */ + private array $symbols = []; + + public function __construct( + private Store $store, + ) { + } + + public function register(string $namespace, string $name, Extern $extern): void + { + $externVal = $this->store->register($extern); + $this->symbols[$namespace][$name] = $externVal; + } + + public function registerNamespace(string $namespace, ExporterInterface $exporter): void + { + foreach ($exporter->exports() as $export) { + $this->symbols[$namespace][$export->name] = $export->value; + } + } + + /** + * @return list<ExternVal> + */ + public function resolve(Module $module): array + { + $externVals = []; + foreach ($module->imports as $import) { + $externVal = $this->symbols[$import->module][$import->name] ?? null; + if ($externVal === null) { + throw new LinkErrorException("import not found: {$import->module}::{$import->name}"); + } + $externVals[] = $externVal; + } + return $externVals; + } +} diff --git a/src/WebAssembly/Execution/Runtime.php b/src/WebAssembly/Execution/Runtime.php index 07dc0d0..c4a78c8 100644 --- a/src/WebAssembly/Execution/Runtime.php +++ b/src/WebAssembly/Execution/Runtime.php @@ -39,7 +39,7 @@ use function sqrt; use function unpack; use const PHP_INT_MIN; -final class Runtime +final class Runtime implements ExporterInterface { /** * @var array<string, array{int, int}> @@ -54,28 +54,9 @@ final class Runtime } /** - * @param array<string, array<string, Extern>> $imports - */ - public static function instantiate( - Store $store, - Module $module, - array $imports, - ): self { - $externVals = []; - foreach ($module->imports as $import) { - $extern = $imports[$import->module][$import->name] ?? null; - if ($extern === null) { - throw new RuntimeException("instantiate: import not found: {$import->module}::{$import->name}"); - } - $externVals[] = $store->register($extern); - } - return self::doInstantiate($store, $module, $externVals); - } - - /** * @param list<ExternVal> $externVals */ - private static function doInstantiate( + public static function instantiate( Store $store, Module $module, array $externVals, @@ -159,6 +140,11 @@ final class Runtime return new self($store, $stack, $moduleInst); } + public function exports(): array + { + return $this->module->exports; + } + public function getExport(string $name): ?ExternVal { foreach ($this->module->exports as $export) { |
