ssa_types.mx raw
1 package main
2
3 import "go/token"
4
5 // SSA operator codes (replacing go/token.Token for BinOp/UnOp).
6 type SSAOp int32
7
8 const (
9 OpIllegal SSAOp = iota
10 OpAdd
11 OpSub
12 OpMul
13 OpQuo
14 OpRem
15 OpAnd
16 OpXor
17 OpShl
18 OpShr
19 OpOr
20 OpAndNot
21 OpLand
22 OpLor
23 OpArrow
24 OpNot
25 OpEql
26 OpNeq
27 OpLss
28 OpLeq
29 OpGtr
30 OpGeq
31 )
32
33 func (op SSAOp) String() string {
34 switch op {
35 case OpAdd:
36 return "+"
37 case OpSub:
38 return "-"
39 case OpMul:
40 return "*"
41 case OpQuo:
42 return "/"
43 case OpRem:
44 return "%"
45 case OpAnd:
46 return "&"
47 case OpXor:
48 return "^"
49 case OpOr:
50 return "|"
51 case OpShl:
52 return "<<"
53 case OpShr:
54 return ">>"
55 case OpAndNot:
56 return "&^"
57 case OpLand:
58 return "&&"
59 case OpLor:
60 return "||"
61 case OpArrow:
62 return "<-"
63 case OpNot:
64 return "!"
65 case OpEql:
66 return "=="
67 case OpNeq:
68 return "!="
69 case OpLss:
70 return "<"
71 case OpLeq:
72 return "<="
73 case OpGtr:
74 return ">"
75 case OpGeq:
76 return ">="
77 }
78 return "?"
79 }
80
81 // ssaConstString returns a string representation of a constant value.
82 func ssaConstString(val ConstVal) string {
83 if val == nil {
84 return "nil"
85 }
86 return val.String()
87 }
88
89 // SSA Value interface.
90 type SSAValue interface {
91 SSAName() string
92 String() string
93 SSAType() Type
94 SSAParent() *SSAFunction
95 SSAPos() int32
96 }
97
98 // SSA Instruction interface.
99 type SSAInstruction interface {
100 InstrBlock() *SSABasicBlock
101 InstrParent() *SSAFunction
102 InstrPos() int32
103 InstrString() string
104 setBlock(*SSABasicBlock)
105 }
106
107 // SSA Member interface (package-level declaration).
108 type SSAMember interface {
109 MemberName() string
110 MemberString() string
111 MemberType() Type
112 MemberPkg() *SSAPackage
113 }
114
115 // SSA Program - top-level container.
116 type SSAProgram struct {
117 imported map[string]*SSAPackage
118 packages map[*TCPackage]*SSAPackage
119 }
120
121 func NewSSAProgram() *SSAProgram {
122 return &SSAProgram{
123 imported: map[string]*SSAPackage{},
124 packages: map[*TCPackage]*SSAPackage{},
125 }
126 }
127
128 func (prog *SSAProgram) ImportedPackage(path string) *SSAPackage {
129 return prog.imported[path]
130 }
131
132 // SSA Package.
133 type SSAPackage struct {
134 Prog *SSAProgram
135 Pkg *TCPackage
136 Members map[string]SSAMember
137 }
138
139 func (p *SSAPackage) Func(name string) *SSAFunction {
140 m := p.Members[name]
141 if m == nil {
142 return nil
143 }
144 fn, _ := m.(*SSAFunction)
145 return fn
146 }
147
148 // SSA Function.
149 type SSAFunction struct {
150 name string
151 object *TCFunc
152 Signature *Signature
153 pos int32
154 Synthetic string
155
156 Pkg *SSAPackage
157 Prog *SSAProgram
158
159 Params []*SSAParameter
160 FreeVars []*SSAFreeVar
161 Locals []*SSAAlloc
162 Blocks []*SSABasicBlock
163 AnonFuncs []*SSAFunction
164
165 parent *SSAFunction
166 vars map[Object]SSAValue
167 }
168
169 func (f *SSAFunction) MemberName() string { return f.name }
170 func (f *SSAFunction) MemberString() string { return f.name }
171 func (f *SSAFunction) MemberType() Type {
172 if f.Signature == nil {
173 return nil
174 }
175 return f.Signature
176 }
177 func (f *SSAFunction) MemberPkg() *SSAPackage { return f.Pkg }
178 func (f *SSAFunction) SSAName() string { return f.name }
179 func (f *SSAFunction) String() string { return f.name }
180 func (f *SSAFunction) SSAType() Type { return f.MemberType() }
181 func (f *SSAFunction) SSAParent() *SSAFunction { return f.parent }
182 func (f *SSAFunction) SSAPos() int32 { return f.pos }
183
184 // SSA BasicBlock.
185 type SSABasicBlock struct {
186 Index int
187 Comment string
188 parent *SSAFunction
189 Instrs []SSAInstruction
190 Preds []*SSABasicBlock
191 Succs []*SSABasicBlock
192 }
193
194 func (b *SSABasicBlock) Parent() *SSAFunction { return b.parent }
195
196 func NewSSABasicBlock(parent *SSAFunction, comment string) *SSABasicBlock {
197 b := &SSABasicBlock{
198 Index: len(parent.Blocks),
199 Comment: comment,
200 parent: parent,
201 }
202 parent.Blocks = append(parent.Blocks, b)
203 return b
204 }
205
206 // ssaRegister - shared base for instructions that produce a value.
207 type ssaRegister struct {
208 ssaInstr
209 name string
210 typ Type
211 pos int32
212 }
213
214 func (r *ssaRegister) SSAName() string { return r.name }
215 func (r *ssaRegister) SSAType() Type { return r.typ }
216 func (r *ssaRegister) SSAPos() int32 { return r.pos }
217 func (r *ssaRegister) SSAParent() *SSAFunction { return r.block.parent }
218 func (r *ssaRegister) String() string { return r.name }
219
220 // ssaInstr - base for all instructions.
221 type ssaInstr struct {
222 block *SSABasicBlock
223 }
224
225 func (a *ssaInstr) InstrBlock() *SSABasicBlock { return a.block }
226 func (a *ssaInstr) InstrParent() *SSAFunction { return a.block.parent }
227 func (a *ssaInstr) setBlock(b *SSABasicBlock) { a.block = b }
228
229 // Package-level global variable.
230 type SSAGlobal struct {
231 name string
232 object *TCVar
233 typ Type
234 pos int32
235 pkg *SSAPackage
236 }
237
238 func (g *SSAGlobal) MemberName() string { return g.name }
239 func (g *SSAGlobal) MemberString() string { return g.pkg.Pkg.Path() | "." | g.name }
240 func (g *SSAGlobal) MemberType() Type { return g.typ }
241 func (g *SSAGlobal) MemberPkg() *SSAPackage { return g.pkg }
242 func (g *SSAGlobal) SSAName() string { return g.name }
243 func (g *SSAGlobal) String() string { return g.MemberString() }
244 func (g *SSAGlobal) SSAType() Type { return g.typ }
245 func (g *SSAGlobal) SSAParent() *SSAFunction { return nil }
246 func (g *SSAGlobal) SSAPos() int32 { return g.pos }
247
248 // Package-level named type.
249 type SSAType_ struct {
250 object *TypeName
251 pkg *SSAPackage
252 }
253
254 func (t *SSAType_) MemberName() string { return t.object.Name() }
255 func (t *SSAType_) MemberString() string { return t.pkg.Pkg.Path() | "." | t.object.Name() }
256 func (t *SSAType_) MemberType() Type { return t.object.Type() }
257 func (t *SSAType_) MemberPkg() *SSAPackage { return t.pkg }
258
259 // Package-level named constant.
260 type SSANamedConst struct {
261 object *TCConst
262 Value *SSAConst
263 pkg *SSAPackage
264 }
265
266 func (c *SSANamedConst) MemberName() string { return c.object.Name() }
267 func (c *SSANamedConst) MemberString() string { return c.pkg.Pkg.Path() | "." | c.object.Name() }
268 func (c *SSANamedConst) MemberType() Type { return c.object.Type() }
269 func (c *SSANamedConst) MemberPkg() *SSAPackage { return c.pkg }
270
271 // Parameter.
272 type SSAParameter struct {
273 name string
274 object *TCVar
275 typ Type
276 pos int32
277 parent *SSAFunction
278 }
279
280 func (p *SSAParameter) SSAName() string { return p.name }
281 func (p *SSAParameter) String() string { return p.name }
282 func (p *SSAParameter) SSAType() Type { return p.typ }
283 func (p *SSAParameter) SSAParent() *SSAFunction { return p.parent }
284 func (p *SSAParameter) SSAPos() int32 { return p.pos }
285
286 // FreeVar (closure capture).
287 type SSAFreeVar struct {
288 name string
289 typ Type
290 pos int32
291 parent *SSAFunction
292 }
293
294 func (v *SSAFreeVar) SSAName() string { return v.name }
295 func (v *SSAFreeVar) String() string { return v.name }
296 func (v *SSAFreeVar) SSAType() Type { return v.typ }
297 func (v *SSAFreeVar) SSAParent() *SSAFunction { return v.parent }
298 func (v *SSAFreeVar) SSAPos() int32 { return v.pos }
299
300 // Const value.
301 type SSAConst struct {
302 typ Type
303 val ConstVal
304 }
305
306 func NewSSAConst(val ConstVal, typ Type) *SSAConst {
307 return &SSAConst{typ: typ, val: val}
308 }
309
310 func (c *SSAConst) SSAName() string { return ssaConstString(c.val) }
311 func (c *SSAConst) String() string { return ssaConstString(c.val) }
312 func (c *SSAConst) SSAType() Type { return c.typ }
313 func (c *SSAConst) SSAParent() *SSAFunction { return nil }
314 func (c *SSAConst) SSAPos() int32 { return 0 }
315 func (c *SSAConst) Value() ConstVal { return c.val }
316
317 type SSABuiltin struct {
318 id BuiltinID
319 name string
320 }
321
322 func (b *SSABuiltin) SSAName() string { return b.name }
323 func (b *SSABuiltin) String() string { return b.name }
324 func (b *SSABuiltin) SSAType() Type { return nil }
325 func (b *SSABuiltin) SSAParent() *SSAFunction { return nil }
326 func (b *SSABuiltin) SSAPos() int32 { return 0 }
327
328 // CallCommon describes a function/method call.
329 type SSACallCommon struct {
330 Value SSAValue
331 Args []SSAValue
332 pos int32
333 }
334
335 // -- Instruction types --
336
337 // Alloc allocates space for a variable.
338 type SSAAlloc struct {
339 ssaRegister
340 Heap bool
341 Comment string
342 }
343
344 func (a *SSAAlloc) InstrPos() int32 { return a.pos }
345 func (a *SSAAlloc) InstrString() string {
346 if a.Heap {
347 return "new " | a.typ.String()
348 }
349 return "local " | a.typ.String()
350 }
351
352 // Phi node.
353 type SSAPhi struct {
354 ssaRegister
355 Comment string
356 Edges []SSAValue
357 }
358
359 func (p *SSAPhi) InstrPos() int32 { return p.pos }
360 func (p *SSAPhi) InstrString() string { return "phi " | p.Comment }
361
362 // Call instruction.
363 type SSACall struct {
364 ssaRegister
365 Call SSACallCommon
366 }
367
368 func (c *SSACall) InstrPos() int32 { return c.Call.pos }
369 func (c *SSACall) InstrString() string { return "call " | c.Call.Value.SSAName() }
370
371 // BinOp.
372 type SSABinOp struct {
373 ssaRegister
374 Op SSAOp
375 X SSAValue
376 Y SSAValue
377 }
378
379 func (b *SSABinOp) InstrPos() int32 { return b.pos }
380 func (b *SSABinOp) InstrString() string { return "binop " | b.Op.String() }
381
382 // UnOp.
383 type SSAUnOp struct {
384 ssaRegister
385 Op SSAOp
386 X SSAValue
387 CommaOk bool
388 }
389
390 func (u *SSAUnOp) InstrPos() int32 { return u.pos }
391 func (u *SSAUnOp) InstrString() string { return "unop " | u.Op.String() }
392
393 // ChangeType.
394 type SSAChangeType struct {
395 ssaRegister
396 X SSAValue
397 }
398
399 func (c *SSAChangeType) InstrPos() int32 { return c.pos }
400 func (c *SSAChangeType) InstrString() string { return "changetype" }
401
402 // Convert.
403 type SSAConvert struct {
404 ssaRegister
405 X SSAValue
406 }
407
408 func (c *SSAConvert) InstrPos() int32 { return c.pos }
409 func (c *SSAConvert) InstrString() string { return "convert" }
410
411 // MakeInterface.
412 type SSAMakeInterface struct {
413 ssaRegister
414 X SSAValue
415 IType Type
416 }
417
418 func (m *SSAMakeInterface) InstrPos() int32 { return m.pos }
419 func (m *SSAMakeInterface) InstrString() string { return "makeinterface" }
420
421 // Invoke - interface method call.
422 type SSAInvoke struct {
423 ssaRegister
424 X SSAValue
425 MethodName string
426 IfaceType *TCInterface
427 Args []SSAValue
428 }
429
430 func (inv *SSAInvoke) InstrPos() int32 { return inv.pos }
431 func (inv *SSAInvoke) InstrString() string { return "invoke " | inv.MethodName }
432
433 // MakeClosure.
434 type SSAMakeClosure struct {
435 ssaRegister
436 Fn SSAValue
437 Bindings []SSAValue
438 }
439
440 func (m *SSAMakeClosure) InstrPos() int32 { return m.pos }
441 func (m *SSAMakeClosure) InstrString() string { return "makeclosure" }
442
443 // MakeMap.
444 type SSAMakeMap struct {
445 ssaRegister
446 Reserve SSAValue
447 }
448
449 func (m *SSAMakeMap) InstrPos() int32 { return m.pos }
450 func (m *SSAMakeMap) InstrString() string { return "makemap" }
451
452 // MakeChan.
453 type SSAMakeChan struct {
454 ssaRegister
455 Size SSAValue
456 }
457
458 func (m *SSAMakeChan) InstrPos() int32 { return m.pos }
459 func (m *SSAMakeChan) InstrString() string { return "makechan" }
460
461 // MakeSlice.
462 type SSAMakeSlice struct {
463 ssaRegister
464 Len SSAValue
465 Cap SSAValue
466 Data SSAValue
467 }
468
469 func (m *SSAMakeSlice) InstrPos() int32 { return m.pos }
470 func (m *SSAMakeSlice) InstrString() string { return "makeslice" }
471
472 // Slice.
473 type SSASlice struct {
474 ssaRegister
475 X SSAValue
476 Low SSAValue
477 High SSAValue
478 Max SSAValue
479 }
480
481 func (s *SSASlice) InstrPos() int32 { return s.pos }
482 func (s *SSASlice) InstrString() string { return "slice" }
483
484 // FieldAddr.
485 type SSAFieldAddr struct {
486 ssaRegister
487 X SSAValue
488 Field int
489 }
490
491 func (f *SSAFieldAddr) InstrPos() int32 { return f.pos }
492 func (f *SSAFieldAddr) InstrString() string { return "fieldaddr" }
493
494 // IndexAddr.
495 type SSAIndexAddr struct {
496 ssaRegister
497 X SSAValue
498 Index SSAValue
499 }
500
501 func (i *SSAIndexAddr) InstrPos() int32 { return i.pos }
502 func (i *SSAIndexAddr) InstrString() string { return "indexaddr" }
503
504 // Lookup (map[k]).
505 type SSALookup struct {
506 ssaRegister
507 X SSAValue
508 Index SSAValue
509 CommaOk bool
510 }
511
512 func (l *SSALookup) InstrPos() int32 { return l.pos }
513 func (l *SSALookup) InstrString() string { return "lookup" }
514
515 // Range.
516 type SSARange struct {
517 ssaRegister
518 X SSAValue
519 }
520
521 func (r *SSARange) InstrPos() int32 { return r.pos }
522 func (r *SSARange) InstrString() string { return "range" }
523
524 // Next (iterator advance).
525 type SSANext struct {
526 ssaRegister
527 Iter SSAValue
528 IsString bool
529 }
530
531 func (n *SSANext) InstrPos() int32 { return n.pos }
532 func (n *SSANext) InstrString() string { return "next" }
533
534 // TypeAssert.
535 type SSATypeAssert struct {
536 ssaRegister
537 X SSAValue
538 AssertedType Type
539 CommaOk bool
540 }
541
542 func (t *SSATypeAssert) InstrPos() int32 { return t.pos }
543 func (t *SSATypeAssert) InstrString() string { return "typeassert" }
544
545 // Extract (tuple component).
546 type SSAExtract struct {
547 ssaRegister
548 Tuple SSAValue
549 Index int
550 }
551
552 func (e *SSAExtract) InstrPos() int32 { return e.pos }
553 func (e *SSAExtract) InstrString() string { return "extract" }
554
555 // -- Terminator instructions --
556
557 // Jump.
558 type SSAJump struct {
559 ssaInstr
560 Comment string
561 }
562
563 func (j *SSAJump) InstrPos() int32 { return 0 }
564 func (j *SSAJump) InstrString() string { return "jump " | j.Comment }
565
566 // If.
567 type SSAIf struct {
568 ssaInstr
569 Cond SSAValue
570 }
571
572 func (i *SSAIf) InstrPos() int32 { return 0 }
573 func (i *SSAIf) InstrString() string { return "if" }
574
575 // Return.
576 type SSAReturn struct {
577 ssaInstr
578 Results []SSAValue
579 pos int32
580 }
581
582 func (r *SSAReturn) InstrPos() int32 { return r.pos }
583 func (r *SSAReturn) InstrString() string { return "return" }
584
585 // RunDefers.
586 type SSARunDefers struct {
587 ssaInstr
588 }
589
590 func (rd *SSARunDefers) InstrPos() int32 { return 0 }
591 func (rd *SSARunDefers) InstrString() string { return "rundefers" }
592
593 // Panic.
594 type SSAPanic struct {
595 ssaInstr
596 X SSAValue
597 pos int32
598 }
599
600 func (p *SSAPanic) InstrPos() int32 { return p.pos }
601 func (p *SSAPanic) InstrString() string { return "panic" }
602
603 // Go (spawn).
604 type SSAGo struct {
605 ssaInstr
606 Call SSACallCommon
607 pos int32
608 }
609
610 func (g *SSAGo) InstrPos() int32 { return g.pos }
611 func (g *SSAGo) InstrString() string { return "go" }
612
613 // Defer.
614 type SSADefer struct {
615 ssaInstr
616 Call SSACallCommon
617 pos int32
618 }
619
620 func (d *SSADefer) InstrPos() int32 { return d.pos }
621 func (d *SSADefer) InstrString() string { return "defer" }
622
623 // -- Side-effecting instructions --
624
625 // Send.
626 type SSASend struct {
627 ssaInstr
628 Chan SSAValue
629 X SSAValue
630 pos int32
631 }
632
633 func (s *SSASend) InstrPos() int32 { return s.pos }
634 func (s *SSASend) InstrString() string { return "send" }
635
636 // Store.
637 type SSAStore struct {
638 ssaInstr
639 Addr SSAValue
640 Val SSAValue
641 pos int32
642 }
643
644 func (s *SSAStore) InstrPos() int32 { return s.pos }
645 func (s *SSAStore) InstrString() string { return "store" }
646
647 // MapUpdate.
648 type SSAMapUpdate struct {
649 ssaInstr
650 Map SSAValue
651 Key SSAValue
652 Value SSAValue
653 pos int32
654 }
655
656 func (m *SSAMapUpdate) InstrPos() int32 { return m.pos }
657 func (m *SSAMapUpdate) InstrString() string { return "mapupdate" }
658
659 // SelectState describes one case of a select statement.
660 type SSASelectState struct {
661 Dir token.Token // token.ARROW for send, token.DEFAULT for recv
662 Chan SSAValue
663 Send SSAValue
664 }
665
666 // Select instruction.
667 type SSASelect struct {
668 ssaRegister
669 States []*SSASelectState
670 Blocking bool
671 }
672
673 func (s *SSASelect) InstrPos() int32 { return s.pos }
674 func (s *SSASelect) InstrString() string { return "select" }
675
676 // Operator mapping from syntax.Operator to SSAOp.
677 func syntaxOpToSSAOp(op Operator, unary bool) SSAOp {
678 if unary {
679 switch op {
680 case Not:
681 return OpNot
682 case Recv:
683 return OpArrow
684 case And:
685 return OpAnd
686 case Mul:
687 return OpMul
688 case Sub:
689 return OpSub
690 case Xor:
691 return OpXor
692 }
693 }
694 switch op {
695 case Add:
696 return OpAdd
697 case Or:
698 return OpOr
699 case Sub:
700 return OpSub
701 case Mul:
702 return OpMul
703 case Div:
704 return OpQuo
705 case Rem:
706 return OpRem
707 case And:
708 return OpAnd
709 case Xor:
710 return OpXor
711 case Shl:
712 return OpShl
713 case Shr:
714 return OpShr
715 case AndNot:
716 return OpAndNot
717 case OrOr:
718 return OpLor
719 case AndAnd:
720 return OpLand
721 case Eql:
722 return OpEql
723 case Neq:
724 return OpNeq
725 case Lss:
726 return OpLss
727 case Leq:
728 return OpLeq
729 case Gtr:
730 return OpGtr
731 case Geq:
732 return OpGeq
733 }
734 return OpIllegal
735 }
736
737 func compoundOp(op Operator) SSAOp {
738 switch op {
739 case Add:
740 return OpAdd
741 case Or:
742 return OpOr
743 case Sub:
744 return OpSub
745 case Mul:
746 return OpMul
747 case Div:
748 return OpQuo
749 case Rem:
750 return OpRem
751 case And:
752 return OpAnd
753 case Xor:
754 return OpXor
755 case Shl:
756 return OpShl
757 case Shr:
758 return OpShr
759 case AndNot:
760 return OpAndNot
761 }
762 return OpIllegal
763 }
764
765 func ssaBuiltinID(name string) (BuiltinID, bool) {
766 switch name {
767 case "append":
768 return BuiltinAppend, true
769 case "cap":
770 return BuiltinCap, true
771 case "clear":
772 return BuiltinClear, true
773 case "close":
774 return BuiltinClose, true
775 case "copy":
776 return BuiltinCopy, true
777 case "delete":
778 return BuiltinDelete, true
779 case "len":
780 return BuiltinLen, true
781 case "make":
782 return BuiltinMake, true
783 case "max":
784 return BuiltinMax, true
785 case "min":
786 return BuiltinMin, true
787 case "new":
788 return BuiltinNew, true
789 case "panic":
790 return BuiltinPanic, true
791 case "print":
792 return BuiltinPrint, true
793 case "println":
794 return BuiltinPrintln, true
795 case "recover":
796 return BuiltinRecover, true
797 }
798 return 0, false
799 }
800
801 func ssaItoa(n int) string {
802 if n == 0 {
803 return "0"
804 }
805 neg := n < 0
806 if neg {
807 n = -n
808 }
809 buf := []byte{:0:20}
810 for n > 0 {
811 buf = append(buf, byte('0'+n%10))
812 n /= 10
813 }
814 if neg {
815 buf = append(buf, '-')
816 }
817 for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
818 buf[i], buf[j] = buf[j], buf[i]
819 }
820 return string(buf)
821 }
822
823 // Type helpers for SSA builder.
824 func ssaElemType(t Type) Type {
825 if t == nil {
826 return nil
827 }
828 switch t := safeUnderlying(t).(type) {
829 case *Slice:
830 return t.Elem()
831 case *Array:
832 return t.Elem()
833 case *TCMap:
834 return t.Elem()
835 case *Pointer:
836 return t.Elem()
837 case *Basic:
838 if t.Info()&IsString != 0 {
839 return Typ[Uint8]
840 }
841 }
842 return nil
843 }
844
845 func ssaChanElemType(t Type) Type {
846 if t == nil {
847 return nil
848 }
849 if ch, ok := safeUnderlying(t).(*TCChan); ok {
850 return ch.Elem()
851 }
852 return nil
853 }
854
855 func ssaIsStringType(t Type) bool {
856 if t == nil {
857 return false
858 }
859 if b, ok := safeUnderlying(t).(*Basic); ok {
860 return b.Info()&IsString != 0
861 }
862 return false
863 }
864
865 func ssaSliceOf(t Type) Type {
866 if t == nil {
867 return nil
868 }
869 if b, ok := safeUnderlying(t).(*Basic); ok && b.Info()&IsString != 0 {
870 return t
871 }
872 switch t := safeUnderlying(t).(type) {
873 case *Slice:
874 return t
875 case *Array:
876 if b, ok := t.Elem().(*Basic); ok && b.kind == Uint8 {
877 return Typ[TCString]
878 }
879 return NewSlice(t.Elem())
880 }
881 return Typ[TCString]
882 }
883
884 func ssaTupleElemType(t Type, i int) Type {
885 if t == nil {
886 return nil
887 }
888 if tup, ok := t.(*Tuple); ok && i < tup.Len() {
889 return tup.At(i).Type()
890 }
891 return nil
892 }
893
894 func ssaParseInt64(s string) int64 {
895 var n int64
896 for i := 0; i < len(s); i++ {
897 c := s[i]
898 if c < '0' || c > '9' {
899 break
900 }
901 n = n*10 + int64(c-'0')
902 }
903 return n
904 }
905