github.com/goplus/igop@v0.25.0/opblock.go (about) 1 /* 2 * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package igop 18 19 import ( 20 "fmt" 21 "go/token" 22 "go/types" 23 "io" 24 "reflect" 25 "strings" 26 "sync" 27 "sync/atomic" 28 "unsafe" 29 30 "github.com/goplus/igop/load" 31 "github.com/goplus/reflectx" 32 "github.com/visualfc/funcval" 33 "github.com/visualfc/xtype" 34 "golang.org/x/tools/go/ssa" 35 ) 36 37 /* 38 type Op int 39 40 const ( 41 OpInvalid Op = iota 42 // Value-defining instructions 43 OpAlloc 44 OpPhi 45 OpCall 46 OpBinOp 47 OpUnOp 48 OpChangeType 49 OpConvert 50 OpChangeInterface 51 OpSliceToArrayPointer 52 OpMakeInterface 53 OpMakeClosure 54 OpMakeMap 55 OpMakeChan 56 OpMakeSlice 57 OpSlice 58 OpFieldAddr 59 OpField 60 OpIndexAddr 61 OpIndex 62 OpLookup 63 OpSelect 64 OpRange 65 OpNext 66 OpTypeAssert 67 OpExtract 68 // Instructions executed for effect 69 OpJump 70 OpIf 71 OpReturn 72 OpRunDefers 73 OpPanic 74 OpGo 75 OpDefer 76 OpSend 77 OpStore 78 OpMapUpdate 79 OpDebugRef 80 ) 81 */ 82 83 type kind int 84 85 func (k kind) isStatic() bool { 86 return k == kindConst || k == kindGlobal || k == kindFunction 87 } 88 89 const ( 90 kindInvalid kind = iota 91 kindConst 92 kindGlobal 93 kindFunction 94 ) 95 96 type Value = value 97 type Tuple = tuple 98 99 type register int 100 type value = interface{} 101 type tuple []value 102 103 type closure struct { 104 pfn *function 105 env []value 106 } 107 108 type function struct { 109 Interp *Interp 110 Fn *ssa.Function // ssa function 111 Main *ssa.BasicBlock // Fn.Blocks[0] 112 pool *sync.Pool // create frame pool 113 makeInstr ssa.Instruction // make instr check 114 index map[ssa.Value]uint32 // stack value index 32bit: kind(2) reflect.Kind(6) index(24) 115 instrIndex map[ssa.Instruction][]uint32 // instr -> index 116 Instrs []func(fr *frame) // main instrs 117 Recover []func(fr *frame) // recover instrs 118 Blocks []int // block offset 119 stack []value // results args envs datas 120 ssaInstrs []ssa.Instruction // org ssa instr 121 base int // base of interp 122 nres int // results count 123 narg int // arguments count 124 nenv int // closure free vars count 125 used int32 // function used count 126 cached int32 // enable cached by pool 127 } 128 129 func (p *function) UnsafeRelease() { 130 p.Interp = nil 131 p.Fn = nil 132 p.pool = nil 133 p.index = nil 134 p.instrIndex = nil 135 p.Instrs = nil 136 p.Recover = nil 137 p.Blocks = nil 138 p.stack = nil 139 p.ssaInstrs = nil 140 p.Main = nil 141 } 142 143 func (p *function) initPool() { 144 p.pool = &sync.Pool{} 145 p.pool.New = func() interface{} { 146 fr := &frame{interp: p.Interp, pfn: p, block: p.Main} 147 fr.stack = append([]value{}, p.stack...) 148 return fr 149 } 150 } 151 152 func (p *function) allocFrame(caller *frame) *frame { 153 var fr *frame 154 if atomic.LoadInt32(&p.cached) == 1 { 155 fr = p.pool.Get().(*frame) 156 fr.block = p.Main 157 fr._defer = nil 158 fr._panic = nil 159 fr.ipc = 0 160 fr.pred = 0 161 } else { 162 if atomic.AddInt32(&p.used, 1) > int32(p.Interp.ctx.callForPool) { 163 atomic.StoreInt32(&p.cached, 1) 164 } 165 fr = &frame{interp: p.Interp, pfn: p, block: p.Main} 166 fr.stack = append([]value{}, p.stack...) 167 } 168 fr.caller = caller 169 fr.deferid = caller.deferid 170 caller.callee = fr 171 return fr 172 } 173 174 func (p *function) deleteFrame(caller *frame, fr *frame) { 175 if atomic.LoadInt32(&p.cached) == 1 { 176 p.pool.Put(fr) 177 } else { 178 caller.callee = nil 179 } 180 fr = nil 181 } 182 183 func (p *function) InstrForPC(pc int) ssa.Instruction { 184 if pc >= 0 && pc < len(p.ssaInstrs) { 185 return p.ssaInstrs[pc] 186 } 187 return nil 188 } 189 190 func (p *function) PosForPC(pc int) token.Pos { 191 if instr := p.InstrForPC(pc); instr != nil { 192 if _, ok := instr.(*ssa.RunDefers); ok { 193 return p.Fn.Syntax().End() 194 } 195 return instr.Pos() 196 } 197 return token.NoPos 198 } 199 200 func (p *function) PositionForPC(pc int) token.Position { 201 pos := p.PosForPC(pc) 202 return p.Fn.Prog.Fset.Position(pos) 203 } 204 205 func (p *function) regIndex3(v ssa.Value) (register, kind, value) { 206 instr := p.regInstr(v) 207 index := int(instr & 0xffffff) 208 return register(index), kind(instr >> 30), p.stack[index] 209 } 210 211 func (p *function) regIndex(v ssa.Value) register { 212 instr := p.regInstr(v) 213 return register(instr & 0xffffff) 214 } 215 216 func (p *function) regInstr(v ssa.Value) uint32 { 217 if i, ok := p.index[v]; ok { 218 return i 219 } 220 var vs interface{} 221 var vk kind 222 switch v := v.(type) { 223 case *ssa.Const: 224 vs = constToValue(p.Interp, v) 225 vk = kindConst 226 case *ssa.Global: 227 vs, _ = globalToValue(p.Interp, v) 228 vk = kindGlobal 229 case *ssa.Function: 230 vk = kindFunction 231 if v.Blocks != nil { 232 typ := p.Interp.preToType(v.Type()) 233 pfn := p.Interp.loadFunction(v) 234 vs = pfn.makeFunction(typ, nil).Interface() 235 } else { 236 ext, ok := findExternFunc(p.Interp, v) 237 if !ok { 238 if v.Name() != "init" { 239 panic(fmt.Errorf("no code for function: %v", v)) 240 } 241 } else { 242 vs = ext.Interface() 243 } 244 } 245 } 246 var kind reflect.Kind 247 if v != nil { 248 kind = toKind(v.Type()) 249 } 250 i := uint32(len(p.stack) | int(vk<<30) | int(kind<<24)) 251 p.stack = append(p.stack, vs) 252 p.index[v] = i 253 p.instrIndex[p.makeInstr] = append(p.instrIndex[p.makeInstr], i) 254 return i 255 } 256 257 func findExternValue(interp *Interp, name string) (ext reflect.Value, ok bool) { 258 // check override value 259 ext, ok = interp.ctx.override[name] 260 if !ok { 261 // check extern value 262 ext, ok = externValues[name] 263 } 264 return 265 } 266 267 func findExternLinkFunc(interp *Interp, link *load.Linkname) (ext reflect.Value, ok bool) { 268 fullName := link.PkgPath + "." + link.Name 269 // check override value 270 ext, ok = interp.ctx.override[fullName] 271 if ok { 272 return 273 } 274 // check extern value 275 ext, ok = externValues[fullName] 276 if ok { 277 return 278 } 279 // check install pkg 280 if pkg, found := interp.installed(link.PkgPath); found { 281 if recv := link.Recv; recv != "" { 282 var star bool 283 if recv[0] == '*' { 284 star = true 285 recv = recv[1:] 286 } 287 if typ, ok := pkg.NamedTypes[recv]; ok { 288 if star { 289 typ = reflect.PtrTo(typ) 290 } 291 if m, ok := reflectx.MethodByName(typ, link.Method); ok { 292 return m.Func, true 293 } 294 } 295 return 296 } 297 ext, ok = pkg.Funcs[link.Name] 298 } 299 return 300 } 301 302 func findExternVar(interp *Interp, pkgPath string, name string) (ext reflect.Value, ok bool) { 303 fullName := pkgPath + "." + name 304 // check override value 305 ext, ok = interp.ctx.override[fullName] 306 if ok { 307 return 308 } 309 // check extern value 310 ext, ok = externValues[fullName] 311 if ok { 312 return 313 } 314 // check install pkg 315 if pkg, found := interp.installed(pkgPath); found { 316 ext, ok = pkg.Vars[name] 317 } 318 return 319 } 320 321 func checkFuncCompatible(t1, t2 reflect.Type) bool { 322 i1 := t1.NumIn() 323 i2 := t2.NumIn() 324 if i1 != i2 { 325 return false 326 } 327 for i := 0; i < i1; i++ { 328 if t1.In(i).Size() != t2.In(i).Size() { 329 return false 330 } 331 } 332 return true 333 } 334 335 func findExternFunc(interp *Interp, fn *ssa.Function) (ext reflect.Value, ok bool) { 336 fnName := fn.String() 337 ext, ok = findExternValue(interp, fnName) 338 if ok { 339 typ := interp.preToType(fn.Type()) 340 ftyp := ext.Type() 341 if typ != ftyp && checkFuncCompatible(typ, ftyp) { 342 ext = xtype.ConvertFunc(ext, xtype.TypeOfType(typ)) 343 } 344 return 345 } 346 if fn.Pkg != nil { 347 if recv := fn.Signature.Recv(); recv == nil { 348 if pkg, found := interp.installed(fn.Pkg.Pkg.Path()); found { 349 ext, ok = pkg.Funcs[fn.Name()] 350 } 351 } else if typ, found := interp.ctx.Loader.LookupReflect(recv.Type()); found { 352 if m, found := reflectx.MethodByName(typ, fn.Name()); found { 353 ext, ok = m.Func, true 354 } 355 } 356 } 357 return 358 } 359 360 func makeInstr(interp *Interp, pfn *function, instr ssa.Instruction) func(fr *frame) { 361 switch instr := instr.(type) { 362 case *ssa.Alloc: 363 if instr.Heap { 364 typ := interp.preToType(instr.Type()) 365 ir := pfn.regIndex(instr) 366 t := xtype.TypeOfType(typ.Elem()) 367 pt := xtype.TypeOfType(typ) 368 return func(fr *frame) { 369 fr.setReg(ir, xtype.New(t, pt)) 370 } 371 } 372 typ := interp.preToType(instr.Type()) 373 ir := pfn.regIndex(instr) 374 t := xtype.TypeOfType(typ.Elem()) 375 pt := xtype.TypeOfType(typ) 376 // ptr := xtype.NewPointer(t) 377 elem := reflect.New(typ.Elem()).Elem() 378 return func(fr *frame) { 379 if v := fr.reg(ir); v != nil { 380 reflect.ValueOf(v).Elem().Set(elem) 381 } else { 382 fr.setReg(ir, xtype.New(t, pt)) 383 } 384 } 385 case *ssa.Phi: 386 ir := pfn.regIndex(instr) 387 ie := make([]register, len(instr.Edges)) 388 for i, v := range instr.Edges { 389 ie[i] = pfn.regIndex(v) 390 } 391 return func(fr *frame) { 392 for i, pred := range instr.Block().Preds { 393 if fr.pred == pred.Index { 394 fr.setReg(ir, fr.reg(ie[i])) 395 break 396 } 397 } 398 } 399 case *ssa.Call: 400 return makeCallInstr(pfn, interp, instr, &instr.Call) 401 case *ssa.BinOp: 402 switch instr.Op { 403 case token.ADD: 404 return makeBinOpADD(pfn, instr) 405 case token.SUB: 406 return makeBinOpSUB(pfn, instr) 407 case token.MUL: 408 return makeBinOpMUL(pfn, instr) 409 case token.QUO: 410 return makeBinOpQUO(pfn, instr) 411 case token.REM: 412 return makeBinOpREM(pfn, instr) 413 case token.AND: 414 return makeBinOpAND(pfn, instr) 415 case token.OR: 416 return makeBinOpOR(pfn, instr) 417 case token.XOR: 418 return makeBinOpXOR(pfn, instr) 419 case token.AND_NOT: 420 return makeBinOpANDNOT(pfn, instr) 421 case token.LSS: 422 return makeBinOpLSS(pfn, instr) 423 case token.LEQ: 424 return makeBinOpLEQ(pfn, instr) 425 case token.GTR: 426 return makeBinOpGTR(pfn, instr) 427 case token.GEQ: 428 return makeBinOpGEQ(pfn, instr) 429 case token.EQL: 430 return makeBinOpEQL(pfn, instr) 431 case token.NEQ: 432 return makeBinOpNEQ(pfn, instr) 433 case token.SHL: 434 return makeBinOpSHL(pfn, instr) 435 case token.SHR: 436 return makeBinOpSHR(pfn, instr) 437 default: 438 panic("unreachable") 439 } 440 case *ssa.UnOp: 441 switch instr.Op { 442 case token.NOT: 443 return makeUnOpNOT(pfn, instr) 444 case token.SUB: 445 return makeUnOpSUB(pfn, instr) 446 case token.XOR: 447 return makeUnOpXOR(pfn, instr) 448 case token.ARROW: 449 return makeUnOpARROW(pfn, instr) 450 case token.MUL: 451 return makeUnOpMUL(pfn, instr) 452 default: 453 panic("unreachable") 454 } 455 case *ssa.ChangeInterface: 456 ir := pfn.regIndex(instr) 457 ix := pfn.regIndex(instr.X) 458 return func(fr *frame) { 459 fr.setReg(ir, fr.reg(ix)) 460 } 461 case *ssa.ChangeType: 462 return makeTypeChangeInstr(pfn, instr) 463 case *ssa.Convert: 464 return makeConvertInstr(pfn, interp, instr) 465 case *ssa.MakeInterface: 466 typ := interp.preToType(instr.Type()) 467 ir := pfn.regIndex(instr) 468 ix, kx, vx := pfn.regIndex3(instr.X) 469 if kx.isStatic() { 470 if typ == tyEmptyInterface { 471 return func(fr *frame) { 472 fr.setReg(ir, vx) 473 } 474 } 475 v := reflect.New(typ).Elem() 476 if vx != nil { 477 SetValue(v, reflect.ValueOf(vx)) 478 } 479 vx = v.Interface() 480 return func(fr *frame) { 481 fr.setReg(ir, vx) 482 } 483 } 484 if typ == tyEmptyInterface { 485 return func(fr *frame) { 486 fr.setReg(ir, fr.reg(ix)) 487 } 488 } 489 return func(fr *frame) { 490 v := reflect.New(typ).Elem() 491 if x := fr.reg(ix); x != nil { 492 vx := reflect.ValueOf(x) 493 SetValue(v, vx) 494 } 495 fr.setReg(ir, v.Interface()) 496 } 497 case *ssa.MakeClosure: 498 fn := instr.Fn.(*ssa.Function) 499 typ := interp.preToType(fn.Type()) 500 ir := pfn.regIndex(instr) 501 ib := make([]register, len(instr.Bindings)) 502 for i, v := range instr.Bindings { 503 ib[i] = pfn.regIndex(v) 504 } 505 pfn := interp.loadFunction(fn) 506 return func(fr *frame) { 507 var bindings []value 508 for i := range instr.Bindings { 509 bindings = append(bindings, fr.reg(ib[i])) 510 } 511 v := pfn.makeFunction(typ, bindings) 512 fr.setReg(ir, v.Interface()) 513 } 514 case *ssa.MakeChan: 515 typ := interp.preToType(instr.Type()) 516 ir := pfn.regIndex(instr) 517 is := pfn.regIndex(instr.Size) 518 if typ.ChanDir() == reflect.BothDir { 519 return func(fr *frame) { 520 size := fr.reg(is) 521 buffer := asInt(size) 522 if buffer < 0 { 523 panic(runtimeError("makechan: size out of range")) 524 } 525 fr.setReg(ir, reflect.MakeChan(typ, buffer).Interface()) 526 } 527 } 528 ctyp := reflect.ChanOf(reflect.BothDir, typ.Elem()) 529 return func(fr *frame) { 530 size := fr.reg(is) 531 buffer := asInt(size) 532 if buffer < 0 { 533 panic(runtimeError("makechan: size out of range")) 534 } 535 fr.setReg(ir, reflect.MakeChan(ctyp, buffer).Convert(typ).Interface()) 536 } 537 case *ssa.MakeMap: 538 typ := instr.Type() 539 rtyp := interp.preToType(typ) 540 ir := pfn.regIndex(instr) 541 if instr.Reserve == nil { 542 return func(fr *frame) { 543 fr.setReg(ir, reflect.MakeMap(rtyp).Interface()) 544 } 545 } 546 iv := pfn.regIndex(instr.Reserve) 547 return func(fr *frame) { 548 reserve := asInt(fr.reg(iv)) 549 fr.setReg(ir, reflect.MakeMapWithSize(rtyp, reserve).Interface()) 550 } 551 case *ssa.MakeSlice: 552 typ := interp.preToType(instr.Type()) 553 ir := pfn.regIndex(instr) 554 il := pfn.regIndex(instr.Len) 555 ic := pfn.regIndex(instr.Cap) 556 return func(fr *frame) { 557 Len := asInt(fr.reg(il)) 558 if Len < 0 || Len >= maxMemLen { 559 panic(runtimeError("makeslice: len out of range")) 560 } 561 Cap := asInt(fr.reg(ic)) 562 if Cap < 0 || Cap >= maxMemLen { 563 panic(runtimeError("makeslice: cap out of range")) 564 } 565 fr.setReg(ir, reflect.MakeSlice(typ, Len, Cap).Interface()) 566 } 567 case *ssa.Slice: 568 typ := interp.preToType(instr.Type()) 569 isNamed := typ.Kind() == reflect.Slice && typ != reflect.SliceOf(typ.Elem()) 570 _, makesliceCheck := instr.X.(*ssa.Alloc) 571 ir := pfn.regIndex(instr) 572 ix := pfn.regIndex(instr.X) 573 ih := pfn.regIndex(instr.High) 574 il := pfn.regIndex(instr.Low) 575 im := pfn.regIndex(instr.Max) 576 if isNamed { 577 return func(fr *frame) { 578 fr.setReg(ir, slice(fr, instr, makesliceCheck, ix, ih, il, im).Convert(typ).Interface()) 579 } 580 } 581 return func(fr *frame) { 582 fr.setReg(ir, slice(fr, instr, makesliceCheck, ix, ih, il, im).Interface()) 583 } 584 case *ssa.FieldAddr: 585 ir := pfn.regIndex(instr) 586 ix := pfn.regIndex(instr.X) 587 return func(fr *frame) { 588 v, err := fieldAddrX(fr.reg(ix), instr.Field) 589 if err != nil { 590 panic(runtimeError(err.Error())) 591 } 592 fr.setReg(ir, v) 593 } 594 case *ssa.Field: 595 ir := pfn.regIndex(instr) 596 ix := pfn.regIndex(instr.X) 597 return func(fr *frame) { 598 v, err := fieldX(fr.reg(ix), instr.Field) 599 if err != nil { 600 panic(runtimeError(err.Error())) 601 } 602 fr.setReg(ir, v) 603 } 604 case *ssa.IndexAddr: 605 ir := pfn.regIndex(instr) 606 ix := pfn.regIndex(instr.X) 607 ii := pfn.regIndex(instr.Index) 608 return func(fr *frame) { 609 x := fr.reg(ix) 610 idx := fr.reg(ii) 611 v := reflect.ValueOf(x) 612 if v.Kind() == reflect.Ptr { 613 v = v.Elem() 614 } 615 switch v.Kind() { 616 case reflect.Slice: 617 case reflect.Array: 618 case reflect.Invalid: 619 panic(runtimeError("invalid memory address or nil pointer dereference")) 620 default: 621 panic(fmt.Sprintf("unexpected x type in IndexAddr: %T", x)) 622 } 623 index := asInt(idx) 624 if index < 0 { 625 panic(runtimeError(fmt.Sprintf("index out of range [%v]", index))) 626 } else if length := v.Len(); index >= length { 627 panic(runtimeError(fmt.Sprintf("index out of range [%v] with length %v", index, length))) 628 } 629 fr.setReg(ir, v.Index(index).Addr().Interface()) 630 } 631 case *ssa.Index: 632 ir := pfn.regIndex(instr) 633 ix := pfn.regIndex(instr.X) 634 ii := pfn.regIndex(instr.Index) 635 return func(fr *frame) { 636 x := fr.reg(ix) 637 idx := fr.reg(ii) 638 index := asInt(idx) 639 v := reflect.ValueOf(x) 640 if index < 0 { 641 panic(runtimeError(fmt.Sprintf("index out of range [%v]", index))) 642 } else if length := v.Len(); index >= length { 643 panic(runtimeError(fmt.Sprintf("index out of range [%v] with length %v", index, length))) 644 } 645 fr.setReg(ir, v.Index(index).Interface()) 646 } 647 case *ssa.Lookup: 648 typ := interp.preToType(instr.X.Type()) 649 ir := pfn.regIndex(instr) 650 ix := pfn.regIndex(instr.X) 651 ii := pfn.regIndex(instr.Index) 652 switch typ.Kind() { 653 case reflect.String: 654 return func(fr *frame) { 655 v := fr.reg(ix) 656 idx := fr.reg(ii) 657 fr.setReg(ir, reflect.ValueOf(v).String()[asInt(idx)]) 658 } 659 case reflect.Map: 660 return func(fr *frame) { 661 m := fr.reg(ix) 662 idx := fr.reg(ii) 663 vm := reflect.ValueOf(m) 664 v := vm.MapIndex(reflect.ValueOf(idx)) 665 ok := v.IsValid() 666 var rv value 667 if ok { 668 rv = v.Interface() 669 } else { 670 rv = reflect.New(typ.Elem()).Elem().Interface() 671 } 672 if instr.CommaOk { 673 fr.setReg(ir, tuple{rv, ok}) 674 } else { 675 fr.setReg(ir, rv) 676 } 677 } 678 default: 679 panic("unreachable") 680 } 681 case *ssa.Select: 682 ir := pfn.regIndex(instr) 683 ic := make([]register, len(instr.States)) 684 is := make([]register, len(instr.States)) 685 for i, state := range instr.States { 686 ic[i] = pfn.regIndex(state.Chan) 687 if state.Send != nil { 688 is[i] = pfn.regIndex(state.Send) 689 } 690 } 691 return func(fr *frame) { 692 var cases []reflect.SelectCase 693 if !instr.Blocking { 694 cases = append(cases, reflect.SelectCase{ 695 Dir: reflect.SelectDefault, 696 }) 697 } 698 for i, state := range instr.States { 699 var dir reflect.SelectDir 700 if state.Dir == types.RecvOnly { 701 dir = reflect.SelectRecv 702 } else { 703 dir = reflect.SelectSend 704 } 705 ch := reflect.ValueOf(fr.reg(ic[i])) 706 var send reflect.Value 707 if state.Send != nil { 708 v := fr.reg(is[i]) 709 if v == nil { 710 send = reflect.New(ch.Type().Elem()).Elem() 711 } else { 712 send = reflect.ValueOf(v) 713 } 714 } 715 cases = append(cases, reflect.SelectCase{ 716 Dir: dir, 717 Chan: ch, 718 Send: send, 719 }) 720 } 721 chosen, recv, recvOk := reflect.Select(cases) 722 if !instr.Blocking { 723 chosen-- // default case should have index -1. 724 } 725 r := tuple{chosen, recvOk} 726 for n, st := range instr.States { 727 if st.Dir == types.RecvOnly { 728 var v value 729 if n == chosen && recvOk { 730 // No need to copy since send makes an unaliased copy. 731 v = recv.Interface() 732 } else { 733 typ := interp.toType(st.Chan.Type()) 734 v = reflect.New(typ.Elem()).Elem().Interface() 735 } 736 r = append(r, v) 737 } 738 } 739 fr.setReg(ir, r) 740 } 741 case *ssa.SliceToArrayPointer: 742 typ := interp.preToType(instr.Type()) 743 ir := pfn.regIndex(instr) 744 ix := pfn.regIndex(instr.X) 745 return func(fr *frame) { 746 x := fr.reg(ix) 747 v := reflect.ValueOf(x) 748 vLen := v.Len() 749 tLen := typ.Elem().Len() 750 if tLen > vLen { 751 panic(runtimeError(fmt.Sprintf(errSliceToArrayPointer, vLen, tLen))) 752 } 753 fr.setReg(ir, v.Convert(typ).Interface()) 754 } 755 case *ssa.Range: 756 typ := interp.preToType(instr.X.Type()) 757 ir := pfn.regIndex(instr) 758 ix := pfn.regIndex(instr.X) 759 switch typ.Kind() { 760 case reflect.String: 761 return func(fr *frame) { 762 v := fr.string(ix) 763 fr.setReg(ir, &stringIter{Reader: strings.NewReader(v)}) 764 } 765 case reflect.Map: 766 return func(fr *frame) { 767 v := fr.reg(ix) 768 fr.setReg(ir, &mapIter{iter: reflect.ValueOf(v).MapRange()}) 769 } 770 default: 771 panic("unreachable") 772 } 773 case *ssa.Next: 774 ir := pfn.regIndex(instr) 775 ii := pfn.regIndex(instr.Iter) 776 if instr.IsString { 777 return func(fr *frame) { 778 fr.setReg(ir, fr.reg(ii).(*stringIter).next()) 779 } 780 } 781 return func(fr *frame) { 782 fr.setReg(ir, fr.reg(ii).(*mapIter).next()) 783 } 784 case *ssa.TypeAssert: 785 typ := interp.preToType(instr.AssertedType) 786 xtyp := interp.preToType(instr.X.Type()) 787 ir := pfn.regIndex(instr) 788 ix, kx, vx := pfn.regIndex3(instr.X) 789 if kx.isStatic() { 790 return func(fr *frame) { 791 fr.setReg(ir, typeAssert(interp, instr, typ, xtyp, vx)) 792 } 793 } 794 return func(fr *frame) { 795 v := fr.reg(ix) 796 fr.setReg(ir, typeAssert(interp, instr, typ, xtyp, v)) 797 } 798 case *ssa.Extract: 799 if *instr.Referrers() == nil { 800 return nil 801 } 802 ir := pfn.regIndex(instr) 803 it := pfn.regIndex(instr.Tuple) 804 return func(fr *frame) { 805 fr.setReg(ir, fr.reg(it).(tuple)[instr.Index]) 806 } 807 // Instructions executed for effect 808 case *ssa.Jump: 809 return func(fr *frame) { 810 fr.pred, fr.block = fr.block.Index, fr.block.Succs[0] 811 fr.ipc = fr.pfn.Blocks[fr.block.Index] 812 } 813 case *ssa.If: 814 ic, kc, vc := pfn.regIndex3(instr.Cond) 815 if kc == kindConst { 816 if xtype.Bool(vc) { 817 return func(fr *frame) { 818 fr.pred = fr.block.Index 819 fr.block = fr.block.Succs[0] 820 fr.ipc = fr.pfn.Blocks[fr.block.Index] 821 } 822 } 823 return func(fr *frame) { 824 fr.pred = fr.block.Index 825 fr.block = fr.block.Succs[1] 826 fr.ipc = fr.pfn.Blocks[fr.block.Index] 827 } 828 } 829 switch instr.Cond.Type().(type) { 830 case *types.Basic: 831 return func(fr *frame) { 832 fr.pred = fr.block.Index 833 if fr.reg(ic).(bool) { 834 fr.block = fr.block.Succs[0] 835 } else { 836 fr.block = fr.block.Succs[1] 837 } 838 fr.ipc = fr.pfn.Blocks[fr.block.Index] 839 } 840 default: 841 return func(fr *frame) { 842 fr.pred = fr.block.Index 843 if fr.bool(ic) { 844 fr.block = fr.block.Succs[0] 845 } else { 846 fr.block = fr.block.Succs[1] 847 } 848 fr.ipc = fr.pfn.Blocks[fr.block.Index] 849 } 850 } 851 case *ssa.Return: 852 switch n := pfn.nres; n { 853 case 0: 854 return func(fr *frame) { 855 fr.ipc = -1 856 } 857 case 1: 858 ir, ik, iv := pfn.regIndex3(instr.Results[0]) 859 if ik.isStatic() { 860 return func(fr *frame) { 861 fr.stack[0] = iv 862 fr.ipc = -1 863 } 864 } 865 return func(fr *frame) { 866 fr.stack[0] = fr.reg(ir) 867 fr.ipc = -1 868 } 869 case 2: 870 r1, k1, v1 := pfn.regIndex3(instr.Results[0]) 871 r2, k2, v2 := pfn.regIndex3(instr.Results[1]) 872 if k1.isStatic() && k2.isStatic() { 873 return func(fr *frame) { 874 fr.stack[0] = v1 875 fr.stack[1] = v2 876 fr.ipc = -1 877 } 878 } else if k1.isStatic() { 879 return func(fr *frame) { 880 fr.stack[0] = v1 881 fr.stack[1] = fr.reg(r2) 882 fr.ipc = -1 883 } 884 } else if k2.isStatic() { 885 return func(fr *frame) { 886 fr.stack[0] = fr.reg(r1) 887 fr.stack[1] = v2 888 fr.ipc = -1 889 } 890 } 891 return func(fr *frame) { 892 fr.stack[0] = fr.reg(r1) 893 fr.stack[1] = fr.reg(r2) 894 fr.ipc = -1 895 } 896 default: 897 ir := make([]register, n) 898 for i, v := range instr.Results { 899 ir[i] = pfn.regIndex(v) 900 } 901 return func(fr *frame) { 902 for i := 0; i < n; i++ { 903 fr.stack[i] = fr.reg(ir[i]) 904 } 905 fr.ipc = -1 906 } 907 } 908 case *ssa.RunDefers: 909 return func(fr *frame) { 910 fr.runDefers() 911 } 912 case *ssa.Panic: 913 ix := pfn.regIndex(instr.X) 914 return func(fr *frame) { 915 panic(PanicError{stack: debugStack(fr), Value: fr.reg(ix)}) 916 } 917 case *ssa.Go: 918 iv, ia, ib := getCallIndex(pfn, &instr.Call) 919 return func(fr *frame) { 920 fn, args := interp.prepareCall(fr, &instr.Call, iv, ia, ib) 921 atomic.AddInt32(&interp.goroutines, 1) 922 if interp.ctx.RunContext != nil { 923 go func() { 924 root := &frame{interp: interp} 925 switch f := fn.(type) { 926 case *ssa.Function: 927 root.pfn = interp.funcs[f] 928 case *closure: 929 root.pfn = f.pfn 930 } 931 defer func() { 932 e := recover() 933 if e != nil { 934 interp.cherror <- PanicError{stack: debugStack(root), Value: e} 935 } 936 }() 937 interp.callDiscardsResult(root, fn, args, instr.Call.Args) 938 atomic.AddInt32(&interp.goroutines, -1) 939 }() 940 } else { 941 go func() { 942 interp.callDiscardsResult(&frame{}, fn, args, instr.Call.Args) 943 atomic.AddInt32(&interp.goroutines, -1) 944 }() 945 } 946 } 947 case *ssa.Defer: 948 iv, ia, ib := getCallIndex(pfn, &instr.Call) 949 return func(fr *frame) { 950 fn, args := interp.prepareCall(fr, &instr.Call, iv, ia, ib) 951 fr._defer = &_defer{ 952 fn: fn, 953 args: args, 954 ssaArgs: instr.Call.Args, 955 tail: fr._defer, 956 } 957 } 958 case *ssa.Send: 959 ic := pfn.regIndex(instr.Chan) 960 ix := pfn.regIndex(instr.X) 961 return func(fr *frame) { 962 c := fr.reg(ic) 963 x := fr.reg(ix) 964 ch := reflect.ValueOf(c) 965 if x == nil { 966 ch.Send(reflect.New(ch.Type().Elem()).Elem()) 967 } else { 968 ch.Send(reflect.ValueOf(x)) 969 } 970 } 971 case *ssa.Store: 972 // skip struct field _ 973 if addr, ok := instr.Addr.(*ssa.FieldAddr); ok { 974 if s, ok := addr.X.Type().(*types.Pointer).Elem().(*types.Struct); ok { 975 if s.Field(addr.Field).Name() == "_" { 976 return nil 977 } 978 } 979 } 980 if pfn.Fn.Name() == "init" && pfn.Fn.Synthetic == "package initializer" { 981 pfn.Interp.chkinit[instr.Addr.String()] = true 982 } 983 ia := pfn.regIndex(instr.Addr) 984 iv, kv, vv := pfn.regIndex3(instr.Val) 985 if kv.isStatic() { 986 if vv == nil { 987 return func(fr *frame) { 988 x := reflect.ValueOf(fr.reg(ia)) 989 SetValue(x.Elem(), reflect.New(x.Elem().Type()).Elem()) 990 } 991 } 992 return func(fr *frame) { 993 x := reflect.ValueOf(fr.reg(ia)) 994 SetValue(x.Elem(), reflect.ValueOf(vv)) 995 } 996 } 997 return func(fr *frame) { 998 x := reflect.ValueOf(fr.reg(ia)) 999 val := fr.reg(iv) 1000 v := reflect.ValueOf(val) 1001 if v.IsValid() { 1002 SetValue(x.Elem(), v) 1003 } else { 1004 SetValue(x.Elem(), reflect.New(x.Elem().Type()).Elem()) 1005 } 1006 } 1007 case *ssa.MapUpdate: 1008 im := pfn.regIndex(instr.Map) 1009 ik := pfn.regIndex(instr.Key) 1010 iv, kv, vv := pfn.regIndex3(instr.Value) 1011 if kv.isStatic() { 1012 return func(fr *frame) { 1013 vm := reflect.ValueOf(fr.reg(im)) 1014 vk := reflect.ValueOf(fr.reg(ik)) 1015 vm.SetMapIndex(vk, reflect.ValueOf(vv)) 1016 } 1017 } 1018 return func(fr *frame) { 1019 vm := reflect.ValueOf(fr.reg(im)) 1020 vk := reflect.ValueOf(fr.reg(ik)) 1021 v := fr.reg(iv) 1022 vm.SetMapIndex(vk, reflect.ValueOf(v)) 1023 } 1024 case *ssa.DebugRef: 1025 if v, ok := instr.Object().(*types.Var); ok { 1026 ix := pfn.regIndex(instr.X) 1027 return func(fr *frame) { 1028 ref := &DebugInfo{DebugRef: instr, fset: interp.ctx.FileSet} 1029 ref.toValue = func() (*types.Var, interface{}, bool) { 1030 return v, fr.reg(ix), true 1031 } 1032 interp.ctx.debugFunc(ref) 1033 } 1034 } 1035 return func(fr *frame) { 1036 ref := &DebugInfo{DebugRef: instr, fset: interp.ctx.FileSet} 1037 ref.toValue = func() (*types.Var, interface{}, bool) { 1038 return nil, nil, false 1039 } 1040 interp.ctx.debugFunc(ref) 1041 } 1042 default: 1043 panic(fmt.Errorf("unreachable %T", instr)) 1044 } 1045 } 1046 1047 func getCallIndex(pfn *function, call *ssa.CallCommon) (iv register, ia []register, ib []register) { 1048 iv = pfn.regIndex(call.Value) 1049 ia = make([]register, len(call.Args)) 1050 for i, v := range call.Args { 1051 ia[i] = pfn.regIndex(v) 1052 } 1053 if f, ok := call.Value.(*ssa.MakeClosure); ok { 1054 ib = make([]register, len(f.Bindings)) 1055 for i, binding := range f.Bindings { 1056 ib[i] = pfn.regIndex(binding) 1057 } 1058 } 1059 return 1060 } 1061 1062 var ( 1063 typFramePtr = reflect.TypeOf((*frame)(nil)) 1064 ) 1065 1066 func makeCallInstr(pfn *function, interp *Interp, instr ssa.Value, call *ssa.CallCommon) func(fr *frame) { 1067 ir := pfn.regIndex(instr) 1068 iv, ia, ib := getCallIndex(pfn, call) 1069 switch fn := call.Value.(type) { 1070 case *ssa.Builtin: 1071 fname := fn.Name() 1072 return func(fr *frame) { 1073 interp.callBuiltinByStack(fr, fname, call.Args, ir, ia) 1074 } 1075 case *ssa.MakeClosure: 1076 ifn := interp.loadFunction(fn.Fn.(*ssa.Function)) 1077 ia = append(ia, ib...) 1078 if ifn.Recover == nil { 1079 switch ifn.nres { 1080 case 0: 1081 return func(fr *frame) { 1082 interp.callFunctionByStackNoRecover0(fr, ifn, ir, ia) 1083 } 1084 case 1: 1085 return func(fr *frame) { 1086 interp.callFunctionByStackNoRecover1(fr, ifn, ir, ia) 1087 } 1088 default: 1089 return func(fr *frame) { 1090 interp.callFunctionByStackNoRecoverN(fr, ifn, ir, ia) 1091 } 1092 } 1093 } 1094 switch ifn.nres { 1095 case 0: 1096 return func(fr *frame) { 1097 interp.callFunctionByStack0(fr, ifn, ir, ia) 1098 } 1099 case 1: 1100 return func(fr *frame) { 1101 interp.callFunctionByStack1(fr, ifn, ir, ia) 1102 } 1103 default: 1104 return func(fr *frame) { 1105 interp.callFunctionByStackN(fr, ifn, ir, ia) 1106 } 1107 } 1108 case *ssa.Function: 1109 // "static func/method call" 1110 if fn.Blocks == nil { 1111 ext, ok := findExternFunc(interp, fn) 1112 if !ok { 1113 // skip pkg.init 1114 if fn.Pkg != nil && fn.Name() == "init" { 1115 return nil 1116 } 1117 panic(fmt.Errorf("no code for function: %v", fn)) 1118 } 1119 if typ := ext.Type(); typ.NumIn() > 0 && typ.In(0) == typFramePtr { 1120 return func(fr *frame) { 1121 interp.callExternalWithFrameByStack(fr, ext, ir, ia) 1122 } 1123 } 1124 return func(fr *frame) { 1125 interp.callExternalByStack(fr, ext, ir, ia) 1126 } 1127 } 1128 ifn := interp.loadFunction(fn) 1129 if ifn.Recover == nil { 1130 switch ifn.nres { 1131 case 0: 1132 return func(fr *frame) { 1133 interp.callFunctionByStackNoRecover0(fr, ifn, ir, ia) 1134 } 1135 case 1: 1136 return func(fr *frame) { 1137 interp.callFunctionByStackNoRecover1(fr, ifn, ir, ia) 1138 } 1139 default: 1140 return func(fr *frame) { 1141 interp.callFunctionByStackNoRecoverN(fr, ifn, ir, ia) 1142 } 1143 } 1144 } 1145 switch ifn.nres { 1146 case 0: 1147 return func(fr *frame) { 1148 interp.callFunctionByStack0(fr, ifn, ir, ia) 1149 } 1150 case 1: 1151 return func(fr *frame) { 1152 interp.callFunctionByStack1(fr, ifn, ir, ia) 1153 } 1154 default: 1155 return func(fr *frame) { 1156 interp.callFunctionByStackN(fr, ifn, ir, ia) 1157 } 1158 } 1159 } 1160 // "dynamic method call" // ("invoke" mode) 1161 if call.IsInvoke() { 1162 return makeCallMethodInstr(interp, instr, call, ir, iv, ia) 1163 } 1164 // dynamic func call 1165 typ := interp.preToType(call.Value.Type()) 1166 if typ.Kind() != reflect.Func { 1167 panic("unsupport") 1168 } 1169 if !funcval.IsSupport { 1170 return func(fr *frame) { 1171 fn := fr.reg(iv) 1172 v := reflect.ValueOf(fn) 1173 interp.callExternalByStack(fr, v, ir, ia) 1174 } 1175 } 1176 return func(fr *frame) { 1177 fn := fr.reg(iv) 1178 if fv, n := funcval.Get(fn); n == 1 { 1179 c := (*makeFuncVal)(unsafe.Pointer(fv)) 1180 if c.pfn.Recover == nil { 1181 interp.callFunctionByStackNoRecoverWithEnv(fr, c.pfn, ir, ia, c.env) 1182 } else { 1183 interp.callFunctionByStackWithEnv(fr, c.pfn, ir, ia, c.env) 1184 } 1185 } else { 1186 v := reflect.ValueOf(fn) 1187 interp.callExternalByStack(fr, v, ir, ia) 1188 } 1189 } 1190 } 1191 1192 // makeFuncVal sync with function.makeFunction 1193 // func (pfn *function) makeFunction(typ reflect.Type, env []value) reflect.Value { 1194 // return reflect.MakeFunc(typ, func(args []reflect.Value) []reflect.Value { 1195 // return pfn.Interp.callFunctionByReflect(pfn.Interp.tryDeferFrame(), typ, pfn, args, env) 1196 // }) 1197 // } 1198 1199 type makeFuncVal struct { 1200 funcval.FuncVal 1201 pfn *function 1202 typ reflect.Type 1203 env []interface{} 1204 } 1205 1206 var ( 1207 typeOfType = reflect.TypeOf(reflect.TypeOf(0)) 1208 vfnMethod = reflect.ValueOf(reflectx.MethodByIndex) 1209 vfnMethodByName = reflect.ValueOf(reflectx.MethodByName) 1210 ) 1211 1212 func findUserMethod(typ reflect.Type, name string) (ext reflect.Value, ok bool) { 1213 if m, ok := reflectx.MethodByName(typ, name); ok { 1214 return m.Func, true 1215 } 1216 return 1217 } 1218 1219 func findExternMethod(typ reflect.Type, name string) (ext reflect.Value, ok bool) { 1220 if typ == typeOfType { 1221 switch name { 1222 case "Method": 1223 return vfnMethod, true 1224 case "MethodByName": 1225 return vfnMethodByName, true 1226 } 1227 } 1228 if m, ok := typ.MethodByName(name); ok { 1229 return m.Func, true 1230 } 1231 return 1232 } 1233 1234 func (i *Interp) findMethod(typ reflect.Type, mname string) (fn *ssa.Function, ok bool) { 1235 if mset, mok := i.msets[typ]; mok { 1236 fn, ok = mset[mname] 1237 } 1238 return 1239 } 1240 1241 func makeCallMethodInstr(interp *Interp, instr ssa.Value, call *ssa.CallCommon, ir register, iv register, ia []register) func(fr *frame) { 1242 mname := call.Method.Name() 1243 ia = append([]register{iv}, ia...) 1244 var found bool 1245 var ext reflect.Value 1246 return func(fr *frame) { 1247 v := fr.reg(iv) 1248 rtype := reflect.TypeOf(v) 1249 // find user type method *ssa.Function 1250 if mset, ok := interp.msets[rtype]; ok { 1251 if fn, ok := mset[mname]; ok { 1252 interp.callFunctionByStack(fr, interp.funcs[fn], ir, ia) 1253 return 1254 } 1255 ext, found = findUserMethod(rtype, mname) 1256 } else { 1257 ext, found = findExternMethod(rtype, mname) 1258 } 1259 if !found { 1260 panic(fmt.Errorf("no code for method: %v.%v", rtype, mname)) 1261 } 1262 interp.callExternalByStack(fr, ext, ir, ia) 1263 } 1264 } 1265 1266 type stringIter struct { 1267 *strings.Reader 1268 i int 1269 } 1270 1271 func (it *stringIter) next() tuple { 1272 okv := make(tuple, 3) 1273 ch, n, err := it.ReadRune() 1274 ok := err != io.EOF 1275 okv[0] = ok 1276 if ok { 1277 okv[1] = it.i 1278 okv[2] = ch 1279 } 1280 it.i += n 1281 return okv 1282 } 1283 1284 type mapIter struct { 1285 iter *reflect.MapIter 1286 ok bool 1287 } 1288 1289 func (it *mapIter) next() tuple { 1290 it.ok = it.iter.Next() 1291 if !it.ok { 1292 return []value{false, nil, nil} 1293 } 1294 k, v := it.iter.Key().Interface(), it.iter.Value().Interface() 1295 return []value{true, k, v} 1296 } 1297 1298 func toKind(typ types.Type) reflect.Kind { 1299 retry: 1300 switch t := typ.(type) { 1301 case *types.Basic: 1302 switch t.Kind() { 1303 case types.Bool: 1304 return reflect.Bool 1305 case types.Int: 1306 return reflect.Int 1307 case types.Int8: 1308 return reflect.Int8 1309 case types.Int16: 1310 return reflect.Int16 1311 case types.Int32: 1312 return reflect.Int32 1313 case types.Int64: 1314 return reflect.Int64 1315 case types.Uint: 1316 return reflect.Uint 1317 case types.Uint8: 1318 return reflect.Uint8 1319 case types.Uint16: 1320 return reflect.Uint16 1321 case types.Uint32: 1322 return reflect.Uint32 1323 case types.Uint64: 1324 return reflect.Uint64 1325 case types.Uintptr: 1326 return reflect.Uintptr 1327 case types.Float32: 1328 return reflect.Float32 1329 case types.Float64: 1330 return reflect.Float64 1331 case types.Complex64: 1332 return reflect.Complex64 1333 case types.Complex128: 1334 return reflect.Complex128 1335 case types.String: 1336 return reflect.String 1337 case types.UnsafePointer: 1338 return reflect.UnsafePointer 1339 // types for untyped values 1340 case types.UntypedBool: 1341 return reflect.Bool 1342 case types.UntypedInt: 1343 return reflect.Int 1344 case types.UntypedRune: 1345 return reflect.Int32 1346 case types.UntypedFloat: 1347 return reflect.Float64 1348 case types.UntypedComplex: 1349 return reflect.Complex128 1350 case types.UntypedString: 1351 return reflect.String 1352 case types.UntypedNil: 1353 return reflect.Invalid 1354 } 1355 case *types.Chan: 1356 return reflect.Chan 1357 case *types.Named: 1358 typ = t.Underlying() 1359 goto retry 1360 case *types.Signature: 1361 return reflect.Func 1362 case *types.Slice: 1363 return reflect.Slice 1364 case *types.Array: 1365 return reflect.Array 1366 case *types.Pointer: 1367 return reflect.Ptr 1368 case *types.Struct: 1369 return reflect.Struct 1370 case *types.Map: 1371 return reflect.Map 1372 case *types.Interface: 1373 return reflect.Interface 1374 case *types.Tuple: 1375 return reflect.Slice 1376 } 1377 return reflect.Invalid 1378 }