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

chai2010's avatar
chai2010 已提交
3
package compiler_wat
3
3dgen 已提交
4 5 6

import (
	"strconv"
3
3dgen 已提交
7
	"strings"
3
3dgen 已提交
8

chai2010's avatar
chai2010 已提交
9 10 11 12 13 14 15 16
	"wa-lang.org/wa/internal/constant"
	"wa-lang.org/wa/internal/token"
	"wa-lang.org/wa/internal/types"

	"wa-lang.org/wa/internal/backends/compiler_wat/wir"
	"wa-lang.org/wa/internal/backends/compiler_wat/wir/wat"
	"wa-lang.org/wa/internal/logger"
	"wa-lang.org/wa/internal/ssa"
3
3dgen 已提交
17 18
)

3
3dgen 已提交
19 20 21 22 23
type valueWrap struct {
	value          wir.Value
	force_register bool
}

3
3dgen 已提交
24
type functionGenerator struct {
3
3dgen 已提交
25
	module *wir.Module
3
3dgen 已提交
26

3
3dgen 已提交
27
	locals_map map[ssa.Value]valueWrap
3
3dgen 已提交
28 29 30 31 32 33

	registers    []wir.Value
	cur_local_id int

	var_block_selector wir.Value
	var_current_block  wir.Value
3
3dgen 已提交
34
	var_rets           []wir.Value
3
3dgen 已提交
35 36
}

3
3dgen 已提交
37 38
func newFunctionGenerator(module *wir.Module) *functionGenerator {
	return &functionGenerator{module: module, locals_map: make(map[ssa.Value]valueWrap)}
3
3dgen 已提交
39 40
}

3
3dgen 已提交
41
func (g *functionGenerator) getValue(i ssa.Value) valueWrap {
3
3dgen 已提交
42
	if i == nil {
3
3dgen 已提交
43
		return valueWrap{}
3
3dgen 已提交
44 45 46 47 48 49
	}

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

50
	if v, ok := g.module.Globals_map[i]; ok {
3
3dgen 已提交
51
		return valueWrap{value: v}
52 53
	}

3
3dgen 已提交
54 55
	switch v := i.(type) {
	case *ssa.Const:
56 57 58
		//if v.Value == nil {
		//	return nil
		//}
3
3dgen 已提交
59

3
3dgen 已提交
60 61 62
		switch t := v.Type().(type) {
		case *types.Basic:
			switch t.Kind() {
3
3dgen 已提交
63

3
3dgen 已提交
64
			case types.Bool:
65
				if constant.BoolVal(v.Value) {
3
3dgen 已提交
66
					return valueWrap{value: wir.NewConst("1", wir.I32{})}
67
				} else {
3
3dgen 已提交
68
					return valueWrap{value: wir.NewConst("0", wir.I32{})}
69
				}
3
3dgen 已提交
70 71 72

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

3
3dgen 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
			case types.Uint8:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.U8{})}

			case types.Int8:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.I8{})}

			case types.Uint16:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.U16{})}

			case types.Int16:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.I16{})}

3
3dgen 已提交
91 92 93
			case types.Uint32:
				val, _ := constant.Uint64Val(v.Value)
				return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.U32{})}
3
3dgen 已提交
94

chai2010's avatar
chai2010 已提交
95 96
			case types.Int32:
				val, _ := constant.Int64Val(v.Value)
3
3dgen 已提交
97
				if t.Name() == "rune" {
3
3dgen 已提交
98
					return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.RUNE{})}
3
3dgen 已提交
99
				} else {
3
3dgen 已提交
100
					return valueWrap{value: wir.NewConst(strconv.Itoa(int(val)), wir.I32{})}
3
3dgen 已提交
101
				}
chai2010's avatar
chai2010 已提交
102

3
3dgen 已提交
103
			case types.Float32:
3
3dgen 已提交
104
				val, _ := constant.Float64Val(v.Value)
3
3dgen 已提交
105
				return valueWrap{value: wir.NewConst(strconv.FormatFloat(val, 'f', -1, 32), wir.F32{})}
3
3dgen 已提交
106 107

			case types.Float64:
3
3dgen 已提交
108
				val, _ := constant.Float64Val(v.Value)
3
3dgen 已提交
109
				return valueWrap{value: wir.NewConst(strconv.FormatFloat(val, 'f', -1, 64), wir.F64{})}
3
3dgen 已提交
110 111

			case types.String, types.UntypedString:
3
3dgen 已提交
112
				val := constant.StringVal(v.Value)
3
3dgen 已提交
113
				return valueWrap{value: wir.NewConst(val, wir.NewString())}
3
3dgen 已提交
114 115

			default:
3
3dgen 已提交
116
				logger.Fatalf("Todo:%T %v", t, t.Kind())
3
3dgen 已提交
117 118
			}

3
3dgen 已提交
119
		case *types.Pointer:
3
3dgen 已提交
120 121 122 123 124
			if v.Value == nil {
				return valueWrap{}
			} else {
				logger.Fatalf("Todo:%T", t)
			}
3
3dgen 已提交
125

3
3dgen 已提交
126
		case *types.Slice:
127
			if v.Value == nil {
3
3dgen 已提交
128
				return valueWrap{value: wir.NewConst("0", wir.NewSlice(wir.ToWType(t.Elem())))}
129
			}
