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