compile_func.go 14.3 KB
Newer Older
3
3dgen 已提交
1 2
// 版权 @2021 凹语言 作者。保留所有权利。

chai2010's avatar
chai2010 已提交
3
package compiler_wat
3
3dgen 已提交
4 5 6 7 8 9 10 11

import (
	"strconv"

	"github.com/wa-lang/wa/internal/constant"
	"github.com/wa-lang/wa/internal/token"
	"github.com/wa-lang/wa/internal/types"

chai2010's avatar
chai2010 已提交
12
	"github.com/wa-lang/wa/internal/backends/compiler_wat/wir"
3
3dgen 已提交
13
	"github.com/wa-lang/wa/internal/backends/compiler_wat/wir/wat"
3
3dgen 已提交
14 15 16 17 18
	"github.com/wa-lang/wa/internal/logger"
	"github.com/wa-lang/wa/internal/ssa"
)

type functionGenerator struct {
3
3dgen 已提交
19
	module *wir.Module
3
3dgen 已提交
20 21 22 23 24 25 26 27 28 29 30 31

	locals_map map[ssa.Value]wir.Value

	registers    []wir.Value
	cur_local_id int

	var_block_selector wir.Value
	var_current_block  wir.Value
	var_ret            wir.Value
}

func newFunctionGenerator(p *Compiler) *functionGenerator {
3
3dgen 已提交
32
	return &functionGenerator{module: p.module, locals_map: make(map[ssa.Value]wir.Value)}
3
3dgen 已提交
33 34 35 36 37 38 39 40 41 42 43
}

func (g *functionGenerator) getValue(i ssa.Value) wir.Value {
	if i == nil {
		return nil
	}

	if v, ok := g.locals_map[i]; ok {
		return v
	}

44 45 46 47
	if v, ok := g.module.Globals_map[i]; ok {
		return v
	}

3
3dgen 已提交
48 49
	switch v := i.(type) {
	case *ssa.Const:
50 51 52
		//if v.Value == nil {
		//	return nil
		//}
3
3dgen 已提交
53

3
3dgen 已提交
54 55 56
		switch t := v.Type().(type) {
		case *types.Basic:
			switch t.Kind() {
3
3dgen 已提交
57

3
3dgen 已提交
58
			case types.Bool:
59
				if constant.BoolVal(v.Value) {
3
3dgen 已提交
60
					return wir.NewConst("1", wir.I32{})
61
				} else {
3
3dgen 已提交
62
					return wir.NewConst("0", wir.I32{})
63
				}
3
3dgen 已提交
64 65 66

			case types.Int:
				val, _ := constant.Int64Val(v.Value)
3
3dgen 已提交
67
				return wir.NewConst(strconv.Itoa(int(val)), wir.I32{})
3
3dgen 已提交
68

chai2010's avatar
chai2010 已提交
69 70
			case types.Int32:
				val, _ := constant.Int64Val(v.Value)
3
3dgen 已提交
71
				if t.Name() == "rune" {
3
3dgen 已提交
72
					return wir.NewConst(strconv.Itoa(int(val)), wir.RUNE{})
3
3dgen 已提交
73
				} else {
3
3dgen 已提交
74
					return wir.NewConst(strconv.Itoa(int(val)), wir.I32{})
3
3dgen 已提交
75
				}
chai2010's avatar
chai2010 已提交
76

3
3dgen 已提交
77
			case types.Float32:
3
3dgen 已提交
78
				val, _ := constant.Float64Val(v.Value)
3
3dgen 已提交
79
				return wir.NewConst(strconv.FormatFloat(val, 'f', -1, 32), wir.F32{})
3
3dgen 已提交
80 81

			case types.Float64:
3
3dgen 已提交
82
				val, _ := constant.Float64Val(v.Value)
3
3dgen 已提交
83
				return wir.NewConst(strconv.FormatFloat(val, 'f', -1, 64), wir.F64{})
3
3dgen 已提交
84 85

			case types.String, types.UntypedString:
3
3dgen 已提交
86 87
				val := constant.StringVal(v.Value)
				return wir.NewConst(val, wir.NewString())
3
3dgen 已提交
88 89 90 91 92

			default:
				logger.Fatalf("Todo:%T", t)
			}

3
3dgen 已提交
93 94 95
		case *types.Pointer:
			logger.Fatalf("Todo:%T", t)

3
3dgen 已提交
96
		case *types.Slice:
97 98 99
			if v.Value == nil {
				return wir.NewConst("0", wir.NewSlice(wir.ToWType(t.Elem())))
			}
3
3dgen 已提交
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
			logger.Fatalf("Todo:%T", t)

		default:
			logger.Fatalf("Todo:%T", t)
		}

	case ssa.Instruction:
		nv := g.addRegister(wir.ToWType(i.Type()))
		g.locals_map[i] = nv
		return nv
	}

	logger.Fatal("Value not found:", i)
	return nil
}