3
3dgen 已提交
130 131 132 133 134 135 136
			logger.Fatalf("Todo:%T", t)

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

	case ssa.Instruction:
3
3dgen 已提交
137
		nv := valueWrap{value: g.addRegister(wir.ToWType(i.Type()))}
3
3dgen 已提交
138 139
		g.locals_map[i] = nv
		return nv
3
3dgen 已提交
140 141

	case *ssa.Function:
142
		fn_name, _ := GetFnMangleName(v)
3
3dgen 已提交
143 144 145
		fn_sig := wir.NewFnSigFromSignature(v.Signature)

		return valueWrap{value: wir.GenConstFnValue(fn_name, fn_sig)}
3
3dgen 已提交
146 147 148
	}

	logger.Fatal("Value not found:", i)
3
3dgen 已提交
149
	return valueWrap{}
3
3dgen 已提交
150 151
}

3
3dgen 已提交
152
func (g *functionGenerator) genFunction(f *ssa.Function) *wir.Function {
3
3dgen 已提交
153
	var wir_fn wir.Function
3
3dgen 已提交
154 155 156 157 158 159 160 161 162 163 164 165
	{
		internal, external := GetFnMangleName(f)
		if len(f.LinkName()) > 0 {
			wir_fn.InternalName = f.LinkName()
		} else {
			wir_fn.InternalName = internal
		}
		if len(f.ExportName()) > 0 {
			wir_fn.ExternalName = f.ExportName()
		} else {
			wir_fn.ExternalName = external
		}
166
	}
3
3dgen 已提交
167 168

	rets := f.Signature.Results()
3
3dgen 已提交
169 170 171 172 173 174 175 176 177 178 179 180
	switch rets.Len() {
	case 0:
		break

	case 1:
		wir_fn.Results = append(wir_fn.Results, wir.ToWType(rets.At(0).Type()))

	default:
		typ := wir.ToWType(rets).(wir.Tuple)
		for _, f := range typ.Members {
			wir_fn.Results = append(wir_fn.Results, f.Type())
		}
3
3dgen 已提交
181 182
	}

3
3dgen 已提交
183 184 185 186 187
	for _, i := range f.FreeVars {
		fv := valueWrap{value: wir.NewLocal(i.Name(), wir.ToWType(i.Type()))}
		wir_fn.Params = append(wir_fn.Params, fv.value)
		g.locals_map[i] = fv
	}
3
3dgen 已提交
188
	for _, i := range f.Params {
3
3dgen 已提交
189 190 191
		pv := valueWrap{value: wir.NewLocal(i.Name(), wir.ToWType(i.Type()))}
		wir_fn.Params = append(wir_fn.Params, pv.value)
		g.locals_map[i] = pv
3
3dgen 已提交
192 193
	}

3
3dgen 已提交
194
	g.var_block_selector = wir.NewLocal("$block_selector", wir.I32{})
3
3dgen 已提交
195
	g.registers = append(g.registers, g.var_block_selector)
3
3dgen 已提交
196
	g.var_current_block = wir.NewLocal("$current_block", wir.I32{})
3
3dgen 已提交
197
	g.registers = append(g.registers, g.var_current_block)
3
3dgen 已提交
198 199 200 201 202
	for i, rt := range wir_fn.Results {
		rname := "$ret_" + strconv.Itoa(i)
		r := wir.NewLocal(rname, rt)
		g.var_rets = append(g.var_rets, r)
		g.registers = append(g.registers, r)
3
3dgen 已提交
203 204
	}

3
3dgen 已提交
205
	var block_temp wat.Inst
3
3dgen 已提交
206 207
	//BlockSel:
	{
3
3dgen 已提交
208
		inst := wat.NewInstBlock("$BlockSel")
3
ref WIP  
3dgen 已提交
209
		inst.Insts = append(inst.Insts, g.var_block_selector.EmitPush()...)
3
3dgen 已提交
210 211 212 213 214
		t := make([]int, len(f.Blocks)+1)
		for i := range f.Blocks {
			t[i] = i
		}
		t[len(f.Blocks)] = 0
3
3dgen 已提交
215
		inst.Insts = append(inst.Insts, wat.NewInstBrTable(t))
3
3dgen 已提交
216 217 218 219
		block_temp = inst
	}

	for i, b := range f.Blocks {
3
3dgen 已提交
220
		block := wat.NewInstBlock("$Block_" + strconv.Itoa(i))
3
3dgen 已提交
221 222 223 224 225 226 227
		block.Insts = append(block.Insts, block_temp)
		block.Insts = append(block.Insts, g.genBlock(b)...)
		block_temp = block
	}

	//BlockDisp
	{
3
3dgen 已提交
228
		inst := wat.NewInstLoop("$BlockDisp")
3
3dgen 已提交
229 230 231 232 233 234
		inst.Insts = append(inst.Insts, block_temp)
		block_temp = inst
	}

	//BlockFnBody
	{
3
3dgen 已提交
235
		inst := wat.NewInstBlock("$BlockFnBody")
3
3dgen 已提交
236 237 238 239
		inst.Insts = append(inst.Insts, block_temp)
		block_temp = inst
	}

3
ref WIP  
3dgen 已提交
240 241 242 243
	for _, i := range g.registers {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitInit()...)
	}

