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