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