3
3dgen 已提交
244
	wir_fn.Insts = append(wir_fn.Insts, block_temp)
3
3dgen 已提交
245

3
3dgen 已提交
246 247
	for _, r := range g.var_rets {
		wir_fn.Insts = append(wir_fn.Insts, r.EmitPush()...)
3
ref WIP  
3dgen 已提交
248 249 250 251
	}

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

3
3dgen 已提交
254 255 256 257
	for _, i := range wir_fn.Params {
		wir_fn.Insts = append(wir_fn.Insts, i.EmitRelease()...)
	}

3
3dgen 已提交
258 259
	wir_fn.Locals = g.registers

3
3dgen 已提交
260
	return &wir_fn
3
3dgen 已提交
261 262
}

3
3dgen 已提交
263
func (g *functionGenerator) genBlock(block *ssa.BasicBlock) []wat.Inst {
3
3dgen 已提交
264 265 266 267 268
	if len(block.Instrs) == 0 {
		logger.Fatalf("Block:%s is empty", block)
	}

	cur_block_assigned := false
3
3dgen 已提交
269
	var b []wat.Inst
3
3dgen 已提交
270 271 272
	for _, inst := range block.Instrs {
		if _, ok := inst.(*ssa.Phi); !ok {
			if !cur_block_assigned {
3
3dgen 已提交
273
				b = append(b, wir.EmitAssginValue(g.var_current_block, wir.NewConst(strconv.Itoa(block.Index), wir.I32{}))...)
3
3dgen 已提交
274
				b = append(b, wat.NewBlank())
3
3dgen 已提交
275 276 277 278 279 280 281 282 283 284
				cur_block_assigned = true
			}
		}

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

}

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

3
3dgen 已提交
288 289 290
	switch inst := inst.(type) {

	case *ssa.If:
3
3dgen 已提交
291
		insts = append(insts, g.genIf(inst)...)
3
3dgen 已提交
292 293

	case *ssa.Store:
3
3dgen 已提交
294
		insts = append(insts, g.genStore(inst)...)
3
3dgen 已提交
295 296

	case *ssa.Jump:
3
3dgen 已提交
297
		insts = append(insts, g.genJump(inst)...)
3
3dgen 已提交
298 299

	case *ssa.Return:
3
3dgen 已提交
300
		insts = append(insts, g.genReturn(inst)...)
3
3dgen 已提交
301 302 303

	case ssa.Value:
		s, t := g.genValue(inst)
3
3dgen 已提交
304
		if t != nil && !t.Equal(wir.VOID{}) {
3
3dgen 已提交
305
			if v, ok := g.locals_map[inst]; ok {
3
3dgen 已提交
306
				if !v.value.Type().Equal(t) {
3
3dgen 已提交
307 308
					panic("Type not match")
				}
3
3dgen 已提交
309
				s = append(s, v.value.EmitPop()...)
3
3dgen 已提交
310 311
			} else {
				nv := g.addRegister(t)
3
3dgen 已提交
312
				g.locals_map[inst] = valueWrap{value: nv}
3
3dgen 已提交
313 314
				s = append(s, nv.EmitPop()...)
			}
3
3dgen 已提交
315
		}
3
3dgen 已提交
316
		insts = append(insts, s...)
3
3dgen 已提交
317 318 319 320

	default:
		logger.Fatal("Todo:", inst.String())
	}
3
3dgen 已提交
321 322
	insts = append(insts, wat.NewBlank())
	return
3
3dgen 已提交
323 324
}

3
3dgen 已提交
325 326 327 328
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 已提交
329 330 331

	switch v := v.(type) {
	case *ssa.UnOp:
3
Ref WIP  
3dgen 已提交
332
		return g.genUnOp(v)
3
3dgen 已提交
333 334 335 336 337 338 339 340 341 342

	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 已提交
343 344 345
	case *ssa.Alloc:
		return g.genAlloc(v)

3
3dgen 已提交
346 347 348
	case *ssa.Extract:
		return g.genExtract(v)

3
3dgen 已提交
349 350 351
	case *ssa.Field:
		return g.genFiled(v)

3
3dgen 已提交
352
	case *ssa.FieldAddr:
3
3dgen 已提交
353
		return g.genFieldAddr(v)
3
3dgen 已提交
354 355

	case *ssa.IndexAddr:
3
3dgen 已提交
356
		return g.genIndexAddr(v)
3
3dgen 已提交
357 358

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

3
3dgen 已提交
361 362 363 364 365 366
	case *ssa.Lookup:
		return g.genLookup(v)

	case *ssa.Convert:
		return g.genConvert(v)

3
3dgen 已提交
367 368
	case *ssa.ChangeType:
		return g.genChangeType(v)
3
3dgen 已提交
369 370 371

	case *ssa.MakeClosure:
		return g.genMakeClosre(v)
3
3dgen 已提交
372 373 374 375 376 377
	}

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

