Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
2ca544e3
wa
项目概览
wa-lang
/
wa
12 个月 前同步成功
通知
68
Star
655
Fork
45
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
wa
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2ca544e3
编写于
8月 13, 2022
作者:
chai2010
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
loader: 增加 LoadProgramVFS 实现
上级
f3d6f582
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
238 addition
and
5 deletion
+238
-5
internal/loader/api.go
internal/loader/api.go
+2
-2
internal/loader/loader_vfs.go
internal/loader/loader_vfs.go
+236
-3
未找到文件。
internal/loader/api.go
浏览文件 @
2ca544e3
...
...
@@ -42,6 +42,6 @@ func LoadProgram(cfg *config.Config, appPath string) (*Program, error) {
// 从 VFS 加载程序
// 入口 pkgPath 是包的导入路径
func
LoadProgramVFS
(
cfg
*
config
.
Config
,
pkgPath
string
,
vfs
fs
.
FS
)
(
*
Program
,
error
)
{
return
newLoaderVFS
(
vfs
)
.
LoadProgram
(
cfg
,
pkg
Path
)
func
LoadProgramVFS
(
vfs
fs
.
FS
,
cfg
*
config
.
Config
,
appPath
string
)
(
*
Program
,
error
)
{
return
newLoaderVFS
(
vfs
)
.
LoadProgram
(
cfg
,
app
Path
)
}
internal/loader/loader_vfs.go
浏览文件 @
2ca544e3
...
...
@@ -3,10 +3,19 @@
package
loader
import
(
"fmt"
"io/fs"
"os"
pathpkg
"path"
"strings"
"github.com/wa-lang/wa/internal/ast"
"github.com/wa-lang/wa/internal/config"
"github.com/wa-lang/wa/internal/logger"
"github.com/wa-lang/wa/internal/parser"
"github.com/wa-lang/wa/internal/ssa"
"github.com/wa-lang/wa/internal/token"
"github.com/wa-lang/wa/internal/types"
"github.com/wa-lang/wa/internal/waroot"
)
type
_LoaderVFS
struct
{
...
...
@@ -23,6 +32,230 @@ func newLoaderVFS(vfs fs.FS) *_LoaderVFS {
}
}
func
(
p
*
_LoaderVFS
)
LoadProgram
(
cfg
*
config
.
Config
,
pkgPath
string
)
(
*
Program
,
error
)
{
return
p
.
Program
,
fmt
.
Errorf
(
"TODO"
)
func
(
p
*
_LoaderVFS
)
LoadProgram
(
cfg
*
config
.
Config
,
appPath
string
)
(
*
Program
,
error
)
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"cfg: %+v"
,
cfg
)
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"appPath: %s"
,
appPath
)
manifest
,
err
:=
config
.
LoadManifestVFS
(
p
.
vfs
,
appPath
)
if
err
!=
nil
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"err: %v"
,
err
)
return
nil
,
err
}
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"manifest: %s"
,
manifest
.
JSONString
())
p
.
Cfg
=
cfg
p
.
Manifest
=
manifest
p
.
Fset
=
token
.
NewFileSet
()
// import "runtime"
logger
.
Trace
(
&
config
.
EnableTrace_loader
,
"import runtime"
)
if
_
,
err
:=
p
.
Import
(
"runtime"
);
err
!=
nil
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"err: %v"
,
err
)
return
nil
,
err
}
// import "main"
// TODO: 触发递归导入?
logger
.
Trace
(
&
config
.
EnableTrace_loader
,
"import "
+
manifest
.
MainPkg
)
if
_
,
err
:=
p
.
Import
(
manifest
.
MainPkg
);
err
!=
nil
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"err: %v"
,
err
)
return
nil
,
err
}
// 转为 SSA
p
.
SSAProgram
=
ssa
.
NewProgram
(
p
.
Fset
,
ssa
.
SanityCheckFunctions
)
for
pkgpath
,
pkg
:=
range
p
.
Pkgs
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"build SSA; pkgpath: %v"
,
pkgpath
)
if
err
:=
p
.
buildSSA
(
pkgpath
);
err
!=
nil
{
return
p
.
Program
,
err
}
if
pkgpath
==
manifest
.
MainPkg
{
p
.
SSAMainPkg
=
pkg
.
SSAPkg
}
}
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"return ok"
)
return
p
.
Program
,
nil
}
func
(
p
*
_LoaderVFS
)
buildSSA
(
pkgpath
string
)
error
{
pkg
:=
p
.
Pkgs
[
pkgpath
]
if
pkg
.
SSAPkg
!=
nil
{
return
nil
}
for
_
,
importPkg
:=
range
pkg
.
Pkg
.
Imports
()
{
if
p
.
Pkgs
[
importPkg
.
Path
()]
.
SSAPkg
==
nil
{
if
err
:=
p
.
buildSSA
(
importPkg
.
Path
());
err
!=
nil
{
return
err
}
}
}
pkg
.
SSAPkg
=
p
.
SSAProgram
.
CreatePackage
(
pkg
.
Pkg
,
pkg
.
Files
,
pkg
.
Info
,
true
)
pkg
.
SSAPkg
.
Build
()
return
nil
}
func
(
p
*
_LoaderVFS
)
Import
(
pkgpath
string
)
(
*
types
.
Package
,
error
)
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"pkgpath: %v"
,
pkgpath
)
if
pkg
,
ok
:=
p
.
Pkgs
[
pkgpath
];
ok
{
return
pkg
.
Pkg
,
nil
}
var
err
error
var
pkg
Package
// 解析当前包到 AST
pkg
.
Files
,
err
=
p
.
ParseDir
(
pkgpath
)
if
err
!=
nil
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"err: %v"
,
err
)
return
nil
,
err
}
// 修复 pkg 名称(wa 是可选)
for
_
,
f
:=
range
pkg
.
Files
{
if
f
.
Name
.
Name
==
""
{
if
pkgpath
==
p
.
Manifest
.
MainPkg
{
f
.
Name
.
Name
=
"main"
}
else
{
pkgname
:=
pkgpath
if
idx
:=
strings
.
LastIndex
(
pkgname
,
"/"
);
idx
!=
-
1
{
pkgname
=
pkgname
[
idx
+
1
:
]
}
f
.
Name
.
Name
=
pkgname
}
}
}
pkg
.
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
),
Selections
:
make
(
map
[
*
ast
.
SelectorExpr
]
*
types
.
Selection
),
Scopes
:
make
(
map
[
ast
.
Node
]
*
types
.
Scope
),
}
conf
:=
types
.
Config
{
Importer
:
p
,
Sizes
:
p
.
getSizes
(),
}
pkg
.
Pkg
,
err
=
conf
.
Check
(
pkgpath
,
p
.
Fset
,
pkg
.
Files
,
pkg
.
Info
)
if
err
!=
nil
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"err: %v"
,
err
)
return
nil
,
err
}
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"save pkgpath: %v"
,
pkgpath
)
p
.
Pkgs
[
pkgpath
]
=
&
pkg
return
pkg
.
Pkg
,
nil
}
func
(
p
*
_LoaderVFS
)
ParseDir
(
pkgpath
string
)
([]
*
ast
.
File
,
error
)
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"pkgpath: %v"
,
pkgpath
)
var
(
filenames
[]
string
datas
[][]
byte
err
error
)
switch
{
case
p
.
isStdPkg
(
pkgpath
)
:
dirpath
:=
"src/"
+
pkgpath
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"isStdPkg; dirpath: %v"
,
dirpath
)
filenames
,
datas
,
err
=
p
.
readDirFiles
(
p
.
getWaRootFS
(),
dirpath
)
if
err
!=
nil
{
return
nil
,
err
}
case
p
.
isSelfPkg
(
pkgpath
)
:
var
dirpath
string
if
pkgpath
==
p
.
Manifest
.
Pkg
.
Pkgpath
{
dirpath
=
"src"
}
else
{
relpkg
:=
strings
.
TrimPrefix
(
pkgpath
,
p
.
Manifest
.
Pkg
.
Pkgpath
)
dirpath
=
pathpkg
.
Join
(
"src"
,
relpkg
)
}
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"isSelfPkg; dirpath: %v"
,
dirpath
)
filenames
,
datas
,
err
=
p
.
readDirFiles
(
os
.
DirFS
(
p
.
Manifest
.
Root
),
dirpath
)
if
err
!=
nil
{
return
nil
,
err
}
logger
.
Trace
(
&
config
.
EnableTrace_loader
,
"isSelfPkg; return ok"
)
default
:
// vendor
dirpath
:=
"vendor/"
+
strings
.
TrimPrefix
(
pkgpath
,
p
.
Manifest
.
Pkg
.
Pkgpath
)
filenames
,
datas
,
err
=
p
.
readDirFiles
(
os
.
DirFS
(
p
.
Manifest
.
Root
),
dirpath
)
if
err
!=
nil
{
return
nil
,
err
}
}
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"filenames: %v"
,
filenames
)
var
files
[]
*
ast
.
File
for
i
,
filename
:=
range
filenames
{
f
,
err
:=
parser
.
ParseFile
(
p
.
vfs
,
p
.
Fset
,
filename
,
datas
[
i
],
parser
.
AllErrors
)
if
err
!=
nil
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"filename: %v"
,
filename
)
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"datas[i]: %s"
,
datas
[
i
])
return
nil
,
err
}
files
=
append
(
files
,
f
)
}
return
files
,
nil
}
func
(
p
*
_LoaderVFS
)
isStdPkg
(
pkgpath
string
)
bool
{
return
waroot
.
IsStdPkg
(
pkgpath
)
}
func
(
p
*
_LoaderVFS
)
isSelfPkg
(
pkgpath
string
)
bool
{
if
pkgpath
==
p
.
Manifest
.
Pkg
.
Pkgpath
{
return
true
}
if
strings
.
HasPrefix
(
pkgpath
,
p
.
Manifest
.
Pkg
.
Pkgpath
+
"/"
)
{
return
true
}
return
false
}
func
(
p
*
_LoaderVFS
)
readDirFiles
(
fileSystem
fs
.
FS
,
path
string
)
(
filenames
[]
string
,
datas
[][]
byte
,
err
error
)
{
logger
.
Tracef
(
&
config
.
EnableTrace_loader
,
"path: %v"
,
path
)
panic
(
"TODO"
)
}
func
(
p
*
_LoaderVFS
)
getWaRootFS
()
fs
.
FS
{
if
p
.
Cfg
.
WaRoot
!=
""
{
return
os
.
DirFS
(
p
.
Cfg
.
WaRoot
)
}
return
waroot
.
GetFS
()
}
func
(
p
*
_LoaderVFS
)
getSizes
()
types
.
Sizes
{
var
zero
config
.
StdSizes
//types.StdSizes
if
p
==
nil
||
p
.
Cfg
.
WaSizes
==
zero
{
return
types
.
SizesFor
(
p
.
Cfg
.
WaArch
)
}
else
{
return
&
types
.
StdSizes
{
WordSize
:
p
.
Cfg
.
WaSizes
.
WordSize
,
MaxAlign
:
p
.
Cfg
.
WaSizes
.
MaxAlign
,
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录