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 }
467
468 func (m *SSAMakeSlice) InstrPos() int32 { return m.pos }
469 func (m *SSAMakeSlice) InstrString() string { return "makeslice" }
470
471 // Slice.
472 type SSASlice struct {
473 ssaRegister
474 X SSAValue
475 Low SSAValue
476 High SSAValue
477 Max SSAValue
478 }
479
480 func (s *SSASlice) InstrPos() int32 { return s.pos }
481 func (s *SSASlice) InstrString() string { return "slice" }
482
483 // FieldAddr.
484 type SSAFieldAddr struct {
485 ssaRegister
486 X SSAValue
487 Field int
488 }
489
490 func (f *SSAFieldAddr) InstrPos() int32 { return f.pos }
491 func (f *SSAFieldAddr) InstrString() string { return "fieldaddr" }
492
493 // IndexAddr.
494 type SSAIndexAddr struct {
495 ssaRegister
496 X SSAValue
497 Index SSAValue
498 }
499
500 func (i *SSAIndexAddr) InstrPos() int32 { return i.pos }
501 func (i *SSAIndexAddr) InstrString() string { return "indexaddr" }
502
503 // Lookup (map[k]).
504 type SSALookup struct {
505 ssaRegister
506 X SSAValue
507 Index SSAValue
508 CommaOk bool
509 }
510
511 func (l *SSALookup) InstrPos() int32 { return l.pos }
512 func (l *SSALookup) InstrString() string { return "lookup" }
513
514 // Range.
515 type SSARange struct {
516 ssaRegister
517 X SSAValue
518 }
519
520 func (r *SSARange) InstrPos() int32 { return r.pos }
521 func (r *SSARange) InstrString() string { return "range" }
522
523 // Next (iterator advance).
524 type SSANext struct {
525 ssaRegister
526 Iter SSAValue
527 IsString bool
528 }
529
530 func (n *SSANext) InstrPos() int32 { return n.pos }
531 func (n *SSANext) InstrString() string { return "next" }
532
533 // TypeAssert.
534 type SSATypeAssert struct {
535 ssaRegister
536 X SSAValue
537 AssertedType Type
538 CommaOk bool
539 }
540
541 func (t *SSATypeAssert) InstrPos() int32 { return t.pos }
542 func (t *SSATypeAssert) InstrString() string { return "typeassert" }
543
544 // Extract (tuple component).
545 type SSAExtract struct {
546 ssaRegister
547 Tuple SSAValue
548 Index int
549 }
550
551 func (e *SSAExtract) InstrPos() int32 { return e.pos }
552 func (e *SSAExtract) InstrString() string { return "extract" }
553
554 // -- Terminator instructions --
555
556 // Jump.
557 type SSAJump struct {
558 ssaInstr
559 Comment string
560 }
561
562 func (j *SSAJump) InstrPos() int32 { return 0 }
563 func (j *SSAJump) InstrString() string { return "jump " | j.Comment }
564
565 // If.
566 type SSAIf struct {
567 ssaInstr
568 Cond SSAValue
569 }
570
571 func (i *SSAIf) InstrPos() int32 { return 0 }
572 func (i *SSAIf) InstrString() string { return "if" }
573
574 // Return.
575 type SSAReturn struct {
576 ssaInstr
577 Results []SSAValue
578 pos int32
579 }
580
581 func (r *SSAReturn) InstrPos() int32 { return r.pos }
582 func (r *SSAReturn) InstrString() string { return "return" }
583
584 // RunDefers.
585 type SSARunDefers struct {
586 ssaInstr
587 }
588
589 func (rd *SSARunDefers) InstrPos() int32 { return 0 }
590 func (rd *SSARunDefers) InstrString() string { return "rundefers" }
591
592 // Panic.
593 type SSAPanic struct {
594 ssaInstr
595 X SSAValue
596 pos int32
597 }
598
599 func (p *SSAPanic) InstrPos() int32 { return p.pos }
600 func (p *SSAPanic) InstrString() string { return "panic" }
601
602 // Go (spawn).
603 type SSAGo struct {
604 ssaInstr
605 Call SSACallCommon
606 pos int32
607 }
608
609 func (g *SSAGo) InstrPos() int32 { return g.pos }
610 func (g *SSAGo) InstrString() string { return "go" }
611
612 // Defer.
613 type SSADefer struct {
614 ssaInstr
615 Call SSACallCommon
616 pos int32
617 }
618
619 func (d *SSADefer) InstrPos() int32 { return d.pos }
620 func (d *SSADefer) InstrString() string { return "defer" }
621
622 // -- Side-effecting instructions --
623
624 // Send.
625 type SSASend struct {
626 ssaInstr
627 Chan SSAValue
628 X SSAValue
629 pos int32
630 }
631
632 func (s *SSASend) InstrPos() int32 { return s.pos }
633 func (s *SSASend) InstrString() string { return "send" }
634
635 // Store.
636 type SSAStore struct {
637 ssaInstr
638 Addr SSAValue
639 Val SSAValue
640 pos int32
641 }
642
643 func (s *SSAStore) InstrPos() int32 { return s.pos }
644 func (s *SSAStore) InstrString() string { return "store" }
645
646 // MapUpdate.
647 type SSAMapUpdate struct {
648 ssaInstr
649 Map SSAValue
650 Key SSAValue
651 Value SSAValue
652 pos int32
653 }
654
655 func (m *SSAMapUpdate) InstrPos() int32 { return m.pos }
656 func (m *SSAMapUpdate) InstrString() string { return "mapupdate" }
657
658 // SelectState describes one case of a select statement.
659 type SSASelectState struct {
660 Dir token.Token // token.ARROW for send, token.DEFAULT for recv
661 Chan SSAValue
662 Send SSAValue
663 }
664
665 // Select instruction.
666 type SSASelect struct {
667 ssaRegister
668 States []*SSASelectState
669 Blocking bool
670 }
671
672 func (s *SSASelect) InstrPos() int32 { return s.pos }
673 func (s *SSASelect) InstrString() string { return "select" }
674
675 // Operator mapping from syntax.Operator to SSAOp.
676 func syntaxOpToSSAOp(op Operator, unary bool) SSAOp {
677 if unary {
678 switch op {
679 case Not:
680 return OpNot
681 case Recv:
682 return OpArrow
683 case And:
684 return OpAnd
685 case Mul:
686 return OpMul
687 case Sub:
688 return OpSub
689 case Xor:
690 return OpXor
691 }
692 }
693 switch op {
694 case Add:
695 return OpAdd
696 case Or:
697 return OpOr
698 case Sub:
699 return OpSub
700 case Mul:
701 return OpMul
702 case Div:
703 return OpQuo
704 case Rem:
705 return OpRem
706 case And:
707 return OpAnd
708 case Xor:
709 return OpXor
710 case Shl:
711 return OpShl
712 case Shr:
713 return OpShr
714 case AndNot:
715 return OpAndNot
716 case OrOr:
717 return OpLor
718 case AndAnd:
719 return OpLand
720 case Eql:
721 return OpEql
722 case Neq:
723 return OpNeq
724 case Lss:
725 return OpLss
726 case Leq:
727 return OpLeq
728 case Gtr:
729 return OpGtr
730 case Geq:
731 return OpGeq
732 }
733 return OpIllegal
734 }
735
736 func compoundOp(op Operator) SSAOp {
737 switch op {
738 case Add:
739 return OpAdd
740 case Or:
741 return OpOr
742 case Sub:
743 return OpSub
744 case Mul:
745 return OpMul
746 case Div:
747 return OpQuo
748 case Rem:
749 return OpRem
750 case And:
751 return OpAnd
752 case Xor:
753 return OpXor
754 case Shl:
755 return OpShl
756 case Shr:
757 return OpShr
758 case AndNot:
759 return OpAndNot
760 }
761 return OpIllegal
762 }
763
764 func ssaBuiltinID(name string) (BuiltinID, bool) {
765 switch name {
766 case "append":
767 return BuiltinAppend, true
768 case "cap":
769 return BuiltinCap, true
770 case "clear":
771 return BuiltinClear, true
772 case "close":
773 return BuiltinClose, true
774 case "copy":
775 return BuiltinCopy, true
776 case "delete":
777 return BuiltinDelete, true
778 case "len":
779 return BuiltinLen, true
780 case "make":
781 return BuiltinMake, true
782 case "max":
783 return BuiltinMax, true
784 case "min":
785 return BuiltinMin, true
786 case "new":
787 return BuiltinNew, true
788 case "panic":
789 return BuiltinPanic, true
790 case "print":
791 return BuiltinPrint, true
792 case "println":
793 return BuiltinPrintln, true
794 case "recover":
795 return BuiltinRecover, true
796 }
797 return 0, false
798 }
799
800 func ssaItoa(n int) string {
801 if n == 0 {
802 return "0"
803 }
804 neg := n < 0
805 if neg {
806 n = -n
807 }
808 buf := []byte{:0:20}
809 for n > 0 {
810 buf = append(buf, byte('0'+n%10))
811 n /= 10
812 }
813 if neg {
814 buf = append(buf, '-')
815 }
816 for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
817 buf[i], buf[j] = buf[j], buf[i]
818 }
819 return string(buf)
820 }
821
822 // Type helpers for SSA builder.
823 func ssaElemType(t Type) Type {
824 if t == nil {
825 return nil
826 }
827 switch t := t.Underlying().(type) {
828 case *Slice:
829 return t.Elem()
830 case *Array:
831 return t.Elem()
832 case *TCMap:
833 return t.Elem()
834 case *Pointer:
835 return t.Elem()
836 case *Basic:
837 if t.Info()&IsString != 0 {
838 return Typ[Uint8]
839 }
840 }
841 return nil
842 }
843
844 func ssaChanElemType(t Type) Type {
845 if t == nil {
846 return nil
847 }
848 if ch, ok := t.Underlying().(*TCChan); ok {
849 return ch.Elem()
850 }
851 return nil
852 }
853
854 func ssaIsStringType(t Type) bool {
855 if t == nil {
856 return false
857 }
858 if b, ok := t.Underlying().(*Basic); ok {
859 return b.Info()&IsString != 0
860 }
861 return false
862 }
863
864 func ssaSliceOf(t Type) Type {
865 if t == nil {
866 return nil
867 }
868 if b, ok := t.Underlying().(*Basic); ok && b.Info()&IsString != 0 {
869 return t
870 }
871 switch t := t.Underlying().(type) {
872 case *Slice:
873 return t
874 case *Array:
875 if b, ok := t.Elem().(*Basic); ok && b.kind == Uint8 {
876 return Typ[TCString]
877 }
878 return NewSlice(t.Elem())
879 }
880 return Typ[TCString]
881 }
882
883 func ssaTupleElemType(t Type, i int) Type {
884 if t == nil {
885 return nil
886 }
887 if tup, ok := t.(*Tuple); ok && i < tup.Len() {
888 return tup.At(i).Type()
889 }
890 return nil
891 }
892
893 func ssaParseInt64(s string) int64 {
894 var n int64
895 for i := 0; i < len(s); i++ {
896 c := s[i]
897 if c < '0' || c > '9' {
898 break
899 }
900 n = n*10 + int64(c-'0')
901 }
902 return n
903 }
904