3
3dgen 已提交
378
func (g *functionGenerator) genUnOp(inst *ssa.UnOp) (insts []wat.Inst, ret_type wir.ValueType) {
3
Ref WIP  
3dgen 已提交
379 380
	switch inst.Op {
	case token.MUL: //*x
381
		return g.genLoad(inst.X)
3
3dgen 已提交
382 383 384

	case token.SUB:
		x := g.getValue(inst.X)
3
3dgen 已提交
385
		return wir.EmitUnOp(x.value, wat.OpCodeSub)
3
3dgen 已提交
386 387 388

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

3
3dgen 已提交
391
	return
3
Ref WIP  
3dgen 已提交
392 393
}

3
3dgen 已提交
394
func (g *functionGenerator) genBinOp(inst *ssa.BinOp) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
395 396 397 398 399 400 401
	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 已提交
402
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeAdd)
3
3dgen 已提交
403 404

		case token.SUB:
3
3dgen 已提交
405
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeSub)
3
3dgen 已提交
406 407

		case token.MUL:
3
3dgen 已提交
408
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeMul)
3
3dgen 已提交
409 410

		case token.QUO:
3
3dgen 已提交
411
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeQuo)
3
3dgen 已提交
412 413

		case token.REM:
3
3dgen 已提交
414
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeRem)
3
3dgen 已提交
415 416

		case token.EQL:
3
3dgen 已提交
417
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeEql)
3
3dgen 已提交
418 419

		case token.NEQ:
3
3dgen 已提交
420
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeNe)
3
3dgen 已提交
421 422

		case token.LSS:
3
3dgen 已提交
423
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeLt)
3
3dgen 已提交
424 425

		case token.GTR:
3
3dgen 已提交
426
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeGt)
3
3dgen 已提交
427 428

		case token.LEQ:
3
3dgen 已提交
429
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeLe)
3
3dgen 已提交
430 431

		case token.GEQ:
3
3dgen 已提交
432
			return wir.EmitBinOp(x.value, y.value, wat.OpCodeGe)
3
3dgen 已提交
433 434 435 436 437 438 439 440 441 442
		}

	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 已提交
443
func (g *functionGenerator) genCall(inst *ssa.Call) (insts []wat.Inst, ret_type wir.ValueType) {
3
3dgen 已提交
444 445 446 447 448 449
	if inst.Call.IsInvoke() {
		logger.Fatal("Todo: genCall(), Invoke")
	}

	switch inst.Call.Value.(type) {
	case *ssa.Function:
3
3dgen 已提交
450
		ret_type = wir.ToWType(inst.Call.Signature().Results())
3
3dgen 已提交
451
		for _, v := range inst.Call.Args {
3
3dgen 已提交
452
			insts = append(insts, g.getValue(v).value.EmitPush()...)
3
3dgen 已提交
453
		}
454
		callee := inst.Call.StaticCallee()
3
3dgen 已提交
455 456 457 458
		if callee.Parent() != nil {
			g.module.AddFunc(newFunctionGenerator(g.module).genFunction(callee))
		}

459
		if len(callee.LinkName()) > 0 {
3
3dgen 已提交
460
			insts = append(insts, wat.NewInstCall(callee.LinkName()))
461
		} else {
462 463
			fn_internal_name, _ := GetFnMangleName(callee)
			insts = append(insts, wat.NewInstCall(fn_internal_name))
464
		}
3
3dgen 已提交
465 466 467 468 469

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

	case *ssa.MakeClosure:
3
3dgen 已提交
470 471 472 473 474 475 476
		ret_type = wir.ToWType(inst.Type())
		var params []wir.Value
		for _, v := range inst.Call.Args {
			params = append(params, g.getValue(v).value)
		}
		closure := g.getValue(inst.Call.Value)
		insts = wir.EmitCallClosure(closure.value, params)
3
3dgen 已提交
477 478

	default:
3
3dgen 已提交
479 480 481 482 483 484 485
		ret_type = wir.ToWType(inst.Type())
		var params []wir.Value
		for _, v := range inst.Call.Args {
			params = append(params, g.getValue(v).value)
		}
		closure := g.getValue(inst.Call.Value)
		insts = wir.EmitCallClosure(closure.value, params)
3
3dgen 已提交
486

3
3dgen 已提交
487
	}
3
3dgen 已提交
488

3
3dgen 已提交
489
	return
3
3dgen 已提交
490 491
}

492
func (g *functionGenerator) genBuiltin(call *ssa.CallCommon) (insts []wat.Inst, ret_type wir.ValueType) {
3
3dgen 已提交
493 494 495 496
	switch call.Value.Name() {
	case "print", "println":
		for _, arg := range call.Args {
			arg := g.getValue(arg)
3
3dgen 已提交
497
			switch arg.value.Type().(type) {
3
3dgen 已提交
498
			case wir.I32:
3
3dgen 已提交
499
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
500
				insts = append(insts, wat.NewInstCall("$runtime.waPrintI32"))
3
3dgen 已提交
501

3
3dgen 已提交
502
			case wir.F32:
3
3dgen 已提交
503
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
504
				insts = append(insts, wat.NewInstCall("$runtime.waPrintF32"))
3
3dgen 已提交
505 506

			case wir.F64:
3
3dgen 已提交
507
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
508
				insts = append(insts, wat.NewInstCall("$runtime.waPrintF64"))
3
3dgen 已提交
509

3
3dgen 已提交
510
			case wir.RUNE:
3
3dgen 已提交
511
				insts = append(insts, arg.value.EmitPush()...)
3
3dgen 已提交
512
				insts = append(insts, wat.NewInstCall("$runtime.waPrintRune"))
3
3dgen 已提交
513

3
3dgen 已提交
514
			case wir.String:
3
3dgen 已提交
515
				insts = append(insts, wir.EmitPrintString(arg.value)...)
3
3dgen 已提交
516

3
3dgen 已提交
517
			default:
3
3dgen 已提交
518
				logger.Fatalf("Todo: print(%T)", arg.value.Type())
3
3dgen 已提交
519 520 521 522
			}
		}

		if call.Value.Name() == "println" {
3
3dgen 已提交
523
			insts = append(insts, wir.NewConst(strconv.Itoa('\n'), wir.I32{}).EmitPush()...)
3
3dgen 已提交
524
			insts = append(insts, wat.NewInstCall("$runtime.waPrintRune"))
3
3dgen 已提交
525
		}
526 527 528 529 530 531
		ret_type = wir.VOID{}

	case "append":
		if len(call.Args) != 2 {
			panic("len(call.Args) != 2")
		}
3
3dgen 已提交
532
		insts, ret_type = wir.EmitGenAppend(g.getValue(call.Args[0]).value, g.getValue(call.Args[1]).value)
533 534 535 536 537

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

541 542
	default:
		logger.Fatal("Todo:", call.Value)
3
3dgen 已提交
543
	}
544
	return
3
3dgen 已提交
545 546
}

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

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