3
3dgen 已提交
116
func (g *functionGenerator) genFunction(f *ssa.Function) *wir.Function {
3
3dgen 已提交
117
	var wir_fn wir.Function
118
	if len(f.LinkName()) > 0 {
3
3dgen 已提交
119
		wir_fn.Name = f.LinkName()
120
	} else {
3
3dgen 已提交
121
		wir_fn.Name = wir.GetPkgMangleName(f.Pkg.Pkg.Path()) + f.Name()
122
	}
3
3dgen 已提交
123 124 125 126 127 128 129 130

	rets := f.Signature.Results()
	wir_fn.Result = wir.ToWType(rets)
	if rets.Len() > 1 {
		logger.Fatal("Todo")
	}

	for _, i := range f.Params {
3
3dgen 已提交
131
		pa := wir.NewLocal(i.Name(), wir.ToWType(i.Type()))
3
3dgen 已提交
132 133 134 135
		wir_fn.Params = append(wir_fn.Params, pa)
		g.locals_map[i] = pa
	}

3
3dgen 已提交
136
	g.var_block_selector = wir.NewLocal("$block_selector", wir.I32{})
3
3dgen 已提交
137
	g.registers = append(g.registers, g.var_block_selector)
3
3dgen 已提交
138
	g.var_current_block = wir.NewLocal("$current_block", wir.I32{})
3
3dgen 已提交
139
	g.registers = append(g.registers, g.var_current_block)
3
3dgen 已提交
140
	if !wir_fn.Result.Equal(wir.VOID{}) {
3
3dgen 已提交
141
		g.var_ret = wir.NewLocal("$ret", wir_fn.Result)
3
3dgen 已提交
142 143 144
		g.registers = append(g.registers, g.var_ret)
	}

3
3dgen 已提交
145
	var block_temp wat.Inst
3
3dgen 已提交
146 147
	//BlockSel:
	{
3
3dgen 已提交
148
		inst := wat.NewInstBlock("$BlockSel")
3
ref WIP  
3dgen 已提交
149
		inst.Insts = append(inst.Insts, g.var_block_selector.EmitPush()...)
3
3dgen 已提交
150 151 152 153 154
		t := make([]int, len(f.Blocks)+1)
		for i := range f.Blocks {
			t[i] = i
		}
		t[len(f.Blocks)] = 0
3
3dgen 已提交
155
		inst.Insts = append(inst.Insts, wat.NewInstBrTable(t))
3
3dgen 已提交
156 157 158 159
		block_temp = inst
	}

	for i, b := range f.Blocks {
3
3dgen 已提交
160
		block := wat.NewInstBlock("$Block_" + strconv.Itoa(i))
3
3dgen 已提交
161 162 163 164 165 166 167
		block.Insts = append(block.Insts, block_temp)
		block.Insts = append(block.Insts, g.genBlock(b)...)
		block_temp = block
	}

	//BlockDisp
	{
3
3dgen 已提交
168
		inst := wat.NewInstLoop("$BlockDisp")
3
3dgen 已提交
169 170 171 172 173 174
		inst.Insts = append(inst.Insts, block_temp)
		block_temp = inst
	}

	//BlockFnBody
	{
3
3dgen 已提交
175
		inst := wat.NewInstBlock("$BlockFnBody")
3
3dgen 已提交
176 177 178 179
		inst.Insts = append(inst.Insts, block_temp)
		block_temp = inst
	}

3
ref WIP  
3dgen 已提交
180 181 182 183
	for _, i := range g.registers {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitInit()...)
	}

