github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/imports/wasi_snapshot_preview1/args.go (about)

     1  package wasi_snapshot_preview1
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/tetratelabs/wazero/api"
     7  	"github.com/tetratelabs/wazero/experimental/sys"
     8  	"github.com/tetratelabs/wazero/internal/wasip1"
     9  	"github.com/tetratelabs/wazero/internal/wasm"
    10  )
    11  
    12  // argsGet is the WASI function named ArgsGetName that reads command-line
    13  // argument data.
    14  //
    15  // # Parameters
    16  //
    17  //   - argv: offset to begin writing argument offsets in uint32 little-endian
    18  //     encoding to api.Memory
    19  //   - argsSizesGet result argc * 4 bytes are written to this offset
    20  //   - argvBuf: offset to write the null terminated arguments to api.Memory
    21  //   - argsSizesGet result argv_len bytes are written to this offset
    22  //
    23  // Result (Errno)
    24  //
    25  // The return value is ErrnoSuccess except the following error conditions:
    26  //   - sys.EFAULT: there is not enough memory to write results
    27  //
    28  // For example, if argsSizesGet wrote argc=2 and argvLen=5 for arguments:
    29  // "a" and "bc" parameters argv=7 and argvBuf=1, this function writes the below
    30  // to api.Memory:
    31  //
    32  //	                   argvLen          uint32le    uint32le
    33  //	            +----------------+     +--------+  +--------+
    34  //	            |                |     |        |  |        |
    35  //	 []byte{?, 'a', 0, 'b', 'c', 0, ?, 1, 0, 0, 0, 3, 0, 0, 0, ?}
    36  //	argvBuf --^                      ^           ^
    37  //	                          argv --|           |
    38  //	        offset that begins "a" --+           |
    39  //	                   offset that begins "bc" --+
    40  //
    41  // See argsSizesGet
    42  // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_get
    43  // See https://en.wikipedia.org/wiki/Null-terminated_string
    44  var argsGet = newHostFunc(wasip1.ArgsGetName, argsGetFn, []api.ValueType{i32, i32}, "argv", "argv_buf")
    45  
    46  func argsGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
    47  	sysCtx := mod.(*wasm.ModuleInstance).Sys
    48  	argv, argvBuf := uint32(params[0]), uint32(params[1])
    49  	return writeOffsetsAndNullTerminatedValues(mod.Memory(), sysCtx.Args(), argv, argvBuf, sysCtx.ArgsSize())
    50  }
    51  
    52  // argsSizesGet is the WASI function named ArgsSizesGetName that reads
    53  // command-line argument sizes.
    54  //
    55  // # Parameters
    56  //
    57  //   - resultArgc: offset to write the argument count to api.Memory
    58  //   - resultArgvLen: offset to write the null-terminated argument length to
    59  //     api.Memory
    60  //
    61  // Result (Errno)
    62  //
    63  // The return value is ErrnoSuccess except the following error conditions:
    64  //   - sys.EFAULT: there is not enough memory to write results
    65  //
    66  // For example, if args are "a", "bc" and parameters resultArgc=1 and
    67  // resultArgvLen=6, this function writes the below to api.Memory:
    68  //
    69  //	                uint32le       uint32le
    70  //	               +--------+     +--------+
    71  //	               |        |     |        |
    72  //	     []byte{?, 2, 0, 0, 0, ?, 5, 0, 0, 0, ?}
    73  //	  resultArgc --^              ^
    74  //	      2 args --+              |
    75  //	              resultArgvLen --|
    76  //	len([]byte{'a',0,'b',c',0}) --+
    77  //
    78  // See argsGet
    79  // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_sizes_get
    80  // See https://en.wikipedia.org/wiki/Null-terminated_string
    81  var argsSizesGet = newHostFunc(wasip1.ArgsSizesGetName, argsSizesGetFn, []api.ValueType{i32, i32}, "result.argc", "result.argv_len")
    82  
    83  func argsSizesGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
    84  	sysCtx := mod.(*wasm.ModuleInstance).Sys
    85  	mem := mod.Memory()
    86  	resultArgc, resultArgvLen := uint32(params[0]), uint32(params[1])
    87  
    88  	// argc and argv_len offsets are not necessarily sequential, so we have to
    89  	// write them independently.
    90  	if !mem.WriteUint32Le(resultArgc, uint32(len(sysCtx.Args()))) {
    91  		return sys.EFAULT
    92  	}
    93  	if !mem.WriteUint32Le(resultArgvLen, sysCtx.ArgsSize()) {
    94  		return sys.EFAULT
    95  	}
    96  	return 0
    97  }