/
skip.go
100 lines (80 loc) · 2.49 KB
/
skip.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
// Copyright (c) 2016 Timo Savola. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package codegen
import (
"github.com/tsavola/wag/internal/gen"
"github.com/tsavola/wag/internal/gen/debug"
"github.com/tsavola/wag/internal/loader"
"github.com/tsavola/wag/wa/opcode"
)
func skipOps(f *gen.Func, load loader.L) {
for {
op := opcode.Opcode(load.Byte())
if f.DebugMap != nil {
f.DebugMap.PutInsnAddr(uint32(f.Text.Addr))
}
if op == opcode.End {
return
}
skipOp(f, load, op)
}
}
func skipThenOps(f *gen.Func, load loader.L) (haveElse bool) {
for {
op := opcode.Opcode(load.Byte())
if f.DebugMap != nil {
f.DebugMap.PutInsnAddr(uint32(f.Text.Addr))
}
switch op {
case opcode.End:
return
case opcode.Else:
haveElse = true
return
}
skipOp(f, load, op)
}
}
func skipOp(f *gen.Func, load loader.L, op opcode.Opcode) {
if debug.Enabled {
debug.Printf("skip %s", op)
}
opcodeSkips[op](f, load, op)
}
func skipBlock(f *gen.Func, load loader.L, op opcode.Opcode) {
load.Varint7() // block type
skipOps(f, load)
}
func skipBrTable(f *gen.Func, load loader.L, op opcode.Opcode) {
for range load.Count(MaxBranchTableLen, "branch table target") {
load.Varuint32() // target
}
load.Varuint32() // default target
}
func skipCallIndirect(f *gen.Func, load loader.L, op opcode.Opcode) {
load.Varuint32() // type index
load.Byte() // reserved
}
func skipIf(f *gen.Func, load loader.L, op opcode.Opcode) {
load.Varint7() // block type
if haveElse := skipThenOps(f, load); haveElse {
skipOps(f, load)
}
}
func skipLoop(f *gen.Func, load loader.L, op opcode.Opcode) {
load.Varint7() // block type
skipOps(f, load)
}
func skipMemoryImmediate(f *gen.Func, load loader.L, op opcode.Opcode) {
load.Varuint32() // flags
load.Varuint32() // offset
}
func skipUint32(f *gen.Func, load loader.L, op opcode.Opcode) { load.Uint32() }
func skipUint64(f *gen.Func, load loader.L, op opcode.Opcode) { load.Uint64() }
func skipVarint32(f *gen.Func, load loader.L, op opcode.Opcode) { load.Varint32() }
func skipVarint64(f *gen.Func, load loader.L, op opcode.Opcode) { load.Varint64() }
func skipVaruint1(f *gen.Func, load loader.L, op opcode.Opcode) { load.Varuint1() }
func skipVaruint32(f *gen.Func, load loader.L, op opcode.Opcode) { load.Varuint32() }
func skipNothing(f *gen.Func, load loader.L, op opcode.Opcode) {}
func badSkip(f *gen.Func, load loader.L, op opcode.Opcode) { badOp(op) }