wa-lang.org/wazero@v1.0.2/imports/wasi_snapshot_preview1/environ.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 functionEnvironGet = "environ_get" 12 functionEnvironSizesGet = "environ_sizes_get" 13 ) 14 15 // environGet is the WASI function named functionEnvironGet that reads 16 // environment variables. 17 // 18 // # Parameters 19 // 20 // - environ: offset to begin writing environment offsets in uint32 21 // little-endian encoding to api.Memory 22 // - environSizesGet result environc * 4 bytes are written to this offset 23 // - environBuf: offset to write the null-terminated variables to api.Memory 24 // - the format is like os.Environ: null-terminated "key=val" entries 25 // - environSizesGet result environLen bytes are written to this offset 26 // 27 // Result (Errno) 28 // 29 // The return value is ErrnoSuccess except the following error conditions: 30 // - ErrnoFault: there is not enough memory to write results 31 // 32 // For example, if environSizesGet wrote environc=2 and environLen=9 for 33 // environment variables: "a=b", "b=cd" and parameters environ=11 and 34 // environBuf=1, this function writes the below to api.Memory: 35 // 36 // environLen uint32le uint32le 37 // +------------------------------------+ +--------+ +--------+ 38 // | | | | | | 39 // []byte{?, 'a', '=', 'b', 0, 'b', '=', 'c', 'd', 0, ?, 1, 0, 0, 0, 5, 0, 0, 0, ?} 40 // environBuf --^ ^ ^ 41 // environ offset for "a=b" --+ | 42 // environ offset for "b=cd" --+ 43 // 44 // See environSizesGet 45 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_get 46 // See https://en.wikipedia.org/wiki/Null-terminated_string 47 var environGet = &wasm.HostFunc{ 48 ExportNames: []string{functionEnvironGet}, 49 Name: functionEnvironGet, 50 ParamTypes: []api.ValueType{i32, i32}, 51 ParamNames: []string{"environ", "environ_buf"}, 52 ResultTypes: []api.ValueType{i32}, 53 Code: &wasm.Code{ 54 IsHostFunction: true, 55 GoFunc: wasiFunc(environGetFn), 56 }, 57 } 58 59 func environGetFn(ctx context.Context, mod api.Module, params []uint64) Errno { 60 sysCtx := mod.(*wasm.CallContext).Sys 61 environ, environBuf := uint32(params[0]), uint32(params[1]) 62 63 return writeOffsetsAndNullTerminatedValues(ctx, mod.Memory(), sysCtx.Environ(), environ, environBuf) 64 } 65 66 // environSizesGet is the WASI function named functionEnvironSizesGet that 67 // reads environment variable sizes. 68 // 69 // # Parameters 70 // 71 // - resultEnvironc: offset to write the count of environment variables to 72 // api.Memory 73 // - resultEnvironvLen: offset to write the null-terminated environment 74 // variable length to api.Memory 75 // 76 // Result (Errno) 77 // 78 // The return value is ErrnoSuccess except the following error conditions: 79 // - ErrnoFault: there is not enough memory to write results 80 // 81 // For example, if environ are "a=b","b=cd" and parameters resultEnvironc=1 and 82 // resultEnvironvLen=6, this function writes the below to api.Memory: 83 // 84 // uint32le uint32le 85 // +--------+ +--------+ 86 // | | | | 87 // []byte{?, 2, 0, 0, 0, ?, 9, 0, 0, 0, ?} 88 // resultEnvironc --^ ^ 89 // 2 variables --+ | 90 // resultEnvironvLen --| 91 // len([]byte{'a','=','b',0, | 92 // 'b','=','c','d',0}) --+ 93 // 94 // See environGet 95 // https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_sizes_get 96 // and https://en.wikipedia.org/wiki/Null-terminated_string 97 var environSizesGet = &wasm.HostFunc{ 98 ExportNames: []string{functionEnvironSizesGet}, 99 Name: functionEnvironSizesGet, 100 ParamTypes: []api.ValueType{i32, i32}, 101 ParamNames: []string{"result.environc", "result.environv_len"}, 102 ResultTypes: []api.ValueType{i32}, 103 Code: &wasm.Code{ 104 IsHostFunction: true, 105 GoFunc: wasiFunc(environSizesGetFn), 106 }, 107 } 108 109 func environSizesGetFn(ctx context.Context, mod api.Module, params []uint64) Errno { 110 sysCtx := mod.(*wasm.CallContext).Sys 111 mem := mod.Memory() 112 resultEnvironc, resultEnvironvLen := uint32(params[0]), uint32(params[1]) 113 114 if !mem.WriteUint32Le(ctx, resultEnvironc, uint32(len(sysCtx.Environ()))) { 115 return ErrnoFault 116 } 117 if !mem.WriteUint32Le(ctx, resultEnvironvLen, sysCtx.EnvironSize()) { 118 return ErrnoFault 119 } 120 return ErrnoSuccess 121 }