提交 2de29d42 编写于 作者: 3 3dgen

Merge branch 'backend_wasm'

......@@ -131,13 +131,16 @@ func (tLib *typeLib) compile(from types.Type) wir.ValueType {
}
newType = tStruct
uncommanFlag = true
//uncommanFlag = true
case *types.Interface:
if ut.NumMethods() == 0 {
return tLib.compile(ut)
}
pkg_name, _ := wir.GetPkgMangleName(t.Obj().Pkg().Path())
pkg_name := ""
if t.Obj().Pkg() != nil {
pkg_name, _ = wir.GetPkgMangleName(t.Obj().Pkg().Path())
}
obj_name := wir.GenSymbolName(t.Obj().Name())
newType = tLib.module.GenValueType_Interface(pkg_name + "." + obj_name)
......@@ -145,17 +148,17 @@ func (tLib *typeLib) compile(from types.Type) wir.ValueType {
for i := 0; i < ut.NumMethods(); i++ {
var method wir.Method
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.AddMethod(method)
var fnSig wir.FnSig
fnSig.Params = append(fnSig.Params, tLib.module.GenValueType_Ref(tLib.module.VOID))
fnSig.Params = append(fnSig.Params, method.Sig.Params...)
fnSig.Results = method.Sig.Results
method.FullFnName = tLib.module.AddFnSig(&fnSig)
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.AddMethod(method)
}
case *types.Signature:
......
......@@ -2,17 +2,23 @@ package wir
import (
"strconv"
"strings"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
"wa-lang.org/wa/internal/ssa"
)
type fnSigWrap struct {
name string
typeAddr int
}
/**************************************
Module:
**************************************/
type Module struct {
VOID, RUNE, I8, U8, I16, U16, I32, U32, I64, U64, F32, F64, STRING ValueType
VOID, RUNE, I8, U8, I16, U16, I32, U32, UPTR, I64, U64, F32, F64, STRING ValueType
types_map map[string]ValueType
usedConcreteTypes []ValueType
......@@ -20,8 +26,8 @@ type Module struct {
imports []wat.Import
fn_types []*FnType
fn_types_map map[string]int
fnSigs []*FnSig
fnSigsName map[string]fnSigWrap
funcs []*Function
funcs_map map[string]*Function
......@@ -54,6 +60,7 @@ func NewModule() *Module {
m.U16 = &tU16{}
m.I32 = &tI32{}
m.U32 = &tU32{}
m.UPTR = m.U32
m.I64 = &tI64{}
m.U64 = &tU64{}
m.F32 = &tF32{}
......@@ -75,13 +82,7 @@ func NewModule() *Module {
m.STRING = m.GenValueType_String()
m.fn_types_map = make(map[string]int)
{
var free_type FnType
free_type.Name = "$onFree"
free_type.Params = []ValueType{m.I32}
m.AddFnType(&free_type)
}
m.fnSigsName = make(map[string]fnSigWrap)
m.funcs_map = make(map[string]*Function)
......@@ -110,21 +111,23 @@ func (m *Module) AddImportFunc(moduleName string, objName string, funcName strin
m.imports = append(m.imports, wat.NewImpFunc(moduleName, objName, funcName, wat_sig))
}
func (m *Module) findFnType(name string) int {
if i, ok := m.fn_types_map[name]; ok {
return i
func (m *Module) FindFnSig(sig *FnSig) string {
if s, ok := m.fnSigsName[sig.String()]; ok {
return s.name
}
return 0
return ""
}
func (m *Module) AddFnType(typ *FnType) int {
if i := m.findFnType(typ.Name); i != 0 {
return i
func (m *Module) AddFnSig(sig *FnSig) string {
if s, ok := m.fnSigsName[sig.String()]; ok {
return s.name
}
i := len(m.fn_types)
m.fn_types = append(m.fn_types, typ)
m.fn_types_map[typ.Name] = i
return i
m.fnSigs = append(m.fnSigs, sig)
s := "$$fnSig" + strconv.Itoa(len(m.fnSigs))
m.fnSigsName[sig.String()] = fnSigWrap{name: s}
return s
}
func (m *Module) findTableElem(elem string) int {
......@@ -229,14 +232,21 @@ func (m *Module) genGlobalAlloc() *Function {
func (m *Module) ToWatModule() *wat.Module {
m.buildItab()
m.buildTypesInfo()
var wat_module wat.Module
wat_module.Imports = m.imports
wat_module.BaseWat = m.BaseWat
for _, t := range m.fn_types {
{
var onfree_type wat.FuncType
onfree_type.Name = "$onFree"
onfree_type.Params = m.I32.Raw()
wat_module.FuncTypes = append(wat_module.FuncTypes, onfree_type)
}
for _, t := range m.fnSigs {
var fn_type wat.FuncType
fn_type.Name = t.Name
fn_type.Name = m.fnSigsName[t.String()].name
for _, i := range t.Params {
fn_type.Params = append(fn_type.Params, i.Raw()...)
}
......@@ -335,15 +345,15 @@ func (m *Module) buildItab() {
var addr int
if fits {
var itab []byte
var itab_bin []byte
header := NewConst("0", t_itab)
itab = append(itab, header.Bin()...)
itab_bin = append(itab_bin, header.Bin()...)
for _, v := range vtable {
fnid := NewConst(strconv.Itoa(v), m.U32)
itab = append(itab, fnid.Bin()...)
itab_bin = append(itab_bin, fnid.Bin()...)
}
addr = m.DataSeg.Append(itab, 8)
addr = m.DataSeg.Append(itab_bin, 8)
}
itabs = append(itabs, NewConst(strconv.Itoa(addr), m.U32).Bin()...)
......@@ -355,3 +365,195 @@ func (m *Module) buildItab() {
m.SetGlobalInitValue("$wa.RT._interfaceCount", strconv.Itoa(len(m.usedInterfaces)))
m.SetGlobalInitValue("$wa.RT._concretTypeCount", strconv.Itoa(len(m.usedConcreteTypes)))
}
func (m *Module) buildTypesInfo() {
for name, t := range m.types_map {
if strings.HasPrefix(name, "runtime.") {
continue
}
m.buildTypeInfo(t)
}
}
func (m *Module) buildTypeInfo(t ValueType) int {
if t.typeInfoAddr() != 0 {
return t.typeInfoAddr()
}
_type := NewConst("0", m.types_map["runtime._type"]).(*aStruct)
_type.setFieldConstValue("size", NewConst(strconv.Itoa(t.Size()), m.U32))
_type.setFieldConstValue("hash", NewConst(strconv.Itoa(t.Hash()), m.I32))
_type.setFieldConstValue("kind", NewConst(strconv.Itoa(int(t.Kind())), m.U8))
_type.setFieldConstValue("align", NewConst(strconv.Itoa(t.align()), m.U8))
_type.setFieldConstValue("flag", NewConst("0", m.U16))
_type.setFieldConstValue("name", NewConst(t.Name(), m.STRING))
switch typ := t.(type) {
case *tVoid:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tI8:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU8:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tI16:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU16:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tI32:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU32:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tI64:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU64:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tF32:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tF64:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tRune:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *String:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *Ptr:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *Block:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *Array:
_array := NewConst("0", m.types_map["runtime._arrayType"]).(*aStruct)
_array.setFieldConstValue("$_type", _type)
_array.setFieldConstValue("elemType", NewConst(strconv.Itoa(m.buildTypeInfo(typ.Base)), m.UPTR))
_array.setFieldConstValue("cap", NewConst(strconv.Itoa(typ.Capacity), m.UPTR))
typ.addr = m.DataSeg.Append(_array.Bin(), 8)
return typ.addr
case *Slice:
_slice := NewConst("0", m.types_map["runtime._arrayType"]).(*aStruct)
_slice.setFieldConstValue("$_type", _type)
_slice.setFieldConstValue("elemType", NewConst(strconv.Itoa(m.buildTypeInfo(typ.Base)), m.UPTR))
typ.addr = m.DataSeg.Append(_slice.Bin(), 8)
return typ.addr
case *Ref:
_ref := NewConst("0", m.types_map["runtime._refType"]).(*aStruct)
typ.addr = m.DataSeg.Alloc(len(_ref.Bin()), 8)
_ref.setFieldConstValue("$_type", _type)
_ref.setFieldConstValue("elemType", NewConst(strconv.Itoa(m.buildTypeInfo(typ.Base)), m.UPTR))
if len(typ.methods) > 0 {
_uncommon := NewConst("0", m.types_map["runtime._uncommonType"]).(*aStruct)
_uncommon.setFieldConstValue("methodCount", NewConst(strconv.Itoa(len(typ.methods)), m.U32))
_uncommon_bin := _uncommon.Bin()
for _, method := range typ.methods {
_method := NewConst("0", m.types_map["runtime._method"]).(*aStruct)
_method.setFieldConstValue("name", NewConst(method.Name, m.STRING))
_method.setFieldConstValue("fnType", NewConst(strconv.Itoa(m.buildFnTypeInfo(&method.Sig)), m.UPTR))
_method.setFieldConstValue("fnID", NewConst(strconv.Itoa(m.AddTableElem(method.FullFnName)), m.U32))
_uncommon_bin = append(_uncommon_bin, _method.Bin()...)
}
_ref.setFieldConstValue("uncommon", NewConst(strconv.Itoa(m.DataSeg.Append(_uncommon_bin, 8)), m.UPTR))
}
m.DataSeg.Set(_ref.Bin(), typ.addr)
return typ.addr
case *Closure:
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *Struct:
_struct := NewConst("0", m.types_map["runtime._structType"]).(*aStruct)
_structField := NewConst("0", m.types_map["runtime._structField"]).(*aStruct)
typ.addr = m.DataSeg.Alloc(len(_struct.Bin())+len(_structField.Bin())*len(typ.fields), 8)
_struct.setFieldConstValue("$_type", _type)
_struct.setFieldConstValue("fieldCount", NewConst(strconv.Itoa(len(typ.fields)), m.U32))
_struct_bin := _struct.Bin()
for _, f := range typ.fields {
_structField.setFieldConstValue("name", NewConst(f.Name(), m.STRING))
_structField.setFieldConstValue("typ", NewConst(strconv.Itoa(m.buildTypeInfo(f.Type())), m.UPTR))
_struct_bin = append(_struct_bin, _structField.Bin()...)
}
m.DataSeg.Set(_struct_bin, typ.addr)
return typ.addr
case *Interface:
_interface := NewConst("0", m.types_map["runtime._interfaceType"]).(*aStruct)
_imethod := NewConst("0", m.types_map["runtime._imethod"]).(*aStruct)
typ.addr = m.DataSeg.Alloc(len(_interface.Bin())+len(_imethod.Bin())*typ.NumMethods(), 8)
_interface.setFieldConstValue("methodCount", NewConst(strconv.Itoa(typ.NumMethods()), m.U32))
_interface_bin := _interface.Bin()
for _, method := range typ.methods {
_imethod.setFieldConstValue("name", NewConst(method.Name, m.STRING))
_imethod.setFieldConstValue("fnType", NewConst(strconv.Itoa(m.buildFnTypeInfo(&method.Sig)), m.UPTR))
_interface_bin = append(_interface_bin, _imethod.Bin()...)
}
m.DataSeg.Set(_interface_bin, typ.addr)
return typ.addr
default:
logger.Fatalf("Todo: %t", t)
return 0
}
}
func (m *Module) buildFnTypeInfo(sig *FnSig) int {
s, ok := m.fnSigsName[sig.String()]
if ok && s.typeAddr != 0 {
return s.typeAddr
}
_fnType := NewConst("0", m.types_map["runtime._fnType"]).(*aStruct)
_fnType.setFieldConstValue("paramCount", NewConst(strconv.Itoa(len(sig.Params)), m.U32))
_fnType.setFieldConstValue("resultCount", NewConst(strconv.Itoa(len(sig.Results)), m.U32))
_fnType_bin := _fnType.Bin()
for _, p := range sig.Params {
typaddr := m.buildTypeInfo(p)
typaddr_bin := NewConst(strconv.Itoa(typaddr), m.UPTR).Bin()
_fnType_bin = append(_fnType_bin, typaddr_bin...)
}
for _, p := range sig.Results {
typaddr := m.buildTypeInfo(p)
typaddr_bin := NewConst(strconv.Itoa(typaddr), m.UPTR).Bin()
_fnType_bin = append(_fnType_bin, typaddr_bin...)
}
s.typeAddr = m.DataSeg.Append(_fnType_bin, 8)
m.fnSigsName[sig.String()] = s
return s.typeAddr
}
......@@ -26,12 +26,7 @@ func (m *Module) GenValueType_Array(base ValueType, capacity int) *Array {
return t.(*Array)
}
var found bool
arr_t.underlying, found = m.GenValueType_Struct(arr_t.Name() + ".underlying")
if found {
logger.Fatalf("Type: %s already registered.", arr_t.Name()+".underlying")
}
arr_t.underlying = m.genInternalStruct(arr_t.Name() + ".underlying")
for i := 0; i < capacity; i++ {
field := m.NewStructField("m"+strconv.Itoa(i), base)
arr_t.underlying.AppendField(field)
......@@ -45,6 +40,7 @@ func (m *Module) GenValueType_Array(base ValueType, capacity int) *Array {
func (t *Array) Name() string { return t.Base.Name() + ".$array" + strconv.Itoa(t.Capacity) }
func (t *Array) Size() int { return t.underlying.Size() }
func (t *Array) align() int { return t.underlying.align() }
func (t *Array) Kind() TypeKind { return kArray }
func (t *Array) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *Array) onFree() int { return t.underlying.onFree() }
......
......@@ -21,27 +21,35 @@ type Block struct {
func (m *Module) GenValueType_Block(base ValueType) *Block {
block_t := Block{Base: base}
t, ok := m.findValueType(block_t.Name())
if ok {
return t.(*Block)
}
//t, ok := m.findValueType(block_t.Name())
//if ok {
// return t.(*Block)
//}
//m.addValueType(&block_t)
block_t._i32 = m.I32
block_t._u32 = m.U32
m.addValueType(&block_t)
return &block_t
}
func (t *Block) Name() string { return t.Base.Name() + ".$$block" }
func (t *Block) Size() int { return 4 }
func (t *Block) align() int { return 4 }
func (t *Block) Kind() TypeKind { return kBlock }
func (t *Block) Raw() []wat.ValueType { return []wat.ValueType{wat.U32{}} }
func (t *Block) typeInfoAddr() int {
logger.Fatalf("Internal type: %s shouldn't have typeInfo.", t.Name())
return 0
}
func (t *Block) Equal(u ValueType) bool {
if ut, ok := u.(*Block); ok {
return t.Base.Equal(ut.Base)
}
return false
}
func (t *Block) onFree() int {
var f Function
f.InternalName = "$" + GenSymbolName(t.Name()) + ".$$onFree"
......
......@@ -52,44 +52,29 @@ func (s *FnSig) String() string {
return n
}
/**************************************
FnType:
**************************************/
type FnType struct {
Name string
FnSig
}
/**************************************
Closure:
**************************************/
type Closure struct {
tCommon
underlying *Struct
_fn_type FnType
_u32 ValueType
underlying *Struct
_fnSig FnSig
_fnTypeName string
_u32 ValueType
}
var _closure_id int
func (m *Module) GenValueType_Closure(sig FnSig) *Closure {
var closure_t Closure
closure_t._fn_type.FnSig = sig
closure_t._fnSig = sig
t, ok := m.findValueType(closure_t.Name())
if ok {
return t.(*Closure)
}
closure_t._u32 = m.U32
closure_t._fn_type.Name = "closure$" + strconv.Itoa(_closure_id)
_closure_id++
m.AddFnType(&closure_t._fn_type)
var found bool
closure_t.underlying, found = m.GenValueType_Struct(closure_t.Name() + ".underlying")
if found {
logger.Fatalf("Type: %s already registered.", closure_t.Name()+".underlying")
}
closure_t._fnTypeName = m.AddFnSig(&sig)
closure_t.underlying = m.genInternalStruct(closure_t.Name() + ".underlying")
closure_t.underlying.AppendField(m.NewStructField("fn_index", m.U32))
closure_t.underlying.AppendField(m.NewStructField("data", m.GenValueType_Ref(m.VOID)))
closure_t.underlying.Finish()
......@@ -98,15 +83,16 @@ func (m *Module) GenValueType_Closure(sig FnSig) *Closure {
return &closure_t
}
func (t *Closure) Name() string { return t._fn_type.String() }
func (t *Closure) Name() string { return t._fnSig.String() }
func (t *Closure) Size() int { return t.underlying.Size() }
func (t *Closure) align() int { return t.underlying.align() }
func (t *Closure) Kind() TypeKind { return kStruct }
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 {
return t._fn_type.FnSig.Equal(&ut._fn_type.FnSig)
return t._fnSig.Equal(&ut._fnSig)
}
return false
}
......@@ -157,6 +143,6 @@ func EmitCallClosure(c Value, params []Value) (insts []wat.Inst) {
insts = append(insts, closure.Extract("data").EmitPush()...)
insts = append(insts, currentModule.FindGlobalByName("$wa.RT.closure_data").EmitPop()...)
insts = append(insts, wat.NewInstCallIndirect(closure.typ._fn_type.Name))
insts = append(insts, wat.NewInstCallIndirect(closure.typ._fnTypeName))
return
}
......@@ -6,7 +6,6 @@ import (
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
/**************************************
......@@ -27,12 +26,7 @@ func (m *Module) GenValueType_Interface(name string) *Interface {
var interface_t Interface
interface_t.name = name
var found bool
interface_t.underlying, found = m.GenValueType_Struct(interface_t.Name() + ".underlying")
if found {
logger.Fatalf("Type: %s already registered.", interface_t.Name()+".underlying")
}
interface_t.underlying = m.genInternalStruct(interface_t.Name() + ".underlying")
interface_t.underlying.AppendField(m.NewStructField("data", m.GenValueType_Ref(m.GenValueType_Ref(m.VOID))))
interface_t.underlying.AppendField(m.NewStructField("itab", m.U32))
interface_t.underlying.Finish()
......@@ -44,6 +38,7 @@ func (m *Module) GenValueType_Interface(name string) *Interface {
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) Kind() TypeKind { return kInterface }
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 {
......
......@@ -17,26 +17,33 @@ type Ptr struct {
func (m *Module) GenValueType_Ptr(base ValueType) *Ptr {
ptr_t := Ptr{Base: base}
t, ok := m.findValueType(ptr_t.Name())
if ok {
return t.(*Ptr)
}
m.addValueType(&ptr_t)
//t, ok := m.findValueType(ptr_t.Name())
//if ok {
// return t.(*Ptr)
//}
//m.addValueType(&ptr_t)
return &ptr_t
}
func (t *Ptr) Name() string { return t.Base.Name() + ".$$ptr" }
func (t *Ptr) Size() int { return 4 }
func (t *Ptr) align() int { return 4 }
func (t *Ptr) Kind() TypeKind { return kPtr }
func (t *Ptr) onFree() int { return 0 }
func (t *Ptr) Raw() []wat.ValueType { return []wat.ValueType{toWatType(t)} }
func (t *Ptr) typeInfoAddr() int {
logger.Fatalf("Internal type: %s shouldn't have typeInfo.", t.Name())
return 0
}
func (t *Ptr) Equal(u ValueType) bool {
if ut, ok := u.(*Ptr); ok {
return t.Base.Equal(ut.Base)
}
return false
}
func (t *Ptr) EmitLoadFromAddr(addr Value, offset int) []wat.Inst {
if !addr.Type().(*Ptr).Base.Equal(t) {
logger.Fatal("Type not match")
......
......@@ -31,12 +31,7 @@ func (m *Module) GenValueType_Ref(base ValueType) *Ref {
ref_t._void = m.VOID
base_ptr := m.GenValueType_Ptr(base)
var found bool
ref_t.underlying, found = m.GenValueType_Struct(ref_t.Name() + ".underlying")
if found {
logger.Fatalf("Type: %s already registered.", ref_t.Name()+".underlying")
}
ref_t.underlying = m.genInternalStruct(ref_t.Name() + ".underlying")
ref_t.underlying.AppendField(m.NewStructField("block", ref_t._base_block))
ref_t.underlying.AppendField(m.NewStructField("data", base_ptr))
ref_t.underlying.Finish()
......@@ -48,6 +43,7 @@ func (m *Module) GenValueType_Ref(base ValueType) *Ref {
func (t *Ref) Name() string { return t.Base.Name() + ".$ref" }
func (t *Ref) Size() int { return t.underlying.Size() }
func (t *Ref) align() int { return t.underlying.align() }
func (t *Ref) Kind() TypeKind { return kRef }
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 {
......
......@@ -34,12 +34,7 @@ func (m *Module) GenValueType_Slice(base ValueType) *Slice {
slice_t._base_block = m.GenValueType_Block(base)
slice_t._base_ptr = m.GenValueType_Ptr(base)
var found bool
slice_t.underlying, found = m.GenValueType_Struct(slice_t.Name() + ".underlying")
if found {
logger.Fatalf("Type: %s already registered.", slice_t.Name()+".underlying")
}
slice_t.underlying = m.genInternalStruct(slice_t.Name() + ".underlying")
slice_t.underlying.AppendField(m.NewStructField("block", slice_t._base_block))
slice_t.underlying.AppendField(m.NewStructField("data", slice_t._base_ptr))
slice_t.underlying.AppendField(m.NewStructField("len", slice_t._u32))
......@@ -53,6 +48,7 @@ func (m *Module) GenValueType_Slice(base ValueType) *Slice {
func (t *Slice) Name() string { return t.Base.Name() + ".$slice" }
func (t *Slice) Size() int { return t.underlying.Size() }
func (t *Slice) align() int { return t.underlying.align() }
func (t *Slice) Kind() TypeKind { return kSlice }
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 {
......
......@@ -6,7 +6,6 @@ import (
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
/**************************************
......@@ -35,12 +34,7 @@ func (m *Module) GenValueType_String() *String {
str_t._u8_block = m.GenValueType_Block(m.U8)
str_t._u8_ptr = m.GenValueType_Ptr(m.U8)
var found bool
str_t.underlying, found = m.GenValueType_Struct(str_t.Name() + ".underlying")
if found {
logger.Fatalf("Type: %s already registered.", str_t.Name()+".underlying")
}
str_t.underlying = m.genInternalStruct(str_t.Name() + ".underlying")
str_t.underlying.AppendField(m.NewStructField("block", str_t._u8_block))
str_t.underlying.AppendField(m.NewStructField("data", str_t._u8_ptr))
str_t.underlying.AppendField(m.NewStructField("len", str_t._u32))
......@@ -54,6 +48,7 @@ func (m *Module) GenValueType_String() *String {
func (t *String) Name() string { return "string" }
func (t *String) Size() int { return t.underlying.Size() }
func (t *String) align() int { return t.underlying.align() }
func (t *String) Kind() TypeKind { return kString }
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 }
......
......@@ -65,9 +65,18 @@ func (m *Module) GenValueType_Struct(name string) (*Struct, bool) {
return &struct_type, false
}
func (t *Struct) Name() string { return t.name }
func (t *Struct) Size() int { return t._size }
func (t *Struct) align() int { return t._align }
func (m *Module) genInternalStruct(name string) *Struct {
var struct_type Struct
struct_type.name = name
struct_type._u32 = m.U32
return &struct_type
}
func (t *Struct) Name() string { return t.name }
func (t *Struct) Size() int { return t._size }
func (t *Struct) align() int { return t._align }
func (t *Struct) Kind() TypeKind { return kStruct }
func (t *Struct) AppendField(f *StructField) {
t.fields = append(t.fields, f)
......
......@@ -6,7 +6,6 @@ import (
"strconv"
"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
"wa-lang.org/wa/internal/logger"
)
/**************************************
......@@ -25,12 +24,7 @@ func (m *Module) GenValueType_Tuple(fields []ValueType) *Tuple {
return t.(*Tuple)
}
var found bool
tuple_t.underlying, found = m.GenValueType_Struct(tuple_t.Name() + ".underlying")
if found {
logger.Fatalf("Type: %s already registered.", tuple_t.Name()+".underlying")
}
tuple_t.underlying = m.genInternalStruct(tuple_t.Name() + ".underlying")
for i, t := range fields {
name := "m" + strconv.Itoa(i)
tuple_t.underlying.AppendField(m.NewStructField(name, t))
......@@ -51,6 +45,7 @@ func (t *Tuple) Name() string {
func (t *Tuple) Size() int { return t.underlying.Size() }
func (t *Tuple) align() int { return t.underlying.align() }
func (t *Tuple) Kind() TypeKind { return kTuple }
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 {
......
......@@ -7,6 +7,34 @@ import (
"wa-lang.org/wa/internal/logger"
)
type TypeKind uint8
const (
kUnknown TypeKind = iota
kVoid
kU8
kU16
kU32
kU64
kI8
kI16
kI32
kI64
kF32
kF64
kRune
kPtr
kBlock
kStruct
kTuple
kRef
kString
kSlice
kArray
kMap
kInterface
)
func toWatType(t ValueType) wat.ValueType {
switch t.(type) {
case *tI32, *tRune, *tI8, *tI16:
......@@ -44,6 +72,7 @@ func toWatType(t ValueType) wat.ValueType {
tCommon:
**************************************/
type tCommon struct {
addr int
hash int
methods []Method
}
......@@ -53,6 +82,7 @@ func (t *tCommon) SetHash(h int) { t.hash = h }
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) AddMethodEntry(m FnType) { logger.Fatal("Can't add method for common type.") }
//
......@@ -76,6 +106,7 @@ type tVoid struct {
func (t *tVoid) Name() string { return "void" }
func (t *tVoid) Size() int { return 0 }
func (t *tVoid) align() int { return 0 }
func (t *tVoid) Kind() TypeKind { return kVoid }
func (t *tVoid) onFree() int { return 0 }
func (t *tVoid) Raw() []wat.ValueType { return []wat.ValueType{} }
func (t *tVoid) Equal(u ValueType) bool { _, ok := u.(*tVoid); return ok }
......@@ -94,6 +125,7 @@ type tRune struct {
func (t *tRune) Name() string { return "rune" }
func (t *tRune) Size() int { return 4 }
func (t *tRune) align() int { return 4 }
func (t *tRune) Kind() TypeKind { return kRune }
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 }
......@@ -117,6 +149,7 @@ type tI8 struct {
func (t *tI8) Name() string { return "i8" }
func (t *tI8) Size() int { return 1 }
func (t *tI8) align() int { return 1 }
func (t *tI8) Kind() TypeKind { return kI8 }
func (t *tI8) onFree() int { return 0 }
func (t *tI8) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tI8) Equal(u ValueType) bool { _, ok := u.(*tI8); return ok }
......@@ -140,6 +173,7 @@ type tU8 struct {
func (t *tU8) Name() string { return "u8" }
func (t *tU8) Size() int { return 1 }
func (t *tU8) align() int { return 1 }
func (t *tU8) Kind() TypeKind { return kU8 }
func (t *tU8) onFree() int { return 0 }
func (t *tU8) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tU8) Equal(u ValueType) bool { _, ok := u.(*tU8); return ok }
......@@ -163,6 +197,7 @@ type tI16 struct {
func (t *tI16) Name() string { return "i16" }
func (t *tI16) Size() int { return 2 }
func (t *tI16) align() int { return 2 }
func (t *tI16) Kind() TypeKind { return kI16 }
func (t *tI16) onFree() int { return 0 }
func (t *tI16) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tI16) Equal(u ValueType) bool { _, ok := u.(*tI16); return ok }
......@@ -186,6 +221,7 @@ type tU16 struct {
func (t *tU16) Name() string { return "u16" }
func (t *tU16) Size() int { return 2 }
func (t *tU16) align() int { return 2 }
func (t *tU16) Kind() TypeKind { return kU16 }
func (t *tU16) onFree() int { return 0 }
func (t *tU16) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tU16) Equal(u ValueType) bool { _, ok := u.(*tU16); return ok }
......@@ -209,6 +245,7 @@ type tI32 struct {
func (t *tI32) Name() string { return "i32" }
func (t *tI32) Size() int { return 4 }
func (t *tI32) align() int { return 4 }
func (t *tI32) Kind() TypeKind { return kI32 }
func (t *tI32) onFree() int { return 0 }
func (t *tI32) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tI32) Equal(u ValueType) bool { _, ok := u.(*tI32); return ok }
......@@ -232,6 +269,7 @@ type tU32 struct {
func (t *tU32) Name() string { return "u32" }
func (t *tU32) Size() int { return 4 }
func (t *tU32) align() int { return 4 }
func (t *tU32) Kind() TypeKind { return kU32 }
func (t *tU32) onFree() int { return 0 }
func (t *tU32) Raw() []wat.ValueType { return []wat.ValueType{wat.U32{}} }
func (t *tU32) Equal(u ValueType) bool { _, ok := u.(*tU32); return ok }
......@@ -255,6 +293,7 @@ type tI64 struct {
func (t *tI64) Name() string { return "i64" }
func (t *tI64) Size() int { return 8 }
func (t *tI64) align() int { return 8 }
func (t *tI64) Kind() TypeKind { return kI64 }
func (t *tI64) onFree() int { return 0 }
func (t *tI64) Raw() []wat.ValueType { return []wat.ValueType{wat.I64{}} }
func (t *tI64) Equal(u ValueType) bool { _, ok := u.(*tI64); return ok }
......@@ -278,6 +317,7 @@ type tU64 struct {
func (t *tU64) Name() string { return "u64" }
func (t *tU64) Size() int { return 8 }
func (t *tU64) align() int { return 8 }
func (t *tU64) Kind() TypeKind { return kU64 }
func (t *tU64) onFree() int { return 0 }
func (t *tU64) Raw() []wat.ValueType { return []wat.ValueType{wat.U64{}} }
func (t *tU64) Equal(u ValueType) bool { _, ok := u.(*tU64); return ok }
......@@ -301,6 +341,7 @@ type tF32 struct {
func (t *tF32) Name() string { return "f32" }
func (t *tF32) Size() int { return 4 }
func (t *tF32) align() int { return 4 }
func (t *tF32) Kind() TypeKind { return kF32 }
func (t *tF32) onFree() int { return 0 }
func (t *tF32) Raw() []wat.ValueType { return []wat.ValueType{wat.F32{}} }
func (t *tF32) Equal(u ValueType) bool { _, ok := u.(*tF32); return ok }
......@@ -324,6 +365,7 @@ type tF64 struct {
func (t *tF64) Name() string { return "f64" }
func (t *tF64) Size() int { return 8 }
func (t *tF64) align() int { return 8 }
func (t *tF64) Kind() TypeKind { return kF64 }
func (t *tF64) onFree() int { return 0 }
func (t *tF64) Raw() []wat.ValueType { return []wat.ValueType{wat.F64{}} }
func (t *tF64) Equal(u ValueType) bool { _, ok := u.(*tF64); return ok }
......
......@@ -54,6 +54,7 @@ type ValueType interface {
Name() string
Size() int
align() int
Kind() TypeKind
onFree() int
Raw() []wat.ValueType
Equal(ValueType) bool
......@@ -65,6 +66,8 @@ type ValueType interface {
AddMethod(m Method)
NumMethods() int
Method(i int) Method
typeInfoAddr() int
}
/**************************************
......
......@@ -13,8 +13,8 @@ type _type struct {
type _refType struct {
_type
uncommon: uintptr //@_uncommonType
elemType: uintptr //@_type
uncommon: uintptr //@_uncommonType
}
type _arrayType struct {
......@@ -30,10 +30,8 @@ type _sliceType struct {
type _structType struct {
_type
uncommon: uintptr //@_uncommonType
fieldCount: i32
fieldPtr: uintptr //@_structField, len==fieldCount
}
fieldCount: u32
} //followed by [fieldCount]_structField
type _structField struct {
name: string
......@@ -42,9 +40,8 @@ type _structField struct {
type _uncommonType struct {
pkgName: string
methodCount: i32
methodPtr: uintptr //@_method, len==methodCount
}
methodCount: u32
} //followed by [methodCount]_method
type _method struct {
name: string
......@@ -53,19 +50,16 @@ type _method struct {
}
type _fnType struct {
_type
paramCount: i32
paramPtr: uintptr //@@_type, len==paramCount
resultCount: i32
resultPtr: uintptr //@@_type, len==resultCount
}
//_type //Todo
paramCount: u32
resultCount: u32
} //followed by [paramCount]@_type + [resultCount]@_type
type _interfaceType struct {
_type
pkgName: string
methodCount: i32
methodPtr: uintptr //@_imethod, len==methodCount
}
methodCount: u32
} //followed by [methodCount]_imethod
type _imethod struct {
name: string
......@@ -75,7 +69,7 @@ type _imethod struct {
type _itab struct {
dtype: uintptr //@_type, ptr of (*data).(type)
itype: uintptr //@_interfacetype
} //紧接[itype.methodCound]fnID, fnID=id for call_indirect
} //followed by [itype.methodCound]fnID, fnID=>id for call_indirect
type _iface struct {
data: *i32
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册