aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/WebAssembly/Execution/Linker.php
blob: 3c9c1d0e0aa232f34e95a6484037ec5a3f28fcbf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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;
    }
}