github.com/goplus/gossa@v0.3.25/interp.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 ssa/interp defines an interpreter for the SSA 6 // representation of Go programs. 7 // 8 // This interpreter is provided as an adjunct for testing the SSA 9 // construction algorithm. Its purpose is to provide a minimal 10 // metacircular implementation of the dynamic semantics of each SSA 11 // instruction. It is not, and will never be, a production-quality Go 12 // interpreter. 13 // 14 // The following is a partial list of Go features that are currently 15 // unsupported or incomplete in the interpreter. 16 // 17 // * Unsafe operations, including all uses of unsafe.Pointer, are 18 // impossible to support given the "boxed" value representation we 19 // have chosen. 20 // 21 // * The reflect package is only partially implemented. 22 // 23 // * The "testing" package is no longer supported because it 24 // depends on low-level details that change too often. 25 // 26 // * "sync/atomic" operations are not atomic due to the "boxed" value 27 // representation: it is not possible to read, modify and write an 28 // interface value atomically. As a consequence, Mutexes are currently 29 // broken. 30 // 31 // * recover is only partially implemented. Also, the interpreter 32 // makes no attempt to distinguish target panics from interpreter 33 // crashes. 34 // 35 // * the sizes of the int, uint and uintptr types in the target 36 // program are assumed to be the same as those of the interpreter 37 // itself. 38 // 39 // * all values occupy space, even those of types defined by the spec 40 // to have zero size, e.g. struct{}. This can cause asymptotic 41 // performance degradation. 42 // 43 // * os.Exit is implemented using panic, causing deferred functions to 44 // run. 45 package gossa 46 47 import ( 48 "fmt" 49 "go/constant" 50 "go/token" 51 "go/types" 52 "reflect" 53 "runtime" 54 "sync" 55 "sync/atomic" 56 "unsafe" 57 58 "github.com/goplus/gossa/internal/xtype" 59 "github.com/petermattis/goid" 60 "golang.org/x/tools/go/ssa" 61 ) 62 63 var ( 64 maxMemLen int 65 ) 66 67 const intSize = 32 << (^uint(0) >> 63) 68 69 func init() { 70 if intSize == 32 { 71 maxMemLen = 1<<31 - 1 72 } else { 73 v := int64(1) << 59 74 maxMemLen = int(v) 75 } 76 } 77 78 type plainError string 79 80 func (e plainError) Error() string { 81 return string(e) 82 } 83 84 type runtimeError string 85 86 func (e runtimeError) RuntimeError() {} 87 88 func (e runtimeError) Error() string { 89 return "runtime error: " + string(e) 90 } 91 92 // State shared between all interpreted goroutines. 93 type Interp struct { 94 ctx *Context 95 fset *token.FileSet 96 prog *ssa.Program // the SSA program 97 mainpkg *ssa.Package // the SSA main package 98 globals map[ssa.Value]value // addresses of global variables (immutable) 99 mode Mode // interpreter options 100 goroutines int32 // atomically updated 101 deferCount int32 // fast has defer check 102 preloadTypes map[types.Type]reflect.Type // preload types.Type -> reflect.Type 103 deferMap sync.Map // defer goroutine id -> call frame 104 loader Loader // loader types 105 record *TypesRecord // lookup type and ToType 106 typesMutex sync.RWMutex // findType/toType mutex 107 funcs map[*ssa.Function]*function // ssa.Function -> *function 108 msets map[reflect.Type](map[string]*ssa.Function) // user defined type method sets 109 mainid int64 // main goroutine id 110 exitCode int // call os.Exit code 111 chexit chan int // call os.Exit code by chan for runtime.Goexit 112 goexited int32 // is call runtime.Goexit 113 exited int32 // is call os.Exit 114 } 115 116 func (i *Interp) installed(path string) (pkg *Package, ok bool) { 117 pkg, ok = i.loader.Installed(path) 118 return 119 } 120 121 func (i *Interp) loadFunction(fn *ssa.Function) *function { 122 if pfn, ok := i.funcs[fn]; ok { 123 return pfn 124 } 125 pfn := &function{ 126 Interp: i, 127 Fn: fn, 128 Main: fn.Blocks[0], 129 mapUnderscoreKey: make(map[types.Type]bool), 130 index: make(map[ssa.Value]uint32), 131 narg: len(fn.Params), 132 nenv: len(fn.FreeVars), 133 } 134 if res := fn.Signature.Results(); res != nil { 135 pfn.nres = res.Len() 136 pfn.stack = make([]value, pfn.nres) 137 } 138 i.funcs[fn] = pfn 139 return pfn 140 } 141 142 func (i *Interp) findType(rt reflect.Type, local bool) (types.Type, bool) { 143 i.typesMutex.Lock() 144 defer i.typesMutex.Unlock() 145 if local { 146 return i.record.LookupLocalTypes(rt) 147 } else { 148 return i.record.LookupTypes(rt) 149 } 150 } 151 152 func (i *Interp) tryDeferFrame() *frame { 153 if atomic.LoadInt32(&i.deferCount) != 0 { 154 if f, ok := i.deferMap.Load(goroutineId()); ok { 155 return f.(*frame) 156 } 157 } 158 return nil 159 } 160 161 func (i *Interp) FindMethod(mtyp reflect.Type, fn *types.Func) func([]reflect.Value) []reflect.Value { 162 typ := fn.Type().(*types.Signature).Recv().Type() 163 if f := i.prog.LookupMethod(typ, fn.Pkg(), fn.Name()); f != nil { 164 pfn := i.loadFunction(f) 165 return func(args []reflect.Value) []reflect.Value { 166 return i.callFunctionByReflect(i.tryDeferFrame(), mtyp, pfn, args, nil) 167 } 168 } 169 name := fn.FullName() 170 if v, ok := externValues[name]; ok && v.Kind() == reflect.Func { 171 return func(args []reflect.Value) []reflect.Value { 172 return v.Call(args) 173 } 174 } 175 panic(fmt.Sprintf("Not found method %v", fn)) 176 } 177 178 func (i *Interp) makeFunc(typ reflect.Type, pfn *function, env []value) reflect.Value { 179 return reflect.MakeFunc(typ, func(args []reflect.Value) []reflect.Value { 180 return i.callFunctionByReflect(i.tryDeferFrame(), typ, pfn, args, env) 181 }) 182 } 183 184 type deferred struct { 185 fn value 186 args []value 187 ssaArgs []ssa.Value 188 instr *ssa.Defer 189 tail *deferred 190 } 191 192 type frame struct { 193 caller *frame 194 pfn *function 195 defers *deferred 196 panicking *panicking 197 block *ssa.BasicBlock 198 pc int 199 pred int 200 deferid int64 201 stack []value // result args env datas 202 } 203 204 func (fr *frame) setReg(ir register, v value) { 205 fr.stack[ir] = v 206 } 207 208 func (fr *frame) reg(ir register) value { 209 return fr.stack[ir] 210 } 211 212 func (fr *frame) bytes(ir register) []byte { 213 return xtype.Bytes(fr.stack[ir]) 214 } 215 216 func (fr *frame) runes(ir register) []rune { 217 return xtype.Runes(fr.stack[ir]) 218 } 219 220 func (fr *frame) bool(ir register) bool { 221 return xtype.Bool(fr.stack[ir]) 222 } 223 224 func (fr *frame) int(ir register) int { 225 return xtype.Int(fr.stack[ir]) 226 } 227 228 func (fr *frame) int8(ir register) int8 { 229 return xtype.Int8(fr.stack[ir]) 230 } 231 232 func (fr *frame) int16(ir register) int16 { 233 return xtype.Int16(fr.stack[ir]) 234 } 235 236 func (fr *frame) int32(ir register) int32 { 237 return xtype.Int32(fr.stack[ir]) 238 } 239 240 func (fr *frame) int64(ir register) int64 { 241 return xtype.Int64(fr.stack[ir]) 242 } 243 244 func (fr *frame) uint(ir register) uint { 245 return xtype.Uint(fr.stack[ir]) 246 } 247 248 func (fr *frame) uint8(ir register) uint8 { 249 return xtype.Uint8(fr.stack[ir]) 250 } 251 252 func (fr *frame) uint16(ir register) uint16 { 253 return xtype.Uint16(fr.stack[ir]) 254 } 255 256 func (fr *frame) uint32(ir register) uint32 { 257 return xtype.Uint32(fr.stack[ir]) 258 } 259 260 func (fr *frame) uint64(ir register) uint64 { 261 return xtype.Uint64(fr.stack[ir]) 262 } 263 264 func (fr *frame) uintptr(ir register) uintptr { 265 return xtype.Uintptr(fr.stack[ir]) 266 } 267 268 func (fr *frame) float32(ir register) float32 { 269 return xtype.Float32(fr.stack[ir]) 270 } 271 272 func (fr *frame) float64(ir register) float64 { 273 return xtype.Float64(fr.stack[ir]) 274 } 275 276 func (fr *frame) complex64(ir register) complex64 { 277 return xtype.Complex64(fr.stack[ir]) 278 } 279 280 func (fr *frame) complex128(ir register) complex128 { 281 return xtype.Complex128(fr.stack[ir]) 282 } 283 284 func (fr *frame) string(ir register) string { 285 return xtype.String(fr.stack[ir]) 286 } 287 288 func (fr *frame) pointer(ir register) unsafe.Pointer { 289 return xtype.Pointer(fr.stack[ir]) 290 } 291 292 func (fr *frame) copyReg(dst register, src register) { 293 fr.stack[dst] = fr.stack[src] 294 } 295 296 type panicking struct { 297 value interface{} 298 } 299 300 // runDefer runs a deferred call d. 301 // It always returns normally, but may set or clear fr.panic. 302 // 303 func (fr *frame) runDefer(d *deferred) { 304 var ok bool 305 defer func() { 306 if !ok { 307 // Deferred call created a new state of panic. 308 fr.panicking = &panicking{recover()} 309 } 310 }() 311 fr.pfn.Interp.callDiscardsResult(fr, d.fn, d.args, d.ssaArgs) 312 ok = true 313 } 314 315 // runDefers executes fr's deferred function calls in LIFO order. 316 // 317 // On entry, fr.panicking indicates a state of panic; if 318 // true, fr.panic contains the panic value. 319 // 320 // On completion, if a deferred call started a panic, or if no 321 // deferred call recovered from a previous state of panic, then 322 // runDefers itself panics after the last deferred call has run. 323 // 324 // If there was no initial state of panic, or it was recovered from, 325 // runDefers returns normally. 326 // 327 func (fr *frame) runDefers() { 328 interp := fr.pfn.Interp 329 atomic.AddInt32(&interp.deferCount, 1) 330 fr.deferid = goroutineId() 331 interp.deferMap.Store(fr.deferid, fr) 332 for d := fr.defers; d != nil; d = d.tail { 333 fr.runDefer(d) 334 } 335 interp.deferMap.Delete(fr.deferid) 336 atomic.AddInt32(&interp.deferCount, -1) 337 fr.deferid = 0 338 // runtime.Goexit() fr.panic == nil 339 if fr.panicking != nil { 340 panic(fr.panicking.value) // new panic, or still panicking 341 } 342 } 343 344 // lookupMethod returns the method set for type typ, which may be one 345 // of the interpreter's fake types. 346 func lookupMethod(i *Interp, typ types.Type, meth *types.Func) *ssa.Function { 347 return i.prog.LookupMethod(typ, meth.Pkg(), meth.Name()) 348 } 349 350 func SetValue(v reflect.Value, x reflect.Value) { 351 switch v.Kind() { 352 case reflect.Bool: 353 v.SetBool(x.Bool()) 354 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 355 v.SetInt(x.Int()) 356 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 357 v.SetUint(x.Uint()) 358 case reflect.Uintptr: 359 v.SetUint(x.Uint()) 360 case reflect.Float32, reflect.Float64: 361 v.SetFloat(x.Float()) 362 case reflect.Complex64, reflect.Complex128: 363 v.SetComplex(x.Complex()) 364 case reflect.String: 365 v.SetString(x.String()) 366 case reflect.UnsafePointer: 367 v.SetPointer(unsafe.Pointer(x.Pointer())) 368 default: 369 v.Set(x) 370 } 371 } 372 373 func hasUnderscore(st *types.Struct) bool { 374 n := st.NumFields() 375 for i := 0; i < n; i++ { 376 if st.Field(i).Name() == "_" { 377 return true 378 } 379 } 380 return false 381 } 382 383 type DebugInfo struct { 384 *ssa.DebugRef 385 fset *token.FileSet 386 toValue func() (*types.Var, interface{}, bool) // var object value 387 } 388 389 func (i *DebugInfo) Position() token.Position { 390 return i.fset.Position(i.Pos()) 391 } 392 393 func (i *DebugInfo) AsVar() (*types.Var, interface{}, bool) { 394 return i.toValue() 395 } 396 397 func (i *DebugInfo) AsFunc() (*types.Func, bool) { 398 v, ok := i.Object().(*types.Func) 399 return v, ok 400 } 401 402 // prepareCall determines the function value and argument values for a 403 // function call in a Call, Go or Defer instruction, performing 404 // interface method lookup if needed. 405 // 406 func (i *Interp) prepareCall(fr *frame, call *ssa.CallCommon, iv register, ia []register, ib []register) (fv value, args []value) { 407 if call.Method == nil { 408 switch f := call.Value.(type) { 409 case *ssa.Builtin: 410 fv = f 411 case *ssa.Function: 412 if f.Blocks == nil { 413 ext, ok := findExternFunc(i, f) 414 if !ok { 415 // skip pkg.init 416 if f.Pkg != nil && f.Name() == "init" { 417 fv = func() {} 418 } else { 419 panic(fmt.Errorf("no code for function: %v", f)) 420 } 421 } else { 422 fv = ext 423 } 424 } else { 425 fv = f 426 } 427 case *ssa.MakeClosure: 428 var bindings []value 429 for i, _ := range f.Bindings { 430 bindings = append(bindings, fr.reg(ib[i])) 431 } 432 fv = &closure{i.funcs[f.Fn.(*ssa.Function)], bindings} 433 default: 434 fv = fr.reg(iv) 435 } 436 } else { 437 v := fr.reg(iv) 438 rtype := reflect.TypeOf(v) 439 mname := call.Method.Name() 440 if mset, ok := i.msets[rtype]; ok { 441 if f, ok := mset[mname]; ok { 442 fv = f 443 } else { 444 ext, ok := findUserMethod(rtype, mname) 445 if !ok { 446 panic(fmt.Errorf("no code for method: %v.%v", rtype, mname)) 447 } 448 fv = ext 449 } 450 } else { 451 ext, ok := findExternMethod(rtype, mname) 452 if !ok { 453 panic(fmt.Errorf("no code for method: %v.%v", rtype, mname)) 454 } 455 fv = ext 456 } 457 args = append(args, v) 458 } 459 for i, _ := range call.Args { 460 v := fr.reg(ia[i]) 461 args = append(args, v) 462 } 463 return 464 } 465 466 // call interprets a call to a function (function, builtin or closure) 467 // fn with arguments args, returning its result. 468 // callpos is the position of the callsite. 469 // 470 func (i *Interp) call(caller *frame, fn value, args []value, ssaArgs []ssa.Value) value { 471 switch fn := fn.(type) { 472 case *ssa.Function: 473 return i.callFunction(caller, i.funcs[fn], args, nil) 474 case *closure: 475 return i.callFunction(caller, fn.pfn, args, fn.env) 476 case *ssa.Builtin: 477 return i.callBuiltin(caller, fn, args, ssaArgs) 478 case reflect.Value: 479 return i.callExternal(caller, fn, args, nil) 480 default: 481 return i.callExternal(caller, reflect.ValueOf(fn), args, nil) 482 } 483 panic(fmt.Sprintf("cannot call %T %v", fn, reflect.ValueOf(fn).Kind())) 484 } 485 486 // call interprets a call to a function (function, builtin or closure) 487 // fn with arguments args, returning its result. 488 // callpos is the position of the callsite. 489 // 490 func (i *Interp) callDiscardsResult(caller *frame, fn value, args []value, ssaArgs []ssa.Value) { 491 switch fn := fn.(type) { 492 case *ssa.Function: 493 i.callFunctionDiscardsResult(caller, i.funcs[fn], args, nil) 494 case *closure: 495 i.callFunctionDiscardsResult(caller, fn.pfn, args, fn.env) 496 case *ssa.Builtin: 497 i.callBuiltinDiscardsResult(caller, fn, args, ssaArgs) 498 case reflect.Value: 499 i.callExternalDiscardsResult(caller, fn, args, nil) 500 default: 501 i.callExternalDiscardsResult(caller, reflect.ValueOf(fn), args, nil) 502 } 503 } 504 505 func (i *Interp) callFunction(caller *frame, pfn *function, args []value, env []value) (result value) { 506 fr := pfn.allocFrame(caller) 507 for i := 0; i < pfn.narg; i++ { 508 fr.stack[i+pfn.nres] = args[i] 509 } 510 for i := 0; i < pfn.nenv; i++ { 511 fr.stack[pfn.narg+i+pfn.nres] = env[i] 512 } 513 fr.run() 514 if pfn.nres == 1 { 515 result = fr.stack[0] 516 } else if pfn.nres > 1 { 517 result = tuple(fr.stack[0:pfn.nres]) 518 } 519 pfn.deleteFrame(fr) 520 return 521 } 522 523 func (i *Interp) callFunctionByReflect(caller *frame, typ reflect.Type, pfn *function, args []reflect.Value, env []value) (results []reflect.Value) { 524 fr := pfn.allocFrame(caller) 525 for i := 0; i < pfn.narg; i++ { 526 fr.stack[i+pfn.nres] = args[i].Interface() 527 } 528 for i := 0; i < pfn.nenv; i++ { 529 fr.stack[pfn.narg+i+pfn.nres] = env[i] 530 } 531 fr.run() 532 if pfn.nres > 0 { 533 results = make([]reflect.Value, pfn.nres, pfn.nres) 534 for i := 0; i < pfn.nres; i++ { 535 v := fr.stack[i] 536 if v == nil { 537 results[i] = reflect.New(typ.Out(i)).Elem() 538 } else { 539 results[i] = reflect.ValueOf(v) 540 } 541 } 542 } 543 pfn.deleteFrame(fr) 544 return 545 } 546 547 func (i *Interp) callFunctionDiscardsResult(caller *frame, pfn *function, args []value, env []value) { 548 fr := pfn.allocFrame(caller) 549 for i := 0; i < pfn.narg; i++ { 550 fr.stack[i+pfn.nres] = args[i] 551 } 552 for i := 0; i < pfn.nenv; i++ { 553 fr.stack[pfn.narg+i+pfn.nres] = env[i] 554 } 555 fr.run() 556 pfn.deleteFrame(fr) 557 } 558 559 func (i *Interp) callFunctionByStack0(caller *frame, pfn *function, ir register, ia []register) { 560 fr := pfn.allocFrame(caller) 561 for i := 0; i < len(ia); i++ { 562 fr.stack[i] = caller.reg(ia[i]) 563 } 564 fr.run() 565 pfn.deleteFrame(fr) 566 } 567 568 func (i *Interp) callFunctionByStack1(caller *frame, pfn *function, ir register, ia []register) { 569 fr := pfn.allocFrame(caller) 570 for i := 0; i < len(ia); i++ { 571 fr.stack[i+1] = caller.reg(ia[i]) 572 } 573 fr.run() 574 caller.setReg(ir, fr.stack[0]) 575 pfn.deleteFrame(fr) 576 } 577 578 func (i *Interp) callFunctionByStackN(caller *frame, pfn *function, ir register, ia []register) { 579 fr := pfn.allocFrame(caller) 580 for i := 0; i < len(ia); i++ { 581 fr.stack[i+pfn.nres] = caller.reg(ia[i]) 582 } 583 fr.run() 584 caller.setReg(ir, tuple(fr.stack[0:pfn.nres])) 585 pfn.deleteFrame(fr) 586 } 587 588 func (i *Interp) callFunctionByStack(caller *frame, pfn *function, ir register, ia []register) { 589 fr := pfn.allocFrame(caller) 590 for i := 0; i < len(ia); i++ { 591 fr.stack[i+pfn.nres] = caller.reg(ia[i]) 592 } 593 fr.run() 594 if pfn.nres == 1 { 595 caller.setReg(ir, fr.stack[0]) 596 } else if pfn.nres > 1 { 597 caller.setReg(ir, tuple(fr.stack[0:pfn.nres])) 598 } 599 pfn.deleteFrame(fr) 600 } 601 602 func (i *Interp) callFunctionByStackNoRecover0(caller *frame, pfn *function, ir register, ia []register) { 603 fr := pfn.allocFrame(caller) 604 for i := 0; i < len(ia); i++ { 605 fr.stack[i] = caller.reg(ia[i]) 606 } 607 for fr.pc != -1 { 608 fn := fr.pfn.Instrs[fr.pc] 609 fr.pc++ 610 fn(fr) 611 } 612 pfn.deleteFrame(fr) 613 } 614 615 func (i *Interp) callFunctionByStackNoRecover1(caller *frame, pfn *function, ir register, ia []register) { 616 fr := pfn.allocFrame(caller) 617 for i := 0; i < len(ia); i++ { 618 fr.stack[i+1] = caller.reg(ia[i]) 619 } 620 for fr.pc != -1 { 621 fn := fr.pfn.Instrs[fr.pc] 622 fr.pc++ 623 fn(fr) 624 } 625 caller.setReg(ir, fr.stack[0]) 626 pfn.deleteFrame(fr) 627 } 628 629 func (i *Interp) callFunctionByStackNoRecoverN(caller *frame, pfn *function, ir register, ia []register) { 630 fr := pfn.allocFrame(caller) 631 for i := 0; i < len(ia); i++ { 632 fr.stack[i+pfn.nres] = caller.reg(ia[i]) 633 } 634 for fr.pc != -1 { 635 fn := fr.pfn.Instrs[fr.pc] 636 fr.pc++ 637 fn(fr) 638 } 639 caller.setReg(ir, tuple(fr.stack[0:pfn.nres])) 640 pfn.deleteFrame(fr) 641 } 642 643 func (i *Interp) callFunctionByStackWithEnv(caller *frame, pfn *function, ir register, ia []register, env []value) { 644 fr := pfn.allocFrame(caller) 645 for i := 0; i < pfn.narg; i++ { 646 fr.stack[i+pfn.nres] = caller.reg(ia[i]) 647 } 648 for i := 0; i < pfn.nenv; i++ { 649 fr.stack[pfn.narg+i+pfn.nres] = env[i] 650 } 651 fr.run() 652 if pfn.nres == 1 { 653 caller.setReg(ir, fr.stack[0]) 654 } else if pfn.nres > 1 { 655 caller.setReg(ir, tuple(fr.stack[0:pfn.nres])) 656 } 657 pfn.deleteFrame(fr) 658 } 659 660 func (i *Interp) callFunctionByStackNoRecoverWithEnv(caller *frame, pfn *function, ir register, ia []register, env []value) { 661 fr := pfn.allocFrame(caller) 662 for i := 0; i < pfn.narg; i++ { 663 fr.stack[i+pfn.nres] = caller.reg(ia[i]) 664 } 665 for i := 0; i < pfn.nenv; i++ { 666 fr.stack[pfn.narg+i+pfn.nres] = env[i] 667 } 668 for fr.pc != -1 { 669 fn := fr.pfn.Instrs[fr.pc] 670 fr.pc++ 671 fn(fr) 672 } 673 if pfn.nres == 1 { 674 caller.setReg(ir, fr.stack[0]) 675 } else if pfn.nres > 1 { 676 caller.setReg(ir, tuple(fr.stack[0:pfn.nres])) 677 } 678 pfn.deleteFrame(fr) 679 } 680 681 func (i *Interp) callExternal(caller *frame, fn reflect.Value, args []value, env []value) value { 682 if caller != nil && caller.deferid != 0 { 683 i.deferMap.Store(caller.deferid, caller) 684 } 685 var ins []reflect.Value 686 typ := fn.Type() 687 isVariadic := fn.Type().IsVariadic() 688 if isVariadic { 689 for i := 0; i < len(args)-1; i++ { 690 if args[i] == nil { 691 ins = append(ins, reflect.New(typ.In(i)).Elem()) 692 } else { 693 ins = append(ins, reflect.ValueOf(args[i])) 694 } 695 } 696 ins = append(ins, reflect.ValueOf(args[len(args)-1])) 697 } else { 698 ins = make([]reflect.Value, len(args), len(args)) 699 for i := 0; i < len(args); i++ { 700 if args[i] == nil { 701 ins[i] = reflect.New(typ.In(i)).Elem() 702 } else { 703 ins[i] = reflect.ValueOf(args[i]) 704 } 705 } 706 } 707 var results []reflect.Value 708 if isVariadic { 709 results = fn.CallSlice(ins) 710 } else { 711 results = fn.Call(ins) 712 } 713 switch len(results) { 714 case 0: 715 return nil 716 case 1: 717 return results[0].Interface() 718 default: 719 var res []value 720 for _, r := range results { 721 res = append(res, r.Interface()) 722 } 723 return tuple(res) 724 } 725 } 726 func (i *Interp) callExternalDiscardsResult(caller *frame, fn reflect.Value, args []value, env []value) { 727 if caller != nil && caller.deferid != 0 { 728 i.deferMap.Store(caller.deferid, caller) 729 } 730 var ins []reflect.Value 731 typ := fn.Type() 732 isVariadic := fn.Type().IsVariadic() 733 if isVariadic { 734 for i := 0; i < len(args)-1; i++ { 735 if args[i] == nil { 736 ins = append(ins, reflect.New(typ.In(i)).Elem()) 737 } else { 738 ins = append(ins, reflect.ValueOf(args[i])) 739 } 740 } 741 ins = append(ins, reflect.ValueOf(args[len(args)-1])) 742 fn.CallSlice(ins) 743 } else { 744 ins = make([]reflect.Value, len(args), len(args)) 745 for i := 0; i < len(args); i++ { 746 if args[i] == nil { 747 ins[i] = reflect.New(typ.In(i)).Elem() 748 } else { 749 ins[i] = reflect.ValueOf(args[i]) 750 } 751 } 752 fn.Call(ins) 753 } 754 } 755 756 func (i *Interp) callExternalByStack(caller *frame, fn reflect.Value, ir register, ia []register) { 757 if caller.deferid != 0 { 758 i.deferMap.Store(caller.deferid, caller) 759 } 760 var ins []reflect.Value 761 typ := fn.Type() 762 isVariadic := fn.Type().IsVariadic() 763 if isVariadic { 764 var i int 765 for n := len(ia) - 1; i < n; i++ { 766 arg := caller.reg(ia[i]) 767 if arg == nil { 768 ins = append(ins, reflect.New(typ.In(i)).Elem()) 769 } else { 770 ins = append(ins, reflect.ValueOf(arg)) 771 } 772 } 773 ins = append(ins, reflect.ValueOf(caller.reg(ia[i]))) 774 } else { 775 n := len(ia) 776 ins = make([]reflect.Value, n, n) 777 for i := 0; i < n; i++ { 778 arg := caller.reg(ia[i]) 779 if arg == nil { 780 ins[i] = reflect.New(typ.In(i)).Elem() 781 } else { 782 ins[i] = reflect.ValueOf(arg) 783 } 784 } 785 } 786 var results []reflect.Value 787 if isVariadic { 788 results = fn.CallSlice(ins) 789 } else { 790 results = fn.Call(ins) 791 } 792 switch len(results) { 793 case 0: 794 case 1: 795 caller.setReg(ir, results[0].Interface()) 796 default: 797 var res []value 798 for _, r := range results { 799 res = append(res, r.Interface()) 800 } 801 caller.setReg(ir, tuple(res)) 802 } 803 } 804 805 // runFrame executes SSA instructions starting at fr.block and 806 // continuing until a return, a panic, or a recovered panic. 807 // 808 // After a panic, runFrame panics. 809 // 810 // After a normal return, fr.result contains the result of the call 811 // and fr.block is nil. 812 // 813 // A recovered panic in a function without named return parameters 814 // (NRPs) becomes a normal return of the zero value of the function's 815 // result type. 816 // 817 // After a recovered panic in a function with NRPs, fr.result is 818 // undefined and fr.block contains the block at which to resume 819 // control. 820 // 821 func (fr *frame) run() { 822 if fr.pfn.Recover != nil { 823 defer func() { 824 if fr.pc == -1 { 825 return // normal return 826 } 827 fr.panicking = &panicking{recover()} 828 fr.runDefers() 829 for _, fn := range fr.pfn.Recover { 830 fn(fr) 831 } 832 }() 833 } 834 835 for fr.pc != -1 { 836 fn := fr.pfn.Instrs[fr.pc] 837 fr.pc++ 838 fn(fr) 839 } 840 } 841 842 // doRecover implements the recover() built-in. 843 func doRecover(caller *frame) value { 844 // recover() must be exactly one level beneath the deferred 845 // function (two levels beneath the panicking function) to 846 // have any effect. Thus we ignore both "defer recover()" and 847 // "defer f() -> g() -> recover()". 848 if caller.pfn.Interp.mode&DisableRecover == 0 && 849 caller.panicking == nil && 850 caller.caller != nil && caller.caller.panicking != nil { 851 p := caller.caller.panicking.value 852 caller.caller.panicking = nil 853 // TODO(adonovan): support runtime.Goexit. 854 switch p := p.(type) { 855 case targetPanic: 856 // The target program explicitly called panic(). 857 return p.v 858 case runtime.Error: 859 // The interpreter encountered a runtime error. 860 return p 861 //return iface{caller.i.runtimeErrorString, p.Error()} 862 case string: 863 return p 864 case plainError: 865 return p 866 case runtimeError: 867 return p 868 case *reflect.ValueError: 869 return p 870 default: 871 panic(fmt.Sprintf("unexpected panic type %T in target call to recover()", p)) 872 } 873 } 874 return nil //iface{} 875 } 876 877 // setGlobal sets the value of a system-initialized global variable. 878 func setGlobal(i *Interp, pkg *ssa.Package, name string, v value) { 879 // if g, ok := i.globals[pkg.Var(name)]; ok { 880 // *g = v 881 // return 882 // } 883 panic("no global variable: " + pkg.Pkg.Path() + "." + name) 884 } 885 886 // Interpret interprets the Go program whose main package is mainpkg. 887 // mode specifies various interpreter options. filename and args are 888 // the initial values of os.Args for the target program. sizes is the 889 // effective type-sizing function for this program. 890 // 891 // Interpret returns the exit code of the program: 2 for panic (like 892 // gc does), or the argument to os.Exit for normal termination. 893 // 894 // The SSA program must include the "runtime" package. 895 // 896 897 func NewInterp(ctx *Context, mainpkg *ssa.Package) (*Interp, error) { 898 return newInterp(ctx, mainpkg, nil) 899 } 900 901 func newInterp(ctx *Context, mainpkg *ssa.Package, globals map[string]interface{}) (*Interp, error) { 902 i := &Interp{ 903 ctx: ctx, 904 fset: mainpkg.Prog.Fset, 905 prog: mainpkg.Prog, 906 mainpkg: mainpkg, 907 globals: make(map[ssa.Value]value), 908 mode: ctx.Mode, 909 loader: ctx.Loader, 910 goroutines: 1, 911 preloadTypes: make(map[types.Type]reflect.Type), 912 funcs: make(map[*ssa.Function]*function), 913 msets: make(map[reflect.Type](map[string]*ssa.Function)), 914 chexit: make(chan int), 915 mainid: goroutineId(), 916 } 917 i.record = NewTypesRecord(i.loader, i) 918 i.record.Load(mainpkg) 919 920 var pkgs []*ssa.Package 921 for _, pkg := range mainpkg.Prog.AllPackages() { 922 // skip external pkg 923 if pkg.Func("init").Blocks == nil { 924 continue 925 } 926 pkgs = append(pkgs, pkg) 927 // Initialize global storage. 928 for _, m := range pkg.Members { 929 switch v := m.(type) { 930 case *ssa.Global: 931 typ := i.preToType(deref(v.Type())) 932 i.globals[v] = reflect.New(typ).Interface() 933 } 934 } 935 } 936 if globals != nil { 937 for k, _ := range i.globals { 938 if fv, ok := globals[k.String()]; ok { 939 i.globals[k] = fv 940 } 941 } 942 } 943 944 // static types check 945 err := checkPackages(i, pkgs) 946 if err != nil { 947 return i, err 948 } 949 return i, err 950 } 951 952 func (i *Interp) loadType(typ types.Type) { 953 if _, ok := i.preloadTypes[typ]; !ok { 954 i.preloadTypes[typ] = i.record.ToType(typ) 955 } 956 } 957 958 func (i *Interp) preToType(typ types.Type) reflect.Type { 959 if t, ok := i.preloadTypes[typ]; ok { 960 return t 961 } 962 t := i.record.ToType(typ) 963 i.preloadTypes[typ] = t 964 return t 965 } 966 967 func (i *Interp) toType(typ types.Type) reflect.Type { 968 if t, ok := i.preloadTypes[typ]; ok { 969 return t 970 } 971 // log.Panicf("toType %v %p\n", typ, typ) 972 i.typesMutex.Lock() 973 defer i.typesMutex.Unlock() 974 return i.record.ToType(typ) 975 } 976 977 func (i *Interp) RunFunc(name string, args ...Value) (r Value, err error) { 978 defer func() { 979 if i.mode&DisableRecover != 0 { 980 return 981 } 982 switch p := recover().(type) { 983 case nil: 984 // nothing 985 case exitPanic: 986 i.exitCode = int(p) 987 atomic.StoreInt32(&i.exited, 1) 988 case goexitPanic: 989 // check goroutines 990 if atomic.LoadInt32(&i.goroutines) == 1 { 991 err = ErrGoexitDeadlock 992 } else { 993 i.exitCode = <-i.chexit 994 atomic.StoreInt32(&i.exited, 1) 995 } 996 case targetPanic: 997 err = p 998 case runtime.Error: 999 err = p 1000 case string: 1001 err = plainError(p) 1002 case plainError: 1003 err = p 1004 default: 1005 err = fmt.Errorf("unexpected type: %T: %v", p, p) 1006 } 1007 }() 1008 if fn := i.mainpkg.Func(name); fn != nil { 1009 r = i.call(nil, fn, args, nil) 1010 } else { 1011 err = fmt.Errorf("no function %v", name) 1012 } 1013 return 1014 } 1015 1016 func (i *Interp) ExitCode() int { 1017 return i.exitCode 1018 } 1019 1020 func (i *Interp) RunInit() (err error) { 1021 i.goexited = 0 1022 i.exitCode = 0 1023 i.exited = 0 1024 _, err = i.RunFunc("init") 1025 return 1026 } 1027 1028 func (i *Interp) RunMain() (exitCode int, err error) { 1029 if atomic.LoadInt32(&i.exited) == 1 { 1030 return i.exitCode, nil 1031 } 1032 _, err = i.RunFunc("main") 1033 if err != nil { 1034 exitCode = 2 1035 } 1036 if atomic.LoadInt32(&i.exited) == 1 { 1037 exitCode = i.exitCode 1038 } 1039 return 1040 } 1041 1042 func (i *Interp) GetFunc(key string) (interface{}, bool) { 1043 m, ok := i.mainpkg.Members[key] 1044 if !ok { 1045 return nil, false 1046 } 1047 fn, ok := m.(*ssa.Function) 1048 if !ok { 1049 return nil, false 1050 } 1051 return i.makeFunc(i.toType(fn.Type()), i.funcs[fn], nil).Interface(), true 1052 } 1053 1054 func (i *Interp) GetVarAddr(key string) (interface{}, bool) { 1055 m, ok := i.mainpkg.Members[key] 1056 if !ok { 1057 return nil, false 1058 } 1059 v, ok := m.(*ssa.Global) 1060 if !ok { 1061 return nil, false 1062 } 1063 p, ok := i.globals[v] 1064 return p, ok 1065 } 1066 1067 func (i *Interp) GetConst(key string) (constant.Value, bool) { 1068 m, ok := i.mainpkg.Members[key] 1069 if !ok { 1070 return nil, false 1071 } 1072 v, ok := m.(*ssa.NamedConst) 1073 if !ok { 1074 return nil, false 1075 } 1076 return v.Value.Value, true 1077 } 1078 1079 func (i *Interp) GetType(key string) (reflect.Type, bool) { 1080 m, ok := i.mainpkg.Members[key] 1081 if !ok { 1082 return nil, false 1083 } 1084 t, ok := m.(*ssa.Type) 1085 if !ok { 1086 return nil, false 1087 } 1088 return i.toType(t.Type()), true 1089 } 1090 1091 // deref returns a pointer's element type; otherwise it returns typ. 1092 // TODO(adonovan): Import from ssa? 1093 func deref(typ types.Type) types.Type { 1094 if p, ok := typ.Underlying().(*types.Pointer); ok { 1095 return p.Elem() 1096 } 1097 return typ 1098 } 1099 1100 func goroutineId() int64 { 1101 return goid.Get() 1102 }