wa-lang.org/wazero@v1.0.2/imports/wasi_snapshot_preview1/args.go (about)

     1  package wasi_snapshot_preview1
     2  
     3  import (
     4  	"context"
     5  
     6  	"wa-lang.org/wazero/api"
     7  	"wa-lang.org/wazero/internal/wasm"
     8  )
     9  
    10  const (
    11  	functionArgsGet      = "args_get"
    12  	functionArgsSizesGet = "args_sizes_get"
    13  )
    14  
    15  // argsGet is the WASI function named functionArgsGet that reads command-line
    16  // argument data.
    17  //
    18  // # Parameters
    19  //
    20  //   - argv: offset to begin writing argument offsets in uint32 little-endian
    21  //     encoding to api.Memory
    22  //   - argsSizesGet result argc * 4 bytes are written to this offset
    23  //   - argvBuf: offset to write the null terminated arguments to api.Memory
    24  //   - argsSizesGet result argv_len bytes are written to this offset
    25  //
    26  // Result (Errno)
    27  //
    28  // The return value is ErrnoSuccess except the following error conditions:
    29  //   - ErrnoFault: there is not enough memory to write results
    30  //
    31  // For example, if argsSizesGet wrote argc=2 and argvLen=5 for arguments:
    32  // "a" and "bc" parameters argv=7 and argvBuf=1, this function writes the below
    33  // to api.Memory:
    34  //
    35  //	                   argvLen          uint32le    uint32le
    36  //	            +----------------+     +--------+  +--------+
    37  //	            |                |     |        |  |        |
    38  //	 []byte{?, 'a', 0, 'b', 'c', 0, ?, 1, 0, 0, 0, 3, 0, 0, 0, ?}
    39  //	argvBuf --^                      ^           ^
    40  //	                          argv --|           |
    41  //	        offset that begins "a" --+           |
    42  //	                   offset that begins "bc" --+
    43  //
    44  // See argsSizesGet
    45  // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_get
    46  // See https://en.wikipedia.org/wiki/Null-terminated_string
    47  var argsGet = &wasm.HostFunc{
    48  	ExportNames: []string{functionArgsGet},
    49  	Name:        functionArgsGet,
    50  	ParamTypes:  []api.ValueType{i32, i32},
    51  	ParamNames:  []string{"argv", "argv_buf"},
    52  	ResultTypes: []api.ValueType{i32},
    53  	Code: &wasm.Code{
    54  		IsHostFunction: true,
    55  		GoFunc:         wasiFunc(argsGetFn),
    56  	},
    57  }
    58  
    59  func argsGetFn(ctx context.Context, mod api.Module, params []uint64) Errno {
    60  	sysCtx := mod.(*wasm.CallContext).Sys
    61  	argv, argvBuf := uint32(params[0]), uint32(params[1])
    62  	return writeOffsetsAndNullTerminatedValues(ctx, mod.Memory(), sysCtx.Args(), argv, argvBuf)
    63  }
    64  
    65  // argsSizesGet is the WASI function named functionArgsSizesGet that reads
    66  // command-line argument sizes.
    67  //
    68  // # Parameters
    69  //
    70  //   - resultArgc: offset to write the argument count to api.Memory
    71  //   - resultArgvLen: offset to write the null-terminated argument length to
    72  //     api.Memory
    73  //
    74  // Result (Errno)
    75  //
    76  // The return value is ErrnoSuccess except the following error conditions:
    77  //   - ErrnoFault: there is not enough memory to write results
    78  //
    79  // For example, if args are "a", "bc" and parameters resultArgc=1 and
    80  // resultArgvLen=6, this function writes the below to api.Memory:
    81  //
    82  //	                uint32le       uint32le
    83  //	               +--------+     +--------+
    84  //	               |        |     |        |
    85  //	     []byte{?, 2, 0, 0, 0, ?, 5, 0, 0, 0, ?}
    86  //	  resultArgc --^              ^
    87  //	      2 args --+              |
    88  //	              resultArgvLen --|
    89  //	len([]byte{'a',0,'b',c',0}) --+
    90  //
    91  // See argsGet
    92  // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_sizes_get
    93  // See https://en.wikipedia.org/wiki/Null-terminated_string
    94  var argsSizesGet = &wasm.HostFunc{
    95  	ExportNames: []string{functionArgsSizesGet},
    96  	Name:        functionArgsSizesGet,
    97  	ParamTypes:  []api.ValueType{i32, i32},
    98  	ParamNames:  []string{"result.argc", "result.argv_len"},
    99  	ResultTypes: []api.ValueType{i32},
   100  	Code: &wasm.Code{
   101  		IsHostFunction: true,
   102  		GoFunc:         wasiFunc(argsSizesGetFn),
   103  	},
   104  }
   105  
   106  func argsSizesGetFn(ctx context.Context, mod api.Module, params []uint64) Errno {
   107  	sysCtx := mod.(*wasm.CallContext).Sys
   108  	mem := mod.Memory()
   109  	resultArgc, resultArgvLen := uint32(params[0]), uint32(params[1])
   110  
   111  	// Write the Errno back to the stack
   112  	if !mem.WriteUint32Le(ctx, resultArgc, uint32(len(sysCtx.Args()))) {
   113  		return ErrnoFault
   114  	}
   115  	if !mem.WriteUint32Le(ctx, resultArgvLen, sysCtx.ArgsSize()) {
   116  		return ErrnoFault
   117  	}
   118  	return ErrnoSuccess
   119  }