3
ref WIP  
3dgen 已提交
553
	trueInsts := values[0].EmitPush()
3
3dgen 已提交
554
	var falseInsts []wat.Inst
3
3dgen 已提交
555
	if len(preds) == 2 {
3
ref WIP  
3dgen 已提交
556
		falseInsts = values[1].EmitPush()
3
3dgen 已提交
557
	} else {
3
3dgen 已提交
558
		falseInsts = g.genPhiIter(preds[1:], values[1:])
3
3dgen 已提交
559
	}
3
3dgen 已提交
560
	insts = append(insts, wat.NewInstIf(trueInsts, falseInsts, values[0].Type().Raw()))
3
3dgen 已提交
561 562 563

	return insts
}
3
3dgen 已提交
564
func (g *functionGenerator) genPhi(inst *ssa.Phi) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
565 566 567 568
	var preds []int
	var values []wir.Value
	for i, v := range inst.Edges {
		preds = append(preds, inst.Block().Preds[i].Index)
3
3dgen 已提交
569
		values = append(values, g.getValue(v).value)
3
3dgen 已提交
570 571 572 573
	}
	return g.genPhiIter(preds, values), wir.ToWType(inst.Type())
}

3
3dgen 已提交
574 575
func (g *functionGenerator) genReturn(inst *ssa.Return) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
576

3
3dgen 已提交
577 578 579
	if len(inst.Results) != len(g.var_rets) {
		panic("len(inst.Results) != len(g.var_rets)")
	}
3
3dgen 已提交
580

3
3dgen 已提交
581 582
	for i := range inst.Results {
		insts = append(insts, wir.EmitAssginValue(g.var_rets[i], g.getValue(inst.Results[i]).value)...)
3
3dgen 已提交
583 584
	}

3
3dgen 已提交
585
	insts = append(insts, wat.NewInstBr("$BlockFnBody"))
3
3dgen 已提交
586 587 588
	return insts
}

3
3dgen 已提交
589 590 591 592 593 594 595 596 597 598 599
func (g *functionGenerator) genLoad(Addr ssa.Value) (insts []wat.Inst, ret_type wir.ValueType) {
	addr := g.getValue(Addr)

	if addr.force_register {
		insts = append(insts, addr.value.EmitPush()...)
		ret_type = addr.value.Type()
	} else {
		insts, ret_type = wir.EmitLoad(addr.value)
	}

	return
600 601
}

3
ref WIP  
3dgen 已提交
602
func (g *functionGenerator) genStore(inst *ssa.Store) []wat.Inst {
3
3dgen 已提交
603 604 605 606 607 608 609 610
	addr := g.getValue(inst.Addr)
	val := g.getValue(inst.Val)

	if addr.force_register {
		return wir.EmitAssginValue(addr.value, val.value)
	} else {
		return wir.EmitStore(addr.value, val.value)
	}
3
ref WIP  
3dgen 已提交
611 612
}

3
3dgen 已提交
613
func (g *functionGenerator) genIf(inst *ssa.If) []wat.Inst {
3
3dgen 已提交
614
	cond := g.getValue(inst.Cond)
3
3dgen 已提交
615
	if !cond.value.Type().Equal(wir.I32{}) {
3
3dgen 已提交
616 617 618
		logger.Fatal("cond.type() != i32")
	}

3
3dgen 已提交
619
	insts := cond.value.EmitPush()
3
3dgen 已提交
620 621
	instsTrue := g.genJumpID(inst.Block().Index, inst.Block().Succs[0].Index)
	instsFalse := g.genJumpID(inst.Block().Index, inst.Block().Succs[1].Index)
3
3dgen 已提交
622
	insts = append(insts, wat.NewInstIf(instsTrue, instsFalse, nil))
3
3dgen 已提交
623 624 625 626

	return insts
}

3
3dgen 已提交
627
func (g *functionGenerator) genJump(inst *ssa.Jump) []wat.Inst {
3
3dgen 已提交
628 629 630
	return g.genJumpID(inst.Block().Index, inst.Block().Succs[0].Index)
}

