packc/
component_host_stubs.rs1#![forbid(unsafe_code)]
2
3use anyhow::Result;
4use wasmtime::component::Linker;
5use wasmtime_wasi::p2::add_to_linker_sync;
6use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxBuilder, WasiCtxView, WasiView};
7use wasmtime_wasi_http::WasiHttpCtx;
8use wasmtime_wasi_http::p2::{WasiHttpCtxView, WasiHttpView, add_only_http_to_linker_sync};
9use wasmtime_wasi_tls::p2::{
10 LinkOptions as WasiTlsLinkOptions, add_to_linker as add_tls_to_linker,
11};
12use wasmtime_wasi_tls::{
13 UnsupportedProvider, WasiTlsCtx, WasiTlsCtxBuilder, WasiTlsCtxView, WasiTlsView,
14};
15
16pub struct DescribeHostState {
17 table: ResourceTable,
18 wasi: WasiCtx,
19 wasi_http: WasiHttpCtx,
20 wasi_tls: WasiTlsCtx,
21}
22
23impl Default for DescribeHostState {
24 fn default() -> Self {
25 let _ = rustls::crypto::ring::default_provider().install_default();
28 let mut wasi = WasiCtxBuilder::new();
29 Self {
30 table: ResourceTable::new(),
31 wasi: wasi.build(),
32 wasi_http: WasiHttpCtx::new(),
33 wasi_tls: WasiTlsCtxBuilder::new()
34 .provider(Box::new(UnsupportedProvider::default()))
35 .build(),
36 }
37 }
38}
39
40impl WasiView for DescribeHostState {
41 fn ctx(&mut self) -> WasiCtxView<'_> {
42 WasiCtxView {
43 table: &mut self.table,
44 ctx: &mut self.wasi,
45 }
46 }
47}
48
49impl WasiHttpView for DescribeHostState {
50 fn http(&mut self) -> WasiHttpCtxView<'_> {
51 WasiHttpCtxView {
52 ctx: &mut self.wasi_http,
53 table: &mut self.table,
54 hooks: Default::default(),
55 }
56 }
57}
58
59impl WasiTlsView for DescribeHostState {
60 fn tls(&mut self) -> WasiTlsCtxView<'_> {
61 WasiTlsCtxView {
62 ctx: &mut self.wasi_tls,
63 table: &mut self.table,
64 }
65 }
66}
67
68pub fn add_describe_host_imports(linker: &mut Linker<DescribeHostState>) -> Result<()> {
69 linker.allow_shadowing(true);
72
73 add_to_linker_sync(linker)
74 .map_err(|err| anyhow::anyhow!("register wasi preview2 describe host stubs: {err}"))?;
75
76 let mut tls_options = WasiTlsLinkOptions::default();
77 tls_options.tls(true);
78 add_tls_to_linker(linker, &tls_options)
79 .map_err(|err| anyhow::anyhow!("register wasi tls describe host stubs: {err}"))?;
80
81 add_only_http_to_linker_sync(linker)
82 .map_err(|err| anyhow::anyhow!("register wasi http describe host stubs: {err}"))?;
83
84 Ok(())
91}
92
93pub fn stub_remaining_imports(
100 linker: &mut Linker<DescribeHostState>,
101 component: &wasmtime::component::Component,
102) -> Result<()> {
103 linker
104 .define_unknown_imports_as_traps(component)
105 .map_err(|err| anyhow::anyhow!("stub remaining component imports: {err}"))
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn default_host_state_exposes_wasi_and_http_views() {
114 let mut state = DescribeHostState::default();
115
116 let ctx_view = state.ctx();
117 let _ = ctx_view.table;
118 let _ = ctx_view.ctx;
119
120 let http_view = state.http();
121 let _ = http_view.table;
122 let _ = http_view.ctx;
123 }
124
125 #[test]
126 fn describe_host_imports_register_without_error() {
127 let engine = wasmtime::Engine::default();
128 let mut linker = Linker::new(&engine);
129 add_describe_host_imports(&mut linker).expect("host imports should register");
130 }
131}