github.com/primecitizens/pcz/std@v0.2.1/core/sys/os_wasi.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 4 //go:build !noos && wasip1 5 6 package sys 7 8 import ( 9 "unsafe" 10 11 "github.com/primecitizens/pcz/std/core/assert" 12 "github.com/primecitizens/pcz/std/ffi/wasm/wasi" 13 ) 14 15 var ( 16 args []string 17 envs []string 18 ) 19 20 func ntharg(i int) string { 21 return args[i] 22 } 23 24 func nthenv(i int) string { 25 return envs[i] 26 } 27 28 func init() { 29 argc, argSz, errno := wasi.ArgsSizes() 30 if errno != 0 { 31 assert.Throw("args_sizes_get", "failed") 32 } 33 34 envc, envSz, errno := wasi.EnvironSizes() 35 if errno != 0 { 36 assert.Throw("environ_sizes_get", "failed") 37 } 38 39 // defensive: ensure size is zero when count is zero. 40 if argc == 0 { 41 argSz = 0 42 } 43 if envc == 0 { 44 envSz = 0 45 } 46 47 if argSz == 0 && envSz == 0 { 48 return 49 } 50 51 type uintptr32 = uint32 52 53 totalSize := uintptr(envSz) + uintptr(argSz) + 54 unsafe.Sizeof(string(""))*(uintptr(envc)+uintptr(argc)) 55 56 buf := make([]byte, totalSize) 57 args = unsafe.Slice( 58 (*string)(unsafe.Pointer(unsafe.SliceData(buf))), 59 argc, 60 ) 61 62 buf = buf[uintptr(argc)*unsafe.Sizeof(string("")):] 63 envs = unsafe.Slice( 64 (*string)(unsafe.Pointer(unsafe.SliceData(buf))), 65 envc, 66 ) 67 buf = buf[uintptr(envc)*unsafe.Sizeof(string("")):] 68 69 if argSz != 0 { 70 argv := unsafe.Slice((*uintptr32)(unsafe.Pointer(unsafe.SliceData(args))), argc) 71 if wasi.ArgsGet( 72 unsafe.Pointer(unsafe.SliceData(argv)), 73 unsafe.Pointer(unsafe.SliceData(buf)), 74 ) != 0 { 75 assert.Throw("args_get", "failed") 76 } 77 78 for argc > 0 { 79 argc-- 80 start := argv[argc] - uintptr32(uintptr(unsafe.Pointer(unsafe.SliceData(buf)))) 81 end := start 82 for buf[end] != 0 { 83 end++ 84 } 85 args[argc] = unsafe.String(&buf[start], end-start) 86 } 87 88 buf = buf[argSz:] 89 } 90 91 if envSz != 0 { 92 envv := unsafe.Slice((*uintptr32)(unsafe.Pointer(unsafe.SliceData(envs))), envc) 93 if wasi.Environ( 94 unsafe.Pointer(unsafe.SliceData(envv)), 95 unsafe.Pointer(unsafe.SliceData(buf)), 96 ) != 0 { 97 assert.Throw("environ_get", "failed") 98 } 99 100 for envc > 0 { 101 envc-- 102 start := envv[envc] - uintptr32(uintptr(unsafe.Pointer(unsafe.SliceData(buf)))) 103 end := start 104 for buf[end] != 0 { 105 end++ 106 } 107 envs[envc] = unsafe.String(&buf[start], end-start) 108 } 109 } 110 }