wa-lang.org/wazero@v1.0.2/internal/gojs/argsenv.go (about) 1 package gojs 2 3 import ( 4 "context" 5 "errors" 6 7 "wa-lang.org/wazero/api" 8 "wa-lang.org/wazero/internal/wasm" 9 ) 10 11 // Constants about memory layout. See REFERENCE.md 12 const ( 13 endOfPageZero = uint32(4096) // runtime.minLegalPointer 14 maxArgsAndEnviron = uint32(8192) // ld.wasmMinDataAddr - runtime.minLegalPointer 15 wasmMinDataAddr = endOfPageZero + maxArgsAndEnviron // ld.wasmMinDataAddr 16 ) 17 18 // WriteArgsAndEnviron writes arguments and environment variables to memory, so 19 // they can be read by main, Go compiles as the function export "run". 20 func WriteArgsAndEnviron(ctx context.Context, mod api.Module) (argc, argv uint32, err error) { 21 mem := mod.Memory() 22 sysCtx := mod.(*wasm.CallContext).Sys 23 args := sysCtx.Args() 24 environ := sysCtx.Environ() 25 26 argc = uint32(len(args)) 27 offset := endOfPageZero 28 29 strPtr := func(val, field string, i int) (ptr uint32) { 30 // TODO: return err and format "%s[%d], field, i" 31 ptr = offset 32 mustWrite(ctx, mem, field, offset, append([]byte(val), 0)) 33 offset += uint32(len(val) + 1) 34 if pad := offset % 8; pad != 0 { 35 offset += 8 - pad 36 } 37 return 38 } 39 argvPtrs := make([]uint32, 0, len(args)+1+len(environ)+1) 40 for i, arg := range args { 41 argvPtrs = append(argvPtrs, strPtr(arg, "args", i)) 42 } 43 argvPtrs = append(argvPtrs, 0) 44 45 for i, env := range environ { 46 argvPtrs = append(argvPtrs, strPtr(env, "env", i)) 47 } 48 argvPtrs = append(argvPtrs, 0) 49 50 argv = offset 51 for _, ptr := range argvPtrs { 52 // TODO: return err and format "argvPtrs[%d], i" 53 mustWriteUint64Le(ctx, mem, "argvPtrs[i]", offset, uint64(ptr)) 54 offset += 8 55 } 56 57 if offset >= wasmMinDataAddr { 58 err = errors.New("total length of command line and environment variables exceeds limit") 59 } 60 return 61 }