3
3dgen 已提交
631 632
func (g *functionGenerator) genJumpID(cur, dest int) []wat.Inst {
	var insts []wat.Inst
3
3dgen 已提交
633 634

	if cur >= dest {
3
3dgen 已提交
635
		insts = wir.EmitAssginValue(g.var_block_selector, wir.NewConst(strconv.Itoa(dest), wir.I32{}))
3
3dgen 已提交
636
		insts = append(insts, wat.NewInstBr("$BlockDisp"))
3
3dgen 已提交
637
	} else {
3
3dgen 已提交
638
		insts = append(insts, wat.NewInstBr("$Block_"+strconv.Itoa(dest-1)))
3
3dgen 已提交
639 640 641 642 643
	}

	return insts
}

3
3dgen 已提交
644 645 646 647 648 649 650 651
func (g *functionGenerator) genAlloc(inst *ssa.Alloc) (insts []wat.Inst, ret_type wir.ValueType) {
	typ := wir.ToWType(inst.Type().(*types.Pointer).Elem())
	if inst.Parent().ForceRegister() {
		nv := g.addRegister(typ)
		g.locals_map[inst] = valueWrap{value: nv, force_register: true}
		insts = append(insts, nv.EmitRelease()...)
		insts = append(insts, nv.EmitInit()...)
		ret_type = nil
3
Ref WIP  
3dgen 已提交
652
	} else {
3
3dgen 已提交
653 654 655 656 657
		if inst.Heap {
			insts, ret_type = wir.EmitHeapAlloc(typ)
		} else {
			insts, ret_type = wir.EmitStackAlloc(typ)
		}
3
Ref WIP  
3dgen 已提交
658
	}
3
3dgen 已提交
659 660

	return
3
Ref WIP  
3dgen 已提交
661 662
}

3
3dgen 已提交
663 664 665 666 667
func (g *functionGenerator) genExtract(inst *ssa.Extract) ([]wat.Inst, wir.ValueType) {
	v := g.getValue(inst.Tuple)
	return wir.EmitGenExtract(v.value, inst.Index)
}

3
3dgen 已提交
668 669 670
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)
3
3dgen 已提交
671
	fieldname := wir.GenSymbolName(field.Name())
3
3dgen 已提交
672
	if field.Embedded() {
3
3dgen 已提交
673
		if _, ok := field.Type().(*types.Named); ok {
674 675
			pkgname, _ := wir.GetPkgMangleName(field.Pkg().Path())
			fieldname = pkgname + "." + fieldname
3
3dgen 已提交
676
		}
3
3dgen 已提交
677 678 679
		fieldname = "$" + fieldname
	}

3
3dgen 已提交
680
	return wir.EmitGenField(x.value, fieldname)
3
3dgen 已提交
681 682
}

3
3dgen 已提交
683 684
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)
3
3dgen 已提交
685
	fieldname := wir.GenSymbolName(field.Name())
3
3dgen 已提交
686
	if field.Embedded() {
3
3dgen 已提交
687
		if _, ok := field.Type().(*types.Named); ok {
688 689
			pkgname, _ := wir.GetPkgMangleName(field.Pkg().Path())
			fieldname = pkgname + "." + fieldname
3
3dgen 已提交
690
		}
3
3dgen 已提交
691 692 693
		fieldname = "$" + fieldname
	}

3
3dgen 已提交
694 695 696 697 698 699 700 701
	x := g.getValue(inst.X)
	if x.force_register {
		nv := wir.ExtractField(x.value, fieldname)
		g.locals_map[inst] = valueWrap{value: nv, force_register: true}
		return nil, nil
	} else {
		return wir.EmitGenFieldAddr(x.value, fieldname)
	}
3
3dgen 已提交
702 703
}

3
3dgen 已提交
704
func (g *functionGenerator) genIndexAddr(inst *ssa.IndexAddr) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
705 706 707 708 709
	if inst.Parent().ForceRegister() {
		logger.Fatal("ssa.IndexAddr is not available in ForceRegister-mode")
		return nil, nil
	}

3
3dgen 已提交
710 711 712
	x := g.getValue(inst.X)
	id := g.getValue(inst.Index)

3
3dgen 已提交
713
	return wir.EmitGenIndexAddr(x.value, id.value)
3
3dgen 已提交
714 715
}

716
func (g *functionGenerator) genSlice(inst *ssa.Slice) ([]wat.Inst, wir.ValueType) {
3
3dgen 已提交
717 718 719 720 721
	if inst.Parent().ForceRegister() {
		logger.Fatal("ssa.Slice is not available in ForceRegister-mode")
		return nil, nil
	}

722 723 724
	x := g.getValue(inst.X)
	var low, high wir.Value
	if inst.Low != nil {
3
3dgen 已提交
725
		low = g.getValue(inst.Low).value
726 727
	}
	if inst.High != nil {
3
3dgen 已提交
728
		high = g.getValue(inst.High).value
729 730
	}

3
3dgen 已提交
731
	return wir.EmitGenSlice(x.value, low, high)
732 733
}

3
3dgen 已提交
734 735 736 737 738 739 740 741 742 743 744 745 746 747
func (g *functionGenerator) genLookup(inst *ssa.Lookup) ([]wat.Inst, wir.ValueType) {
	x := g.getValue(inst.X)
	index := g.getValue(inst.Index)

	return wir.EmitGenLookup(x.value, index.value, inst.CommaOk)
}

