Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
0fa2cfa3
wa
项目概览
wa-lang
/
wa
9 个月 前同步成功
通知
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,体验更适合开发者的 AI 搜索 >>
提交
0fa2cfa3
编写于
6月 07, 2023
作者:
3
3dgen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
支持非标类型相等操作
上级
e5ed1490
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
419 addition
and
55 deletion
+419
-55
_examples/eq.wa
_examples/eq.wa
+123
-0
internal/backends/compiler_wat/compile_func.go
internal/backends/compiler_wat/compile_func.go
+25
-30
internal/backends/compiler_wat/wir/instruction_emitter.go
internal/backends/compiler_wat/wir/instruction_emitter.go
+81
-18
internal/backends/compiler_wat/wir/module.go
internal/backends/compiler_wat/wir/module.go
+11
-0
internal/backends/compiler_wat/wir/value_basic.go
internal/backends/compiler_wat/wir/value_basic.go
+13
-0
internal/backends/compiler_wat/wir/value_block.go
internal/backends/compiler_wat/wir/value_block.go
+5
-0
internal/backends/compiler_wat/wir/value_closure.go
internal/backends/compiler_wat/wir/value_closure.go
+5
-0
internal/backends/compiler_wat/wir/value_dup.go
internal/backends/compiler_wat/wir/value_dup.go
+8
-0
internal/backends/compiler_wat/wir/value_interface.go
internal/backends/compiler_wat/wir/value_interface.go
+61
-3
internal/backends/compiler_wat/wir/value_ref.go
internal/backends/compiler_wat/wir/value_ref.go
+8
-0
internal/backends/compiler_wat/wir/value_slice.go
internal/backends/compiler_wat/wir/value_slice.go
+5
-0
internal/backends/compiler_wat/wir/value_string.go
internal/backends/compiler_wat/wir/value_string.go
+14
-0
internal/backends/compiler_wat/wir/value_struct.go
internal/backends/compiler_wat/wir/value_struct.go
+26
-0
internal/backends/compiler_wat/wir/value_type.go
internal/backends/compiler_wat/wir/value_type.go
+7
-4
internal/backends/compiler_wat/wir/wat/instruction_bit.go
internal/backends/compiler_wat/wir/wat/instruction_bit.go
+22
-0
internal/backends/compiler_wat/wir/wir.go
internal/backends/compiler_wat/wir/wir.go
+5
-0
未找到文件。
_examples/eq.wa
0 → 100644
浏览文件 @
0fa2cfa3
// 版权 @2021 凹语言 作者。保留所有权利。
type T1 struct {
a: i32
b: string
}
func T1.print(){
println("a: ", this.a)
}
type I interface {
print()
}
type T2 struct {
a: []i32
}
func main() {
var v1, v2: T1
v1.a = 13
v2.a = 42
if v1 == v2 {
println("eq")
} else {
println("ne")
}
v2.a = 13
if v1 == v2 {
println("eq")
} else {
println("ne")
}
v1.b = "abc"
if v1 == v2 {
println("eq")
} else {
println("ne")
}
v2.b = "abc"
if v1 == v2 {
println("eq")
} else {
println("ne")
}
var i1, i2: interface{}
i1 = i32(13)
i2 = i32(42)
if i1 == i2 {
println("eq")
} else {
println("ne")
}
i2 = i32(13)
if i1 == i2 {
println("eq")
} else {
println("ne")
}
i2 = "abc"
if i1 == i2 {
println("eq")
} else {
println("ne")
}
i1 = "abc"
if i1 == i2 {
println("eq")
} else {
println("ne")
}
i1 = v1
if i1 == i2 {
println("eq")
} else {
println("ne")
}
i2 = v1
if i1 == i2 {
println("eq")
} else {
println("ne")
}
var i3: I
i3 = &v1
if i1 == i3 {
println("eq")
} else {
println("ne")
}
i1 = &v1
if i1 == i3 {
println("eq")
} else {
println("ne")
}
var v3, v4: T2
//if v3 == v4 {
// println("eq")
//} else {
// println("ne")
//}
i1 = v3
i2 = v4
if i1 == i2 { //panic
println("eq")
} else {
println("ne")
}
}
internal/backends/compiler_wat/compile_func.go
浏览文件 @
0fa2cfa3
...
...
@@ -434,49 +434,44 @@ func (g *functionGenerator) genBinOp(inst *ssa.BinOp) ([]wat.Inst, wir.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
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeAdd
)
switch
inst
.
Op
{
case
token
.
ADD
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeAdd
)
case
token
.
SUB
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeSub
)
case
token
.
SUB
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeSub
)
case
token
.
MUL
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeMul
)
case
token
.
MUL
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeMul
)
case
token
.
QUO
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeQuo
)
case
token
.
QUO
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeQuo
)
case
token
.
REM
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeRem
)
case
token
.
REM
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeRem
)
case
token
.
EQL
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeEql
)
case
token
.
EQL
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeEql
)
case
token
.
NEQ
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeNe
)
case
token
.
NEQ
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeNe
)
case
token
.
LSS
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeLt
)
case
token
.
LSS
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeLt
)
case
token
.
GTR
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeGt
)
case
token
.
GTR
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeGt
)
case
token
.
LEQ
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeLe
)
case
token
.
LEQ
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeLe
)
case
token
.
GEQ
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeGe
)
}
case
token
.
GEQ
:
return
g
.
module
.
EmitBinOp
(
x
.
value
,
y
.
value
,
wat
.
OpCodeGe
)
default
:
logger
.
Fatalf
(
"Todo: %v, type: %T, token:%v"
,
inst
,
inst
,
inst
.
Op
)
logger
.
Fatalf
(
"Todo: %v, type: %T, token:%v"
,
inst
,
x
.
value
,
inst
.
Op
)
return
nil
,
nil
}
logger
.
Fatalf
(
"Todo: %v, type: %T, token:%v"
,
inst
,
inst
,
inst
.
Op
)
return
nil
,
nil
}
func
(
g
*
functionGenerator
)
genCall
(
inst
*
ssa
.
Call
)
(
insts
[]
wat
.
Inst
,
ret_type
wir
.
ValueType
)
{
...
...
internal/backends/compiler_wat/wir/instruction_emitter.go
浏览文件 @
0fa2cfa3
...
...
@@ -43,13 +43,28 @@ func (m *Module) EmitUnOp(x Value, op wat.OpCode) (insts []wat.Inst, ret_type Va
}
func
(
m
*
Module
)
EmitBinOp
(
x
,
y
Value
,
op
wat
.
OpCode
)
(
insts
[]
wat
.
Inst
,
ret_type
ValueType
)
{
rtype
:=
m
.
binOpMatchType
(
x
.
Type
(),
y
.
Type
())
for
{
if
ut
,
ok
:=
x
.
(
*
aDup
);
ok
{
x
=
ut
.
underlying
}
else
{
break
}
}
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
for
{
if
ut
,
ok
:=
y
.
(
*
aDup
);
ok
{
y
=
ut
.
underlying
}
else
{
break
}
}
rtype
:=
m
.
binOpMatchType
(
x
.
Type
(),
y
.
Type
())
switch
op
{
case
wat
.
OpCodeAdd
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
if
rtype
.
Equal
(
m
.
STRING
)
{
insts
=
append
(
insts
,
wat
.
NewInstCall
(
m
.
STRING
.
(
*
String
)
.
genFunc_Append
()))
}
else
{
...
...
@@ -58,52 +73,61 @@ func (m *Module) EmitBinOp(x, y Value, op wat.OpCode) (insts []wat.Inst, ret_typ
ret_type
=
rtype
case
wat
.
OpCodeSub
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstSub
(
toWatType
(
rtype
)))
ret_type
=
rtype
case
wat
.
OpCodeMul
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstMul
(
toWatType
(
rtype
)))
ret_type
=
rtype
case
wat
.
OpCodeQuo
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstDiv
(
toWatType
(
rtype
)))
ret_type
=
rtype
case
wat
.
OpCodeRem
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstRem
(
toWatType
(
rtype
)))
ret_type
=
rtype
case
wat
.
OpCodeEql
:
if
rtype
.
Equal
(
m
.
STRING
)
{
insts
=
append
(
insts
,
wat
.
NewInstCall
(
m
.
STRING
.
(
*
String
)
.
genFunc_Equal
()))
}
else
{
insts
=
append
(
insts
,
wat
.
NewInstEq
(
toWatType
(
rtype
)))
}
ins
,
_
:=
x
.
emitEq
(
y
)
insts
=
append
(
insts
,
ins
...
)
ret_type
=
m
.
I32
case
wat
.
OpCodeNe
:
if
rtype
.
Equal
(
m
.
STRING
)
{
insts
=
append
(
insts
,
wat
.
NewInstCall
(
m
.
STRING
.
(
*
String
)
.
genFunc_Equal
()))
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
"1"
))
insts
=
append
(
insts
,
wat
.
NewInstXor
(
wat
.
I32
{}))
}
else
{
insts
=
append
(
insts
,
wat
.
NewInstNe
(
toWatType
(
rtype
)))
}
ins
,
_
:=
x
.
emitEq
(
y
)
insts
=
append
(
insts
,
ins
...
)
insts
=
append
(
insts
,
wat
.
NewInstEqz
(
wat
.
I32
{}))
ret_type
=
m
.
I32
case
wat
.
OpCodeLt
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstLt
(
toWatType
(
rtype
)))
ret_type
=
m
.
I32
case
wat
.
OpCodeGt
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstGt
(
toWatType
(
rtype
)))
ret_type
=
m
.
I32
case
wat
.
OpCodeLe
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstLe
(
toWatType
(
rtype
)))
ret_type
=
m
.
I32
case
wat
.
OpCodeGe
:
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
insts
=
append
(
insts
,
y
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstGe
(
toWatType
(
rtype
)))
ret_type
=
m
.
I32
...
...
@@ -445,11 +469,50 @@ func (m *Module) EmitGenMakeInterface(x Value, itype ValueType) (insts []wat.Ins
switch
x
:=
x
.
(
type
)
{
case
*
aRef
:
return
itype
.
(
*
Interface
)
.
emitGenFrom
SPtr
(
x
)
return
itype
.
(
*
Interface
)
.
emitGenFrom
Ref
(
x
)
default
:
sptr_t
:=
m
.
GenValueType_Ref
(
x
.
Type
())
return
itype
.
(
*
Interface
)
.
emitGenFromValue
(
x
,
sptr_t
)
compID
:=
x_type
.
OnComp
()
if
compID
==
0
{
var
f
Function
f
.
InternalName
=
"$"
+
GenSymbolName
(
x_type
.
Name
())
+
".$$compAddr"
p0
:=
NewLocal
(
"p0"
,
m
.
GenValueType_Ptr
(
x_type
))
p1
:=
NewLocal
(
"p1"
,
m
.
GenValueType_Ptr
(
x_type
))
f
.
Params
=
append
(
f
.
Params
,
p0
)
f
.
Params
=
append
(
f
.
Params
,
p1
)
f
.
Results
=
append
(
f
.
Results
,
m
.
I32
)
v0
:=
NewLocal
(
"v0"
,
x_type
)
v1
:=
NewLocal
(
"v1"
,
x_type
)
f
.
Locals
=
append
(
f
.
Locals
,
v0
)
f
.
Locals
=
append
(
f
.
Locals
,
v1
)
f
.
Insts
=
append
(
f
.
Insts
,
v0
.
EmitInit
()
...
)
f
.
Insts
=
append
(
f
.
Insts
,
v1
.
EmitInit
()
...
)
f
.
Insts
=
append
(
f
.
Insts
,
x_type
.
EmitLoadFromAddr
(
p0
,
0
)
...
)
f
.
Insts
=
append
(
f
.
Insts
,
v0
.
EmitPop
()
...
)
f
.
Insts
=
append
(
f
.
Insts
,
x_type
.
EmitLoadFromAddr
(
p1
,
0
)
...
)
f
.
Insts
=
append
(
f
.
Insts
,
v1
.
EmitPop
()
...
)
if
ins
,
ok
:=
v0
.
emitEq
(
v1
);
ok
{
f
.
Insts
=
append
(
f
.
Insts
,
ins
...
)
f
.
Insts
=
append
(
f
.
Insts
,
v0
.
EmitRelease
()
...
)
f
.
Insts
=
append
(
f
.
Insts
,
v1
.
EmitRelease
()
...
)
m
.
AddFunc
(
&
f
)
compID
=
m
.
AddTableElem
(
f
.
InternalName
)
}
else
{
compID
=
-
1
}
x_type
.
setOnComp
(
compID
)
}
ref_t
:=
m
.
GenValueType_Ref
(
x_type
)
return
itype
.
(
*
Interface
)
.
emitGenFromValue
(
x
,
ref_t
,
compID
)
}
}
...
...
internal/backends/compiler_wat/wir/module.go
浏览文件 @
0fa2cfa3
...
...
@@ -244,6 +244,17 @@ func (m *Module) ToWatModule() *wat.Module {
onfree_type
.
Params
=
m
.
I32
.
Raw
()
wat_module
.
FuncTypes
=
append
(
wat_module
.
FuncTypes
,
onfree_type
)
}
{
var
comp_type
wat
.
FuncType
comp_type
.
Name
=
"$wa.runtime.comp"
ptr_t
:=
m
.
GenValueType_Ptr
(
m
.
VOID
)
comp_type
.
Params
=
append
(
comp_type
.
Params
,
ptr_t
.
Raw
()
...
)
comp_type
.
Params
=
append
(
comp_type
.
Params
,
ptr_t
.
Raw
()
...
)
comp_type
.
Results
=
append
(
comp_type
.
Results
,
m
.
I32
.
Raw
()
...
)
wat_module
.
FuncTypes
=
append
(
wat_module
.
FuncTypes
,
comp_type
)
}
for
_
,
t
:=
range
m
.
fnSigs
{
var
fn_type
wat
.
FuncType
fn_type
.
Name
=
m
.
fnSigsName
[
t
.
String
()]
.
name
...
...
internal/backends/compiler_wat/wir/value_basic.go
浏览文件 @
0fa2cfa3
...
...
@@ -206,3 +206,16 @@ func (v *aBasic) Bin() (b []byte) {
return
}
func
(
v
*
aBasic
)
emitEq
(
r
Value
)
(
insts
[]
wat
.
Inst
,
ok
bool
)
{
if
!
v
.
Type
()
.
Equal
(
r
.
Type
())
{
logger
.
Fatal
(
"v.Type() != r.Type()"
)
}
insts
=
append
(
insts
,
v
.
EmitPush
()
...
)
insts
=
append
(
insts
,
r
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstEq
(
toWatType
(
v
.
Type
())))
ok
=
true
return
}
internal/backends/compiler_wat/wir/value_block.go
浏览文件 @
0fa2cfa3
...
...
@@ -188,3 +188,8 @@ func (v *aBlock) Bin() (b []byte) {
return
}
func
(
v
*
aBlock
)
emitEq
(
r
Value
)
([]
wat
.
Inst
,
bool
)
{
//logger.Fatal("aBlock shouldn't be compared.")
return
nil
,
false
}
internal/backends/compiler_wat/wir/value_closure.go
浏览文件 @
0fa2cfa3
...
...
@@ -149,3 +149,8 @@ func EmitCallClosure(c Value, params []Value) (insts []wat.Inst) {
insts
=
append
(
insts
,
wat
.
NewInstCallIndirect
(
closure
.
typ
.
_fnTypeName
))
return
}
func
(
v
*
aClosure
)
emitEq
(
r
Value
)
([]
wat
.
Inst
,
bool
)
{
//logger.Fatal("aClosure can't be compared.")
return
nil
,
false
}
internal/backends/compiler_wat/wir/value_dup.go
浏览文件 @
0fa2cfa3
...
...
@@ -4,6 +4,7 @@ package wir
import
(
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
/**************************************
...
...
@@ -79,3 +80,10 @@ func (v *aDup) emitStore(offset int) []wat.Inst {
func
(
v
*
aDup
)
Bin
()
[]
byte
{
return
v
.
underlying
.
Bin
()
}
func
(
v
*
aDup
)
emitEq
(
r
Value
)
(
insts
[]
wat
.
Inst
,
ok
bool
)
{
if
!
v
.
Type
()
.
Equal
(
r
.
Type
())
{
logger
.
Fatal
(
"v.Type() != r.Type()"
)
}
return
v
.
underlying
.
emitEq
(
r
.
(
*
aDup
)
.
underlying
)
}
internal/backends/compiler_wat/wir/value_interface.go
浏览文件 @
0fa2cfa3
...
...
@@ -6,6 +6,7 @@ import (
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
/**************************************
...
...
@@ -29,6 +30,7 @@ func (m *Module) GenValueType_Interface(name string) *Interface {
interface_t
.
underlying
=
m
.
genInternalStruct
(
interface_t
.
Name
()
+
".underlying"
)
interface_t
.
underlying
.
AppendField
(
m
.
NewStructField
(
"data"
,
m
.
GenValueType_Ref
(
m
.
VOID
)))
interface_t
.
underlying
.
AppendField
(
m
.
NewStructField
(
"itab"
,
m
.
UPTR
))
interface_t
.
underlying
.
AppendField
(
m
.
NewStructField
(
"eq"
,
m
.
I32
))
interface_t
.
underlying
.
Finish
()
m
.
addValueType
(
&
interface_t
)
...
...
@@ -52,7 +54,7 @@ func (t *Interface) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
return
t
.
underlying
.
EmitLoadFromAddr
(
addr
,
offset
)
}
func
(
t
*
Interface
)
emitGenFrom
SPtr
(
x
*
aRef
)
(
insts
[]
wat
.
Inst
)
{
func
(
t
*
Interface
)
emitGenFrom
Ref
(
x
*
aRef
)
(
insts
[]
wat
.
Inst
)
{
insts
=
append
(
insts
,
x
.
EmitPush
()
...
)
//data
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
strconv
.
Itoa
(
x
.
Type
()
.
Hash
())))
...
...
@@ -60,10 +62,12 @@ func (t *Interface) emitGenFromSPtr(x *aRef) (insts []wat.Inst) {
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
"0"
))
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.runtime.getItab"
))
//itab
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
"0"
))
//eq
return
}
func
(
t
*
Interface
)
emitGenFromValue
(
x
Value
,
xRefType
*
Ref
)
(
insts
[]
wat
.
Inst
)
{
func
(
t
*
Interface
)
emitGenFromValue
(
x
Value
,
xRefType
*
Ref
,
compID
int
)
(
insts
[]
wat
.
Inst
)
{
insts
=
append
(
insts
,
xRefType
.
emitHeapAlloc
()
...
)
insts
=
append
(
insts
,
x
.
emitStore
(
0
)
...
)
//data
...
...
@@ -72,6 +76,8 @@ func (t *Interface) emitGenFromValue(x Value, xRefType *Ref) (insts []wat.Inst)
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
"0"
))
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.runtime.getItab"
))
//itab
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
strconv
.
Itoa
(
compID
)))
//eq
return
}
...
...
@@ -84,6 +90,8 @@ func (t *Interface) emitGenFromInterface(x *aInterface) (insts []wat.Inst) {
insts
=
append
(
insts
,
wat
.
NewInstConst
(
wat
.
I32
{},
"0"
))
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.runtime.getItab"
))
//itab
insts
=
append
(
insts
,
x
.
Extract
(
"eq"
)
.
EmitPush
()
...
)
//eq
return
}
...
...
@@ -160,6 +168,7 @@ func (v *aInterface) emitQueryInterface(destType ValueType, commaOk bool) (insts
insts
=
append
(
insts
,
wat
.
NewInstCall
(
"$wa.runtime.DupI32"
))
ifBlock
:=
wat
.
NewInstIf
(
nil
,
nil
,
nil
)
insts
=
append
(
insts
,
ifBlock
)
if
commaOk
{
ifBlock
.
Ret
=
append
(
ifBlock
.
Ret
,
wat
.
I32
{})
ifBlock
.
True
=
append
(
ifBlock
.
True
,
wat
.
NewInstConst
(
wat
.
I32
{},
"1"
))
...
...
@@ -168,6 +177,55 @@ func (v *aInterface) emitQueryInterface(destType ValueType, commaOk bool) (insts
ifBlock
.
False
=
append
(
ifBlock
.
False
,
wat
.
NewInstUnreachable
())
}
insts
=
append
(
insts
,
ifBlock
)
insts
=
append
(
insts
,
v
.
Extract
(
"eq"
)
.
EmitPush
()
...
)
return
}
func
(
v
*
aInterface
)
emitEq
(
r
Value
)
(
insts
[]
wat
.
Inst
,
ok
bool
)
{
if
!
v
.
Type
()
.
Equal
(
r
.
Type
())
{
logger
.
Fatal
(
"v.Type() != r.Type()"
)
}
d
:=
r
.
(
*
aInterface
)
ins
,
_
:=
v
.
Extract
(
"eq"
)
.
emitEq
(
d
.
Extract
(
"eq"
))
insts
=
append
(
insts
,
ins
...
)
compEq
:=
wat
.
NewInstIf
(
nil
,
nil
,
nil
)
compEq
.
Ret
=
append
(
compEq
.
Ret
,
wat
.
I32
{})
{
compEq
.
True
=
append
(
compEq
.
True
,
v
.
Extract
(
"eq"
)
.
EmitPush
()
...
)
compEq
.
True
=
append
(
compEq
.
True
,
wat
.
NewInstConst
(
wat
.
I32
{},
"-1"
))
compEq
.
True
=
append
(
compEq
.
True
,
wat
.
NewInstNe
(
wat
.
I32
{}))
compable
:=
wat
.
NewInstIf
(
nil
,
nil
,
nil
)
compable
.
Ret
=
append
(
compable
.
Ret
,
wat
.
I32
{})
{
compable
.
True
=
append
(
compable
.
True
,
v
.
Extract
(
"eq"
)
.
EmitPush
()
...
)
compable
.
True
=
append
(
compable
.
True
,
wat
.
NewInstEqz
(
wat
.
I32
{}))
isRef
:=
wat
.
NewInstIf
(
nil
,
nil
,
nil
)
isRef
.
Ret
=
append
(
isRef
.
Ret
,
wat
.
I32
{})
ins
,
_
=
v
.
Extract
(
"data"
)
.
emitEq
(
d
.
Extract
(
"data"
))
isRef
.
True
=
ins
isRef
.
False
=
append
(
isRef
.
False
,
v
.
Extract
(
"data"
)
.
(
*
aRef
)
.
Extract
(
"data"
)
.
EmitPush
()
...
)
isRef
.
False
=
append
(
isRef
.
False
,
d
.
Extract
(
"data"
)
.
(
*
aRef
)
.
Extract
(
"data"
)
.
EmitPush
()
...
)
isRef
.
False
=
append
(
isRef
.
False
,
v
.
Extract
(
"eq"
)
.
EmitPush
()
...
)
isRef
.
False
=
append
(
isRef
.
False
,
wat
.
NewInstCallIndirect
(
"$wa.runtime.comp"
))
compable
.
True
=
append
(
compable
.
True
,
isRef
)
}
compable
.
False
=
append
(
compable
.
False
,
wat
.
NewInstConst
(
wat
.
I32
{},
"0"
))
compable
.
False
=
append
(
compable
.
False
,
wat
.
NewInstUnreachable
())
compEq
.
True
=
append
(
compEq
.
True
,
compable
)
}
compEq
.
False
=
append
(
compEq
.
False
,
wat
.
NewInstConst
(
wat
.
I32
{},
"0"
))
insts
=
append
(
insts
,
compEq
)
ok
=
true
return
}
internal/backends/compiler_wat/wir/value_ref.go
浏览文件 @
0fa2cfa3
...
...
@@ -125,3 +125,11 @@ func (v *aRef) emitSetValue(d Value) []wat.Inst {
}
return
d
.
emitStoreToAddr
(
v
.
aStruct
.
Extract
(
"data"
),
0
)
}
func
(
v
*
aRef
)
emitEq
(
r
Value
)
(
insts
[]
wat
.
Inst
,
ok
bool
)
{
if
!
v
.
Type
()
.
Equal
(
r
.
Type
())
{
logger
.
Fatal
(
"v.Type() != r.Type()"
)
}
return
v
.
Extract
(
"data"
)
.
emitEq
(
r
.
(
*
aRef
)
.
Extract
(
"data"
))
}
internal/backends/compiler_wat/wir/value_slice.go
浏览文件 @
0fa2cfa3
...
...
@@ -420,3 +420,8 @@ func (v *aSlice) emitSub(low, high Value) (insts []wat.Inst) {
return
}
func
(
v
*
aSlice
)
emitEq
(
r
Value
)
([]
wat
.
Inst
,
bool
)
{
//logger.Fatal("aSlice can't be compared.")
return
nil
,
false
}
internal/backends/compiler_wat/wir/value_string.go
浏览文件 @
0fa2cfa3
...
...
@@ -6,6 +6,7 @@ import (
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
/**************************************
...
...
@@ -360,3 +361,16 @@ func (v *aString) emitAt_CommaOk(index Value) (insts []wat.Inst) {
return
}
func
(
v
*
aString
)
emitEq
(
r
Value
)
(
insts
[]
wat
.
Inst
,
ok
bool
)
{
if
!
v
.
Type
()
.
Equal
(
r
.
Type
())
{
logger
.
Fatal
(
"v.Type() != r.Type()"
)
}
insts
=
append
(
insts
,
v
.
EmitPush
()
...
)
insts
=
append
(
insts
,
r
.
EmitPush
()
...
)
insts
=
append
(
insts
,
wat
.
NewInstCall
(
v
.
typ
.
genFunc_Equal
()))
ok
=
true
return
}
internal/backends/compiler_wat/wir/value_struct.go
浏览文件 @
0fa2cfa3
...
...
@@ -328,3 +328,29 @@ func (v *aStruct) Bin() (b []byte) {
return
}
func
(
v
*
aStruct
)
emitEq
(
r
Value
)
(
insts
[]
wat
.
Inst
,
ok
bool
)
{
if
!
v
.
Type
()
.
Equal
(
r
.
Type
())
{
logger
.
Fatal
(
"v.Type() != r.Type()"
)
}
d
:=
r
.
(
*
aStruct
)
for
i
:=
range
v
.
typ
.
fields
{
t1
:=
v
.
genSubValue
(
v
.
typ
.
fields
[
i
])
t2
:=
d
.
genSubValue
(
d
.
typ
.
fields
[
i
])
if
ins
,
o
:=
t1
.
emitEq
(
t2
);
!
o
{
return
nil
,
false
}
else
{
insts
=
append
(
insts
,
ins
...
)
}
if
i
>
0
{
insts
=
append
(
insts
,
wat
.
NewInstAnd
(
wat
.
I32
{}))
}
}
ok
=
true
return
}
internal/backends/compiler_wat/wir/value_type.go
浏览文件 @
0fa2cfa3
...
...
@@ -75,6 +75,7 @@ tCommon:
type
tCommon
struct
{
addr
int
hash
int
comp
int
methods
[]
Method
}
...
...
@@ -84,6 +85,8 @@ func (t *tCommon) AddMethod(m Method) { t.methods = append(t.methods, m) }
func
(
t
*
tCommon
)
NumMethods
()
int
{
return
len
(
t
.
methods
)
}
func
(
t
*
tCommon
)
Method
(
i
int
)
Method
{
return
t
.
methods
[
i
]
}
func
(
t
*
tCommon
)
typeInfoAddr
()
int
{
return
t
.
addr
}
func
(
t
*
tCommon
)
OnComp
()
int
{
return
t
.
comp
}
func
(
t
*
tCommon
)
setOnComp
(
c
int
)
{
t
.
comp
=
c
}
//func (t *tCommon) AddMethodEntry(m FnType) { logger.Fatal("Can't add method for common type.") }
//
...
...
@@ -131,10 +134,10 @@ func (t *tRune) onFree() int { return 0 }
func
(
t
*
tRune
)
Raw
()
[]
wat
.
ValueType
{
return
[]
wat
.
ValueType
{
wat
.
I32
{}}
}
func
(
t
*
tRune
)
Equal
(
u
ValueType
)
bool
{
_
,
ok
:=
u
.
(
*
tRune
);
return
ok
}
func
(
t
*
tRune
)
EmitLoadFromAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
{
if
!
addr
.
Type
()
.
(
*
Ptr
)
.
Base
.
Equal
(
t
)
{
logger
.
Fatal
(
"Type not match"
)
return
nil
}
//
if !addr.Type().(*Ptr).Base.Equal(t) {
//
logger.Fatal("Type not match")
//
return nil
//
}
insts
:=
addr
.
EmitPush
()
insts
=
append
(
insts
,
wat
.
NewInstLoad
(
toWatType
(
t
),
offset
,
1
))
return
insts
...
...
internal/backends/compiler_wat/wir/wat/instruction_bit.go
浏览文件 @
0fa2cfa3
...
...
@@ -2,6 +2,28 @@
package
wat
/**************************************
instAnd:
**************************************/
type
instAnd
struct
{
anInstruction
typ
ValueType
}
func
NewInstAnd
(
t
ValueType
)
*
instAnd
{
return
&
instAnd
{
typ
:
t
}
}
func
(
i
*
instAnd
)
Format
(
indent
string
)
string
{
return
indent
+
i
.
typ
.
Name
()
+
".and"
}
/**************************************
instOr:
**************************************/
type
instOr
struct
{
anInstruction
typ
ValueType
}
func
NewInstOr
(
t
ValueType
)
*
instOr
{
return
&
instOr
{
typ
:
t
}
}
func
(
i
*
instOr
)
Format
(
indent
string
)
string
{
return
indent
+
i
.
typ
.
Name
()
+
".or"
}
/**************************************
instXor:
**************************************/
...
...
internal/backends/compiler_wat/wir/wir.go
浏览文件 @
0fa2cfa3
...
...
@@ -45,6 +45,8 @@ type Value interface {
emitStoreToAddr
(
addr
Value
,
offset
int
)
[]
wat
.
Inst
emitStore
(
offset
int
)
[]
wat
.
Inst
Bin
()
[]
byte
emitEq
(
r
Value
)
([]
wat
.
Inst
,
bool
)
}
/**************************************
...
...
@@ -68,6 +70,9 @@ type ValueType interface {
Method
(
i
int
)
Method
typeInfoAddr
()
int
OnComp
()
int
setOnComp
(
c
int
)
}
/**************************************
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录