podman
1/*
2* Copyright 2021 ByteDance Inc.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17package jit18
19import (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
29type Backend struct {30Ctxt *obj.Link31Arch *arch.Arch32Head *obj.Prog33Tail *obj.Prog34Prog []*obj.Prog35}
36
37var (38_progPool sync.Pool39)
40
41//go:nosplit
42//go:linkname throw runtime.throw
43func throw(_ string)44
45func newProg() *obj.Prog {46if val := _progPool.Get(); val == nil {47return new(obj.Prog)48} else {49return remProg(val.(*obj.Prog))50}51}
52
53func remProg(p *obj.Prog) *obj.Prog {54*p = obj.Prog{}55return p56}
57
58func newBackend(name string) (ret *Backend) {59ret = new(Backend)60ret.Arch = arch.Set(name)61ret.Ctxt = newLinkContext(ret.Arch.LinkArch)62ret.Arch.Init(ret.Ctxt)63return64}
65
66func newLinkContext(arch *obj.LinkArch) (ret *obj.Link) {67ret = obj.Linknew(arch)68ret.Headtype = objabi.Hlinux69ret.DiagFunc = diagLinkContext70return71}
72
73func diagLinkContext(str string, args ...interface{}) {74throw(fmt.Sprintf(str, args...))75}
76
77func (self *Backend) New() (ret *obj.Prog) {78ret = newProg()79ret.Ctxt = self.Ctxt80self.Prog = append(self.Prog, ret)81return82}
83
84func (self *Backend) Append(p *obj.Prog) {85if self.Head == nil {86self.Head = p87self.Tail = p88} else {89self.Tail.Link = p90self.Tail = p91}92}
93
94func (self *Backend) Release() {95self.Arch = nil96self.Ctxt = nil97
98/* return all the progs into pool */99for _, p := range self.Prog {100_progPool.Put(p)101}102
103/* clear all the references */104self.Head = nil105self.Tail = nil106self.Prog = nil107}
108
109func (self *Backend) Assemble() []byte {110var sym obj.LSym111var fnv obj.FuncInfo112
113/* construct the function */114sym.Func = &fnv115fnv.Text = self.Head116
117/* call the assembler */118self.Arch.Assemble(self.Ctxt, &sym, self.New)119return sym.P120}
121