func (g *functionGenerator) genConvert(inst *ssa.Convert) (insts []wat.Inst, ret_type wir.ValueType) {
	x := g.getValue(inst.X)
	ret_type = wir.ToWType(inst.Type())
	insts = wir.EmitGenConvert(x.value, ret_type)
	return
}

3
3dgen 已提交
748 749 750 751 752 753 754
func (g *functionGenerator) genChangeType(inst *ssa.ChangeType) (insts []wat.Inst, ret_type wir.ValueType) {
	ret_type = wir.ToWType(inst.Type())
	x := g.getValue(inst.X)
	insts = append(insts, x.value.EmitPush()...)
	return
}

3
3dgen 已提交
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
func (g *functionGenerator) genMakeClosre(inst *ssa.MakeClosure) (insts []wat.Inst, ret_type wir.ValueType) {
	f := inst.Fn.(*ssa.Function)

	if f.Parent() != nil {
		return g.genMakeClosre_Anonymous(inst)
	}

	if len(f.FreeVars) == 1 && strings.HasSuffix(f.Name(), "$bound") {
		return g.genMakeClosre_Bound(inst)
	}

	panic("todo")
}

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.module).genFunction(f))

	ret_type = wir.NewClosure(wir.NewFnSigFromSignature(f.Signature))
	if !ret_type.Equal(wir.ToWType(inst.Type())) {
		panic("ret_type != inst.Type()")
	}

	var st_free_data wir.Struct
	{
		var fields []wir.Field
		for _, freevar := range f.FreeVars {
			feild := wir.NewField(freevar.Name(), wir.ToWType(freevar.Type()))
			fields = append(fields, feild)
		}
786 787
		fn_internal_name, _ := GetFnMangleName(f)
		st_name := fn_internal_name + ".$warpdata"
3
3dgen 已提交
788 789 790 791 792 793
		st_free_data = wir.NewStruct(st_name, fields)
	}

	var warp_fn_index int
	{
		var warp_fn wir.Function
794 795
		fn_name, _ := GetFnMangleName(f)
		warp_fn.InternalName = fn_name + ".$warpfn"
3
3dgen 已提交
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
		for _, i := range f.Params {
			pa := valueWrap{value: wir.NewLocal(i.Name(), wir.ToWType(i.Type()))}
			warp_fn.Params = append(warp_fn.Params, pa.value)
		}
		warp_fn.Results = wir.NewFnSigFromSignature(f.Signature).Results

		dx := g.module.FindGlobal("$wa.RT.closure_data")
		data_ptr := wir.ExtractField(dx, "data")

		warp_fn.Insts = append(warp_fn.Insts, st_free_data.EmitLoadFromAddr(data_ptr, 0)...)
		warp_fn.Insts = append(warp_fn.Insts, dx.EmitRelease()...)
		warp_fn.Insts = append(warp_fn.Insts, dx.EmitInit()...)

		for _, i := range warp_fn.Params {
			warp_fn.Insts = append(warp_fn.Insts, i.EmitPush()...)
		}

813
		warp_fn.Insts = append(warp_fn.Insts, wat.NewInstCall(fn_name))
3
3dgen 已提交
814 815

		g.module.AddFunc(&warp_fn)
816
		warp_fn_index = g.module.AddTableElem(warp_fn.InternalName)
3
3dgen 已提交
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
	}

	closure := g.addRegister(wir.NewClosure(wir.NewFnSigFromSignature(f.Signature)))

	free_data := g.addRegister(st_free_data)
	{
		for i, freevar := range f.FreeVars {
			sv := g.getValue(inst.Bindings[i])
			insts = append(insts, sv.value.EmitPush()...)
			dv := wir.ExtractField(free_data, freevar.Name())
			insts = append(insts, dv.EmitPop()...)
		}
	}
	insts = append(insts, wir.NewConst(strconv.Itoa(warp_fn_index), wir.U32{}).EmitPush()...)
	insts = append(insts, wir.ExtractField(closure, "fn_index").EmitPop()...)
	{
		i, _ := wir.EmitHeapAlloc(st_free_data)
		insts = append(insts, i...)
		insts = append(insts, wir.ExtractField(closure, "data").EmitPop()...)
	}
	insts = append(insts, wir.EmitStore(wir.ExtractField(closure, "data"), free_data)...)
	insts = append(insts, free_data.EmitRelease()...)
	insts = append(insts, free_data.EmitInit()...)

	insts = append(insts, closure.EmitPush()...)
	return
}

