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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
<?php
declare(strict_types=1);
namespace Nsfisis\Waddiwasi\Debug;
use Nsfisis\Waddiwasi\Structure\Modules\ImportDescs;
use Nsfisis\Waddiwasi\Structure\Modules\Module;
use Nsfisis\Waddiwasi\Structure\Types\FuncType;
use Nsfisis\Waddiwasi\Structure\Types\GlobalType;
use Nsfisis\Waddiwasi\Structure\Types\Limits;
use Nsfisis\Waddiwasi\Structure\Types\MemType;
use Nsfisis\Waddiwasi\Structure\Types\Mut;
use Nsfisis\Waddiwasi\Structure\Types\NumType;
use Nsfisis\Waddiwasi\Structure\Types\RefType;
use Nsfisis\Waddiwasi\Structure\Types\ResultType;
use Nsfisis\Waddiwasi\Structure\Types\TableType;
use Nsfisis\Waddiwasi\Structure\Types\ValType;
use Nsfisis\Waddiwasi\Structure\Types\ValTypes;
final readonly class Debug
{
public static function printImports(Module $module): void
{
foreach ($module->imports as $import) {
$mod = $import->module;
$name = $import->name;
$desc = $import->desc;
$type = match ($desc::class) {
ImportDescs\Func::class => 'func',
ImportDescs\Table::class => 'table',
ImportDescs\Mem::class => 'mem',
ImportDescs\Global_::class => 'global',
default => 'unknown',
};
$extraInfo = match ($desc::class) {
ImportDescs\Func::class => self::typeIdxToString($desc->func, $module),
ImportDescs\Table::class => self::tableTypeToString($desc->table),
ImportDescs\Mem::class => self::memTypeToString($desc->mem),
ImportDescs\Global_::class => self::globalTypeToString($desc->global),
default => 'unknown',
};
echo "$mod::$name: $type $extraInfo\n";
}
}
private static function typeIdxToString(int $idx, Module $module): string
{
$type = $module->types[$idx];
return self::funcTypeToString($type);
}
private static function tableTypeToString(TableType $type): string
{
return self::valTypeToString(ValType::RefType($type->refType)) . ' ' . self::limitsToString($type->limits);
}
private static function memTypeToString(MemType $type): string
{
return self::limitsToString($type->limits);
}
private static function globalTypeToString(GlobalType $type): string
{
return self::mutToString($type->mut) . ' ' . self::valTypeToString($type->valType);
}
private static function funcTypeToString(FuncType $type): string
{
$params = self::resultTypeToString($type->params);
$results = self::resultTypeToString($type->results);
return "($params) -> ($results)";
}
private static function valTypeToString(ValType $type): string
{
return match ($type::class) {
ValTypes\NumType::class => match ($type->inner) {
NumType::I32 => 'i32',
NumType::I64 => 'i64',
NumType::F32 => 'f32',
NumType::F64 => 'f64',
},
ValTypes\VecType::class => 'v128',
ValTypes\RefType::class => match ($type->inner) {
RefType::FuncRef => 'funcref',
RefType::ExternRef => 'externref',
},
default => 'unknown',
};
}
private static function limitsToString(Limits $limit): string
{
$min = $limit->min;
$max = $limit->max;
return $max === null ? "[$min, inf)" : "[$min, $max]";
}
private static function mutToString(Mut $mut): string
{
return match ($mut) {
Mut::Const => 'const',
Mut::Var => 'var',
};
}
private static function resultTypeToString(ResultType $type): string
{
return implode(', ', array_map(self::valTypeToString(...), $type->types));
}
}
|