3
3dgen 已提交
184
	wir_fn.Insts = append(wir_fn.Insts, block_temp)
3
3dgen 已提交
185

3
3dgen 已提交
186
	if !wir_fn.Result.Equal(wir.VOID{}) {
3
ref WIP  
3dgen 已提交
187 188 189 190 191
		wir_fn.Insts = append(wir_fn.Insts, g.var_ret.EmitPush()...)
	}

	for _, i := range g.registers {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitRelease()...)
3
3dgen 已提交
192 193
	}

3
3dgen 已提交
194 195 196 197
	for _, i := range wir_fn.Params {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitRelease()...)
	}

3
3dgen 已提交
198 199
	wir_fn.Locals = g.registers

3
3dgen 已提交
200
	return &wir_fn
3
3dgen 已提交
201 202
}

3
3dgen 已提交
203
func (g *functionGenerator) genBlock(block *ssa.BasicBlock) []wat.Inst {
3
3dgen 已提交
204 205 206 207 208
	if len(block.Instrs) == 0 {
		logger.Fatalf("Block:%s is empty", block)
	}

	cur_block_assigned := false
3
3dgen 已提交
209
	var b []wat.Inst
3
3dgen 已提交
210 211 212
	for _, inst := range block.Instrs {
		if _, ok := inst.(*ssa.Phi); !ok {
			if !cur_block_assigned {
3
3dgen 已提交
213
				b = append(b, wir.EmitAssginValue(g.var_current_block, wir.NewConst(strconv.Itoa(block.Index), wir.I32{}))...)
3
3dgen 已提交
214
				b = append(b, wat.NewBlank())
3
3dgen 已提交
215 216 217 218 219 220 221 222 223 224
				cur_block_assigned = true
			}
		}

		b = append(b, g.genInstruction(inst)...)
	}
	return b

}

3
3dgen 已提交
225 226 227
func (g *functionGenerator) genInstruction(inst ssa.Instruction) (insts []wat.Inst) {
	insts = append(insts, wat.NewComment(inst.String()))

3
3dgen 已提交
228 229 230
	switch inst := inst.(type) {

	case *ssa.If:
3
3dgen 已提交
231
		insts = append(insts, g.genIf(inst)...)
3
3dgen 已提交
232 233

	case *ssa.Store:
3
3dgen 已提交
234
		insts = append(insts, g.genStore(inst)...)
3
3dgen 已提交
235 236

	case *ssa.Jump:
3
3dgen 已提交
237
		insts = append(insts, g.genJump(inst)...)
3
3dgen 已提交
238 239

	case *ssa.Return:
3
3dgen 已提交
240
		insts = append(insts, g.genReturn(inst)...)
3
3dgen 已提交
241 242 243 244 245 246

	case *ssa.Extract:
		logger.Fatalf("Todo:%T", inst)

	case ssa.Value:
		s, t := g.genValue(inst)
3
3dgen 已提交
247
		if !t.Equal(wir.VOID{}) {
3
3dgen 已提交
248 249 250 251 252 253 254 255 256 257
			if v, ok := g.locals_map[inst]; ok {
				if !v.Type().Equal(t) {
					panic("Type not match")
				}
				s = append(s, v.EmitPop()...)
			} else {
				nv := g.addRegister(t)
				g.locals_map[inst] = nv
				s = append(s, nv.EmitPop()...)
			}
3
3dgen 已提交
258
		}
3
3dgen 已提交
259
		insts = append(insts, s...)
3
3dgen 已提交
260 261 262 263

	default:
		logger.Fatal("Todo:", inst.String())
	}
3
3dgen 已提交
264 265
	insts = append(insts, wat.NewBlank())
	return
3
3dgen 已提交
266 267
}

