github.com/goplus/gossa@v0.3.25/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 gossa 6 7 import ( 8 "bytes" 9 "fmt" 10 "go/constant" 11 "go/token" 12 "go/types" 13 "reflect" 14 "strings" 15 "unsafe" 16 17 "github.com/goplus/reflectx" 18 "golang.org/x/tools/go/ssa" 19 ) 20 21 // If the target program panics, the interpreter panics with this type. 22 type targetPanic struct { 23 v value 24 } 25 26 func (p targetPanic) Error() string { 27 var buf bytes.Buffer 28 writeany(&buf, p.v) 29 return buf.String() 30 } 31 32 // If the target program calls exit, the interpreter panics with this type. 33 type exitPanic int 34 35 type goexitPanic int 36 37 func xtypeValue(c *ssa.Const, kind types.BasicKind) value { 38 switch kind { 39 case types.Bool, types.UntypedBool: 40 return constant.BoolVal(c.Value) 41 case types.Int, types.UntypedInt: 42 // Assume sizeof(int) is same on host and target. 43 return int(c.Int64()) 44 case types.Int8: 45 return int8(c.Int64()) 46 case types.Int16: 47 return int16(c.Int64()) 48 case types.Int32, types.UntypedRune: 49 return int32(c.Int64()) 50 case types.Int64: 51 return c.Int64() 52 case types.Uint: 53 // Assume sizeof(uint) is same on host and target. 54 return uint(c.Uint64()) 55 case types.Uint8: 56 return uint8(c.Uint64()) 57 case types.Uint16: 58 return uint16(c.Uint64()) 59 case types.Uint32: 60 return uint32(c.Uint64()) 61 case types.Uint64: 62 return c.Uint64() 63 case types.Uintptr: 64 // Assume sizeof(uintptr) is same on host and target. 65 return uintptr(c.Uint64()) 66 case types.Float32: 67 return float32(c.Float64()) 68 case types.Float64, types.UntypedFloat: 69 return c.Float64() 70 case types.Complex64: 71 return complex64(c.Complex128()) 72 case types.Complex128, types.UntypedComplex: 73 return c.Complex128() 74 case types.String, types.UntypedString: 75 if c.Value.Kind() == constant.String { 76 return constant.StringVal(c.Value) 77 } 78 return string(rune(c.Int64())) 79 case types.UnsafePointer: 80 return unsafe.Pointer(uintptr(c.Uint64())) 81 } 82 panic("unreachable") 83 } 84 85 // constValue returns the value of the constant with the 86 // dynamic type tag appropriate for c.Type(). 87 func constToValue(i *Interp, c *ssa.Const) value { 88 typ := c.Type() 89 if c.IsNil() { 90 if xtype, ok := typ.(*types.Basic); ok && xtype.Kind() == types.UntypedNil { 91 return nil 92 } 93 return reflect.Zero(i.preToType(typ)).Interface() 94 } 95 if xtype, ok := typ.(*types.Basic); ok { 96 return xtypeValue(c, xtype.Kind()) 97 } else if xtype, ok := typ.Underlying().(*types.Basic); ok { 98 v := xtypeValue(c, xtype.Kind()) 99 nv := reflect.New(i.preToType(typ)).Elem() 100 SetValue(nv, reflect.ValueOf(v)) 101 return nv.Interface() 102 } 103 panic(fmt.Sprintf("unparser constValue: %s", c)) 104 } 105 106 func globalToValue(i *Interp, key *ssa.Global) (interface{}, bool) { 107 if key.Pkg != nil { 108 pkgpath := key.Pkg.Pkg.Path() 109 if pkg, ok := i.installed(pkgpath); ok { 110 if ext, ok := pkg.Vars[key.Name()]; ok { 111 return ext.Interface(), true 112 } 113 } 114 } 115 if v, ok := i.globals[key]; ok { 116 return v, true 117 } 118 return nil, false 119 } 120 121 func staticToValue(i *Interp, value ssa.Value) (interface{}, bool) { 122 switch v := value.(type) { 123 case *ssa.Global: 124 return globalToValue(i, v) 125 case *ssa.Const: 126 return constToValue(i, v), true 127 } 128 return nil, false 129 } 130 131 // asInt converts x, which must be an integer, to an int suitable for 132 // use as a slice or array index or operand to make(). 133 func asInt(x value) int { 134 switch x := x.(type) { 135 case int: 136 return x 137 case int8: 138 return int(x) 139 case int16: 140 return int(x) 141 case int32: 142 return int(x) 143 case int64: 144 return int(x) 145 case uint: 146 return int(x) 147 case uint8: 148 return int(x) 149 case uint16: 150 return int(x) 151 case uint32: 152 return int(x) 153 case uint64: 154 return int(x) 155 case uintptr: 156 return int(x) 157 default: 158 v := reflect.ValueOf(x) 159 switch v.Kind() { 160 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 161 return int(v.Int()) 162 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 163 return int(v.Uint()) 164 } 165 } 166 panic(fmt.Sprintf("cannot convert %T to int", x)) 167 } 168 169 // asUint64 converts x, which must be an unsigned integer, to a uint64 170 // suitable for use as a bitwise shift count. 171 func asUint64(x value) uint64 { 172 switch x := x.(type) { 173 case int: 174 if x >= 0 { 175 return uint64(x) 176 } 177 case int8: 178 if x >= 0 { 179 return uint64(x) 180 } 181 case int16: 182 if x >= 0 { 183 return uint64(x) 184 } 185 case int32: 186 if x >= 0 { 187 return uint64(x) 188 } 189 case int64: 190 if x >= 0 { 191 return uint64(x) 192 } 193 case uint: 194 return uint64(x) 195 case uint8: 196 return uint64(x) 197 case uint16: 198 return uint64(x) 199 case uint32: 200 return uint64(x) 201 case uint64: 202 return x 203 case uintptr: 204 return uint64(x) 205 default: 206 v := reflect.ValueOf(x) 207 switch v.Kind() { 208 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 209 return v.Uint() 210 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 211 x := v.Int() 212 if x >= 0 { 213 return uint64(x) 214 } 215 default: 216 panic(fmt.Sprintf("cannot convert %T to uint64", x)) 217 } 218 } 219 panic(runtimeError("negative shift amount")) 220 } 221 222 // slice returns x[lo:hi:max]. Any of lo, hi and max may be nil. 223 func slice(fr *frame, instr *ssa.Slice, makesliceCheck bool, ix, ih, il, im register) reflect.Value { 224 // x := fr.get(instr.X) 225 x := fr.reg(ix) 226 var Len, Cap int 227 v := reflect.ValueOf(x) 228 // *array 229 if v.Kind() == reflect.Ptr { 230 v = v.Elem() 231 } 232 kind := v.Kind() 233 switch kind { 234 case reflect.String: 235 Len = v.Len() 236 Cap = Len 237 case reflect.Slice, reflect.Array: 238 Len = v.Len() 239 Cap = v.Cap() 240 } 241 242 lo := 0 243 hi := Len 244 max := Cap 245 var slice3 bool 246 if instr.Low != nil { 247 // lo = asInt(fr.get(instr.Low)) 248 lo = asInt(fr.reg(il)) 249 } 250 if instr.High != nil { 251 // hi = asInt(fr.get(instr.High)) 252 hi = asInt(fr.reg(ih)) 253 } 254 if instr.Max != nil { 255 // max = asInt(fr.get(instr.Max)) 256 max = asInt(fr.reg(im)) 257 slice3 = true 258 } 259 260 if makesliceCheck { 261 if hi < 0 { 262 panic(runtimeError("makeslice: len out of range")) 263 } else if hi > max { 264 panic(runtimeError("makeslice: cap out of range")) 265 } 266 } else { 267 if slice3 { 268 if max < 0 { 269 panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v]", max))) 270 } else if max > Cap { 271 if kind == reflect.Slice { 272 panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v] with capacity %v", max, Cap))) 273 } else { 274 panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v] with length %v", max, Cap))) 275 } 276 } else if hi < 0 { 277 panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v:]", hi))) 278 } else if hi > max { 279 panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v:%v]", hi, max))) 280 } else if lo < 0 { 281 panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v::]", lo))) 282 } else if lo > hi { 283 panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:%v:]", lo, hi))) 284 } 285 } else { 286 if hi < 0 { 287 panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v]", hi))) 288 } else if hi > Cap { 289 if kind == reflect.Slice { 290 panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v] with capacity %v", hi, Cap))) 291 } else { 292 panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v] with length %v", hi, Cap))) 293 } 294 } else if lo < 0 { 295 panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:]", lo))) 296 } else if lo > hi { 297 panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:%v]", lo, hi))) 298 } 299 } 300 } 301 switch kind { 302 case reflect.String: 303 // optimization x[len(x):], see $GOROOT/test/slicecap.go 304 if lo == hi { 305 return v.Slice(0, 0) 306 } 307 return v.Slice(lo, hi) 308 case reflect.Slice, reflect.Array: 309 return v.Slice3(lo, hi, max) 310 } 311 panic(fmt.Sprintf("slice: unexpected X type: %T", x)) 312 } 313 314 func opADD(x, y value) value { 315 switch x.(type) { 316 case int: 317 return x.(int) + y.(int) 318 case int8: 319 return x.(int8) + y.(int8) 320 case int16: 321 return x.(int16) + y.(int16) 322 case int32: 323 return x.(int32) + y.(int32) 324 case int64: 325 return x.(int64) + y.(int64) 326 case uint: 327 return x.(uint) + y.(uint) 328 case uint8: 329 return x.(uint8) + y.(uint8) 330 case uint16: 331 return x.(uint16) + y.(uint16) 332 case uint32: 333 return x.(uint32) + y.(uint32) 334 case uint64: 335 return x.(uint64) + y.(uint64) 336 case uintptr: 337 return x.(uintptr) + y.(uintptr) 338 case float32: 339 return x.(float32) + y.(float32) 340 case float64: 341 return x.(float64) + y.(float64) 342 case complex64: 343 return x.(complex64) + y.(complex64) 344 case complex128: 345 return x.(complex128) + y.(complex128) 346 case string: 347 return x.(string) + y.(string) 348 default: 349 vx := reflect.ValueOf(x) 350 vy := reflect.ValueOf(y) 351 if kind := vx.Kind(); kind == vy.Kind() { 352 r := reflect.New(vx.Type()).Elem() 353 switch kind { 354 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 355 r.SetInt(vx.Int() + vy.Int()) 356 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 357 r.SetUint(vx.Uint() + vy.Uint()) 358 case reflect.Float32, reflect.Float64: 359 r.SetFloat(vx.Float() + vy.Float()) 360 case reflect.Complex64, reflect.Complex128: 361 r.SetComplex(vx.Complex() + vy.Complex()) 362 case reflect.String: 363 r.SetString(vx.String() + vy.String()) 364 default: 365 goto failed 366 } 367 return r.Interface() 368 } 369 } 370 failed: 371 panic(fmt.Sprintf("invalid binary op: %T + %T", x, y)) 372 } 373 374 func opSUB(x, y value) value { 375 switch x.(type) { 376 case int: 377 return x.(int) - y.(int) 378 case int8: 379 return x.(int8) - y.(int8) 380 case int16: 381 return x.(int16) - y.(int16) 382 case int32: 383 return x.(int32) - y.(int32) 384 case int64: 385 return x.(int64) - y.(int64) 386 case uint: 387 return x.(uint) - y.(uint) 388 case uint8: 389 return x.(uint8) - y.(uint8) 390 case uint16: 391 return x.(uint16) - y.(uint16) 392 case uint32: 393 return x.(uint32) - y.(uint32) 394 case uint64: 395 return x.(uint64) - y.(uint64) 396 case uintptr: 397 return x.(uintptr) - y.(uintptr) 398 case float32: 399 return x.(float32) - y.(float32) 400 case float64: 401 return x.(float64) - y.(float64) 402 case complex64: 403 return x.(complex64) - y.(complex64) 404 case complex128: 405 return x.(complex128) - y.(complex128) 406 default: 407 vx := reflect.ValueOf(x) 408 vy := reflect.ValueOf(y) 409 if kind := vx.Kind(); kind == vy.Kind() { 410 r := reflect.New(vx.Type()).Elem() 411 switch kind { 412 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 413 r.SetInt(vx.Int() - vy.Int()) 414 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 415 r.SetUint(vx.Uint() - vy.Uint()) 416 case reflect.Float32, reflect.Float64: 417 r.SetFloat(vx.Float() - vy.Float()) 418 case reflect.Complex64, reflect.Complex128: 419 r.SetComplex(vx.Complex() - vy.Complex()) 420 default: 421 goto failed 422 } 423 return r.Interface() 424 } 425 } 426 failed: 427 panic(fmt.Sprintf("invalid binary op: %T - %T", x, y)) 428 } 429 430 func opMUL(x, y value) value { 431 switch x.(type) { 432 case int: 433 return x.(int) * y.(int) 434 case int8: 435 return x.(int8) * y.(int8) 436 case int16: 437 return x.(int16) * y.(int16) 438 case int32: 439 return x.(int32) * y.(int32) 440 case int64: 441 return x.(int64) * y.(int64) 442 case uint: 443 return x.(uint) * y.(uint) 444 case uint8: 445 return x.(uint8) * y.(uint8) 446 case uint16: 447 return x.(uint16) * y.(uint16) 448 case uint32: 449 return x.(uint32) * y.(uint32) 450 case uint64: 451 return x.(uint64) * y.(uint64) 452 case uintptr: 453 return x.(uintptr) * y.(uintptr) 454 case float32: 455 return x.(float32) * y.(float32) 456 case float64: 457 return x.(float64) * y.(float64) 458 case complex64: 459 return x.(complex64) * y.(complex64) 460 case complex128: 461 return x.(complex128) * y.(complex128) 462 default: 463 vx := reflect.ValueOf(x) 464 vy := reflect.ValueOf(y) 465 if kind := vx.Kind(); kind == vy.Kind() { 466 r := reflect.New(vx.Type()).Elem() 467 switch kind { 468 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 469 r.SetInt(vx.Int() * vy.Int()) 470 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 471 r.SetUint(vx.Uint() * vy.Uint()) 472 case reflect.Float32, reflect.Float64: 473 r.SetFloat(vx.Float() * vy.Float()) 474 case reflect.Complex64, reflect.Complex128: 475 r.SetComplex(vx.Complex() * vy.Complex()) 476 default: 477 goto failed 478 } 479 return r.Interface() 480 } 481 } 482 failed: 483 panic(fmt.Sprintf("invalid binary op: %T * %T", x, y)) 484 } 485 486 func opQuo(x, y value) value { 487 switch x.(type) { 488 case int: 489 return x.(int) / y.(int) 490 case int8: 491 return x.(int8) / y.(int8) 492 case int16: 493 return x.(int16) / y.(int16) 494 case int32: 495 return x.(int32) / y.(int32) 496 case int64: 497 return x.(int64) / y.(int64) 498 case uint: 499 return x.(uint) / y.(uint) 500 case uint8: 501 return x.(uint8) / y.(uint8) 502 case uint16: 503 return x.(uint16) / y.(uint16) 504 case uint32: 505 return x.(uint32) / y.(uint32) 506 case uint64: 507 return x.(uint64) / y.(uint64) 508 case uintptr: 509 return x.(uintptr) / y.(uintptr) 510 case float32: 511 return x.(float32) / y.(float32) 512 case float64: 513 return x.(float64) / y.(float64) 514 case complex64: 515 return x.(complex64) / y.(complex64) 516 case complex128: 517 return x.(complex128) / y.(complex128) 518 default: 519 vx := reflect.ValueOf(x) 520 vy := reflect.ValueOf(y) 521 if kind := vx.Kind(); kind == vy.Kind() { 522 r := reflect.New(vx.Type()).Elem() 523 switch kind { 524 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 525 r.SetInt(vx.Int() / vy.Int()) 526 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 527 r.SetUint(vx.Uint() / vy.Uint()) 528 case reflect.Float32, reflect.Float64: 529 r.SetFloat(vx.Float() / vy.Float()) 530 case reflect.Complex64, reflect.Complex128: 531 r.SetComplex(vx.Complex() / vy.Complex()) 532 default: 533 goto failed 534 } 535 return r.Interface() 536 } 537 } 538 failed: 539 panic(fmt.Sprintf("invalid binary op: %T / %T", x, y)) 540 } 541 542 func opREM(x, y value) value { 543 switch x.(type) { 544 case int: 545 return x.(int) % y.(int) 546 case int8: 547 return x.(int8) % y.(int8) 548 case int16: 549 return x.(int16) % y.(int16) 550 case int32: 551 return x.(int32) % y.(int32) 552 case int64: 553 return x.(int64) % y.(int64) 554 case uint: 555 return x.(uint) % y.(uint) 556 case uint8: 557 return x.(uint8) % y.(uint8) 558 case uint16: 559 return x.(uint16) % y.(uint16) 560 case uint32: 561 return x.(uint32) % y.(uint32) 562 case uint64: 563 return x.(uint64) % y.(uint64) 564 case uintptr: 565 return x.(uintptr) % y.(uintptr) 566 default: 567 vx := reflect.ValueOf(x) 568 vy := reflect.ValueOf(y) 569 if kind := vx.Kind(); kind == vy.Kind() { 570 r := reflect.New(vx.Type()).Elem() 571 switch kind { 572 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 573 r.SetInt(vx.Int() % vy.Int()) 574 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 575 r.SetUint(vx.Uint() % vy.Uint()) 576 default: 577 goto failed 578 } 579 return r.Interface() 580 } 581 } 582 failed: 583 panic(fmt.Sprintf("invalid binary op: %T %% %T", x, y)) 584 } 585 586 func opAND(x, y value) value { 587 switch x.(type) { 588 case int: 589 return x.(int) & y.(int) 590 case int8: 591 return x.(int8) & y.(int8) 592 case int16: 593 return x.(int16) & y.(int16) 594 case int32: 595 return x.(int32) & y.(int32) 596 case int64: 597 return x.(int64) & y.(int64) 598 case uint: 599 return x.(uint) & y.(uint) 600 case uint8: 601 return x.(uint8) & y.(uint8) 602 case uint16: 603 return x.(uint16) & y.(uint16) 604 case uint32: 605 return x.(uint32) & y.(uint32) 606 case uint64: 607 return x.(uint64) & y.(uint64) 608 case uintptr: 609 return x.(uintptr) & y.(uintptr) 610 default: 611 vx := reflect.ValueOf(x) 612 vy := reflect.ValueOf(y) 613 if kind := vx.Kind(); kind == vy.Kind() { 614 r := reflect.New(vx.Type()).Elem() 615 switch kind { 616 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 617 r.SetInt(vx.Int() & vy.Int()) 618 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 619 r.SetUint(vx.Uint() & vy.Uint()) 620 default: 621 goto failed 622 } 623 return r.Interface() 624 } 625 } 626 failed: 627 panic(fmt.Sprintf("invalid binary op: %T && %T", x, y)) 628 } 629 630 func opOR(x, y value) value { 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 default: 655 vx := reflect.ValueOf(x) 656 vy := reflect.ValueOf(y) 657 if kind := vx.Kind(); kind == vy.Kind() { 658 r := reflect.New(vx.Type()).Elem() 659 switch kind { 660 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 661 r.SetInt(vx.Int() | vy.Int()) 662 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 663 r.SetUint(vx.Uint() | vy.Uint()) 664 default: 665 goto failed 666 } 667 return r.Interface() 668 } 669 } 670 failed: 671 panic(fmt.Sprintf("invalid binary op: %T | %T", x, y)) 672 } 673 674 func opXOR(x, y value) value { 675 switch x.(type) { 676 case int: 677 return x.(int) ^ y.(int) 678 case int8: 679 return x.(int8) ^ y.(int8) 680 case int16: 681 return x.(int16) ^ y.(int16) 682 case int32: 683 return x.(int32) ^ y.(int32) 684 case int64: 685 return x.(int64) ^ y.(int64) 686 case uint: 687 return x.(uint) ^ y.(uint) 688 case uint8: 689 return x.(uint8) ^ y.(uint8) 690 case uint16: 691 return x.(uint16) ^ y.(uint16) 692 case uint32: 693 return x.(uint32) ^ y.(uint32) 694 case uint64: 695 return x.(uint64) ^ y.(uint64) 696 case uintptr: 697 return x.(uintptr) ^ y.(uintptr) 698 default: 699 vx := reflect.ValueOf(x) 700 vy := reflect.ValueOf(y) 701 if kind := vx.Kind(); kind == vy.Kind() { 702 r := reflect.New(vx.Type()).Elem() 703 switch kind { 704 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 705 r.SetInt(vx.Int() ^ vy.Int()) 706 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 707 r.SetUint(vx.Uint() ^ vy.Uint()) 708 default: 709 goto failed 710 } 711 return r.Interface() 712 } 713 } 714 failed: 715 panic(fmt.Sprintf("invalid binary op: %T ^ %T", x, y)) 716 } 717 718 func opANDNOT(x, y value) value { 719 switch x.(type) { 720 case int: 721 return x.(int) &^ y.(int) 722 case int8: 723 return x.(int8) &^ y.(int8) 724 case int16: 725 return x.(int16) &^ y.(int16) 726 case int32: 727 return x.(int32) &^ y.(int32) 728 case int64: 729 return x.(int64) &^ y.(int64) 730 case uint: 731 return x.(uint) &^ y.(uint) 732 case uint8: 733 return x.(uint8) &^ y.(uint8) 734 case uint16: 735 return x.(uint16) &^ y.(uint16) 736 case uint32: 737 return x.(uint32) &^ y.(uint32) 738 case uint64: 739 return x.(uint64) &^ y.(uint64) 740 case uintptr: 741 return x.(uintptr) &^ y.(uintptr) 742 default: 743 vx := reflect.ValueOf(x) 744 vy := reflect.ValueOf(y) 745 if kind := vx.Kind(); kind == vy.Kind() { 746 r := reflect.New(vx.Type()).Elem() 747 switch kind { 748 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 749 r.SetInt(vx.Int() &^ vy.Int()) 750 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 751 r.SetUint(vx.Uint() &^ vy.Uint()) 752 default: 753 goto failed 754 } 755 return r.Interface() 756 } 757 } 758 failed: 759 panic(fmt.Sprintf("invalid binary op: %T &^ %T", x, y)) 760 } 761 762 func opSHL(x, _y value) value { 763 y := asUint64(_y) 764 switch x.(type) { 765 case int: 766 return x.(int) << y 767 case int8: 768 return x.(int8) << y 769 case int16: 770 return x.(int16) << y 771 case int32: 772 return x.(int32) << y 773 case int64: 774 return x.(int64) << y 775 case uint: 776 return x.(uint) << y 777 case uint8: 778 return x.(uint8) << y 779 case uint16: 780 return x.(uint16) << y 781 case uint32: 782 return x.(uint32) << y 783 case uint64: 784 return x.(uint64) << y 785 case uintptr: 786 return x.(uintptr) << y 787 default: 788 vx := reflect.ValueOf(x) 789 r := reflect.New(vx.Type()).Elem() 790 switch vx.Kind() { 791 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 792 r.SetInt(vx.Int() << y) 793 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 794 r.SetUint(vx.Uint() << y) 795 default: 796 goto failed 797 } 798 return r.Interface() 799 } 800 failed: 801 panic(fmt.Sprintf("invalid binary op: %T << %T", x, y)) 802 } 803 804 func opSHR(x, _y value) value { 805 y := asUint64(_y) 806 switch x.(type) { 807 case int: 808 return x.(int) >> y 809 case int8: 810 return x.(int8) >> y 811 case int16: 812 return x.(int16) >> y 813 case int32: 814 return x.(int32) >> y 815 case int64: 816 return x.(int64) >> y 817 case uint: 818 return x.(uint) >> y 819 case uint8: 820 return x.(uint8) >> y 821 case uint16: 822 return x.(uint16) >> y 823 case uint32: 824 return x.(uint32) >> y 825 case uint64: 826 return x.(uint64) >> y 827 case uintptr: 828 return x.(uintptr) >> y 829 default: 830 vx := reflect.ValueOf(x) 831 r := reflect.New(vx.Type()).Elem() 832 switch vx.Kind() { 833 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 834 r.SetInt(vx.Int() >> y) 835 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 836 r.SetUint(vx.Uint() >> y) 837 default: 838 goto failed 839 } 840 return r.Interface() 841 } 842 failed: 843 panic(fmt.Sprintf("invalid binary op: %T >> %T", x, y)) 844 } 845 846 func opLSS(x, y value) value { 847 switch x.(type) { 848 case int: 849 return x.(int) < y.(int) 850 case int8: 851 return x.(int8) < y.(int8) 852 case int16: 853 return x.(int16) < y.(int16) 854 case int32: 855 return x.(int32) < y.(int32) 856 case int64: 857 return x.(int64) < y.(int64) 858 case uint: 859 return x.(uint) < y.(uint) 860 case uint8: 861 return x.(uint8) < y.(uint8) 862 case uint16: 863 return x.(uint16) < y.(uint16) 864 case uint32: 865 return x.(uint32) < y.(uint32) 866 case uint64: 867 return x.(uint64) < y.(uint64) 868 case uintptr: 869 return x.(uintptr) < y.(uintptr) 870 case float32: 871 return x.(float32) < y.(float32) 872 case float64: 873 return x.(float64) < y.(float64) 874 case string: 875 return x.(string) < y.(string) 876 default: 877 vx := reflect.ValueOf(x) 878 vy := reflect.ValueOf(y) 879 if kind := vx.Kind(); kind == vy.Kind() { 880 switch kind { 881 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 882 return vx.Int() < vy.Int() 883 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 884 return vx.Uint() < vy.Uint() 885 case reflect.Float32, reflect.Float64: 886 return vx.Float() < vy.Float() 887 case reflect.String: 888 return vx.String() < vy.String() 889 default: 890 goto failed 891 } 892 } 893 } 894 failed: 895 panic(fmt.Sprintf("invalid binary op: %T < %T", x, y)) 896 } 897 898 func opLEQ(x, y value) value { 899 switch x.(type) { 900 case int: 901 return x.(int) <= y.(int) 902 case int8: 903 return x.(int8) <= y.(int8) 904 case int16: 905 return x.(int16) <= y.(int16) 906 case int32: 907 return x.(int32) <= y.(int32) 908 case int64: 909 return x.(int64) <= y.(int64) 910 case uint: 911 return x.(uint) <= y.(uint) 912 case uint8: 913 return x.(uint8) <= y.(uint8) 914 case uint16: 915 return x.(uint16) <= y.(uint16) 916 case uint32: 917 return x.(uint32) <= y.(uint32) 918 case uint64: 919 return x.(uint64) <= y.(uint64) 920 case uintptr: 921 return x.(uintptr) <= y.(uintptr) 922 case float32: 923 return x.(float32) <= y.(float32) 924 case float64: 925 return x.(float64) <= y.(float64) 926 case string: 927 return x.(string) <= y.(string) 928 default: 929 vx := reflect.ValueOf(x) 930 vy := reflect.ValueOf(y) 931 if kind := vx.Kind(); kind == vy.Kind() { 932 switch kind { 933 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 934 return vx.Int() <= vy.Int() 935 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 936 return vx.Uint() <= vy.Uint() 937 case reflect.Float32, reflect.Float64: 938 return vx.Float() <= vy.Float() 939 case reflect.String: 940 return vx.String() <= vy.String() 941 default: 942 goto failed 943 } 944 } 945 } 946 failed: 947 panic(fmt.Sprintf("invalid binary op: %T <= %T", x, y)) 948 } 949 950 func opGTR(x, y value) value { 951 switch x.(type) { 952 case int: 953 return x.(int) > y.(int) 954 case int8: 955 return x.(int8) > y.(int8) 956 case int16: 957 return x.(int16) > y.(int16) 958 case int32: 959 return x.(int32) > y.(int32) 960 case int64: 961 return x.(int64) > y.(int64) 962 case uint: 963 return x.(uint) > y.(uint) 964 case uint8: 965 return x.(uint8) > y.(uint8) 966 case uint16: 967 return x.(uint16) > y.(uint16) 968 case uint32: 969 return x.(uint32) > y.(uint32) 970 case uint64: 971 return x.(uint64) > y.(uint64) 972 case uintptr: 973 return x.(uintptr) > y.(uintptr) 974 case float32: 975 return x.(float32) > y.(float32) 976 case float64: 977 return x.(float64) > y.(float64) 978 case string: 979 return x.(string) > y.(string) 980 default: 981 vx := reflect.ValueOf(x) 982 vy := reflect.ValueOf(y) 983 if kind := vx.Kind(); kind == vy.Kind() { 984 switch kind { 985 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 986 return vx.Int() > vy.Int() 987 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 988 return vx.Uint() > vy.Uint() 989 case reflect.Float32, reflect.Float64: 990 return vx.Float() > vy.Float() 991 case reflect.String: 992 return vx.String() > vy.String() 993 default: 994 goto failed 995 } 996 } 997 } 998 failed: 999 panic(fmt.Sprintf("invalid binary op: %T > %T", x, y)) 1000 } 1001 1002 func opGEQ(x, y value) value { 1003 switch x.(type) { 1004 case int: 1005 return x.(int) >= y.(int) 1006 case int8: 1007 return x.(int8) >= y.(int8) 1008 case int16: 1009 return x.(int16) >= y.(int16) 1010 case int32: 1011 return x.(int32) >= y.(int32) 1012 case int64: 1013 return x.(int64) >= y.(int64) 1014 case uint: 1015 return x.(uint) >= y.(uint) 1016 case uint8: 1017 return x.(uint8) >= y.(uint8) 1018 case uint16: 1019 return x.(uint16) >= y.(uint16) 1020 case uint32: 1021 return x.(uint32) >= y.(uint32) 1022 case uint64: 1023 return x.(uint64) >= y.(uint64) 1024 case uintptr: 1025 return x.(uintptr) >= y.(uintptr) 1026 case float32: 1027 return x.(float32) >= y.(float32) 1028 case float64: 1029 return x.(float64) >= y.(float64) 1030 case string: 1031 return x.(string) >= y.(string) 1032 default: 1033 vx := reflect.ValueOf(x) 1034 vy := reflect.ValueOf(y) 1035 if kind := vx.Kind(); kind == vy.Kind() { 1036 switch kind { 1037 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1038 return vx.Int() >= vy.Int() 1039 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1040 return vx.Uint() >= vy.Uint() 1041 case reflect.Float32, reflect.Float64: 1042 return vx.Float() >= vy.Float() 1043 case reflect.String: 1044 return vx.String() >= vy.String() 1045 default: 1046 goto failed 1047 } 1048 } 1049 } 1050 failed: 1051 panic(fmt.Sprintf("invalid binary op: %T >= %T", x, y)) 1052 } 1053 1054 // binop implements all arithmetic and logical binary operators for 1055 // numeric datatypes and strings. Both operands must have identical 1056 // dynamic type. 1057 // 1058 func binop(instr *ssa.BinOp, t types.Type, x, y value) value { 1059 switch instr.Op { 1060 case token.ADD: 1061 return opADD(x, y) 1062 case token.SUB: 1063 return opSUB(x, y) 1064 case token.MUL: 1065 return opMUL(x, y) 1066 case token.QUO: 1067 return opQuo(x, y) 1068 case token.REM: 1069 return opREM(x, y) 1070 case token.AND: 1071 return opAND(x, y) 1072 case token.OR: 1073 return opOR(x, y) 1074 case token.XOR: 1075 return opXOR(x, y) 1076 case token.AND_NOT: 1077 return opANDNOT(x, y) 1078 case token.SHL: 1079 return opSHL(x, y) 1080 case token.SHR: 1081 return opSHR(x, y) 1082 case token.LSS: 1083 return opLSS(x, y) 1084 case token.LEQ: 1085 return opLEQ(x, y) 1086 case token.EQL: 1087 return opEQL(instr, x, y) 1088 case token.NEQ: 1089 return !opEQL(instr, x, y) 1090 case token.GTR: 1091 return opGTR(x, y) 1092 case token.GEQ: 1093 return opGEQ(x, y) 1094 } 1095 panic(fmt.Sprintf("invalid binary op: %T %s %T", x, instr.Op, y)) 1096 } 1097 1098 func IsConstNil(v ssa.Value) bool { 1099 switch c := v.(type) { 1100 case *ssa.Const: 1101 return c.IsNil() 1102 } 1103 return false 1104 } 1105 1106 func IsNil(v reflect.Value) bool { 1107 switch v.Kind() { 1108 case reflect.Invalid: 1109 return true 1110 case reflect.Slice, reflect.Map, reflect.Func: 1111 return v.IsNil() 1112 case reflect.Chan, reflect.Ptr, reflect.UnsafePointer, reflect.Interface: 1113 return v.IsNil() 1114 default: 1115 return false 1116 } 1117 } 1118 1119 func opEQL(instr *ssa.BinOp, x, y interface{}) bool { 1120 vx := reflect.ValueOf(x) 1121 vy := reflect.ValueOf(y) 1122 if vx.Kind() != vy.Kind() { 1123 return false 1124 } 1125 if IsConstNil(instr.X) { 1126 return IsNil(vy) 1127 } else if IsConstNil(instr.Y) { 1128 return IsNil(vx) 1129 } 1130 return equalValue(vx, vy) 1131 } 1132 1133 func equalNil(vx, vy reflect.Value) bool { 1134 if IsNil(vx) { 1135 return IsNil(vy) 1136 } else if IsNil(vy) { 1137 return IsNil(vx) 1138 } 1139 return equalValue(vx, vy) 1140 } 1141 1142 func equalValue(vx, vy reflect.Value) bool { 1143 if kind := vx.Kind(); kind == vy.Kind() { 1144 switch kind { 1145 case reflect.Invalid: 1146 return true 1147 case reflect.Chan: 1148 dirx := vx.Type().ChanDir() 1149 diry := vy.Type().ChanDir() 1150 if dirx != diry { 1151 if dirx == reflect.BothDir { 1152 return vy.Interface() == vx.Convert(vy.Type()).Interface() 1153 } else if diry == reflect.BothDir { 1154 return vx.Interface() == vy.Convert(vx.Type()).Interface() 1155 } 1156 } else { 1157 return vx.Interface() == vy.Interface() 1158 } 1159 case reflect.Ptr: 1160 return vx.Pointer() == vy.Pointer() 1161 case reflect.Struct: 1162 return equalStruct(vx, vy) 1163 case reflect.Array: 1164 return equalArray(vx, vy) 1165 default: 1166 return vx.Interface() == vy.Interface() 1167 } 1168 } 1169 return false 1170 } 1171 1172 func equalArray(vx, vy reflect.Value) bool { 1173 xlen := vx.Len() 1174 if xlen != vy.Len() { 1175 return false 1176 } 1177 if vx.Type().Elem() != vy.Type().Elem() { 1178 return false 1179 } 1180 for i := 0; i < xlen; i++ { 1181 fx := vx.Index(i) 1182 fy := vy.Index(i) 1183 if !equalNil(fx, fy) { 1184 return false 1185 } 1186 } 1187 return true 1188 } 1189 1190 func equalStruct(vx, vy reflect.Value) bool { 1191 typ := vx.Type() 1192 if typ != vy.Type() { 1193 return false 1194 } 1195 n := typ.NumField() 1196 for i := 0; i < n; i++ { 1197 f := typ.Field(i) 1198 if f.Name == "_" { 1199 continue 1200 } 1201 fx := reflectx.FieldByIndexX(vx, f.Index) 1202 fy := reflectx.FieldByIndexX(vy, f.Index) 1203 // check uncomparable 1204 switch f.Type.Kind() { 1205 case reflect.Slice, reflect.Map, reflect.Func: 1206 if fx.Interface() != fy.Interface() { 1207 return false 1208 } 1209 } 1210 if !equalNil(fx, fy) { 1211 return false 1212 } 1213 } 1214 return true 1215 } 1216 1217 func unop(instr *ssa.UnOp, x value) value { 1218 switch instr.Op { 1219 case token.ARROW: // receive 1220 vx := reflect.ValueOf(x) 1221 v, ok := vx.Recv() 1222 if !ok { 1223 v = reflect.New(vx.Type().Elem()).Elem() 1224 } 1225 if instr.CommaOk { 1226 return tuple{v.Interface(), ok} 1227 } 1228 return v.Interface() 1229 // if !ok { 1230 // v = zero(instr.X.Type().Underlying().(*types.Chan).Elem()) 1231 // } 1232 // if instr.CommaOk { 1233 // v = tuple{v, ok} 1234 // } 1235 // return v 1236 case token.SUB: 1237 switch x := x.(type) { 1238 case int: 1239 return -x 1240 case int8: 1241 return -x 1242 case int16: 1243 return -x 1244 case int32: 1245 return -x 1246 case int64: 1247 return -x 1248 case uint: 1249 return -x 1250 case uint8: 1251 return -x 1252 case uint16: 1253 return -x 1254 case uint32: 1255 return -x 1256 case uint64: 1257 return -x 1258 case uintptr: 1259 return -x 1260 case float32: 1261 return -x 1262 case float64: 1263 return -x 1264 case complex64: 1265 return -x 1266 case complex128: 1267 return -x 1268 default: 1269 v := reflect.ValueOf(x) 1270 r := reflect.New(v.Type()).Elem() 1271 switch v.Kind() { 1272 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1273 r.SetInt(-v.Int()) 1274 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1275 r.SetUint(-v.Uint()) 1276 case reflect.Float32, reflect.Float64: 1277 r.SetFloat(-v.Float()) 1278 case reflect.Complex64, reflect.Complex128: 1279 r.SetComplex(-v.Complex()) 1280 } 1281 return r.Interface() 1282 } 1283 case token.MUL: 1284 v := reflect.ValueOf(x).Elem() 1285 if !v.IsValid() { 1286 panic(runtimeError("invalid memory address or nil pointer dereference")) 1287 } 1288 return v.Interface() 1289 //return load(deref(instr.X.Type()), x.(*value)) 1290 case token.NOT: 1291 switch x := x.(type) { 1292 case bool: 1293 return !x 1294 default: 1295 v := reflect.ValueOf(x) 1296 if v.Kind() == reflect.Bool { 1297 r := reflect.New(v.Type()).Elem() 1298 if v.Bool() { 1299 return v.Interface() 1300 } 1301 r.SetBool(true) 1302 return r.Interface() 1303 } 1304 } 1305 // return !x.(bool) 1306 case token.XOR: 1307 switch x := x.(type) { 1308 case int: 1309 return ^x 1310 case int8: 1311 return ^x 1312 case int16: 1313 return ^x 1314 case int32: 1315 return ^x 1316 case int64: 1317 return ^x 1318 case uint: 1319 return ^x 1320 case uint8: 1321 return ^x 1322 case uint16: 1323 return ^x 1324 case uint32: 1325 return ^x 1326 case uint64: 1327 return ^x 1328 case uintptr: 1329 return ^x 1330 default: 1331 vx := reflect.ValueOf(x) 1332 r := reflect.New(vx.Type()).Elem() 1333 switch vx.Kind() { 1334 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1335 r.SetInt(^r.Int()) 1336 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1337 r.SetUint(^r.Uint()) 1338 default: 1339 goto failed 1340 } 1341 return r.Interface() 1342 } 1343 } 1344 failed: 1345 panic(fmt.Sprintf("invalid unary op %s %T", instr.Op, x)) 1346 } 1347 1348 // typeAssert checks whether dynamic type of itf is instr.AssertedType. 1349 // It returns the extracted value on success, and panics on failure, 1350 // unless instr.CommaOk, in which case it always returns a "value,ok" tuple. 1351 // 1352 func typeAssert(i *Interp, instr *ssa.TypeAssert, typ reflect.Type, iv interface{}) value { 1353 var v value 1354 var err error 1355 if iv == nil { 1356 err = plainError(fmt.Sprintf("interface conversion: interface is nil, not %v", typ)) 1357 } else { 1358 rv := reflect.ValueOf(iv) 1359 rt := rv.Type() 1360 if typ == rt { 1361 v = iv 1362 } else { 1363 if !rt.AssignableTo(typ) { 1364 err = runtimeError(fmt.Sprintf("interface conversion: %v is %v, not %v", instr.X.Type(), rt, typ)) 1365 if itype, ok := instr.AssertedType.Underlying().(*types.Interface); ok { 1366 if it, ok := i.findType(rt, false); ok { 1367 if meth, _ := types.MissingMethod(it, itype, true); meth != nil { 1368 err = runtimeError(fmt.Sprintf("interface conversion: %v is not %v: missing method %s", 1369 rt, instr.AssertedType, meth.Name())) 1370 } 1371 } 1372 } else if typ.PkgPath() == rt.PkgPath() && typ.Name() == rt.Name() { 1373 t1, ok1 := i.findType(typ, false) 1374 t2, ok2 := i.findType(rt, false) 1375 if ok1 && ok2 { 1376 n1, ok1 := t1.(*types.Named) 1377 n2, ok2 := t2.(*types.Named) 1378 if ok1 && ok2 && n1.Obj().Parent() != n2.Obj().Parent() { 1379 err = runtimeError(fmt.Sprintf("interface conversion: %v is %v, not %v (types from different scopes)", instr.X.Type(), rt, typ)) 1380 } 1381 } 1382 } 1383 } else { 1384 v = rv.Convert(typ).Interface() 1385 } 1386 } 1387 } 1388 if err != nil { 1389 if !instr.CommaOk { 1390 panic(err) 1391 } 1392 return tuple{reflect.New(typ).Elem().Interface(), false} 1393 } 1394 if instr.CommaOk { 1395 return tuple{v, true} 1396 } 1397 return v 1398 // err := "" 1399 // if itf.t == nil { 1400 // err = fmt.Sprintf("interface conversion: interface is nil, not %s", instr.AssertedType) 1401 1402 // } else if idst, ok := instr.AssertedType.Underlying().(*types.Interface); ok { 1403 // v = itf 1404 // err = checkInterface(i, idst, itf) 1405 1406 // } else if types.Identical(itf.t, instr.AssertedType) { 1407 // v = itf.v // extract value 1408 1409 // } else { 1410 // err = fmt.Sprintf("interface conversion: interface is %s, not %s", itf.t, instr.AssertedType) 1411 // } 1412 1413 // if err != "" { 1414 // if !instr.CommaOk { 1415 // panic(err) 1416 // } 1417 // return tuple{zero(instr.AssertedType), false} 1418 // } 1419 // if instr.CommaOk { 1420 // return tuple{v, true} 1421 // } 1422 // return v 1423 } 1424 1425 // callBuiltin interprets a call to builtin fn with arguments args, 1426 // returning its result. 1427 func (inter *Interp) callBuiltin(caller *frame, fn *ssa.Builtin, args []value, ssaArgs []ssa.Value) value { 1428 switch fnName := fn.Name(); fnName { 1429 case "append": 1430 if len(args) == 1 { 1431 return args[0] 1432 } 1433 if s, ok := args[1].(string); ok { 1434 // append([]byte, ...string) []byte 1435 args[1] = []byte(s) 1436 } 1437 v0 := reflect.ValueOf(args[0]) 1438 v1 := reflect.ValueOf(args[1]) 1439 i0 := v0.Len() 1440 i1 := v1.Len() 1441 if i0+i1 < i0 { 1442 panic(runtimeError("growslice: cap out of range")) 1443 } 1444 return reflect.AppendSlice(v0, v1).Interface() 1445 1446 case "copy": // copy([]T, []T) int or copy([]byte, string) int 1447 return reflect.Copy(reflect.ValueOf(args[0]), reflect.ValueOf(args[1])) 1448 1449 case "close": // close(chan T) 1450 reflect.ValueOf(args[0]).Close() 1451 return nil 1452 1453 case "delete": // delete(map[K]value, K) 1454 reflect.ValueOf(args[0]).SetMapIndex(reflect.ValueOf(args[1]), reflect.Value{}) 1455 return nil 1456 1457 case "print", "println": // print(any, ...) 1458 ln := fn.Name() == "println" 1459 var buf bytes.Buffer 1460 for i, arg := range args { 1461 if i > 0 && ln { 1462 buf.WriteRune(' ') 1463 } 1464 if len(ssaArgs) > i { 1465 typ := inter.toType(ssaArgs[i].Type()) 1466 if typ.Kind() == reflect.Interface { 1467 writeinterface(&buf, arg) 1468 continue 1469 } 1470 } 1471 writevalue(&buf, arg, inter.mode&EnablePrintAny != 0) 1472 } 1473 if ln { 1474 buf.WriteRune('\n') 1475 } 1476 inter.ctx.writeOutput(buf.Bytes()) 1477 return nil 1478 1479 case "len": 1480 return reflect.ValueOf(args[0]).Len() 1481 1482 case "cap": 1483 return reflect.ValueOf(args[0]).Cap() 1484 1485 case "real": 1486 c := reflect.ValueOf(args[0]) 1487 switch c.Kind() { 1488 case reflect.Complex64: 1489 return real(complex64(c.Complex())) 1490 case reflect.Complex128: 1491 return real(c.Complex()) 1492 default: 1493 panic(fmt.Sprintf("real: illegal operand: %T", c)) 1494 } 1495 1496 case "imag": 1497 c := reflect.ValueOf(args[0]) 1498 switch c.Kind() { 1499 case reflect.Complex64: 1500 return imag(complex64(c.Complex())) 1501 case reflect.Complex128: 1502 return imag(c.Complex()) 1503 default: 1504 panic(fmt.Sprintf("imag: illegal operand: %T", c)) 1505 } 1506 1507 case "complex": 1508 r := reflect.ValueOf(args[0]) 1509 i := reflect.ValueOf(args[1]) 1510 switch r.Kind() { 1511 case reflect.Float32: 1512 return complex(float32(r.Float()), float32(i.Float())) 1513 case reflect.Float64: 1514 return complex(r.Float(), i.Float()) 1515 default: 1516 panic(fmt.Sprintf("complex: illegal operand: %v", r.Kind())) 1517 } 1518 1519 case "panic": 1520 // ssa.Panic handles most cases; this is only for "go 1521 // panic" or "defer panic". 1522 panic(targetPanic{args[0]}) 1523 1524 case "recover": 1525 return doRecover(caller) 1526 1527 case "ssa:wrapnilchk": 1528 recv := args[0] 1529 if reflect.ValueOf(recv).IsNil() { 1530 recvType := args[1] 1531 methodName := args[2] 1532 var info value 1533 if s, ok := recvType.(string); ok && strings.HasPrefix(s, "main.") { 1534 info = s[5:] 1535 } else { 1536 info = recvType 1537 } 1538 panic(plainError(fmt.Sprintf("value method %s.%s called using nil *%s pointer", 1539 recvType, methodName, info))) 1540 } 1541 return recv 1542 1543 case "Add": 1544 ptr := args[0].(unsafe.Pointer) 1545 length := asInt(args[1]) 1546 return unsafe.Pointer(uintptr(ptr) + uintptr(length)) 1547 case "Slice": 1548 //func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType 1549 //(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:] 1550 ptr := reflect.ValueOf(args[0]) 1551 length := asInt(args[1]) 1552 if ptr.IsNil() { 1553 if length == 0 { 1554 return reflect.New(reflect.SliceOf(ptr.Type().Elem())).Elem().Interface() 1555 } 1556 panic(runtimeError("unsafe.Slice: ptr is nil and len is not zero")) 1557 } 1558 typ := reflect.ArrayOf(length, ptr.Type().Elem()) 1559 v := reflect.NewAt(typ, unsafe.Pointer(ptr.Pointer())) 1560 return v.Elem().Slice(0, length).Interface() 1561 default: 1562 panic("unknown built-in: " + fnName) 1563 } 1564 } 1565 1566 // callBuiltinDiscardsResult interprets a call to builtin fn with arguments args, 1567 // discards its result. 1568 func (inter *Interp) callBuiltinDiscardsResult(caller *frame, fn *ssa.Builtin, args []value, ssaArgs []ssa.Value) { 1569 switch fnName := fn.Name(); fnName { 1570 case "append": 1571 panic("discards result of " + fnName) 1572 1573 case "copy": // copy([]T, []T) int or copy([]byte, string) int 1574 reflect.Copy(reflect.ValueOf(args[0]), reflect.ValueOf(args[1])) 1575 1576 case "close": // close(chan T) 1577 reflect.ValueOf(args[0]).Close() 1578 1579 case "delete": // delete(map[K]value, K) 1580 reflect.ValueOf(args[0]).SetMapIndex(reflect.ValueOf(args[1]), reflect.Value{}) 1581 1582 case "print", "println": // print(any, ...) 1583 ln := fn.Name() == "println" 1584 var buf bytes.Buffer 1585 for i, arg := range args { 1586 if i > 0 && ln { 1587 buf.WriteRune(' ') 1588 } 1589 if len(ssaArgs) > i { 1590 typ := inter.toType(ssaArgs[i].Type()) 1591 if typ.Kind() == reflect.Interface { 1592 writeinterface(&buf, arg) 1593 continue 1594 } 1595 } 1596 writevalue(&buf, arg, inter.mode&EnablePrintAny != 0) 1597 } 1598 if ln { 1599 buf.WriteRune('\n') 1600 } 1601 inter.ctx.writeOutput(buf.Bytes()) 1602 1603 case "len": 1604 panic("discards result of " + fnName) 1605 1606 case "cap": 1607 panic("discards result of " + fnName) 1608 1609 case "real": 1610 panic("discards result of " + fnName) 1611 1612 case "imag": 1613 panic("discards result of " + fnName) 1614 1615 case "complex": 1616 panic("discards result of " + fnName) 1617 1618 case "panic": 1619 // ssa.Panic handles most cases; this is only for "go 1620 // panic" or "defer panic". 1621 panic(targetPanic{args[0]}) 1622 1623 case "recover": 1624 doRecover(caller) 1625 1626 case "ssa:wrapnilchk": 1627 recv := args[0] 1628 if reflect.ValueOf(recv).IsNil() { 1629 recvType := args[1] 1630 methodName := args[2] 1631 var info value 1632 if s, ok := recvType.(string); ok && strings.HasPrefix(s, "main.") { 1633 info = s[5:] 1634 } else { 1635 info = recvType 1636 } 1637 panic(plainError(fmt.Sprintf("value method %s.%s called using nil *%s pointer", 1638 recvType, methodName, info))) 1639 } 1640 1641 case "Add": 1642 panic("discards result of " + fnName) 1643 1644 case "Slice": 1645 //func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType 1646 //(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:] 1647 panic("discards result of " + fnName) 1648 1649 default: 1650 panic("unknown built-in: " + fnName) 1651 } 1652 } 1653 1654 // callBuiltin interprets a call to builtin fn with arguments args, 1655 // returning its result. 1656 func (inter *Interp) callBuiltinByStack(caller *frame, fn string, ssaArgs []ssa.Value, ir register, ia []register) { 1657 switch fn { 1658 case "append": 1659 if len(ia) == 1 { 1660 caller.copyReg(ir, ia[0]) 1661 return 1662 } 1663 arg0 := caller.reg(ia[0]) 1664 arg1 := caller.reg(ia[1]) 1665 if s, ok := arg1.(string); ok { 1666 // append([]byte, ...string) []byte 1667 arg1 = []byte(s) 1668 } 1669 v0 := reflect.ValueOf(arg0) 1670 v1 := reflect.ValueOf(arg1) 1671 i0 := v0.Len() 1672 i1 := v1.Len() 1673 if i0+i1 < i0 { 1674 panic(runtimeError("growslice: cap out of range")) 1675 } 1676 caller.setReg(ir, reflect.AppendSlice(v0, v1).Interface()) 1677 1678 case "copy": // copy([]T, []T) int or copy([]byte, string) int 1679 arg0 := caller.reg(ia[0]) 1680 arg1 := caller.reg(ia[1]) 1681 caller.setReg(ir, reflect.Copy(reflect.ValueOf(arg0), reflect.ValueOf(arg1))) 1682 1683 case "close": // close(chan T) 1684 arg0 := caller.reg(ia[0]) 1685 reflect.ValueOf(arg0).Close() 1686 1687 case "delete": // delete(map[K]value, K) 1688 arg0 := caller.reg(ia[0]) 1689 arg1 := caller.reg(ia[1]) 1690 reflect.ValueOf(arg0).SetMapIndex(reflect.ValueOf(arg1), reflect.Value{}) 1691 1692 case "print", "println": // print(any, ...) 1693 ln := fn == "println" 1694 var buf bytes.Buffer 1695 for i := 0; i < len(ia); i++ { 1696 arg := caller.reg(ia[i]) 1697 if i > 0 && ln { 1698 buf.WriteRune(' ') 1699 } 1700 if len(ssaArgs) > i { 1701 typ := inter.toType(ssaArgs[i].Type()) 1702 if typ.Kind() == reflect.Interface { 1703 writeinterface(&buf, arg) 1704 continue 1705 } 1706 } 1707 writevalue(&buf, arg, inter.mode&EnablePrintAny != 0) 1708 } 1709 if ln { 1710 buf.WriteRune('\n') 1711 } 1712 inter.ctx.writeOutput(buf.Bytes()) 1713 1714 case "len": 1715 arg0 := caller.reg(ia[0]) 1716 caller.setReg(ir, reflect.ValueOf(arg0).Len()) 1717 1718 case "cap": 1719 arg0 := caller.reg(ia[0]) 1720 caller.setReg(ir, reflect.ValueOf(arg0).Cap()) 1721 1722 case "real": 1723 arg0 := caller.reg(ia[0]) 1724 c := reflect.ValueOf(arg0) 1725 switch c.Kind() { 1726 case reflect.Complex64: 1727 caller.setReg(ir, real(complex64(c.Complex()))) 1728 case reflect.Complex128: 1729 caller.setReg(ir, real(c.Complex())) 1730 default: 1731 panic(fmt.Sprintf("real: illegal operand: %T", c)) 1732 } 1733 1734 case "imag": 1735 arg0 := caller.reg(ia[0]) 1736 c := reflect.ValueOf(arg0) 1737 switch c.Kind() { 1738 case reflect.Complex64: 1739 caller.setReg(ir, imag(complex64(c.Complex()))) 1740 case reflect.Complex128: 1741 caller.setReg(ir, imag(c.Complex())) 1742 default: 1743 panic(fmt.Sprintf("imag: illegal operand: %T", c)) 1744 } 1745 1746 case "complex": 1747 arg0 := caller.reg(ia[0]) 1748 arg1 := caller.reg(ia[1]) 1749 r := reflect.ValueOf(arg0) 1750 i := reflect.ValueOf(arg1) 1751 switch r.Kind() { 1752 case reflect.Float32: 1753 caller.setReg(ir, complex(float32(r.Float()), float32(i.Float()))) 1754 case reflect.Float64: 1755 caller.setReg(ir, complex(r.Float(), i.Float())) 1756 default: 1757 panic(fmt.Sprintf("complex: illegal operand: %v", r.Kind())) 1758 } 1759 1760 case "panic": 1761 // ssa.Panic handles most cases; this is only for "go 1762 // panic" or "defer panic". 1763 arg0 := caller.reg(ia[0]) 1764 panic(targetPanic{arg0}) 1765 1766 case "recover": 1767 caller.setReg(ir, doRecover(caller)) 1768 1769 case "ssa:wrapnilchk": 1770 recv := caller.reg(ia[0]) 1771 if reflect.ValueOf(recv).IsNil() { 1772 recvType := caller.reg(ia[1]) 1773 methodName := caller.reg(ia[2]) 1774 var info value 1775 if s, ok := recvType.(string); ok && strings.HasPrefix(s, "main.") { 1776 info = s[5:] 1777 } else { 1778 info = recvType 1779 } 1780 panic(plainError(fmt.Sprintf("value method %s.%s called using nil *%s pointer", 1781 recvType, methodName, info))) 1782 } 1783 caller.setReg(ir, recv) 1784 1785 case "Add": 1786 arg0 := caller.reg(ia[0]) 1787 arg1 := caller.reg(ia[1]) 1788 ptr := arg0.(unsafe.Pointer) 1789 length := asInt(arg1) 1790 caller.setReg(ir, unsafe.Pointer(uintptr(ptr)+uintptr(length))) 1791 case "Slice": 1792 //func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType 1793 //(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:] 1794 arg0 := caller.reg(ia[0]) 1795 arg1 := caller.reg(ia[1]) 1796 ptr := reflect.ValueOf(arg0) 1797 length := asInt(arg1) 1798 if ptr.IsNil() { 1799 if length == 0 { 1800 caller.setReg(ir, reflect.New(reflect.SliceOf(ptr.Type().Elem())).Elem().Interface()) 1801 return 1802 } 1803 panic(runtimeError("unsafe.Slice: ptr is nil and len is not zero")) 1804 } 1805 typ := reflect.ArrayOf(length, ptr.Type().Elem()) 1806 v := reflect.NewAt(typ, unsafe.Pointer(ptr.Pointer())) 1807 caller.setReg(ir, v.Elem().Slice(0, length).Interface()) 1808 default: 1809 panic("unknown built-in: " + fn) 1810 } 1811 } 1812 1813 // widen widens a xtype typed value x to the widest type of its 1814 // category, one of: 1815 // bool, int64, uint64, float64, complex128, string. 1816 // This is inefficient but reduces the size of the cross-product of 1817 // cases we have to consider. 1818 // 1819 func widen(x value) value { 1820 switch y := x.(type) { 1821 case bool, int64, uint64, float64, complex128, string, unsafe.Pointer: 1822 return x 1823 case int: 1824 return int64(y) 1825 case int8: 1826 return int64(y) 1827 case int16: 1828 return int64(y) 1829 case int32: 1830 return int64(y) 1831 case uint: 1832 return uint64(y) 1833 case uint8: 1834 return uint64(y) 1835 case uint16: 1836 return uint64(y) 1837 case uint32: 1838 return uint64(y) 1839 case uintptr: 1840 return uint64(y) 1841 case float32: 1842 return float64(y) 1843 case complex64: 1844 return complex128(y) 1845 } 1846 panic(fmt.Sprintf("cannot widen %T", x)) 1847 } 1848 1849 //go:nocheckptr 1850 func toUnsafePointer(v uintptr) unsafe.Pointer { 1851 return unsafe.Pointer(v) 1852 } 1853 1854 func toUserFuncId(v *reflect.Value) uintptr { 1855 return uintptr((*reflectValue)(unsafe.Pointer(v)).ptr) 1856 } 1857 1858 type reflectValue struct { 1859 typ unsafe.Pointer 1860 ptr unsafe.Pointer 1861 flag uintptr 1862 } 1863 1864 func convert(x interface{}, typ reflect.Type) interface{} { 1865 v := reflect.ValueOf(x) 1866 vk := v.Kind() 1867 switch typ.Kind() { 1868 case reflect.UnsafePointer: 1869 if vk == reflect.Uintptr { 1870 return toUnsafePointer(uintptr(v.Uint())) 1871 } else if vk == reflect.Ptr { 1872 return unsafe.Pointer(v.Pointer()) 1873 } 1874 case reflect.Uintptr: 1875 if vk == reflect.UnsafePointer { 1876 return v.Pointer() 1877 } 1878 case reflect.Ptr: 1879 if vk == reflect.UnsafePointer { 1880 return reflect.NewAt(typ.Elem(), unsafe.Pointer(v.Pointer())).Interface() 1881 } 1882 case reflect.Slice: 1883 if v.Kind() == reflect.String { 1884 elem := typ.Elem() 1885 switch elem.Kind() { 1886 case reflect.Uint8: 1887 if elem.PkgPath() != "" { 1888 dst := reflect.New(typ).Elem() 1889 dst.SetBytes([]byte(v.String())) 1890 return dst.Interface() 1891 } 1892 case reflect.Int32: 1893 if elem.PkgPath() != "" { 1894 dst := reflect.New(typ).Elem() 1895 *(*[]rune)((*reflectValue)(unsafe.Pointer(&dst)).ptr) = []rune(v.String()) 1896 return dst.Interface() 1897 } 1898 } 1899 } 1900 case reflect.String: 1901 if v.Kind() == reflect.Slice { 1902 elem := v.Type().Elem() 1903 switch elem.Kind() { 1904 case reflect.Uint8: 1905 if elem.PkgPath() != "" { 1906 v = reflect.ValueOf(string(v.Bytes())) 1907 } 1908 case reflect.Int32: 1909 if elem.PkgPath() != "" { 1910 v = reflect.ValueOf(*(*[]rune)(((*reflectValue)(unsafe.Pointer(&v))).ptr)) 1911 } 1912 } 1913 } 1914 } 1915 return v.Convert(typ).Interface() 1916 }