...
1 package golangasm
2
3 import (
4 "fmt"
5
6 "github.com/twitchyliquid64/golang-asm/asm/arch"
7 "github.com/twitchyliquid64/golang-asm/obj"
8 "github.com/twitchyliquid64/golang-asm/objabi"
9 )
10
11
12 type Builder struct {
13 ctxt *obj.Link
14 arch *arch.Arch
15
16 first *obj.Prog
17 last *obj.Prog
18
19
20 block *[]obj.Prog
21 used int
22 }
23
24
25 func (b *Builder) Root() *obj.Prog {
26 return b.first
27 }
28
29
30 func (b *Builder) NewProg() *obj.Prog {
31 return b.progAlloc()
32 }
33
34 func (b *Builder) progAlloc() *obj.Prog {
35 var p *obj.Prog
36
37 if b.used >= len(*b.block) {
38 p = b.ctxt.NewProg()
39 } else {
40 p = &(*b.block)[b.used]
41 b.used++
42 }
43
44 p.Ctxt = b.ctxt
45 return p
46 }
47
48
49
50 func (b *Builder) AddInstruction(p *obj.Prog) {
51 if b.first == nil {
52 b.first = p
53 b.last = p
54 } else {
55 b.last.Link = p
56 b.last = p
57 }
58 }
59
60
61 func (b *Builder) Assemble() []byte {
62 s := &obj.LSym{
63 Func: &obj.FuncInfo{
64 Text: b.first,
65 },
66 }
67 b.arch.Assemble(b.ctxt, s, b.progAlloc)
68 return s.P
69 }
70
71
72 func NewBuilder(archStr string, cacheSize int) (*Builder, error) {
73 a := arch.Set(archStr)
74 ctxt := obj.Linknew(a.LinkArch)
75 ctxt.Headtype = objabi.Hlinux
76 ctxt.DiagFunc = func(in string, args ...interface{}) {
77 fmt.Printf(in+"\n", args...)
78 }
79 a.Init(ctxt)
80
81 block := make([]obj.Prog, cacheSize)
82
83 return &Builder{
84 ctxt: ctxt,
85 arch: a,
86 block: &block,
87 }, nil
88 }
89
View as plain text