@@ -21,17 +21,37 @@ use crate::{
2121} ;
2222
2323/// Create WASM engine.
24- fn create_engine ( ) -> DataFusionResult < Engine > {
25- Engine :: new (
26- wasmtime:: Config :: new ( )
27- . async_support ( true )
28- . epoch_interruption ( true )
29- . memory_init_cow ( true )
30- // Disable backtraces for now since debug info parsing doesn't seem to work and hence error
31- // messages are nondeterministic.
32- . wasm_backtrace ( false ) ,
33- )
34- . context ( "create WASM engine" , None )
24+ fn create_engine ( flags : & CompilationFlags ) -> DataFusionResult < Engine > {
25+ // TODO: Once https://github.com/bytecodealliance/wasmtime/pull/12089 is released, make this an `Option` and treat
26+ // `None` as `Config::without_compiler`.
27+ let CompilationFlags { target } = flags;
28+
29+ let mut config = wasmtime:: Config :: new ( ) ;
30+ config. async_support ( true ) ;
31+ config. epoch_interruption ( true ) ;
32+ config. memory_init_cow ( true ) ;
33+ // Disable backtraces for now since debug info parsing doesn't seem to work and hence error
34+ // messages are nondeterministic.
35+ config. wasm_backtrace ( false ) ;
36+
37+ if let Some ( target) = & target {
38+ config
39+ . target ( target)
40+ . with_context ( |_| format ! ( "cannot set target: {target}" ) , None ) ?;
41+ }
42+
43+ Engine :: new ( & config) . context ( "create WASM engine" , None )
44+ }
45+
46+ /// Code compilation flags.
47+ ///
48+ /// This is used when [compiling a component](WasmComponentPrecompiled::compile).
49+ #[ derive( Debug , Default , Clone ) ]
50+ pub struct CompilationFlags {
51+ /// Target (triplet).
52+ ///
53+ /// Set to [`None`] to use the host configuration. Note that this may lead to unportable compiled code.
54+ pub target : Option < String > ,
3555}
3656
3757/// Pre-compiled WASM component.
@@ -51,11 +71,14 @@ impl WasmComponentPrecompiled {
5171 ///
5272 ///
5373 /// [binary format]: https://webassembly.github.io/spec/core/binary/index.html
54- pub async fn new ( wasm_binary : Arc < [ u8 ] > ) -> DataFusionResult < Self > {
55- tokio:: task:: spawn_blocking ( move || {
56- // Create temporary engine that we need for compilation.
57- let engine = create_engine ( ) ?;
74+ pub async fn compile (
75+ wasm_binary : Arc < [ u8 ] > ,
76+ flags : & CompilationFlags ,
77+ ) -> DataFusionResult < Self > {
78+ // Create temporary engine that we need for compilation.
79+ let engine = create_engine ( flags) ?;
5880
81+ tokio:: task:: spawn_blocking ( move || {
5982 let compiled_component = engine
6083 . precompile_component ( & wasm_binary)
6184 . context ( "pre-compile component" , None ) ?;
@@ -83,7 +106,7 @@ impl WasmComponentPrecompiled {
83106 ///
84107 /// # Exposure
85108 /// It is generally safe to leak/expose the pre-compiled data to the user that provided the WASM bytecode (see
86- /// [`new `](Self::new )). However, you must prevent the user from tampering the data, see "safety" section of
109+ /// [`compile `](Self::compile )). However, you must prevent the user from tampering the data, see "safety" section of
87110 /// [`load`](Self::load).
88111 ///
89112 /// The exposed data is opaque and we make no guarantees about the internal structure of it.
@@ -139,7 +162,7 @@ impl WasmComponentPrecompiled {
139162 } ;
140163
141164 // test hydration
142- let engine = create_engine ( ) ?;
165+ let engine = create_engine ( & CompilationFlags :: default ( ) ) ?;
143166 this. hydrate ( & engine) ?;
144167
145168 Ok ( this)
@@ -187,7 +210,7 @@ impl WasmComponentInstance {
187210 io_rt : Handle ,
188211 memory_pool : & Arc < dyn MemoryPool > ,
189212 ) -> DataFusionResult < Self > {
190- let engine = create_engine ( ) ?;
213+ let engine = create_engine ( & CompilationFlags :: default ( ) ) ?;
191214
192215 // set up epoch timer
193216 let mut epoch_task = JoinSet :: new ( ) ;
0 commit comments