@@ -26,6 +26,8 @@ struct WasmerCreateExe {
26
26
native_executable_path : PathBuf ,
27
27
/// Compiler with which to compile the Wasm.
28
28
compiler : Compiler ,
29
+ /// Extra CLI flags
30
+ extra_cli_flags : Vec < & ' static str > ,
29
31
}
30
32
31
33
impl Default for WasmerCreateExe {
@@ -40,17 +42,19 @@ impl Default for WasmerCreateExe {
40
42
wasm_path : PathBuf :: from ( create_exe_test_wasm_path ( ) ) ,
41
43
native_executable_path,
42
44
compiler : Compiler :: Cranelift ,
45
+ extra_cli_flags : vec ! [ ] ,
43
46
}
44
47
}
45
48
}
46
49
47
50
impl WasmerCreateExe {
48
- fn run ( & self ) -> anyhow:: Result < ( ) > {
51
+ fn run ( & self ) -> anyhow:: Result < Vec < u8 > > {
49
52
let output = Command :: new ( & self . wasmer_path )
50
53
. current_dir ( & self . current_dir )
51
54
. arg ( "create-exe" )
52
55
. arg ( & self . wasm_path . canonicalize ( ) ?)
53
56
. arg ( & self . compiler . to_flag ( ) )
57
+ . args ( self . extra_cli_flags . iter ( ) )
54
58
. arg ( "-o" )
55
59
. arg ( & self . native_executable_path )
56
60
. output ( ) ?;
@@ -64,7 +68,66 @@ impl WasmerCreateExe {
64
68
. expect( "stderr is not utf8! need to handle arbitrary bytes" )
65
69
) ;
66
70
}
67
- Ok ( ( ) )
71
+ Ok ( output. stdout )
72
+ }
73
+ }
74
+
75
+ /// Data used to run the `wasmer compile` command.
76
+ #[ derive( Debug ) ]
77
+ struct WasmerCreateObj {
78
+ /// The directory to operate in.
79
+ current_dir : PathBuf ,
80
+ /// Path to wasmer executable used to run the command.
81
+ wasmer_path : PathBuf ,
82
+ /// Path to the Wasm file to compile.
83
+ wasm_path : PathBuf ,
84
+ /// Path to the object file produced by compiling the Wasm.
85
+ output_object_path : PathBuf ,
86
+ /// Compiler with which to compile the Wasm.
87
+ compiler : Compiler ,
88
+ /// Extra CLI flags
89
+ extra_cli_flags : Vec < & ' static str > ,
90
+ }
91
+
92
+ impl Default for WasmerCreateObj {
93
+ fn default ( ) -> Self {
94
+ #[ cfg( not( windows) ) ]
95
+ let output_object_path = PathBuf :: from ( "wasm.o" ) ;
96
+ #[ cfg( windows) ]
97
+ let output_object_path = PathBuf :: from ( "wasm.obj" ) ;
98
+ Self {
99
+ current_dir : std:: env:: current_dir ( ) . unwrap ( ) ,
100
+ wasmer_path : get_wasmer_path ( ) ,
101
+ wasm_path : PathBuf :: from ( create_exe_test_wasm_path ( ) ) ,
102
+ output_object_path,
103
+ compiler : Compiler :: Cranelift ,
104
+ extra_cli_flags : vec ! [ ] ,
105
+ }
106
+ }
107
+ }
108
+
109
+ impl WasmerCreateObj {
110
+ fn run ( & self ) -> anyhow:: Result < Vec < u8 > > {
111
+ let output = Command :: new ( & self . wasmer_path )
112
+ . current_dir ( & self . current_dir )
113
+ . arg ( "create-obj" )
114
+ . arg ( & self . wasm_path . canonicalize ( ) ?)
115
+ . arg ( & self . compiler . to_flag ( ) )
116
+ . args ( self . extra_cli_flags . iter ( ) )
117
+ . arg ( "-o" )
118
+ . arg ( & self . output_object_path )
119
+ . output ( ) ?;
120
+
121
+ if !output. status . success ( ) {
122
+ bail ! (
123
+ "wasmer create-obj failed with: stdout: {}\n \n stderr: {}" ,
124
+ std:: str :: from_utf8( & output. stdout)
125
+ . expect( "stdout is not utf8! need to handle arbitrary bytes" ) ,
126
+ std:: str :: from_utf8( & output. stderr)
127
+ . expect( "stderr is not utf8! need to handle arbitrary bytes" )
128
+ ) ;
129
+ }
130
+ Ok ( output. stdout )
68
131
}
69
132
}
70
133
@@ -160,3 +223,109 @@ fn create_exe_works_with_file() -> anyhow::Result<()> {
160
223
161
224
Ok ( ( ) )
162
225
}
226
+
227
+ #[ test]
228
+ fn create_exe_serialized_works ( ) -> anyhow:: Result < ( ) > {
229
+ let temp_dir = tempfile:: tempdir ( ) ?;
230
+ let operating_dir: PathBuf = temp_dir. path ( ) . to_owned ( ) ;
231
+
232
+ let wasm_path = operating_dir. join ( create_exe_test_wasm_path ( ) ) ;
233
+ #[ cfg( not( windows) ) ]
234
+ let executable_path = operating_dir. join ( "wasm.out" ) ;
235
+ #[ cfg( windows) ]
236
+ let executable_path = operating_dir. join ( "wasm.exe" ) ;
237
+
238
+ let output: Vec < u8 > = WasmerCreateExe {
239
+ current_dir : operating_dir. clone ( ) ,
240
+ wasm_path,
241
+ native_executable_path : executable_path. clone ( ) ,
242
+ compiler : Compiler :: Cranelift ,
243
+ extra_cli_flags : vec ! [ "--object-format" , "serialized" ] ,
244
+ ..Default :: default ( )
245
+ }
246
+ . run ( )
247
+ . context ( "Failed to create-exe wasm with Wasmer" ) ?;
248
+
249
+ let result = run_code (
250
+ & operating_dir,
251
+ & executable_path,
252
+ & [ "--eval" . to_string ( ) , "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));" . to_string ( ) ] ,
253
+ )
254
+ . context ( "Failed to run generated executable" ) ?;
255
+ let result_lines = result. lines ( ) . collect :: < Vec < & str > > ( ) ;
256
+ assert_eq ! ( result_lines, vec![ "\" Hello, World\" " ] , ) ;
257
+
258
+ let output_str = String :: from_utf8_lossy ( & output) ;
259
+ assert ! (
260
+ output_str. contains( "erialized" ) ,
261
+ "create-exe output doesn't mention `serialized` format keyword:\n {}" ,
262
+ output_str
263
+ ) ;
264
+
265
+ Ok ( ( ) )
266
+ }
267
+
268
+ fn create_obj ( args : Vec < & ' static str > , keyword_needle : & str , keyword : & str ) -> anyhow:: Result < ( ) > {
269
+ let temp_dir = tempfile:: tempdir ( ) ?;
270
+ let operating_dir: PathBuf = temp_dir. path ( ) . to_owned ( ) ;
271
+
272
+ let wasm_path = operating_dir. join ( create_exe_test_wasm_path ( ) ) ;
273
+
274
+ #[ cfg( not( windows) ) ]
275
+ let object_path = operating_dir. join ( "wasm.o" ) ;
276
+ #[ cfg( windows) ]
277
+ let object_path = operating_dir. join ( "wasm.obj" ) ;
278
+
279
+ let output: Vec < u8 > = WasmerCreateObj {
280
+ current_dir : operating_dir. clone ( ) ,
281
+ wasm_path,
282
+ output_object_path : object_path. clone ( ) ,
283
+ compiler : Compiler :: Cranelift ,
284
+ extra_cli_flags : args,
285
+ ..Default :: default ( )
286
+ }
287
+ . run ( )
288
+ . context ( "Failed to create-obj wasm with Wasmer" ) ?;
289
+
290
+ assert ! (
291
+ object_path. exists( ) ,
292
+ "create-obj successfully completed but object output file `{}` missing" ,
293
+ object_path. display( )
294
+ ) ;
295
+ let mut object_header_path = object_path. clone ( ) ;
296
+ object_header_path. set_extension ( "h" ) ;
297
+ assert ! (
298
+ object_header_path. exists( ) ,
299
+ "create-obj successfully completed but object output header file `{}` missing" ,
300
+ object_header_path. display( )
301
+ ) ;
302
+
303
+ let output_str = String :: from_utf8_lossy ( & output) ;
304
+ assert ! (
305
+ output_str. contains( keyword_needle) ,
306
+ "create-obj output doesn't mention `{}` format keyword:\n {}" ,
307
+ keyword,
308
+ output_str
309
+ ) ;
310
+
311
+ Ok ( ( ) )
312
+ }
313
+
314
+ #[ test]
315
+ fn create_obj_default ( ) -> anyhow:: Result < ( ) > {
316
+ create_obj ( vec ! [ ] , "ymbols" , "symbols" )
317
+ }
318
+
319
+ #[ test]
320
+ fn create_obj_symbols ( ) -> anyhow:: Result < ( ) > {
321
+ create_obj ( vec ! [ "--object-format" , "symbols" ] , "ymbols" , "symbols" )
322
+ }
323
+
324
+ #[ test]
325
+ fn create_obj_serialized ( ) -> anyhow:: Result < ( ) > {
326
+ create_obj (
327
+ vec ! [ "--object-format" , "serialized" ] ,
328
+ "erialized" ,
329
+ "serialized" ,
330
+ )
331
+ }
0 commit comments