3
3dgen 已提交
268 269 270 271
func (g *functionGenerator) genValue(v ssa.Value) ([]wat.Inst, wir.ValueType) {
	//if _, ok := g.locals_map[v]; ok {
	//	logger.Printf("Instruction already exist:%s\n", v)
	//}
3
3dgen 已提交
272 273 274

	switch v := v.(type) {
	case *ssa.UnOp:
3
Ref WIP  
3dgen 已提交
275
		return g.genUnOp(v)
3
3dgen 已提交
276 277 278 279 280 281 282 283 284 285

	case *ssa.BinOp:
		return g.genBinOp(v)

	case *ssa.Call:
		return g.genCall(v)

	case *ssa.Phi:
		return g.genPhi(v)

3
Ref WIP  
3dgen 已提交
286 287 288
	case *ssa.Alloc:
		return g.genAlloc(v)

3
3dgen 已提交
289 290 291
	case *ssa.Field:
		return g.genFiled(v)

3
3dgen 已提交
292
	case *ssa.FieldAddr:
3
3dgen 已提交
293
		return g.genFieldAddr(v)
3
3dgen 已提交
294 295

	case *ssa.IndexAddr:
3
3dgen 已提交
296
		return g.genIndexAddr(v)
3
3dgen 已提交
297 298

	case *ssa.Slice:
299
		return g.genSlice(v)
3
3dgen 已提交
300

3
3dgen 已提交
301 302 303 304 305 306
	}

	logger.Fatalf("Todo: %v, type: %T", v, v)
	return nil, nil
}

3
3dgen 已提交
307
func (g *functionGenerator) genUnOp(inst *ssa.UnOp) (insts []wat.Inst, ret_type wir.ValueType) {
3
Ref WIP  
3dgen 已提交
308 309
	switch inst.Op {
	case token.MUL: //*x
310
		return g.genLoad(inst.X)
3
3dgen 已提交
311 312 313 314 315 316 317

	case token.SUB:
		x := g.getValue(inst.X)
		return wir.EmitUnOp(x, wat.OpCodeSub)

	default:
		logger.Fatal("Todo")
3
Ref WIP  
3dgen 已提交
318 319
	}

3
3dgen 已提交
320
	return
3
Ref WIP  
3dgen 已提交
321 322
}

3
3dgen 已提交
323
func (g *functionGenerator) genBinOp(inst *ssa.BinOp) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
324 325 326 327 328 329 330
	x := g.getValue(inst.X)
	y := g.getValue(inst.Y)

	switch inst.X.Type().Underlying().(type) {
	case *types.Basic:
		switch inst.Op {
		case token.ADD:
3
3dgen 已提交
331
			return wir.EmitBinOp(x, y, wat.OpCodeAdd)
3
3dgen 已提交
332 333

		case token.SUB:
3
3dgen 已提交
334
			return wir.EmitBinOp(x, y, wat.OpCodeSub)
3
3dgen 已提交
335 336

		case token.MUL:
3
3dgen 已提交
337
			return wir.EmitBinOp(x, y, wat.OpCodeMul)
3
3dgen 已提交
338 339

		case token.QUO:
3
3dgen 已提交
340
			return wir.EmitBinOp(x, y, wat.OpCodeQuo)
3
3dgen 已提交
341 342

		case token.REM:
3
3dgen 已提交
343
			return wir.EmitBinOp(x, y, wat.OpCodeRem)
3
3dgen 已提交
344 345

		case token.EQL:
3
3dgen 已提交
346
			return wir.EmitBinOp(x, y, wat.OpCodeEql)
3
3dgen 已提交
347 348

		case token.NEQ:
3
3dgen 已提交
349
			return wir.EmitBinOp(x, y, wat.OpCodeNe)
3
3dgen 已提交
350 351

		case token.LSS:
3
3dgen 已提交
352
			return wir.EmitBinOp(x, y, wat.OpCodeLt)
3
3dgen 已提交
353 354

		case token.GTR:
3
3dgen 已提交
355
			return wir.EmitBinOp(x, y, wat.OpCodeGt)
3
3dgen 已提交
356 357

		case token.LEQ:
3
3dgen 已提交
358
			return wir.EmitBinOp(x, y, wat.OpCodeLe)
3
3dgen 已提交
359 360

		case token.GEQ:
3
3dgen 已提交
361
			return wir.EmitBinOp(x, y, wat.OpCodeGe)
3
3dgen 已提交
362 363 364 365 366 367 368 369 370 371
		}

	default:
		logger.Fatalf("Todo: %v, type: %T, token:%v", inst, inst, inst.Op)
	}

	logger.Fatalf("Todo: %v, type: %T, token:%v", inst, inst, inst.Op)
	return nil, nil
}

