提交 6ce77e2a 编写于 作者: 3 3dgen

支持常用类型转换

上级 d0f333dd
func main() {
str := "hello"
bytes := []byte(str)
for _, c := range bytes {
println(c)
}
bytes[0] = 113
str = string(bytes)
println(str)
}
......@@ -601,7 +601,9 @@ func (g *functionGenerator) genBuiltin(call *ssa.CallCommon) (insts []wat.Inst,
avt = ut.Base
}
if avt.Equal(g.module.I32) || avt.Equal(g.module.U32) {
if avt.Equal(g.module.U8) || avt.Equal(g.module.I8) ||
avt.Equal(g.module.U16) || avt.Equal(g.module.I16) ||
avt.Equal(g.module.I32) || avt.Equal(g.module.U32) {
insts = append(insts, av.EmitPush()...)
insts = append(insts, wat.NewInstCall("$runtime.waPrintI32"))
} else if avt.Equal(g.module.F32) {
......
......@@ -397,20 +397,226 @@ func (m *Module) EmitGenLookup(x, index Value, CommaOk bool) (insts []wat.Inst,
}
func (m *Module) EmitGenConvert(x Value, typ ValueType) (insts []wat.Inst) {
src_raw_type := x.Type().Raw()
dest_raw_type := typ.Raw()
if len(src_raw_type) != len(dest_raw_type) {
logger.Fatalf("Todo: %T %T", x, typ)
panic("Todo")
for {
if u, ok := x.(*aDup); ok {
x = u.underlying
} else {
break
}
}
for i := range src_raw_type {
if src_raw_type[i].Name() != dest_raw_type[i].Name() {
logger.Fatalf("Todo: %T %T", x, typ)
panic("Todo")
for {
if ut, ok := typ.(*Dup); ok {
typ = ut.Base
} else {
break
}
}
insts = append(insts, x.EmitPush()...)
if x.Type().Equal(typ) {
insts = append(insts, x.EmitPush()...)
return
}
xt := x.Type()
switch {
case typ.Equal(m.I8):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.U8), xt.Equal(m.I16), xt.Equal(m.U16), xt.Equal(m.I32), xt.Equal(m.U32):
break
case xt.Equal(m.I64), xt.Equal(m.U64):
insts = append(insts, wat.NewInstConvert_i32_wrap_i64())
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_i32_truncs_f32())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_i32_truncs_f64())
}
return
case typ.Equal(m.U8):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.U8), xt.Equal(m.I16), xt.Equal(m.U16), xt.Equal(m.I32), xt.Equal(m.U32):
break
case xt.Equal(m.I64), xt.Equal(m.U64):
insts = append(insts, wat.NewInstConvert_i32_wrap_i64())
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_i32_truncs_f32())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_i32_truncs_f64())
}
insts = append(insts, wat.NewInstConst(wat.I32{}, "255"))
insts = append(insts, wat.NewInstAnd(wat.I32{}))
return
case typ.Equal(m.I16):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.U8), xt.Equal(m.I16), xt.Equal(m.U16), xt.Equal(m.I32), xt.Equal(m.U32):
break
case xt.Equal(m.I64), xt.Equal(m.U64):
insts = append(insts, wat.NewInstConvert_i32_wrap_i64())
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_i32_truncs_f32())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_i32_truncs_f64())
}
return
case typ.Equal(m.U16):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.U8), xt.Equal(m.I16), xt.Equal(m.U16), xt.Equal(m.I32), xt.Equal(m.U32):
break
case xt.Equal(m.I64), xt.Equal(m.U64):
insts = append(insts, wat.NewInstConvert_i32_wrap_i64())
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_i32_truncs_f32())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_i32_truncs_f64())
}
insts = append(insts, wat.NewInstConst(wat.I32{}, "65535"))
insts = append(insts, wat.NewInstAnd(wat.I32{}))
return
case typ.Equal(m.I32), typ.Equal(m.U32):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.U8), xt.Equal(m.I16), xt.Equal(m.U16), xt.Equal(m.I32), xt.Equal(m.U32):
break
case xt.Equal(m.I64), xt.Equal(m.U64):
insts = append(insts, wat.NewInstConvert_i32_wrap_i64())
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_i32_truncs_f32())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_i32_truncs_f64())
}
return
case typ.Equal(m.I64):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.I16), xt.Equal(m.I32):
insts = append(insts, wat.NewInstConvert_i64_extends_i32())
case xt.Equal(m.U8), xt.Equal(m.U16), xt.Equal(m.U32):
insts = append(insts, wat.NewInstConvert_i64_extendu_i32())
case xt.Equal(m.I64), xt.Equal(m.U64):
break
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_i64_truncs_f32())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_i64_truncs_f64())
}
return
case typ.Equal(m.U64):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.I16), xt.Equal(m.I32):
insts = append(insts, wat.NewInstConvert_i64_extendu_i32())
case xt.Equal(m.U8), xt.Equal(m.U16), xt.Equal(m.U32):
insts = append(insts, wat.NewInstConvert_i64_extendu_i32())
case xt.Equal(m.I64), xt.Equal(m.U64):
break
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_i64_truncs_f32())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_i64_truncs_f64())
}
return
case typ.Equal(m.F32):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.I16), xt.Equal(m.I32):
insts = append(insts, wat.NewInstConvert_f32_converts_i32())
case xt.Equal(m.U8), xt.Equal(m.U16), xt.Equal(m.U32):
insts = append(insts, wat.NewInstConvert_f32_convertu_i32())
case xt.Equal(m.I64):
insts = append(insts, wat.NewInstConvert_f32_converts_i64())
case xt.Equal(m.U64):
insts = append(insts, wat.NewInstConvert_f32_convertu_i64())
case xt.Equal(m.F64):
insts = append(insts, wat.NewInstConvert_f32_demote_f64())
}
return
case typ.Equal(m.F64):
insts = append(insts, x.EmitPush()...)
switch {
case xt.Equal(m.I8), xt.Equal(m.I16), xt.Equal(m.I32):
insts = append(insts, wat.NewInstConvert_f64_converts_i32())
case xt.Equal(m.U8), xt.Equal(m.U16), xt.Equal(m.U32):
insts = append(insts, wat.NewInstConvert_f64_convertu_i32())
case xt.Equal(m.I64):
insts = append(insts, wat.NewInstConvert_f64_converts_i64())
case xt.Equal(m.U64):
insts = append(insts, wat.NewInstConvert_f64_convertu_i64())
case xt.Equal(m.F32):
insts = append(insts, wat.NewInstConvert_f64_promote_f32())
}
return
case typ.Equal(m.STRING):
switch {
case xt.Equal(m.BYTES):
x := x.(*aSlice)
insts = append(insts, NewConst("", m.STRING).EmitPush()...)
insts = append(insts, x.Extract("block").EmitPush()...)
insts = append(insts, x.Extract("data").EmitPush()...)
insts = append(insts, x.Extract("len").EmitPush()...)
insts = append(insts, wat.NewInstCall(m.STRING.(*String).genFunc_Append()))
}
return
case typ.Equal(m.BYTES):
switch {
case xt.Equal(m.STRING):
x := x.(*aString)
insts = append(insts, NewConst("0", m.BYTES).EmitPush()...)
insts = append(insts, x.Extract("block").EmitPush()...)
insts = append(insts, x.Extract("data").EmitPush()...)
insts = append(insts, x.Extract("len").EmitPush()...)
insts = append(insts, x.Extract("len").EmitPush()...)
insts = append(insts, wat.NewInstCall(m.BYTES.(*Slice).genAppendFunc()))
}
return
}
logger.Fatal("Todo: %T %T", x, typ)
return
}
......
......@@ -18,7 +18,7 @@ type fnSigWrap struct {
Module:
**************************************/
type Module struct {
VOID, RUNE, I8, U8, I16, U16, I32, U32, UPTR, I64, U64, F32, F64, STRING ValueType
VOID, RUNE, I8, U8, I16, U16, I32, U32, UPTR, I64, U64, F32, F64, STRING, BYTES ValueType
types_map map[string]ValueType
usedConcreteTypes []ValueType
......@@ -81,6 +81,7 @@ func NewModule() *Module {
m.addValueType(m.F64)
m.STRING = m.GenValueType_String()
m.BYTES = m.GenValueType_Slice(m.U8)
m.fnSigsName = make(map[string]fnSigWrap)
......
......@@ -99,7 +99,7 @@ func (t *String) genFunc_Append() string {
item_size := NewConst(strconv.Itoa(t._u8.Size()), t._u32)
{ //if_false
//gen new slice
//gen new string
f.Insts = append(f.Insts, t._u8_block.emitHeapAlloc(new_len)...) //block
f.Insts = append(f.Insts, wat.NewInstCall("$wa.runtime.DupI32"))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册