-
Notifications
You must be signed in to change notification settings - Fork 39
/
module.go
executable file
·159 lines (133 loc) · 3.8 KB
/
module.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright 2017~2022 The Bottos Authors
// This file is part of the Bottos Chain library.
// Created by Rocket Core Team of Bottos.
// This program is free software: you can distribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Bottos. If not, see <http://www.gnu.org/licenses/>.
// 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 wasm
import (
"errors"
"io"
"github.com/bottos-project/bottos/vm/wasm/wasm/internal/readpos"
log "github.com/cihub/seelog"
)
// ErrInvalidMagic invalid magic
var ErrInvalidMagic = errors.New("wasm: Invalid magic number")
const (
// Magic magic number
Magic uint32 = 0x6d736100
// Version version number
Version uint32 = 0x1
)
// Function represents an entry in the function index space of a module.
type Function struct {
Sig *FunctionSig
Body *FunctionBody
EnvFunc bool
Method string
}
// Module represents a parsed WebAssembly module:
// http://webassembly.org/docs/modules/
type Module struct {
Version uint32
Types *SectionTypes
Import *SectionImports
Function *SectionFunctions
Table *SectionTables
Memory *SectionMemories
Global *SectionGlobals
Export *SectionExports
Start *SectionStartFunction
Elements *SectionElements
Code *SectionCode
Data *SectionData
// The function index space of the module
FunctionIndexSpace []Function
GlobalIndexSpace []GlobalEntry
// function indices into the global function space
// the limit of each table is its capacity (cap)
TableIndexSpace [][]uint32
LinearMemoryIndexSpace [][]byte
Other []Section // Other holds the custom sections if any
imports struct {
Funcs []uint32
Globals int
Tables int
Memories int
}
}
// EnvGlobal global environment
type EnvGlobal struct {
Env bool
Val uint64
}
// NewEnvGlobal new global environment
func NewEnvGlobal(env bool, val uint64) *EnvGlobal {
e := &EnvGlobal{
Env: env,
Val: val,
}
return e
}
// ResolveFunc is a function that takes a module name and
// returns a valid resolved module.
type ResolveFunc func(name string) (*Module, error)
// ReadModule reads a module from the reader r. resolvePath must take a string
// and a return a reader to the module pointed to by the string.
func ReadModule(r io.Reader, resolvePath ResolveFunc) (*Module, error) {
reader := &readpos.ReadPos{
R: r,
CurPos: 0,
}
m := &Module{}
magic, err := readU32(reader)
if err != nil {
return nil, err
}
if magic != Magic {
return nil, ErrInvalidMagic
}
if m.Version, err = readU32(reader); err != nil {
return nil, err
}
for {
done, err := m.readSection(reader)
if err != nil {
return nil, err
} else if done {
break
}
}
m.LinearMemoryIndexSpace = make([][]byte, 1)
if m.Table != nil {
m.TableIndexSpace = make([][]uint32, int(len(m.Table.Entries)))
}
if m.Import != nil && resolvePath != nil {
err := m.resolveImports(resolvePath) //resolvePath is importer() function
if err != nil {
return nil, err
}
}
for _, fn := range []func() error{
m.populateGlobals,
m.populateFunctions,
m.populateTables,
m.populateLinearMemory,
} {
if err := fn(); err != nil {
return nil, err
}
}
log.Trace("There are %d entries in the function index space.", len(m.FunctionIndexSpace))
return m, nil
}