github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gotools/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/token" 11 "strings" 12 "sync" 13 "unsafe" 14 15 "llvm.org/llgo/third_party/gotools/go/exact" 16 "llvm.org/llgo/third_party/gotools/go/ssa" 17 "llvm.org/llgo/third_party/gotools/go/types" 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 // callBuiltin interprets a call to builtin fn with arguments args, 935 // returning its result. 936 func callBuiltin(caller *frame, callpos token.Pos, fn *ssa.Builtin, args []value) value { 937 switch fn.Name() { 938 case "append": 939 if len(args) == 1 { 940 return args[0] 941 } 942 if s, ok := args[1].(string); ok { 943 // append([]byte, ...string) []byte 944 arg0 := args[0].([]value) 945 for i := 0; i < len(s); i++ { 946 arg0 = append(arg0, s[i]) 947 } 948 return arg0 949 } 950 // append([]T, ...[]T) []T 951 return append(args[0].([]value), args[1].([]value)...) 952 953 case "copy": // copy([]T, []T) int or copy([]byte, string) int 954 src := args[1] 955 if _, ok := src.(string); ok { 956 params := fn.Type().(*types.Signature).Params() 957 src = conv(params.At(0).Type(), params.At(1).Type(), src) 958 } 959 return copy(args[0].([]value), src.([]value)) 960 961 case "close": // close(chan T) 962 close(args[0].(chan value)) 963 return nil 964 965 case "delete": // delete(map[K]value, K) 966 switch m := args[0].(type) { 967 case map[value]value: 968 delete(m, args[1]) 969 case *hashmap: 970 m.delete(args[1].(hashable)) 971 default: 972 panic(fmt.Sprintf("illegal map type: %T", m)) 973 } 974 return nil 975 976 case "print", "println": // print(any, ...) 977 ln := fn.Name() == "println" 978 var buf bytes.Buffer 979 for i, arg := range args { 980 if i > 0 && ln { 981 buf.WriteRune(' ') 982 } 983 buf.WriteString(toString(arg)) 984 } 985 if ln { 986 buf.WriteRune('\n') 987 } 988 write(1, buf.Bytes()) 989 return nil 990 991 case "len": 992 switch x := args[0].(type) { 993 case string: 994 return len(x) 995 case array: 996 return len(x) 997 case *value: 998 return len((*x).(array)) 999 case []value: 1000 return len(x) 1001 case map[value]value: 1002 return len(x) 1003 case *hashmap: 1004 return x.len() 1005 case chan value: 1006 return len(x) 1007 default: 1008 panic(fmt.Sprintf("len: illegal operand: %T", x)) 1009 } 1010 1011 case "cap": 1012 switch x := args[0].(type) { 1013 case array: 1014 return cap(x) 1015 case *value: 1016 return cap((*x).(array)) 1017 case []value: 1018 return cap(x) 1019 case chan value: 1020 return cap(x) 1021 default: 1022 panic(fmt.Sprintf("cap: illegal operand: %T", x)) 1023 } 1024 1025 case "real": 1026 switch c := args[0].(type) { 1027 case complex64: 1028 return real(c) 1029 case complex128: 1030 return real(c) 1031 default: 1032 panic(fmt.Sprintf("real: illegal operand: %T", c)) 1033 } 1034 1035 case "imag": 1036 switch c := args[0].(type) { 1037 case complex64: 1038 return imag(c) 1039 case complex128: 1040 return imag(c) 1041 default: 1042 panic(fmt.Sprintf("imag: illegal operand: %T", c)) 1043 } 1044 1045 case "complex": 1046 switch f := args[0].(type) { 1047 case float32: 1048 return complex(f, args[1].(float32)) 1049 case float64: 1050 return complex(f, args[1].(float64)) 1051 default: 1052 panic(fmt.Sprintf("complex: illegal operand: %T", f)) 1053 } 1054 1055 case "panic": 1056 // ssa.Panic handles most cases; this is only for "go 1057 // panic" or "defer panic". 1058 panic(targetPanic{args[0]}) 1059 1060 case "recover": 1061 return doRecover(caller) 1062 1063 case "ssa:wrapnilchk": 1064 recv := args[0] 1065 if recv.(*value) == nil { 1066 recvType := args[1] 1067 methodName := args[2] 1068 panic(fmt.Sprintf("value method (%s).%s called using nil *%s pointer", 1069 recvType, methodName, recvType)) 1070 } 1071 return recv 1072 } 1073 1074 panic("unknown built-in: " + fn.Name()) 1075 } 1076 1077 func rangeIter(x value, t types.Type) iter { 1078 switch x := x.(type) { 1079 case map[value]value: 1080 // TODO(adonovan): fix: leaks goroutines and channels 1081 // on each incomplete map iteration. We need to open 1082 // up an iteration interface using the 1083 // reflect.(Value).MapKeys machinery. 1084 it := make(mapIter) 1085 go func() { 1086 for k, v := range x { 1087 it <- [2]value{k, v} 1088 } 1089 close(it) 1090 }() 1091 return it 1092 case *hashmap: 1093 // TODO(adonovan): fix: leaks goroutines and channels 1094 // on each incomplete map iteration. We need to open 1095 // up an iteration interface using the 1096 // reflect.(Value).MapKeys machinery. 1097 it := make(mapIter) 1098 go func() { 1099 for _, e := range x.table { 1100 for e != nil { 1101 it <- [2]value{e.key, e.value} 1102 e = e.next 1103 } 1104 } 1105 close(it) 1106 }() 1107 return it 1108 case string: 1109 return &stringIter{Reader: strings.NewReader(x)} 1110 } 1111 panic(fmt.Sprintf("cannot range over %T", x)) 1112 } 1113 1114 // widen widens a basic typed value x to the widest type of its 1115 // category, one of: 1116 // bool, int64, uint64, float64, complex128, string. 1117 // This is inefficient but reduces the size of the cross-product of 1118 // cases we have to consider. 1119 // 1120 func widen(x value) value { 1121 switch y := x.(type) { 1122 case bool, int64, uint64, float64, complex128, string, unsafe.Pointer: 1123 return x 1124 case int: 1125 return int64(y) 1126 case int8: 1127 return int64(y) 1128 case int16: 1129 return int64(y) 1130 case int32: 1131 return int64(y) 1132 case uint: 1133 return uint64(y) 1134 case uint8: 1135 return uint64(y) 1136 case uint16: 1137 return uint64(y) 1138 case uint32: 1139 return uint64(y) 1140 case uintptr: 1141 return uint64(y) 1142 case float32: 1143 return float64(y) 1144 case complex64: 1145 return complex128(y) 1146 } 1147 panic(fmt.Sprintf("cannot widen %T", x)) 1148 } 1149 1150 // conv converts the value x of type t_src to type t_dst and returns 1151 // the result. 1152 // Possible cases are described with the ssa.Convert operator. 1153 // 1154 func conv(t_dst, t_src types.Type, x value) value { 1155 ut_src := t_src.Underlying() 1156 ut_dst := t_dst.Underlying() 1157 1158 // Destination type is not an "untyped" type. 1159 if b, ok := ut_dst.(*types.Basic); ok && b.Info()&types.IsUntyped != 0 { 1160 panic("oops: conversion to 'untyped' type: " + b.String()) 1161 } 1162 1163 // Nor is it an interface type. 1164 if _, ok := ut_dst.(*types.Interface); ok { 1165 if _, ok := ut_src.(*types.Interface); ok { 1166 panic("oops: Convert should be ChangeInterface") 1167 } else { 1168 panic("oops: Convert should be MakeInterface") 1169 } 1170 } 1171 1172 // Remaining conversions: 1173 // + untyped string/number/bool constant to a specific 1174 // representation. 1175 // + conversions between non-complex numeric types. 1176 // + conversions between complex numeric types. 1177 // + integer/[]byte/[]rune -> string. 1178 // + string -> []byte/[]rune. 1179 // 1180 // All are treated the same: first we extract the value to the 1181 // widest representation (int64, uint64, float64, complex128, 1182 // or string), then we convert it to the desired type. 1183 1184 switch ut_src := ut_src.(type) { 1185 case *types.Pointer: 1186 switch ut_dst := ut_dst.(type) { 1187 case *types.Basic: 1188 // *value to unsafe.Pointer? 1189 if ut_dst.Kind() == types.UnsafePointer { 1190 return unsafe.Pointer(x.(*value)) 1191 } 1192 } 1193 1194 case *types.Slice: 1195 // []byte or []rune -> string 1196 // TODO(adonovan): fix: type B byte; conv([]B -> string). 1197 switch ut_src.Elem().(*types.Basic).Kind() { 1198 case types.Byte: 1199 x := x.([]value) 1200 b := make([]byte, 0, len(x)) 1201 for i := range x { 1202 b = append(b, x[i].(byte)) 1203 } 1204 return string(b) 1205 1206 case types.Rune: 1207 x := x.([]value) 1208 r := make([]rune, 0, len(x)) 1209 for i := range x { 1210 r = append(r, x[i].(rune)) 1211 } 1212 return string(r) 1213 } 1214 1215 case *types.Basic: 1216 x = widen(x) 1217 1218 // integer -> string? 1219 // TODO(adonovan): fix: test integer -> named alias of string. 1220 if ut_src.Info()&types.IsInteger != 0 { 1221 if ut_dst, ok := ut_dst.(*types.Basic); ok && ut_dst.Kind() == types.String { 1222 return string(asInt(x)) 1223 } 1224 } 1225 1226 // string -> []rune, []byte or string? 1227 if s, ok := x.(string); ok { 1228 switch ut_dst := ut_dst.(type) { 1229 case *types.Slice: 1230 var res []value 1231 // TODO(adonovan): fix: test named alias of rune, byte. 1232 switch ut_dst.Elem().(*types.Basic).Kind() { 1233 case types.Rune: 1234 for _, r := range []rune(s) { 1235 res = append(res, r) 1236 } 1237 return res 1238 case types.Byte: 1239 for _, b := range []byte(s) { 1240 res = append(res, b) 1241 } 1242 return res 1243 } 1244 case *types.Basic: 1245 if ut_dst.Kind() == types.String { 1246 return x.(string) 1247 } 1248 } 1249 break // fail: no other conversions for string 1250 } 1251 1252 // unsafe.Pointer -> *value 1253 if ut_src.Kind() == types.UnsafePointer { 1254 // TODO(adonovan): this is wrong and cannot 1255 // really be fixed with the current design. 1256 // 1257 // return (*value)(x.(unsafe.Pointer)) 1258 // creates a new pointer of a different 1259 // type but the underlying interface value 1260 // knows its "true" type and so cannot be 1261 // meaningfully used through the new pointer. 1262 // 1263 // To make this work, the interpreter needs to 1264 // simulate the memory layout of a real 1265 // compiled implementation. 1266 // 1267 // To at least preserve type-safety, we'll 1268 // just return the zero value of the 1269 // destination type. 1270 return zero(t_dst) 1271 } 1272 1273 // Conversions between complex numeric types? 1274 if ut_src.Info()&types.IsComplex != 0 { 1275 switch ut_dst.(*types.Basic).Kind() { 1276 case types.Complex64: 1277 return complex64(x.(complex128)) 1278 case types.Complex128: 1279 return x.(complex128) 1280 } 1281 break // fail: no other conversions for complex 1282 } 1283 1284 // Conversions between non-complex numeric types? 1285 if ut_src.Info()&types.IsNumeric != 0 { 1286 kind := ut_dst.(*types.Basic).Kind() 1287 switch x := x.(type) { 1288 case int64: // signed integer -> numeric? 1289 switch kind { 1290 case types.Int: 1291 return int(x) 1292 case types.Int8: 1293 return int8(x) 1294 case types.Int16: 1295 return int16(x) 1296 case types.Int32: 1297 return int32(x) 1298 case types.Int64: 1299 return int64(x) 1300 case types.Uint: 1301 return uint(x) 1302 case types.Uint8: 1303 return uint8(x) 1304 case types.Uint16: 1305 return uint16(x) 1306 case types.Uint32: 1307 return uint32(x) 1308 case types.Uint64: 1309 return uint64(x) 1310 case types.Uintptr: 1311 return uintptr(x) 1312 case types.Float32: 1313 return float32(x) 1314 case types.Float64: 1315 return float64(x) 1316 } 1317 1318 case uint64: // unsigned integer -> numeric? 1319 switch kind { 1320 case types.Int: 1321 return int(x) 1322 case types.Int8: 1323 return int8(x) 1324 case types.Int16: 1325 return int16(x) 1326 case types.Int32: 1327 return int32(x) 1328 case types.Int64: 1329 return int64(x) 1330 case types.Uint: 1331 return uint(x) 1332 case types.Uint8: 1333 return uint8(x) 1334 case types.Uint16: 1335 return uint16(x) 1336 case types.Uint32: 1337 return uint32(x) 1338 case types.Uint64: 1339 return uint64(x) 1340 case types.Uintptr: 1341 return uintptr(x) 1342 case types.Float32: 1343 return float32(x) 1344 case types.Float64: 1345 return float64(x) 1346 } 1347 1348 case float64: // floating point -> numeric? 1349 switch kind { 1350 case types.Int: 1351 return int(x) 1352 case types.Int8: 1353 return int8(x) 1354 case types.Int16: 1355 return int16(x) 1356 case types.Int32: 1357 return int32(x) 1358 case types.Int64: 1359 return int64(x) 1360 case types.Uint: 1361 return uint(x) 1362 case types.Uint8: 1363 return uint8(x) 1364 case types.Uint16: 1365 return uint16(x) 1366 case types.Uint32: 1367 return uint32(x) 1368 case types.Uint64: 1369 return uint64(x) 1370 case types.Uintptr: 1371 return uintptr(x) 1372 case types.Float32: 1373 return float32(x) 1374 case types.Float64: 1375 return float64(x) 1376 } 1377 } 1378 } 1379 } 1380 1381 panic(fmt.Sprintf("unsupported conversion: %s -> %s, dynamic type %T", t_src, t_dst, x)) 1382 } 1383 1384 // checkInterface checks that the method set of x implements the 1385 // interface itype. 1386 // On success it returns "", on failure, an error message. 1387 // 1388 func checkInterface(i *interpreter, itype *types.Interface, x iface) string { 1389 if meth, _ := types.MissingMethod(x.t, itype, true); meth != nil { 1390 return fmt.Sprintf("interface conversion: %v is not %v: missing method %s", 1391 x.t, itype, meth.Name()) 1392 } 1393 return "" // ok 1394 }