From fc504e18d2d3d57f66554abc930fdfdf469aba57 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 28 May 2024 16:59:47 +0800 Subject: [PATCH] TypeSizes: goProgram --- internal/build/build.go | 2 +- internal/llgen/llgenf.go | 4 ++-- internal/packages/load.go | 10 +++++----- ssa/package.go | 1 + ssa/type.go | 30 ++++++++++++++++++++++++++++-- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/internal/build/build.go b/internal/build/build.go index e7da46b7..ec9d73c3 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -89,7 +89,7 @@ const ( func Do(args []string, conf *Config) { prog := llssa.NewProgram(nil) - sizes := prog.TypeSizes() + sizes := prog.TypeSizes flags, patterns, verbose := ParseArgs(args, buildFlags) cfg := &packages.Config{ diff --git a/internal/llgen/llgenf.go b/internal/llgen/llgenf.go index 34489f2d..cabbc234 100644 --- a/internal/llgen/llgenf.go +++ b/internal/llgen/llgenf.go @@ -43,7 +43,7 @@ func initRtAndPy(prog llssa.Program, cfg *packages.Config) { load := func() []*packages.Package { if pkgRtAndPy == nil { var err error - pkgRtAndPy, err = packages.LoadEx(prog.TypeSizes(), cfg, llssa.PkgRuntime, llssa.PkgPython) + pkgRtAndPy, err = packages.LoadEx(prog.TypeSizes, cfg, llssa.PkgRuntime, llssa.PkgPython) check(err) } return pkgRtAndPy @@ -65,7 +65,7 @@ func GenFrom(fileOrPkg string) string { cfg := &packages.Config{ Mode: loadSyntax | packages.NeedDeps, } - initial, err := packages.LoadEx(prog.TypeSizes(), cfg, fileOrPkg) + initial, err := packages.LoadEx(prog.TypeSizes, cfg, fileOrPkg) check(err) _, pkgs := ssautil.AllPackages(initial, ssa.SanityCheckFunctions) diff --git a/internal/packages/load.go b/internal/packages/load.go index 0797e099..18d49d63 100644 --- a/internal/packages/load.go +++ b/internal/packages/load.go @@ -101,17 +101,14 @@ func refine(ld *loader, response *packages.DriverResponse) ([]*Package, error) // return an error. Clients may need to handle such errors before // proceeding with further analysis. The PrintErrors function is // provided for convenient display of all errors. -func LoadEx(sizes types.Sizes, cfg *Config, patterns ...string) ([]*Package, error) { +func LoadEx(sizes func(types.Sizes) types.Sizes, cfg *Config, patterns ...string) ([]*Package, error) { ld := newLoader(cfg) response, external, err := defaultDriver(&ld.Config, patterns...) if err != nil { return nil, err } - if sizes == nil { - sizes = types.SizesFor(response.Compiler, response.Arch) - } - ld.sizes = sizes + ld.sizes = types.SizesFor(response.Compiler, response.Arch) if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 { // Type size information is needed but unavailable. if external { @@ -130,6 +127,9 @@ func LoadEx(sizes types.Sizes, cfg *Config, patterns ...string) ([]*Package, err } } + if sizes != nil { + ld.sizes = sizes(ld.sizes) + } return refine(ld, response) } diff --git a/ssa/package.go b/ssa/package.go index b80d06e9..38fa3ae5 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -101,6 +101,7 @@ func Initialize(flags InitFlags) { type aProgram struct { ctx llvm.Context typs typeutil.Map // rawType -> Type + sizes types.Sizes // provided by Go compiler gocvt goTypes rt *types.Package diff --git a/ssa/type.go b/ssa/type.go index b112fdfb..1dfa1afd 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -74,6 +74,31 @@ func indexType(t types.Type) types.Type { // ----------------------------------------------------------------------------- +type goProgram aProgram + +// Alignof returns the alignment of a variable of type T. +// Alignof must implement the alignment guarantees required by the spec. +// The result must be >= 1. +func (p *goProgram) Alignof(T types.Type) int64 { + return p.sizes.Alignof(T) +} + +// Offsetsof returns the offsets of the given struct fields, in bytes. +// Offsetsof must implement the offset guarantees required by the spec. +// A negative entry in the result indicates that the struct is too large. +func (p *goProgram) Offsetsof(fields []*types.Var) []int64 { + return p.sizes.Offsetsof(fields) +} + +// Sizeof returns the size of a variable of type T. +// Sizeof must implement the size guarantees required by the spec. +// A negative result indicates that T is too large. +func (p *goProgram) Sizeof(T types.Type) int64 { + return p.sizes.Sizeof(T) +} + +// ----------------------------------------------------------------------------- + type rawType struct { Type types.Type } @@ -92,8 +117,9 @@ func (t Type) RawType() types.Type { } // TypeSizes returns the sizes of the types. -func (p Program) TypeSizes() types.Sizes { - return nil // TODO(xsw) +func (p Program) TypeSizes(sizes types.Sizes) types.Sizes { + p.sizes = sizes + return (*goProgram)(p) } // TODO(xsw):