提交 1b663af6 编写于 作者: chai2010's avatar chai2010

loader 包增加对汇编代码的解析

上级 3bce782a
......@@ -7,6 +7,7 @@ import "wa-lang.org/wa/internal/config"
// 命令行选项
type Option struct {
Debug bool
WaBackend string
BuilgTags []string
TargetArch string
TargetOS string
......@@ -22,6 +23,9 @@ func (opt *Option) Config() *config.Config {
if opt.Debug {
cfg.Debug = true
}
if opt.WaBackend != "" {
cfg.WaBackend = opt.WaBackend
}
if len(opt.BuilgTags) > 0 {
cfg.BuilgTags = append(cfg.BuilgTags, opt.BuilgTags...)
}
......@@ -40,8 +44,11 @@ func (opt *Option) Config() *config.Config {
switch cfg.WaArch {
case "wasm":
cfg.WaSizes.MaxAlign = 4
cfg.WaSizes.MaxAlign = 8
cfg.WaSizes.WordSize = 4
case "wasm64":
cfg.WaSizes.MaxAlign = 8
cfg.WaSizes.WordSize = 8
case "amd64":
cfg.WaSizes.MaxAlign = 8
cfg.WaSizes.WordSize = 8
......
......@@ -22,12 +22,13 @@ type PkgVFS struct {
// 通用配置信息
type Config struct {
BuilgTags []string // 条件编译的标志
UnitTest bool // 单元测试模式
WaBackend string // 编译器后端
WaRoot string // 凹 程序根目录, src 目录下是包代码, 为空时用内置标准库实现
WaArch string // 目标 CPU
WaOS string // 目标 OS
WaSizes StdSizes // 指针大小
BuilgTags []string // 条件编译的标志
UnitTest bool // 单元测试模式
Optimize bool // 是否优化
Debug bool // 调试模式
LDFlags // 链接参数
......@@ -47,6 +48,10 @@ func (p *Config) Clone() *Config {
func DefaultConfig() *Config {
p := &Config{}
if p.WaBackend == "" {
p.WaBackend = WaBackend_Default
}
if p.WaArch == "" {
if s := os.Getenv("WAARCH"); s != "" {
p.WaArch = s
......
......@@ -48,3 +48,26 @@ const (
WaArch_riscv64 = "riscv64" // riscv64 平台
WaArch_wasm = "wasm" // wasm 平台
)
// 后端列表
var WaBackend_List = []string{
WaBackend_clang,
WaBackend_llvm,
WaBackend_wat,
}
// OS 列表
var WaOS_List = []string{
WaOS_arduino,
WaOS_chrome,
WaOS_wasi,
}
// CPU 列表
var WaArch_List = []string{
WaArch_386,
WaArch_amd64,
WaArch_arm64,
WaArch_riscv64,
WaArch_wasm,
}
......@@ -168,7 +168,14 @@ func (p *_Loader) Import(pkgpath string) (*types.Package, error) {
var pkg Package
var filenames []string
// 解析当前包到 AST
// 解析当前包的汇编代码
pkg.WsFiles, err = p.ParseDir_wsFiles(pkgpath)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, err
}
// 解析当前包的 AST
filenames, pkg.Files, err = p.ParseDir(pkgpath)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
......@@ -269,10 +276,70 @@ func (p *_Loader) Import(pkgpath string) (*types.Package, error) {
return pkg.Pkg, nil
}
func (p *_Loader) ParseDir_wsFiles(pkgpath string) (files []WsFile, err error) {
logger.Tracef(&config.EnableTrace_loader, "pkgpath: %v", pkgpath)
if p.cfg.WaBackend == "" {
panic("unreachable")
}
var (
extNames = []string{fmt.Sprintf(".%s.ws", p.cfg.WaBackend)}
unitTestMode bool = false
filenames []string
datas [][]byte
)
switch {
case p.isStdPkg(pkgpath):
logger.Tracef(&config.EnableTrace_loader, "isStdPkg; pkgpath: %v", pkgpath)
filenames, datas, err = p.readDirFiles(p.vfs.Std, pkgpath, unitTestMode, extNames)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, err
}
case p.isSelfPkg(pkgpath):
relpkg := strings.TrimPrefix(pkgpath, p.prog.Manifest.Pkg.Pkgpath)
if relpkg == "" {
relpkg = "."
}
logger.Tracef(&config.EnableTrace_loader, "isSelfPkg; pkgpath=%v, relpkg=%v", pkgpath, relpkg)
filenames, datas, err = p.readDirFiles(p.vfs.App, relpkg, unitTestMode, extNames)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, err
}
logger.Trace(&config.EnableTrace_loader, "isSelfPkg; return ok")
default: // vendor
logger.Tracef(&config.EnableTrace_loader, "vendorPkg; pkgpath: %v", pkgpath)
filenames, datas, err = p.readDirFiles(p.vfs.Vendor, pkgpath, unitTestMode, extNames)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, err
}
}
for i := 0; i < len(filenames); i++ {
files = append(files, WsFile{
Name: filenames[i],
Code: string(datas[i]),
})
}
return
}
func (p *_Loader) ParseDir(pkgpath string) (filenames []string, files []*ast.File, err error) {
logger.Tracef(&config.EnableTrace_loader, "pkgpath: %v", pkgpath)
var (
extNames = []string{".wa", ".wz", ".wa.go"}
unitTestMode bool = false
datas [][]byte
)
......@@ -281,7 +348,7 @@ func (p *_Loader) ParseDir(pkgpath string) (filenames []string, files []*ast.Fil
case p.isStdPkg(pkgpath):
logger.Tracef(&config.EnableTrace_loader, "isStdPkg; pkgpath: %v", pkgpath)
filenames, datas, err = p.readDirFiles(p.vfs.Std, pkgpath, unitTestMode)
filenames, datas, err = p.readDirFiles(p.vfs.Std, pkgpath, unitTestMode, extNames)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, nil, err
......@@ -297,7 +364,7 @@ func (p *_Loader) ParseDir(pkgpath string) (filenames []string, files []*ast.Fil
logger.Tracef(&config.EnableTrace_loader, "isSelfPkg; pkgpath=%v, relpkg=%v", pkgpath, relpkg)
filenames, datas, err = p.readDirFiles(p.vfs.App, relpkg, unitTestMode)
filenames, datas, err = p.readDirFiles(p.vfs.App, relpkg, unitTestMode, extNames)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, nil, err
......@@ -308,7 +375,7 @@ func (p *_Loader) ParseDir(pkgpath string) (filenames []string, files []*ast.Fil
default: // vendor
logger.Tracef(&config.EnableTrace_loader, "vendorPkg; pkgpath: %v", pkgpath)
filenames, datas, err = p.readDirFiles(p.vfs.Vendor, pkgpath, unitTestMode)
filenames, datas, err = p.readDirFiles(p.vfs.Vendor, pkgpath, unitTestMode, extNames)
if err != nil {
logger.Tracef(&config.EnableTrace_loader, "err: %v", err)
return nil, nil, err
......@@ -337,7 +404,11 @@ func (p *_Loader) ParseDir(pkgpath string) (filenames []string, files []*ast.Fil
return filenames, files, nil
}
func (p *_Loader) readDirFiles(fileSystem fs.FS, path string, unitTestMode bool) (filenames []string, datas [][]byte, err error) {
func (p *_Loader) readDirFiles(fileSystem fs.FS, path string, unitTestMode bool, extNames []string) (filenames []string, datas [][]byte, err error) {
if len(extNames) == 0 {
panic("unreachable")
}
path = filepath.ToSlash(path)
path = strings.TrimPrefix(path, "/")
......@@ -357,7 +428,7 @@ func (p *_Loader) readDirFiles(fileSystem fs.FS, path string, unitTestMode bool)
continue
}
if p.isSkipedSouceFile(entry.Name(), unitTestMode) {
if p.isSkipedSouceFile(entry.Name(), unitTestMode, extNames) {
continue
}
......@@ -479,11 +550,14 @@ func (p *_Loader) isSkipedAstFile(f *ast.File) (bool, error) {
return !ok, err
}
func (p *_Loader) isSkipedSouceFile(filename string, unitTestMode bool) bool {
func (p *_Loader) isSkipedSouceFile(filename string, unitTestMode bool, extNames []string) bool {
if len(extNames) == 0 {
panic("unreachable")
}
if strings.HasPrefix(filename, "_") {
return true
}
if !p.hasExt(filename, ".wa", ".wa.go", ".wz") {
if !p.hasExt(filename, extNames...) {
return true
}
......@@ -495,8 +569,8 @@ func (p *_Loader) isSkipedSouceFile(filename string, unitTestMode bool) bool {
if p.cfg.WaOS != "" {
var isTargetFile bool
for _, ext := range []string{".wa", ".wa.go", ".wz"} {
for _, os := range []string{"wasi", "arduino", "chrome"} {
for _, ext := range extNames {
for _, os := range config.WaOS_List {
if strings.HasSuffix(filename, "_"+os+ext) {
isTargetFile = true
break
......@@ -505,7 +579,7 @@ func (p *_Loader) isSkipedSouceFile(filename string, unitTestMode bool) bool {
}
if isTargetFile {
var shouldSkip = true
for _, ext := range []string{".wa", ".wa.go", ".wz"} {
for _, ext := range extNames {
if strings.HasSuffix(filename, "_"+p.cfg.WaOS+ext) {
shouldSkip = false
break
......
......@@ -39,7 +39,7 @@ func main() {
cliApp.Flags = []cli.Flag{
&cli.StringFlag{
Name: "target",
Usage: "set target os (wasi|arduino|chrome)",
Usage: "set target os (arduino|chrome|wasi)",
Value: config.WaOS_Default,
},
&cli.BoolFlag{
......@@ -264,7 +264,7 @@ func main() {
}
infile = c.Args().First()
ctx := app.NewApp(build_Options(c, true))
ctx := app.NewApp(build_Options(c, config.WaBackend_llvm))
if err := ctx.LLVM(infile, outfile, target, debug); err != nil {
fmt.Println(err)
os.Exit(1)
......@@ -476,9 +476,10 @@ func main() {
cliApp.Run(os.Args)
}
func build_Options(c *cli.Context, isLLVMBackend ...bool) *app.Option {
func build_Options(c *cli.Context, waBackend ...string) *app.Option {
opt := &app.Option{
Debug: c.Bool("debug"),
WaBackend: config.WaBackend_Default,
BuilgTags: strings.Fields(c.String("tags")),
Clang: c.String("clang"),
Llc: c.String("llc"),
......@@ -487,9 +488,8 @@ func build_Options(c *cli.Context, isLLVMBackend ...bool) *app.Option {
}
opt.TargetArch = "wasm"
if len(isLLVMBackend) > 0 && isLLVMBackend[0] {
opt.TargetArch = "native"
return opt
if len(waBackend) > 0 {
opt.WaBackend = waBackend[0]
}
switch c.String("target") {
case "", "wa", "walang":
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册