Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
9dc08a73
wa
项目概览
wa-lang
/
wa
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
9dc08a73
编写于
4月 11, 2023
作者:
3
3dgen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
interface 阶段性实现
上级
7b0be4ec
变更
25
隐藏空白更改
内联
并排
Showing
25 changed file
with
1290 addition
and
379 deletion
+1290
-379
internal/ast/astutil/comment_info.go
internal/ast/astutil/comment_info.go
+3
-0
internal/backends/compiler_wat/compile.go
internal/backends/compiler_wat/compile.go
+40
-37
internal/backends/compiler_wat/compile_func.go
internal/backends/compiler_wat/compile_func.go
+117
-57
internal/backends/compiler_wat/compile_global.go
internal/backends/compiler_wat/compile_global.go
+3
-3
internal/backends/compiler_wat/compile_type.go
internal/backends/compiler_wat/compile_type.go
+300
-1
internal/backends/compiler_wat/util.go
internal/backends/compiler_wat/util.go
+0
-67
internal/backends/compiler_wat/wir/data_seg.go
internal/backends/compiler_wat/wir/data_seg.go
+33
-0
internal/backends/compiler_wat/wir/instruction_emitter.go
internal/backends/compiler_wat/wir/instruction_emitter.go
+29
-6
internal/backends/compiler_wat/wir/module.go
internal/backends/compiler_wat/wir/module.go
+76
-39
internal/backends/compiler_wat/wir/util.go
internal/backends/compiler_wat/wir/util.go
+116
-5
internal/backends/compiler_wat/wir/value_array.go
internal/backends/compiler_wat/wir/value_array.go
+13
-12
internal/backends/compiler_wat/wir/value_basic.go
internal/backends/compiler_wat/wir/value_basic.go
+54
-0
internal/backends/compiler_wat/wir/value_block.go
internal/backends/compiler_wat/wir/value_block.go
+37
-10
internal/backends/compiler_wat/wir/value_closure.go
internal/backends/compiler_wat/wir/value_closure.go
+19
-28
internal/backends/compiler_wat/wir/value_interface.go
internal/backends/compiler_wat/wir/value_interface.go
+100
-0
internal/backends/compiler_wat/wir/value_pointer.go
internal/backends/compiler_wat/wir/value_pointer.go
+20
-2
internal/backends/compiler_wat/wir/value_ref.go
internal/backends/compiler_wat/wir/value_ref.go
+16
-15
internal/backends/compiler_wat/wir/value_slice.go
internal/backends/compiler_wat/wir/value_slice.go
+21
-20
internal/backends/compiler_wat/wir/value_string.go
internal/backends/compiler_wat/wir/value_string.go
+19
-18
internal/backends/compiler_wat/wir/value_struct.go
internal/backends/compiler_wat/wir/value_struct.go
+52
-20
internal/backends/compiler_wat/wir/value_tuple.go
internal/backends/compiler_wat/wir/value_tuple.go
+26
-14
internal/backends/compiler_wat/wir/value_type.go
internal/backends/compiler_wat/wir/value_type.go
+70
-24
internal/backends/compiler_wat/wir/wir.go
internal/backends/compiler_wat/wir/wir.go
+8
-1
internal/ssa/ssa.go
internal/ssa/ssa.go
+15
-0
internal/waroot/_waroot/src/runtime/runtime_type.wa
internal/waroot/_waroot/src/runtime/runtime_type.wa
+103
-0
未找到文件。
internal/ast/astutil/comment_info.go
浏览文件 @
9dc08a73
...
...
@@ -21,6 +21,7 @@ type CommentInfo struct {
ForceRegister
bool
// #wa:force_register
RuntimeGetter
bool
// #wa:runtime_getter
RuntimeSetter
bool
// #wa:runtime_setter
RuntimeSizer
bool
// #wa:runtime_sizer
WasmModule
string
// #wa:wasm-module xxx
}
...
...
@@ -85,6 +86,8 @@ func ParseCommentInfo(docList ...*ast.CommentGroup) (info CommentInfo) {
info
.
RuntimeGetter
=
true
case
"#wa:runtime_setter"
,
"//wa:runtime_setter"
:
info
.
RuntimeSetter
=
true
case
"#wa:runtime_sizer"
:
info
.
RuntimeSizer
=
true
case
"#wa:wasm-module"
,
"//wa:wasm-module"
:
if
len
(
parts
)
>=
2
{
...
...
internal/backends/compiler_wat/compile.go
浏览文件 @
9dc08a73
...
...
@@ -19,6 +19,7 @@ type Compiler struct {
ssaPkg
*
ssa
.
Package
module
*
wir
.
Module
tLib
*
typeLib
}
func
New
()
*
Compiler
{
...
...
@@ -33,6 +34,8 @@ func (p *Compiler) Compile(prog *loader.Program, mainFunc string) (output string
p
.
prog
=
prog
p
.
CompileWsFiles
(
prog
)
p
.
tLib
=
newTypeLib
(
p
.
module
,
prog
.
SSAProgram
)
for
_
,
pkg
:=
range
prog
.
Pkgs
{
p
.
ssaPkg
=
pkg
.
SSAPkg
p
.
CompilePkgConst
(
pkg
.
SSAPkg
)
...
...
@@ -40,7 +43,12 @@ func (p *Compiler) Compile(prog *loader.Program, mainFunc string) (output string
for
_
,
pkg
:=
range
prog
.
Pkgs
{
p
.
ssaPkg
=
pkg
.
SSAPkg
p
.
CompilePkgGlocal
(
pkg
.
SSAPkg
)
p
.
CompilePkgType
(
pkg
.
SSAPkg
)
}
for
_
,
pkg
:=
range
prog
.
Pkgs
{
p
.
ssaPkg
=
pkg
.
SSAPkg
p
.
CompilePkgGlobal
(
pkg
.
SSAPkg
)
}
for
_
,
pkg
:=
range
prog
.
Pkgs
{
...
...
@@ -48,6 +56,8 @@ func (p *Compiler) Compile(prog *loader.Program, mainFunc string) (output string
p
.
CompilePkgFunc
(
pkg
.
SSAPkg
)
}
p
.
tLib
.
buildItab
()
{
var
f
wir
.
Function
f
.
InternalName
,
f
.
ExternalName
=
"_start"
,
"_start"
...
...
@@ -112,7 +122,15 @@ func (p *Compiler) CompilePkgConst(ssaPkg *ssa.Package) {
}
}
func
(
p
*
Compiler
)
CompilePkgGlocal
(
ssaPkg
*
ssa
.
Package
)
{
func
(
p
*
Compiler
)
CompilePkgType
(
ssaPkg
*
ssa
.
Package
)
{
for
_
,
m
:=
range
p
.
ssaPkg
.
Members
{
if
t
,
ok
:=
m
.
(
*
ssa
.
Type
);
ok
{
p
.
compileType
(
t
)
}
}
}
func
(
p
*
Compiler
)
CompilePkgGlobal
(
ssaPkg
*
ssa
.
Package
)
{
for
_
,
m
:=
range
p
.
ssaPkg
.
Members
{
if
global
,
ok
:=
m
.
(
*
ssa
.
Global
);
ok
{
p
.
compileGlobal
(
global
)
...
...
@@ -121,48 +139,33 @@ func (p *Compiler) CompilePkgGlocal(ssaPkg *ssa.Package) {
}
func
(
p
*
Compiler
)
CompilePkgFunc
(
ssaPkg
*
ssa
.
Package
)
{
var
fns
[]
*
ssa
.
Function
for
_
,
m
:=
range
p
.
ssaPkg
.
Members
{
if
fn
,
ok
:=
m
.
(
*
ssa
.
Function
);
ok
{
fns
=
append
(
fns
,
fn
)
p
.
CompileFunc
(
fn
,
p
.
tLib
,
p
.
module
)
}
}
}
for
_
,
v
:=
range
ssaPkg
.
GetValues
()
{
if
f
,
ok
:=
v
.
(
*
ssa
.
Function
);
ok
{
found
:=
false
for
_
,
m
:=
range
fns
{
if
m
.
Object
()
==
f
.
Object
()
{
found
=
true
}
}
if
found
{
continue
func
(
p
*
Compiler
)
CompileFunc
(
f
*
ssa
.
Function
,
tLib
*
typeLib
,
module
*
wir
.
Module
)
{
if
len
(
f
.
Blocks
)
<
1
{
if
f
.
RuntimeGetter
()
{
module
.
AddFunc
(
newFunctionGenerator
(
module
,
tLib
)
.
genGetter
(
f
))
}
else
if
f
.
RuntimeSetter
()
{
module
.
AddFunc
(
newFunctionGenerator
(
p
.
prog
,
module
,
tLib
)
.
genSetter
(
f
))
}
else
if
f
.
RuntimeSizer
()
{
module
.
AddFunc
(
newFunctionGenerator
(
p
.
prog
,
module
,
tLib
)
.
genSizer
(
f
))
}
else
if
iname0
,
iname1
:=
f
.
ImportName
();
len
(
iname0
)
>
0
&&
len
(
iname1
)
>
0
{
var
fn_name
string
if
len
(
f
.
LinkName
())
>
0
{
fn_name
=
f
.
LinkName
()
}
else
{
fn_name
,
_
=
wir
.
GetFnMangleName
(
f
)
}
fns
=
append
(
fns
,
f
)
}
}
for
_
,
v
:=
range
fns
{
if
len
(
v
.
Blocks
)
<
1
{
if
v
.
RuntimeGetter
()
{
p
.
module
.
AddFunc
(
newFunctionGenerator
(
p
.
prog
,
p
.
module
)
.
genGetter
(
v
))
}
else
if
v
.
RuntimeSetter
()
{
p
.
module
.
AddFunc
(
newFunctionGenerator
(
p
.
prog
,
p
.
module
)
.
genSetter
(
v
))
}
else
if
iname0
,
iname1
:=
v
.
ImportName
();
len
(
iname0
)
>
0
&&
len
(
iname1
)
>
0
{
var
fn_name
string
if
len
(
v
.
LinkName
())
>
0
{
fn_name
=
v
.
LinkName
()
}
else
{
fn_name
,
_
=
GetFnMangleName
(
v
)
}
sig
:=
p
.
module
.
GenFnSig
(
v
.
Signature
)
p
.
module
.
AddImportFunc
(
iname0
,
iname1
,
fn_name
,
sig
)
}
continue
sig
:=
tLib
.
GenFnSig
(
f
.
Signature
)
module
.
AddImportFunc
(
iname0
,
iname1
,
fn_name
,
sig
)
}
p
.
module
.
AddFunc
(
newFunctionGenerator
(
p
.
prog
,
p
.
module
)
.
genFunction
(
v
))
return
}
module
.
AddFunc
(
newFunctionGenerator
(
p
.
prog
,
module
,
tLib
)
.
genFunction
(
f
))
}
internal/backends/compiler_wat/compile_func.go
浏览文件 @
9dc08a73
...
...
@@ -25,6 +25,7 @@ type valueWrap struct {
type
functionGenerator
struct
{
prog
*
loader
.
Program
module
*
wir
.
Module
tLib
*
typeLib
locals_map
map
[
ssa
.
Value
]
valueWrap
...
...
@@ -36,8 +37,8 @@ type functionGenerator struct {
var_rets
[]
wir
.
Value
}
func
newFunctionGenerator
(
prog
*
loader
.
Program
,
module
*
wir
.
Module
)
*
functionGenerator
{
return
&
functionGenerator
{
prog
:
prog
,
module
:
module
,
locals_map
:
make
(
map
[
ssa
.
Value
]
valueWrap
)}
func
newFunctionGenerator
(
prog
*
loader
.
Program
,
module
*
wir
.
Module
,
tLib
*
typeLib
)
*
functionGenerator
{
return
&
functionGenerator
{
prog
:
prog
,
module
:
module
,
tLib
:
tLib
,
locals_map
:
make
(
map
[
ssa
.
Value
]
valueWrap
)}
}
func
(
g
*
functionGenerator
)
getValue
(
i
ssa
.
Value
)
valueWrap
{
...
...
@@ -49,16 +50,12 @@ func (g *functionGenerator) getValue(i ssa.Value) valueWrap {
return
v
}
if
v
,
ok
:=
g
.
module
.
Globals_map
[
i
];
ok
{
if
v
:=
g
.
module
.
FindGlobalByValue
(
i
);
v
!=
nil
{
return
valueWrap
{
value
:
v
}
}
switch
v
:=
i
.
(
type
)
{
case
*
ssa
.
Const
:
//if v.Value == nil {
// return nil
//}
switch
t
:=
v
.
Type
()
.
(
type
)
{
case
*
types
.
Basic
:
switch
t
.
Kind
()
{
...
...
@@ -90,7 +87,7 @@ func (g *functionGenerator) getValue(i ssa.Value) valueWrap {
val
,
_
:=
constant
.
Uint64Val
(
v
.
Value
)
return
valueWrap
{
value
:
wir
.
NewConst
(
strconv
.
Itoa
(
int
(
val
)),
g
.
module
.
I16
)}
case
types
.
Uint32
:
case
types
.
Uint32
,
types
.
Uintptr
:
val
,
_
:=
constant
.
Uint64Val
(
v
.
Value
)
return
valueWrap
{
value
:
wir
.
NewConst
(
strconv
.
Itoa
(
int
(
val
)),
g
.
module
.
U32
)}
...
...
@@ -120,14 +117,15 @@ func (g *functionGenerator) getValue(i ssa.Value) valueWrap {
case
*
types
.
Pointer
:
if
v
.
Value
==
nil
{
return
valueWrap
{}
p_type
:=
g
.
tLib
.
compile
(
t
)
return
valueWrap
{
value
:
wir
.
NewConst
(
"0"
,
p_type
)}
}
else
{
logger
.
Fatalf
(
"Todo:%T"
,
t
)
}
case
*
types
.
Slice
:
if
v
.
Value
==
nil
{
return
valueWrap
{
value
:
wir
.
NewConst
(
"0"
,
g
.
module
.
GenValueTyp
e
(
t
))}
return
valueWrap
{
value
:
wir
.
NewConst
(
"0"
,
g
.
tLib
.
compil
e
(
t
))}
}
logger
.
Fatalf
(
"Todo:%T"
,
t
)
...
...
@@ -136,20 +134,20 @@ func (g *functionGenerator) getValue(i ssa.Value) valueWrap {
}
case
ssa
.
Instruction
:
nv
:=
valueWrap
{
value
:
g
.
addRegister
(
g
.
module
.
GenValueTyp
e
(
i
.
Type
()))}
nv
:=
valueWrap
{
value
:
g
.
addRegister
(
g
.
tLib
.
compil
e
(
i
.
Type
()))}
g
.
locals_map
[
i
]
=
nv
return
nv
case
*
ssa
.
Function
:
fn_name
,
_
:=
GetFnMangleName
(
v
)
fn_name
,
_
:=
wir
.
GetFnMangleName
(
v
)
if
v
.
Parent
()
!=
nil
{
if
g
.
module
.
FindFunc
(
fn_name
)
==
nil
{
g
.
module
.
AddFunc
(
newFunctionGenerator
(
g
.
prog
,
g
.
module
)
.
genFunction
(
v
))
g
.
module
.
AddFunc
(
newFunctionGenerator
(
g
.
prog
,
g
.
module
,
g
.
tLib
)
.
genFunction
(
v
))
}
}
return
valueWrap
{
value
:
g
.
module
.
GenConstFnValue
(
fn_name
,
v
.
Signature
)}
return
valueWrap
{
value
:
g
.
module
.
GenConstFnValue
(
fn_name
,
g
.
tLib
.
GenFnSig
(
v
.
Signature
)
)}
}
logger
.
Fatal
(
"Value not found:"
,
i
)
...
...
@@ -159,7 +157,7 @@ func (g *functionGenerator) getValue(i ssa.Value) valueWrap {
func
(
g
*
functionGenerator
)
genFunction
(
f
*
ssa
.
Function
)
*
wir
.
Function
{
var
wir_fn
wir
.
Function
{
internal
,
external
:=
GetFnMangleName
(
f
)
internal
,
external
:=
wir
.
GetFnMangleName
(
f
)
if
len
(
f
.
LinkName
())
>
0
{
wir_fn
.
InternalName
=
f
.
LinkName
()
}
else
{
...
...
@@ -178,22 +176,20 @@ func (g *functionGenerator) genFunction(f *ssa.Function) *wir.Function {
break
case
1
:
wir_fn
.
Results
=
append
(
wir_fn
.
Results
,
g
.
module
.
GenValueTyp
e
(
rets
.
At
(
0
)
.
Type
()))
wir_fn
.
Results
=
append
(
wir_fn
.
Results
,
g
.
tLib
.
compil
e
(
rets
.
At
(
0
)
.
Type
()))
default
:
typ
:=
g
.
module
.
GenValueType
(
rets
)
.
(
*
wir
.
Tuple
)
for
_
,
f
:=
range
typ
.
Members
{
wir_fn
.
Results
=
append
(
wir_fn
.
Results
,
f
.
Type
())
}
typ
:=
g
.
tLib
.
compile
(
rets
)
.
(
*
wir
.
Tuple
)
wir_fn
.
Results
=
append
(
wir_fn
.
Results
,
typ
.
Fields
...
)
}
for
_
,
i
:=
range
f
.
FreeVars
{
fv
:=
valueWrap
{
value
:
wir
.
NewLocal
(
wir
.
GenSymbolName
(
i
.
Name
()),
g
.
module
.
GenValueTyp
e
(
i
.
Type
()))}
fv
:=
valueWrap
{
value
:
wir
.
NewLocal
(
wir
.
GenSymbolName
(
i
.
Name
()),
g
.
tLib
.
compil
e
(
i
.
Type
()))}
wir_fn
.
Params
=
append
(
wir_fn
.
Params
,
fv
.
value
)
g
.
locals_map
[
i
]
=
fv
}
for
_
,
i
:=
range
f
.
Params
{
pv
:=
valueWrap
{
value
:
wir
.
NewLocal
(
wir
.
GenSymbolName
(
i
.
Name
()),
g
.
module
.
GenValueTyp
e
(
i
.
Type
()))}
pv
:=
valueWrap
{
value
:
wir
.
NewLocal
(
wir
.
GenSymbolName
(
i
.
Name
()),
g
.
tLib
.
compil
e
(
i
.
Type
()))}
wir_fn
.
Params
=
append
(
wir_fn
.
Params
,
pv
.
value
)
g
.
locals_map
[
i
]
=
pv
}
...
...
@@ -334,6 +330,9 @@ func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
// logger.Printf("Instruction already exist:%s\n", v)
//}
//Todo: 下面的做法过于粗暴
g
.
tLib
.
compile
(
v
.
Type
())
switch
v
:=
v
.
(
type
)
{
case
*
ssa
.
UnOp
:
return
g
.
genUnOp
(
v
)
...
...
@@ -382,6 +381,9 @@ func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
case
*
ssa
.
MakeClosure
:
return
g
.
genMakeClosre
(
v
)
case
*
ssa
.
MakeInterface
:
return
g
.
genInterface
(
v
)
}
logger
.
Fatalf
(
"Todo: %v, type: %T"
,
v
,
v
)
...
...
@@ -455,24 +457,43 @@ func (g *functionGenerator) genBinOp(inst *ssa.BinOp) ([]wat.Inst, wir.ValueType
func
(
g
*
functionGenerator
)
genCall
(
inst
*
ssa
.
Call
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
if
inst
.
Call
.
IsInvoke
()
{
logger
.
Fatal
(
"Todo: genCall(), Invoke"
)
ret_type
=
g
.
tLib
.
compile
(
inst
.
Call
.
Signature
()
.
Results
())
t
:=
g
.
tLib
.
find
(
inst
.
Call
.
Value
.
Type
())
for
id
,
m
:=
range
t
.
methods
{
if
m
.
name
==
inst
.
Call
.
Method
.
Name
()
{
iface
:=
g
.
getValue
(
inst
.
Call
.
Value
)
var
params
[]
wir
.
Value
for
_
,
v
:=
range
inst
.
Call
.
Args
{
params
=
append
(
params
,
g
.
getValue
(
v
)
.
value
)
}
insts
=
append
(
insts
,
g
.
module
.
EmitInvoke
(
iface
.
value
,
params
,
id
,
m
.
fullFnName
)
...
)
break
}
}
return
//logger.Fatal("Todo: genCall(), Invoke")
}
switch
inst
.
Call
.
Value
.
(
type
)
{
case
*
ssa
.
Function
:
ret_type
=
g
.
module
.
GenValueTyp
e
(
inst
.
Call
.
Signature
()
.
Results
())
ret_type
=
g
.
tLib
.
compil
e
(
inst
.
Call
.
Signature
()
.
Results
())
for
_
,
v
:=
range
inst
.
Call
.
Args
{
insts
=
append
(
insts
,
g
.
getValue
(
v
)
.
value
.
EmitPush
()
...
)
}
callee
:=
inst
.
Call
.
StaticCallee
()
if
callee
.
Parent
()
!=
nil
{
g
.
module
.
AddFunc
(
newFunctionGenerator
(
g
.
prog
,
g
.
module
)
.
genFunction
(
callee
))
g
.
module
.
AddFunc
(
newFunctionGenerator
(
g
.
prog
,
g
.
module
,
g
.
tLib
)
.
genFunction
(
callee
))
}
if
len
(
callee
.
LinkName
())
>
0
{
insts
=
append
(
insts
,
wat
.
NewInstCall
(
callee
.
LinkName
()))
}
else
{
fn_internal_name
,
_
:=
GetFnMangleName
(
callee
)
fn_internal_name
,
_
:=
wir
.
GetFnMangleName
(
callee
)
insts
=
append
(
insts
,
wat
.
NewInstCall
(
fn_internal_name
))
}
...
...
@@ -480,7 +501,7 @@ func (g *functionGenerator) genCall(inst *ssa.Call) (insts []wat.Inst, ret_type
return
g
.
genBuiltin
(
inst
.
Common
())
case
*
ssa
.
MakeClosure
:
ret_type
=
g
.
module
.
GenValueTyp
e
(
inst
.
Type
())
ret_type
=
g
.
tLib
.
compil
e
(
inst
.
Type
())
var
params
[]
wir
.
Value
for
_
,
v
:=
range
inst
.
Call
.
Args
{
params
=
append
(
params
,
g
.
getValue
(
v
)
.
value
)
...
...
@@ -489,7 +510,7 @@ func (g *functionGenerator) genCall(inst *ssa.Call) (insts []wat.Inst, ret_type
insts
=
wir
.
EmitCallClosure
(
closure
.
value
,
params
)
default
:
ret_type
=
g
.
module
.
GenValueTyp
e
(
inst
.
Type
())
ret_type
=
g
.
tLib
.
compil
e
(
inst
.
Type
())
var
params
[]
wir
.
Value
for
_
,
v
:=
range
inst
.
Call
.
Args
{
params
=
append
(
params
,
g
.
getValue
(
v
)
.
value
)
...
...
@@ -626,7 +647,7 @@ func (g *functionGenerator) genPhi(inst *ssa.Phi) ([]wat.Inst, wir.ValueType) {
preds
=
append
(
preds
,
inst
.
Block
()
.
Preds
[
i
]
.
Index
)
values
=
append
(
values
,
g
.
getValue
(
v
)
.
value
)
}
return
g
.
genPhiIter
(
preds
,
values
),
g
.
module
.
GenValueTyp
e
(
inst
.
Type
())
return
g
.
genPhiIter
(
preds
,
values
),
g
.
tLib
.
compil
e
(
inst
.
Type
())
}
func
(
g
*
functionGenerator
)
genReturn
(
inst
*
ssa
.
Return
)
[]
wat
.
Inst
{
...
...
@@ -700,7 +721,7 @@ func (g *functionGenerator) genJumpID(cur, dest int) []wat.Inst {
}
func
(
g
*
functionGenerator
)
genAlloc
(
inst
*
ssa
.
Alloc
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
typ
:=
g
.
module
.
GenValueTyp
e
(
inst
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
())
typ
:=
g
.
tLib
.
compil
e
(
inst
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
())
if
inst
.
Parent
()
.
ForceRegister
()
{
nv
:=
g
.
addRegister
(
typ
)
g
.
locals_map
[
inst
]
=
valueWrap
{
value
:
nv
,
force_register
:
true
}
...
...
@@ -803,7 +824,7 @@ func (g *functionGenerator) genMakeSlice(inst *ssa.MakeSlice) ([]wat.Inst, wir.V
}
elem
:=
inst
.
Type
()
.
(
*
types
.
Slice
)
.
Elem
()
base_type
:=
g
.
module
.
GenValueTyp
e
(
elem
)
base_type
:=
g
.
tLib
.
compil
e
(
elem
)
Len
:=
g
.
getValue
(
inst
.
Len
)
Cap
:=
g
.
getValue
(
inst
.
Cap
)
return
g
.
module
.
EmitGenMakeSlice
(
base_type
,
Len
.
value
,
Cap
.
value
)
...
...
@@ -818,13 +839,13 @@ func (g *functionGenerator) genLookup(inst *ssa.Lookup) ([]wat.Inst, wir.ValueTy
func
(
g
*
functionGenerator
)
genConvert
(
inst
*
ssa
.
Convert
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
x
:=
g
.
getValue
(
inst
.
X
)
ret_type
=
g
.
module
.
GenValueTyp
e
(
inst
.
Type
())
ret_type
=
g
.
tLib
.
compil
e
(
inst
.
Type
())
insts
=
g
.
module
.
EmitGenConvert
(
x
.
value
,
ret_type
)
return
}
func
(
g
*
functionGenerator
)
genChangeType
(
inst
*
ssa
.
ChangeType
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
ret_type
=
g
.
module
.
GenValueTyp
e
(
inst
.
Type
())
ret_type
=
g
.
tLib
.
compil
e
(
inst
.
Type
())
x
:=
g
.
getValue
(
inst
.
X
)
insts
=
append
(
insts
,
x
.
value
.
EmitPush
()
...
)
return
...
...
@@ -847,10 +868,10 @@ func (g *functionGenerator) genMakeClosre(inst *ssa.MakeClosure) (insts []wat.In
func
(
g
*
functionGenerator
)
genMakeClosre_Anonymous
(
inst
*
ssa
.
MakeClosure
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
f
:=
inst
.
Fn
.
(
*
ssa
.
Function
)
g
.
module
.
AddFunc
(
newFunctionGenerator
(
g
.
prog
,
g
.
module
)
.
genFunction
(
f
))
g
.
module
.
AddFunc
(
newFunctionGenerator
(
g
.
prog
,
g
.
module
,
g
.
tLib
)
.
genFunction
(
f
))
ret_type
=
g
.
module
.
GenValueType_Closure
(
f
.
Signature
)
if
!
ret_type
.
Equal
(
g
.
module
.
GenValueTyp
e
(
inst
.
Type
()))
{
ret_type
=
g
.
module
.
GenValueType_Closure
(
g
.
tLib
.
GenFnSig
(
f
.
Signature
)
)
if
!
ret_type
.
Equal
(
g
.
tLib
.
compil
e
(
inst
.
Type
()))
{
panic
(
"ret_type != inst.Type()"
)
}
...
...
@@ -858,10 +879,10 @@ func (g *functionGenerator) genMakeClosre_Anonymous(inst *ssa.MakeClosure) (inst
{
var
fields
[]
wir
.
Field
for
_
,
freevar
:=
range
f
.
FreeVars
{
feild
:=
wir
.
NewField
(
freevar
.
Name
(),
g
.
module
.
GenValueTyp
e
(
freevar
.
Type
()))
feild
:=
wir
.
NewField
(
freevar
.
Name
(),
g
.
tLib
.
compil
e
(
freevar
.
Type
()))
fields
=
append
(
fields
,
feild
)
}
fn_internal_name
,
_
:=
GetFnMangleName
(
f
)
fn_internal_name
,
_
:=
wir
.
GetFnMangleName
(
f
)
st_name
:=
fn_internal_name
+
".$warpdata"
st_free_data
=
g
.
module
.
GenValueType_Struct
(
st_name
,
fields
)
}
...
...
@@ -869,15 +890,15 @@ func (g *functionGenerator) genMakeClosre_Anonymous(inst *ssa.MakeClosure) (inst
var
warp_fn_index
int
{
var
warp_fn
wir
.
Function
fn_name
,
_
:=
GetFnMangleName
(
f
)
fn_name
,
_
:=
wir
.
GetFnMangleName
(
f
)
warp_fn
.
InternalName
=
fn_name
+
".$warpfn"
for
_
,
i
:=
range
f
.
Params
{
pa
:=
valueWrap
{
value
:
wir
.
NewLocal
(
i
.
Name
(),
g
.
module
.
GenValueTyp
e
(
i
.
Type
()))}
pa
:=
valueWrap
{
value
:
wir
.
NewLocal
(
i
.
Name
(),
g
.
tLib
.
compil
e
(
i
.
Type
()))}
warp_fn
.
Params
=
append
(
warp_fn
.
Params
,
pa
.
value
)
}
warp_fn
.
Results
=
g
.
module
.
GenFnSig
(
f
.
Signature
)
.
Results
warp_fn
.
Results
=
g
.
tLib
.
GenFnSig
(
f
.
Signature
)
.
Results
dx
:=
g
.
module
.
FindGlobal
(
"$wa.RT.closure_data"
)
dx
:=
g
.
module
.
FindGlobal
ByName
(
"$wa.RT.closure_data"
)
data_ptr
:=
wir
.
ExtractField
(
dx
,
"data"
)
warp_fn
.
Insts
=
append
(
warp_fn
.
Insts
,
st_free_data
.
EmitLoadFromAddr
(
data_ptr
,
0
)
...
)
...
...
@@ -894,7 +915,7 @@ func (g *functionGenerator) genMakeClosre_Anonymous(inst *ssa.MakeClosure) (inst
warp_fn_index
=
g
.
module
.
AddTableElem
(
warp_fn
.
InternalName
)
}
closure
:=
g
.
addRegister
(
g
.
module
.
GenValueType_Closure
(
f
.
Signature
))
closure
:=
g
.
addRegister
(
g
.
module
.
GenValueType_Closure
(
g
.
tLib
.
GenFnSig
(
f
.
Signature
)
))
free_data
:=
g
.
addRegister
(
st_free_data
)
{
...
...
@@ -923,25 +944,25 @@ func (g *functionGenerator) genMakeClosre_Anonymous(inst *ssa.MakeClosure) (inst
func
(
g
*
functionGenerator
)
genMakeClosre_Bound
(
inst
*
ssa
.
MakeClosure
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
f
:=
inst
.
Fn
.
(
*
ssa
.
Function
)
ret_type
=
g
.
module
.
GenValueType_Closure
(
f
.
Signature
)
if
!
ret_type
.
Equal
(
g
.
module
.
GenValueTyp
e
(
inst
.
Type
()))
{
ret_type
=
g
.
module
.
GenValueType_Closure
(
g
.
tLib
.
GenFnSig
(
f
.
Signature
)
)
if
!
ret_type
.
Equal
(
g
.
tLib
.
compil
e
(
inst
.
Type
()))
{
panic
(
"ret_type != inst.Type()"
)
}
recv_type
:=
g
.
module
.
GenValueTyp
e
(
f
.
FreeVars
[
0
]
.
Type
())
recv_type
:=
g
.
tLib
.
compil
e
(
f
.
FreeVars
[
0
]
.
Type
())
var
warp_fn_index
int
{
var
warp_fn
wir
.
Function
fn_name
,
_
:=
GetFnMangleName
(
f
.
Object
())
fn_name
,
_
:=
wir
.
GetFnMangleName
(
f
.
Object
())
warp_fn
.
InternalName
=
fn_name
+
".$bound"
for
_
,
i
:=
range
f
.
Params
{
pa
:=
valueWrap
{
value
:
wir
.
NewLocal
(
i
.
Name
(),
g
.
module
.
GenValueTyp
e
(
i
.
Type
()))}
pa
:=
valueWrap
{
value
:
wir
.
NewLocal
(
i
.
Name
(),
g
.
tLib
.
compil
e
(
i
.
Type
()))}
warp_fn
.
Params
=
append
(
warp_fn
.
Params
,
pa
.
value
)
}
warp_fn
.
Results
=
g
.
module
.
GenFnSig
(
f
.
Signature
)
.
Results
warp_fn
.
Results
=
g
.
tLib
.
GenFnSig
(
f
.
Signature
)
.
Results
dx
:=
g
.
module
.
FindGlobal
(
"$wa.RT.closure_data"
)
dx
:=
g
.
module
.
FindGlobal
ByName
(
"$wa.RT.closure_data"
)
data_ptr
:=
wir
.
ExtractField
(
dx
,
"data"
)
warp_fn
.
Insts
=
append
(
warp_fn
.
Insts
,
recv_type
.
EmitLoadFromAddr
(
data_ptr
,
0
)
...
)
...
...
@@ -958,7 +979,7 @@ func (g *functionGenerator) genMakeClosre_Bound(inst *ssa.MakeClosure) (insts []
warp_fn_index
=
g
.
module
.
AddTableElem
(
warp_fn
.
InternalName
)
}
closure
:=
g
.
addRegister
(
g
.
module
.
GenValueType_Closure
(
f
.
Signature
))
closure
:=
g
.
addRegister
(
g
.
module
.
GenValueType_Closure
(
g
.
tLib
.
GenFnSig
(
f
.
Signature
)
))
insts
=
append
(
insts
,
wir
.
NewConst
(
strconv
.
Itoa
(
warp_fn_index
),
g
.
module
.
U32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wir
.
ExtractField
(
closure
,
"fn_index"
)
.
EmitPop
()
...
)
...
...
@@ -975,6 +996,16 @@ func (g *functionGenerator) genMakeClosre_Bound(inst *ssa.MakeClosure) (insts []
return
}
func
(
g
*
functionGenerator
)
genInterface
(
inst
*
ssa
.
MakeInterface
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
x
:=
g
.
getValue
(
inst
.
X
)
g
.
tLib
.
markConcreteTypeUsed
(
inst
.
X
.
Type
())
ret_type
=
g
.
tLib
.
compile
(
inst
.
Type
())
g
.
tLib
.
markInterfaceUsed
(
inst
.
Type
())
insts
=
g
.
module
.
EmitGenMakeInterface
(
x
.
value
,
ret_type
)
return
}
func
(
g
*
functionGenerator
)
addRegister
(
typ
wir
.
ValueType
)
wir
.
Value
{
defer
func
()
{
g
.
cur_local_id
++
}()
name
:=
"$T_"
+
strconv
.
Itoa
(
g
.
cur_local_id
)
...
...
@@ -989,7 +1020,7 @@ func (g *functionGenerator) genGetter(f *ssa.Function) *wir.Function {
wir_fn
.
InternalName
=
f
.
LinkName
()
wir_fn
.
ExternalName
=
f
.
LinkName
()
}
else
{
wir_fn
.
InternalName
,
wir_fn
.
ExternalName
=
GetFnMangleName
(
f
)
wir_fn
.
InternalName
,
wir_fn
.
ExternalName
=
wir
.
GetFnMangleName
(
f
)
}
rets
:=
f
.
Signature
.
Results
()
...
...
@@ -997,14 +1028,14 @@ func (g *functionGenerator) genGetter(f *ssa.Function) *wir.Function {
logger
.
Fatal
(
"rets.Len() > 1"
)
return
nil
}
rtype
:=
g
.
module
.
GenValueTyp
e
(
rets
)
rtype
:=
g
.
tLib
.
compil
e
(
rets
)
wir_fn
.
Results
=
append
(
wir_fn
.
Results
,
rtype
)
if
len
(
f
.
Params
)
!=
1
{
logger
.
Fatal
(
"len(f.Params) != 1"
)
return
nil
}
if
!
g
.
module
.
GenValueTyp
e
(
f
.
Params
[
0
]
.
Type
())
.
Equal
(
g
.
module
.
U32
)
{
if
!
g
.
tLib
.
compil
e
(
f
.
Params
[
0
]
.
Type
())
.
Equal
(
g
.
module
.
U32
)
{
logger
.
Fatal
(
"addr_type != U32"
)
return
nil
}
...
...
@@ -1023,7 +1054,7 @@ func (g *functionGenerator) genSetter(f *ssa.Function) *wir.Function {
wir_fn
.
InternalName
=
f
.
LinkName
()
wir_fn
.
ExternalName
=
f
.
LinkName
()
}
else
{
wir_fn
.
InternalName
,
wir_fn
.
ExternalName
=
GetFnMangleName
(
f
)
wir_fn
.
InternalName
,
wir_fn
.
ExternalName
=
wir
.
GetFnMangleName
(
f
)
}
rets
:=
f
.
Signature
.
Results
()
...
...
@@ -1036,12 +1067,12 @@ func (g *functionGenerator) genSetter(f *ssa.Function) *wir.Function {
logger
.
Fatal
(
"len(f.Params) != 2"
)
return
nil
}
if
!
g
.
module
.
GenValueTyp
e
(
f
.
Params
[
0
]
.
Type
())
.
Equal
(
g
.
module
.
U32
)
{
if
!
g
.
tLib
.
compil
e
(
f
.
Params
[
0
]
.
Type
())
.
Equal
(
g
.
module
.
U32
)
{
logger
.
Fatal
(
"addr_type != U32"
)
return
nil
}
value_type
:=
g
.
module
.
GenValueTyp
e
(
f
.
Params
[
1
]
.
Type
())
value_type
:=
g
.
tLib
.
compil
e
(
f
.
Params
[
1
]
.
Type
())
addr
:=
wir
.
NewLocal
(
"addr"
,
g
.
module
.
GenValueType_Ptr
(
value_type
))
wir_fn
.
Params
=
append
(
wir_fn
.
Params
,
addr
)
...
...
@@ -1054,3 +1085,32 @@ func (g *functionGenerator) genSetter(f *ssa.Function) *wir.Function {
return
&
wir_fn
}
func
(
g
*
functionGenerator
)
genSizer
(
f
*
ssa
.
Function
)
*
wir
.
Function
{
var
wir_fn
wir
.
Function
if
len
(
f
.
LinkName
())
>
0
{
wir_fn
.
InternalName
=
f
.
LinkName
()
wir_fn
.
ExternalName
=
f
.
LinkName
()
}
else
{
wir_fn
.
InternalName
,
wir_fn
.
ExternalName
=
wir
.
GetFnMangleName
(
f
)
}
rets
:=
f
.
Signature
.
Results
()
if
rets
.
Len
()
!=
1
{
logger
.
Fatal
(
"rets.Len() != 1"
)
return
nil
}
rtype
:=
g
.
tLib
.
compile
(
rets
)
wir_fn
.
Results
=
append
(
wir_fn
.
Results
,
rtype
)
if
len
(
f
.
Params
)
!=
1
{
logger
.
Fatal
(
"len(f.Params) != 1"
)
return
nil
}
value_type
:=
g
.
tLib
.
compile
(
f
.
Params
[
0
]
.
Type
())
t_size
:=
value_type
.
(
*
wir
.
Ref
)
.
Base
.
Size
()
wir_fn
.
Insts
=
append
(
wir_fn
.
Insts
,
wir
.
NewConst
(
strconv
.
Itoa
(
t_size
),
g
.
module
.
I32
)
.
EmitPush
()
...
)
return
&
wir_fn
}
internal/backends/compiler_wat/compile_global.go
浏览文件 @
9dc08a73
...
...
@@ -10,13 +10,13 @@ import (
func
(
p
*
Compiler
)
compileGlobal
(
g
*
ssa
.
Global
)
{
if
len
(
g
.
LinkName
())
>
0
{
p
.
module
.
AddGlobal
(
g
.
LinkName
(),
p
.
module
.
GenValueTyp
e
(
g
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
()),
false
,
g
)
p
.
module
.
AddGlobal
(
g
.
LinkName
(),
p
.
tLib
.
compil
e
(
g
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
()),
false
,
g
)
}
else
{
pkg_name
,
_
:=
wir
.
GetPkgMangleName
(
g
.
Pkg
.
Pkg
.
Path
())
if
g
.
Name
()
==
"init$guard"
{
p
.
module
.
AddGlobal
(
pkg_name
+
"."
+
g
.
Name
(),
p
.
module
.
GenValueTyp
e
(
g
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
()),
false
,
g
)
p
.
module
.
AddGlobal
(
pkg_name
+
"."
+
g
.
Name
(),
p
.
tLib
.
compil
e
(
g
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
()),
false
,
g
)
}
else
{
p
.
module
.
AddGlobal
(
pkg_name
+
"."
+
wir
.
GenSymbolName
(
g
.
Name
()),
p
.
module
.
GenValueType_Ref
(
p
.
module
.
GenValueTyp
e
(
g
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
())),
true
,
g
)
p
.
module
.
AddGlobal
(
pkg_name
+
"."
+
wir
.
GenSymbolName
(
g
.
Name
()),
p
.
module
.
GenValueType_Ref
(
p
.
tLib
.
compil
e
(
g
.
Type
()
.
(
*
types
.
Pointer
)
.
Elem
())),
true
,
g
)
}
}
//logger.Fatal("Todo")
...
...
internal/backends/compiler_wat/compile_type.go
浏览文件 @
9dc08a73
...
...
@@ -3,9 +3,308 @@
package
compiler_wat
import
(
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir"
"wa-lang.org/wa/internal/logger"
"wa-lang.org/wa/internal/ssa"
"wa-lang.org/wa/internal/types"
)
type
typeLib
struct
{
module
*
wir
.
Module
ssaProg
*
ssa
.
Program
typeTable
map
[
string
]
*
wrapType
usedConcreteTypes
[]
*
wrapType
usedInterfaces
[]
*
wrapType
}
type
wrapMethod
struct
{
sig
wir
.
FnSig
name
string
fullFnName
string
}
type
wrapType
struct
{
wirType
wir
.
ValueType
methods
[]
wrapMethod
}
func
newTypeLib
(
m
*
wir
.
Module
,
prog
*
ssa
.
Program
)
*
typeLib
{
te
:=
typeLib
{
module
:
m
,
ssaProg
:
prog
}
te
.
typeTable
=
make
(
map
[
string
]
*
wrapType
)
return
&
te
}
func
(
tLib
*
typeLib
)
find
(
v
types
.
Type
)
*
wrapType
{
if
v
,
ok
:=
tLib
.
typeTable
[
v
.
String
()];
ok
{
return
v
}
return
nil
}
func
(
tLib
*
typeLib
)
compile
(
from
types
.
Type
)
wir
.
ValueType
{
if
v
,
ok
:=
tLib
.
typeTable
[
from
.
String
()];
ok
{
return
v
.
wirType
}
//s := from.String()
//println(s)
var
newType
wrapType
tLib
.
typeTable
[
from
.
String
()]
=
&
newType
uncommanFlag
:=
false
switch
t
:=
from
.
(
type
)
{
case
*
types
.
Basic
:
switch
t
.
Kind
()
{
case
types
.
Bool
,
types
.
UntypedBool
,
types
.
Int
,
types
.
UntypedInt
:
newType
.
wirType
=
tLib
.
module
.
I32
case
types
.
Int32
:
if
t
.
Name
()
==
"rune"
{
newType
.
wirType
=
tLib
.
module
.
RUNE
}
else
{
newType
.
wirType
=
tLib
.
module
.
I32
}
case
types
.
Uint32
,
types
.
Uintptr
:
newType
.
wirType
=
tLib
.
module
.
U32
case
types
.
Int64
:
newType
.
wirType
=
tLib
.
module
.
I64
case
types
.
Uint64
:
newType
.
wirType
=
tLib
.
module
.
U64
case
types
.
Float32
,
types
.
UntypedFloat
:
newType
.
wirType
=
tLib
.
module
.
F32
case
types
.
Float64
:
newType
.
wirType
=
tLib
.
module
.
F64
case
types
.
Int8
:
newType
.
wirType
=
tLib
.
module
.
I8
case
types
.
Uint8
:
newType
.
wirType
=
tLib
.
module
.
U8
case
types
.
Int16
:
newType
.
wirType
=
tLib
.
module
.
I16
case
types
.
Uint16
:
newType
.
wirType
=
tLib
.
module
.
U16
case
types
.
String
:
newType
.
wirType
=
tLib
.
module
.
STRING
default
:
logger
.
Fatalf
(
"Unknown type:%s"
,
t
)
return
nil
}
case
*
types
.
Tuple
:
switch
t
.
Len
()
{
case
0
:
newType
.
wirType
=
tLib
.
module
.
VOID
case
1
:
newType
.
wirType
=
tLib
.
compile
(
t
.
At
(
0
)
.
Type
())
default
:
var
feilds
[]
wir
.
ValueType
for
i
:=
0
;
i
<
t
.
Len
();
i
++
{
feilds
=
append
(
feilds
,
tLib
.
compile
(
t
.
At
(
i
)
.
Type
()))
}
newType
.
wirType
=
tLib
.
module
.
GenValueType_Tuple
(
feilds
)
}
case
*
types
.
Pointer
:
newType
.
wirType
=
tLib
.
module
.
GenValueType_Ref
(
tLib
.
compile
(
t
.
Elem
()))
uncommanFlag
=
true
case
*
types
.
Named
:
switch
ut
:=
t
.
Underlying
()
.
(
type
)
{
case
*
types
.
Struct
:
//Todo: 待解决类型嵌套包含的问题
var
fs
[]
wir
.
Field
for
i
:=
0
;
i
<
ut
.
NumFields
();
i
++
{
f
:=
ut
.
Field
(
i
)
wtyp
:=
tLib
.
compile
(
f
.
Type
())
if
f
.
Embedded
()
{
fs
=
append
(
fs
,
wir
.
NewField
(
"$"
+
wtyp
.
Name
(),
wtyp
))
}
else
{
fs
=
append
(
fs
,
wir
.
NewField
(
wir
.
GenSymbolName
(
f
.
Name
()),
wtyp
))
}
}
pkg_name
,
_
:=
wir
.
GetPkgMangleName
(
t
.
Obj
()
.
Pkg
()
.
Path
())
obj_name
:=
wir
.
GenSymbolName
(
t
.
Obj
()
.
Name
())
tStruct
:=
tLib
.
module
.
GenValueType_Struct
(
pkg_name
+
"."
+
obj_name
,
fs
)
newType
.
wirType
=
tStruct
uncommanFlag
=
true
case
*
types
.
Interface
:
if
ut
.
NumMethods
()
==
0
{
return
tLib
.
compile
(
ut
)
}
pkg_name
,
_
:=
wir
.
GetPkgMangleName
(
t
.
Obj
()
.
Pkg
()
.
Path
())
obj_name
:=
wir
.
GenSymbolName
(
t
.
Obj
()
.
Name
())
for
i
:=
0
;
i
<
ut
.
NumMethods
();
i
++
{
var
method
wrapMethod
method
.
sig
=
tLib
.
GenFnSig
(
ut
.
Method
(
i
)
.
Type
()
.
(
*
types
.
Signature
))
method
.
name
=
ut
.
Method
(
i
)
.
Name
()
method
.
fullFnName
=
pkg_name
+
"."
+
obj_name
+
"."
+
method
.
name
newType
.
methods
=
append
(
newType
.
methods
,
method
)
var
fntype
wir
.
FnType
fntype
.
FnSig
.
Params
=
append
(
fntype
.
FnSig
.
Params
,
tLib
.
module
.
GenValueType_Ref
(
tLib
.
module
.
VOID
))
fntype
.
FnSig
.
Params
=
append
(
fntype
.
FnSig
.
Params
,
method
.
sig
.
Params
...
)
fntype
.
FnSig
.
Results
=
method
.
sig
.
Results
fntype
.
Name
=
method
.
fullFnName
tLib
.
module
.
AddFnType
(
&
fntype
)
}
newType
.
wirType
=
tLib
.
module
.
GenValueType_Interface
(
pkg_name
+
"."
+
obj_name
)
case
*
types
.
Signature
:
newType
.
wirType
=
tLib
.
module
.
GenValueType_Closure
(
tLib
.
GenFnSig
(
ut
))
default
:
logger
.
Fatalf
(
"Todo:%T"
,
ut
)
}
case
*
types
.
Array
:
newType
.
wirType
=
tLib
.
module
.
GenValueType_Array
(
tLib
.
compile
(
t
.
Elem
()),
int
(
t
.
Len
()))
case
*
types
.
Slice
:
newType
.
wirType
=
tLib
.
module
.
GenValueType_Slice
(
tLib
.
compile
(
t
.
Elem
()))
case
*
types
.
Signature
:
newType
.
wirType
=
tLib
.
module
.
GenValueType_Closure
(
tLib
.
GenFnSig
(
t
))
case
*
types
.
Interface
:
if
t
.
NumMethods
()
!=
0
{
panic
(
"NumMethods of interface{} != 0"
)
}
newType
.
wirType
=
tLib
.
module
.
GenValueType_Interface
(
"interface"
)
default
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
}
if
uncommanFlag
{
methodset
:=
tLib
.
ssaProg
.
MethodSets
.
MethodSet
(
from
)
for
i
:=
0
;
i
<
methodset
.
Len
();
i
++
{
sel
:=
methodset
.
At
(
i
)
mfn
:=
tLib
.
ssaProg
.
MethodValue
(
sel
)
CompileFunc
(
mfn
,
tLib
,
tLib
.
module
)
var
method
wrapMethod
method
.
name
=
mfn
.
Name
()
method
.
sig
=
tLib
.
GenFnSig
(
mfn
.
Signature
)
method
.
fullFnName
,
_
=
wir
.
GetFnMangleName
(
mfn
)
newType
.
methods
=
append
(
newType
.
methods
,
method
)
}
}
return
newType
.
wirType
}
func
(
tl
*
typeLib
)
GenFnSig
(
s
*
types
.
Signature
)
wir
.
FnSig
{
var
sig
wir
.
FnSig
for
i
:=
0
;
i
<
s
.
Params
()
.
Len
();
i
++
{
typ
:=
tl
.
compile
(
s
.
Params
()
.
At
(
i
)
.
Type
())
sig
.
Params
=
append
(
sig
.
Params
,
typ
)
}
for
i
:=
0
;
i
<
s
.
Results
()
.
Len
();
i
++
{
typ
:=
tl
.
compile
(
s
.
Results
()
.
At
(
i
)
.
Type
())
sig
.
Results
=
append
(
sig
.
Results
,
typ
)
}
return
sig
}
func
(
tLib
*
typeLib
)
markConcreteTypeUsed
(
t
types
.
Type
)
{
v
,
ok
:=
tLib
.
typeTable
[
t
.
String
()]
if
!
ok
{
logger
.
Fatal
(
"Type not found."
)
}
if
v
.
wirType
.
Hash
()
!=
0
{
return
}
tLib
.
usedConcreteTypes
=
append
(
tLib
.
usedConcreteTypes
,
v
)
v
.
wirType
.
SetHash
(
len
(
tLib
.
usedConcreteTypes
))
}
func
(
tLib
*
typeLib
)
markInterfaceUsed
(
t
types
.
Type
)
{
v
,
ok
:=
tLib
.
typeTable
[
t
.
String
()]
if
!
ok
{
logger
.
Fatal
(
"Type not found."
)
}
if
v
.
wirType
.
Hash
()
!=
0
{
return
}
tLib
.
usedInterfaces
=
append
(
tLib
.
usedInterfaces
,
v
)
v
.
wirType
.
SetHash
(
-
len
(
tLib
.
usedInterfaces
))
}
func
(
tLib
*
typeLib
)
buildItab
()
{
var
itabs
[]
byte
t_itab
:=
tLib
.
typeTable
[
"runtime._itab"
]
.
wirType
for
_
,
conrete
:=
range
tLib
.
usedConcreteTypes
{
for
_
,
iface
:=
range
tLib
.
usedInterfaces
{
fits
:=
true
vtable
:=
make
([]
int
,
len
(
iface
.
methods
))
for
mid
,
method
:=
range
iface
.
methods
{
found
:=
false
for
_
,
d
:=
range
conrete
.
methods
{
if
d
.
name
==
method
.
name
&&
d
.
sig
.
Equal
(
&
method
.
sig
)
{
found
=
true
vtable
[
mid
]
=
tLib
.
module
.
AddTableElem
(
d
.
fullFnName
)
break
}
}
if
!
found
{
fits
=
false
break
}
}
var
addr
int
if
fits
{
var
itab
[]
byte
header
:=
wir
.
NewConst
(
"0"
,
t_itab
)
itab
=
append
(
itab
,
header
.
Bin
()
...
)
for
_
,
v
:=
range
vtable
{
fnid
:=
wir
.
NewConst
(
strconv
.
Itoa
(
v
),
tLib
.
module
.
U32
)
itab
=
append
(
itab
,
fnid
.
Bin
()
...
)
}
addr
=
tLib
.
module
.
DataSeg
.
Append
(
itab
,
8
)
}
itabs
=
append
(
itabs
,
wir
.
NewConst
(
strconv
.
Itoa
(
addr
),
tLib
.
module
.
U32
)
.
Bin
()
...
)
}
}
itabs_ptr
:=
tLib
.
module
.
DataSeg
.
Append
(
itabs
,
8
)
tLib
.
module
.
SetGlobalInitValue
(
"$wa.RT._itabsPtr"
,
strconv
.
Itoa
(
itabs_ptr
))
tLib
.
module
.
SetGlobalInitValue
(
"$wa.RT._interfaceCount"
,
strconv
.
Itoa
(
len
(
tLib
.
usedInterfaces
)))
tLib
.
module
.
SetGlobalInitValue
(
"$wa.RT._concretTypeCount"
,
strconv
.
Itoa
(
len
(
tLib
.
usedConcreteTypes
)))
}
func
(
p
*
Compiler
)
compileType
(
t
*
ssa
.
Type
)
{
//logger.Fatal("Todo"
)
p
.
tLib
.
compile
(
t
.
Type
()
)
}
internal/backends/compiler_wat/util.go
浏览文件 @
9dc08a73
// 版权 @2021 凹语言 作者。保留所有权利。
package
compiler_wat
import
(
"wa-lang.org/wa/internal/backends/compiler_wat/wir"
"wa-lang.org/wa/internal/ssa"
"wa-lang.org/wa/internal/types"
)
func
GetFnMangleName
(
v
interface
{})
(
internal
string
,
external
string
)
{
switch
f
:=
v
.
(
type
)
{
case
*
ssa
.
Function
:
internal
,
external
=
wir
.
GetPkgMangleName
(
f
.
Pkg
.
Pkg
.
Path
())
if
recv
:=
f
.
Signature
.
Recv
();
recv
!=
nil
{
internal
+=
"."
external
+=
"."
switch
rt
:=
recv
.
Type
()
.
(
type
)
{
case
*
types
.
Named
:
internal
+=
wir
.
GenSymbolName
(
rt
.
Obj
()
.
Name
())
external
+=
rt
.
Obj
()
.
Name
()
case
*
types
.
Pointer
:
btype
,
ok
:=
rt
.
Elem
()
.
(
*
types
.
Named
)
if
!
ok
{
panic
(
"Unreachable"
)
}
internal
+=
wir
.
GenSymbolName
(
btype
.
Obj
()
.
Name
())
external
+=
btype
.
Obj
()
.
Name
()
default
:
panic
(
"Unreachable"
)
}
}
internal
+=
"."
external
+=
"."
internal
+=
wir
.
GenSymbolName
(
f
.
Name
())
external
+=
f
.
Name
()
case
*
types
.
Func
:
internal
,
external
=
wir
.
GetPkgMangleName
(
f
.
Pkg
()
.
Path
())
sig
:=
f
.
Type
()
.
(
*
types
.
Signature
)
if
recv
:=
sig
.
Recv
();
recv
!=
nil
{
internal
+=
"."
external
+=
"."
switch
rt
:=
recv
.
Type
()
.
(
type
)
{
case
*
types
.
Named
:
internal
+=
wir
.
GenSymbolName
(
rt
.
Obj
()
.
Name
())
external
+=
rt
.
Obj
()
.
Name
()
case
*
types
.
Pointer
:
btype
,
ok
:=
rt
.
Elem
()
.
(
*
types
.
Named
)
if
!
ok
{
panic
(
"Unreachable"
)
}
internal
+=
wir
.
GenSymbolName
(
btype
.
Obj
()
.
Name
())
external
+=
btype
.
Obj
()
.
Name
()
default
:
panic
(
"Unreachable"
)
}
}
internal
+=
"."
external
+=
"."
internal
+=
wir
.
GenSymbolName
(
f
.
Name
())
external
+=
f
.
Name
()
}
return
internal
,
external
}
internal/backends/compiler_wat/wir/data_seg.go
0 → 100644
浏览文件 @
9dc08a73
package
wir
/**************************************
DataSeg:
**************************************/
type
DataSeg
struct
{
start
int
data
[]
byte
}
func
newDataSeg
(
start
int
)
*
DataSeg
{
return
&
DataSeg
{
start
:
start
}
}
func
(
s
*
DataSeg
)
Append
(
data
[]
byte
,
align
int
)
(
ptr
int
)
{
ptr
=
s
.
Alloc
(
len
(
data
),
align
)
s
.
Set
(
data
,
ptr
)
return
}
func
(
s
*
DataSeg
)
Alloc
(
size
,
align
int
)
(
ptr
int
)
{
p
:=
s
.
start
+
len
(
s
.
data
)
ptr
=
makeAlign
(
p
,
align
)
d
:=
ptr
+
size
-
p
s
.
data
=
append
(
s
.
data
,
make
([]
byte
,
d
)
...
)
return
}
func
(
s
*
DataSeg
)
Set
(
data
[]
byte
,
ptr
int
)
{
if
copy
(
s
.
data
[
ptr
-
s
.
start
:
],
data
)
!=
len
(
data
)
{
panic
(
"len(dst) < len(src)"
)
}
}
internal/backends/compiler_wat/wir/instruction_emitter.go
浏览文件 @
9dc08a73
...
...
@@ -255,7 +255,7 @@ func (m *Module) EmitGenIndexAddr(x, id Value) (insts []wat.Inst, ret_type Value
switch
typ
:=
x
.
Type
()
.
(
*
Ptr
)
.
Base
.
(
type
)
{
case
*
Array
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
typ
.
Base
.
s
ize
()),
m
.
I32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
typ
.
Base
.
S
ize
()),
m
.
I32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
id
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
wat
.
I32
{}))
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
I32
{}))
...
...
@@ -269,7 +269,7 @@ func (m *Module) EmitGenIndexAddr(x, id Value) (insts []wat.Inst, ret_type Value
switch
typ
:=
x
.
Type
()
.
(
*
Ref
)
.
Base
.
(
type
)
{
case
*
Array
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
typ
.
Base
.
s
ize
()),
m
.
I32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
typ
.
Base
.
S
ize
()),
m
.
I32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
id
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
wat
.
I32
{}))
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
I32
{}))
...
...
@@ -283,7 +283,7 @@ func (m *Module) EmitGenIndexAddr(x, id Value) (insts []wat.Inst, ret_type Value
base_type
:=
x
.
Type
()
.
(
*
Slice
)
.
Base
insts
=
append
(
insts
,
x
.
Extract
(
"block"
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
x
.
Extract
(
"data"
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
base_type
.
s
ize
()),
m
.
I32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
base_type
.
S
ize
()),
m
.
I32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
id
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
wat
.
I32
{}))
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
I32
{}))
...
...
@@ -326,12 +326,12 @@ func (m *Module) EmitGenSlice(x, low, high Value) (insts []wat.Inst, ret_type Va
case
*
aRef
:
switch
btype
:=
x
.
Type
()
.
(
*
Ref
)
.
Base
.
(
type
)
{
case
*
Slice
:
slt
:=
m
.
g
enValueType_Slice
(
btype
.
Base
)
slt
:=
m
.
G
enValueType_Slice
(
btype
.
Base
)
insts
=
slt
.
emitGenFromRefOfSlice
(
x
,
low
,
high
)
ret_type
=
slt
case
*
Array
:
slt
:=
m
.
g
enValueType_Slice
(
btype
.
Base
)
slt
:=
m
.
G
enValueType_Slice
(
btype
.
Base
)
insts
=
slt
.
emitGenFromRefOfArray
(
x
,
low
,
high
)
ret_type
=
slt
...
...
@@ -347,7 +347,7 @@ func (m *Module) EmitGenSlice(x, low, high Value) (insts []wat.Inst, ret_type Va
}
func
(
m
*
Module
)
EmitGenMakeSlice
(
base_type
ValueType
,
Len
,
Cap
Value
)
(
insts
[]
wat
.
Inst
,
ret_type
ValueType
)
{
slice_type
:=
m
.
g
enValueType_Slice
(
base_type
)
slice_type
:=
m
.
G
enValueType_Slice
(
base_type
)
insts
=
slice_type
.
emitGenMake
(
Len
,
Cap
)
ret_type
=
slice_type
return
...
...
@@ -438,6 +438,29 @@ func (m *Module) EmitGenCap(x Value) (insts []wat.Inst) {
return
}
func
(
m
*
Module
)
EmitGenMakeInterface
(
x
Value
,
interfaceType
ValueType
)
(
insts
[]
wat
.
Inst
)
{
x_type
:=
x
.
Type
()
x_ref_type
:=
m
.
GenValueType_Ref
(
x_type
)
return
interfaceType
.
(
*
Interface
)
.
emitGenMake
(
x
,
x_ref_type
)
}
func
(
m
*
Module
)
EmitInvoke
(
i
Value
,
params
[]
Value
,
mid
int
,
typeName
string
)
(
insts
[]
wat
.
Inst
)
{
iface
:=
i
.
(
*
aInterface
)
insts
=
append
(
insts
,
iface
.
Extract
(
"data"
)
.
(
*
aRef
)
.
emitGetValue
()
...
)
for
_
,
v
:=
range
params
{
insts
=
append
(
insts
,
v
.
EmitPush
()
...
)
}
insts
=
append
(
insts
,
iface
.
Extract
(
"itab"
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstLoad
(
wat
.
I32
{},
0
,
4
))
insts
=
append
(
insts
,
wat
.
NewInstLoad
(
wat
.
I32
{},
8
+
mid
*
4
,
4
))
insts
=
append
(
insts
,
wat
.
NewInstCallIndirect
(
typeName
))
return
}
func
(
m
*
Module
)
EmitPrintString
(
v
Value
)
(
insts
[]
wat
.
Inst
)
{
s
:=
v
.
(
*
aString
)
...
...
internal/backends/compiler_wat/wir/module.go
浏览文件 @
9dc08a73
...
...
@@ -27,10 +27,16 @@ type Module struct {
table
[]
string
table_map
map
[
string
]
int
globals
[]
Value
Globals_map
map
[
ssa
.
Value
]
Value
globals
[]
struct
{
v
Value
init_val
string
}
globalsMapByValue
map
[
ssa
.
Value
]
int
globalsMapByName
map
[
string
]
int
constGlobals
[]
wat
.
Global
data_seg
[]
byte
DataSeg
*
DataSeg
BaseWat
string
}
...
...
@@ -52,18 +58,18 @@ func NewModule() *Module {
m
.
F64
=
&
tF64
{}
m
.
types_map
=
make
(
map
[
string
]
ValueType
)
m
.
reg
ValueType
(
m
.
VOID
)
m
.
reg
ValueType
(
m
.
RUNE
)
m
.
reg
ValueType
(
m
.
I8
)
m
.
reg
ValueType
(
m
.
U8
)
m
.
reg
ValueType
(
m
.
I16
)
m
.
reg
ValueType
(
m
.
U16
)
m
.
reg
ValueType
(
m
.
I32
)
m
.
reg
ValueType
(
m
.
U32
)
m
.
reg
ValueType
(
m
.
I64
)
m
.
reg
ValueType
(
m
.
U64
)
m
.
reg
ValueType
(
m
.
F32
)
m
.
reg
ValueType
(
m
.
F64
)
m
.
add
ValueType
(
m
.
VOID
)
m
.
add
ValueType
(
m
.
RUNE
)
m
.
add
ValueType
(
m
.
I8
)
m
.
add
ValueType
(
m
.
U8
)
m
.
add
ValueType
(
m
.
I16
)
m
.
add
ValueType
(
m
.
U16
)
m
.
add
ValueType
(
m
.
I32
)
m
.
add
ValueType
(
m
.
U32
)
m
.
add
ValueType
(
m
.
I64
)
m
.
add
ValueType
(
m
.
U64
)
m
.
add
ValueType
(
m
.
F32
)
m
.
add
ValueType
(
m
.
F64
)
m
.
STRING
=
m
.
GenValueType_String
()
...
...
@@ -72,7 +78,7 @@ func NewModule() *Module {
var
free_type
FnType
free_type
.
Name
=
"$onFree"
free_type
.
Params
=
[]
ValueType
{
m
.
I32
}
m
.
a
ddFnType
(
&
free_type
)
m
.
A
ddFnType
(
&
free_type
)
}
m
.
funcs_map
=
make
(
map
[
string
]
*
Function
)
...
...
@@ -82,9 +88,11 @@ func NewModule() *Module {
m
.
table_map
=
make
(
map
[
string
]
int
)
//data_seg中先插入标志,防止产生0值
m
.
data_seg
=
append
(
m
.
data_seg
,
[]
byte
(
"$$wads$$"
)
...
)
m
.
DataSeg
=
newDataSeg
(
0
)
m
.
DataSeg
.
Append
([]
byte
(
"$$wads$$"
),
8
)
m
.
Globals_map
=
make
(
map
[
ssa
.
Value
]
Value
)
m
.
globalsMapByValue
=
make
(
map
[
ssa
.
Value
]
int
)
m
.
globalsMapByName
=
make
(
map
[
string
]
int
)
return
&
m
}
...
...
@@ -107,7 +115,7 @@ func (m *Module) findFnType(name string) int {
return
0
}
func
(
m
*
Module
)
a
ddFnType
(
typ
*
FnType
)
int
{
func
(
m
*
Module
)
A
ddFnType
(
typ
*
FnType
)
int
{
if
i
:=
m
.
findFnType
(
typ
.
Name
);
i
!=
0
{
return
i
}
...
...
@@ -149,27 +157,53 @@ func (m *Module) AddFunc(f *Function) {
}
func
(
m
*
Module
)
AddGlobal
(
name
string
,
typ
ValueType
,
is_pointer
bool
,
ssa_value
ssa
.
Value
)
Value
{
v
:=
NewGlobal
(
name
,
typ
,
is_pointer
)
m
.
globals
=
append
(
m
.
globals
,
v
)
v
:=
struct
{
v
Value
init_val
string
}{
v
:
NewGlobal
(
name
,
typ
,
is_pointer
)}
if
ssa_value
!=
nil
{
m
.
Globals_map
[
ssa_value
]
=
v
m
.
globalsMapByValue
[
ssa_value
]
=
len
(
m
.
globals
)
}
return
v
m
.
globalsMapByName
[
name
]
=
len
(
m
.
globals
)
m
.
globals
=
append
(
m
.
globals
,
v
)
return
v
.
v
}
func
(
m
*
Module
)
FindGlobal
(
name
string
)
Value
{
for
_
,
g
:=
range
m
.
globals
{
if
g
.
Name
()
==
name
{
return
g
}
func
(
m
*
Module
)
AddConstGlobal
(
name
string
,
init_val
string
,
typ
ValueType
)
{
var
v
wat
.
Global
v
.
V
=
wat
.
NewVar
(
name
,
toWatType
(
typ
))
v
.
IsMut
=
false
v
.
InitValue
=
init_val
m
.
constGlobals
=
append
(
m
.
constGlobals
,
v
)
}
func
(
m
*
Module
)
FindGlobalByName
(
name
string
)
Value
{
id
,
ok
:=
m
.
globalsMapByName
[
name
]
if
!
ok
{
return
nil
}
return
nil
return
m
.
globals
[
id
]
.
v
}
func
(
m
*
Module
)
AddDataSeg
(
data
[]
byte
)
(
ptr
int
)
{
ptr
=
len
(
m
.
data_seg
)
m
.
data_seg
=
append
(
m
.
data_seg
,
data
...
)
return
func
(
m
*
Module
)
FindGlobalByValue
(
v
ssa
.
Value
)
Value
{
id
,
ok
:=
m
.
globalsMapByValue
[
v
]
if
!
ok
{
return
nil
}
return
m
.
globals
[
id
]
.
v
}
func
(
m
*
Module
)
SetGlobalInitValue
(
name
string
,
val
string
)
{
id
,
ok
:=
m
.
globalsMapByName
[
name
]
if
!
ok
{
logger
.
Fatalf
(
"Global not found:%s"
,
name
)
}
m
.
globals
[
id
]
.
init_val
=
val
}
func
(
m
*
Module
)
genGlobalAlloc
()
*
Function
{
...
...
@@ -177,13 +211,13 @@ func (m *Module) genGlobalAlloc() *Function {
f
.
InternalName
=
"$waGlobalAlloc"
for
_
,
g
:=
range
m
.
globals
{
if
g
.
Kind
()
!=
ValueKindGlobal_Pointer
{
if
g
.
v
.
Kind
()
!=
ValueKindGlobal_Pointer
{
continue
}
ref
:=
g
.
(
*
aRef
)
ref
:=
g
.
v
.
(
*
aRef
)
t
:=
ref
.
Type
()
.
(
*
Ref
)
.
Base
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
strconv
.
Itoa
(
t
.
s
ize
())))
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
strconv
.
Itoa
(
t
.
S
ize
())))
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstCall
(
"$waHeapAlloc"
))
f
.
Insts
=
append
(
f
.
Insts
,
ref
.
Extract
(
"data"
)
.
EmitPop
()
...
)
}
...
...
@@ -219,21 +253,24 @@ func (m *Module) ToWatModule() *wat.Module {
}
for
_
,
g
:=
range
m
.
globals
{
raw
:=
g
.
raw
()
raw
:=
g
.
v
.
raw
()
for
_
,
r
:=
range
raw
{
var
wat_global
wat
.
Global
wat_global
.
V
=
r
wat_global
.
IsMut
=
true
wat_global
.
InitValue
=
g
.
init_val
wat_module
.
Globals
=
append
(
wat_module
.
Globals
,
wat_global
)
}
}
wat_module
.
DataSeg
=
m
.
data_seg
wat_module
.
Globals
=
append
(
wat_module
.
Globals
,
m
.
constGlobals
...
)
wat_module
.
DataSeg
=
m
.
DataSeg
.
data
return
&
wat_module
}
func
(
m
*
Module
)
reg
ValueType
(
t
ValueType
)
{
func
(
m
*
Module
)
add
ValueType
(
t
ValueType
)
{
_
,
ok
:=
m
.
types_map
[
t
.
Name
()]
if
ok
{
logger
.
Fatalf
(
"ValueType:%T already registered."
,
t
)
...
...
internal/backends/compiler_wat/wir/util.go
浏览文件 @
9dc08a73
...
...
@@ -8,9 +8,11 @@ import (
"unicode/utf8"
"wa-lang.org/wa/internal/logger"
"wa-lang.org/wa/internal/ssa"
"wa-lang.org/wa/internal/types"
)
/*
func (m *Module) GenValueType(from types.Type) ValueType {
switch t := from.(type) {
case *types.Basic:
...
...
@@ -25,7 +27,7 @@ func (m *Module) GenValueType(from types.Type) ValueType {
return m.I32
}
case
types
.
Uint32
:
case types.Uint32
, types.Uintptr
:
return m.U32
case types.Int64:
...
...
@@ -77,7 +79,21 @@ func (m *Module) GenValueType(from types.Type) ValueType {
}
case *types.Pointer:
return
m
.
GenValueType_Ref
(
m
.
GenValueType
(
t
.
Elem
()))
tRef := m.GenValueType_Ref(m.GenValueType(t.Elem()))
{
methodset := m.ssaProg.MethodSets.MethodSet(t)
for i := 0; i < methodset.Len(); i++ {
sel := methodset.At(i)
method := m.ssaProg.MethodValue(sel)
var mtype FnType
mtype.Name, _ = GetFnMangleName(method)
mtype.FnSig = m.GenFnSig(method.Signature)
tRef.AddMethodEntry(mtype)
}
}
return tRef
case *types.Named:
switch ut := t.Underlying().(type) {
...
...
@@ -94,7 +110,30 @@ func (m *Module) GenValueType(from types.Type) ValueType {
}
pkg_name, _ := GetPkgMangleName(t.Obj().Pkg().Path())
obj_name := GenSymbolName(t.Obj().Name())
return
m
.
GenValueType_Struct
(
pkg_name
+
"."
+
obj_name
,
fs
)
tStruct := m.GenValueType_Struct(pkg_name+"."+obj_name, fs)
{
methodset := m.ssaProg.MethodSets.MethodSet(t)
for i := 0; i < methodset.Len(); i++ {
sel := methodset.At(i)
method := m.ssaProg.MethodValue(sel)
var mtype FnType
mtype.Name, _ = GetFnMangleName(method)
mtype.FnSig = m.GenFnSig(method.Signature)
tStruct.AddMethodEntry(mtype)
}
}
return tStruct
case *types.Interface:
if ut.NumMethods() == 0 {
return m.GenValueType(ut)
}
pkg_name, _ := GetPkgMangleName(t.Obj().Pkg().Path())
obj_name := GenSymbolName(t.Obj().Name())
return m.GenValueType_Interface(pkg_name+"."+obj_name, ut)
case *types.Signature:
return m.GenValueType_Closure(ut)
...
...
@@ -107,17 +146,23 @@ func (m *Module) GenValueType(from types.Type) ValueType {
return m.GenValueType_Array(m.GenValueType(t.Elem()), int(t.Len()))
case *types.Slice:
return
m
.
g
enValueType_Slice
(
m
.
GenValueType
(
t
.
Elem
()))
return m.
G
enValueType_Slice(m.GenValueType(t.Elem()))
case *types.Signature:
return m.GenValueType_Closure(t)
case *types.Interface:
if t.NumMethods() != 0 {
panic("NumMethods of interface{} != 0")
}
return m.GenValueType_Interface("interface", t)
default:
logger.Fatalf("Todo:%T", t)
}
return nil
}
}
//*/
func
IsNumber
(
v
Value
)
bool
{
switch
v
.
Type
()
.
(
type
)
{
...
...
@@ -128,6 +173,72 @@ func IsNumber(v Value) bool {
return
false
}
func
GetFnMangleName
(
v
interface
{})
(
internal
string
,
external
string
)
{
switch
f
:=
v
.
(
type
)
{
case
*
ssa
.
Function
:
if
recv
:=
f
.
Signature
.
Recv
();
recv
!=
nil
{
internal
,
external
=
GetPkgMangleName
(
recv
.
Pkg
()
.
Path
())
internal
+=
"."
external
+=
"."
switch
rt
:=
recv
.
Type
()
.
(
type
)
{
case
*
types
.
Named
:
internal
+=
GenSymbolName
(
rt
.
Obj
()
.
Name
())
external
+=
rt
.
Obj
()
.
Name
()
case
*
types
.
Pointer
:
btype
,
ok
:=
rt
.
Elem
()
.
(
*
types
.
Named
)
if
!
ok
{
panic
(
"Unreachable"
)
}
internal
+=
GenSymbolName
(
btype
.
Obj
()
.
Name
())
external
+=
btype
.
Obj
()
.
Name
()
default
:
panic
(
"Unreachable"
)
}
}
else
{
if
f
.
Pkg
!=
nil
{
internal
,
external
=
GetPkgMangleName
(
f
.
Pkg
.
Pkg
.
Path
())
}
}
internal
+=
"."
external
+=
"."
internal
+=
GenSymbolName
(
f
.
Name
())
external
+=
f
.
Name
()
case
*
types
.
Func
:
internal
,
external
=
GetPkgMangleName
(
f
.
Pkg
()
.
Path
())
sig
:=
f
.
Type
()
.
(
*
types
.
Signature
)
if
recv
:=
sig
.
Recv
();
recv
!=
nil
{
internal
+=
"."
external
+=
"."
switch
rt
:=
recv
.
Type
()
.
(
type
)
{
case
*
types
.
Named
:
internal
+=
GenSymbolName
(
rt
.
Obj
()
.
Name
())
external
+=
rt
.
Obj
()
.
Name
()
case
*
types
.
Pointer
:
btype
,
ok
:=
rt
.
Elem
()
.
(
*
types
.
Named
)
if
!
ok
{
panic
(
"Unreachable"
)
}
internal
+=
GenSymbolName
(
btype
.
Obj
()
.
Name
())
external
+=
btype
.
Obj
()
.
Name
()
default
:
panic
(
"Unreachable"
)
}
}
internal
+=
"."
external
+=
"."
internal
+=
GenSymbolName
(
f
.
Name
())
external
+=
f
.
Name
()
}
return
internal
,
external
}
func
GetPkgMangleName
(
pkg_path
string
)
(
string
,
string
)
{
var
symbol_name
,
exp_name
string
for
i
:=
strings
.
IndexAny
(
pkg_path
,
"/
\\
"
);
i
!=
-
1
;
i
=
strings
.
IndexAny
(
pkg_path
,
"/
\\
"
)
{
...
...
internal/backends/compiler_wat/wir/value_array.go
浏览文件 @
9dc08a73
...
...
@@ -13,9 +13,10 @@ import (
Array:
**************************************/
type
Array
struct
{
Base
ValueType
*
Struct
Capacity
int
tCommon
Base
ValueType
underlying
*
Struct
Capacity
int
}
func
(
m
*
Module
)
GenValueType_Array
(
base
ValueType
,
capacity
int
)
*
Array
{
...
...
@@ -29,16 +30,16 @@ func (m *Module) GenValueType_Array(base ValueType, capacity int) *Array {
for
i
:=
0
;
i
<
capacity
;
i
++
{
members
=
append
(
members
,
NewField
(
"m"
+
strconv
.
Itoa
(
i
),
base
))
}
arr_t
.
Struct
=
m
.
GenValueType_Struct
(
arr_t
.
Name
()
+
".underlying"
,
members
)
m
.
reg
ValueType
(
&
arr_t
)
arr_t
.
underlying
=
m
.
GenValueType_Struct
(
arr_t
.
Name
()
+
".underlying"
,
members
)
m
.
add
ValueType
(
&
arr_t
)
return
&
arr_t
}
func
(
t
*
Array
)
Name
()
string
{
return
t
.
Base
.
Name
()
+
".$array"
+
strconv
.
Itoa
(
t
.
Capacity
)
}
func
(
t
*
Array
)
size
()
int
{
return
t
.
Struct
.
s
ize
()
}
func
(
t
*
Array
)
align
()
int
{
return
t
.
Struct
.
align
()
}
func
(
t
*
Array
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
Struct
.
Raw
()
}
func
(
t
*
Array
)
onFree
()
int
{
return
t
.
Struct
.
onFree
()
}
func
(
t
*
Array
)
Size
()
int
{
return
t
.
underlying
.
S
ize
()
}
func
(
t
*
Array
)
align
()
int
{
return
t
.
underlying
.
align
()
}
func
(
t
*
Array
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
underlying
.
Raw
()
}
func
(
t
*
Array
)
onFree
()
int
{
return
t
.
underlying
.
onFree
()
}
func
(
t
*
Array
)
Equal
(
u
ValueType
)
bool
{
if
ut
,
ok
:=
u
.
(
*
Array
);
ok
{
...
...
@@ -48,7 +49,7 @@ func (t *Array) Equal(u ValueType) bool {
}
func
(
t
*
Array
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
(
insts
[]
wat
.
Inst
)
{
return
t
.
Struct
.
EmitLoadFromAddr
(
addr
,
offset
)
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
func
(
t
*
Array
)
genFunc_IndexOf
()
string
{
...
...
@@ -64,7 +65,7 @@ func (t *Array) genFunc_IndexOf() string {
var
f
Function
f
.
InternalName
=
fn_name
x
:=
newValue_Array
(
"x"
,
ValueKindLocal
,
t
)
id
:=
newValue_Basic
(
"id"
,
ValueKindLocal
,
t
.
_u32
)
id
:=
newValue_Basic
(
"id"
,
ValueKindLocal
,
t
.
underlying
.
_u32
)
f
.
Params
=
append
(
f
.
Params
,
x
)
f
.
Params
=
append
(
f
.
Params
,
id
)
f
.
Results
=
append
(
f
.
Results
,
t
.
Base
)
...
...
@@ -112,7 +113,7 @@ type aArray struct {
func
newValue_Array
(
name
string
,
kind
ValueKind
,
typ
*
Array
)
*
aArray
{
var
v
aArray
v
.
typ
=
typ
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
Struct
)
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
underlying
)
return
&
v
}
...
...
internal/backends/compiler_wat/wir/value_basic.go
浏览文件 @
9dc08a73
...
...
@@ -3,6 +3,8 @@
package
wir
import
(
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
...
...
@@ -49,6 +51,9 @@ func newValue(name string, kind ValueKind, typ ValueType) Value {
case
*
Closure
:
return
newValue_Closure
(
name
,
kind
,
typ
)
case
*
Interface
:
return
newValue_Interface
(
name
,
kind
,
typ
)
case
*
Tuple
:
return
newValue_Tuple
(
name
,
kind
,
typ
)
...
...
@@ -149,3 +154,52 @@ func (v *aBasic) emitStoreToAddr(addr Value, offset int) []wat.Inst {
}
return
insts
}
func
(
v
*
aBasic
)
emitStore
(
offset
int
)
(
insts
[]
wat
.
Inst
)
{
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.DupI32"
))
insts
=
append
(
insts
,
v
.
EmitPush
()
...
)
switch
v
.
Type
()
.
(
type
)
{
case
*
tU8
,
*
tI8
:
insts
=
append
(
insts
,
wat
.
NewInstStore8
(
offset
,
1
))
case
*
tU16
,
*
tI16
:
insts
=
append
(
insts
,
wat
.
NewInstStore16
(
offset
,
1
))
default
:
insts
=
append
(
insts
,
wat
.
NewInstStore
(
toWatType
(
v
.
Type
()),
offset
,
1
))
}
return
}
func
(
v
*
aBasic
)
Bin
()
(
b
[]
byte
)
{
if
v
.
Kind
()
!=
ValueKindConst
{
panic
(
"Value.bin(): const only!"
)
}
switch
v
.
Type
()
.
(
type
)
{
case
*
tU8
,
*
tI8
:
b
=
make
([]
byte
,
1
)
i
,
_
:=
strconv
.
Atoi
(
v
.
Name
())
b
[
0
]
=
byte
(
i
&
0xFF
)
case
*
tU16
,
*
tI16
:
b
=
make
([]
byte
,
2
)
i
,
_
:=
strconv
.
Atoi
(
v
.
Name
())
b
[
0
]
=
byte
(
i
&
0xFF
)
b
[
1
]
=
byte
((
i
>>
8
)
&
0xFF
)
case
*
tU32
,
*
tI32
:
b
=
make
([]
byte
,
4
)
i
,
_
:=
strconv
.
Atoi
(
v
.
Name
())
b
[
0
]
=
byte
(
i
&
0xFF
)
b
[
1
]
=
byte
((
i
>>
8
)
&
0xFF
)
b
[
2
]
=
byte
((
i
>>
16
)
&
0xFF
)
b
[
3
]
=
byte
((
i
>>
24
)
&
0xFF
)
default
:
panic
(
"todo"
)
}
return
}
internal/backends/compiler_wat/wir/value_block.go
浏览文件 @
9dc08a73
...
...
@@ -13,6 +13,7 @@ import (
Block:
**************************************/
type
Block
struct
{
tCommon
Base
ValueType
_i32
ValueType
_u32
ValueType
...
...
@@ -27,12 +28,12 @@ func (m *Module) GenValueType_Block(base ValueType) *Block {
block_t
.
_i32
=
m
.
I32
block_t
.
_u32
=
m
.
U32
m
.
reg
ValueType
(
&
block_t
)
m
.
add
ValueType
(
&
block_t
)
return
&
block_t
}
func
(
t
*
Block
)
Name
()
string
{
return
t
.
Base
.
Name
()
+
".$$block"
}
func
(
t
*
Block
)
s
ize
()
int
{
return
4
}
func
(
t
*
Block
)
S
ize
()
int
{
return
4
}
func
(
t
*
Block
)
align
()
int
{
return
4
}
func
(
t
*
Block
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
U32
{}}
}
func
(
t
*
Block
)
Equal
(
u
ValueType
)
bool
{
...
...
@@ -77,7 +78,7 @@ func (t *Block) emitHeapAlloc(item_count Value) (insts []wat.Inst) {
logger
.
Fatalf
(
"%v
\n
"
,
err
)
return
nil
}
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
s
ize
()
*
c
+
16
),
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
S
ize
()
*
c
+
16
),
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$waHeapAlloc"
))
default
:
...
...
@@ -87,7 +88,7 @@ func (t *Block) emitHeapAlloc(item_count Value) (insts []wat.Inst) {
}
insts
=
append
(
insts
,
item_count
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
s
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
S
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
wat
.
U32
{}))
insts
=
append
(
insts
,
NewConst
(
"16"
,
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
...
...
@@ -97,7 +98,7 @@ func (t *Block) emitHeapAlloc(item_count Value) (insts []wat.Inst) {
insts
=
append
(
insts
,
item_count
.
EmitPush
()
...
)
//item_count
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
onFree
()),
t
.
_u32
)
.
EmitPush
()
...
)
//free_method
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
s
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
//item_size
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
S
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
//item_size
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Block.Init"
))
return
...
...
@@ -143,13 +144,39 @@ func (v *aBlock) EmitRelease() (insts []wat.Inst) {
}
func
(
v
*
aBlock
)
emitStoreToAddr
(
addr
Value
,
offset
int
)
(
insts
[]
wat
.
Inst
)
{
insts
=
append
(
insts
,
addr
.
EmitPush
()
...
)
insts
=
append
(
insts
,
v
.
EmitPush
()
...
)
insts
=
append
(
insts
,
addr
.
EmitPush
()
...
)
// a
insts
=
append
(
insts
,
v
.
EmitPush
()
...
)
// a v
insts
=
append
(
insts
,
addr
.
EmitPush
()
...
)
// a v a
insts
=
append
(
insts
,
wat
.
NewInstLoad
(
wat
.
U32
{},
offset
,
1
))
// a v o
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Block.Release"
))
// a v
insts
=
append
(
insts
,
addr
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstLoad
(
wat
.
U32
{},
offset
,
1
))
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Block.Release"
))
insts
=
append
(
insts
,
wat
.
NewInstStore
(
toWatType
(
v
.
Type
()),
offset
,
1
))
return
}
func
(
v
*
aBlock
)
emitStore
(
offset
int
)
(
insts
[]
wat
.
Inst
)
{
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.DupI32"
))
// a
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.DupI32"
))
// a a
insts
=
append
(
insts
,
v
.
EmitPush
()
...
)
// a a v
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.SwapI32"
))
// a v a
insts
=
append
(
insts
,
wat
.
NewInstLoad
(
wat
.
U32
{},
offset
,
1
))
// a v o
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Block.Release"
))
// a v
insts
=
append
(
insts
,
wat
.
NewInstStore
(
toWatType
(
v
.
Type
()),
offset
,
1
))
return
}
func
(
v
*
aBlock
)
Bin
()
(
b
[]
byte
)
{
if
v
.
Kind
()
!=
ValueKindConst
{
panic
(
"Value.bin(): const only!"
)
}
b
=
make
([]
byte
,
4
)
i
,
_
:=
strconv
.
Atoi
(
v
.
Name
())
b
[
0
]
=
byte
(
i
&
0xFF
)
b
[
1
]
=
byte
((
i
>>
8
)
&
0xFF
)
b
[
2
]
=
byte
((
i
>>
16
)
&
0xFF
)
b
[
3
]
=
byte
((
i
>>
24
)
&
0xFF
)
return
}
internal/backends/compiler_wat/wir/value_closure.go
浏览文件 @
9dc08a73
...
...
@@ -5,7 +5,6 @@ import (
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
"wa-lang.org/wa/internal/types"
)
/**************************************
...
...
@@ -16,19 +15,6 @@ type FnSig struct {
Results
[]
ValueType
}
func
(
m
*
Module
)
GenFnSig
(
s
*
types
.
Signature
)
FnSig
{
var
sig
FnSig
for
i
:=
0
;
i
<
s
.
Params
()
.
Len
();
i
++
{
typ
:=
m
.
GenValueType
(
s
.
Params
()
.
At
(
i
)
.
Type
())
sig
.
Params
=
append
(
sig
.
Params
,
typ
)
}
for
i
:=
0
;
i
<
s
.
Results
()
.
Len
();
i
++
{
typ
:=
m
.
GenValueType
(
s
.
Results
()
.
At
(
i
)
.
Type
())
sig
.
Results
=
append
(
sig
.
Results
,
typ
)
}
return
sig
}
func
(
s
*
FnSig
)
Equal
(
u
*
FnSig
)
bool
{
if
len
(
s
.
Params
)
!=
len
(
u
.
Params
)
{
return
false
...
...
@@ -78,16 +64,17 @@ type FnType struct {
Closure:
**************************************/
type
Closure
struct
{
*
Struct
_fn_type
FnType
_u32
ValueType
tCommon
underlying
*
Struct
_fn_type
FnType
_u32
ValueType
}
var
_closure_id
int
func
(
m
*
Module
)
GenValueType_Closure
(
s
*
types
.
Signature
)
*
Closure
{
func
(
m
*
Module
)
GenValueType_Closure
(
s
ig
FnSig
)
*
Closure
{
var
closure_t
Closure
closure_t
.
_fn_type
.
FnSig
=
m
.
GenFnSig
(
s
)
closure_t
.
_fn_type
.
FnSig
=
sig
t
,
ok
:=
m
.
findValueType
(
closure_t
.
Name
())
if
ok
{
return
t
.
(
*
Closure
)
...
...
@@ -96,17 +83,21 @@ func (m *Module) GenValueType_Closure(s *types.Signature) *Closure {
closure_t
.
_u32
=
m
.
U32
closure_t
.
_fn_type
.
Name
=
"closure$"
+
strconv
.
Itoa
(
_closure_id
)
_closure_id
++
m
.
a
ddFnType
(
&
closure_t
.
_fn_type
)
m
.
A
ddFnType
(
&
closure_t
.
_fn_type
)
var
fields
[]
Field
fields
=
append
(
fields
,
NewField
(
"fn_index"
,
m
.
U32
))
fields
=
append
(
fields
,
NewField
(
"data"
,
m
.
GenValueType_Ref
(
m
.
VOID
)))
closure_t
.
Struct
=
m
.
GenValueType_Struct
(
closure_t
.
Name
()
+
".underlying"
,
fields
)
closure_t
.
underlying
=
m
.
GenValueType_Struct
(
closure_t
.
Name
()
+
".underlying"
,
fields
)
m
.
reg
ValueType
(
&
closure_t
)
m
.
add
ValueType
(
&
closure_t
)
return
&
closure_t
}
func
(
t
*
Closure
)
Name
()
string
{
return
t
.
_fn_type
.
String
()
}
func
(
t
*
Closure
)
Name
()
string
{
return
t
.
_fn_type
.
String
()
}
func
(
t
*
Closure
)
Size
()
int
{
return
t
.
underlying
.
Size
()
}
func
(
t
*
Closure
)
align
()
int
{
return
t
.
underlying
.
align
()
}
func
(
t
*
Closure
)
onFree
()
int
{
return
t
.
underlying
.
onFree
()
}
func
(
t
*
Closure
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
underlying
.
Raw
()
}
func
(
t
*
Closure
)
Equal
(
u
ValueType
)
bool
{
if
ut
,
ok
:=
u
.
(
*
Closure
);
ok
{
...
...
@@ -121,7 +112,7 @@ func (t *Closure) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
return
nil
}
return
t
.
Struct
.
EmitLoadFromAddr
(
addr
,
offset
)
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
/**************************************
...
...
@@ -135,16 +126,16 @@ type aClosure struct {
func
newValue_Closure
(
name
string
,
kind
ValueKind
,
typ
*
Closure
)
*
aClosure
{
var
v
aClosure
v
.
typ
=
typ
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
Struct
)
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
underlying
)
return
&
v
}
func
(
v
*
aClosure
)
Type
()
ValueType
{
return
v
.
typ
}
func
(
m
*
Module
)
GenConstFnValue
(
fn_name
string
,
s
*
types
.
Signature
)
Value
{
func
(
m
*
Module
)
GenConstFnValue
(
fn_name
string
,
s
ig
FnSig
)
Value
{
fn_index
:=
currentModule
.
AddTableElem
(
fn_name
)
closure_t
:=
m
.
GenValueType_Closure
(
s
)
closure_t
:=
m
.
GenValueType_Closure
(
s
ig
)
aClosure
:=
newValue_Closure
(
"0"
,
ValueKindConst
,
closure_t
)
aClosure
.
aStruct
.
setFieldConstValue
(
"fn_index"
,
NewConst
(
strconv
.
Itoa
(
fn_index
),
m
.
U32
))
...
...
@@ -159,7 +150,7 @@ func EmitCallClosure(c Value, params []Value) (insts []wat.Inst) {
insts
=
append
(
insts
,
closure
.
Extract
(
"fn_index"
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
closure
.
Extract
(
"data"
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
currentModule
.
FindGlobal
(
"$wa.RT.closure_data"
)
.
EmitPop
()
...
)
insts
=
append
(
insts
,
currentModule
.
FindGlobal
ByName
(
"$wa.RT.closure_data"
)
.
EmitPop
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstCallIndirect
(
closure
.
typ
.
_fn_type
.
Name
))
return
...
...
internal/backends/compiler_wat/wir/value_interface.go
0 → 100644
浏览文件 @
9dc08a73
// 版权 @2022 凹语言 作者。保留所有权利。
package
wir
import
(
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
)
/**************************************
Interface:
**************************************/
type
Interface
struct
{
tCommon
name
string
underlying
*
Struct
}
func
(
m
*
Module
)
GenValueType_Interface
(
name
string
)
*
Interface
{
t
,
ok
:=
m
.
findValueType
(
name
)
if
ok
{
return
t
.
(
*
Interface
)
}
var
interface_t
Interface
interface_t
.
name
=
name
//interface_t.methodTab = make([]FnType, len(methods))
//copy(interface_t.methodTab, methods)
//
//for i := 0; i < s.NumMethods(); i++ {
// var method FnType
// method.Name = s.Method(i).Name()
// method.FnSig = m.GenFnSig(s.Method(i).Type().(*types.Signature))
// interface_t.methods = append(interface_t.methods, method)
//}
var
fields
[]
Field
fields
=
append
(
fields
,
NewField
(
"data"
,
m
.
GenValueType_Ref
(
m
.
GenValueType_Ref
(
m
.
VOID
))))
fields
=
append
(
fields
,
NewField
(
"itab"
,
m
.
U32
))
interface_t
.
underlying
=
m
.
GenValueType_Struct
(
interface_t
.
Name
()
+
".underlying"
,
fields
)
m
.
addValueType
(
&
interface_t
)
return
&
interface_t
}
func
(
t
*
Interface
)
Name
()
string
{
return
t
.
name
}
func
(
t
*
Interface
)
Size
()
int
{
return
t
.
underlying
.
Size
()
}
func
(
t
*
Interface
)
align
()
int
{
return
t
.
underlying
.
align
()
}
func
(
t
*
Interface
)
onFree
()
int
{
return
t
.
underlying
.
onFree
()
}
func
(
t
*
Interface
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
underlying
.
Raw
()
}
func
(
t
*
Interface
)
Equal
(
u
ValueType
)
bool
{
if
ut
,
ok
:=
u
.
(
*
Interface
);
ok
{
return
t
.
name
==
ut
.
name
}
return
false
}
func
(
t
*
Interface
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
{
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
func
(
t
*
Interface
)
emitGenMake
(
x
Value
,
x_ref
*
Ref
)
(
insts
[]
wat
.
Inst
)
{
insts
=
append
(
insts
,
x_ref
.
emitHeapAlloc
()
...
)
insts
=
append
(
insts
,
x
.
emitStore
(
0
)
...
)
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
strconv
.
Itoa
(
x
.
Type
()
.
Hash
())))
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
strconv
.
Itoa
(
t
.
Hash
())))
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
"0"
))
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.getItab"
))
return
}
/**************************************
aInterface:
**************************************/
type
aInterface
struct
{
aStruct
typ
*
Interface
}
func
newValue_Interface
(
name
string
,
kind
ValueKind
,
typ
*
Interface
)
*
aInterface
{
var
v
aInterface
v
.
typ
=
typ
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
underlying
)
return
&
v
}
func
(
v
*
aInterface
)
Type
()
ValueType
{
return
v
.
typ
}
func
(
v
*
aInterface
)
raw
()
[]
wat
.
Value
{
return
v
.
aStruct
.
raw
()
}
func
(
v
*
aInterface
)
EmitInit
()
[]
wat
.
Inst
{
return
v
.
aStruct
.
EmitInit
()
}
func
(
v
*
aInterface
)
EmitPush
()
[]
wat
.
Inst
{
return
v
.
aStruct
.
EmitPush
()
}
func
(
v
*
aInterface
)
EmitPop
()
[]
wat
.
Inst
{
return
v
.
aStruct
.
EmitPop
()
}
func
(
v
*
aInterface
)
EmitRelease
()
[]
wat
.
Inst
{
return
v
.
aStruct
.
EmitRelease
()
}
func
(
v
*
aInterface
)
emitStoreToAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
{
return
v
.
aStruct
.
emitStoreToAddr
(
addr
,
offset
)
}
internal/backends/compiler_wat/wir/value_pointer.go
浏览文件 @
9dc08a73
package
wir
import
(
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
...
...
@@ -9,6 +11,7 @@ import (
Ptr:
**************************************/
type
Ptr
struct
{
tCommon
Base
ValueType
}
...
...
@@ -19,12 +22,12 @@ func (m *Module) GenValueType_Ptr(base ValueType) *Ptr {
return
t
.
(
*
Ptr
)
}
m
.
reg
ValueType
(
&
ptr_t
)
m
.
add
ValueType
(
&
ptr_t
)
return
&
ptr_t
}
func
(
t
*
Ptr
)
Name
()
string
{
return
t
.
Base
.
Name
()
+
".$$ptr"
}
func
(
t
*
Ptr
)
s
ize
()
int
{
return
4
}
func
(
t
*
Ptr
)
S
ize
()
int
{
return
4
}
func
(
t
*
Ptr
)
align
()
int
{
return
4
}
func
(
t
*
Ptr
)
onFree
()
int
{
return
0
}
func
(
t
*
Ptr
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
toWatType
(
t
)}
}
...
...
@@ -69,3 +72,18 @@ func (v *aPtr) emitSetValue(d Value) []wat.Inst {
}
return
d
.
emitStoreToAddr
(
v
,
0
)
}
func
(
v
*
aPtr
)
Bin
()
(
b
[]
byte
)
{
if
v
.
Kind
()
!=
ValueKindConst
{
panic
(
"Value.bin(): const only!"
)
}
b
=
make
([]
byte
,
4
)
i
,
_
:=
strconv
.
Atoi
(
v
.
Name
())
b
[
0
]
=
byte
(
i
&
0xFF
)
b
[
1
]
=
byte
((
i
>>
8
)
&
0xFF
)
b
[
2
]
=
byte
((
i
>>
16
)
&
0xFF
)
b
[
3
]
=
byte
((
i
>>
24
)
&
0xFF
)
return
}
internal/backends/compiler_wat/wir/value_ref.go
浏览文件 @
9dc08a73
...
...
@@ -13,8 +13,9 @@ import (
Ref:
**************************************/
type
Ref
struct
{
Base
ValueType
*
Struct
tCommon
Base
ValueType
underlying
*
Struct
_base_block
*
Block
_void
ValueType
}
...
...
@@ -32,16 +33,16 @@ func (m *Module) GenValueType_Ref(base ValueType) *Ref {
var
members
[]
Field
members
=
append
(
members
,
NewField
(
"block"
,
ref_t
.
_base_block
))
members
=
append
(
members
,
NewField
(
"data"
,
base_ptr
))
ref_t
.
Struct
=
m
.
GenValueType_Struct
(
ref_t
.
Name
()
+
".underlying"
,
members
)
m
.
reg
ValueType
(
&
ref_t
)
ref_t
.
underlying
=
m
.
GenValueType_Struct
(
ref_t
.
Name
()
+
".underlying"
,
members
)
m
.
add
ValueType
(
&
ref_t
)
return
&
ref_t
}
func
(
t
*
Ref
)
Name
()
string
{
return
t
.
Base
.
Name
()
+
".$ref"
}
func
(
t
*
Ref
)
size
()
int
{
return
t
.
Struct
.
s
ize
()
}
func
(
t
*
Ref
)
align
()
int
{
return
t
.
Struct
.
align
()
}
func
(
t
*
Ref
)
onFree
()
int
{
return
t
.
Struct
.
onFree
()
}
func
(
t
*
Ref
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
Struct
.
Raw
()
}
func
(
t
*
Ref
)
Size
()
int
{
return
t
.
underlying
.
S
ize
()
}
func
(
t
*
Ref
)
align
()
int
{
return
t
.
underlying
.
align
()
}
func
(
t
*
Ref
)
onFree
()
int
{
return
t
.
underlying
.
onFree
()
}
func
(
t
*
Ref
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
underlying
.
Raw
()
}
func
(
t
*
Ref
)
Equal
(
u
ValueType
)
bool
{
if
ut
,
ok
:=
u
.
(
*
Ref
);
ok
{
return
t
.
Base
.
Equal
(
ut
.
Base
)
...
...
@@ -53,9 +54,9 @@ func (t *Ref) emitHeapAlloc() (insts []wat.Inst) {
//insts = append(insts, wat.NewBlank())
//insts = append(insts, wat.NewComment("Ref.emitHeapAlloc start"))
insts
=
append
(
insts
,
t
.
_base_block
.
emitHeapAlloc
(
NewConst
(
"1"
,
t
.
_u32
))
...
)
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
WatStack
"
))
insts
=
append
(
insts
,
NewConst
(
"16"
,
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
t
.
_base_block
.
emitHeapAlloc
(
NewConst
(
"1"
,
t
.
underlying
.
_u32
))
...
)
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
I32
"
))
insts
=
append
(
insts
,
NewConst
(
"16"
,
t
.
underlying
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
//insts = append(insts, wat.NewComment("Ref.emitHeapAlloc end"))
...
...
@@ -70,8 +71,8 @@ func (t *Ref) emitStackAlloc() (insts []wat.Inst) {
logger
.
Fatal
(
"Todo"
)
insts
=
append
(
insts
,
NewConst
(
"0"
,
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
size
()),
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
"0"
,
t
.
underlying
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
Size
()),
t
.
underlying
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$waStackAlloc"
))
//insts = append(insts, wat.NewComment("Ref.emitStackAlloc end"))
...
...
@@ -80,7 +81,7 @@ func (t *Ref) emitStackAlloc() (insts []wat.Inst) {
}
func
(
t
*
Ref
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
{
return
t
.
Struct
.
EmitLoadFromAddr
(
addr
,
offset
)
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
/**************************************
...
...
@@ -94,7 +95,7 @@ type aRef struct {
func
newValue_Ref
(
name
string
,
kind
ValueKind
,
typ
*
Ref
)
*
aRef
{
var
v
aRef
v
.
typ
=
typ
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
Struct
)
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
underlying
)
return
&
v
}
...
...
internal/backends/compiler_wat/wir/value_slice.go
浏览文件 @
9dc08a73
...
...
@@ -13,15 +13,16 @@ import (
Slice:
**************************************/
type
Slice
struct
{
Base
ValueType
*
Struct
tCommon
Base
ValueType
underlying
*
Struct
_i32
ValueType
_u32
ValueType
_base_block
*
Block
_base_ptr
*
Ptr
}
func
(
m
*
Module
)
g
enValueType_Slice
(
base
ValueType
)
*
Slice
{
func
(
m
*
Module
)
G
enValueType_Slice
(
base
ValueType
)
*
Slice
{
slice_t
:=
Slice
{
Base
:
base
}
t
,
ok
:=
m
.
findValueType
(
slice_t
.
Name
())
if
ok
{
...
...
@@ -38,16 +39,16 @@ func (m *Module) genValueType_Slice(base ValueType) *Slice {
members
=
append
(
members
,
NewField
(
"data"
,
slice_t
.
_base_ptr
))
members
=
append
(
members
,
NewField
(
"len"
,
slice_t
.
_u32
))
members
=
append
(
members
,
NewField
(
"cap"
,
slice_t
.
_u32
))
slice_t
.
Struct
=
m
.
GenValueType_Struct
(
slice_t
.
Name
()
+
".underlying"
,
members
)
m
.
reg
ValueType
(
&
slice_t
)
slice_t
.
underlying
=
m
.
GenValueType_Struct
(
slice_t
.
Name
()
+
".underlying"
,
members
)
m
.
add
ValueType
(
&
slice_t
)
return
&
slice_t
}
func
(
t
*
Slice
)
Name
()
string
{
return
t
.
Base
.
Name
()
+
".$slice"
}
func
(
t
*
Slice
)
size
()
int
{
return
t
.
Struct
.
s
ize
()
}
func
(
t
*
Slice
)
align
()
int
{
return
t
.
Struct
.
align
()
}
func
(
t
*
Slice
)
onFree
()
int
{
return
t
.
Struct
.
onFree
()
}
func
(
t
*
Slice
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
Struct
.
Raw
()
}
func
(
t
*
Slice
)
Size
()
int
{
return
t
.
underlying
.
S
ize
()
}
func
(
t
*
Slice
)
align
()
int
{
return
t
.
underlying
.
align
()
}
func
(
t
*
Slice
)
onFree
()
int
{
return
t
.
underlying
.
onFree
()
}
func
(
t
*
Slice
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
underlying
.
Raw
()
}
func
(
t
*
Slice
)
Equal
(
u
ValueType
)
bool
{
if
ut
,
ok
:=
u
.
(
*
Slice
);
ok
{
return
t
.
Base
.
Equal
(
ut
.
Base
)
...
...
@@ -56,7 +57,7 @@ func (t *Slice) Equal(u ValueType) bool {
}
func
(
t
*
Slice
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
{
return
t
.
Struct
.
EmitLoadFromAddr
(
addr
,
offset
)
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
/*这个函数极其不优雅*/
...
...
@@ -73,8 +74,8 @@ func (t *Slice) emitGenFromRefOfSlice(x *aRef, low, high Value) (insts []wat.Ins
insts
=
append
(
insts
,
x
.
Extract
(
"data"
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstLoad
(
wat
.
U32
{},
4
,
1
))
//insts = append(insts, NewConst(strconv.Itoa(x.Type().(*Ref).Base.(*Slice).Base.
s
ize()), t._u32).EmitPush()...)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
s
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
//insts = append(insts, NewConst(strconv.Itoa(x.Type().(*Ref).Base.(*Slice).Base.
S
ize()), t._u32).EmitPush()...)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
S
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
low
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
wat
.
U32
{}))
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
...
...
@@ -107,8 +108,8 @@ func (t *Slice) emitGenFromRefOfArray(x *aRef, low, high Value) (insts []wat.Ins
low
=
NewConst
(
"0"
,
t
.
_u32
)
}
insts
=
append
(
insts
,
x
.
Extract
(
"data"
)
.
EmitPush
()
...
)
//insts = append(insts, NewConst(strconv.Itoa(x.Type().(*Ref).Base.(*Array).Base.
s
ize()), t._u32).EmitPush()...)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
s
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
//insts = append(insts, NewConst(strconv.Itoa(x.Type().(*Ref).Base.(*Array).Base.
S
ize()), t._u32).EmitPush()...)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
S
ize
()),
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
low
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
wat
.
U32
{}))
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
...
...
@@ -136,7 +137,7 @@ func (t *Slice) emitGenMake(Len, Cap Value) (insts []wat.Inst) {
insts
=
append
(
insts
,
t
.
_base_block
.
emitHeapAlloc
(
Cap
)
...
)
//data
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
WatStack
"
))
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
I32
"
))
insts
=
append
(
insts
,
NewConst
(
"16"
,
t
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
...
...
@@ -196,7 +197,7 @@ func (t *Slice) genAppendFunc() string {
f
.
Locals
=
append
(
f
.
Locals
,
src
)
dest
:=
NewLocal
(
"dest"
,
t
.
_base_ptr
)
f
.
Locals
=
append
(
f
.
Locals
,
dest
)
item_size
:=
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
s
ize
()),
t
.
_u32
)
item_size
:=
NewConst
(
strconv
.
Itoa
(
t
.
Base
.
S
ize
()),
t
.
_u32
)
inst_if
:=
wat
.
NewInstIf
(
nil
,
nil
,
t
.
Raw
())
{
//if_true
...
...
@@ -266,10 +267,10 @@ func (t *Slice) genAppendFunc() string {
if_false
=
append
(
if_false
,
new_cap
.
EmitPop
()
...
)
if_false
=
append
(
if_false
,
t
.
_base_block
.
emitHeapAlloc
(
new_cap
)
...
)
//block
if_false
=
append
(
if_false
,
wat
.
NewInstCall
(
"$wa.RT.Dup
WatStack
"
))
if_false
=
append
(
if_false
,
wat
.
NewInstCall
(
"$wa.RT.Dup
I32
"
))
if_false
=
append
(
if_false
,
NewConst
(
"16"
,
t
.
_u32
)
.
EmitPush
()
...
)
if_false
=
append
(
if_false
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
//data
if_false
=
append
(
if_false
,
wat
.
NewInstCall
(
"$wa.RT.Dup
WatStack
"
))
if_false
=
append
(
if_false
,
wat
.
NewInstCall
(
"$wa.RT.Dup
I32
"
))
if_false
=
append
(
if_false
,
dest
.
EmitPop
()
...
)
//dest
if_false
=
append
(
if_false
,
new_len
.
EmitPush
()
...
)
//len
if_false
=
append
(
if_false
,
new_cap
.
EmitPush
()
...
)
//cap
...
...
@@ -372,7 +373,7 @@ type aSlice struct {
func
newValue_Slice
(
name
string
,
kind
ValueKind
,
typ
*
Slice
)
*
aSlice
{
var
v
aSlice
v
.
typ
=
typ
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
Struct
)
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
underlying
)
return
&
v
}
...
...
@@ -397,7 +398,7 @@ func (v *aSlice) emitSub(low, high Value) (insts []wat.Inst) {
low
=
NewConst
(
"0"
,
v
.
typ
.
_u32
)
}
insts
=
append
(
insts
,
v
.
Extract
(
"data"
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
v
.
typ
.
Base
.
s
ize
()),
v
.
typ
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
NewConst
(
strconv
.
Itoa
(
v
.
typ
.
Base
.
S
ize
()),
v
.
typ
.
_u32
)
.
EmitPush
()
...
)
insts
=
append
(
insts
,
low
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
wat
.
U32
{}))
insts
=
append
(
insts
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
...
...
internal/backends/compiler_wat/wir/value_string.go
浏览文件 @
9dc08a73
...
...
@@ -12,12 +12,13 @@ import (
String:
**************************************/
type
String
struct
{
*
Struct
_u8
ValueType
_u32
ValueType
_i32
ValueType
_u8_block
*
Block
_u8_ptr
ValueType
tCommon
underlying
*
Struct
_u8
ValueType
_u32
ValueType
_i32
ValueType
_u8_block
*
Block
_u8_ptr
ValueType
}
func
(
m
*
Module
)
GenValueType_String
()
*
String
{
...
...
@@ -37,21 +38,21 @@ func (m *Module) GenValueType_String() *String {
members
=
append
(
members
,
NewField
(
"block"
,
str_t
.
_u8_block
))
members
=
append
(
members
,
NewField
(
"data"
,
str_t
.
_u8_ptr
))
members
=
append
(
members
,
NewField
(
"len"
,
str_t
.
_u32
))
str_t
.
Struct
=
m
.
GenValueType_Struct
(
str_t
.
Name
()
+
".underlying"
,
members
)
m
.
reg
ValueType
(
&
str_t
)
str_t
.
underlying
=
m
.
GenValueType_Struct
(
str_t
.
Name
()
+
".underlying"
,
members
)
m
.
add
ValueType
(
&
str_t
)
return
&
str_t
}
func
(
t
*
String
)
Name
()
string
{
return
"string"
}
func
(
t
*
String
)
size
()
int
{
return
t
.
Struct
.
s
ize
()
}
func
(
t
*
String
)
align
()
int
{
return
t
.
Struct
.
align
()
}
func
(
t
*
String
)
onFree
()
int
{
return
t
.
Struct
.
onFree
()
}
func
(
t
*
String
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
Struct
.
Raw
()
}
func
(
t
*
String
)
Size
()
int
{
return
t
.
underlying
.
S
ize
()
}
func
(
t
*
String
)
align
()
int
{
return
t
.
underlying
.
align
()
}
func
(
t
*
String
)
onFree
()
int
{
return
t
.
underlying
.
onFree
()
}
func
(
t
*
String
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
underlying
.
Raw
()
}
func
(
t
*
String
)
Equal
(
u
ValueType
)
bool
{
_
,
ok
:=
u
.
(
*
String
);
return
ok
}
func
(
t
*
String
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
{
return
t
.
Struct
.
EmitLoadFromAddr
(
addr
,
offset
)
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
func
(
t
*
String
)
genFunc_Append
()
string
{
...
...
@@ -92,16 +93,16 @@ func (t *String) genFunc_Append() string {
f
.
Locals
=
append
(
f
.
Locals
,
src
)
dest
:=
NewLocal
(
"dest"
,
t
.
_u8_ptr
)
f
.
Locals
=
append
(
f
.
Locals
,
dest
)
item_size
:=
NewConst
(
strconv
.
Itoa
(
t
.
_u8
.
s
ize
()),
t
.
_u32
)
item_size
:=
NewConst
(
strconv
.
Itoa
(
t
.
_u8
.
S
ize
()),
t
.
_u32
)
{
//if_false
//gen new slice
f
.
Insts
=
append
(
f
.
Insts
,
t
.
_u8_block
.
emitHeapAlloc
(
new_len
)
...
)
//block
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
WatStack
"
))
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
I32
"
))
f
.
Insts
=
append
(
f
.
Insts
,
NewConst
(
"16"
,
t
.
_u32
)
.
EmitPush
()
...
)
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstAdd
(
wat
.
U32
{}))
//data
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
WatStack
"
))
f
.
Insts
=
append
(
f
.
Insts
,
wat
.
NewInstCall
(
"$wa.RT.Dup
I32
"
))
f
.
Insts
=
append
(
f
.
Insts
,
dest
.
EmitPop
()
...
)
//dest
f
.
Insts
=
append
(
f
.
Insts
,
new_len
.
EmitPush
()
...
)
//len
...
...
@@ -275,10 +276,10 @@ type aString struct {
func
newValue_String
(
name
string
,
kind
ValueKind
,
typ
*
String
)
*
aString
{
var
v
aString
v
.
typ
=
typ
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
Struct
)
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
underlying
)
if
kind
==
ValueKindConst
{
v
.
aStruct
.
setFieldConstValue
(
"block"
,
NewConst
(
"0"
,
typ
.
_u8_block
))
ptr
:=
currentModule
.
AddDataSeg
([]
byte
(
name
)
)
ptr
:=
currentModule
.
DataSeg
.
Append
([]
byte
(
name
),
1
)
v
.
aStruct
.
setFieldConstValue
(
"data"
,
NewConst
(
strconv
.
Itoa
(
ptr
),
typ
.
_u8_ptr
))
v
.
aStruct
.
setFieldConstValue
(
"len"
,
NewConst
(
strconv
.
Itoa
(
len
(
name
)),
typ
.
_u32
))
}
...
...
internal/backends/compiler_wat/wir/value_struct.go
浏览文件 @
9dc08a73
...
...
@@ -26,6 +26,7 @@ func (i *Field) Equal(u Field) bool { return i.name == u.name && i.typ.Eq
Struct:
**************************************/
type
Struct
struct
{
tCommon
name
string
Members
[]
Field
_size
int
...
...
@@ -38,14 +39,14 @@ type iStruct interface {
genRawFree
()
(
ret
[]
fn_offset_pair
)
}
func
makeAlign
(
i
,
a
int
)
int
{
if
a
==
1
||
a
==
0
{
func
makeAlign
(
i
,
a
lign
int
)
int
{
if
a
lign
==
1
||
align
==
0
{
return
i
}
return
(
i
+
a
-
1
)
/
a
*
a
return
(
i
+
a
lign
-
1
)
/
align
*
align
}
func
(
m
*
Module
)
GenValueType_Struct
(
name
string
,
member
s
[]
Field
)
*
Struct
{
func
(
m
*
Module
)
GenValueType_Struct
(
name
string
,
field
s
[]
Field
)
*
Struct
{
t
,
ok
:=
m
.
findValueType
(
name
)
if
ok
{
return
t
.
(
*
Struct
)
...
...
@@ -54,15 +55,15 @@ func (m *Module) GenValueType_Struct(name string, members []Field) *Struct {
var
struct_type
Struct
struct_type
.
name
=
name
struct_type
.
_u32
=
m
.
U32
m
.
reg
ValueType
(
&
struct_type
)
m
.
add
ValueType
(
&
struct_type
)
for
_
,
f
:=
range
member
s
{
for
_
,
f
:=
range
field
s
{
ma
:=
f
.
Type
()
.
align
()
f
.
_start
=
makeAlign
(
struct_type
.
_size
,
ma
)
f
.
_typ_ptr
=
m
.
GenValueType_Ptr
(
f
.
typ
)
struct_type
.
Members
=
append
(
struct_type
.
Members
,
f
)
struct_type
.
_size
=
f
.
_start
+
f
.
Type
()
.
s
ize
()
struct_type
.
_size
=
f
.
_start
+
f
.
Type
()
.
S
ize
()
if
ma
>
struct_type
.
_align
{
struct_type
.
_align
=
ma
}
...
...
@@ -72,7 +73,7 @@ func (m *Module) GenValueType_Struct(name string, members []Field) *Struct {
}
func
(
t
*
Struct
)
Name
()
string
{
return
t
.
name
}
func
(
t
*
Struct
)
s
ize
()
int
{
return
t
.
_size
}
func
(
t
*
Struct
)
S
ize
()
int
{
return
t
.
_size
}
func
(
t
*
Struct
)
align
()
int
{
return
t
.
_align
}
type
fn_offset_pair
struct
{
...
...
@@ -137,20 +138,22 @@ func (t *Struct) Raw() []wat.ValueType {
}
func
(
t
*
Struct
)
Equal
(
u
ValueType
)
bool
{
if
u
,
ok
:=
u
.
(
*
Struct
);
ok
{
if
len
(
t
.
Members
)
!=
len
(
u
.
Members
)
{
return
false
}
ut
,
ok
:=
u
.
(
*
Struct
)
if
!
ok
{
return
false
}
for
i
:=
range
t
.
Members
{
if
!
t
.
Members
[
i
]
.
Equal
(
u
.
Members
[
i
])
{
return
false
}
}
if
len
(
t
.
Members
)
!=
len
(
ut
.
Members
)
{
return
false
}
return
true
for
i
:=
range
t
.
Members
{
if
!
t
.
Members
[
i
]
.
Equal
(
ut
.
Members
[
i
])
{
return
false
}
}
return
false
return
true
}
func
(
t
*
Struct
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
(
insts
[]
wat
.
Inst
)
{
...
...
@@ -175,11 +178,17 @@ aStruct:
**************************************/
type
aStruct
struct
{
aValue
typ
*
Struct
field_const_vals
map
[
string
]
Value
}
func
newValue_Struct
(
name
string
,
kind
ValueKind
,
typ
*
Struct
)
*
aStruct
{
return
&
aStruct
{
aValue
:
aValue
{
name
:
name
,
kind
:
kind
,
typ
:
typ
}}
var
v
aStruct
v
.
typ
=
typ
v
.
aValue
.
name
=
name
v
.
aValue
.
kind
=
kind
v
.
aValue
.
typ
=
typ
return
&
v
}
func
(
v
*
aStruct
)
genSubValue
(
m
Field
)
Value
{
...
...
@@ -276,3 +285,26 @@ func (v *aStruct) emitStoreToAddr(addr Value, offset int) (insts []wat.Inst) {
}
return
}
func
(
v
*
aStruct
)
emitStore
(
offset
int
)
(
insts
[]
wat
.
Inst
)
{
st
:=
v
.
Type
()
.
(
*
Struct
)
for
_
,
m
:=
range
st
.
Members
{
t
:=
v
.
genSubValue
(
m
)
insts
=
append
(
insts
,
t
.
emitStore
(
m
.
_start
+
offset
)
...
)
}
return
}
func
(
v
*
aStruct
)
Bin
()
(
b
[]
byte
)
{
if
v
.
Kind
()
!=
ValueKindConst
{
panic
(
"Value.bin(): const only!"
)
}
b
=
make
([]
byte
,
v
.
typ
.
Size
())
for
_
,
m
:=
range
v
.
typ
.
Members
{
d
:=
b
[
m
.
_start
:
]
copy
(
d
,
v
.
genSubValue
(
m
)
.
Bin
())
}
return
}
internal/backends/compiler_wat/wir/value_tuple.go
浏览文件 @
9dc08a73
...
...
@@ -12,12 +12,13 @@ import (
Tuple:
**************************************/
type
Tuple
struct
{
*
Struct
_fields
[]
ValueType
tCommon
underlying
*
Struct
Fields
[]
ValueType
}
func
(
m
*
Module
)
GenValueType_Tuple
(
fields
[]
ValueType
)
*
Tuple
{
tuple_t
:=
Tuple
{
_f
ields
:
fields
}
tuple_t
:=
Tuple
{
F
ields
:
fields
}
t
,
ok
:=
m
.
findValueType
(
tuple_t
.
Name
())
if
ok
{
return
t
.
(
*
Tuple
)
...
...
@@ -28,33 +29,44 @@ func (m *Module) GenValueType_Tuple(fields []ValueType) *Tuple {
fname
:=
"m"
+
strconv
.
Itoa
(
i
)
members
=
append
(
members
,
NewField
(
fname
,
t
))
}
tuple_t
.
Struct
=
m
.
GenValueType_Struct
(
tuple_t
.
Name
()
+
".underlying"
,
members
)
m
.
reg
ValueType
(
&
tuple_t
)
tuple_t
.
underlying
=
m
.
GenValueType_Struct
(
tuple_t
.
Name
()
+
".underlying"
,
members
)
m
.
add
ValueType
(
&
tuple_t
)
return
&
tuple_t
}
func
(
t
*
Tuple
)
Name
()
string
{
s
:=
"$"
for
_
,
t
:=
range
t
.
_f
ields
{
for
_
,
t
:=
range
t
.
F
ields
{
s
+=
t
.
Name
()
}
return
s
}
func
(
t
*
Tuple
)
size
()
int
{
return
t
.
Struct
.
s
ize
()
}
func
(
t
*
Tuple
)
align
()
int
{
return
t
.
Struct
.
align
()
}
func
(
t
*
Tuple
)
onFree
()
int
{
return
t
.
Struct
.
onFree
()
}
func
(
t
*
Tuple
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
Struct
.
Raw
()
}
func
(
t
*
Tuple
)
Size
()
int
{
return
t
.
underlying
.
S
ize
()
}
func
(
t
*
Tuple
)
align
()
int
{
return
t
.
underlying
.
align
()
}
func
(
t
*
Tuple
)
onFree
()
int
{
return
t
.
underlying
.
onFree
()
}
func
(
t
*
Tuple
)
Raw
()
[]
wat
.
ValueType
{
return
t
.
underlying
.
Raw
()
}
func
(
t
*
Tuple
)
Equal
(
u
ValueType
)
bool
{
ut
,
ok
:=
u
.
(
*
Tuple
)
if
!
ok
{
return
false
}
return
t
.
Struct
.
Equal
(
ut
.
Struct
)
if
len
(
t
.
Fields
)
!=
len
(
ut
.
Fields
)
{
return
false
}
for
i
:=
range
t
.
Fields
{
if
!
t
.
Fields
[
i
]
.
Equal
(
ut
.
Fields
[
i
])
{
return
false
}
}
return
true
}
func
(
t
*
Tuple
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
{
return
t
.
Struct
.
EmitLoadFromAddr
(
addr
,
offset
)
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
/**************************************
...
...
@@ -68,7 +80,7 @@ type aTuple struct {
func
newValue_Tuple
(
name
string
,
kind
ValueKind
,
typ
*
Tuple
)
*
aTuple
{
var
v
aTuple
v
.
typ
=
typ
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
Struct
)
v
.
aStruct
=
*
newValue_Struct
(
name
,
kind
,
typ
.
underlying
)
return
&
v
}
...
...
@@ -85,7 +97,7 @@ func (v *aTuple) emitStoreToAddr(addr Value, offset int) []wat.Inst {
}
func
(
v
*
aTuple
)
Extract
(
id
int
)
Value
{
st
:=
v
.
typ
.
Struct
st
:=
v
.
typ
.
underlying
if
id
>=
len
(
st
.
Members
)
{
panic
(
"id >= len(st.Members)"
)
}
...
...
internal/backends/compiler_wat/wir/value_type.go
浏览文件 @
9dc08a73
...
...
@@ -40,13 +40,37 @@ func toWatType(t ValueType) wat.ValueType {
return
nil
}
/**************************************
tCommon:
**************************************/
type
tCommon
struct
{
_hash
int
}
func
(
t
*
tCommon
)
Hash
()
int
{
return
t
.
_hash
}
func
(
t
*
tCommon
)
SetHash
(
h
int
)
{
t
.
_hash
=
h
}
//func (t *tCommon) AddMethodEntry(m FnType) { logger.Fatal("Can't add method for common type.") }
//
///**************************************
//tUncommon:
//**************************************/
//type tUncommon struct {
// tCommon
// methodTab []FnType
//}
//
//func (t *tUncommon) AddMethodEntry(m FnType) { t.methodTab = append(t.methodTab, m) }
/**************************************
tVoid:
**************************************/
type
tVoid
struct
{}
type
tVoid
struct
{
tCommon
}
func
(
t
*
tVoid
)
Name
()
string
{
return
"void"
}
func
(
t
*
tVoid
)
s
ize
()
int
{
return
0
}
func
(
t
*
tVoid
)
S
ize
()
int
{
return
0
}
func
(
t
*
tVoid
)
align
()
int
{
return
0
}
func
(
t
*
tVoid
)
onFree
()
int
{
return
0
}
func
(
t
*
tVoid
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{}
}
...
...
@@ -59,10 +83,12 @@ func (t *tVoid) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tRune:
**************************************/
type
tRune
struct
{}
type
tRune
struct
{
tCommon
}
func
(
t
*
tRune
)
Name
()
string
{
return
"rune"
}
func
(
t
*
tRune
)
s
ize
()
int
{
return
4
}
func
(
t
*
tRune
)
S
ize
()
int
{
return
4
}
func
(
t
*
tRune
)
align
()
int
{
return
4
}
func
(
t
*
tRune
)
onFree
()
int
{
return
0
}
func
(
t
*
tRune
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I32
{}}
}
...
...
@@ -80,10 +106,12 @@ func (t *tRune) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tI8:
**************************************/
type
tI8
struct
{}
type
tI8
struct
{
tCommon
}
func
(
t
*
tI8
)
Name
()
string
{
return
"i8"
}
func
(
t
*
tI8
)
s
ize
()
int
{
return
1
}
func
(
t
*
tI8
)
S
ize
()
int
{
return
1
}
func
(
t
*
tI8
)
align
()
int
{
return
1
}
func
(
t
*
tI8
)
onFree
()
int
{
return
0
}
func
(
t
*
tI8
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I32
{}}
}
...
...
@@ -101,10 +129,12 @@ func (t *tI8) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tU8:
**************************************/
type
tU8
struct
{}
type
tU8
struct
{
tCommon
}
func
(
t
*
tU8
)
Name
()
string
{
return
"u8"
}
func
(
t
*
tU8
)
s
ize
()
int
{
return
1
}
func
(
t
*
tU8
)
S
ize
()
int
{
return
1
}
func
(
t
*
tU8
)
align
()
int
{
return
1
}
func
(
t
*
tU8
)
onFree
()
int
{
return
0
}
func
(
t
*
tU8
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I32
{}}
}
...
...
@@ -122,10 +152,12 @@ func (t *tU8) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tI16:
**************************************/
type
tI16
struct
{}
type
tI16
struct
{
tCommon
}
func
(
t
*
tI16
)
Name
()
string
{
return
"i16"
}
func
(
t
*
tI16
)
s
ize
()
int
{
return
2
}
func
(
t
*
tI16
)
S
ize
()
int
{
return
2
}
func
(
t
*
tI16
)
align
()
int
{
return
2
}
func
(
t
*
tI16
)
onFree
()
int
{
return
0
}
func
(
t
*
tI16
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I32
{}}
}
...
...
@@ -143,10 +175,12 @@ func (t *tI16) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tU16:
**************************************/
type
tU16
struct
{}
type
tU16
struct
{
tCommon
}
func
(
t
*
tU16
)
Name
()
string
{
return
"u16"
}
func
(
t
*
tU16
)
s
ize
()
int
{
return
2
}
func
(
t
*
tU16
)
S
ize
()
int
{
return
2
}
func
(
t
*
tU16
)
align
()
int
{
return
2
}
func
(
t
*
tU16
)
onFree
()
int
{
return
0
}
func
(
t
*
tU16
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I32
{}}
}
...
...
@@ -164,10 +198,12 @@ func (t *tU16) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tI32:
**************************************/
type
tI32
struct
{}
type
tI32
struct
{
tCommon
}
func
(
t
*
tI32
)
Name
()
string
{
return
"i32"
}
func
(
t
*
tI32
)
s
ize
()
int
{
return
4
}
func
(
t
*
tI32
)
S
ize
()
int
{
return
4
}
func
(
t
*
tI32
)
align
()
int
{
return
4
}
func
(
t
*
tI32
)
onFree
()
int
{
return
0
}
func
(
t
*
tI32
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I32
{}}
}
...
...
@@ -185,10 +221,12 @@ func (t *tI32) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tU32:
**************************************/
type
tU32
struct
{}
type
tU32
struct
{
tCommon
}
func
(
t
*
tU32
)
Name
()
string
{
return
"u32"
}
func
(
t
*
tU32
)
s
ize
()
int
{
return
4
}
func
(
t
*
tU32
)
S
ize
()
int
{
return
4
}
func
(
t
*
tU32
)
align
()
int
{
return
4
}
func
(
t
*
tU32
)
onFree
()
int
{
return
0
}
func
(
t
*
tU32
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
U32
{}}
}
...
...
@@ -206,10 +244,12 @@ func (t *tU32) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tI64:
**************************************/
type
tI64
struct
{}
type
tI64
struct
{
tCommon
}
func
(
t
*
tI64
)
Name
()
string
{
return
"i64"
}
func
(
t
*
tI64
)
s
ize
()
int
{
return
8
}
func
(
t
*
tI64
)
S
ize
()
int
{
return
8
}
func
(
t
*
tI64
)
align
()
int
{
return
8
}
func
(
t
*
tI64
)
onFree
()
int
{
return
0
}
func
(
t
*
tI64
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I64
{}}
}
...
...
@@ -227,10 +267,12 @@ func (t *tI64) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tUint64:
**************************************/
type
tU64
struct
{}
type
tU64
struct
{
tCommon
}
func
(
t
*
tU64
)
Name
()
string
{
return
"u64"
}
func
(
t
*
tU64
)
s
ize
()
int
{
return
8
}
func
(
t
*
tU64
)
S
ize
()
int
{
return
8
}
func
(
t
*
tU64
)
align
()
int
{
return
8
}
func
(
t
*
tU64
)
onFree
()
int
{
return
0
}
func
(
t
*
tU64
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
U64
{}}
}
...
...
@@ -248,10 +290,12 @@ func (t *tU64) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tF32:
**************************************/
type
tF32
struct
{}
type
tF32
struct
{
tCommon
}
func
(
t
*
tF32
)
Name
()
string
{
return
"f32"
}
func
(
t
*
tF32
)
s
ize
()
int
{
return
4
}
func
(
t
*
tF32
)
S
ize
()
int
{
return
4
}
func
(
t
*
tF32
)
align
()
int
{
return
4
}
func
(
t
*
tF32
)
onFree
()
int
{
return
0
}
func
(
t
*
tF32
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
F32
{}}
}
...
...
@@ -269,10 +313,12 @@ func (t *tF32) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
/**************************************
tF64:
**************************************/
type
tF64
struct
{}
type
tF64
struct
{
tCommon
}
func
(
t
*
tF64
)
Name
()
string
{
return
"f64"
}
func
(
t
*
tF64
)
s
ize
()
int
{
return
8
}
func
(
t
*
tF64
)
S
ize
()
int
{
return
8
}
func
(
t
*
tF64
)
align
()
int
{
return
8
}
func
(
t
*
tF64
)
onFree
()
int
{
return
0
}
func
(
t
*
tF64
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
F64
{}}
}
...
...
internal/backends/compiler_wat/wir/wir.go
浏览文件 @
9dc08a73
...
...
@@ -43,6 +43,8 @@ type Value interface {
EmitPop
()
[]
wat
.
Inst
EmitRelease
()
[]
wat
.
Inst
emitStoreToAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
emitStore
(
offset
int
)
[]
wat
.
Inst
Bin
()
[]
byte
}
/**************************************
...
...
@@ -50,10 +52,15 @@ ValueType:
**************************************/
type
ValueType
interface
{
Name
()
string
s
ize
()
int
S
ize
()
int
align
()
int
onFree
()
int
Raw
()
[]
wat
.
ValueType
Equal
(
ValueType
)
bool
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
//AddMethodEntry(m FnType)
//
Hash
()
int
SetHash
(
h
int
)
}
internal/ssa/ssa.go
浏览文件 @
9dc08a73
...
...
@@ -1468,6 +1468,21 @@ func (v *Function) RuntimeSetter() bool {
v
.
commentInfo
=
&
info
return
info
.
RuntimeSetter
}
func
(
v
*
Function
)
RuntimeSizer
()
bool
{
if
v
.
commentInfo
!=
nil
{
return
v
.
commentInfo
.
RuntimeSizer
}
if
v
.
Object
()
==
nil
{
v
.
commentInfo
=
new
(
astutil
.
CommentInfo
)
return
v
.
commentInfo
.
RuntimeSizer
}
doc
:=
v
.
Object
()
.
NodeDoc
()
info
:=
astutil
.
ParseCommentInfo
(
doc
)
v
.
commentInfo
=
&
info
return
info
.
RuntimeSizer
}
func
(
v
*
Parameter
)
Type
()
types
.
Type
{
return
v
.
typ
}
func
(
v
*
Parameter
)
Name
()
string
{
return
v
.
name
}
...
...
internal/waroot/_waroot/src/runtime/runtime_type.wa
0 → 100644
浏览文件 @
9dc08a73
// 版权 @2019 凹语言 作者。保留所有权利。
// 不要轻易修改本文件!
// Don't modify this file unless you know what you're doing!
type _type struct {
size: u32
hash: i32
kind: u8
align: u8
flag: u16
name: string
}
type _refType struct {
_type
uncommon: uintptr //@_uncommonType
elemType: uintptr //@_type
}
type _arrayType struct {
_type
elemType: uintptr //@_type
cap: uintptr
}
type _sliceType struct {
_type
elemType: uintptr //@_type
}
type _structType struct {
_type
uncommon: uintptr //@_uncommonType
fieldCount: i32
fieldPtr: uintptr //@_structField, len==fieldCount
}
type _structField struct {
name: string
typ: uintptr //@_type
}
type _uncommonType struct {
pkgName: string
methodCount: i32
methodPtr: uintptr //@_method, len==methodCount
}
type _method struct {
name: string
fnType: uintptr //@_fntype
fnID: u32 //id for call_indirect
}
type _fnType struct {
_type
paramCount: i32
paramPtr: uintptr //@@_type, len==paramCount
resultCount: i32
resultPtr: uintptr //@@_type, len==resultCount
}
type _interfaceType struct {
_type
pkgName: string
methodCount: i32
methodPtr: uintptr //@_imethod, len==methodCount
}
type _imethod struct {
name: string
fnType: uintptr //@_fntype
}
type _itab struct {
dtype: uintptr //@_type, ptr of (*data).(type)
itype: uintptr //@_interfacetype
} //紧接[itype.methodCound]fnID, fnID=id for call_indirect
type _iface struct {
data: *i32
itab: uintptr //@_itab
}
#wa:linkname $wa.RT.getTypePtr
func getTypePtr(hash i32) uintptr {
return 0
}
#wa:linkname $wa.RT.getItab
func getItab(dhash i32, ihash i32, commanok i32) i32 {
itab := _itabsPtr + ((dhash - 1) * _interfaceCount - ihash - 1) * 4
return itab
}
#wa:linkname $wa.RT._itabsPtr
var _itabsPtr i32
#wa:linkname $wa.RT._interfaceCount
var _interfaceCount i32
#wa:linkname $wa.RT._concretTypeCount
var _concretTypeCount i32
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录