basic structure

This commit is contained in:
xushiwei
2024-04-15 00:48:04 +08:00
parent a1211a98e3
commit 55b310d266
13 changed files with 249 additions and 74 deletions

2
.gitignore vendored
View File

@@ -20,4 +20,4 @@ _tinygo/
# vendor/
# Go workspace file
go.work
go.work*

View File

@@ -16,18 +16,21 @@
package build
import (
"go/build"
)
// An ImportMode controls the behavior of the Import method.
type ImportMode uint
type ImportMode = build.ImportMode
// A Package describes the Go package found in a directory.
type Package struct {
Dir string // directory containing package sources
Name string // package name
ImportPath string // import path of package ("" if unknown)
*build.Package
}
// A Context specifies the supporting context for a build.
type Context struct {
*build.Context
}
// Import returns details about the Go package named by the import path,
@@ -38,12 +41,17 @@ type Context struct {
//
// If an error occurs, Import returns a non-nil error and a non-nil
// *Package containing partial information.
func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
panic("todo")
func (ctxt Context) Import(path string, srcDir string, mode ImportMode) (ret Package, err error) {
pkg, err := build.Import(path, srcDir, mode)
if err != nil {
return
}
ret = Package{pkg}
return
}
// ImportDir is like Import but processes the Go package found in
// the named directory.
func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
func (ctxt *Context) ImportDir(dir string, mode ImportMode) (Package, error) {
return ctxt.Import(".", dir, mode)
}

View File

@@ -16,6 +16,7 @@
package cl
/*
import (
llvm "tinygo.org/x/go-llvm"
)
@@ -42,3 +43,4 @@ var stdlibAliases = map[string]string{
func (b *builder) createAlias(alias llvm.Value) {
panic("todo")
}
*/

View File

@@ -16,6 +16,7 @@
package cl
/*
import (
"golang.org/x/tools/go/ssa"
llvm "tinygo.org/x/go-llvm"
@@ -35,3 +36,4 @@ func newBuilder(c *context, irbuilder llvm.Builder, f *ssa.Function) *builder {
func (b *builder) createFunction() {
panic("todo")
}
*/

View File

@@ -16,6 +16,7 @@
package cl
/*
import (
"go/types"
"os"
@@ -213,8 +214,8 @@ func NewPackage(moduleName string, pkg loader.Package, conf *Config) (ret Packag
// Predeclare trackPointer, which is used everywhere we use runtime.alloc.
c.getFunction(c.program.ImportedPackage("runtime").Members["trackPointer"].(*ssa.Function))
}
*/
*/
/*
// Compile all functions, methods, and global variables in this package.
irbuilder := c.ctx.NewBuilder()
defer irbuilder.Dispose()
@@ -232,7 +233,8 @@ func NewPackage(moduleName string, pkg loader.Package, conf *Config) (ret Packag
}),
)
}
*/
*/
/*
ret.Module = c.mod
err = c.errs.ToError()
return
@@ -271,3 +273,4 @@ func (p Package) WriteTo(f *os.File) (err error) {
}
return
}
*/

View File

@@ -16,6 +16,7 @@
package cl
/*
// Define unimplemented intrinsic functions.
//
// Some functions are either normally implemented in Go assembly (like
@@ -58,3 +59,4 @@ func (b *builder) defineMathOp() {
func (b *builder) defineMathBitsIntrinsic() bool {
panic("todo")
}
*/

View File

@@ -16,6 +16,7 @@
package cl
/*
import (
"go/types"
@@ -40,7 +41,8 @@ type functionInfo struct {
nobounds bool // go:nobounds
variadic bool // go:variadic (CGo only)
inline inlineType // go:inline
*/
*/
/*
linkName string // go:linkname, go:export - the IR function name
}
@@ -64,7 +66,7 @@ const (
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
// exported.
@@ -79,7 +81,8 @@ type globalInfo struct {
/*
linkName string // go:extern
align int // go:align
*/
*/
/*
section string // go:section
extern bool // go:extern
}
@@ -103,3 +106,4 @@ func (c *context) getGlobalInfo(g *ssa.Global) globalInfo {
func getAllMethods(prog *ssa.Program, typ types.Type) []*types.Selection {
panic("todo")
}
*/

View File

@@ -33,7 +33,7 @@ import (
// llgo build
var Cmd = &base.Command{
UsageLine: "llog build [flags] [packages]",
UsageLine: "llgo build [flags] [packages]",
Short: "Build Go files",
}
@@ -87,7 +87,7 @@ func build(proj gopprojs.Proj, conf *llgo.Config, build *gocmd.BuildConfig) {
err = llgo.BuildDir(obj, conf, build)
case *gopprojs.PkgPathProj:
obj = v.Path
err = llgo.BuildPkgPath("", v.Path, conf, build)
err = llgo.BuildPkgPath("", obj, conf, build)
case *gopprojs.FilesProj:
err = llgo.BuildFiles(v.Files, conf, build)
default:

13
go.mod
View File

@@ -5,14 +5,13 @@ go 1.18
require (
github.com/aykevl/go-wasm v0.0.1
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
github.com/goplus/gop v1.1.13
github.com/qiniu/x v1.13.1
golang.org/x/tools v0.16.0
tinygo.org/x/go-llvm v0.0.0-20231014233752-75a8a9fe6f74
github.com/goplus/gop v1.2.6
github.com/qiniu/x v1.13.10
)
require (
github.com/goplus/gox v1.13.1 // indirect
github.com/goplus/mod v0.11.9 // indirect
golang.org/x/mod v0.14.0 // indirect
github.com/goplus/gogen v1.15.2 // indirect
github.com/goplus/mod v0.13.10 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/tools v0.19.0 // indirect
)

28
go.sum
View File

@@ -2,14 +2,14 @@ github.com/aykevl/go-wasm v0.0.1 h1:lPxy8l48P39W7I0tLrtCrLfZBOUq9IWZ7odGdyJP2AM=
github.com/aykevl/go-wasm v0.0.1/go.mod h1:b4nggwg3lEkNKOU4wzhtLKz2q2sLxSHFnc98aGt6z/Y=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/goplus/gop v1.1.13 h1:Nnyzy7BeE25SbpGfOX/mHGBCpvVsmkr/9hW0FtUXZwY=
github.com/goplus/gop v1.1.13/go.mod h1:iRl6Rxc4bazQaDr4yUlxSpa9Wxs8J2nXG0ON8vcfh4g=
github.com/goplus/gox v1.13.1 h1:/X6Ja9R2hQuLVbN+PzLHRtaBcan+YmhASvGO3nMJsZw=
github.com/goplus/gox v1.13.1/go.mod h1:UNzOPlRyO/uQn+9iHelk6KelAFaaC7OBn5AxtSSsC9c=
github.com/goplus/mod v0.11.9 h1:XdWvSNi55fQ3KHnk0PVVHsXynG58lTbfXps/C9HjTVQ=
github.com/goplus/mod v0.11.9/go.mod h1:YxrBMhvWGcvLU14j8e7qyKSVnj5Loba7GgH1rNXJtDg=
github.com/qiniu/x v1.13.1 h1:hi7tkXFq6BWGbBpMoLV7kvA2elop69j6Kl7TlxnFAiU=
github.com/qiniu/x v1.13.1/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/goplus/gogen v1.15.2 h1:Q6XaSx/Zi5tWnjfAziYsQI6Jv6MgODRpFtOYqNkiiqM=
github.com/goplus/gogen v1.15.2/go.mod h1:92qEzVgv7y8JEFICWG9GvYI5IzfEkxYdsA1DbmnTkqk=
github.com/goplus/gop v1.2.6 h1:kog3c5Js+8EopqmI4+CwueXsqibnBwYVt5q5N7juRVY=
github.com/goplus/gop v1.2.6/go.mod h1:uREWbR1MrFaviZ4Mbx4ZCcAYDoqzO0iv1Qo6Np0Xx4E=
github.com/goplus/mod v0.13.10 h1:5Om6KOvo31daN7N30kWU1vC5zhsJPM+uPbcEN/FnlzE=
github.com/goplus/mod v0.13.10/go.mod h1:HDuPZgpWiaTp3PUolFgsiX+Q77cbUWB/mikVHfYND3c=
github.com/qiniu/x v1.13.10 h1:J4Z3XugYzAq85SlyAfqlKVrbf05glMbAOh+QncsDQpE=
github.com/qiniu/x v1.13.10/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -17,8 +17,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -29,7 +29,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -54,8 +54,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
tinygo.org/x/go-llvm v0.0.0-20231014233752-75a8a9fe6f74 h1:tW8XhLI9gUZLL+2pG0HYb5dc6bpMj1aqtESpizXPnMY=
tinygo.org/x/go-llvm v0.0.0-20231014233752-75a8a9fe6f74/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=

View File

@@ -1,36 +0,0 @@
/*
* Copyright (c) 2023 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 loader
import (
"golang.org/x/tools/go/ssa"
)
type Package struct {
SSA *ssa.Package
EmbedGlobals map[string][]*EmbedFile
}
type EmbedFile struct {
/*
Name string
Size uint64
Hash string // hash of the file (as a hex string)
NeedsData bool // true if this file is embedded as a byte slice
Data []byte // contents of this file (only if NeedsData is set)
*/
}

130
x/loader/loader.go Normal file
View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2023 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 loader
/*
import (
"go/ast"
"go/token"
"go/types"
"github.com/goplus/llgo/build"
"golang.org/x/tools/go/ssa"
)
type Package struct {
SSA *ssa.Package
EmbedGlobals map[string][]*EmbedFile
}
type EmbedFile struct {
/*
Name string
Size uint64
Hash string // hash of the file (as a hex string)
NeedsData bool // true if this file is embedded as a byte slice
Data []byte // contents of this file (only if NeedsData is set)
*/
/*
}
type Context struct {
*ssa.Program
}
func (ctx *Context) Load(pkg build.Package) (ret Package, err error) {
return
}
// BuildPackage builds an SSA program with IR for a single package.
//
// It populates pkg by type-checking the specified file ASTs. All
// dependencies are loaded using the importer specified by tc, which
// typically loads compiler export data; SSA code cannot be built for
// those packages. BuildPackage then constructs an ssa.Program with all
// dependency packages created, and builds and returns the SSA package
// corresponding to pkg.
//
// The caller must have set pkg.Path() to the import path.
//
// The operation fails if there were any type-checking or import errors.
//
// See ../example_test.go for an example.
func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ssa.BuilderMode) (*ssa.Package, *types.Info, error) {
if fset == nil {
panic("no token.FileSet")
}
if pkg.Path() == "" {
panic("package has no import path")
}
info := &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
Implicits: make(map[ast.Node]types.Object),
Scopes: make(map[ast.Node]*types.Scope),
Selections: make(map[*ast.SelectorExpr]*types.Selection),
}
typeparams.InitInstanceInfo(info)
versions.InitFileVersions(info)
if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil {
return nil, nil, err
}
prog := ssa.NewProgram(fset, mode)
// Create SSA packages for all imports.
// Order is not significant.
created := make(map[*types.Package]bool)
var createAll func(pkgs []*types.Package)
createAll = func(pkgs []*types.Package) {
for _, p := range pkgs {
if !created[p] {
created[p] = true
prog.CreatePackage(p, nil, nil, true)
createAll(p.Imports())
}
}
}
createAll(pkg.Imports())
// TODO(adonovan): we could replace createAll with just:
//
// // Create SSA packages for all imports.
// for _, p := range pkg.Imports() {
// prog.CreatePackage(p, nil, nil, true)
// }
//
// (with minor changes to changes to ../builder_test.go as
// shown in CL 511715 PS 10.) But this would strictly violate
// the letter of the doc comment above, which says "all
// dependencies created".
//
// Tim makes the good point with some extra work we could
// remove the need for any CreatePackage calls except the
// ones with syntax (i.e. primary packages). Of course
// You wouldn't have ssa.Packages and Members for as
// many things but no-one really uses that anyway.
// I wish I had done this from the outset.
// Create and build the primary package.
ssapkg := prog.CreatePackage(pkg, files, info, false)
ssapkg.Build()
return ssapkg, info, nil
}
*/

63
x/parser/parser.go Normal file
View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 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 parser
/*
import (
"go/ast"
"go/parser"
"go/token"
"github.com/goplus/llgo/build"
)
// A Mode value is a set of flags (or 0).
// They control the amount of source code parsed and other optional
// parser functionality.
type Mode = parser.Mode
const (
PackageClauseOnly = parser.PackageClauseOnly // stop parsing after package clause
ImportsOnly = parser.ImportsOnly // stop parsing after import declarations
ParseComments = parser.ParseComments // parse comments and add them to AST
Trace = parser.Trace // print a trace of parsed productions
DeclarationErrors = parser.DeclarationErrors // report declaration errors
SpuriousErrors = parser.SpuriousErrors // same as AllErrors, for backward-compatibility
SkipObjectResolution = parser.SkipObjectResolution // don't resolve identifiers to objects - see ParseFile
AllErrors = parser.AllErrors // report all errors (not just the first 10 on different lines)
)
// A Package node represents a set of source files
// collectively building a Go package.
type Package struct {
*ast.Package
}
func Parse(fset *token.FileSet, pkg build.Package, mode Mode) (_ Package, first error) {
ret := map[string]*ast.Package{}
for _, file := range pkg.GoFiles {
f, err := parser.ParseFile(fset, file, nil, mode)
if err != nil {
if first == nil {
first = err
}
continue
}
ret[file] = f
}
}
*/