-
Notifications
You must be signed in to change notification settings - Fork 916
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
syscall: split out env logic so wasip2 can do non-libc version
- Loading branch information
Showing
5 changed files
with
111 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//go:build (darwin || nintendoswitch || wasi || wasip1) && !wasip2 | ||
|
||
package syscall | ||
|
||
import ( | ||
"unsafe" | ||
) | ||
|
||
func Environ() []string { | ||
|
||
// This function combines all the environment into a single allocation. | ||
// While this optimizes for memory usage and garbage collector | ||
// overhead, it does run the risk of potentially pinning a "large" | ||
// allocation if a user holds onto a single environment variable or | ||
// value. Having each variable be its own allocation would make the | ||
// trade-off in the other direction. | ||
|
||
// calculate total memory required | ||
var length uintptr | ||
var vars int | ||
for environ := libc_environ; *environ != nil; { | ||
length += libc_strlen(*environ) | ||
vars++ | ||
environ = (*unsafe.Pointer)(unsafe.Add(unsafe.Pointer(environ), unsafe.Sizeof(environ))) | ||
} | ||
|
||
// allocate our backing slice for the strings | ||
b := make([]byte, length) | ||
// and the slice we're going to return | ||
envs := make([]string, 0, vars) | ||
|
||
// loop over the environment again, this time copying over the data to the backing slice | ||
for environ := libc_environ; *environ != nil; { | ||
length = libc_strlen(*environ) | ||
// construct a Go string pointing at the libc-allocated environment variable data | ||
var envVar string | ||
rawEnvVar := (*struct { | ||
ptr unsafe.Pointer | ||
length uintptr | ||
})(unsafe.Pointer(&envVar)) | ||
rawEnvVar.ptr = *environ | ||
rawEnvVar.length = length | ||
// pull off the number of bytes we need for this environment variable | ||
var bs []byte | ||
bs, b = b[:length], b[length:] | ||
// copy over the bytes to the Go heap | ||
copy(bs, envVar) | ||
// convert trimmed slice to string | ||
s := *(*string)(unsafe.Pointer(&bs)) | ||
// add s to our list of environment variables | ||
envs = append(envs, s) | ||
// environ++ | ||
environ = (*unsafe.Pointer)(unsafe.Add(unsafe.Pointer(environ), unsafe.Sizeof(environ))) | ||
} | ||
return envs | ||
} | ||
|
||
//go:extern environ | ||
var libc_environ *unsafe.Pointer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
//go:build wasip2 | ||
|
||
package syscall | ||
|
||
import ( | ||
"unsafe" | ||
) | ||
|
||
type __wasi_list_tuple struct { | ||
ptr unsafe.Pointer | ||
len uint32 | ||
} | ||
|
||
type __wasi_tuple_string_string struct { | ||
first __wasi_string | ||
second __wasi_string | ||
} | ||
|
||
type __wasi_string struct { | ||
data unsafe.Pointer | ||
len uint32 | ||
} | ||
|
||
type _string struct { | ||
ptr *byte | ||
length uintptr | ||
} | ||
|
||
//go:wasmimport wasi:cli/[email protected] get-environment | ||
func __wasi_cli_environment_get_environment() __wasi_list_tuple | ||
|
||
func Environ() []string { | ||
var envs []string | ||
list_tuple := __wasi_cli_environment_get_environment() | ||
envs = make([]string, list_tuple.len) | ||
ptr := list_tuple.ptr | ||
for i := uint32(0); i < list_tuple.len; i++ { | ||
tuple := *(*__wasi_tuple_string_string)(ptr) | ||
first, second := tuple.first, tuple.second | ||
envKey := _string{ | ||
(*byte)(first.data), uintptr(first.len), | ||
} | ||
envValue := _string{ | ||
(*byte)(second.data), uintptr(second.len), | ||
} | ||
envs[i] = *(*string)(unsafe.Pointer(&envKey)) + "=" + *(*string)(unsafe.Pointer(&envValue)) | ||
ptr = unsafe.Add(ptr, unsafe.Sizeof(__wasi_tuple_string_string{})) | ||
} | ||
|
||
return envs | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters