Skip to content

Commit 2712b93

Browse files
committed
feat: add wasip3 behind flag
1 parent a64d084 commit 2712b93

33 files changed

Lines changed: 2585 additions & 1148 deletions

.cargo/config.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
[target.wasm32-wasip2]
22
# wasmtime is given:
3+
# * p3 enabled for wasip3 component support (backwards compat with p2)
4+
# * http enabled for wasi-http tests
35
# * AWS auth environment variables, for running the wstd-aws integration tests.
46
# * . directory is available at .
5-
runner = "wasmtime run -Shttp --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN --dir .::."
7+
runner = "wasmtime run -Wcomponent-model-async -Wcomponent-model-async-builtins -Wcomponent-model-async-stackful -Sp3 -Shttp --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN --dir .::."

.github/workflows/ci.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,12 @@ jobs:
5151
- name: check
5252
run: cargo check --workspace --all --bins --examples
5353

54-
- name: wstd tests
54+
- name: wstd tests (wasip2)
5555
run: cargo test -p wstd -p wstd-axum --target wasm32-wasip2 -- --nocapture
5656

57+
- name: wstd tests (wasip3)
58+
run: cargo test -p wstd -p wstd-axum --target wasm32-wasip2 --no-default-features --features wasip3 -- --nocapture
59+
5760
- name: test-programs tests
5861
run: cargo test -p test-programs -- --nocapture
5962
if: steps.creds.outcome == 'success'

Cargo.toml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ repository.workspace = true
1313
rust-version.workspace = true
1414

1515
[features]
16-
default = ["json"]
16+
default = ["json", "wasip2"]
1717
json = ["dep:serde", "dep:serde_json"]
18+
wasip2 = ["dep:wasip2"]
19+
wasip3 = ["dep:wasip3", "dep:wit-bindgen"]
1820

1921
[dependencies]
2022
anyhow.workspace = true
@@ -27,7 +29,9 @@ http.workspace = true
2729
itoa.workspace = true
2830
pin-project-lite.workspace = true
2931
slab.workspace = true
30-
wasip2.workspace = true
32+
wasip2 = { workspace = true, optional = true }
33+
wasip3 = { workspace = true, optional = true }
34+
wit-bindgen = { workspace = true, optional = true }
3135
wstd-macro.workspace = true
3236

3337
# optional
@@ -95,13 +99,15 @@ test-programs = { path = "test-programs" }
9599
tower-service = "0.3.3"
96100
ureq = { version = "3.1", default-features = false, features = ["json"] }
97101
wasip2 = "1.0"
98-
wstd = { path = ".", version = "=0.6.6" }
102+
wasip3 = "0.5"
103+
wit-bindgen = { version = "0.54", default-features = false, features = ["async", "async-spawn", "inter-task-wakeup"] }
104+
wstd = { path = ".", version = "=0.6.6", default-features = false }
99105
wstd-axum = { path = "./axum", version = "=0.6.6" }
100106
wstd-axum-macro = { path = "./axum/macro", version = "=0.6.6" }
101107
wstd-macro = { path = "./macro", version = "=0.6.6" }
102108

103109
[package.metadata.docs.rs]
104110
all-features = true
105111
targets = [
106-
"wasm32-wasip2"
112+
"wasm32-wasip2",
107113
]

axum/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ categories.workspace = true
1010
repository.workspace = true
1111
rust-version.workspace = true
1212

13+
[features]
14+
default = ["wasip2"]
15+
wasip2 = ["wstd/wasip2"]
16+
wasip3 = ["wstd/wasip3"]
17+
1318
[dependencies]
1419
axum.workspace = true
1520
tower-service.workspace = true
16-
wstd.workspace = true
21+
wstd = { workspace = true, default-features = false }
1722
wstd-axum-macro.workspace = true
1823

1924
[dev-dependencies]

macro/src/lib.rs