3
3dgen 已提交
372
func (g *functionGenerator) genCall(inst *ssa.Call) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
373 374 375 376 377 378 379
	if inst.Call.IsInvoke() {
		logger.Fatal("Todo: genCall(), Invoke")
	}

	switch inst.Call.Value.(type) {
	case *ssa.Function:
		ret_type := wir.ToWType(inst.Call.Signature().Results())
3
3dgen 已提交
380
		var insts []wat.Inst
3
3dgen 已提交
381
		for _, v := range inst.Call.Args {
3
ref WIP  
3dgen 已提交
382
			insts = append(insts, g.getValue(v).EmitPush()...)
3
3dgen 已提交
383
		}
384 385
		callee := inst.Call.StaticCallee()
		if len(callee.LinkName()) > 0 {
3
3dgen 已提交
386
			insts = append(insts, wat.NewInstCall(callee.LinkName()))
387
		} else {
3
3dgen 已提交
388
			insts = append(insts, wat.NewInstCall(wir.GetPkgMangleName(callee.Pkg.Pkg.Path())+callee.Name()))
389
		}
3
3dgen 已提交
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
		return insts, ret_type

	case *ssa.Builtin:
		return g.genBuiltin(inst.Common())

	case *ssa.MakeClosure:
		logger.Fatal("Todo: genCall(), MakeClosure")

	default:
		logger.Fatalf("Todo: type:%T", inst.Call.Value)
	}

	logger.Fatal("Todo")

	return nil, nil
}

407
func (g *functionGenerator) genBuiltin(call *ssa.CallCommon) (insts []wat.Inst, ret_type wir.ValueType) {
3
3dgen 已提交
408 409 410 411 412
	switch call.Value.Name() {
	case "print", "println":
		for _, arg := range call.Args {
			arg := g.getValue(arg)
			switch arg.Type().(type) {
3
3dgen 已提交
413
			case wir.I32:
3
ref WIP  
3dgen 已提交
414
				insts = append(insts, arg.EmitPush()...)
415
				insts = append(insts, wat.NewInstCall("$waPrintI32"))
3
3dgen 已提交
416

3
3dgen 已提交
417 418 419 420 421 422 423 424
			case wir.F32:
				insts = append(insts, arg.EmitPush()...)
				insts = append(insts, wat.NewInstCall("$waPrintF32"))

			case wir.F64:
				insts = append(insts, arg.EmitPush()...)
				insts = append(insts, wat.NewInstCall("$waPrintF64"))

3
3dgen 已提交
425
			case wir.RUNE:
3
ref WIP  
3dgen 已提交
426
				insts = append(insts, arg.EmitPush()...)
427
				insts = append(insts, wat.NewInstCall("$waPrintRune"))
3
3dgen 已提交
428

3
3dgen 已提交
429 430 431
			case wir.String:
				insts = append(insts, wir.EmitPrintString(arg)...)

3
3dgen 已提交
432
			default:
3
3dgen 已提交
433
				logger.Fatalf("Todo: print(%T)", arg.Type())
3
3dgen 已提交
434 435 436 437
			}
		}

		if call.Value.Name() == "println" {
3
3dgen 已提交
438
			insts = append(insts, wir.NewConst(strconv.Itoa('\n'), wir.I32{}).EmitPush()...)
439
			insts = append(insts, wat.NewInstCall("$waPrintRune"))
3
3dgen 已提交
440
		}
441 442 443 444 445 446 447 448 449 450 451 452 453 454
		ret_type = wir.VOID{}

	case "append":
		if len(call.Args) != 2 {
			panic("len(call.Args) != 2")
		}
		insts, ret_type = wir.EmitGenAppend(g.getValue(call.Args[0]), g.getValue(call.Args[1]))

	case "len":
		if len(call.Args) != 1 {
			panic("len(call.Args) != 1")
		}
		insts = wir.EmitGenLen(g.getValue(call.Args[0]))
		ret_type = wir.I32{}
3
3dgen 已提交
455

456 457
	default:
		logger.Fatal("Todo:", call.Value)
3
3dgen 已提交
458
	}
459
	return
3
3dgen 已提交
460 461
}

