Merge branch 'backend_wasm'
This commit is contained in:
commit
6017de5bec
|
|
@ -42,6 +42,13 @@ func (p *Compiler) Compile(prog *loader.Program, mainFunc string) (output string
|
|||
}
|
||||
sort.Strings(pkgnames)
|
||||
|
||||
for i, v := range pkgnames {
|
||||
if v == "runtime" && i != 0 {
|
||||
pkgnames[i] = pkgnames[0]
|
||||
pkgnames[0] = "runtime"
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range pkgnames {
|
||||
p.ssaPkg = prog.Pkgs[n].SSAPkg
|
||||
p.CompilePkgConst(p.ssaPkg)
|
||||
|
|
|
|||
|
|
@ -359,6 +359,10 @@ func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
|
|||
// logger.Printf("Instruction already exist:%s\n", v)
|
||||
//}
|
||||
|
||||
if v, ok := v.(*ssa.Range); ok {
|
||||
return g.genRange(v)
|
||||
}
|
||||
|
||||
//Todo: 下面的做法过于粗暴
|
||||
g.tLib.compile(v.Type())
|
||||
|
||||
|
|
@ -419,6 +423,9 @@ func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
|
|||
|
||||
case *ssa.TypeAssert:
|
||||
return g.genTypeAssert(v)
|
||||
|
||||
case *ssa.Next:
|
||||
return g.genNext(v)
|
||||
}
|
||||
|
||||
logger.Fatalf("Todo: %v, type: %T", v, v)
|
||||
|
|
@ -1142,6 +1149,22 @@ func (g *functionGenerator) genTypeAssert(inst *ssa.TypeAssert) (insts []wat.Ins
|
|||
return
|
||||
}
|
||||
|
||||
func (g *functionGenerator) genRange(inst *ssa.Range) (insts []wat.Inst, ret_type wir.ValueType) {
|
||||
x := g.getValue(inst.X)
|
||||
return g.module.EmitGenRange(x.value)
|
||||
}
|
||||
|
||||
func (g *functionGenerator) genNext(inst *ssa.Next) (insts []wat.Inst, ret_type wir.ValueType) {
|
||||
if inst.IsString {
|
||||
ret_type = g.tLib.compile(inst.Type())
|
||||
iter := g.getValue(inst.Iter).value
|
||||
insts = g.module.EmitGenNext_String(iter)
|
||||
} else {
|
||||
logger.Fatalf("Todo:%T", inst.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)
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ func (m *Module) EmitAssginValue(lh, rh Value) []wat.Inst {
|
|||
insts = append(insts, lh.EmitRelease()...)
|
||||
insts = append(insts, lh.EmitInit()...)
|
||||
} else {
|
||||
if !lh.Type().Equal(rh.Type()) {
|
||||
logger.Fatal("x.Type() != y.Type()")
|
||||
if !lh.Type().Equal(rh.Type()) && !(lh.Type().Equal(m.I32) && rh.Type().Equal(m.RUNE) || lh.Type().Equal(m.RUNE) && rh.Type().Equal(m.I32)) {
|
||||
logger.Fatal("x.Type:", lh.Type().Name(), ", y.Type():", rh.Type().Name())
|
||||
}
|
||||
|
||||
insts = append(insts, rh.EmitPush()...)
|
||||
|
|
@ -893,6 +893,28 @@ func (m *Module) EmitGenTypeAssert(x Value, destType ValueType, commaOk bool) (i
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Module) EmitGenRange(x Value) (insts []wat.Inst, ret_type ValueType) {
|
||||
switch x := x.(type) {
|
||||
case *aString:
|
||||
ret_type, _ = m.findValueType("runtime.stringIter")
|
||||
insts = append(insts, x.Extract("d").EmitPush()...)
|
||||
insts = append(insts, x.Extract("l").EmitPush()...)
|
||||
insts = append(insts, wat.NewInstConst(wat.I32{}, "0"))
|
||||
|
||||
default:
|
||||
logger.Fatalf("Todo:%T", x)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Module) EmitGenNext_String(iter Value) (insts []wat.Inst) {
|
||||
insts = append(insts, iter.EmitPush()...)
|
||||
insts = append(insts, wat.NewInstCall("runtime.next_rune"))
|
||||
insts = append(insts, iter.(*aStruct).Extract("pos").EmitPop()...)
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Module) EmitInvoke(i Value, params []Value, mid int, typeName string) (insts []wat.Inst) {
|
||||
iface := i.(*aInterface)
|
||||
insts = append(insts, iface.Extract("d").EmitPush()...)
|
||||
|
|
|
|||
|
|
@ -163,3 +163,43 @@ func refToPtr_byteSlice(t: []byte) => i32 {
|
|||
func refToPtr_string(s: string) => i32 {
|
||||
return U8_string_to_ptr(s)
|
||||
}
|
||||
|
||||
type stringIter struct {
|
||||
ptr: uint
|
||||
len: int
|
||||
pos: int
|
||||
}
|
||||
|
||||
#wa:runtime_getter
|
||||
func get_u8(p: u32) => u8
|
||||
|
||||
#wa:runtime_setter
|
||||
func set_u8(p: u32, v: u8)
|
||||
|
||||
func next_rune(iter: stringIter) => (ok: bool, k: int, v: rune, pos: int) {
|
||||
if iter.pos >= iter.len {
|
||||
return false, iter.pos, 0, iter.pos
|
||||
}
|
||||
|
||||
p0 := i32(get_u8(u32(iter.ptr) + u32(iter.pos)))
|
||||
if p0 & 0b10000000 == 0 {
|
||||
return true, iter.pos, rune(p0), iter.pos + 1
|
||||
} else if p0 & 0b11100000 == 0b11000000 {
|
||||
p0 = (p0 & 0b11111) << 6
|
||||
p1 := i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 1)) & 0b00111111
|
||||
return true, iter.pos, rune(p0 | p1), iter.pos + 2
|
||||
} else if p0 & 0b11110000 == 0b11100000 {
|
||||
p0 = (p0 & 0b1111) << 12
|
||||
p1 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 1)) & 0b00111111) << 6
|
||||
p2 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 2)) & 0b00111111)
|
||||
return true, iter.pos, rune(p0 | p1 | p2), iter.pos + 3
|
||||
} else if p0 & 0b11111000 == 0b11110000 {
|
||||
p0 = (p0 & 0b111) << 18
|
||||
p1 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 1)) & 0b00111111) << 12
|
||||
p2 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 2)) & 0b00111111) << 6
|
||||
p3 := (i32(get_u8(u32(iter.ptr) + u32(iter.pos) + 3)) & 0b00111111)
|
||||
return true, iter.pos, rune(p0 | p1 | p2 | p3), iter.pos + 4
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue