-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
132 lines (103 loc) · 2.5 KB
/
main.go
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Modified from https://github.com/go-interpreter/wagon/blob/master/cmd/wasm-run/main.go
// Copyright 2017 The go-interpreter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"github.com/go-interpreter/wagon/exec"
"github.com/go-interpreter/wagon/validate"
"github.com/go-interpreter/wagon/wasm"
)
func main() {
log.SetPrefix("wasm-run: ")
log.SetFlags(0)
verbose := flag.Bool("v", false, "enable/disable verbose mode")
verify := flag.Bool("verify-module", false, "run module verification")
entryName := flag.String("entry", "app_main", "entry function name")
flag.Parse()
if flag.NArg() < 1 {
flag.Usage()
flag.PrintDefaults()
os.Exit(1)
}
wasm.SetDebugMode(*verbose)
run(os.Stdout, flag.Arg(0), *verify, *entryName)
}
func run(w io.Writer, fname string, verify bool, entryName string) {
f, err := os.Open(fname)
if err != nil {
log.Fatal(err)
}
defer func() {
_ = f.Close()
}()
m, err := wasm.ReadModule(f, importer)
if err != nil {
log.Fatalf("could not read module: %v", err)
}
if verify {
err = validate.VerifyModule(m)
if err != nil {
log.Fatalf("could not verify module: %v", err)
}
}
if m.Export == nil {
log.Fatalf("module has no export section")
}
vm, err := exec.NewVM(m)
if err != nil {
log.Fatalf("could not create VM: %v", err)
}
e, ok := m.Export.Entries[entryName]
if !ok {
log.Fatalf("export not found")
}
i := int64(e.Index)
fidx := m.Function.Types[int(i)]
ftype := m.Types.Entries[int(fidx)]
switch len(ftype.ReturnTypes) {
case 1:
fmt.Fprintf(w, "%s() %s => ", entryName, ftype.ReturnTypes[0])
case 0:
fmt.Fprintf(w, "%s() => ", entryName)
default:
log.Printf("running exported functions with more than one return value is not supported")
return
}
if len(ftype.ParamTypes) > 0 {
log.Printf("running exported functions with input parameters is not supported")
return
}
o, err := vm.ExecCode(i)
if err != nil {
fmt.Fprintf(w, "\n")
log.Printf("err=%v", err)
return
}
if len(ftype.ReturnTypes) == 0 {
fmt.Fprintf(w, "\n")
return
}
fmt.Fprintf(w, "%[1]v (%[1]T)\n", o)
}
func importer(name string) (*wasm.Module, error) {
f, err := os.Open(name + ".wasm")
if err != nil {
return nil, err
}
defer f.Close()
m, err := wasm.ReadModule(f, nil)
if err != nil {
return nil, err
}
err = validate.VerifyModule(m)
if err != nil {
return nil, err
}
return m, nil
}