Skip to content

Commit 0f17434

Browse files
committed
fix support for packages split across multiple WIT paths
This also adds a test for the case, updates the WASIp3 WIT files to 0.3.0-rc-2026-03-15, and updates the Wasmtime used in CI to 43.0.0.
1 parent 84179ab commit 0f17434

45 files changed

Lines changed: 4747 additions & 2140 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/pr.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ jobs:
3636
go-version: 'stable'
3737
- uses: bytecodealliance/actions/wasmtime/setup@v1
3838
with:
39-
version: "40.0.2"
39+
version: "43.0.0"
4040
- run: rustup update stable --no-self-update && rustup default stable
4141
- run: cargo test --workspace
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package export_wasi_http_handler
2+
3+
import (
4+
. "wit_component/wasi_http_types"
5+
6+
. "go.bytecodealliance.org/pkg/wit/types"
7+
)
8+
9+
// Handle the specified `Request`, returning a `Response`
10+
func Handle(request *Request) Result[*Response, ErrorCode] {
11+
method := request.GetMethod().Tag()
12+
path := request.GetPathWithQuery().SomeOr("/")
13+
14+
if method == MethodGet && path == "/hello" {
15+
// Say hello!
16+
17+
tx, rx := MakeStreamU8()
18+
19+
go func() {
20+
defer tx.Drop()
21+
tx.WriteAll([]uint8("Hello, world!"))
22+
}()
23+
24+
response, send := ResponseNew(
25+
FieldsFromList([]Tuple2[string, []byte]{
26+
{F0: "content-type", F1: []byte("text/plain")},
27+
}).Ok(),
28+
Some(rx),
29+
trailersFuture(),
30+
)
31+
send.Drop()
32+
33+
return Ok[*Response, ErrorCode](response)
34+
35+
} else {
36+
// Bad request
37+
38+
response, send := ResponseNew(
39+
MakeFields(),
40+
None[*StreamReader[uint8]](),
41+
trailersFuture(),
42+
)
43+
send.Drop()
44+
response.SetStatusCode(400).Ok()
45+
46+
return Ok[*Response, ErrorCode](response)
47+
48+
}
49+
}
50+
51+
func trailersFuture() *FutureReader[Result[Option[*Fields], ErrorCode]] {
52+
tx, rx := MakeFutureResultOptionFieldsErrorCode()
53+
go tx.Write(Ok[Option[*Fields], ErrorCode](None[*Fields]()))
54+
return rx
55+
}
56+
57+
func unitFuture() *FutureReader[Result[Unit, ErrorCode]] {
58+
tx, rx := MakeFutureResultUnitErrorCode()
59+
go tx.Write(Ok[Unit, ErrorCode](Unit{}))
60+
return rx
61+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package export_wit_world
2+
3+
func Foo() {}
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
package wasi:cli@0.3.0-rc-2026-03-15;
2+
3+
@since(version = 0.3.0-rc-2026-03-15)
4+
interface environment {
5+
/// Get the POSIX-style environment variables.
6+
///
7+
/// Each environment variable is provided as a pair of string variable names
8+
/// and string value.
9+
///
10+
/// Morally, these are a value import, but until value imports are available
11+
/// in the component model, this import function should return the same
12+
/// values each time it is called.
13+
@since(version = 0.3.0-rc-2026-03-15)
14+
get-environment: func() -> list<tuple<string, string>>;
15+
16+
/// Get the POSIX-style arguments to the program.
17+
@since(version = 0.3.0-rc-2026-03-15)
18+
get-arguments: func() -> list<string>;
19+
20+
/// Return a path that programs should use as their initial current working
21+
/// directory, interpreting `.` as shorthand for this.
22+
@since(version = 0.3.0-rc-2026-03-15)
23+
get-initial-cwd: func() -> option<string>;
24+
}
25+
26+
@since(version = 0.3.0-rc-2026-03-15)
27+
interface exit {
28+
/// Exit the current instance and any linked instances.
29+
@since(version = 0.3.0-rc-2026-03-15)
30+
exit: func(status: result);
31+
32+
/// Exit the current instance and any linked instances, reporting the
33+
/// specified status code to the host.
34+
///
35+
/// The meaning of the code depends on the context, with 0 usually meaning
36+
/// "success", and other values indicating various types of failure.
37+
///
38+
/// This function does not return; the effect is analogous to a trap, but
39+
/// without the connotation that something bad has happened.
40+
@unstable(feature = cli-exit-with-code)
41+
exit-with-code: func(status-code: u8);
42+
}
43+
44+
@since(version = 0.3.0-rc-2026-03-15)
45+
interface run {
46+
/// Run the program.
47+
@since(version = 0.3.0-rc-2026-03-15)
48+
run: async func() -> result;
49+
}
50+
51+
@since(version = 0.3.0-rc-2026-03-15)
52+
interface types {
53+
@since(version = 0.3.0-rc-2026-03-15)
54+
enum error-code {
55+
/// Input/output error
56+
io,
57+
/// Invalid or incomplete multibyte or wide character
58+
illegal-byte-sequence,
59+
/// Broken pipe
60+
pipe,
61+
}
62+
}
63+
64+
@since(version = 0.3.0-rc-2026-03-15)
65+
interface stdin {
66+
use types.{error-code};
67+
68+
/// Return a stream for reading from stdin.
69+
///
70+
/// This function returns a stream which provides data read from stdin,
71+
/// and a future to signal read results.
72+
///
73+
/// If the stream's readable end is dropped the future will resolve to success.
74+
///
75+
/// If the stream's writable end is dropped the future will either resolve to
76+
/// success if stdin was closed by the writer or to an error-code if reading
77+
/// failed for some other reason.
78+
///
79+
/// Multiple streams may be active at the same time. The behavior of concurrent
80+
/// reads is implementation-specific.
81+
@since(version = 0.3.0-rc-2026-03-15)
82+
read-via-stream: func() -> tuple<stream<u8>, future<result<_, error-code>>>;
83+
}
84+
85+
@since(version = 0.3.0-rc-2026-03-15)
86+
interface stdout {
87+
use types.{error-code};
88+
89+
/// Write the given stream to stdout.
90+
///
91+
/// If the stream's writable end is dropped this function will either return
92+
/// success once the entire contents of the stream have been written or an
93+
/// error-code representing a failure.
94+
///
95+
/// Otherwise if there is an error the readable end of the stream will be
96+
/// dropped and this function will return an error-code.
97+
@since(version = 0.3.0-rc-2026-03-15)
98+
write-via-stream: func(data: stream<u8>) -> future<result<_, error-code>>;
99+
}
100+
101+
@since(version = 0.3.0-rc-2026-03-15)
102+
interface stderr {
103+
use types.{error-code};
104+
105+
/// Write the given stream to stderr.
106+
///
107+
/// If the stream's writable end is dropped this function will either return
108+
/// success once the entire contents of the stream have been written or an
109+
/// error-code representing a failure.
110+
///
111+
/// Otherwise if there is an error the readable end of the stream will be
112+
/// dropped and this function will return an error-code.
113+
@since(version = 0.3.0-rc-2026-03-15)
114+
write-via-stream: func(data: stream<u8>) -> future<result<_, error-code>>;
115+
}
116+
117+
/// Terminal input.
118+
///
119+
/// In the future, this may include functions for disabling echoing,
120+
/// disabling input buffering so that keyboard events are sent through
121+
/// immediately, querying supported features, and so on.
122+
@since(version = 0.3.0-rc-2026-03-15)
123+
interface terminal-input {
124+
/// The input side of a terminal.
125+
@since(version = 0.3.0-rc-2026-03-15)
126+
resource terminal-input;
127+
}
128+
129+
/// Terminal output.
130+
///
131+
/// In the future, this may include functions for querying the terminal
132+
/// size, being notified of terminal size changes, querying supported
133+
/// features, and so on.
134+
@since(version = 0.3.0-rc-2026-03-15)
135+
interface terminal-output {
136+
/// The output side of a terminal.
137+
@since(version = 0.3.0-rc-2026-03-15)
138+
resource terminal-output;
139+
}
140+
141+
/// An interface providing an optional `terminal-input` for stdin as a
142+
/// link-time authority.
143+
@since(version = 0.3.0-rc-2026-03-15)
144+
interface terminal-stdin {
145+
@since(version = 0.3.0-rc-2026-03-15)
146+
use terminal-input.{terminal-input};
147+
148+
/// If stdin is connected to a terminal, return a `terminal-input` handle
149+
/// allowing further interaction with it.
150+
@since(version = 0.3.0-rc-2026-03-15)
151+
get-terminal-stdin: func() -> option<terminal-input>;
152+
}
153+
154+
/// An interface providing an optional `terminal-output` for stdout as a
155+
/// link-time authority.
156+
@since(version = 0.3.0-rc-2026-03-15)
157+
interface terminal-stdout {
158+
@since(version = 0.3.0-rc-2026-03-15)
159+
use terminal-output.{terminal-output};
160+
161+
/// If stdout is connected to a terminal, return a `terminal-output` handle
162+
/// allowing further interaction with it.
163+
@since(version = 0.3.0-rc-2026-03-15)
164+
get-terminal-stdout: func() -> option<terminal-output>;
165+
}
166+
167+
/// An interface providing an optional `terminal-output` for stderr as a
168+
/// link-time authority.
169+
@since(version = 0.3.0-rc-2026-03-15)
170+
interface terminal-stderr {
171+
@since(version = 0.3.0-rc-2026-03-15)
172+
use terminal-output.{terminal-output};
173+
174+
/// If stderr is connected to a terminal, return a `terminal-output` handle
175+
/// allowing further interaction with it.
176+
@since(version = 0.3.0-rc-2026-03-15)
177+
get-terminal-stderr: func() -> option<terminal-output>;
178+
}
179+
180+
@since(version = 0.3.0-rc-2026-03-15)
181+
world imports {
182+
@since(version = 0.3.0-rc-2026-03-15)
183+
import environment;
184+
@since(version = 0.3.0-rc-2026-03-15)
185+
import exit;
186+
@since(version = 0.3.0-rc-2026-03-15)
187+
import types;
188+
@since(version = 0.3.0-rc-2026-03-15)
189+
import stdin;
190+
@since(version = 0.3.0-rc-2026-03-15)
191+
import stdout;
192+
@since(version = 0.3.0-rc-2026-03-15)
193+
import stderr;
194+
@since(version = 0.3.0-rc-2026-03-15)
195+
import terminal-input;
196+
@since(version = 0.3.0-rc-2026-03-15)
197+
import terminal-output;
198+
@since(version = 0.3.0-rc-2026-03-15)
199+
import terminal-stdin;
200+
@since(version = 0.3.0-rc-2026-03-15)
201+
import terminal-stdout;
202+
@since(version = 0.3.0-rc-2026-03-15)
203+
import terminal-stderr;
204+
import wasi:clocks/types@0.3.0-rc-2026-03-15;
205+
import wasi:clocks/monotonic-clock@0.3.0-rc-2026-03-15;
206+
import wasi:clocks/system-clock@0.3.0-rc-2026-03-15;
207+
@unstable(feature = clocks-timezone)
208+
import wasi:clocks/timezone@0.3.0-rc-2026-03-15;
209+
import wasi:filesystem/types@0.3.0-rc-2026-03-15;
210+
import wasi:filesystem/preopens@0.3.0-rc-2026-03-15;
211+
import wasi:sockets/types@0.3.0-rc-2026-03-15;
212+
import wasi:sockets/ip-name-lookup@0.3.0-rc-2026-03-15;
213+
import wasi:random/random@0.3.0-rc-2026-03-15;
214+
import wasi:random/insecure@0.3.0-rc-2026-03-15;
215+
import wasi:random/insecure-seed@0.3.0-rc-2026-03-15;
216+
}
217+
@since(version = 0.3.0-rc-2026-03-15)
218+
world command {
219+
@since(version = 0.3.0-rc-2026-03-15)
220+
import environment;
221+
@since(version = 0.3.0-rc-2026-03-15)
222+
import exit;
223+
@since(version = 0.3.0-rc-2026-03-15)
224+
import types;
225+
@since(version = 0.3.0-rc-2026-03-15)
226+
import stdin;
227+
@since(version = 0.3.0-rc-2026-03-15)
228+
import stdout;
229+
@since(version = 0.3.0-rc-2026-03-15)
230+
import stderr;
231+
@since(version = 0.3.0-rc-2026-03-15)
232+
import terminal-input;
233+
@since(version = 0.3.0-rc-2026-03-15)
234+
import terminal-output;
235+
@since(version = 0.3.0-rc-2026-03-15)
236+
import terminal-stdin;
237+
@since(version = 0.3.0-rc-2026-03-15)
238+
import terminal-stdout;
239+
@since(version = 0.3.0-rc-2026-03-15)
240+
import terminal-stderr;
241+
import wasi:clocks/types@0.3.0-rc-2026-03-15;
242+
import wasi:clocks/monotonic-clock@0.3.0-rc-2026-03-15;
243+
import wasi:clocks/system-clock@0.3.0-rc-2026-03-15;
244+
@unstable(feature = clocks-timezone)
245+
import wasi:clocks/timezone@0.3.0-rc-2026-03-15;
246+
import wasi:filesystem/types@0.3.0-rc-2026-03-15;
247+
import wasi:filesystem/preopens@0.3.0-rc-2026-03-15;
248+
import wasi:sockets/types@0.3.0-rc-2026-03-15;
249+
import wasi:sockets/ip-name-lookup@0.3.0-rc-2026-03-15;
250+
import wasi:random/random@0.3.0-rc-2026-03-15;
251+
import wasi:random/insecure@0.3.0-rc-2026-03-15;
252+
import wasi:random/insecure-seed@0.3.0-rc-2026-03-15;
253+
254+
@since(version = 0.3.0-rc-2026-03-15)
255+
export run;
256+
}

0 commit comments

Comments
 (0)