diff --git a/go/ssa/interp/external.go b/go/ssa/interp/external.go index 3aa7a5f3dea..26a39da07f9 100644 --- a/go/ssa/interp/external.go +++ b/go/ssa/interp/external.go @@ -78,6 +78,7 @@ func init() { "math.Ldexp": ext۰math۰Ldexp, "math.Log": ext۰math۰Log, "math.Min": ext۰math۰Min, + "os.runtime_args": ext۰os۰runtime_args, "reflect.New": ext۰reflect۰New, "reflect.TypeOf": ext۰reflect۰TypeOf, "reflect.ValueOf": ext۰reflect۰ValueOf, @@ -127,6 +128,7 @@ func init() { "syscall.ReadDirent": ext۰syscall۰ReadDirent, "syscall.Stat": ext۰syscall۰Stat, "syscall.Write": ext۰syscall۰Write, + "syscall.runtime_envs": ext۰runtime۰environ, "time.Sleep": ext۰time۰Sleep, "time.now": ext۰time۰now, } @@ -221,6 +223,10 @@ func ext۰math۰Log(fr *frame, args []value) value { return math.Log(args[0].(float64)) } +func ext۰os۰runtime_args(fr *frame, args []value) value { + return fr.i.osArgs +} + func ext۰runtime۰Breakpoint(fr *frame, args []value) value { runtime.Breakpoint() return nil @@ -281,13 +287,8 @@ func ext۰runtime۰FuncForPC(fr *frame, args []value) value { } func ext۰runtime۰environ(fr *frame, args []value) value { - // We don't return syscall.envs (see Interpret()) because it's - // not a dependency of runtime so the package might not exist. - var env []value - for _, s := range os.Environ() { - env = append(env, s) - } - return env + // This function also implements syscall.runtime_envs. + return environ } func ext۰runtime۰getgoroot(fr *frame, args []value) value { diff --git a/go/ssa/interp/interp.go b/go/ssa/interp/interp.go index 77f11f6215b..80c620caba7 100644 --- a/go/ssa/interp/interp.go +++ b/go/ssa/interp/interp.go @@ -75,6 +75,7 @@ type methodSet map[string]*ssa.Function // State shared between all interpreted goroutines. type interpreter struct { + osArgs []value // the value of os.Args prog *ssa.Program // the SSA program globals map[ssa.Value]*value // addresses of global variables (immutable) mode Mode // interpreter options @@ -620,6 +621,16 @@ func setGlobal(i *interpreter, pkg *ssa.Package, name string, v value) { panic("no global variable: " + pkg.Object.Path() + "." + name) } +var environ []value + +func init() { + for _, s := range os.Environ() { + environ = append(environ, s) + } + environ = append(environ, "GOSSAINTERP=1") + environ = append(environ, "GOARCH="+runtime.GOARCH) +} + // Interpret interprets the Go program whose main package is mainpkg. // mode specifies various interpreter options. filename and args are // the initial values of os.Args for the target program. sizes is the @@ -645,6 +656,11 @@ func Interpret(mainpkg *ssa.Package, mode Mode, sizes types.Sizes, filename stri initReflect(i) + i.osArgs = append(i.osArgs, filename) + for _, arg := range args { + i.osArgs = append(i.osArgs, arg) + } + for _, pkg := range i.prog.AllPackages() { // Initialize global storage. for _, m := range pkg.Members { @@ -658,13 +674,7 @@ func Interpret(mainpkg *ssa.Package, mode Mode, sizes types.Sizes, filename stri // Ad-hoc initialization for magic system variables. switch pkg.Object.Path() { case "syscall": - var envs []value - for _, s := range os.Environ() { - envs = append(envs, s) - } - envs = append(envs, "GOSSAINTERP=1") - envs = append(envs, "GOARCH="+runtime.GOARCH) - setGlobal(i, pkg, "envs", envs) + setGlobal(i, pkg, "envs", environ) case "runtime": sz := sizes.Sizeof(pkg.Object.Scope().Lookup("MemStats").Type()) @@ -682,13 +692,6 @@ func Interpret(mainpkg *ssa.Package, mode Mode, sizes types.Sizes, filename stri } } } - - case "os": - Args := []value{filename} - for _, s := range args { - Args = append(Args, s) - } - setGlobal(i, pkg, "Args", Args) } }