@@ -14,16 +14,16 @@ fn reverse_string(a: String) -> String {
1414}
1515
1616#[ rustler:: nif]
17- fn wasm_example ( source : String , f : String ) -> Result < i32 , Error > {
17+ fn wasm_example_0 ( source : String , f : String ) -> Result < i32 , Error > {
1818 // return Ok(5);
1919 //return Err(Error::Term(Box::new("hello")));
20- return match wasm_example_interal ( source, f) {
20+ return match wasm_example_0_internal ( source, f) {
2121 Ok ( v) => Ok ( v) ,
2222 Err ( e) => Err ( Error :: Term ( Box :: new ( e. to_string ( ) ) ) )
2323 }
2424}
2525
26- fn wasm_example_interal ( source : String , f : String ) -> Result < i32 , anyhow:: Error > {
26+ fn wasm_example_0_internal ( source : String , f : String ) -> Result < i32 , anyhow:: Error > {
2727 let engine = Engine :: default ( ) ;
2828
2929 // We start off by creating a `Module` which represents a compiled form
@@ -60,4 +60,100 @@ fn wasm_example_interal(source: String, f: String) -> Result<i32, anyhow::Error>
6060 return Ok ( result) ;
6161}
6262
63- rustler:: init!( "Elixir.ComponentsGuide.Rustler.Math" , [ add, reverse_string, wasm_example] ) ;
63+ #[ rustler:: nif]
64+ fn wasm_example_1_i32 ( source : String , f : String , a : i32 ) -> Result < i32 , Error > {
65+ return match wasm_example_1_i32_internal ( source, f, a) {
66+ Ok ( v) => Ok ( v) ,
67+ Err ( e) => Err ( Error :: Term ( Box :: new ( e. to_string ( ) ) ) )
68+ }
69+ }
70+
71+ fn wasm_example_1_i32_internal ( source : String , f : String , a : i32 ) -> Result < i32 , anyhow:: Error > {
72+ let engine = Engine :: default ( ) ;
73+
74+ // We start off by creating a `Module` which represents a compiled form
75+ // of our input wasm module. In this case it'll be JIT-compiled after
76+ // we parse the text format.
77+ let module = Module :: new ( & engine, source) ?;
78+
79+ // A `Store` is what will own instances, functions, globals, etc. All wasm
80+ // items are stored within a `Store`, and it's what we'll always be using to
81+ // interact with the wasm world. Custom data can be stored in stores but for
82+ // now we just use `()`.
83+ let mut store = Store :: new ( & engine, ( ) ) ;
84+
85+ // With a compiled `Module` we can then instantiate it, creating
86+ // an `Instance` which we can actually poke at functions on.
87+ let instance = Instance :: new ( & mut store, & module, & [ ] ) ?;
88+
89+ // The `Instance` gives us access to various exported functions and items,
90+ // which we access here to pull out our `answer` exported function and
91+ // run it.
92+ let answer = instance
93+ . get_func ( & mut store, & f)
94+ . expect ( & format ! ( "{} was not an exported function" , f) ) ;
95+
96+ // There's a few ways we can call the `answer` `Func` value. The easiest
97+ // is to statically assert its signature with `typed` (in this case
98+ // asserting it takes no arguments and returns one i32) and then call it.
99+ let answer = answer. typed :: < ( i32 ) , i32 , _ > ( & store) ?;
100+
101+ // And finally we can call our function! Note that the error propagation
102+ // with `?` is done to handle the case where the wasm function traps.
103+ let result = answer. call ( & mut store, ( a) ) ?;
104+
105+ return Ok ( result) ;
106+ }
107+
108+ #[ rustler:: nif]
109+ fn wasm_example_2_i32 ( source : String , f : String , a : i32 , b : i32 ) -> Result < i32 , Error > {
110+ return match wasm_example_2_i32_internal ( source, f, a, b) {
111+ Ok ( v) => Ok ( v) ,
112+ Err ( e) => Err ( Error :: Term ( Box :: new ( e. to_string ( ) ) ) )
113+ }
114+ }
115+
116+ fn wasm_example_2_i32_internal ( source : String , f : String , a : i32 , b : i32 ) -> Result < i32 , anyhow:: Error > {
117+ let engine = Engine :: default ( ) ;
118+
119+ // We start off by creating a `Module` which represents a compiled form
120+ // of our input wasm module. In this case it'll be JIT-compiled after
121+ // we parse the text format.
122+ let module = Module :: new ( & engine, source) ?;
123+
124+ // A `Store` is what will own instances, functions, globals, etc. All wasm
125+ // items are stored within a `Store`, and it's what we'll always be using to
126+ // interact with the wasm world. Custom data can be stored in stores but for
127+ // now we just use `()`.
128+ let mut store = Store :: new ( & engine, ( ) ) ;
129+
130+ // With a compiled `Module` we can then instantiate it, creating
131+ // an `Instance` which we can actually poke at functions on.
132+ let instance = Instance :: new ( & mut store, & module, & [ ] ) ?;
133+
134+ // The `Instance` gives us access to various exported functions and items,
135+ // which we access here to pull out our `answer` exported function and
136+ // run it.
137+ let answer = instance
138+ . get_func ( & mut store, & f)
139+ . expect ( & format ! ( "{} was not an exported function" , f) ) ;
140+
141+ // There's a few ways we can call the `answer` `Func` value. The easiest
142+ // is to statically assert its signature with `typed` (in this case
143+ // asserting it takes no arguments and returns one i32) and then call it.
144+ let answer = answer. typed :: < ( i32 , i32 ) , i32 , _ > ( & store) ?;
145+
146+ // And finally we can call our function! Note that the error propagation
147+ // with `?` is done to handle the case where the wasm function traps.
148+ let result = answer. call ( & mut store, ( a, b) ) ?;
149+
150+ return Ok ( result) ;
151+ }
152+
153+ rustler:: init!( "Elixir.ComponentsGuide.Rustler.Math" , [
154+ add,
155+ reverse_string,
156+ wasm_example_0,
157+ wasm_example_1_i32,
158+ wasm_example_2_i32
159+ ] ) ;
0 commit comments