1
1
use std:: net:: SocketAddr ;
2
+ use std:: path:: Path ;
3
+ use std:: sync:: Arc ;
2
4
3
5
use hyper:: {
4
6
http:: request:: Parts ,
5
7
Body , Request , Response , StatusCode ,
6
8
} ;
7
9
use sha2:: { Digest , Sha256 } ;
8
10
use tracing:: { instrument} ;
11
+ use wasmtime:: { Engine , Config } ;
9
12
10
13
use crate :: dynamic_route:: { DynamicRoutes , interpret_routes} ;
11
14
use crate :: emplacer:: Bits ;
@@ -16,7 +19,7 @@ use crate::request::{RequestContext, RequestGlobalContext};
16
19
17
20
use crate :: bindle_util:: { WagiHandlerInfo } ;
18
21
use crate :: wagi_config:: { LoadedHandlerConfiguration , ModuleMapConfigurationEntry } ;
19
- use crate :: wasm_module:: WasmModuleSource ;
22
+ use crate :: wasm_module:: CompiledWasmModule ;
20
23
use crate :: wasm_runner:: { RunWasmResult , prepare_stdio_streams, prepare_wasm_instance, run_prepared_wasm_instance_if_present, WasmLinkOptions } ;
21
24
22
25
#[ derive( Clone , Debug ) ]
@@ -89,12 +92,33 @@ impl RoutingTableEntry {
89
92
self . route_pattern . is_match ( uri_fragment)
90
93
}
91
94
92
- fn build_from_modules_toml ( source : & Loaded < ModuleMapConfigurationEntry > ) -> anyhow:: Result < RoutingTableEntry > {
95
+ /// Create a new Wasm Engine and configure it.
96
+ fn new_engine ( cache_config_path : & Path ) -> anyhow:: Result < Engine > {
97
+ let mut config = Config :: default ( ) ;
98
+
99
+ // Enable multi memory and module linking support.
100
+ config. wasm_multi_memory ( true ) ;
101
+ config. wasm_module_linking ( true ) ;
102
+
103
+ if let Ok ( p) = std:: fs:: canonicalize ( cache_config_path) {
104
+ config. cache_config_load ( p) ?;
105
+ } ;
106
+
107
+ Engine :: new ( & config)
108
+ }
109
+
110
+ fn compile_module ( data : Arc < Vec < u8 > > , cache_config_path : & Path ) -> anyhow:: Result < CompiledWasmModule > {
111
+ let engine = RoutingTableEntry :: new_engine ( cache_config_path) ?;
112
+ let module = wasmtime:: Module :: new ( & engine, & * * data) ?;
113
+ Ok ( CompiledWasmModule :: Object ( module, engine) )
114
+ }
115
+
116
+ fn build_from_modules_toml ( source : & Loaded < ModuleMapConfigurationEntry > , global_context : & RequestGlobalContext , ) -> anyhow:: Result < RoutingTableEntry > {
93
117
let route_pattern = RoutePattern :: parse ( & source. metadata . route ) ;
94
118
95
- let wasm_source = WasmModuleSource :: Blob ( source. content . clone ( ) ) ;
119
+ let wasm_module = RoutingTableEntry :: compile_module ( source. content . clone ( ) , & global_context . cache_config_path ) ? ;
96
120
let wasm_route_handler = WasmRouteHandler {
97
- wasm_module_source : wasm_source ,
121
+ wasm_module_source : wasm_module ,
98
122
wasm_module_name : source. metadata . module . clone ( ) ,
99
123
entrypoint : source. metadata . entrypoint . clone ( ) . unwrap_or_else ( || DEFAULT_ENTRYPOINT . to_owned ( ) ) ,
100
124
volumes : source. metadata . volumes . clone ( ) . unwrap_or_default ( ) ,
@@ -109,25 +133,29 @@ impl RoutingTableEntry {
109
133
} )
110
134
}
111
135
112
- fn build_from_bindle_entry ( source : & ( WagiHandlerInfo , Bits ) ) -> Option < anyhow:: Result < RoutingTableEntry > > {
136
+ fn build_from_bindle_entry ( source : & ( WagiHandlerInfo , Bits ) , global_context : & RequestGlobalContext , ) -> Option < anyhow:: Result < RoutingTableEntry > > {
113
137
let ( wagi_handler, bits) = source;
114
138
115
139
let route_pattern = RoutePattern :: parse ( & wagi_handler. route ) ;
116
- let wasm_source = WasmModuleSource :: Blob ( bits. wasm_module . clone ( ) ) ;
117
- let wasm_route_handler = WasmRouteHandler {
118
- wasm_module_source : wasm_source,
119
- wasm_module_name : wagi_handler. parcel . label . name . clone ( ) ,
120
- entrypoint : wagi_handler. entrypoint . clone ( ) . unwrap_or_else ( || DEFAULT_ENTRYPOINT . to_owned ( ) ) ,
121
- volumes : bits. volume_mounts . clone ( ) ,
122
- allowed_hosts : wagi_handler. allowed_hosts . clone ( ) ,
123
- http_max_concurrency : None ,
124
- } ;
125
- let handler_info = RouteHandler :: Wasm ( wasm_route_handler) ;
140
+ match RoutingTableEntry :: compile_module ( bits. wasm_module . clone ( ) , & global_context. cache_config_path ) {
141
+ Err ( e) => Some ( Err ( e) ) , // Not clear what we are supposed to return here.
142
+ Ok ( wasm_module) => {
143
+ let wasm_route_handler = WasmRouteHandler {
144
+ wasm_module_source : wasm_module,
145
+ wasm_module_name : wagi_handler. parcel . label . name . clone ( ) ,
146
+ entrypoint : wagi_handler. entrypoint . clone ( ) . unwrap_or_else ( || DEFAULT_ENTRYPOINT . to_owned ( ) ) ,
147
+ volumes : bits. volume_mounts . clone ( ) ,
148
+ allowed_hosts : wagi_handler. allowed_hosts . clone ( ) ,
149
+ http_max_concurrency : None ,
150
+ } ;
151
+ let handler_info = RouteHandler :: Wasm ( wasm_route_handler) ;
126
152
127
- Some ( Ok ( Self {
128
- route_pattern,
129
- handler_info,
130
- } ) )
153
+ Some ( Ok ( Self {
154
+ route_pattern,
155
+ handler_info,
156
+ } ) )
157
+ }
158
+ }
131
159
}
132
160
133
161
fn inbuilt ( path : & str , handler : RouteHandler ) -> Self {
@@ -263,9 +291,9 @@ impl RoutingTable {
263
291
pub fn build ( source : & LoadedHandlerConfiguration , global_context : RequestGlobalContext ) -> anyhow:: Result < RoutingTable > {
264
292
let user_entries = match source {
265
293
LoadedHandlerConfiguration :: ModuleMapFile ( module_map_entries) =>
266
- Self :: build_from_modules_toml ( module_map_entries) ,
294
+ Self :: build_from_modules_toml ( module_map_entries, & global_context ) ,
267
295
LoadedHandlerConfiguration :: Bindle ( bindle_entries) =>
268
- Self :: build_from_bindle_entries ( bindle_entries) ,
296
+ Self :: build_from_bindle_entries ( bindle_entries, & global_context ) ,
269
297
} ?;
270
298
let full_user_entries = augment_dynamic_routes ( user_entries, & global_context) ?;
271
299
@@ -278,18 +306,18 @@ impl RoutingTable {
278
306
} )
279
307
}
280
308
281
- fn build_from_modules_toml ( module_map_entries : & [ Loaded < ModuleMapConfigurationEntry > ] ) -> anyhow:: Result < Vec < RoutingTableEntry > > {
309
+ fn build_from_modules_toml ( module_map_entries : & [ Loaded < ModuleMapConfigurationEntry > ] , global_context : & RequestGlobalContext ) -> anyhow:: Result < Vec < RoutingTableEntry > > {
282
310
// TODO: look for `_routes` function
283
311
module_map_entries
284
312
. iter ( )
285
- . map ( |e| RoutingTableEntry :: build_from_modules_toml ( e) )
313
+ . map ( |e| RoutingTableEntry :: build_from_modules_toml ( e, global_context ) )
286
314
. collect ( )
287
315
}
288
316
289
- fn build_from_bindle_entries ( bindle_entries : & [ ( WagiHandlerInfo , Bits ) ] ) -> anyhow:: Result < Vec < RoutingTableEntry > > {
317
+ fn build_from_bindle_entries ( bindle_entries : & [ ( WagiHandlerInfo , Bits ) ] , global_context : & RequestGlobalContext ) -> anyhow:: Result < Vec < RoutingTableEntry > > {
290
318
bindle_entries
291
319
. iter ( )
292
- . filter_map ( |e| RoutingTableEntry :: build_from_bindle_entry ( e) )
320
+ . filter_map ( |e| RoutingTableEntry :: build_from_bindle_entry ( e, global_context ) )
293
321
. collect ( )
294
322
}
295
323
@@ -318,7 +346,7 @@ fn augment_one_wasm_with_dynamic_routes(routing_table_entry: &RoutingTableEntry,
318
346
319
347
let ctx = build_wasi_context_for_dynamic_route_query ( redirects. streams ) ;
320
348
let link_options = WasmLinkOptions :: none ( ) ;
321
- let ( store, instance) = prepare_wasm_instance ( global_context , ctx, & wasm_route_handler. wasm_module_source , link_options) ?;
349
+ let ( store, instance) = prepare_wasm_instance ( ctx, & wasm_route_handler. wasm_module_source , link_options) ?;
322
350
323
351
match run_prepared_wasm_instance_if_present ( instance, store, "_routes" ) {
324
352
RunWasmResult :: WasmError ( e) => Err ( e) ,
0 commit comments