From f084144f7a12180ded0a679c29f7aa62438955aa Mon Sep 17 00:00:00 2001 From: xushiwei Date: Mon, 11 Dec 2023 00:37:09 +0800 Subject: [PATCH] cl.Package --- cl/compile.go | 46 ++++++++++++++++++++++++++++++++++++++++++++-- cl/symbol.go | 33 ++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/cl/compile.go b/cl/compile.go index 83ac1c15..fe54f3ce 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -18,6 +18,8 @@ package cl import ( "go/types" + "os" + "runtime" "sort" "github.com/goplus/llgo/loader" @@ -189,7 +191,11 @@ func (c *context) createEmbedGlobal(member *ssa.Global, global llvm.Value, files panic("todo") } -func NewPackage(moduleName string, pkg loader.Package, conf *Config) (ret llvm.Module, err error) { +type Package struct { + llvm.Module +} + +func NewPackage(moduleName string, pkg loader.Package, conf *Config) (ret Package, err error) { ssaPkg := pkg.SSA ssaPkg.Build() @@ -227,5 +233,41 @@ func NewPackage(moduleName string, pkg loader.Package, conf *Config) (ret llvm.M ) } */ - return c.mod, c.errs.ToError() + ret.Module = c.mod + err = c.errs.ToError() + return +} + +func (p Package) Dispose() { + p.Module.Dispose() +} + +func (p Package) WriteFile(file string) (err error) { + f, err := os.Create(file) + if err != nil { + return + } + err = p.WriteTo(f) + f.Close() + if err != nil { + os.Remove(file) + } + return +} + +func (p Package) WriteTo(f *os.File) (err error) { + if runtime.GOOS == "windows" { + // Work around a problem on Windows. + // For some reason, WriteBitcodeToFile causes TinyGo to + // exit with the following message: + // LLVM ERROR: IO failure on output stream: Bad file descriptor + buf := llvm.WriteBitcodeToMemoryBuffer(p.Module) + defer buf.Dispose() + _, err = f.Write(buf.Bytes()) + } else { + // Otherwise, write bitcode directly to the file (probably + // faster). + err = llvm.WriteBitcodeToFile(p.Module, f) + } + return } diff --git a/cl/symbol.go b/cl/symbol.go index 7db0d222..eb8e8d5f 100644 --- a/cl/symbol.go +++ b/cl/symbol.go @@ -30,17 +30,21 @@ import ( // The linkName value contains a valid link name, even if //go:linkname is not // present. type functionInfo struct { - wasmModule string // go:wasm-module - wasmName string // wasm-export-name or wasm-import-name in the IR - linkName string // go:linkname, go:export - the IR function name - section string // go:section - object file section name - exported bool // go:export, CGo - interrupt bool // go:interrupt - nobounds bool // go:nobounds - variadic bool // go:variadic (CGo only) - inline inlineType // go:inline + /* + wasmModule string // go:wasm-module + wasmName string // wasm-export-name or wasm-import-name in the IR + linkName string // go:linkname, go:export - the IR function name + section string // go:section - object file section name + exported bool // go:export, CGo + interrupt bool // go:interrupt + nobounds bool // go:nobounds + variadic bool // go:variadic (CGo only) + inline inlineType // go:inline + */ + linkName string // go:linkname, go:export - the IR function name } +/* type inlineType int // How much to inline. @@ -59,6 +63,7 @@ const ( // //go:noinline. inlineNone ) +*/ // getFunctionInfo returns information about a function that is not directly // present in *ssa.Function, such as the link name and whether it should be @@ -71,10 +76,12 @@ func (c *context) getFunctionInfo(f *ssa.Function) functionInfo { // linkName is equal to .RelString(nil) on a global and extern is false, but for // some symbols this is different (due to //go:extern for example). type globalInfo struct { - linkName string // go:extern - extern bool // go:extern - align int // go:align - section string // go:section + /* + linkName string // go:extern + align int // go:align + */ + section string // go:section + extern bool // go:extern } func (c *context) loadASTComments(loader.Package) {