func (g *functionGenerator) genMakeClosre_Bound(inst *ssa.MakeClosure) (insts []wat.Inst, ret_type wir.ValueType) {
	f := inst.Fn.(*ssa.Function)

	ret_type = wir.NewClosure(wir.NewFnSigFromSignature(f.Signature))
	if !ret_type.Equal(wir.ToWType(inst.Type())) {
		panic("ret_type != inst.Type()")
	}

	recv_type := wir.ToWType(f.FreeVars[0].Type())

	var warp_fn_index int
	{
		var warp_fn wir.Function
858 859
		fn_name, _ := GetFnMangleName(f.Object())
		warp_fn.InternalName = fn_name + ".$bound"
3
3dgen 已提交
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
		for _, i := range f.Params {
			pa := valueWrap{value: wir.NewLocal(i.Name(), wir.ToWType(i.Type()))}
			warp_fn.Params = append(warp_fn.Params, pa.value)
		}
		warp_fn.Results = wir.NewFnSigFromSignature(f.Signature).Results

		dx := g.module.FindGlobal("$wa.RT.closure_data")
		data_ptr := wir.ExtractField(dx, "data")

		warp_fn.Insts = append(warp_fn.Insts, recv_type.EmitLoadFromAddr(data_ptr, 0)...)
		warp_fn.Insts = append(warp_fn.Insts, dx.EmitRelease()...)
		warp_fn.Insts = append(warp_fn.Insts, dx.EmitInit()...)

		for _, i := range warp_fn.Params {
			warp_fn.Insts = append(warp_fn.Insts, i.EmitPush()...)
		}

877
		warp_fn.Insts = append(warp_fn.Insts, wat.NewInstCall(fn_name))
3
3dgen 已提交
878 879

		g.module.AddFunc(&warp_fn)
880
		warp_fn_index = g.module.AddTableElem(warp_fn.InternalName)
3
3dgen 已提交
881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
	}

	closure := g.addRegister(wir.NewClosure(wir.NewFnSigFromSignature(f.Signature)))

	insts = append(insts, wir.NewConst(strconv.Itoa(warp_fn_index), wir.U32{}).EmitPush()...)
	insts = append(insts, wir.ExtractField(closure, "fn_index").EmitPop()...)
	{
		i, _ := wir.EmitHeapAlloc(recv_type)
		insts = append(insts, i...)
		insts = append(insts, wir.ExtractField(closure, "data").EmitPop()...)
	}

	recv := g.getValue(inst.Bindings[0])
	insts = append(insts, wir.EmitStore(wir.ExtractField(closure, "data"), recv.value)...)

	insts = append(insts, closure.EmitPush()...)
	return
}

3
3dgen 已提交
900
func (g *functionGenerator) addRegister(typ wir.ValueType) wir.Value {
3
3dgen 已提交
901
	defer func() { g.cur_local_id++ }()
3
3dgen 已提交
902
	name := "$T_" + strconv.Itoa(g.cur_local_id)
3
3dgen 已提交
903
	v := wir.NewLocal(name, typ)
3
3dgen 已提交
904 905 906
	g.registers = append(g.registers, v)
	return v
}
3
3dgen 已提交
907 908 909 910

func (g *functionGenerator) genGetter(f *ssa.Function) *wir.Function {
	var wir_fn wir.Function
	if len(f.LinkName()) > 0 {
911 912
		wir_fn.InternalName = f.LinkName()
		wir_fn.ExternalName = f.LinkName()
3
3dgen 已提交
913
	} else {
914
		wir_fn.InternalName, wir_fn.ExternalName = GetFnMangleName(f)
3
3dgen 已提交
915 916 917 918 919 920 921
	}

	rets := f.Signature.Results()
	if rets.Len() > 1 {
		logger.Fatal("rets.Len() > 1")
		return nil
	}
3
3dgen 已提交
922 923
	rtype := wir.ToWType(rets)
	wir_fn.Results = append(wir_fn.Results, rtype)
3
3dgen 已提交
924 925 926 927 928 929 930 931 932

	if len(f.Params) != 1 {
		logger.Fatal("len(f.Params) != 1")
		return nil
	}
	if !wir.ToWType(f.Params[0].Type()).Equal(wir.U32{}) {
		logger.Fatal("addr_type != U32")
		return nil
	}
3
3dgen 已提交
933
	addr := wir.NewLocal("addr", wir.NewPointer(rtype))
3
3dgen 已提交
934 935 936 937 938 939 940 941 942 943 944
	wir_fn.Params = append(wir_fn.Params, addr)

	insts, _ := wir.EmitLoad(addr)
	wir_fn.Insts = append(wir_fn.Insts, insts...)

	return &wir_fn
}

func (g *functionGenerator) genSetter(f *ssa.Function) *wir.Function {
	var wir_fn wir.Function
	if len(f.LinkName()) > 0 {
945 946
		wir_fn.InternalName = f.LinkName()
		wir_fn.ExternalName = f.LinkName()
3
3dgen 已提交
947
	} else {
948
		wir_fn.InternalName, wir_fn.ExternalName = GetFnMangleName(f)
3
3dgen 已提交
949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
	}

	rets := f.Signature.Results()
	if rets.Len() > 0 {
		logger.Fatal("rets.Len() > 0")
		return nil
	}

	if len(f.Params) != 2 {
		logger.Fatal("len(f.Params) != 2")
		return nil
	}
	if !wir.ToWType(f.Params[0].Type()).Equal(wir.U32{}) {
		logger.Fatal("addr_type != U32")
		return nil
	}

	value_type := wir.ToWType(f.Params[1].Type())

	addr := wir.NewLocal("addr", wir.NewPointer(value_type))
	wir_fn.Params = append(wir_fn.Params, addr)

	value := wir.NewLocal("data", value_type)
	wir_fn.Params = append(wir_fn.Params, value)

	insts := wir.EmitStore(addr, value)
	wir_fn.Insts = append(wir_fn.Insts, insts...)

	return &wir_fn
}