Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
5ba98d1a
wa
项目概览
wa-lang
/
wa
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
5ba98d1a
编写于
9月 03, 2022
作者:
3
3dgen
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'backend_wasm'
上级
d9682627
b1740a4a
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
1523 addition
and
0 deletion
+1523
-0
internal/backends/compiler_wasm/compile.go
internal/backends/compiler_wasm/compile.go
+95
-0
internal/backends/compiler_wasm/compile_const.go
internal/backends/compiler_wasm/compile_const.go
+12
-0
internal/backends/compiler_wasm/compile_func.go
internal/backends/compiler_wasm/compile_func.go
+437
-0
internal/backends/compiler_wasm/compile_global.go
internal/backends/compiler_wasm/compile_global.go
+11
-0
internal/backends/compiler_wasm/compile_type.go
internal/backends/compiler_wasm/compile_type.go
+12
-0
internal/backends/compiler_wasm/wir/funcion.go
internal/backends/compiler_wasm/wir/funcion.go
+58
-0
internal/backends/compiler_wasm/wir/import.go
internal/backends/compiler_wasm/wir/import.go
+29
-0
internal/backends/compiler_wasm/wir/instruction.go
internal/backends/compiler_wasm/wir/instruction.go
+350
-0
internal/backends/compiler_wasm/wir/instruction_emitter.go
internal/backends/compiler_wasm/wir/instruction_emitter.go
+140
-0
internal/backends/compiler_wasm/wir/module.go
internal/backends/compiler_wasm/wir/module.go
+16
-0
internal/backends/compiler_wasm/wir/util.go
internal/backends/compiler_wasm/wir/util.go
+72
-0
internal/backends/compiler_wasm/wir/value_const.go
internal/backends/compiler_wasm/wir/value_const.go
+80
-0
internal/backends/compiler_wasm/wir/value_var.go
internal/backends/compiler_wasm/wir/value_var.go
+32
-0
internal/backends/compiler_wasm/wir/wir.go
internal/backends/compiler_wasm/wir/wir.go
+97
-0
internal/backends/compiler_wasm/wir/wtypes/wtypes.go
internal/backends/compiler_wasm/wir/wtypes/wtypes.go
+82
-0
未找到文件。
internal/backends/compiler_wasm/compile.go
0 → 100644
浏览文件 @
5ba98d1a
// 版权 @2021 凹语言 作者。保留所有权利。
package
compiler_wasm
import
(
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir"
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/loader"
"github.com/wa-lang/wa/internal/ssa"
)
type
Compiler
struct
{
ssaPkg
*
ssa
.
Package
module
wir
.
Module
}
func
New
()
*
Compiler
{
p
:=
new
(
Compiler
)
return
p
}
func
(
p
*
Compiler
)
Compile
(
prog
*
loader
.
Program
)
(
output
string
,
err
error
)
{
p
.
CompilePackage
(
prog
.
SSAMainPkg
)
return
p
.
String
(),
nil
}
func
(
p
*
Compiler
)
CompilePackage
(
ssaPkg
*
ssa
.
Package
)
{
p
.
ssaPkg
=
ssaPkg
var
ts
[]
*
ssa
.
Type
var
cs
[]
*
ssa
.
NamedConst
var
gs
[]
*
ssa
.
Global
var
fns
[]
*
ssa
.
Function
{
var
sig
wir
.
FuncSig
sig
.
Params
=
append
(
sig
.
Params
,
wtypes
.
Int32
{})
p
.
module
.
Imports
=
append
(
p
.
module
.
Imports
,
wir
.
NewImpFunc
(
"js"
,
"print_i32"
,
"$$print_i32"
,
sig
))
p
.
module
.
Imports
=
append
(
p
.
module
.
Imports
,
wir
.
NewImpFunc
(
"js"
,
"print_char"
,
"$$print_char"
,
sig
))
}
for
_
,
m
:=
range
p
.
ssaPkg
.
Members
{
switch
member
:=
m
.
(
type
)
{
case
*
ssa
.
Type
:
ts
=
append
(
ts
,
member
)
case
*
ssa
.
NamedConst
:
cs
=
append
(
cs
,
member
)
case
*
ssa
.
Global
:
gs
=
append
(
gs
,
member
)
case
*
ssa
.
Function
:
//fns = append(fns, member)
default
:
panic
(
"Unreachable"
)
}
}
for
_
,
v
:=
range
ts
{
p
.
compileType
(
v
)
}
for
_
,
v
:=
range
cs
{
p
.
compileConst
(
v
)
}
for
_
,
v
:=
range
gs
{
p
.
compileGlobal
(
v
)
}
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
}
fns
=
append
(
fns
,
f
)
}
}
for
_
,
v
:=
range
fns
{
p
.
module
.
Funcs
=
append
(
p
.
module
.
Funcs
,
newFunctionGenerator
(
p
)
.
genFunction
(
v
))
}
println
(
p
.
module
.
String
())
}
func
(
p
*
Compiler
)
String
()
string
{
return
""
}
internal/backends/compiler_wasm/compile_const.go
0 → 100644
浏览文件 @
5ba98d1a
// 版权 @2021 凹语言 作者。保留所有权利。
package
compiler_wasm
import
(
"github.com/wa-lang/wa/internal/logger"
"github.com/wa-lang/wa/internal/ssa"
)
func
(
p
*
Compiler
)
compileConst
(
c
*
ssa
.
NamedConst
)
{
logger
.
Fatal
(
"Todo"
)
}
internal/backends/compiler_wasm/compile_func.go
0 → 100644
浏览文件 @
5ba98d1a
// 版权 @2021 凹语言 作者。保留所有权利。
package
compiler_wasm
import
(
"strconv"
"github.com/wa-lang/wa/internal/constant"
"github.com/wa-lang/wa/internal/token"
"github.com/wa-lang/wa/internal/types"
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir"
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/logger"
"github.com/wa-lang/wa/internal/ssa"
)
type
functionGenerator
struct
{
module
*
wir
.
Module
locals_map
map
[
ssa
.
Value
]
wir
.
Value
registers
[]
wir
.
Value
cur_local_id
int
var_block_selector
wir
.
Value
var_current_block
wir
.
Value
var_ret
wir
.
Value
}
func
newFunctionGenerator
(
p
*
Compiler
)
*
functionGenerator
{
return
&
functionGenerator
{
module
:
&
p
.
module
,
locals_map
:
make
(
map
[
ssa
.
Value
]
wir
.
Value
)}
}
func
(
g
*
functionGenerator
)
getValue
(
i
ssa
.
Value
)
wir
.
Value
{
if
i
==
nil
{
return
nil
}
if
v
,
ok
:=
g
.
locals_map
[
i
];
ok
{
return
v
}
switch
v
:=
i
.
(
type
)
{
case
*
ssa
.
Const
:
switch
t
:=
v
.
Type
()
.
(
type
)
{
case
*
types
.
Basic
:
switch
t
.
Kind
()
{
case
types
.
Bool
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
case
types
.
Int
:
val
,
_
:=
constant
.
Int64Val
(
v
.
Value
)
return
wir
.
NewConstI32
(
int32
(
val
))
case
types
.
Float32
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
case
types
.
Float64
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
case
types
.
String
,
types
.
UntypedString
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
default
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
}
case
*
types
.
Slice
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
default
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
}
case
ssa
.
Instruction
:
nv
:=
g
.
addRegister
(
wir
.
ToWType
(
i
.
Type
()))
g
.
locals_map
[
i
]
=
nv
return
nv
}
logger
.
Fatal
(
"Value not found:"
,
i
)
return
nil
}
func
(
g
*
functionGenerator
)
genFunction
(
f
*
ssa
.
Function
)
*
wir
.
Function
{
var
wir_fn
wir
.
Function
wir_fn
.
Name
=
f
.
Name
()
rets
:=
f
.
Signature
.
Results
()
wir_fn
.
Result
=
wir
.
ToWType
(
rets
)
if
rets
.
Len
()
>
1
{
logger
.
Fatal
(
"Todo"
)
}
for
_
,
i
:=
range
f
.
Params
{
pa
:=
wir
.
NewVar
(
i
.
Name
(),
wir
.
ValueKindLocal
,
wir
.
ToWType
(
i
.
Type
()))
wir_fn
.
Params
=
append
(
wir_fn
.
Params
,
pa
)
g
.
locals_map
[
i
]
=
pa
}
g
.
var_block_selector
=
wir
.
NewVar
(
"$$block_selector"
,
wir
.
ValueKindLocal
,
wtypes
.
Int32
{})
g
.
registers
=
append
(
g
.
registers
,
g
.
var_block_selector
)
wir_fn
.
Insts
=
append
(
wir_fn
.
Insts
,
wir
.
EmitAssginValue
(
g
.
var_block_selector
,
nil
)
...
)
g
.
var_current_block
=
wir
.
NewVar
(
"$$current_block"
,
wir
.
ValueKindLocal
,
wtypes
.
Int32
{})
g
.
registers
=
append
(
g
.
registers
,
g
.
var_current_block
)
wir_fn
.
Insts
=
append
(
wir_fn
.
Insts
,
wir
.
EmitAssginValue
(
g
.
var_current_block
,
nil
)
...
)
if
!
wir_fn
.
Result
.
Equal
(
wtypes
.
Void
{})
{
g
.
var_ret
=
wir
.
NewVar
(
"$$ret"
,
wir
.
ValueKindLocal
,
wir_fn
.
Result
)
g
.
registers
=
append
(
g
.
registers
,
g
.
var_ret
)
wir_fn
.
Insts
=
append
(
wir_fn
.
Insts
,
wir
.
EmitAssginValue
(
g
.
var_ret
,
nil
)
...
)
}
var
block_temp
wir
.
Instruction
//BlockSel:
{
inst
:=
wir
.
NewInstBlock
(
"$$BlockSel"
)
inst
.
Insts
=
append
(
inst
.
Insts
,
wir
.
EmitPushValue
(
g
.
var_block_selector
)
...
)
t
:=
make
([]
int
,
len
(
f
.
Blocks
)
+
1
)
for
i
:=
range
f
.
Blocks
{
t
[
i
]
=
i
}
t
[
len
(
f
.
Blocks
)]
=
0
inst
.
Insts
=
append
(
inst
.
Insts
,
wir
.
NewInstBrTable
(
t
))
block_temp
=
inst
}
for
i
,
b
:=
range
f
.
Blocks
{
block
:=
wir
.
NewInstBlock
(
"$$Block_"
+
strconv
.
Itoa
(
i
))
block
.
Insts
=
append
(
block
.
Insts
,
block_temp
)
block
.
Insts
=
append
(
block
.
Insts
,
g
.
genBlock
(
b
)
...
)
block_temp
=
block
}
//BlockDisp
{
inst
:=
wir
.
NewInstLoop
(
"$$BlockDisp"
)
inst
.
Insts
=
append
(
inst
.
Insts
,
block_temp
)
block_temp
=
inst
}
//BlockFnBody
{
inst
:=
wir
.
NewInstBlock
(
"$$BlockFnBody"
)
inst
.
Insts
=
append
(
inst
.
Insts
,
block_temp
)
block_temp
=
inst
}
wir_fn
.
Insts
=
append
(
wir_fn
.
Insts
,
block_temp
)
wir_fn
.
Locals
=
g
.
registers
return
&
wir_fn
}
func
(
g
*
functionGenerator
)
genBlock
(
block
*
ssa
.
BasicBlock
)
[]
wir
.
Instruction
{
if
len
(
block
.
Instrs
)
==
0
{
logger
.
Fatalf
(
"Block:%s is empty"
,
block
)
}
cur_block_assigned
:=
false
var
b
[]
wir
.
Instruction
for
_
,
inst
:=
range
block
.
Instrs
{
if
_
,
ok
:=
inst
.
(
*
ssa
.
Phi
);
!
ok
{
if
!
cur_block_assigned
{
b
=
append
(
b
,
wir
.
EmitAssginValue
(
g
.
var_current_block
,
wir
.
NewConstI32
(
int32
(
block
.
Index
)))
...
)
cur_block_assigned
=
true
}
}
b
=
append
(
b
,
g
.
genInstruction
(
inst
)
...
)
}
return
b
}
func
(
g
*
functionGenerator
)
genInstruction
(
inst
ssa
.
Instruction
)
[]
wir
.
Instruction
{
switch
inst
:=
inst
.
(
type
)
{
case
*
ssa
.
Alloc
:
logger
.
Fatalf
(
"Todo:%T"
,
inst
)
case
*
ssa
.
If
:
return
g
.
genIf
(
inst
)
case
*
ssa
.
Store
:
logger
.
Fatalf
(
"Todo:%T"
,
inst
)
case
*
ssa
.
Jump
:
return
g
.
genJump
(
inst
)
case
*
ssa
.
Return
:
return
g
.
genReturn
(
inst
)
case
*
ssa
.
Extract
:
logger
.
Fatalf
(
"Todo:%T"
,
inst
)
case
*
ssa
.
Field
:
logger
.
Fatalf
(
"Todo:%T"
,
inst
)
case
ssa
.
Value
:
s
,
t
:=
g
.
genValue
(
inst
)
if
!
t
.
Equal
(
wtypes
.
Void
{})
{
v
:=
g
.
getValue
(
inst
)
s
=
append
(
s
,
wir
.
EmitPopValue
(
v
)
...
)
g
.
locals_map
[
inst
]
=
v
}
return
s
default
:
logger
.
Fatal
(
"Todo:"
,
inst
.
String
())
}
return
nil
}
func
(
g
*
functionGenerator
)
genValue
(
v
ssa
.
Value
)
([]
wir
.
Instruction
,
wtypes
.
ValueType
)
{
if
_
,
ok
:=
g
.
locals_map
[
v
];
ok
{
logger
.
Printf
(
"Instruction already exist:%s
\n
"
,
v
)
}
switch
v
:=
v
.
(
type
)
{
case
*
ssa
.
UnOp
:
logger
.
Fatalf
(
"Todo: %v, type: %T"
,
v
,
v
)
case
*
ssa
.
BinOp
:
return
g
.
genBinOp
(
v
)
case
*
ssa
.
Call
:
return
g
.
genCall
(
v
)
case
*
ssa
.
Phi
:
return
g
.
genPhi
(
v
)
case
*
ssa
.
FieldAddr
:
logger
.
Fatalf
(
"Todo: %v, type: %T"
,
v
,
v
)
case
*
ssa
.
IndexAddr
:
logger
.
Fatalf
(
"Todo: %v, type: %T"
,
v
,
v
)
case
*
ssa
.
Slice
:
logger
.
Fatalf
(
"Todo: %v, type: %T"
,
v
,
v
)
}
logger
.
Fatalf
(
"Todo: %v, type: %T"
,
v
,
v
)
return
nil
,
nil
}
func
(
g
*
functionGenerator
)
genBinOp
(
inst
*
ssa
.
BinOp
)
([]
wir
.
Instruction
,
wtypes
.
ValueType
)
{
x
:=
g
.
getValue
(
inst
.
X
)
y
:=
g
.
getValue
(
inst
.
Y
)
switch
inst
.
X
.
Type
()
.
Underlying
()
.
(
type
)
{
case
*
types
.
Basic
:
switch
inst
.
Op
{
case
token
.
ADD
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeAdd
)
case
token
.
SUB
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeSub
)
case
token
.
MUL
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeMul
)
case
token
.
QUO
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeQuo
)
case
token
.
REM
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeRem
)
case
token
.
EQL
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeEql
)
case
token
.
NEQ
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeNe
)
case
token
.
LSS
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeLt
)
case
token
.
GTR
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeGt
)
case
token
.
LEQ
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeLe
)
case
token
.
GEQ
:
return
wir
.
EmitBinOp
(
x
,
y
,
wir
.
OpCodeGe
)
}
default
:
logger
.
Fatalf
(
"Todo: %v, type: %T, token:%v"
,
inst
,
inst
,
inst
.
Op
)
}
logger
.
Fatalf
(
"Todo: %v, type: %T, token:%v"
,
inst
,
inst
,
inst
.
Op
)
return
nil
,
nil
}
func
(
g
*
functionGenerator
)
genCall
(
inst
*
ssa
.
Call
)
([]
wir
.
Instruction
,
wtypes
.
ValueType
)
{
if
inst
.
Call
.
IsInvoke
()
{
logger
.
Fatal
(
"Todo: genCall(), Invoke"
)
}
switch
inst
.
Call
.
Value
.
(
type
)
{
case
*
ssa
.
Function
:
ret_type
:=
wir
.
ToWType
(
inst
.
Call
.
Signature
()
.
Results
())
var
insts
[]
wir
.
Instruction
for
_
,
v
:=
range
inst
.
Call
.
Args
{
insts
=
append
(
insts
,
wir
.
EmitPushValue
(
g
.
getValue
(
v
))
...
)
}
insts
=
append
(
insts
,
wir
.
NewInstCall
(
inst
.
Call
.
StaticCallee
()
.
Name
()))
return
insts
,
ret_type
case
*
ssa
.
Builtin
:
return
g
.
genBuiltin
(
inst
.
Common
())
case
*
ssa
.
MakeClosure
:
logger
.
Fatal
(
"Todo: genCall(), MakeClosure"
)
default
:
logger
.
Fatalf
(
"Todo: type:%T"
,
inst
.
Call
.
Value
)
}
logger
.
Fatal
(
"Todo"
)
return
nil
,
nil
}
func
(
g
*
functionGenerator
)
genBuiltin
(
call
*
ssa
.
CallCommon
)
([]
wir
.
Instruction
,
wtypes
.
ValueType
)
{
switch
call
.
Value
.
Name
()
{
case
"print"
,
"println"
:
var
insts
[]
wir
.
Instruction
for
_
,
arg
:=
range
call
.
Args
{
arg
:=
g
.
getValue
(
arg
)
switch
arg
.
Type
()
.
(
type
)
{
case
wtypes
.
Int32
:
insts
=
append
(
insts
,
wir
.
EmitPushValue
(
arg
)
...
)
insts
=
append
(
insts
,
wir
.
NewInstCall
(
"$$print_i32"
))
default
:
logger
.
Fatalf
(
"Todo: print(%s)"
,
arg
.
Type
()
.
Name
())
}
}
if
call
.
Value
.
Name
()
==
"println"
{
insts
=
append
(
insts
,
wir
.
EmitPushValue
(
wir
.
NewConstI32
(
'\n'
))
...
)
insts
=
append
(
insts
,
wir
.
NewInstCall
(
"$$print_char"
))
}
return
insts
,
wtypes
.
Void
{}
}
logger
.
Fatal
(
"Todo:"
,
call
.
Value
)
return
nil
,
nil
}
func
(
g
*
functionGenerator
)
genPhiIter
(
preds
[]
int
,
values
[]
wir
.
Value
)
[]
wir
.
Instruction
{
var
insts
[]
wir
.
Instruction
cond
,
_
:=
wir
.
EmitBinOp
(
g
.
var_current_block
,
wir
.
NewConstI32
(
int32
(
preds
[
0
])),
wir
.
OpCodeEql
)
insts
=
append
(
insts
,
cond
...
)
trueInsts
:=
append
([]
wir
.
Instruction
(
nil
),
wir
.
EmitPushValue
(
values
[
0
])
...
)
var
falseInsts
[]
wir
.
Instruction
if
len
(
preds
)
==
2
{
falseInsts
=
append
([]
wir
.
Instruction
(
nil
),
wir
.
EmitPushValue
(
values
[
1
])
...
)
}
else
{
falseInsts
=
append
([]
wir
.
Instruction
(
nil
),
g
.
genPhiIter
(
preds
[
1
:
],
values
[
1
:
])
...
)
}
insts
=
append
(
insts
,
wir
.
NewInstIf
(
trueInsts
,
falseInsts
,
values
[
0
]
.
Type
()))
return
insts
}
func
(
g
*
functionGenerator
)
genPhi
(
inst
*
ssa
.
Phi
)
([]
wir
.
Instruction
,
wtypes
.
ValueType
)
{
var
preds
[]
int
var
values
[]
wir
.
Value
for
i
,
v
:=
range
inst
.
Edges
{
preds
=
append
(
preds
,
inst
.
Block
()
.
Preds
[
i
]
.
Index
)
values
=
append
(
values
,
g
.
getValue
(
v
))
}
return
g
.
genPhiIter
(
preds
,
values
),
wir
.
ToWType
(
inst
.
Type
())
}
func
(
g
*
functionGenerator
)
genReturn
(
inst
*
ssa
.
Return
)
[]
wir
.
Instruction
{
var
insts
[]
wir
.
Instruction
switch
len
(
inst
.
Results
)
{
case
0
:
break
case
1
:
insts
=
append
(
insts
,
wir
.
EmitAssginValue
(
g
.
var_ret
,
g
.
getValue
(
inst
.
Results
[
0
]))
...
)
default
:
logger
.
Fatal
(
"Todo"
)
}
insts
=
append
(
insts
,
wir
.
NewInstBr
(
"$$BlockFnBody"
))
return
insts
}
func
(
g
*
functionGenerator
)
genIf
(
inst
*
ssa
.
If
)
[]
wir
.
Instruction
{
cond
:=
g
.
getValue
(
inst
.
Cond
)
if
!
cond
.
Type
()
.
Equal
(
wtypes
.
Int32
{})
{
logger
.
Fatal
(
"cond.type() != i32"
)
}
insts
:=
wir
.
EmitPushValue
(
cond
)
instsTrue
:=
g
.
genJumpID
(
inst
.
Block
()
.
Index
,
inst
.
Block
()
.
Succs
[
0
]
.
Index
)
instsFalse
:=
g
.
genJumpID
(
inst
.
Block
()
.
Index
,
inst
.
Block
()
.
Succs
[
1
]
.
Index
)
insts
=
append
(
insts
,
wir
.
NewInstIf
(
instsTrue
,
instsFalse
,
wtypes
.
Void
{}))
return
insts
}
func
(
g
*
functionGenerator
)
genJump
(
inst
*
ssa
.
Jump
)
[]
wir
.
Instruction
{
return
g
.
genJumpID
(
inst
.
Block
()
.
Index
,
inst
.
Block
()
.
Succs
[
0
]
.
Index
)
}
func
(
g
*
functionGenerator
)
genJumpID
(
cur
,
dest
int
)
[]
wir
.
Instruction
{
var
insts
[]
wir
.
Instruction
if
cur
>=
dest
{
insts
=
wir
.
EmitAssginValue
(
g
.
var_block_selector
,
wir
.
NewConstI32
(
int32
(
dest
)))
insts
=
append
(
insts
,
wir
.
NewInstBr
(
"$$BlockDisp"
))
}
else
{
insts
=
append
(
insts
,
wir
.
NewInstBr
(
"$$Block_"
+
strconv
.
Itoa
(
dest
-
1
)))
}
return
insts
}
func
(
g
*
functionGenerator
)
addRegister
(
typ
wtypes
.
ValueType
)
wir
.
Value
{
defer
func
()
{
g
.
cur_local_id
++
}()
name
:=
"$$T_"
+
strconv
.
Itoa
(
g
.
cur_local_id
)
v
:=
wir
.
NewVar
(
name
,
wir
.
ValueKindLocal
,
typ
)
g
.
registers
=
append
(
g
.
registers
,
v
)
return
v
}
internal/backends/compiler_wasm/compile_global.go
0 → 100644
浏览文件 @
5ba98d1a
// 版权 @2021 凹语言 作者。保留所有权利。
package
compiler_wasm
import
(
"github.com/wa-lang/wa/internal/ssa"
)
func
(
p
*
Compiler
)
compileGlobal
(
g
*
ssa
.
Global
)
{
//logger.Fatal("Todo")
}
internal/backends/compiler_wasm/compile_type.go
0 → 100644
浏览文件 @
5ba98d1a
// 版权 @2021 凹语言 作者。保留所有权利。
package
compiler_wasm
import
(
"github.com/wa-lang/wa/internal/logger"
"github.com/wa-lang/wa/internal/ssa"
)
func
(
p
*
Compiler
)
compileType
(
t
*
ssa
.
Type
)
{
logger
.
Fatal
(
"Todo"
)
}
internal/backends/compiler_wasm/wir/funcion.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
import
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
func
(
f
*
Function
)
Format
(
indent
string
)
string
{
s
:=
indent
+
"(func $"
+
f
.
Name
+
" (export
\"
"
+
f
.
Name
+
"
\"
)"
for
_
,
param
:=
range
f
.
Params
{
rps
:=
param
.
Raw
()
for
_
,
rp
:=
range
rps
{
s
+=
" (param "
+
rp
.
Name
()
+
" "
+
rp
.
Type
()
.
Name
()
+
")"
}
}
if
!
f
.
Result
.
Equal
(
wtypes
.
Void
{})
{
s
+=
" (result"
rrs
:=
f
.
Result
.
Raw
()
for
_
,
rr
:=
range
rrs
{
s
+=
" "
+
rr
.
Name
()
}
s
+=
")"
}
s
+=
"
\n
"
for
_
,
local
:=
range
f
.
Locals
{
rls
:=
local
.
Raw
()
s
+=
indent
+
" "
for
_
,
rl
:=
range
rls
{
s
+=
" (local "
+
rl
.
Name
()
+
" "
+
rl
.
Type
()
.
Name
()
+
")"
}
s
+=
"
\n
"
}
for
_
,
inst
:=
range
f
.
Insts
{
s
+=
inst
.
Format
(
indent
+
" "
)
+
"
\n
"
}
s
+=
indent
+
") ;;"
+
f
.
Name
return
s
}
func
(
sig
*
FuncSig
)
String
()
string
{
str
:=
""
for
_
,
param
:=
range
sig
.
Params
{
rps
:=
param
.
Raw
()
for
_
,
rp
:=
range
rps
{
str
+=
" (param "
+
rp
.
Name
()
+
")"
}
}
for
_
,
ret
:=
range
sig
.
Results
{
rrs
:=
ret
.
Raw
()
for
_
,
rp
:=
range
rrs
{
str
+=
" (result "
+
rp
.
Name
()
+
")"
}
}
return
str
}
internal/backends/compiler_wasm/wir/import.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
/**************************************
ImpObj:
**************************************/
type
ImpObj
struct
{
moduleName
string
objName
string
}
func
(
o
*
ImpObj
)
ModuleName
()
string
{
return
o
.
moduleName
}
func
(
o
*
ImpObj
)
ObjName
()
string
{
return
o
.
objName
}
/**************************************
ImpFunc:
**************************************/
type
ImpFunc
struct
{
ImpObj
funcName
string
sig
FuncSig
}
func
NewImpFunc
(
moduleName
string
,
objName
string
,
funcName
string
,
sig
FuncSig
)
*
ImpFunc
{
return
&
ImpFunc
{
ImpObj
:
ImpObj
{
moduleName
:
moduleName
,
objName
:
objName
},
funcName
:
funcName
,
sig
:
sig
}
}
func
(
o
*
ImpFunc
)
Type
()
ObjType
{
return
ObjTypeFunc
}
func
(
o
*
ImpFunc
)
Format
(
indent
string
)
string
{
return
"(import
\"
"
+
o
.
moduleName
+
"
\"
\"
"
+
o
.
objName
+
"
\"
(func "
+
o
.
funcName
+
o
.
sig
.
String
()
+
"))"
}
internal/backends/compiler_wasm/wir/instruction.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
import
(
"strconv"
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/logger"
)
type
anInstruction
struct
{
}
func
(
i
*
anInstruction
)
isInstruction
()
{}
/**************************************
InstConst:
**************************************/
type
InstConst
struct
{
anInstruction
value
Value
}
func
NewInstConst
(
v
Value
)
*
InstConst
{
if
v
.
Kind
()
!=
ValueKindConst
{
logger
.
Fatal
(
"newInstructionConst()只能接受常数"
)
}
return
&
InstConst
{
value
:
v
}
}
func
(
i
*
InstConst
)
Format
(
indent
string
)
string
{
switch
i
.
value
.
Type
()
.
(
type
)
{
case
wtypes
.
Int32
:
return
indent
+
"i32.const "
+
i
.
value
.
Name
()
case
wtypes
.
Int64
:
return
indent
+
"i64.const "
+
i
.
value
.
Name
()
}
logger
.
Fatalf
(
"Todo %T"
,
i
.
value
.
Type
())
return
""
}
/**************************************
InstGetLocal:
**************************************/
type
InstGetLocal
struct
{
anInstruction
name
string
}
func
NewInstGetLocal
(
name
string
)
*
InstGetLocal
{
return
&
InstGetLocal
{
name
:
name
}
}
func
(
i
*
InstGetLocal
)
Format
(
indent
string
)
string
{
return
indent
+
"local.get "
+
i
.
name
}
/**************************************
instSetLocal:
**************************************/
type
InstSetLocal
struct
{
anInstruction
name
string
}
func
NewInstSetLocal
(
name
string
)
*
InstSetLocal
{
return
&
InstSetLocal
{
name
:
name
}
}
func
(
i
*
InstSetLocal
)
Format
(
indent
string
)
string
{
return
indent
+
"local.set "
+
i
.
name
}
/**************************************
InstAdd:
**************************************/
type
InstAdd
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstAdd
(
t
wtypes
.
ValueType
)
*
InstAdd
{
return
&
InstAdd
{
typ
:
t
}
}
func
(
i
*
InstAdd
)
Format
(
indent
string
)
string
{
return
indent
+
i
.
typ
.
String
()
+
".add"
}
/**************************************
InstSub:
**************************************/
type
InstSub
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstSub
(
t
wtypes
.
ValueType
)
*
InstSub
{
return
&
InstSub
{
typ
:
t
}
}
func
(
i
*
InstSub
)
Format
(
indent
string
)
string
{
return
indent
+
i
.
typ
.
String
()
+
".sub"
}
/**************************************
InstMul:
**************************************/
type
InstMul
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstMul
(
t
wtypes
.
ValueType
)
*
InstMul
{
return
&
InstMul
{
typ
:
t
}
}
func
(
i
*
InstMul
)
Format
(
indent
string
)
string
{
return
indent
+
i
.
typ
.
String
()
+
".mul"
}
/**************************************
InstDiv:
**************************************/
type
InstDiv
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstDiv
(
t
wtypes
.
ValueType
)
*
InstDiv
{
return
&
InstDiv
{
typ
:
t
}
}
func
(
i
*
InstDiv
)
Format
(
indent
string
)
string
{
switch
i
.
typ
.
(
type
)
{
case
wtypes
.
Int32
:
return
indent
+
"i32.div_s"
}
logger
.
Fatal
(
"Todo"
)
return
""
}
/**************************************
InstRem:
**************************************/
type
InstRem
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstRem
(
t
wtypes
.
ValueType
)
*
InstRem
{
return
&
InstRem
{
typ
:
t
}
}
func
(
i
*
InstRem
)
Format
(
indent
string
)
string
{
switch
i
.
typ
.
(
type
)
{
case
wtypes
.
Int32
:
return
indent
+
"i32.rem_s"
}
logger
.
Fatal
(
"Todo"
)
return
""
}
/**************************************
InstEq:
**************************************/
type
InstEq
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstEq
(
t
wtypes
.
ValueType
)
*
InstEq
{
return
&
InstEq
{
typ
:
t
}
}
func
(
i
*
InstEq
)
Format
(
indent
string
)
string
{
return
indent
+
i
.
typ
.
String
()
+
".eq"
}
/**************************************
InstNe:
**************************************/
type
InstNe
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstNe
(
t
wtypes
.
ValueType
)
*
InstNe
{
return
&
InstNe
{
typ
:
t
}
}
func
(
i
*
InstNe
)
Format
(
indent
string
)
string
{
return
indent
+
i
.
typ
.
String
()
+
".ne"
}
/**************************************
InstLt:
**************************************/
type
InstLt
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstLt
(
t
wtypes
.
ValueType
)
*
InstLt
{
return
&
InstLt
{
typ
:
t
}
}
func
(
i
*
InstLt
)
Format
(
indent
string
)
string
{
switch
i
.
typ
.
(
type
)
{
case
wtypes
.
Int32
:
return
indent
+
"i32.lt_s"
}
logger
.
Fatal
(
"Todo"
)
return
""
}
/**************************************
InstGt:
**************************************/
type
InstGt
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstGt
(
t
wtypes
.
ValueType
)
*
InstGt
{
return
&
InstGt
{
typ
:
t
}
}
func
(
i
*
InstGt
)
Format
(
indent
string
)
string
{
switch
i
.
typ
.
(
type
)
{
case
wtypes
.
Int32
:
return
indent
+
"i32.gt_s"
}
logger
.
Fatal
(
"Todo"
)
return
""
}
/**************************************
InstLe:
**************************************/
type
InstLe
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstLe
(
t
wtypes
.
ValueType
)
*
InstLe
{
return
&
InstLe
{
typ
:
t
}
}
func
(
i
*
InstLe
)
Format
(
indent
string
)
string
{
switch
i
.
typ
.
(
type
)
{
case
wtypes
.
Int32
:
return
indent
+
"i32.le_s"
}
logger
.
Fatal
(
"Todo"
)
return
""
}
/**************************************
InstGe:
**************************************/
type
InstGe
struct
{
anInstruction
typ
wtypes
.
ValueType
}
func
NewInstGe
(
t
wtypes
.
ValueType
)
*
InstGe
{
return
&
InstGe
{
typ
:
t
}
}
func
(
i
*
InstGe
)
Format
(
indent
string
)
string
{
switch
i
.
typ
.
(
type
)
{
case
wtypes
.
Int32
:
return
indent
+
"i32.ge_s"
}
logger
.
Fatal
(
"Todo"
)
return
""
}
/**************************************
InstCall:
**************************************/
type
InstCall
struct
{
anInstruction
name
string
}
func
NewInstCall
(
name
string
)
*
InstCall
{
return
&
InstCall
{
name
:
name
}
}
func
(
i
*
InstCall
)
Format
(
indent
string
)
string
{
return
indent
+
"call "
+
i
.
name
}
/**************************************
InstBlock:
**************************************/
type
InstBlock
struct
{
anInstruction
name
string
Insts
[]
Instruction
}
func
NewInstBlock
(
name
string
)
*
InstBlock
{
return
&
InstBlock
{
name
:
name
}
}
func
(
i
*
InstBlock
)
Format
(
indent
string
)
string
{
s
:=
indent
+
"(block "
s
+=
i
.
name
+
"
\n
"
for
_
,
v
:=
range
i
.
Insts
{
s
+=
v
.
Format
(
indent
+
" "
)
+
"
\n
"
}
s
+=
indent
+
") ;;"
+
i
.
name
return
s
}
/**************************************
InstLoop:
**************************************/
type
InstLoop
struct
{
anInstruction
name
string
Insts
[]
Instruction
}
func
NewInstLoop
(
name
string
)
*
InstLoop
{
return
&
InstLoop
{
name
:
name
}
}
func
(
i
*
InstLoop
)
Format
(
indent
string
)
string
{
s
:=
indent
+
"(loop "
s
+=
i
.
name
+
"
\n
"
for
_
,
v
:=
range
i
.
Insts
{
s
+=
v
.
Format
(
indent
+
" "
)
+
"
\n
"
}
s
+=
indent
+
") ;;"
+
i
.
name
return
s
}
/**************************************
InstBr:
**************************************/
type
InstBr
struct
{
anInstruction
Name
string
}
func
NewInstBr
(
name
string
)
*
InstBr
{
return
&
InstBr
{
Name
:
name
}
}
func
(
i
*
InstBr
)
Format
(
indent
string
)
string
{
return
indent
+
"br "
+
i
.
Name
}
/**************************************
InstBrTable:
**************************************/
type
InstBrTable
struct
{
anInstruction
Table
[]
int
}
func
NewInstBrTable
(
t
[]
int
)
*
InstBrTable
{
return
&
InstBrTable
{
Table
:
t
}
}
func
(
i
*
InstBrTable
)
Format
(
indent
string
)
string
{
s
:=
indent
+
"br_table"
for
_
,
v
:=
range
i
.
Table
{
s
+=
" "
+
strconv
.
Itoa
(
v
)
}
return
s
}
/**************************************
InstIf:
**************************************/
type
InstIf
struct
{
anInstruction
True
[]
Instruction
False
[]
Instruction
Ret
wtypes
.
ValueType
}
func
NewInstIf
(
instsTrue
,
instsFalse
[]
Instruction
,
ret
wtypes
.
ValueType
)
*
InstIf
{
return
&
InstIf
{
True
:
instsTrue
,
False
:
instsFalse
,
Ret
:
ret
}
}
func
(
i
*
InstIf
)
Format
(
indent
string
)
string
{
s
:=
indent
+
"if"
if
!
i
.
Ret
.
Equal
(
wtypes
.
Void
{})
{
s
+=
" (result"
rrs
:=
i
.
Ret
.
Raw
()
for
_
,
rr
:=
range
rrs
{
s
+=
" "
+
rr
.
Name
()
}
s
+=
")"
}
s
+=
"
\n
"
for
_
,
v
:=
range
i
.
True
{
s
+=
v
.
Format
(
indent
+
" "
)
+
"
\n
"
}
s
+=
indent
+
"else
\n
"
for
_
,
v
:=
range
i
.
False
{
s
+=
v
.
Format
(
indent
+
" "
)
+
"
\n
"
}
s
+=
indent
+
"end"
return
s
}
/**************************************
InstReturn:
**************************************/
type
InstReturn
struct
{
anInstruction
}
func
NewInstReturn
()
*
InstReturn
{
return
&
InstReturn
{}
}
func
(
i
*
InstReturn
)
Format
(
indent
string
)
string
{
return
indent
+
"return"
}
internal/backends/compiler_wasm/wir/instruction_emitter.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
import
(
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/logger"
)
func
EmitPushValue
(
x
Value
)
[]
Instruction
{
var
insts
[]
Instruction
vs
:=
x
.
Raw
()
if
len
(
vs
)
>
1
{
for
_
,
v
:=
range
vs
{
insts
=
append
(
insts
,
EmitPushValue
(
v
)
...
)
}
}
switch
x
.
Kind
()
{
case
ValueKindConst
:
insts
=
append
(
insts
,
NewInstConst
(
x
))
case
ValueKindLocal
:
insts
=
append
(
insts
,
NewInstGetLocal
(
x
.
Name
()))
case
ValueKindGlobal
:
logger
.
Fatal
(
"Todo"
)
}
return
insts
}
func
EmitPopValue
(
x
Value
)
[]
Instruction
{
var
insts
[]
Instruction
vs
:=
x
.
Raw
()
if
len
(
vs
)
>
1
{
for
_
,
v
:=
range
vs
{
insts
=
append
(
insts
,
EmitPopValue
(
v
)
...
)
}
}
switch
x
.
Kind
()
{
case
ValueKindConst
:
logger
.
Fatal
(
"不可Pop至常数"
)
case
ValueKindLocal
:
insts
=
append
(
insts
,
NewInstSetLocal
(
x
.
Name
()))
case
ValueKindGlobal
:
logger
.
Fatal
(
"Todo"
)
}
return
insts
}
func
EmitAssginValue
(
lh
,
rh
Value
)
[]
Instruction
{
var
insts
[]
Instruction
if
rh
==
nil
{
ls
:=
lh
.
Raw
()
for
_
,
v
:=
range
ls
{
c
:=
NewConst
(
v
.
Type
(),
nil
)
insts
=
append
(
insts
,
EmitPushValue
(
c
)
...
)
insts
=
append
(
insts
,
EmitPopValue
(
v
)
...
)
}
}
else
{
if
!
lh
.
Type
()
.
Equal
(
rh
.
Type
())
{
logger
.
Fatal
(
"x.Type() != y.Type()"
)
}
ls
:=
lh
.
Raw
()
rs
:=
rh
.
Raw
()
for
i
:=
range
ls
{
insts
=
append
(
insts
,
EmitPushValue
(
rs
[
i
])
...
)
insts
=
append
(
insts
,
EmitPopValue
(
ls
[
i
])
...
)
}
}
return
insts
}
func
EmitConvertValueType
(
from
,
to
wtypes
.
ValueType
)
{
logger
.
Fatal
(
"Todo"
)
}
func
EmitBinOp
(
x
,
y
Value
,
op
OpCode
)
([]
Instruction
,
wtypes
.
ValueType
)
{
var
insts
[]
Instruction
rtype
:=
binOpMatchType
(
x
.
Type
(),
y
.
Type
())
insts
=
append
(
insts
,
EmitPushValue
(
x
)
...
)
insts
=
append
(
insts
,
EmitPushValue
(
y
)
...
)
switch
op
{
case
OpCodeAdd
:
insts
=
append
(
insts
,
NewInstAdd
(
rtype
))
case
OpCodeSub
:
insts
=
append
(
insts
,
NewInstSub
(
rtype
))
case
OpCodeMul
:
insts
=
append
(
insts
,
NewInstMul
(
rtype
))
case
OpCodeQuo
:
insts
=
append
(
insts
,
NewInstDiv
(
rtype
))
case
OpCodeRem
:
insts
=
append
(
insts
,
NewInstRem
(
rtype
))
case
OpCodeEql
:
insts
=
append
(
insts
,
NewInstEq
(
rtype
))
case
OpCodeNe
:
insts
=
append
(
insts
,
NewInstNe
(
rtype
))
case
OpCodeLt
:
insts
=
append
(
insts
,
NewInstLt
(
rtype
))
case
OpCodeGt
:
insts
=
append
(
insts
,
NewInstGt
(
rtype
))
case
OpCodeLe
:
insts
=
append
(
insts
,
NewInstLe
(
rtype
))
case
OpCodeGe
:
insts
=
append
(
insts
,
NewInstGe
(
rtype
))
default
:
logger
.
Fatal
(
"Todo"
)
}
return
insts
,
rtype
}
func
binOpMatchType
(
x
,
y
wtypes
.
ValueType
)
wtypes
.
ValueType
{
if
x
.
Equal
(
y
)
{
return
x
}
logger
.
Fatalf
(
"Todo %T %T"
,
x
,
y
)
return
nil
}
internal/backends/compiler_wasm/wir/module.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
func
(
m
*
Module
)
String
()
string
{
s
:=
"(module
\n
"
for
_
,
i
:=
range
m
.
Imports
{
s
+=
i
.
Format
(
" "
)
+
"
\n
"
}
for
_
,
f
:=
range
m
.
Funcs
{
s
+=
f
.
Format
(
" "
)
+
"
\n
"
}
s
+=
") ;;module"
return
s
}
internal/backends/compiler_wasm/wir/util.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
import
(
"github.com/wa-lang/wa/internal/types"
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/logger"
)
func
ToWType
(
from
types
.
Type
)
wtypes
.
ValueType
{
switch
t
:=
from
.
(
type
)
{
case
*
types
.
Basic
:
switch
t
.
Kind
()
{
case
types
.
Bool
:
return
wtypes
.
Int32
{}
case
types
.
Int8
,
types
.
UntypedBool
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Uint8
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Int16
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Uint16
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Int
,
types
.
Int32
,
types
.
UntypedInt
:
return
wtypes
.
Int32
{}
case
types
.
Uint
,
types
.
Uint32
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Int64
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Uint64
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Float32
,
types
.
UntypedFloat
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
Float64
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
case
types
.
String
:
logger
.
Fatalf
(
"ToWType Todo:%T"
,
t
)
default
:
logger
.
Fatalf
(
"Unknown type:%s"
,
t
)
return
nil
}
case
*
types
.
Tuple
:
switch
t
.
Len
()
{
case
0
:
return
wtypes
.
Void
{}
case
1
:
return
ToWType
(
t
.
At
(
0
)
.
Type
())
default
:
logger
.
Fatalf
(
"Todo type:%s"
,
t
)
}
default
:
logger
.
Fatalf
(
"Todo:%T"
,
t
)
}
return
nil
}
internal/backends/compiler_wasm/wir/value_const.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
import
(
"strconv"
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/logger"
)
type
Const
interface
{
Value
}
/**************************************
ConstZero:
**************************************/
/*type ConstZero struct {
}
func NewConstZero() *ConstZero { return &ConstZero{} }
func (c *ConstZero) Name() string { return "0" }
func (c *ConstZero) Kind() ValueKind { return ValueKindConst }
func (c *ConstZero) Type() wtypes.ValueType { return wtypes.Void{} }
func (c *ConstZero) Raw() []Value { return append([]Value(nil), c) }
//*/
func
NewConst
(
t
wtypes
.
ValueType
,
v
interface
{})
Const
{
switch
t
.
(
type
)
{
case
wtypes
.
Int32
:
if
v
==
nil
{
return
NewConstI32
(
0
)
}
if
c
,
ok
:=
v
.
(
int
);
ok
{
return
NewConstI32
(
int32
(
c
))
}
logger
.
Fatal
(
"Todo"
)
case
wtypes
.
Int64
:
if
v
==
nil
{
return
NewConstI64
(
0
)
}
if
c
,
ok
:=
v
.
(
int
);
ok
{
return
NewConstI64
(
int64
(
c
))
}
logger
.
Fatal
(
"Todo"
)
default
:
logger
.
Fatal
(
"Todo"
)
}
return
nil
}
/**************************************
ConstInt32:
**************************************/
type
ConstI32
struct
{
x
int32
}
func
NewConstI32
(
x
int32
)
*
ConstI32
{
return
&
ConstI32
{
x
:
x
}
}
func
(
c
*
ConstI32
)
Name
()
string
{
return
strconv
.
FormatInt
(
int64
(
c
.
x
),
10
)
}
func
(
c
*
ConstI32
)
Kind
()
ValueKind
{
return
ValueKindConst
}
func
(
c
*
ConstI32
)
Type
()
wtypes
.
ValueType
{
return
wtypes
.
Int32
{}
}
func
(
c
*
ConstI32
)
Raw
()
[]
Value
{
return
append
([]
Value
(
nil
),
c
)
}
/**************************************
ConstInt64:
**************************************/
type
ConstI64
struct
{
x
int64
}
func
NewConstI64
(
x
int64
)
*
ConstI64
{
return
&
ConstI64
{
x
:
x
}
}
func
(
c
*
ConstI64
)
Name
()
string
{
return
strconv
.
FormatInt
(
c
.
x
,
10
)
}
func
(
c
*
ConstI64
)
Kind
()
ValueKind
{
return
ValueKindConst
}
func
(
c
*
ConstI64
)
Type
()
wtypes
.
ValueType
{
return
wtypes
.
Int64
{}
}
func
(
c
*
ConstI64
)
Raw
()
[]
Value
{
return
append
([]
Value
(
nil
),
c
)
}
internal/backends/compiler_wasm/wir/value_var.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
import
(
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/logger"
)
func
NewVar
(
name
string
,
kind
ValueKind
,
typ
wtypes
.
ValueType
)
Value
{
switch
typ
.
(
type
)
{
case
wtypes
.
Int32
:
return
&
VarI32
{
name
:
name
,
kind
:
kind
,
typ
:
typ
}
default
:
logger
.
Fatalf
(
"Todo: %T"
,
typ
)
}
return
nil
}
/**************************************
VarI32:
**************************************/
type
VarI32
struct
{
name
string
kind
ValueKind
typ
wtypes
.
ValueType
}
func
(
v
*
VarI32
)
Name
()
string
{
return
v
.
name
}
func
(
v
*
VarI32
)
Kind
()
ValueKind
{
return
v
.
kind
}
func
(
v
*
VarI32
)
Type
()
wtypes
.
ValueType
{
return
v
.
typ
}
func
(
v
*
VarI32
)
Raw
()
[]
Value
{
return
append
([]
Value
(
nil
),
v
)
}
internal/backends/compiler_wasm/wir/wir.go
0 → 100644
浏览文件 @
5ba98d1a
package
wir
import
(
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
)
type
Module
struct
{
Imports
[]
Import
Funcs
[]
*
Function
}
/**************************************
Import:
**************************************/
type
Import
interface
{
Format
(
indent
string
)
string
ModuleName
()
string
ObjName
()
string
Type
()
ObjType
}
/**************************************
Function:
**************************************/
type
Function
struct
{
Name
string
Result
wtypes
.
ValueType
Params
[]
Value
Locals
[]
Value
Insts
[]
Instruction
}
/**************************************
FuncSig:
**************************************/
type
FuncSig
struct
{
Params
[]
wtypes
.
ValueType
Results
[]
wtypes
.
ValueType
}
/**************************************
Instruction:
**************************************/
type
Instruction
interface
{
Format
(
indent
string
)
string
isInstruction
()
}
type
ValueKind
uint8
const
(
ValueKindLocal
ValueKind
=
iota
ValueKindGlobal
ValueKindConst
)
/**************************************
Value:
**************************************/
type
Value
interface
{
Name
()
string
Kind
()
ValueKind
Type
()
wtypes
.
ValueType
Raw
()
[]
Value
}
/**************************************
OpCode:
**************************************/
type
OpCode
int32
const
(
OpCodeAdd
OpCode
=
iota
OpCodeSub
OpCodeMul
OpCodeQuo
OpCodeRem
OpCodeEql
OpCodeNe
OpCodeLt
OpCodeGt
OpCodeLe
OpCodeGe
)
/**************************************
ObjType:
**************************************/
type
ObjType
int32
const
(
ObjTypeFunc
ObjType
=
iota
ObjTypeMem
ObjTypeTable
ObjTypeGlobal
)
internal/backends/compiler_wasm/wir/wtypes/wtypes.go
0 → 100644
浏览文件 @
5ba98d1a
package
wtypes
import
"fmt"
type
ValueType
interface
{
fmt
.
Stringer
Name
()
string
GetByteSize
()
int
Raw
()
[]
ValueType
Equal
(
ValueType
)
bool
}
/**************************************
Void:
**************************************/
type
Void
struct
{
}
func
(
t
Void
)
String
()
string
{
return
t
.
Name
()
}
func
(
t
Void
)
Name
()
string
{
return
"void"
}
func
(
t
Void
)
GetByteSize
()
int
{
return
0
}
func
(
t
Void
)
Raw
()
[]
ValueType
{
return
append
([]
ValueType
(
nil
),
t
)
}
func
(
t
Void
)
Equal
(
u
ValueType
)
bool
{
if
_
,
ok
:=
u
.
(
Void
);
ok
{
return
true
}
return
false
}
/**************************************
Int32:
**************************************/
type
Int32
struct
{
}
func
(
t
Int32
)
String
()
string
{
return
t
.
Name
()
}
func
(
t
Int32
)
Name
()
string
{
return
"i32"
}
func
(
t
Int32
)
GetByteSize
()
int
{
return
4
}
func
(
t
Int32
)
Raw
()
[]
ValueType
{
return
append
([]
ValueType
(
nil
),
t
)
}
func
(
t
Int32
)
Equal
(
u
ValueType
)
bool
{
if
_
,
ok
:=
u
.
(
Int32
);
ok
{
return
true
}
return
false
}
/**************************************
Int64:
**************************************/
type
Int64
struct
{
}
func
(
t
Int64
)
String
()
string
{
return
t
.
Name
()
}
func
(
t
Int64
)
Name
()
string
{
return
"i64"
}
func
(
t
Int64
)
GetByteSize
()
int
{
return
8
}
func
(
t
Int64
)
Raw
()
[]
ValueType
{
return
append
([]
ValueType
(
nil
),
t
)
}
func
(
t
Int64
)
Equal
(
u
ValueType
)
bool
{
if
_
,
ok
:=
u
.
(
Int64
);
ok
{
return
true
}
return
false
}
/**************************************
Pointer:
**************************************/
type
Pointer
struct
{
Base
ValueType
}
func
NewPointer
(
base
ValueType
)
Pointer
{
return
Pointer
{
Base
:
base
}
}
func
(
t
Pointer
)
String
()
string
{
return
"*"
+
t
.
Base
.
Name
()
}
func
(
t
Pointer
)
Name
()
string
{
return
"Todo"
}
func
(
t
Pointer
)
GetByteSize
()
int
{
return
4
}
func
(
t
Pointer
)
Raw
()
[]
ValueType
{
return
append
([]
ValueType
(
nil
),
Int32
{})
}
func
(
t
Pointer
)
Equal
(
u
ValueType
)
bool
{
if
ut
,
ok
:=
u
.
(
Pointer
);
ok
{
return
t
.
Base
.
Equal
(
ut
.
Base
)
}
return
false
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录