forked from tetratelabs/wazero
-
Notifications
You must be signed in to change notification settings - Fork 0
/
random.go
55 lines (48 loc) · 1.66 KB
/
random.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package wasi_snapshot_preview1
import (
"context"
"io"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/wasip1"
"github.com/tetratelabs/wazero/internal/wasm"
)
// randomGet is the WASI function named RandomGetName which writes random
// data to a buffer.
//
// # Parameters
//
// - buf: api.Memory offset to write random values
// - bufLen: size of random data in bytes
//
// Result (Errno)
//
// The return value is ErrnoSuccess except the following error conditions:
// - sys.EFAULT: `buf` or `bufLen` point to an offset out of memory
// - sys.EIO: a file system error
//
// For example, if underlying random source was seeded like
// `rand.NewSource(42)`, we expect api.Memory to contain:
//
// bufLen (5)
// +--------------------------+
// | |
// []byte{?, 0x53, 0x8c, 0x7f, 0x96, 0xb1, ?}
// buf --^
//
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-bufLen-size---errno
var randomGet = newHostFunc(wasip1.RandomGetName, randomGetFn, []api.ValueType{i32, i32}, "buf", "buf_len")
func randomGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
sysCtx := mod.(*wasm.ModuleInstance).Sys
randSource := sysCtx.RandSource()
buf, bufLen := uint32(params[0]), uint32(params[1])
randomBytes, ok := mod.Memory().Read(buf, bufLen)
if !ok { // out-of-range
return sys.EFAULT
}
// We can ignore the returned n as it only != byteCount on error
if _, err := io.ReadAtLeast(randSource, randomBytes, int(bufLen)); err != nil {
return sys.EIO
}
return 0
}