提交 9dc08a73 编写于 作者: 3 3dgen

interface 阶段性实现

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