@@ -2,6 +2,17 @@ mod capi;
2
2
3
3
use wasmtime:: * ;
4
4
5
+ use crate :: kernel:: systemtime:: now_micros;
6
+
7
+ #[ inline( never) ]
8
+ pub fn native_fibonacci ( n : u64 ) -> u64 {
9
+ match n {
10
+ 0 => 0 ,
11
+ 1 => 1 ,
12
+ _ => native_fibonacci ( n - 1 ) + native_fibonacci ( n - 2 ) ,
13
+ }
14
+ }
15
+
5
16
pub ( crate ) fn init ( ) -> Result < ( ) , Error > {
6
17
let mut config: Config = Config :: new ( ) ;
7
18
config. memory_init_cow ( false ) ;
@@ -12,21 +23,34 @@ pub(crate) fn init() -> Result<(), Error> {
12
23
// In this example we are using the default configuration.
13
24
let engine = Engine :: new ( & config) ?;
14
25
15
- debug ! ( "Create Module" ) ;
26
+ info ! ( "Create Module" ) ;
16
27
let module_bytes = include_bytes ! ( "fib.cwasm" ) ;
17
28
let module = unsafe { Module :: deserialize ( & engine, & module_bytes[ ..] ) ? } ;
18
29
19
- debug ! ( "Create Linker" ) ;
20
- let linker = Linker :: new ( & engine) ;
30
+ let mut imports = module. imports ( ) ;
31
+ while let Some ( i) = imports. next ( ) {
32
+ info ! ( "import from module {} symbol {}" , i. module( ) , i. name( ) ) ;
33
+ }
34
+
35
+ info ! ( "Create Linker" ) ;
36
+ let mut linker = Linker :: new ( & engine) ;
37
+
38
+ // In case WASI, it is required to emulate
39
+ // https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md
40
+
41
+ linker. func_wrap ( "env" , "now" , || {
42
+ crate :: arch:: kernel:: systemtime:: now_micros ( )
43
+ } ) ?;
44
+ linker. func_wrap ( "env" , "exit" , || panic ! ( "Panic in WASM module" ) ) ?;
21
45
22
46
// All wasm objects operate within the context of a "store". Each
23
47
// `Store` has a type parameter to store host-specific data, which in
24
48
// this case we're using `4` for.
25
49
let mut store = Store :: new ( & engine, 4 ) ;
26
- debug ! ( "Create instance" ) ;
27
- let instance = linker. instantiate ( & mut store, & module) ? ;
50
+ info ! ( "Create instance" ) ;
51
+ let instance = linker. instantiate ( & mut store, & module) . unwrap ( ) ;
28
52
29
- debug ! ( "Try to find function fibonacci" ) ;
53
+ info ! ( "Try to find function fibonacci" ) ;
30
54
let fibonacci = instance. get_typed_func :: < u64 , u64 > ( & mut store, "fibonacci" ) ?;
31
55
32
56
// And finally we can call the wasm function
@@ -38,5 +62,39 @@ pub(crate) fn init() -> Result<(), Error> {
38
62
"Error in the calculation of fibonacci(30) "
39
63
) ;
40
64
65
+ const N : u64 = 100 ;
66
+ let start = now_micros ( ) ;
67
+ for _ in 0 ..N {
68
+ let _result = fibonacci. call ( & mut store, 30 ) ?;
69
+ }
70
+ let end = now_micros ( ) ;
71
+ info ! (
72
+ "Average time to call fibonacci(30): {} usec" ,
73
+ ( end - start) / N
74
+ ) ;
75
+
76
+ let start = now_micros ( ) ;
77
+ for _ in 0 ..N {
78
+ let _result = native_fibonacci ( 30 ) ;
79
+ }
80
+ let end = now_micros ( ) ;
81
+ info ! (
82
+ "Average time to call native_fibonacci(30): {} usec" ,
83
+ ( end - start) / N
84
+ ) ;
85
+
86
+ let bench = instance. get_typed_func :: < ( u64 , u64 ) , i64 > ( & mut store, "bench" ) ?;
87
+ let usec = bench. call ( & mut store, ( N , 30 ) ) ?;
88
+ info ! ( "Benchmark takes {} msec" , usec / 1000 ) ;
89
+
90
+ let foo = instance. get_typed_func :: < ( ) , ( ) > ( & mut store, "foo" ) ?;
91
+ foo. call ( & mut store, ( ) ) ?;
92
+ let start = now_micros ( ) ;
93
+ for _ in 0 ..N {
94
+ foo. call ( & mut store, ( ) ) ?;
95
+ }
96
+ let end = now_micros ( ) ;
97
+ info ! ( "Average time to call foo: {} usec" , ( end - start) / N ) ;
98
+
41
99
Ok ( ( ) )
42
100
}
0 commit comments