github.com/goplus/llgo/internal/packages; prog.TypeSizes: todo
This commit is contained in:
@@ -29,10 +29,10 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
|
|
||||||
"github.com/goplus/llgo/cl"
|
"github.com/goplus/llgo/cl"
|
||||||
|
"github.com/goplus/llgo/internal/packages"
|
||||||
"github.com/goplus/llgo/xtool/clang"
|
"github.com/goplus/llgo/xtool/clang"
|
||||||
|
|
||||||
llssa "github.com/goplus/llgo/ssa"
|
llssa "github.com/goplus/llgo/ssa"
|
||||||
@@ -88,6 +88,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Do(args []string, conf *Config) {
|
func Do(args []string, conf *Config) {
|
||||||
|
prog := llssa.NewProgram(nil)
|
||||||
|
sizes := prog.TypeSizes()
|
||||||
|
|
||||||
flags, patterns, verbose := ParseArgs(args, buildFlags)
|
flags, patterns, verbose := ParseArgs(args, buildFlags)
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: loadSyntax | packages.NeedDeps | packages.NeedModule | packages.NeedExportFile,
|
Mode: loadSyntax | packages.NeedDeps | packages.NeedModule | packages.NeedExportFile,
|
||||||
@@ -97,7 +100,7 @@ func Do(args []string, conf *Config) {
|
|||||||
if patterns == nil {
|
if patterns == nil {
|
||||||
patterns = []string{"."}
|
patterns = []string{"."}
|
||||||
}
|
}
|
||||||
initial, err := packages.Load(cfg, patterns...)
|
initial, err := packages.LoadEx(sizes, cfg, patterns...)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
mode := conf.Mode
|
mode := conf.Mode
|
||||||
@@ -122,11 +125,10 @@ func Do(args []string, conf *Config) {
|
|||||||
|
|
||||||
var needRt bool
|
var needRt bool
|
||||||
var rt []*packages.Package
|
var rt []*packages.Package
|
||||||
prog := llssa.NewProgram(nil)
|
|
||||||
load := func() []*packages.Package {
|
load := func() []*packages.Package {
|
||||||
if rt == nil {
|
if rt == nil {
|
||||||
var err error
|
var err error
|
||||||
rt, err = packages.Load(cfg, llssa.PkgRuntime, llssa.PkgPython)
|
rt, err = packages.LoadEx(sizes, cfg, llssa.PkgRuntime, llssa.PkgPython)
|
||||||
check(err)
|
check(err)
|
||||||
}
|
}
|
||||||
return rt
|
return rt
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"golang.org/x/tools/go/packages"
|
"github.com/goplus/llgo/internal/packages"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -42,7 +42,7 @@ func Clean(args []string, conf *Config) {
|
|||||||
if patterns == nil {
|
if patterns == nil {
|
||||||
patterns = []string{"."}
|
patterns = []string{"."}
|
||||||
}
|
}
|
||||||
initial, err := packages.Load(cfg, patterns...)
|
initial, err := packages.LoadEx(nil, cfg, patterns...)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
cleanPkgs(initial, verbose)
|
cleanPkgs(initial, verbose)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/goplus/llgo/cl"
|
"github.com/goplus/llgo/cl"
|
||||||
"golang.org/x/tools/go/packages"
|
"github.com/goplus/llgo/internal/packages"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
"golang.org/x/tools/go/ssa/ssautil"
|
"golang.org/x/tools/go/ssa/ssautil"
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ func initRtAndPy(prog llssa.Program, cfg *packages.Config) {
|
|||||||
load := func() []*packages.Package {
|
load := func() []*packages.Package {
|
||||||
if pkgRtAndPy == nil {
|
if pkgRtAndPy == nil {
|
||||||
var err error
|
var err error
|
||||||
pkgRtAndPy, err = packages.Load(cfg, llssa.PkgRuntime, llssa.PkgPython)
|
pkgRtAndPy, err = packages.LoadEx(prog.TypeSizes(), cfg, llssa.PkgRuntime, llssa.PkgPython)
|
||||||
check(err)
|
check(err)
|
||||||
}
|
}
|
||||||
return pkgRtAndPy
|
return pkgRtAndPy
|
||||||
@@ -60,10 +60,12 @@ func initRtAndPy(prog llssa.Program, cfg *packages.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GenFrom(fileOrPkg string) string {
|
func GenFrom(fileOrPkg string) string {
|
||||||
|
prog := llssa.NewProgram(nil)
|
||||||
|
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: loadSyntax | packages.NeedDeps,
|
Mode: loadSyntax | packages.NeedDeps,
|
||||||
}
|
}
|
||||||
initial, err := packages.Load(cfg, fileOrPkg)
|
initial, err := packages.LoadEx(prog.TypeSizes(), cfg, fileOrPkg)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
_, pkgs := ssautil.AllPackages(initial, ssa.SanityCheckFunctions)
|
_, pkgs := ssautil.AllPackages(initial, ssa.SanityCheckFunctions)
|
||||||
@@ -72,7 +74,6 @@ func GenFrom(fileOrPkg string) string {
|
|||||||
ssaPkg := pkgs[0]
|
ssaPkg := pkgs[0]
|
||||||
ssaPkg.Build()
|
ssaPkg.Build()
|
||||||
|
|
||||||
prog := llssa.NewProgram(nil)
|
|
||||||
initRtAndPy(prog, cfg)
|
initRtAndPy(prog, cfg)
|
||||||
|
|
||||||
if Verbose {
|
if Verbose {
|
||||||
|
|||||||
144
internal/packages/load.go
Normal file
144
internal/packages/load.go
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package packages
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go/types"
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/packages"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A LoadMode controls the amount of detail to return when loading.
|
||||||
|
// The bits below can be combined to specify which fields should be
|
||||||
|
// filled in the result packages.
|
||||||
|
// The zero value is a special case, equivalent to combining
|
||||||
|
// the NeedName, NeedFiles, and NeedCompiledGoFiles bits.
|
||||||
|
// ID and Errors (if present) will always be filled.
|
||||||
|
// Load may return more information than requested.
|
||||||
|
type LoadMode = packages.LoadMode
|
||||||
|
|
||||||
|
const (
|
||||||
|
NeedName = packages.NeedName
|
||||||
|
NeedFiles = packages.NeedFiles
|
||||||
|
|
||||||
|
NeedSyntax = packages.NeedSyntax
|
||||||
|
NeedImports = packages.NeedImports
|
||||||
|
NeedDeps = packages.NeedDeps
|
||||||
|
NeedModule = packages.NeedModule
|
||||||
|
NeedExportFile = packages.NeedExportFile
|
||||||
|
|
||||||
|
NeedCompiledGoFiles = packages.NeedCompiledGoFiles
|
||||||
|
|
||||||
|
NeedTypes = packages.NeedTypes
|
||||||
|
NeedTypesSizes = packages.NeedTypesSizes
|
||||||
|
NeedTypesInfo = packages.NeedTypesInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Config specifies details about how packages should be loaded.
|
||||||
|
// The zero value is a valid configuration.
|
||||||
|
// Calls to Load do not modify this struct.
|
||||||
|
type Config = packages.Config
|
||||||
|
|
||||||
|
// A Package describes a loaded Go package.
|
||||||
|
type Package = packages.Package
|
||||||
|
|
||||||
|
// loader holds the working state of a single call to load.
|
||||||
|
type loader struct {
|
||||||
|
pkgs map[string]unsafe.Pointer
|
||||||
|
Config
|
||||||
|
sizes types.Sizes // non-nil if needed by mode
|
||||||
|
parseCache map[string]unsafe.Pointer
|
||||||
|
parseCacheMu sync.Mutex
|
||||||
|
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
||||||
|
|
||||||
|
// Config.Mode contains the implied mode (see impliedLoadMode).
|
||||||
|
// Implied mode contains all the fields we need the data for.
|
||||||
|
// In requestedMode there are the actually requested fields.
|
||||||
|
// We'll zero them out before returning packages to the user.
|
||||||
|
// This makes it easier for us to get the conditions where
|
||||||
|
// we need certain modes right.
|
||||||
|
requestedMode LoadMode
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname newLoader golang.org/x/tools/go/packages.newLoader
|
||||||
|
func newLoader(cfg *Config) *loader
|
||||||
|
|
||||||
|
//go:linkname defaultDriver golang.org/x/tools/go/packages.defaultDriver
|
||||||
|
func defaultDriver(cfg *Config, patterns ...string) (*packages.DriverResponse, bool, error)
|
||||||
|
|
||||||
|
//go:linkname refine golang.org/x/tools/go/packages.(*loader).refine
|
||||||
|
func refine(ld *loader, response *packages.DriverResponse) ([]*Package, error)
|
||||||
|
|
||||||
|
// LoadEx loads and returns the Go packages named by the given patterns.
|
||||||
|
//
|
||||||
|
// Config specifies loading options;
|
||||||
|
// nil behaves the same as an empty Config.
|
||||||
|
//
|
||||||
|
// If any of the patterns was invalid as defined by the
|
||||||
|
// underlying build system, Load returns an error.
|
||||||
|
// It may return an empty list of packages without an error,
|
||||||
|
// for instance for an empty expansion of a valid wildcard.
|
||||||
|
// Errors associated with a particular package are recorded in the
|
||||||
|
// corresponding Package's Errors list, and do not cause Load to
|
||||||
|
// 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) {
|
||||||
|
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
|
||||||
|
if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 {
|
||||||
|
// Type size information is needed but unavailable.
|
||||||
|
if external {
|
||||||
|
// An external driver may fail to populate the Compiler/GOARCH fields,
|
||||||
|
// especially since they are relatively new (see #63700).
|
||||||
|
// Provide a sensible fallback in this case.
|
||||||
|
ld.sizes = types.SizesFor("gc", runtime.GOARCH)
|
||||||
|
if ld.sizes == nil { // gccgo-only arch
|
||||||
|
ld.sizes = types.SizesFor("gc", "amd64")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Go list should never fail to deliver accurate size information.
|
||||||
|
// Reject the whole Load since the error is the same for every package.
|
||||||
|
return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q",
|
||||||
|
response.Compiler, response.Arch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return refine(ld, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visit visits all the packages in the import graph whose roots are
|
||||||
|
// pkgs, calling the optional pre function the first time each package
|
||||||
|
// is encountered (preorder), and the optional post function after a
|
||||||
|
// package's dependencies have been visited (postorder).
|
||||||
|
// The boolean result of pre(pkg) determines whether
|
||||||
|
// the imports of package pkg are visited.
|
||||||
|
//
|
||||||
|
//go:linkname Visit golang.org/x/tools/go/packages.Visit
|
||||||
|
func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package))
|
||||||
@@ -91,6 +91,11 @@ func (t Type) RawType() types.Type {
|
|||||||
return t.raw.Type
|
return t.raw.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TypeSizes returns the sizes of the types.
|
||||||
|
func (p Program) TypeSizes() types.Sizes {
|
||||||
|
return nil // TODO(xsw)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(xsw):
|
// TODO(xsw):
|
||||||
// how to generate platform independent code?
|
// how to generate platform independent code?
|
||||||
func (p Program) SizeOf(typ Type, n ...int64) uint64 {
|
func (p Program) SizeOf(typ Type, n ...int64) uint64 {
|
||||||
|
|||||||
Reference in New Issue
Block a user