Lines changed: 23 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,6 @@ pub fn attr_macro_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
100100
pub fn attr_macro_http_server(_attr: TokenStream, item: TokenStream) -> TokenStream {
101101
let input = parse_macro_input!(item as ItemFn);
102102

103-
let (run_async, run_await) = if input.sig.asyncness.is_some() {
104-
(quote!(async), quote!(.await))
105-
} else {
106-
(quote!(), quote!())
107-
};
108-
109103
let output = &input.sig.output;
110104
let inputs = &input.sig.inputs;
111105
let name = &input.sig.ident;
@@ -120,63 +114,32 @@ pub fn attr_macro_http_server(_attr: TokenStream, item: TokenStream) -> TokenStr
120114
.into();
121115
}
122116

117+
// Delegate to wstd's conditionally-compiled declarative macro.
118+
// The `cfg` checks in `__http_server_export!` run in wstd's context,
119+
// so consumers don't need to define wasip2/wasip3 features themselves.
120+
//
121+
// We use @async/@sync markers so the declarative macro can construct
122+
// the handler call in its own hygiene context (avoiding variable name
123+
// mismatches between proc macro and declarative macro scopes)
124+
// NOTE: we can avoid this once wasm32-wasip3 is an available target
125+
let asyncness = if input.sig.asyncness.is_some() {
126+
quote!(@async)
127+
} else {
128+
quote!(@sync)
129+
};
130+
131+
let run_async = if input.sig.asyncness.is_some() {
132+
quote!(async)
133+
} else {
134+
quote!()
135+
};
136+
123137
quote! {
124-
struct TheServer;
125-
126-
impl ::wstd::__internal::wasip2::exports::http::incoming_handler::Guest for TheServer {
127-
fn handle(
128-
request: ::wstd::__internal::wasip2::http::types::IncomingRequest,
129-
response_out: ::wstd::__internal::wasip2::http::types::ResponseOutparam
130-
) {
131-
#(#attrs)*
132-
#vis #run_async fn __run(#inputs) #output {
133-
#body
134-
}
135-
136-
let responder = ::wstd::http::server::Responder::new(response_out);
137-
::wstd::runtime::block_on(async move {
138-
match ::wstd::http::request::try_from_incoming(request) {
139-
Ok(request) => match __run(request) #run_await {
140-
Ok(response) => { responder.respond(response).await.unwrap() },
141-
Err(err) => responder.fail(err),
142-
}
143-
Err(err) => responder.fail(err),
144-
}
145-
})
146-
}
138+
::wstd::__http_server_export! {
139+
#asyncness
140+
{ #(#attrs)* #vis #run_async fn __run(#inputs) #output { #body } }
147141
}
148142

149-
::wstd::__internal::wasip2::http::proxy::export!(TheServer with_types_in ::wstd::__internal::wasip2);
150-
151-
// Provide an actual function named `main`.
152-
//
153-
// WASI HTTP server components don't use a traditional `main` function.
154-
// They export a function named `handle` which takes a `Request`
155-
// argument, and which may be called multiple times on the same
156-
// instance. To let users write a familiar `fn main` in a file
157-
// named src/main.rs, we provide this `wstd::http_server` macro, which
158-
// transforms the user's `fn main` into the appropriate `handle`
159-
// function.
160-
//
161-
// However, when the top-level file is named src/main.rs, rustc
162-
// requires there to be a function named `main` somewhere in it. This
163-
// requirement can be disabled using `#![no_main]`, however we can't
164-
// use that automatically because macros can't contain inner
165-
// attributes, and we don't want to require users to add `#![no_main]`
166-
// in their own code.
167-
//
168-
// So, we include a definition of a function named `main` here, which
169-
// isn't intended to ever be called, and exists just to satify the
170-
// requirement for a `main` function.
171-
//
172-
// Users could use `#![no_main]` if they want to. Or, they could name
173-
// their top-level file src/lib.rs and add
174-
// ```toml
175-
// [lib]
176-
// crate-type = ["cdylib"]
177-
// ```
178-
// to their Cargo.toml. With either of these, this "main" function will
179-
// be ignored as dead code.
180143
fn main() {
181144
unreachable!("HTTP server components should be run with `handle` rather than `run`")
182145
}

0 commit comments

Comments
 (0)