...
1
16
17 package jit
18
19 import (
20 `fmt`
21 `sync`
22 _ `unsafe`
23
24 `github.com/twitchyliquid64/golang-asm/asm/arch`
25 `github.com/twitchyliquid64/golang-asm/obj`
26 `github.com/twitchyliquid64/golang-asm/objabi`
27 )
28
29 type Backend struct {
30 Ctxt *obj.Link
31 Arch *arch.Arch
32 Head *obj.Prog
33 Tail *obj.Prog
34 Prog []*obj.Prog
35 }
36
37 var (
38 _progPool sync.Pool
39 )
40
41
42
43 func throw(_ string)
44
45 func newProg() *obj.Prog {
46 if val := _progPool.Get(); val == nil {
47 return new(obj.Prog)
48 } else {
49 return remProg(val.(*obj.Prog))
50 }
51 }
52
53 func remProg(p *obj.Prog) *obj.Prog {
54 *p = obj.Prog{}
55 return p
56 }
57
58 func newBackend(name string) (ret *Backend) {
59 ret = new(Backend)
60 ret.Arch = arch.Set(name)
61 ret.Ctxt = newLinkContext(ret.Arch.LinkArch)
62 ret.Arch.Init(ret.Ctxt)
63 return
64 }
65
66 func newLinkContext(arch *obj.LinkArch) (ret *obj.Link) {
67 ret = obj.Linknew(arch)
68 ret.Headtype = objabi.Hlinux
69 ret.DiagFunc = diagLinkContext
70 return
71 }
72
73 func diagLinkContext(str string, args ...interface{}) {
74 throw(fmt.Sprintf(str, args...))
75 }
76
77 func (self *Backend) New() (ret *obj.Prog) {
78 ret = newProg()
79 ret.Ctxt = self.Ctxt
80 self.Prog = append(self.Prog, ret)
81 return
82 }
83
84 func (self *Backend) Append(p *obj.Prog) {
85 if self.Head == nil {
86 self.Head = p
87 self.Tail = p
88 } else {
89 self.Tail.Link = p
90 self.Tail = p
91 }
92 }
93
94 func (self *Backend) Release() {
95 self.Arch = nil
96 self.Ctxt = nil
97
98
99 for _, p := range self.Prog {
100 _progPool.Put(p)
101 }
102
103
104 self.Head = nil
105 self.Tail = nil
106 self.Prog = nil
107 }
108
109 func (self *Backend) Assemble() []byte {
110 var sym obj.LSym
111 var fnv obj.FuncInfo
112
113
114 sym.Func = &fnv
115 fnv.Text = self.Head
116
117
118 self.Arch.Assemble(self.Ctxt, &sym, self.New)
119 return sym.P
120 }
121
View as plain text