diff --git a/internal/backends/compiler_wat/compile_func.go b/internal/backends/compiler_wat/compile_func.go index 8a3c12c1495e611a3313fe84ab3891c55894030e..a310665be0cfaa7c90dd493786ca30fc8235980b 100644 --- a/internal/backends/compiler_wat/compile_func.go +++ b/internal/backends/compiler_wat/compile_func.go @@ -53,30 +53,30 @@ func (g *functionGenerator) getValue(i ssa.Value) wir.Value { case types.Bool: if constant.BoolVal(v.Value) { - return wir.NewConst(wir.I32{}, "1") + return wir.NewConst("1", wir.I32{}) } else { - return wir.NewConst(wir.I32{}, "0") + return wir.NewConst("0", wir.I32{}) } case types.Int: val, _ := constant.Int64Val(v.Value) - return wir.NewConst(wir.I32{}, strconv.Itoa(int(val))) + return wir.NewConst(strconv.Itoa(int(val)), wir.I32{}) case types.Int32: val, _ := constant.Int64Val(v.Value) if t.Name() == "rune" { - return wir.NewConst(wir.RUNE{}, strconv.Itoa(int(val))) + return wir.NewConst(strconv.Itoa(int(val)), wir.RUNE{}) } else { - return wir.NewConst(wir.I32{}, strconv.Itoa(int(val))) + return wir.NewConst(strconv.Itoa(int(val)), wir.I32{}) } case types.Float32: val, _ := constant.Float64Val(v.Value) - return wir.NewConst(wir.F32{}, strconv.FormatFloat(val, 'f', -1, 32)) + return wir.NewConst(strconv.FormatFloat(val, 'f', -1, 32), wir.F32{}) case types.Float64: val, _ := constant.Float64Val(v.Value) - return wir.NewConst(wir.F64{}, strconv.FormatFloat(val, 'f', -1, 64)) + return wir.NewConst(strconv.FormatFloat(val, 'f', -1, 64), wir.F64{}) case types.String, types.UntypedString: logger.Fatalf("Todo:%T", t) @@ -120,17 +120,17 @@ func (g *functionGenerator) genFunction(f *ssa.Function) *wir.Function { } for _, i := range f.Params { - pa := wir.NewVar(i.Name(), wir.ValueKindLocal, wir.ToWType(i.Type())) + pa := wir.NewLocal(i.Name(), 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, wir.I32{}) + g.var_block_selector = wir.NewLocal("$block_selector", wir.I32{}) g.registers = append(g.registers, g.var_block_selector) - g.var_current_block = wir.NewVar("$current_block", wir.ValueKindLocal, wir.I32{}) + g.var_current_block = wir.NewLocal("$current_block", wir.I32{}) g.registers = append(g.registers, g.var_current_block) if !wir_fn.Result.Equal(wir.VOID{}) { - g.var_ret = wir.NewVar("$ret", wir.ValueKindLocal, wir_fn.Result) + g.var_ret = wir.NewLocal("$ret", wir_fn.Result) g.registers = append(g.registers, g.var_ret) } @@ -198,7 +198,7 @@ func (g *functionGenerator) genBlock(block *ssa.BasicBlock) []wat.Inst { 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.NewConst(wir.I32{}, strconv.Itoa(block.Index)))...) + b = append(b, wir.EmitAssginValue(g.var_current_block, wir.NewConst(strconv.Itoa(block.Index), wir.I32{}))...) cur_block_assigned = true } } @@ -395,7 +395,7 @@ func (g *functionGenerator) genBuiltin(call *ssa.CallCommon) ([]wat.Inst, wir.Va } if call.Value.Name() == "println" { - insts = append(insts, wir.NewConst(wir.I32{}, strconv.Itoa('\n')).EmitPush()...) + insts = append(insts, wir.NewConst(strconv.Itoa('\n'), wir.I32{}).EmitPush()...) insts = append(insts, wat.NewInstCall("$waPrintRune")) } @@ -408,7 +408,7 @@ func (g *functionGenerator) genBuiltin(call *ssa.CallCommon) ([]wat.Inst, wir.Va func (g *functionGenerator) genPhiIter(preds []int, values []wir.Value) []wat.Inst { var insts []wat.Inst - cond, _ := wir.EmitBinOp(g.var_current_block, wir.NewConst(wir.I32{}, strconv.Itoa(preds[0])), wat.OpCodeEql) + cond, _ := wir.EmitBinOp(g.var_current_block, wir.NewConst(strconv.Itoa(preds[0]), wir.I32{}), wat.OpCodeEql) insts = append(insts, cond...) trueInsts := values[0].EmitPush() @@ -480,7 +480,7 @@ func (g *functionGenerator) genJumpID(cur, dest int) []wat.Inst { var insts []wat.Inst if cur >= dest { - insts = wir.EmitAssginValue(g.var_block_selector, wir.NewConst(wir.I32{}, strconv.Itoa(dest))) + insts = wir.EmitAssginValue(g.var_block_selector, wir.NewConst(strconv.Itoa(dest), wir.I32{})) insts = append(insts, wat.NewInstBr("$BlockDisp")) } else { insts = append(insts, wat.NewInstBr("$Block_"+strconv.Itoa(dest-1))) @@ -500,7 +500,7 @@ func (g *functionGenerator) genAlloc(inst *ssa.Alloc) ([]wat.Inst, wir.ValueType func (g *functionGenerator) addRegister(typ wir.ValueType) wir.Value { defer func() { g.cur_local_id++ }() name := "$T_" + strconv.Itoa(g.cur_local_id) - v := wir.NewVar(name, wir.ValueKindLocal, typ) + v := wir.NewLocal(name, typ) g.registers = append(g.registers, v) return v } diff --git a/internal/backends/compiler_wat/wir/module.go b/internal/backends/compiler_wat/wir/module.go index 8142377c990db80746fbe5cebac9243f4e4db50e..51c9850a6921469aac01b4c85bf82616f9fe685b 100644 --- a/internal/backends/compiler_wat/wir/module.go +++ b/internal/backends/compiler_wat/wir/module.go @@ -26,13 +26,7 @@ func NewModule() *Module { } func (m *Module) AddGlobal(name string, typ ValueType, is_pointer bool, ssa_value ssa.Value) Value { - var kind ValueKind - if is_pointer { - kind = ValueKindGlobal_Pointer - } else { - kind = ValueKindGlobal_Value - } - v := NewVar(name, kind, typ) + v := NewGlobal(name, typ, is_pointer) m.globals = append(m.globals, v) m.Globals_map[ssa_value] = v return v diff --git a/internal/backends/compiler_wat/wir/var_basic.go b/internal/backends/compiler_wat/wir/value_basic.go similarity index 74% rename from internal/backends/compiler_wat/wir/var_basic.go rename to internal/backends/compiler_wat/wir/value_basic.go index 0f24718646606d8ebf67d6b2f0a5da5ab88578c7..437ae8384144857efaa4a92b81c5f2a0ff1f2721 100644 --- a/internal/backends/compiler_wat/wir/var_basic.go +++ b/internal/backends/compiler_wat/wir/value_basic.go @@ -7,9 +7,25 @@ import ( "github.com/wa-lang/wa/internal/logger" ) -func NewVar(name string, kind ValueKind, typ ValueType) Value { +func NewConst(lit string, t ValueType) Value { + return newValue(lit, ValueKindConst, t) +} + +func NewLocal(name string, typ ValueType) Value { + return newValue(name, ValueKindLocal, typ) +} + +func NewGlobal(name string, typ ValueType, as_pointer bool) Value { + if as_pointer { + return newValue(name, ValueKindGlobal_Pointer, typ) + } else { + return newValue(name, ValueKindGlobal_Value, typ) + } +} + +func newValue(name string, kind ValueKind, typ ValueType) Value { switch typ := typ.(type) { - case I32, U32, I64, U64, F32, F64: + case I32, U32, I64, U64, F32, F64, RUNE: return newVarBasic(name, kind, typ) case Pointer: @@ -51,8 +67,11 @@ func (v *aVar) push(name string) wat.Inst { case ValueKindGlobal_Value, ValueKindGlobal_Pointer: return wat.NewInstGetGlobal(name) + case ValueKindConst: + return wat.NewInstConst(toWatType(v.Type()), name) + default: - logger.Fatal("Todo") + logger.Fatal("Unreachable.") return nil } } @@ -64,8 +83,12 @@ func (v *aVar) pop(name string) wat.Inst { case ValueKindGlobal_Value, ValueKindGlobal_Pointer: return wat.NewInstSetGlobal(name) + case ValueKindConst: + logger.Fatal("Can't pop to const.") + return nil + default: - logger.Fatal("Todo") + logger.Fatal("Unreachable.") return nil } } @@ -80,13 +103,18 @@ type varBasic struct { func newVarBasic(name string, kind ValueKind, typ ValueType) *varBasic { return &varBasic{aVar: aVar{name: name, kind: kind, typ: typ}} } -func (v *varBasic) raw() []wat.Value { return []wat.Value{wat.NewVar(v.name, toWatType(v.Type()))} } -func (v *varBasic) EmitInit() []wat.Inst { - return []wat.Inst{wat.NewInstConst(toWatType(v.Type()), "0"), v.pop(v.name)} -} + +func (v *varBasic) raw() []wat.Value { return []wat.Value{wat.NewVar(v.name, toWatType(v.Type()))} } func (v *varBasic) EmitPush() []wat.Inst { return []wat.Inst{v.push(v.name)} } func (v *varBasic) EmitPop() []wat.Inst { return []wat.Inst{v.pop(v.name)} } func (v *varBasic) EmitRelease() []wat.Inst { return nil } + +func (v *varBasic) EmitInit() (insts []wat.Inst) { + insts = append(insts, wat.NewInstConst(toWatType(v.Type()), "0")) + insts = append(insts, v.pop(v.name)) + return +} + func (v *varBasic) emitLoadFromAddr(addr Value, offset int) []wat.Inst { if !addr.Type().(Pointer).Base.Equal(v.Type()) { logger.Fatal("Type not match") @@ -96,6 +124,7 @@ func (v *varBasic) emitLoadFromAddr(addr Value, offset int) []wat.Inst { insts = append(insts, wat.NewInstLoad(toWatType(v.Type()), offset, 1)) return insts } + func (v *varBasic) emitStoreToAddr(addr Value, offset int) []wat.Inst { if !addr.Type().(Pointer).Base.Equal(v.Type()) { logger.Fatal("Type not match") @@ -122,7 +151,7 @@ func newVarPointer(name string, kind ValueKind, base_type ValueType) *VarPointer } func (v *VarPointer) emitGetValue() []wat.Inst { - t := NewVar("", v.kind, v.Type().(Pointer).Base) + t := newValue("", v.kind, v.Type().(Pointer).Base) return t.emitLoadFromAddr(v, 0) } diff --git a/internal/backends/compiler_wat/wir/value_const.go b/internal/backends/compiler_wat/wir/value_const.go deleted file mode 100644 index 4852a7ae4beeccdb423a5d7ac992a7e98c9bfd54..0000000000000000000000000000000000000000 --- a/internal/backends/compiler_wat/wir/value_const.go +++ /dev/null @@ -1,90 +0,0 @@ -// 版权 @2022 凹语言 作者。保留所有权利。 - -package wir - -import ( - "github.com/wa-lang/wa/internal/backends/compiler_wat/wir/wat" - "github.com/wa-lang/wa/internal/logger" -) - -type Const interface { - Value - isConst() -} - -/************************************** -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 ValueType, lit string) Const { - switch t.(type) { - case RUNE: - return &aConst{typ: t, lit: lit} - - case I32: - return &aConst{typ: t, lit: lit} - - case U32: - return &aConst{typ: t, lit: lit} - - case I64: - return &aConst{typ: t, lit: lit} - - case U64: - return &aConst{typ: t, lit: lit} - - case F32: - return &aConst{typ: t, lit: lit} - - case F64: - return &aConst{typ: t, lit: lit} - - default: - logger.Fatal("Todo") - } - - return nil -} - -/************************************** -aConst: -**************************************/ -type aConst struct { - typ ValueType - lit string -} - -func (c *aConst) Name() string { return c.lit } -func (c *aConst) Kind() ValueKind { return ValueKindConst } -func (c *aConst) Type() ValueType { return c.typ } -func (c *aConst) raw() []wat.Value { logger.Fatal("Todo"); return nil } -func (c *aConst) isConst() {} -func (c *aConst) EmitInit() []wat.Inst { logger.Fatal("不可0值化常数"); return nil } -func (c *aConst) EmitPop() []wat.Inst { logger.Fatal("不可Pop至常数"); return nil } -func (c *aConst) EmitRelease() []wat.Inst { logger.Fatal("不可清除常数"); return nil } -func (c *aConst) emitLoadFromAddr(addr Value, offset int) []wat.Inst { - logger.Fatal("不可Load常数") - return nil -} -func (c *aConst) EmitPush() []wat.Inst { - return []wat.Inst{wat.NewInstConst(toWatType(c.Type()), c.lit)} -} -func (c *aConst) emitStoreToAddr(addr Value, offset int) []wat.Inst { - if !addr.Type().(Pointer).Base.Equal(c.Type()) { - logger.Fatal("Type not match") - return nil - } - insts := addr.EmitPush() - insts = append(insts, c.EmitPush()...) - insts = append(insts, wat.NewInstStore(toWatType(c.Type()), offset, 1)) - return insts -} diff --git a/internal/backends/compiler_wat/wir/var_block.go b/internal/backends/compiler_wat/wir/var_block.go index de7270e05d836e8e98f7eae2a0f6503308716c7c..7f3bca2d23e787b7b1189e30285c4e08e52b1d8a 100644 --- a/internal/backends/compiler_wat/wir/var_block.go +++ b/internal/backends/compiler_wat/wir/var_block.go @@ -75,11 +75,11 @@ func (v *varBlock) emitHeapAlloc(item_count Value, module *Module) (insts []wat. logger.Fatalf("%v\n", err) return nil } - insts = append(insts, NewConst(I32{}, strconv.Itoa(v.Type().(Block).Base.size()*c+16)).EmitPush()...) + insts = append(insts, NewConst(strconv.Itoa(v.Type().(Block).Base.size()*c+16), I32{}).EmitPush()...) insts = append(insts, wat.NewInstCall("$waHeapAlloc")) insts = append(insts, item_count.EmitPush()...) //item_count - insts = append(insts, NewConst(I32{}, strconv.Itoa(v.Type().(Block).Base.onFree(module))).EmitPush()...) //free_method + insts = append(insts, NewConst(strconv.Itoa(v.Type().(Block).Base.onFree(module)), I32{}).EmitPush()...) //free_method insts = append(insts, wat.NewInstCall("$wa.RT.Block.Init")) default: @@ -89,14 +89,14 @@ func (v *varBlock) emitHeapAlloc(item_count Value, module *Module) (insts []wat. } insts = append(insts, item_count.EmitPush()...) - insts = append(insts, NewConst(I32{}, strconv.Itoa(v.Type().(Block).Base.size())).EmitPush()...) + insts = append(insts, NewConst(strconv.Itoa(v.Type().(Block).Base.size()), I32{}).EmitPush()...) insts = append(insts, wat.NewInstMul(wat.I32{})) - insts = append(insts, NewConst(I32{}, "16").EmitPush()...) + insts = append(insts, NewConst("16", I32{}).EmitPush()...) insts = append(insts, wat.NewInstAdd(wat.I32{})) insts = append(insts, wat.NewInstCall("$waHeapAlloc")) insts = append(insts, item_count.EmitPush()...) - insts = append(insts, NewConst(I32{}, strconv.Itoa(v.Type().(Block).Base.onFree(module))).EmitPush()...) //free_method + insts = append(insts, NewConst(strconv.Itoa(v.Type().(Block).Base.onFree(module)), I32{}).EmitPush()...) //free_method insts = append(insts, wat.NewInstCall("$wa.RT.Block.Init")) } diff --git a/internal/backends/compiler_wat/wir/var_ref.go b/internal/backends/compiler_wat/wir/var_ref.go index afe76c5e9d91fe0b8f1e3798e12263b42055827a..d941317a4b1e454901defc7b742e0a09b42fc6dc 100644 --- a/internal/backends/compiler_wat/wir/var_ref.go +++ b/internal/backends/compiler_wat/wir/var_ref.go @@ -40,7 +40,7 @@ func (v *VarRef) emitStoreToAddr(addr Value, offset int) []wat.Inst { } func (v *VarRef) emitGetValue() []wat.Inst { - t := NewVar("", v.kind, v.Type().(Ref).Base) + t := newValue("", v.kind, v.Type().(Ref).Base) return t.emitLoadFromAddr(v.underlying.Extract("data"), 0) } @@ -56,9 +56,9 @@ func (v *VarRef) emitHeapAlloc(module *Module) (insts []wat.Inst) { insts = append(insts, wat.NewBlank()) insts = append(insts, wat.NewComment(v.name+" Ref.emitHeapAlloc start")) - insts = append(insts, newVarBlock("", v.Kind(), v.Type().(Ref).Base).emitHeapAlloc(NewConst(I32{}, "1"), module)...) + insts = append(insts, newVarBlock("", v.Kind(), v.Type().(Ref).Base).emitHeapAlloc(NewConst("1", I32{}), module)...) insts = append(insts, wat.NewInstCall("$wa.RT.DupWatStack")) - insts = append(insts, NewConst(I32{}, "16").EmitPush()...) + insts = append(insts, NewConst("16", I32{}).EmitPush()...) insts = append(insts, wat.NewInstAdd(wat.I32{})) insts = append(insts, wat.NewComment(v.name+" Ref.emitHeapAlloc end")) @@ -71,8 +71,8 @@ func (v *VarRef) emitStackAlloc(module *Module) (insts []wat.Inst) { insts = append(insts, wat.NewBlank()) insts = append(insts, wat.NewComment(v.name+" Ref.emitStackAlloc start")) - insts = append(insts, NewConst(I32{}, "0").EmitPush()...) - insts = append(insts, NewConst(I32{}, strconv.Itoa(v.Type().(Ref).Base.size())).EmitPush()...) + insts = append(insts, NewConst("0", I32{}).EmitPush()...) + insts = append(insts, NewConst(strconv.Itoa(v.Type().(Ref).Base.size()), I32{}).EmitPush()...) insts = append(insts, wat.NewInstCall("$waStackAlloc")) insts = append(insts, wat.NewComment(v.name+" Ref.emitStackAlloc end")) diff --git a/internal/backends/compiler_wat/wir/var_struct.go b/internal/backends/compiler_wat/wir/var_struct.go index d145aa49c988c84a681e728a346a19103d0dc935..74b703531bb16d9e9e44335949da23429649c2b3 100644 --- a/internal/backends/compiler_wat/wir/var_struct.go +++ b/internal/backends/compiler_wat/wir/var_struct.go @@ -19,7 +19,7 @@ func (v *VarStruct) raw() []wat.Value { var r []wat.Value st := v.Type().(Struct) for _, m := range st.Members { - t := NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + t := newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) r = append(r, t.raw()...) } return r @@ -29,7 +29,7 @@ func (v *VarStruct) EmitInit() []wat.Inst { var insts []wat.Inst st := v.Type().(Struct) for _, m := range st.Members { - t := NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + t := newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) insts = append(insts, t.EmitInit()...) } return insts @@ -39,7 +39,7 @@ func (v *VarStruct) EmitPush() []wat.Inst { var insts []wat.Inst st := v.Type().(Struct) for _, m := range st.Members { - t := NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + t := newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) insts = append(insts, t.EmitPush()...) } return insts @@ -50,7 +50,7 @@ func (v *VarStruct) EmitPop() []wat.Inst { st := v.Type().(Struct) for i := range st.Members { m := st.Members[len(st.Members)-i-1] - t := NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + t := newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) insts = append(insts, t.EmitPop()...) } return insts @@ -61,7 +61,7 @@ func (v *VarStruct) EmitRelease() []wat.Inst { st := v.Type().(Struct) for i := range st.Members { m := st.Members[len(st.Members)-i-1] - t := NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + t := newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) insts = append(insts, t.EmitRelease()...) } return insts @@ -71,7 +71,7 @@ func (v *VarStruct) Extract(member_name string) Value { st := v.Type().(Struct) for _, m := range st.Members { if m.Name() == member_name { - return NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + return newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) } } return nil @@ -80,7 +80,7 @@ func (v *VarStruct) Extract(member_name string) Value { func (v *VarStruct) emitLoadFromAddr(addr Value, offset int) (insts []wat.Inst) { st := v.Type().(Struct) for _, m := range st.Members { - t := NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + t := newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) a := newVarPointer(addr.Name(), addr.Kind(), m.Type()) insts = append(insts, t.emitLoadFromAddr(a, m._start+offset)...) } @@ -91,7 +91,7 @@ func (v *VarStruct) emitStoreToAddr(addr Value, offset int) (insts []wat.Inst) { st := v.Type().(Struct) for i := range st.Members { m := st.Members[len(st.Members)-i-1] - t := NewVar(v.Name()+"."+m.Name(), v.kind, m.Type()) + t := newValue(v.Name()+"."+m.Name(), v.kind, m.Type()) a := newVarPointer(addr.Name(), addr.Kind(), m.Type()) insts = append(insts, t.emitStoreToAddr(a, m._start+offset)...) }