gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/golang.org/x/tools/go/ssa/interp/external.go (about)

     1  // Copyright 2013 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package interp
     6  
     7  // Emulated functions that we cannot interpret because they are
     8  // external or because they use "unsafe" or "reflect" operations.
     9  
    10  import (
    11  	"go/types"
    12  	"math"
    13  	"os"
    14  	"runtime"
    15  	"strings"
    16  	"sync/atomic"
    17  	"time"
    18  	"unsafe"
    19  
    20  	"golang.org/x/tools/go/ssa"
    21  )
    22  
    23  type externalFn func(fr *frame, args []value) value
    24  
    25  // TODO(adonovan): fix: reflect.Value abstracts an lvalue or an
    26  // rvalue; Set() causes mutations that can be observed via aliases.
    27  // We have not captured that correctly here.
    28  
    29  // Key strings are from Function.String().
    30  var externals = make(map[string]externalFn)
    31  
    32  func init() {
    33  	// That little dot ۰ is an Arabic zero numeral (U+06F0), categories [Nd].
    34  	for k, v := range map[string]externalFn{
    35  		"(*sync.Pool).Get":                 ext۰sync۰Pool۰Get,
    36  		"(*sync.Pool).Put":                 ext۰nop,
    37  		"(reflect.Value).Bool":             ext۰reflect۰Value۰Bool,
    38  		"(reflect.Value).CanAddr":          ext۰reflect۰Value۰CanAddr,
    39  		"(reflect.Value).CanInterface":     ext۰reflect۰Value۰CanInterface,
    40  		"(reflect.Value).Elem":             ext۰reflect۰Value۰Elem,
    41  		"(reflect.Value).Field":            ext۰reflect۰Value۰Field,
    42  		"(reflect.Value).Float":            ext۰reflect۰Value۰Float,
    43  		"(reflect.Value).Index":            ext۰reflect۰Value۰Index,
    44  		"(reflect.Value).Int":              ext۰reflect۰Value۰Int,
    45  		"(reflect.Value).Interface":        ext۰reflect۰Value۰Interface,
    46  		"(reflect.Value).IsNil":            ext۰reflect۰Value۰IsNil,
    47  		"(reflect.Value).IsValid":          ext۰reflect۰Value۰IsValid,
    48  		"(reflect.Value).Kind":             ext۰reflect۰Value۰Kind,
    49  		"(reflect.Value).Len":              ext۰reflect۰Value۰Len,
    50  		"(reflect.Value).MapIndex":         ext۰reflect۰Value۰MapIndex,
    51  		"(reflect.Value).MapKeys":          ext۰reflect۰Value۰MapKeys,
    52  		"(reflect.Value).NumField":         ext۰reflect۰Value۰NumField,
    53  		"(reflect.Value).NumMethod":        ext۰reflect۰Value۰NumMethod,
    54  		"(reflect.Value).Pointer":          ext۰reflect۰Value۰Pointer,
    55  		"(reflect.Value).Set":              ext۰reflect۰Value۰Set,
    56  		"(reflect.Value).String":           ext۰reflect۰Value۰String,
    57  		"(reflect.Value).Type":             ext۰reflect۰Value۰Type,
    58  		"(reflect.Value).Uint":             ext۰reflect۰Value۰Uint,
    59  		"(reflect.error).Error":            ext۰reflect۰error۰Error,
    60  		"(reflect.rtype).Bits":             ext۰reflect۰rtype۰Bits,
    61  		"(reflect.rtype).Elem":             ext۰reflect۰rtype۰Elem,
    62  		"(reflect.rtype).Field":            ext۰reflect۰rtype۰Field,
    63  		"(reflect.rtype).In":               ext۰reflect۰rtype۰In,
    64  		"(reflect.rtype).Kind":             ext۰reflect۰rtype۰Kind,
    65  		"(reflect.rtype).NumField":         ext۰reflect۰rtype۰NumField,
    66  		"(reflect.rtype).NumIn":            ext۰reflect۰rtype۰NumIn,
    67  		"(reflect.rtype).NumMethod":        ext۰reflect۰rtype۰NumMethod,
    68  		"(reflect.rtype).NumOut":           ext۰reflect۰rtype۰NumOut,
    69  		"(reflect.rtype).Out":              ext۰reflect۰rtype۰Out,
    70  		"(reflect.rtype).Size":             ext۰reflect۰rtype۰Size,
    71  		"(reflect.rtype).String":           ext۰reflect۰rtype۰String,
    72  		"bytes.init":                       ext۰nop, // avoid asm dependency
    73  		"bytes.Equal":                      ext۰bytes۰Equal,
    74  		"bytes.IndexByte":                  ext۰bytes۰IndexByte,
    75  		"hash/crc32.haveSSE42":             ext۰crc32۰haveSSE42,
    76  		"internal/cpu.cpuid":               ext۰cpu۰cpuid,
    77  		"math.Abs":                         ext۰math۰Abs,
    78  		"math.Exp":                         ext۰math۰Exp,
    79  		"math.Float32bits":                 ext۰math۰Float32bits,
    80  		"math.Float32frombits":             ext۰math۰Float32frombits,
    81  		"math.Float64bits":                 ext۰math۰Float64bits,
    82  		"math.Float64frombits":             ext۰math۰Float64frombits,
    83  		"math.Ldexp":                       ext۰math۰Ldexp,
    84  		"math.Log":                         ext۰math۰Log,
    85  		"math.Min":                         ext۰math۰Min,
    86  		"math.hasSSE4":                     ext۰math۰hasSSE4,
    87  		"os.runtime_args":                  ext۰os۰runtime_args,
    88  		"os.runtime_beforeExit":            ext۰nop,
    89  		"os/signal.init":                   ext۰nop,
    90  		"reflect.New":                      ext۰reflect۰New,
    91  		"reflect.SliceOf":                  ext۰reflect۰SliceOf,
    92  		"reflect.TypeOf":                   ext۰reflect۰TypeOf,
    93  		"reflect.ValueOf":                  ext۰reflect۰ValueOf,
    94  		"reflect.Zero":                     ext۰reflect۰Zero,
    95  		"reflect.init":                     ext۰reflect۰Init,
    96  		"reflect.valueInterface":           ext۰reflect۰valueInterface,
    97  		"runtime.Breakpoint":               ext۰runtime۰Breakpoint,
    98  		"runtime.Caller":                   ext۰runtime۰Caller,
    99  		"runtime.Callers":                  ext۰runtime۰Callers,
   100  		"runtime.FuncForPC":                ext۰runtime۰FuncForPC,
   101  		"runtime.GC":                       ext۰runtime۰GC,
   102  		"runtime.GOMAXPROCS":               ext۰runtime۰GOMAXPROCS,
   103  		"runtime.Goexit":                   ext۰runtime۰Goexit,
   104  		"runtime.Gosched":                  ext۰runtime۰Gosched,
   105  		"runtime.init":                     ext۰nop,
   106  		"runtime.KeepAlive":                ext۰nop,
   107  		"runtime.NumCPU":                   ext۰runtime۰NumCPU,
   108  		"runtime.NumGoroutine":             ext۰runtime۰NumGoroutine,
   109  		"runtime.ReadMemStats":             ext۰runtime۰ReadMemStats,
   110  		"runtime.SetFinalizer":             ext۰nop, // ignore
   111  		"(*runtime.Func).Entry":            ext۰runtime۰Func۰Entry,
   112  		"(*runtime.Func).FileLine":         ext۰runtime۰Func۰FileLine,
   113  		"(*runtime.Func).Name":             ext۰runtime۰Func۰Name,
   114  		"runtime.environ":                  ext۰runtime۰environ,
   115  		"runtime.getgoroot":                ext۰runtime۰getgoroot,
   116  		"strings.init":                     ext۰nop, // avoid asm dependency
   117  		"strings.Count":                    ext۰strings۰Count,
   118  		"strings.Index":                    ext۰strings۰Index,
   119  		"strings.IndexByte":                ext۰strings۰IndexByte,
   120  		"sync.runtime_Semacquire":          ext۰nop, // unimplementable
   121  		"sync.runtime_Semrelease":          ext۰nop, // unimplementable
   122  		"sync.runtime_Syncsemcheck":        ext۰nop, // unimplementable
   123  		"sync.runtime_notifyListCheck":     ext۰nop,
   124  		"sync.runtime_registerPoolCleanup": ext۰nop,
   125  		"sync/atomic.AddInt32":             ext۰atomic۰AddInt32,
   126  		"sync/atomic.AddUint32":            ext۰atomic۰AddUint32,
   127  		"sync/atomic.CompareAndSwapInt32":  ext۰atomic۰CompareAndSwapInt32,
   128  		"sync/atomic.CompareAndSwapUint32": ext۰atomic۰CompareAndSwapUint32,
   129  		"sync/atomic.LoadInt32":            ext۰atomic۰LoadInt32,
   130  		"sync/atomic.LoadUint32":           ext۰atomic۰LoadUint32,
   131  		"sync/atomic.StoreInt32":           ext۰atomic۰StoreInt32,
   132  		"sync/atomic.StoreUint32":          ext۰atomic۰StoreUint32,
   133  		"sync/atomic.AddInt64":             ext۰atomic۰AddInt64,
   134  		"sync/atomic.AddUint64":            ext۰atomic۰AddUint64,
   135  		"sync/atomic.CompareAndSwapInt64":  ext۰atomic۰CompareAndSwapInt64,
   136  		"sync/atomic.CompareAndSwapUint64": ext۰atomic۰CompareAndSwapUint64,
   137  		"sync/atomic.LoadInt64":            ext۰atomic۰LoadInt64,
   138  		"sync/atomic.LoadUint64":           ext۰atomic۰LoadUint64,
   139  		"sync/atomic.StoreInt64":           ext۰atomic۰StoreInt64,
   140  		"sync/atomic.StoreUint64":          ext۰atomic۰StoreUint64,
   141  		"testing.callerEntry":              ext۰testing۰callerEntry,
   142  		"testing.runExample":               ext۰testing۰runExample,
   143  		"time.Sleep":                       ext۰time۰Sleep,
   144  		"time.now":                         ext۰time۰now,
   145  	} {
   146  		externals[k] = v
   147  	}
   148  }
   149  
   150  // wrapError returns an interpreted 'error' interface value for err.
   151  func wrapError(err error) value {
   152  	if err == nil {
   153  		return iface{}
   154  	}
   155  	return iface{t: errorType, v: err.Error()}
   156  }
   157  
   158  func ext۰nop(fr *frame, args []value) value { return nil }
   159  
   160  func ext۰sync۰Pool۰Get(fr *frame, args []value) value {
   161  	Pool := fr.i.prog.ImportedPackage("sync").Type("Pool").Object()
   162  	_, newIndex, _ := types.LookupFieldOrMethod(Pool.Type(), false, Pool.Pkg(), "New")
   163  
   164  	if New := (*args[0].(*value)).(structure)[newIndex[0]]; New != nil {
   165  		return call(fr.i, fr, 0, New, nil)
   166  	}
   167  	return nil
   168  }
   169  
   170  func ext۰bytes۰Equal(fr *frame, args []value) value {
   171  	// func Equal(a, b []byte) bool
   172  	a := args[0].([]value)
   173  	b := args[1].([]value)
   174  	if len(a) != len(b) {
   175  		return false
   176  	}
   177  	for i := range a {
   178  		if a[i] != b[i] {
   179  			return false
   180  		}
   181  	}
   182  	return true
   183  }
   184  
   185  func ext۰bytes۰IndexByte(fr *frame, args []value) value {
   186  	// func IndexByte(s []byte, c byte) int
   187  	s := args[0].([]value)
   188  	c := args[1].(byte)
   189  	for i, b := range s {
   190  		if b.(byte) == c {
   191  			return i
   192  		}
   193  	}
   194  	return -1
   195  }
   196  
   197  func ext۰crc32۰haveSSE42(fr *frame, args []value) value {
   198  	return false
   199  }
   200  
   201  func ext۰math۰Float64frombits(fr *frame, args []value) value {
   202  	return math.Float64frombits(args[0].(uint64))
   203  }
   204  
   205  func ext۰math۰Float64bits(fr *frame, args []value) value {
   206  	return math.Float64bits(args[0].(float64))
   207  }
   208  
   209  func ext۰math۰Float32frombits(fr *frame, args []value) value {
   210  	return math.Float32frombits(args[0].(uint32))
   211  }
   212  
   213  func ext۰math۰Abs(fr *frame, args []value) value {
   214  	return math.Abs(args[0].(float64))
   215  }
   216  
   217  func ext۰math۰Exp(fr *frame, args []value) value {
   218  	return math.Exp(args[0].(float64))
   219  }
   220  
   221  func ext۰math۰Float32bits(fr *frame, args []value) value {
   222  	return math.Float32bits(args[0].(float32))
   223  }
   224  
   225  func ext۰math۰Min(fr *frame, args []value) value {
   226  	return math.Min(args[0].(float64), args[1].(float64))
   227  }
   228  
   229  func ext۰math۰hasSSE4(fr *frame, args []value) value {
   230  	return false
   231  }
   232  
   233  func ext۰math۰Ldexp(fr *frame, args []value) value {
   234  	return math.Ldexp(args[0].(float64), args[1].(int))
   235  }
   236  
   237  func ext۰math۰Log(fr *frame, args []value) value {
   238  	return math.Log(args[0].(float64))
   239  }
   240  
   241  func ext۰os۰runtime_args(fr *frame, args []value) value {
   242  	return fr.i.osArgs
   243  }
   244  
   245  func ext۰runtime۰Breakpoint(fr *frame, args []value) value {
   246  	runtime.Breakpoint()
   247  	return nil
   248  }
   249  
   250  func ext۰runtime۰Caller(fr *frame, args []value) value {
   251  	// func Caller(skip int) (pc uintptr, file string, line int, ok bool)
   252  	skip := 1 + args[0].(int)
   253  	for i := 0; i < skip; i++ {
   254  		if fr != nil {
   255  			fr = fr.caller
   256  		}
   257  	}
   258  	var pc uintptr
   259  	var file string
   260  	var line int
   261  	var ok bool
   262  	if fr != nil {
   263  		fn := fr.fn
   264  		// TODO(adonovan): use pc/posn of current instruction, not start of fn.
   265  		// (Required to interpret the log package's tests.)
   266  		pc = uintptr(unsafe.Pointer(fn))
   267  		posn := fn.Prog.Fset.Position(fn.Pos())
   268  		file = posn.Filename
   269  		line = posn.Line
   270  		ok = true
   271  	}
   272  	return tuple{pc, file, line, ok}
   273  }
   274  
   275  func ext۰runtime۰Callers(fr *frame, args []value) value {
   276  	// Callers(skip int, pc []uintptr) int
   277  	skip := args[0].(int)
   278  	pc := args[1].([]value)
   279  	for i := 0; i < skip; i++ {
   280  		if fr != nil {
   281  			fr = fr.caller
   282  		}
   283  	}
   284  	i := 0
   285  	for fr != nil && i < len(pc) {
   286  		pc[i] = uintptr(unsafe.Pointer(fr.fn))
   287  		i++
   288  		fr = fr.caller
   289  	}
   290  	return i
   291  }
   292  
   293  func ext۰runtime۰FuncForPC(fr *frame, args []value) value {
   294  	// FuncForPC(pc uintptr) *Func
   295  	pc := args[0].(uintptr)
   296  	var fn *ssa.Function
   297  	if pc != 0 {
   298  		fn = (*ssa.Function)(unsafe.Pointer(pc)) // indeed unsafe!
   299  	}
   300  	var Func value
   301  	Func = structure{fn} // a runtime.Func
   302  	return &Func
   303  }
   304  
   305  func ext۰runtime۰environ(fr *frame, args []value) value {
   306  	// This function also implements syscall.runtime_envs.
   307  	return environ
   308  }
   309  
   310  func ext۰runtime۰getgoroot(fr *frame, args []value) value {
   311  	return os.Getenv("GOROOT")
   312  }
   313  
   314  func ext۰strings۰Count(fr *frame, args []value) value {
   315  	// Call compiled version to avoid asm dependency.
   316  	return strings.Count(args[0].(string), args[1].(string))
   317  }
   318  
   319  func ext۰strings۰IndexByte(fr *frame, args []value) value {
   320  	// Call compiled version to avoid asm dependency.
   321  	return strings.IndexByte(args[0].(string), args[1].(byte))
   322  }
   323  
   324  func ext۰strings۰Index(fr *frame, args []value) value {
   325  	// Call compiled version to avoid asm dependency.
   326  	return strings.Index(args[0].(string), args[1].(string))
   327  }
   328  
   329  func ext۰runtime۰GOMAXPROCS(fr *frame, args []value) value {
   330  	// Ignore args[0]; don't let the interpreted program
   331  	// set the interpreter's GOMAXPROCS!
   332  	return runtime.GOMAXPROCS(0)
   333  }
   334  
   335  func ext۰runtime۰Goexit(fr *frame, args []value) value {
   336  	// TODO(adonovan): don't kill the interpreter's main goroutine.
   337  	runtime.Goexit()
   338  	return nil
   339  }
   340  
   341  func ext۰runtime۰GC(fr *frame, args []value) value {
   342  	runtime.GC()
   343  	return nil
   344  }
   345  
   346  func ext۰runtime۰Gosched(fr *frame, args []value) value {
   347  	runtime.Gosched()
   348  	return nil
   349  }
   350  
   351  func ext۰runtime۰NumCPU(fr *frame, args []value) value {
   352  	return runtime.NumCPU()
   353  }
   354  
   355  func ext۰runtime۰NumGoroutine(fr *frame, args []value) value {
   356  	return int(atomic.LoadInt32(&fr.i.goroutines))
   357  }
   358  
   359  func ext۰runtime۰ReadMemStats(fr *frame, args []value) value {
   360  	// TODO(adonovan): populate args[0].(Struct)
   361  	return nil
   362  }
   363  
   364  func ext۰atomic۰LoadUint32(fr *frame, args []value) value {
   365  	// TODO(adonovan): fix: not atomic!
   366  	return (*args[0].(*value)).(uint32)
   367  }
   368  
   369  func ext۰atomic۰StoreUint32(fr *frame, args []value) value {
   370  	// TODO(adonovan): fix: not atomic!
   371  	*args[0].(*value) = args[1].(uint32)
   372  	return nil
   373  }
   374  
   375  func ext۰atomic۰LoadInt32(fr *frame, args []value) value {
   376  	// TODO(adonovan): fix: not atomic!
   377  	return (*args[0].(*value)).(int32)
   378  }
   379  
   380  func ext۰atomic۰StoreInt32(fr *frame, args []value) value {
   381  	// TODO(adonovan): fix: not atomic!
   382  	*args[0].(*value) = args[1].(int32)
   383  	return nil
   384  }
   385  
   386  func ext۰atomic۰CompareAndSwapInt32(fr *frame, args []value) value {
   387  	// TODO(adonovan): fix: not atomic!
   388  	p := args[0].(*value)
   389  	if (*p).(int32) == args[1].(int32) {
   390  		*p = args[2].(int32)
   391  		return true
   392  	}
   393  	return false
   394  }
   395  
   396  func ext۰atomic۰CompareAndSwapUint32(fr *frame, args []value) value {
   397  	// TODO(adonovan): fix: not atomic!
   398  	p := args[0].(*value)
   399  	if (*p).(uint32) == args[1].(uint32) {
   400  		*p = args[2].(uint32)
   401  		return true
   402  	}
   403  	return false
   404  }
   405  
   406  func ext۰atomic۰AddInt32(fr *frame, args []value) value {
   407  	// TODO(adonovan): fix: not atomic!
   408  	p := args[0].(*value)
   409  	newv := (*p).(int32) + args[1].(int32)
   410  	*p = newv
   411  	return newv
   412  }
   413  
   414  func ext۰atomic۰AddUint32(fr *frame, args []value) value {
   415  	// TODO(adonovan): fix: not atomic!
   416  	p := args[0].(*value)
   417  	newv := (*p).(uint32) + args[1].(uint32)
   418  	*p = newv
   419  	return newv
   420  }
   421  
   422  func ext۰atomic۰LoadUint64(fr *frame, args []value) value {
   423  	// TODO(adonovan): fix: not atomic!
   424  	return (*args[0].(*value)).(uint64)
   425  }
   426  
   427  func ext۰atomic۰StoreUint64(fr *frame, args []value) value {
   428  	// TODO(adonovan): fix: not atomic!
   429  	*args[0].(*value) = args[1].(uint64)
   430  	return nil
   431  }
   432  
   433  func ext۰atomic۰LoadInt64(fr *frame, args []value) value {
   434  	// TODO(adonovan): fix: not atomic!
   435  	return (*args[0].(*value)).(int64)
   436  }
   437  
   438  func ext۰atomic۰StoreInt64(fr *frame, args []value) value {
   439  	// TODO(adonovan): fix: not atomic!
   440  	*args[0].(*value) = args[1].(int64)
   441  	return nil
   442  }
   443  
   444  func ext۰atomic۰CompareAndSwapInt64(fr *frame, args []value) value {
   445  	// TODO(adonovan): fix: not atomic!
   446  	p := args[0].(*value)
   447  	if (*p).(int64) == args[1].(int64) {
   448  		*p = args[2].(int64)
   449  		return true
   450  	}
   451  	return false
   452  }
   453  
   454  func ext۰atomic۰CompareAndSwapUint64(fr *frame, args []value) value {
   455  	// TODO(adonovan): fix: not atomic!
   456  	p := args[0].(*value)
   457  	if (*p).(uint64) == args[1].(uint64) {
   458  		*p = args[2].(uint64)
   459  		return true
   460  	}
   461  	return false
   462  }
   463  
   464  func ext۰atomic۰AddInt64(fr *frame, args []value) value {
   465  	// TODO(adonovan): fix: not atomic!
   466  	p := args[0].(*value)
   467  	newv := (*p).(int64) + args[1].(int64)
   468  	*p = newv
   469  	return newv
   470  }
   471  
   472  func ext۰atomic۰AddUint64(fr *frame, args []value) value {
   473  	// TODO(adonovan): fix: not atomic!
   474  	p := args[0].(*value)
   475  	newv := (*p).(uint64) + args[1].(uint64)
   476  	*p = newv
   477  	return newv
   478  }
   479  
   480  func ext۰cpu۰cpuid(fr *frame, args []value) value {
   481  	return tuple{uint32(0), uint32(0), uint32(0), uint32(0)}
   482  }
   483  
   484  // Pretend: type runtime.Func struct { entry *ssa.Function }
   485  
   486  func ext۰runtime۰Func۰FileLine(fr *frame, args []value) value {
   487  	// func (*runtime.Func) FileLine(uintptr) (string, int)
   488  	f, _ := (*args[0].(*value)).(structure)[0].(*ssa.Function)
   489  	pc := args[1].(uintptr)
   490  	_ = pc
   491  	if f != nil {
   492  		// TODO(adonovan): use position of current instruction, not fn.
   493  		posn := f.Prog.Fset.Position(f.Pos())
   494  		return tuple{posn.Filename, posn.Line}
   495  	}
   496  	return tuple{"", 0}
   497  }
   498  
   499  func ext۰runtime۰Func۰Name(fr *frame, args []value) value {
   500  	// func (*runtime.Func) Name() string
   501  	f, _ := (*args[0].(*value)).(structure)[0].(*ssa.Function)
   502  	if f != nil {
   503  		return f.String()
   504  	}
   505  	return ""
   506  }
   507  
   508  func ext۰runtime۰Func۰Entry(fr *frame, args []value) value {
   509  	// func (*runtime.Func) Entry() uintptr
   510  	f, _ := (*args[0].(*value)).(structure)[0].(*ssa.Function)
   511  	return uintptr(unsafe.Pointer(f))
   512  }
   513  
   514  // This is a workaround for a bug in go/ssa/testmain.go: it creates
   515  // InternalExamples even for Example functions with no Output comment.
   516  // TODO(adonovan): fix (and redesign) testmain.go..
   517  func ext۰testing۰runExample(fr *frame, args []value) value {
   518  	// This is a stripped down runExample that simply calls the function.
   519  	// It does not capture and compare output nor recover from panic.
   520  	//
   521  	// func runExample(eg testing.InternalExample) bool {
   522  	//     eg.F()
   523  	//     return true
   524  	// }
   525  	F := args[0].(structure)[1]
   526  	call(fr.i, fr, 0, F, nil)
   527  	return true
   528  }
   529  
   530  func ext۰testing۰callerEntry(fr *frame, args []value) value {
   531  	return uintptr(0) // bogus implementation for now
   532  }
   533  
   534  func ext۰time۰now(fr *frame, args []value) value {
   535  	nano := time.Now().UnixNano()
   536  	return tuple{int64(nano / 1e9), int32(nano % 1e9), int64(0)}
   537  }
   538  
   539  func ext۰time۰Sleep(fr *frame, args []value) value {
   540  	time.Sleep(time.Duration(args[0].(int64)))
   541  	return nil
   542  }
   543  
   544  func valueToBytes(v value) []byte {
   545  	in := v.([]value)
   546  	b := make([]byte, len(in))
   547  	for i := range in {
   548  		b[i] = in[i].(byte)
   549  	}
   550  	return b
   551  }