1
2
3
4
5 package interp
6
7 import (
8 "bytes"
9 "fmt"
10 "go/constant"
11 "go/token"
12 "go/types"
13 "os"
14 "reflect"
15 "strings"
16 "sync"
17 "unsafe"
18
19 "golang.org/x/tools/go/ssa"
20 "golang.org/x/tools/internal/aliases"
21 "golang.org/x/tools/internal/typeparams"
22 )
23
24
25 type targetPanic struct {
26 v value
27 }
28
29 func (p targetPanic) String() string {
30 return toString(p.v)
31 }
32
33
34 type exitPanic int
35
36
37
38 func constValue(c *ssa.Const) value {
39 if c.Value == nil {
40 return zero(c.Type())
41 }
42
43
44 if t, ok := c.Type().Underlying().(*types.Basic); ok {
45
46 switch t.Kind() {
47 case types.Bool, types.UntypedBool:
48 return constant.BoolVal(c.Value)
49 case types.Int, types.UntypedInt:
50
51 return int(c.Int64())
52 case types.Int8:
53 return int8(c.Int64())
54 case types.Int16:
55 return int16(c.Int64())
56 case types.Int32, types.UntypedRune:
57 return int32(c.Int64())
58 case types.Int64:
59 return c.Int64()
60 case types.Uint:
61
62 return uint(c.Uint64())
63 case types.Uint8:
64 return uint8(c.Uint64())
65 case types.Uint16:
66 return uint16(c.Uint64())
67 case types.Uint32:
68 return uint32(c.Uint64())
69 case types.Uint64:
70 return c.Uint64()
71 case types.Uintptr:
72
73 return uintptr(c.Uint64())
74 case types.Float32:
75 return float32(c.Float64())
76 case types.Float64, types.UntypedFloat:
77 return c.Float64()
78 case types.Complex64:
79 return complex64(c.Complex128())
80 case types.Complex128, types.UntypedComplex:
81 return c.Complex128()
82 case types.String, types.UntypedString:
83 if c.Value.Kind() == constant.String {
84 return constant.StringVal(c.Value)
85 }
86 return string(rune(c.Int64()))
87 }
88 }
89
90 panic(fmt.Sprintf("constValue: %s", c))
91 }
92
93
94 func fitsInt(x int64, sizes types.Sizes) bool {
95 intSize := sizes.Sizeof(types.Typ[types.Int])
96 if intSize < sizes.Sizeof(types.Typ[types.Int64]) {
97 maxInt := int64(1)<<((intSize*8)-1) - 1
98 minInt := -int64(1) << ((intSize * 8) - 1)
99 return minInt <= x && x <= maxInt
100 }
101 return true
102 }
103
104
105
106
107 func asInt64(x value) int64 {
108 switch x := x.(type) {
109 case int:
110 return int64(x)
111 case int8:
112 return int64(x)
113 case int16:
114 return int64(x)
115 case int32:
116 return int64(x)
117 case int64:
118 return x
119 case uint:
120 return int64(x)
121 case uint8:
122 return int64(x)
123 case uint16:
124 return int64(x)
125 case uint32:
126 return int64(x)
127 case uint64:
128 return int64(x)
129 case uintptr:
130 return int64(x)
131 }
132 panic(fmt.Sprintf("cannot convert %T to int64", x))
133 }
134
135
136
137 func asUint64(x value) uint64 {
138 switch x := x.(type) {
139 case uint:
140 return uint64(x)
141 case uint8:
142 return uint64(x)
143 case uint16:
144 return uint64(x)
145 case uint32:
146 return uint64(x)
147 case uint64:
148 return x
149 case uintptr:
150 return uint64(x)
151 }
152 panic(fmt.Sprintf("cannot convert %T to uint64", x))
153 }
154
155
156
157 func asUnsigned(x value) (value, bool) {
158 switch x := x.(type) {
159 case int:
160 return uint(x), x >= 0
161 case int8:
162 return uint8(x), x >= 0
163 case int16:
164 return uint16(x), x >= 0
165 case int32:
166 return uint32(x), x >= 0
167 case int64:
168 return uint64(x), x >= 0
169 case uint, uint8, uint32, uint64, uintptr:
170 return x, true
171 }
172 panic(fmt.Sprintf("cannot convert %T to unsigned", x))
173 }
174
175
176 func zero(t types.Type) value {
177 switch t := t.(type) {
178 case *types.Basic:
179 if t.Kind() == types.UntypedNil {
180 panic("untyped nil has no zero value")
181 }
182 if t.Info()&types.IsUntyped != 0 {
183
184
185
186
187 t = types.Default(t).(*types.Basic)
188 }
189 switch t.Kind() {
190 case types.Bool:
191 return false
192 case types.Int:
193 return int(0)
194 case types.Int8:
195 return int8(0)
196 case types.Int16:
197 return int16(0)
198 case types.Int32:
199 return int32(0)
200 case types.Int64:
201 return int64(0)
202 case types.Uint:
203 return uint(0)
204 case types.Uint8:
205 return uint8(0)
206 case types.Uint16:
207 return uint16(0)
208 case types.Uint32:
209 return uint32(0)
210 case types.Uint64:
211 return uint64(0)
212 case types.Uintptr:
213 return uintptr(0)
214 case types.Float32:
215 return float32(0)
216 case types.Float64:
217 return float64(0)
218 case types.Complex64:
219 return complex64(0)
220 case types.Complex128:
221 return complex128(0)
222 case types.String:
223 return ""
224 case types.UnsafePointer:
225 return unsafe.Pointer(nil)
226 default:
227 panic(fmt.Sprint("zero for unexpected type:", t))
228 }
229 case *types.Pointer:
230 return (*value)(nil)
231 case *types.Array:
232 a := make(array, t.Len())
233 for i := range a {
234 a[i] = zero(t.Elem())
235 }
236 return a
237 case *types.Named:
238 return zero(t.Underlying())
239 case *aliases.Alias:
240 return zero(aliases.Unalias(t))
241 case *types.Interface:
242 return iface{}
243 case *types.Slice:
244 return []value(nil)
245 case *types.Struct:
246 s := make(structure, t.NumFields())
247 for i := range s {
248 s[i] = zero(t.Field(i).Type())
249 }
250 return s
251 case *types.Tuple:
252 if t.Len() == 1 {
253 return zero(t.At(0).Type())
254 }
255 s := make(tuple, t.Len())
256 for i := range s {
257 s[i] = zero(t.At(i).Type())
258 }
259 return s
260 case *types.Chan:
261 return chan value(nil)
262 case *types.Map:
263 if usesBuiltinMap(t.Key()) {
264 return map[value]value(nil)
265 }
266 return (*hashmap)(nil)
267 case *types.Signature:
268 return (*ssa.Function)(nil)
269 }
270 panic(fmt.Sprint("zero: unexpected ", t))
271 }
272
273
274 func slice(x, lo, hi, max value) value {
275 var Len, Cap int
276 switch x := x.(type) {
277 case string:
278 Len = len(x)
279 case []value:
280 Len = len(x)
281 Cap = cap(x)
282 case *value:
283 a := (*x).(array)
284 Len = len(a)
285 Cap = cap(a)
286 }
287
288 l := int64(0)
289 if lo != nil {
290 l = asInt64(lo)
291 }
292
293 h := int64(Len)
294 if hi != nil {
295 h = asInt64(hi)
296 }
297
298 m := int64(Cap)
299 if max != nil {
300 m = asInt64(max)
301 }
302
303 switch x := x.(type) {
304 case string:
305 return x[l:h]
306 case []value:
307 return x[l:h:m]
308 case *value:
309 a := (*x).(array)
310 return []value(a)[l:h:m]
311 }
312 panic(fmt.Sprintf("slice: unexpected X type: %T", x))
313 }
314
315
316 func lookup(instr *ssa.Lookup, x, idx value) value {
317 switch x := x.(type) {
318 case map[value]value, *hashmap:
319 var v value
320 var ok bool
321 switch x := x.(type) {
322 case map[value]value:
323 v, ok = x[idx]
324 case *hashmap:
325 v = x.lookup(idx.(hashable))
326 ok = v != nil
327 }
328 if !ok {
329 v = zero(instr.X.Type().Underlying().(*types.Map).Elem())
330 }
331 if instr.CommaOk {
332 v = tuple{v, ok}
333 }
334 return v
335 }
336 panic(fmt.Sprintf("unexpected x type in Lookup: %T", x))
337 }
338
339
340
341
342 func binop(op token.Token, t types.Type, x, y value) value {
343 switch op {
344 case token.ADD:
345 switch x.(type) {
346 case int:
347 return x.(int) + y.(int)
348 case int8:
349 return x.(int8) + y.(int8)
350 case int16:
351 return x.(int16) + y.(int16)
352 case int32:
353 return x.(int32) + y.(int32)
354 case int64:
355 return x.(int64) + y.(int64)
356 case uint:
357 return x.(uint) + y.(uint)
358 case uint8:
359 return x.(uint8) + y.(uint8)
360 case uint16:
361 return x.(uint16) + y.(uint16)
362 case uint32:
363 return x.(uint32) + y.(uint32)
364 case uint64:
365 return x.(uint64) + y.(uint64)
366 case uintptr:
367 return x.(uintptr) + y.(uintptr)
368 case float32:
369 return x.(float32) + y.(float32)
370 case float64:
371 return x.(float64) + y.(float64)
372 case complex64:
373 return x.(complex64) + y.(complex64)
374 case complex128:
375 return x.(complex128) + y.(complex128)
376 case string:
377 return x.(string) + y.(string)
378 }
379
380 case token.SUB:
381 switch x.(type) {
382 case int:
383 return x.(int) - y.(int)
384 case int8:
385 return x.(int8) - y.(int8)
386 case int16:
387 return x.(int16) - y.(int16)
388 case int32:
389 return x.(int32) - y.(int32)
390 case int64:
391 return x.(int64) - y.(int64)
392 case uint:
393 return x.(uint) - y.(uint)
394 case uint8:
395 return x.(uint8) - y.(uint8)
396 case uint16:
397 return x.(uint16) - y.(uint16)
398 case uint32:
399 return x.(uint32) - y.(uint32)
400 case uint64:
401 return x.(uint64) - y.(uint64)
402 case uintptr:
403 return x.(uintptr) - y.(uintptr)
404 case float32:
405 return x.(float32) - y.(float32)
406 case float64:
407 return x.(float64) - y.(float64)
408 case complex64:
409 return x.(complex64) - y.(complex64)
410 case complex128:
411 return x.(complex128) - y.(complex128)
412 }
413
414 case token.MUL:
415 switch x.(type) {
416 case int:
417 return x.(int) * y.(int)
418 case int8:
419 return x.(int8) * y.(int8)
420 case int16:
421 return x.(int16) * y.(int16)
422 case int32:
423 return x.(int32) * y.(int32)
424 case int64:
425 return x.(int64) * y.(int64)
426 case uint:
427 return x.(uint) * y.(uint)
428 case uint8:
429 return x.(uint8) * y.(uint8)
430 case uint16:
431 return x.(uint16) * y.(uint16)
432 case uint32:
433 return x.(uint32) * y.(uint32)
434 case uint64:
435 return x.(uint64) * y.(uint64)
436 case uintptr:
437 return x.(uintptr) * y.(uintptr)
438 case float32:
439 return x.(float32) * y.(float32)
440 case float64:
441 return x.(float64) * y.(float64)
442 case complex64:
443 return x.(complex64) * y.(complex64)
444 case complex128:
445 return x.(complex128) * y.(complex128)
446 }
447
448 case token.QUO:
449 switch x.(type) {
450 case int:
451 return x.(int) / y.(int)
452 case int8:
453 return x.(int8) / y.(int8)
454 case int16:
455 return x.(int16) / y.(int16)
456 case int32:
457 return x.(int32) / y.(int32)
458 case int64:
459 return x.(int64) / y.(int64)
460 case uint:
461 return x.(uint) / y.(uint)
462 case uint8:
463 return x.(uint8) / y.(uint8)
464 case uint16:
465 return x.(uint16) / y.(uint16)
466 case uint32:
467 return x.(uint32) / y.(uint32)
468 case uint64:
469 return x.(uint64) / y.(uint64)
470 case uintptr:
471 return x.(uintptr) / y.(uintptr)
472 case float32:
473 return x.(float32) / y.(float32)
474 case float64:
475 return x.(float64) / y.(float64)
476 case complex64:
477 return x.(complex64) / y.(complex64)
478 case complex128:
479 return x.(complex128) / y.(complex128)
480 }
481
482 case token.REM:
483 switch x.(type) {
484 case int:
485 return x.(int) % y.(int)
486 case int8:
487 return x.(int8) % y.(int8)
488 case int16:
489 return x.(int16) % y.(int16)
490 case int32:
491 return x.(int32) % y.(int32)
492 case int64:
493 return x.(int64) % y.(int64)
494 case uint:
495 return x.(uint) % y.(uint)
496 case uint8:
497 return x.(uint8) % y.(uint8)
498 case uint16:
499 return x.(uint16) % y.(uint16)
500 case uint32:
501 return x.(uint32) % y.(uint32)
502 case uint64:
503 return x.(uint64) % y.(uint64)
504 case uintptr:
505 return x.(uintptr) % y.(uintptr)
506 }
507
508 case token.AND:
509 switch x.(type) {
510 case int:
511 return x.(int) & y.(int)
512 case int8:
513 return x.(int8) & y.(int8)
514 case int16:
515 return x.(int16) & y.(int16)
516 case int32:
517 return x.(int32) & y.(int32)
518 case int64:
519 return x.(int64) & y.(int64)
520 case uint:
521 return x.(uint) & y.(uint)
522 case uint8:
523 return x.(uint8) & y.(uint8)
524 case uint16:
525 return x.(uint16) & y.(uint16)
526 case uint32:
527 return x.(uint32) & y.(uint32)
528 case uint64:
529 return x.(uint64) & y.(uint64)
530 case uintptr:
531 return x.(uintptr) & y.(uintptr)
532 }
533
534 case token.OR:
535 switch x.(type) {
536 case int:
537 return x.(int) | y.(int)
538 case int8:
539 return x.(int8) | y.(int8)
540 case int16:
541 return x.(int16) | y.(int16)
542 case int32:
543 return x.(int32) | y.(int32)
544 case int64:
545 return x.(int64) | y.(int64)
546 case uint:
547 return x.(uint) | y.(uint)
548 case uint8:
549 return x.(uint8) | y.(uint8)
550 case uint16:
551 return x.(uint16) | y.(uint16)
552 case uint32:
553 return x.(uint32) | y.(uint32)
554 case uint64:
555 return x.(uint64) | y.(uint64)
556 case uintptr:
557 return x.(uintptr) | y.(uintptr)
558 }
559
560 case token.XOR:
561 switch x.(type) {
562 case int:
563 return x.(int) ^ y.(int)
564 case int8:
565 return x.(int8) ^ y.(int8)
566 case int16:
567 return x.(int16) ^ y.(int16)
568 case int32:
569 return x.(int32) ^ y.(int32)
570 case int64:
571 return x.(int64) ^ y.(int64)
572 case uint:
573 return x.(uint) ^ y.(uint)
574 case uint8:
575 return x.(uint8) ^ y.(uint8)
576 case uint16:
577 return x.(uint16) ^ y.(uint16)
578 case uint32:
579 return x.(uint32) ^ y.(uint32)
580 case uint64:
581 return x.(uint64) ^ y.(uint64)
582 case uintptr:
583 return x.(uintptr) ^ y.(uintptr)
584 }
585
586 case token.AND_NOT:
587 switch x.(type) {
588 case int:
589 return x.(int) &^ y.(int)
590 case int8:
591 return x.(int8) &^ y.(int8)
592 case int16:
593 return x.(int16) &^ y.(int16)
594 case int32:
595 return x.(int32) &^ y.(int32)
596 case int64:
597 return x.(int64) &^ y.(int64)
598 case uint:
599 return x.(uint) &^ y.(uint)
600 case uint8:
601 return x.(uint8) &^ y.(uint8)
602 case uint16:
603 return x.(uint16) &^ y.(uint16)
604 case uint32:
605 return x.(uint32) &^ y.(uint32)
606 case uint64:
607 return x.(uint64) &^ y.(uint64)
608 case uintptr:
609 return x.(uintptr) &^ y.(uintptr)
610 }
611
612 case token.SHL:
613 u, ok := asUnsigned(y)
614 if !ok {
615 panic("negative shift amount")
616 }
617 y := asUint64(u)
618 switch x.(type) {
619 case int:
620 return x.(int) << y
621 case int8:
622 return x.(int8) << y
623 case int16:
624 return x.(int16) << y
625 case int32:
626 return x.(int32) << y
627 case int64:
628 return x.(int64) << y
629 case uint:
630 return x.(uint) << y
631 case uint8:
632 return x.(uint8) << y
633 case uint16:
634 return x.(uint16) << y
635 case uint32:
636 return x.(uint32) << y
637 case uint64:
638 return x.(uint64) << y
639 case uintptr:
640 return x.(uintptr) << y
641 }
642
643 case token.SHR:
644 u, ok := asUnsigned(y)
645 if !ok {
646 panic("negative shift amount")
647 }
648 y := asUint64(u)
649 switch x.(type) {
650 case int:
651 return x.(int) >> y
652 case int8:
653 return x.(int8) >> y
654 case int16:
655 return x.(int16) >> y
656 case int32:
657 return x.(int32) >> y
658 case int64:
659 return x.(int64) >> y
660 case uint:
661 return x.(uint) >> y
662 case uint8:
663 return x.(uint8) >> y
664 case uint16:
665 return x.(uint16) >> y
666 case uint32:
667 return x.(uint32) >> y
668 case uint64:
669 return x.(uint64) >> y
670 case uintptr:
671 return x.(uintptr) >> y
672 }
673
674 case token.LSS:
675 switch x.(type) {
676 case int:
677 return x.(int) < y.(int)
678 case int8:
679 return x.(int8) < y.(int8)
680 case int16:
681 return x.(int16) < y.(int16)
682 case int32:
683 return x.(int32) < y.(int32)
684 case int64:
685 return x.(int64) < y.(int64)
686 case uint:
687 return x.(uint) < y.(uint)
688 case uint8:
689 return x.(uint8) < y.(uint8)
690 case uint16:
691 return x.(uint16) < y.(uint16)
692 case uint32:
693 return x.(uint32) < y.(uint32)
694 case uint64:
695 return x.(uint64) < y.(uint64)
696 case uintptr:
697 return x.(uintptr) < y.(uintptr)
698 case float32:
699 return x.(float32) < y.(float32)
700 case float64:
701 return x.(float64) < y.(float64)
702 case string:
703 return x.(string) < y.(string)
704 }
705
706 case token.LEQ:
707 switch x.(type) {
708 case int:
709 return x.(int) <= y.(int)
710 case int8:
711 return x.(int8) <= y.(int8)
712 case int16:
713 return x.(int16) <= y.(int16)
714 case int32:
715 return x.(int32) <= y.(int32)
716 case int64:
717 return x.(int64) <= y.(int64)
718 case uint:
719 return x.(uint) <= y.(uint)
720 case uint8:
721 return x.(uint8) <= y.(uint8)
722 case uint16:
723 return x.(uint16) <= y.(uint16)
724 case uint32:
725 return x.(uint32) <= y.(uint32)
726 case uint64:
727 return x.(uint64) <= y.(uint64)
728 case uintptr:
729 return x.(uintptr) <= y.(uintptr)
730 case float32:
731 return x.(float32) <= y.(float32)
732 case float64:
733 return x.(float64) <= y.(float64)
734 case string:
735 return x.(string) <= y.(string)
736 }
737
738 case token.EQL:
739 return eqnil(t, x, y)
740
741 case token.NEQ:
742 return !eqnil(t, x, y)
743
744 case token.GTR:
745 switch x.(type) {
746 case int:
747 return x.(int) > y.(int)
748 case int8:
749 return x.(int8) > y.(int8)
750 case int16:
751 return x.(int16) > y.(int16)
752 case int32:
753 return x.(int32) > y.(int32)
754 case int64:
755 return x.(int64) > y.(int64)
756 case uint:
757 return x.(uint) > y.(uint)
758 case uint8:
759 return x.(uint8) > y.(uint8)
760 case uint16:
761 return x.(uint16) > y.(uint16)
762 case uint32:
763 return x.(uint32) > y.(uint32)
764 case uint64:
765 return x.(uint64) > y.(uint64)
766 case uintptr:
767 return x.(uintptr) > y.(uintptr)
768 case float32:
769 return x.(float32) > y.(float32)
770 case float64:
771 return x.(float64) > y.(float64)
772 case string:
773 return x.(string) > y.(string)
774 }
775
776 case token.GEQ:
777 switch x.(type) {
778 case int:
779 return x.(int) >= y.(int)
780 case int8:
781 return x.(int8) >= y.(int8)
782 case int16:
783 return x.(int16) >= y.(int16)
784 case int32:
785 return x.(int32) >= y.(int32)
786 case int64:
787 return x.(int64) >= y.(int64)
788 case uint:
789 return x.(uint) >= y.(uint)
790 case uint8:
791 return x.(uint8) >= y.(uint8)
792 case uint16:
793 return x.(uint16) >= y.(uint16)
794 case uint32:
795 return x.(uint32) >= y.(uint32)
796 case uint64:
797 return x.(uint64) >= y.(uint64)
798 case uintptr:
799 return x.(uintptr) >= y.(uintptr)
800 case float32:
801 return x.(float32) >= y.(float32)
802 case float64:
803 return x.(float64) >= y.(float64)
804 case string:
805 return x.(string) >= y.(string)
806 }
807 }
808 panic(fmt.Sprintf("invalid binary op: %T %s %T", x, op, y))
809 }
810
811
812
813
814
815 func eqnil(t types.Type, x, y value) bool {
816 switch t.Underlying().(type) {
817 case *types.Map, *types.Signature, *types.Slice:
818
819
820 switch x := x.(type) {
821 case *hashmap:
822 return (x != nil) == (y.(*hashmap) != nil)
823 case map[value]value:
824 return (x != nil) == (y.(map[value]value) != nil)
825 case *ssa.Function:
826 switch y := y.(type) {
827 case *ssa.Function:
828 return (x != nil) == (y != nil)
829 case *closure:
830 return true
831 }
832 case *closure:
833 return (x != nil) == (y.(*ssa.Function) != nil)
834 case []value:
835 return (x != nil) == (y.([]value) != nil)
836 }
837 panic(fmt.Sprintf("eqnil(%s): illegal dynamic type: %T", t, x))
838 }
839
840 return equals(t, x, y)
841 }
842
843 func unop(instr *ssa.UnOp, x value) value {
844 switch instr.Op {
845 case token.ARROW:
846 v, ok := <-x.(chan value)
847 if !ok {
848 v = zero(instr.X.Type().Underlying().(*types.Chan).Elem())
849 }
850 if instr.CommaOk {
851 v = tuple{v, ok}
852 }
853 return v
854 case token.SUB:
855 switch x := x.(type) {
856 case int:
857 return -x
858 case int8:
859 return -x
860 case int16:
861 return -x
862 case int32:
863 return -x
864 case int64:
865 return -x
866 case uint:
867 return -x
868 case uint8:
869 return -x
870 case uint16:
871 return -x
872 case uint32:
873 return -x
874 case uint64:
875 return -x
876 case uintptr:
877 return -x
878 case float32:
879 return -x
880 case float64:
881 return -x
882 case complex64:
883 return -x
884 case complex128:
885 return -x
886 }
887 case token.MUL:
888 return load(typeparams.MustDeref(instr.X.Type()), x.(*value))
889 case token.NOT:
890 return !x.(bool)
891 case token.XOR:
892 switch x := x.(type) {
893 case int:
894 return ^x
895 case int8:
896 return ^x
897 case int16:
898 return ^x
899 case int32:
900 return ^x
901 case int64:
902 return ^x
903 case uint:
904 return ^x
905 case uint8:
906 return ^x
907 case uint16:
908 return ^x
909 case uint32:
910 return ^x
911 case uint64:
912 return ^x
913 case uintptr:
914 return ^x
915 }
916 }
917 panic(fmt.Sprintf("invalid unary op %s %T", instr.Op, x))
918 }
919
920
921
922
923 func typeAssert(i *interpreter, instr *ssa.TypeAssert, itf iface) value {
924 var v value
925 err := ""
926 if itf.t == nil {
927 err = fmt.Sprintf("interface conversion: interface is nil, not %s", instr.AssertedType)
928
929 } else if idst, ok := instr.AssertedType.Underlying().(*types.Interface); ok {
930 v = itf
931 err = checkInterface(i, idst, itf)
932
933 } else if types.Identical(itf.t, instr.AssertedType) {
934 v = itf.v
935
936 } else {
937 err = fmt.Sprintf("interface conversion: interface is %s, not %s", itf.t, instr.AssertedType)
938 }
939
940
941
942 if err != "" {
943 if !instr.CommaOk {
944 panic(err)
945 }
946 return tuple{zero(instr.AssertedType), false}
947 }
948 if instr.CommaOk {
949 return tuple{v, true}
950 }
951 return v
952 }
953
954
955
956
957
958
959
960
961 var CapturedOutput *bytes.Buffer
962 var capturedOutputMu sync.Mutex
963
964
965
966
967 func print(b []byte) (int, error) {
968 if CapturedOutput != nil {
969 capturedOutputMu.Lock()
970 CapturedOutput.Write(b)
971 capturedOutputMu.Unlock()
972 }
973 return os.Stdout.Write(b)
974 }
975
976
977
978 func callBuiltin(caller *frame, callpos token.Pos, fn *ssa.Builtin, args []value) value {
979 switch fn.Name() {
980 case "append":
981 if len(args) == 1 {
982 return args[0]
983 }
984 if s, ok := args[1].(string); ok {
985
986 arg0 := args[0].([]value)
987 for i := 0; i < len(s); i++ {
988 arg0 = append(arg0, s[i])
989 }
990 return arg0
991 }
992
993 return append(args[0].([]value), args[1].([]value)...)
994
995 case "copy":
996 src := args[1]
997 if _, ok := src.(string); ok {
998 params := fn.Type().(*types.Signature).Params()
999 src = conv(params.At(0).Type(), params.At(1).Type(), src)
1000 }
1001 return copy(args[0].([]value), src.([]value))
1002
1003 case "close":
1004 close(args[0].(chan value))
1005 return nil
1006
1007 case "delete":
1008 switch m := args[0].(type) {
1009 case map[value]value:
1010 delete(m, args[1])
1011 case *hashmap:
1012 m.delete(args[1].(hashable))
1013 default:
1014 panic(fmt.Sprintf("illegal map type: %T", m))
1015 }
1016 return nil
1017
1018 case "print", "println":
1019 ln := fn.Name() == "println"
1020 var buf bytes.Buffer
1021 for i, arg := range args {
1022 if i > 0 && ln {
1023 buf.WriteRune(' ')
1024 }
1025 buf.WriteString(toString(arg))
1026 }
1027 if ln {
1028 buf.WriteRune('\n')
1029 }
1030 print(buf.Bytes())
1031 return nil
1032
1033 case "len":
1034 switch x := args[0].(type) {
1035 case string:
1036 return len(x)
1037 case array:
1038 return len(x)
1039 case *value:
1040 return len((*x).(array))
1041 case []value:
1042 return len(x)
1043 case map[value]value:
1044 return len(x)
1045 case *hashmap:
1046 return x.len()
1047 case chan value:
1048 return len(x)
1049 default:
1050 panic(fmt.Sprintf("len: illegal operand: %T", x))
1051 }
1052
1053 case "cap":
1054 switch x := args[0].(type) {
1055 case array:
1056 return cap(x)
1057 case *value:
1058 return cap((*x).(array))
1059 case []value:
1060 return cap(x)
1061 case chan value:
1062 return cap(x)
1063 default:
1064 panic(fmt.Sprintf("cap: illegal operand: %T", x))
1065 }
1066
1067 case "min":
1068 return foldLeft(min, args)
1069 case "max":
1070 return foldLeft(max, args)
1071
1072 case "real":
1073 switch c := args[0].(type) {
1074 case complex64:
1075 return real(c)
1076 case complex128:
1077 return real(c)
1078 default:
1079 panic(fmt.Sprintf("real: illegal operand: %T", c))
1080 }
1081
1082 case "imag":
1083 switch c := args[0].(type) {
1084 case complex64:
1085 return imag(c)
1086 case complex128:
1087 return imag(c)
1088 default:
1089 panic(fmt.Sprintf("imag: illegal operand: %T", c))
1090 }
1091
1092 case "complex":
1093 switch f := args[0].(type) {
1094 case float32:
1095 return complex(f, args[1].(float32))
1096 case float64:
1097 return complex(f, args[1].(float64))
1098 default:
1099 panic(fmt.Sprintf("complex: illegal operand: %T", f))
1100 }
1101
1102 case "panic":
1103
1104
1105 panic(targetPanic{args[0]})
1106
1107 case "recover":
1108 return doRecover(caller)
1109
1110 case "ssa:wrapnilchk":
1111 recv := args[0]
1112 if recv.(*value) == nil {
1113 recvType := args[1]
1114 methodName := args[2]
1115 panic(fmt.Sprintf("value method (%s).%s called using nil *%s pointer",
1116 recvType, methodName, recvType))
1117 }
1118 return recv
1119 }
1120
1121 panic("unknown built-in: " + fn.Name())
1122 }
1123
1124 func rangeIter(x value, t types.Type) iter {
1125 switch x := x.(type) {
1126 case map[value]value:
1127 return &mapIter{iter: reflect.ValueOf(x).MapRange()}
1128 case *hashmap:
1129 return &hashmapIter{iter: reflect.ValueOf(x.entries()).MapRange()}
1130 case string:
1131 return &stringIter{Reader: strings.NewReader(x)}
1132 }
1133 panic(fmt.Sprintf("cannot range over %T", x))
1134 }
1135
1136
1137
1138
1139
1140
1141
1142
1143 func widen(x value) value {
1144 switch y := x.(type) {
1145 case bool, int64, uint64, float64, complex128, string, unsafe.Pointer:
1146 return x
1147 case int:
1148 return int64(y)
1149 case int8:
1150 return int64(y)
1151 case int16:
1152 return int64(y)
1153 case int32:
1154 return int64(y)
1155 case uint:
1156 return uint64(y)
1157 case uint8:
1158 return uint64(y)
1159 case uint16:
1160 return uint64(y)
1161 case uint32:
1162 return uint64(y)
1163 case uintptr:
1164 return uint64(y)
1165 case float32:
1166 return float64(y)
1167 case complex64:
1168 return complex128(y)
1169 }
1170 panic(fmt.Sprintf("cannot widen %T", x))
1171 }
1172
1173
1174
1175
1176 func conv(t_dst, t_src types.Type, x value) value {
1177 ut_src := t_src.Underlying()
1178 ut_dst := t_dst.Underlying()
1179
1180
1181 if b, ok := ut_dst.(*types.Basic); ok && b.Info()&types.IsUntyped != 0 {
1182 panic("oops: conversion to 'untyped' type: " + b.String())
1183 }
1184
1185
1186 if _, ok := ut_dst.(*types.Interface); ok {
1187 if _, ok := ut_src.(*types.Interface); ok {
1188 panic("oops: Convert should be ChangeInterface")
1189 } else {
1190 panic("oops: Convert should be MakeInterface")
1191 }
1192 }
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206 switch ut_src := ut_src.(type) {
1207 case *types.Pointer:
1208 switch ut_dst := ut_dst.(type) {
1209 case *types.Basic:
1210
1211 if ut_dst.Kind() == types.UnsafePointer {
1212 return unsafe.Pointer(x.(*value))
1213 }
1214 }
1215
1216 case *types.Slice:
1217
1218 switch ut_src.Elem().Underlying().(*types.Basic).Kind() {
1219 case types.Byte:
1220 x := x.([]value)
1221 b := make([]byte, 0, len(x))
1222 for i := range x {
1223 b = append(b, x[i].(byte))
1224 }
1225 return string(b)
1226
1227 case types.Rune:
1228 x := x.([]value)
1229 r := make([]rune, 0, len(x))
1230 for i := range x {
1231 r = append(r, x[i].(rune))
1232 }
1233 return string(r)
1234 }
1235
1236 case *types.Basic:
1237 x = widen(x)
1238
1239
1240 if ut_src.Info()&types.IsInteger != 0 {
1241 if ut_dst, ok := ut_dst.(*types.Basic); ok && ut_dst.Kind() == types.String {
1242 return fmt.Sprintf("%c", x)
1243 }
1244 }
1245
1246
1247 if s, ok := x.(string); ok {
1248 switch ut_dst := ut_dst.(type) {
1249 case *types.Slice:
1250 var res []value
1251 switch ut_dst.Elem().Underlying().(*types.Basic).Kind() {
1252 case types.Rune:
1253 for _, r := range []rune(s) {
1254 res = append(res, r)
1255 }
1256 return res
1257 case types.Byte:
1258 for _, b := range []byte(s) {
1259 res = append(res, b)
1260 }
1261 return res
1262 }
1263 case *types.Basic:
1264 if ut_dst.Kind() == types.String {
1265 return x.(string)
1266 }
1267 }
1268 break
1269 }
1270
1271
1272 if ut_src.Kind() == types.UnsafePointer {
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289 return zero(t_dst)
1290 }
1291
1292
1293 if ut_src.Info()&types.IsComplex != 0 {
1294 switch ut_dst.(*types.Basic).Kind() {
1295 case types.Complex64:
1296 return complex64(x.(complex128))
1297 case types.Complex128:
1298 return x.(complex128)
1299 }
1300 break
1301 }
1302
1303
1304 if ut_src.Info()&types.IsNumeric != 0 {
1305 kind := ut_dst.(*types.Basic).Kind()
1306 switch x := x.(type) {
1307 case int64:
1308 switch kind {
1309 case types.Int:
1310 return int(x)
1311 case types.Int8:
1312 return int8(x)
1313 case types.Int16:
1314 return int16(x)
1315 case types.Int32:
1316 return int32(x)
1317 case types.Int64:
1318 return int64(x)
1319 case types.Uint:
1320 return uint(x)
1321 case types.Uint8:
1322 return uint8(x)
1323 case types.Uint16:
1324 return uint16(x)
1325 case types.Uint32:
1326 return uint32(x)
1327 case types.Uint64:
1328 return uint64(x)
1329 case types.Uintptr:
1330 return uintptr(x)
1331 case types.Float32:
1332 return float32(x)
1333 case types.Float64:
1334 return float64(x)
1335 }
1336
1337 case uint64:
1338 switch kind {
1339 case types.Int:
1340 return int(x)
1341 case types.Int8:
1342 return int8(x)
1343 case types.Int16:
1344 return int16(x)
1345 case types.Int32:
1346 return int32(x)
1347 case types.Int64:
1348 return int64(x)
1349 case types.Uint:
1350 return uint(x)
1351 case types.Uint8:
1352 return uint8(x)
1353 case types.Uint16:
1354 return uint16(x)
1355 case types.Uint32:
1356 return uint32(x)
1357 case types.Uint64:
1358 return uint64(x)
1359 case types.Uintptr:
1360 return uintptr(x)
1361 case types.Float32:
1362 return float32(x)
1363 case types.Float64:
1364 return float64(x)
1365 }
1366
1367 case float64:
1368 switch kind {
1369 case types.Int:
1370 return int(x)
1371 case types.Int8:
1372 return int8(x)
1373 case types.Int16:
1374 return int16(x)
1375 case types.Int32:
1376 return int32(x)
1377 case types.Int64:
1378 return int64(x)
1379 case types.Uint:
1380 return uint(x)
1381 case types.Uint8:
1382 return uint8(x)
1383 case types.Uint16:
1384 return uint16(x)
1385 case types.Uint32:
1386 return uint32(x)
1387 case types.Uint64:
1388 return uint64(x)
1389 case types.Uintptr:
1390 return uintptr(x)
1391 case types.Float32:
1392 return float32(x)
1393 case types.Float64:
1394 return float64(x)
1395 }
1396 }
1397 }
1398 }
1399
1400 panic(fmt.Sprintf("unsupported conversion: %s -> %s, dynamic type %T", t_src, t_dst, x))
1401 }
1402
1403
1404
1405 func sliceToArrayPointer(t_dst, t_src types.Type, x value) value {
1406 if _, ok := t_src.Underlying().(*types.Slice); ok {
1407 if ptr, ok := t_dst.Underlying().(*types.Pointer); ok {
1408 if arr, ok := ptr.Elem().Underlying().(*types.Array); ok {
1409 x := x.([]value)
1410 if arr.Len() > int64(len(x)) {
1411 panic("array length is greater than slice length")
1412 }
1413 if x == nil {
1414 return zero(t_dst)
1415 }
1416 v := value(array(x[:arr.Len()]))
1417 return &v
1418 }
1419 }
1420 }
1421
1422 panic(fmt.Sprintf("unsupported conversion: %s -> %s, dynamic type %T", t_src, t_dst, x))
1423 }
1424
1425
1426
1427
1428 func checkInterface(i *interpreter, itype *types.Interface, x iface) string {
1429 if meth, _ := types.MissingMethod(x.t, itype, true); meth != nil {
1430 return fmt.Sprintf("interface conversion: %v is not %v: missing method %s",
1431 x.t, itype, meth.Name())
1432 }
1433 return ""
1434 }
1435
1436 func foldLeft(op func(value, value) value, args []value) value {
1437 x := args[0]
1438 for _, arg := range args[1:] {
1439 x = op(x, arg)
1440 }
1441 return x
1442 }
1443
1444 func min(x, y value) value {
1445 switch x := x.(type) {
1446 case float32:
1447 return fmin(x, y.(float32))
1448 case float64:
1449 return fmin(x, y.(float64))
1450 }
1451
1452
1453 if binop(token.LSS, nil, y, x).(bool) {
1454 return y
1455 }
1456 return x
1457 }
1458
1459 func max(x, y value) value {
1460 switch x := x.(type) {
1461 case float32:
1462 return fmax(x, y.(float32))
1463 case float64:
1464 return fmax(x, y.(float64))
1465 }
1466
1467
1468 if binop(token.GTR, nil, y, x).(bool) {
1469 return y
1470 }
1471 return x
1472 }
1473
1474
1475
1476 type floaty interface{ ~float32 | ~float64 }
1477
1478 func fmin[F floaty](x, y F) F {
1479 if y != y || y < x {
1480 return y
1481 }
1482 if x != x || x < y || x != 0 {
1483 return x
1484 }
1485
1486
1487 return forbits(x, y)
1488 }
1489
1490 func fmax[F floaty](x, y F) F {
1491 if y != y || y > x {
1492 return y
1493 }
1494 if x != x || x > y || x != 0 {
1495 return x
1496 }
1497
1498
1499 return fandbits(x, y)
1500 }
1501
1502 func forbits[F floaty](x, y F) F {
1503 switch unsafe.Sizeof(x) {
1504 case 4:
1505 *(*uint32)(unsafe.Pointer(&x)) |= *(*uint32)(unsafe.Pointer(&y))
1506 case 8:
1507 *(*uint64)(unsafe.Pointer(&x)) |= *(*uint64)(unsafe.Pointer(&y))
1508 }
1509 return x
1510 }
1511
1512 func fandbits[F floaty](x, y F) F {
1513 switch unsafe.Sizeof(x) {
1514 case 4:
1515 *(*uint32)(unsafe.Pointer(&x)) &= *(*uint32)(unsafe.Pointer(&y))
1516 case 8:
1517 *(*uint64)(unsafe.Pointer(&x)) &= *(*uint64)(unsafe.Pointer(&y))
1518 }
1519 return x
1520 }
1521
View as plain text