Skip to content

Commit 9841ac4

Browse files
mathetakedeadprogram
authored andcommitted
WASI & darwin: support env variables based on libc
Signed-off-by: Takeshi Yoneda <[email protected]>
1 parent c299386 commit 9841ac4

File tree

9 files changed

+115
-12
lines changed

9 files changed

+115
-12
lines changed

main_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ func TestCompiler(t *testing.T) {
5858
if runtime.GOOS != "windows" {
5959
t.Run("Host", func(t *testing.T) {
6060
runPlatTests("", matches, t)
61+
if runtime.GOOS == "darwin" {
62+
runTest("testdata/libc/env.go", "", t, []string{"ENV1=VALUE1", "ENV2=VALUE2"}...)
63+
}
6164
})
6265
}
6366

@@ -104,6 +107,7 @@ func TestCompiler(t *testing.T) {
104107

105108
t.Run("WASI", func(t *testing.T) {
106109
runPlatTests("wasi", matches, t)
110+
runTest("testdata/libc/env.go", "wasi", t, []string{"ENV1=VALUE1", "ENV2=VALUE2"}...)
107111
})
108112
}
109113
}
@@ -113,7 +117,6 @@ func runPlatTests(target string, matches []string, t *testing.T) {
113117

114118
for _, path := range matches {
115119
path := path // redefine to avoid race condition
116-
117120
t.Run(filepath.Base(path), func(t *testing.T) {
118121
t.Parallel()
119122
runTest(path, target, t)
@@ -133,7 +136,7 @@ func runBuild(src, out string, opts *compileopts.Options) error {
133136
return Build(src, out, opts)
134137
}
135138

136-
func runTest(path, target string, t *testing.T) {
139+
func runTest(path, target string, t *testing.T, environmentVars ...string) {
137140
// Get the expected output for this test.
138141
txtpath := path[:len(path)-3] + ".txt"
139142
if path[len(path)-1] == os.PathSeparator {
@@ -182,6 +185,7 @@ func runTest(path, target string, t *testing.T) {
182185
ranTooLong := false
183186
if target == "" {
184187
cmd = exec.Command(binary)
188+
cmd.Env = append(cmd.Env, environmentVars...)
185189
} else {
186190
spec, err := compileopts.LoadTarget(target)
187191
if err != nil {
@@ -193,6 +197,14 @@ func runTest(path, target string, t *testing.T) {
193197
args := append(spec.Emulator[1:], binary)
194198
cmd = exec.Command(spec.Emulator[0], args...)
195199
}
200+
201+
if len(spec.Emulator) != 0 && spec.Emulator[0] == "wasmtime" {
202+
for _, v := range environmentVars {
203+
cmd.Args = append(cmd.Args, "--env", v)
204+
}
205+
} else {
206+
cmd.Env = append(cmd.Env, environmentVars...)
207+
}
196208
}
197209
stdout := &bytes.Buffer{}
198210
cmd.Stdout = stdout

src/os/env.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package os
22

3+
import (
4+
"syscall"
5+
)
6+
37
func Getenv(key string) string {
4-
return ""
8+
v, _ := syscall.Getenv(key)
9+
return v
510
}
611

712
func LookupEnv(key string) (string, bool) {
8-
return "", false
13+
return syscall.Getenv(key)
914
}

src/syscall/syscall_baremetal.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build baremetal wasi
1+
// +build baremetal
22

33
package syscall
44

src/syscall/syscall_libc.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
// +build darwin nintendoswitch
1+
// +build darwin nintendoswitch wasi
22

33
package syscall
44

55
import (
66
"unsafe"
77
)
88

9+
type sliceHeader struct {
10+
buf *byte
11+
len uintptr
12+
cap uintptr
13+
}
14+
915
func Close(fd int) (err error) {
1016
return ENOSYS // TODO
1117
}
@@ -48,18 +54,32 @@ func Getpid() (pid int) {
4854
}
4955

5056
func Getenv(key string) (value string, found bool) {
51-
return "", false // TODO
57+
data := append([]byte(key), 0)
58+
raw := libc_getenv(&data[0])
59+
if raw == nil {
60+
return "", false
61+
}
62+
63+
ptr := uintptr(unsafe.Pointer(raw))
64+
for size := uintptr(0); ; size++ {
65+
v := *(*byte)(unsafe.Pointer(ptr))
66+
if v == 0 {
67+
src := *(*[]byte)(unsafe.Pointer(&sliceHeader{buf: raw, len: size, cap: size}))
68+
return string(src), true
69+
}
70+
ptr += unsafe.Sizeof(byte(0))
71+
}
5272
}
5373

5474
func splitSlice(p []byte) (buf *byte, len uintptr) {
55-
slice := (*struct {
56-
buf *byte
57-
len uintptr
58-
cap uintptr
59-
})(unsafe.Pointer(&p))
75+
slice := (*sliceHeader)(unsafe.Pointer(&p))
6076
return slice.buf, slice.len
6177
}
6278

6379
// ssize_t write(int fd, const void *buf, size_t count)
6480
//export write
6581
func libc_write(fd int32, buf *byte, count uint) int
82+
83+
// char *getenv(const char *name);
84+
//export getenv
85+
func libc_getenv(name *byte) *byte
File renamed without changes.
File renamed without changes.

src/syscall/syscall_libc_wasi.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// +build wasi
2+
3+
package syscall
4+
5+
// https://github.com/WebAssembly/wasi-libc/blob/main/expected/wasm32-wasi/predefined-macros.txt
6+
7+
type Signal int
8+
9+
const (
10+
SIGCHLD = 16
11+
SIGINT = 2
12+
SIGKILL = 9
13+
SIGTRAP = 5
14+
SIGQUIT = 3
15+
SIGTERM = 15
16+
)
17+
18+
const (
19+
Stdin = 0
20+
Stdout = 1
21+
Stderr = 2
22+
)
23+
24+
const (
25+
__WASI_OFLAGS_CREAT = 1
26+
__WASI_FDFLAGS_APPEND = 1
27+
__WASI_OFLAGS_EXCL = 4
28+
__WASI_OFLAGS_TRUNC = 8
29+
__WASI_FDFLAGS_SYNC = 16
30+
31+
O_RDONLY = 0x04000000
32+
O_WRONLY = 0x10000000
33+
O_RDWR = O_RDONLY | O_WRONLY
34+
35+
O_CREAT = __WASI_OFLAGS_CREAT << 12
36+
O_CREATE = O_CREAT
37+
O_TRUNC = __WASI_OFLAGS_TRUNC << 12
38+
O_APPEND = __WASI_FDFLAGS_APPEND
39+
O_EXCL = __WASI_OFLAGS_EXCL << 12
40+
O_SYNC = __WASI_FDFLAGS_SYNC
41+
42+
O_CLOEXEC = 0
43+
)
44+
45+
//go:extern errno
46+
var libcErrno uintptr
47+
48+
func getErrno() error {
49+
return Errno(libcErrno)
50+
}

testdata/libc/env.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package main
2+
3+
import (
4+
"os"
5+
)
6+
7+
func main() {
8+
println(os.Getenv("ENV1"))
9+
v, ok := os.LookupEnv("ENV2")
10+
if !ok {
11+
panic("ENV2 not found")
12+
}
13+
println(v)
14+
}

testdata/libc/env.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
VALUE1
2+
VALUE2

0 commit comments

Comments
 (0)