3
3dgen 已提交
462 463
func (g *functionGenerator) genPhiIter(preds []int, values []wir.Value) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
464

3
3dgen 已提交
465
	cond, _ := wir.EmitBinOp(g.var_current_block, wir.NewConst(strconv.Itoa(preds[0]), wir.I32{}), wat.OpCodeEql)
3
3dgen 已提交
466 467
	insts = append(insts, cond...)

3
ref WIP  
3dgen 已提交
468
	trueInsts := values[0].EmitPush()
3
3dgen 已提交
469
	var falseInsts []wat.Inst
3
3dgen 已提交
470
	if len(preds) == 2 {
3
ref WIP  
3dgen 已提交
471
		falseInsts = values[1].EmitPush()
3
3dgen 已提交
472
	} else {
3
3dgen 已提交
473
		falseInsts = g.genPhiIter(preds[1:], values[1:])
3
3dgen 已提交
474
	}
3
3dgen 已提交
475
	insts = append(insts, wat.NewInstIf(trueInsts, falseInsts, values[0].Type().Raw()))
3
3dgen 已提交
476 477 478

	return insts
}
3
3dgen 已提交
479
func (g *functionGenerator) genPhi(inst *ssa.Phi) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
480 481 482 483 484 485 486 487 488
	var preds []int
	var values []wir.Value
	for i, v := range inst.Edges {
		preds = append(preds, inst.Block().Preds[i].Index)
		values = append(values, g.getValue(v))
	}
	return g.genPhiIter(preds, values), wir.ToWType(inst.Type())
}

3
3dgen 已提交
489 490
func (g *functionGenerator) genReturn(inst *ssa.Return) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
491 492 493 494 495 496 497 498 499 500 501 502

	switch len(inst.Results) {
	case 0:
		break

	case 1:
		insts = append(insts, wir.EmitAssginValue(g.var_ret, g.getValue(inst.Results[0]))...)

	default:
		logger.Fatal("Todo")
	}

3
3dgen 已提交
503
	insts = append(insts, wat.NewInstBr("$BlockFnBody"))
3
3dgen 已提交
504 505 506
	return insts
}

507 508 509 510
func (g *functionGenerator) genLoad(addr ssa.Value) ([]wat.Inst, wir.ValueType) {
	return wir.EmitLoad(g.getValue(addr))
}

3
ref WIP  
3dgen 已提交
511 512 513 514
func (g *functionGenerator) genStore(inst *ssa.Store) []wat.Inst {
	return wir.EmitStore(g.getValue(inst.Addr), g.getValue(inst.Val))
}

3
3dgen 已提交
515
func (g *functionGenerator) genIf(inst *ssa.If) []wat.Inst {
3
3dgen 已提交
516
	cond := g.getValue(inst.Cond)
3
3dgen 已提交
517
	if !cond.Type().Equal(wir.I32{}) {
3
3dgen 已提交
518 519 520
		logger.Fatal("cond.type() != i32")
	}

3
ref WIP  
3dgen 已提交
521
	insts := cond.EmitPush()
3
3dgen 已提交
522 523
	instsTrue := g.genJumpID(inst.Block().Index, inst.Block().Succs[0].Index)
	instsFalse := g.genJumpID(inst.Block().Index, inst.Block().Succs[1].Index)
3
3dgen 已提交
524
	insts = append(insts, wat.NewInstIf(instsTrue, instsFalse, nil))
3
3dgen 已提交
525 526 527 528

	return insts
}

3
3dgen 已提交
529
func (g *functionGenerator) genJump(inst *ssa.Jump) []wat.Inst {
3
3dgen 已提交
530 531 532
	return g.genJumpID(inst.Block().Index, inst.Block().Succs[0].Index)
}

3
3dgen 已提交
533 534
func (g *functionGenerator) genJumpID(cur, dest int) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
535 536

	if cur >= dest {
3
3dgen 已提交
537
		insts = wir.EmitAssginValue(g.var_block_selector, wir.NewConst(strconv.Itoa(dest), wir.I32{}))
3
3dgen 已提交
538
		insts = append(insts, wat.NewInstBr("$BlockDisp"))
3
3dgen 已提交
539
	} else {
3
3dgen 已提交
540
		insts = append(insts, wat.NewInstBr("$Block_"+strconv.Itoa(dest-1)))
3
3dgen 已提交
541 542 543 544 545
	}

	return insts
}

3
Ref WIP  
3dgen 已提交
546 547
func (g *functionGenerator) genAlloc(inst *ssa.Alloc) ([]wat.Inst, wir.ValueType) {
	if inst.Heap {
548
		return wir.EmitHeapAlloc(wir.ToWType(inst.Type().(*types.Pointer).Elem()))
3
Ref WIP  
3dgen 已提交
549
	} else {
550
		return wir.EmitStackAlloc(wir.ToWType(inst.Type().(*types.Pointer).Elem()))
3
Ref WIP  
3dgen 已提交
551 552 553
	}
}

3
3dgen 已提交
554 555 556 557 558 559 560 561 562 563 564
func (g *functionGenerator) genFiled(inst *ssa.Field) ([]wat.Inst, wir.ValueType) {
	x := g.getValue(inst.X)
	field := inst.X.Type().Underlying().(*types.Struct).Field(inst.Field)
	fieldname := field.Name()
	if field.Embedded() {
		fieldname = "$" + fieldname
	}

	return wir.EmitGenField(x, fieldname)
}

3
3dgen 已提交
565 566 567 568 569 570 571 572 573 574
func (g *functionGenerator) genFieldAddr(inst *ssa.FieldAddr) ([]wat.Inst, wir.ValueType) {
	field := inst.X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct).Field(inst.Field)
	fieldname := field.Name()
	if field.Embedded() {
		fieldname = "$" + fieldname
	}

	return wir.EmitGenFieldAddr(g.getValue(inst.X), fieldname)
}

3
3dgen 已提交
575 576 577 578 579 580 581
func (g *functionGenerator) genIndexAddr(inst *ssa.IndexAddr) ([]wat.Inst, wir.ValueType) {
	x := g.getValue(inst.X)
	id := g.getValue(inst.Index)

	return wir.EmitGenIndexAddr(x, id)
}

582 583 584 585 586 587 588 589 590 591 592 593 594
func (g *functionGenerator) genSlice(inst *ssa.Slice) ([]wat.Inst, wir.ValueType) {
	x := g.getValue(inst.X)
	var low, high wir.Value
	if inst.Low != nil {
		low = g.getValue(inst.Low)
	}
	if inst.High != nil {
		high = g.getValue(inst.High)
	}

	return wir.EmitGenSlice(x, low, high)
}

3
3dgen 已提交
595
func (g *functionGenerator) addRegister(typ wir.ValueType) wir.Value {
3
3dgen 已提交
596
	defer func() { g.cur_local_id++ }()
3
3dgen 已提交
597
	name := "$T_" + strconv.Itoa(g.cur_local_id)
3
3dgen 已提交
598
	v := wir.NewLocal(name, typ)
3
3dgen 已提交
599 600 601
	g.registers = append(g.registers, v)
	return v
}