Skip to content

Commit 0a1c14b

Browse files
add more host function tests
1 parent d342384 commit 0a1c14b

2 files changed

Lines changed: 140 additions & 53 deletions

File tree

src/bin/resources/host_imports.wat

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,69 @@
1-
;; Module that imports host functions
21
(module
3-
;; Import host functions
42
(import "host" "print" (func $print (param i32)))
53
(import "host" "random" (func $random (result i32)))
64
(import "host" "add" (func $host_add (param i32 i32) (result i32)))
5+
(import "host" "mul" (func $host_mul (param i32 i32) (result i32)))
6+
(import "host" "counter_inc" (func $counter_inc (result i32)))
7+
(import "host" "counter_get" (func $counter_get (result i32)))
78

8-
;; Main function that uses host imports
99
(func $main (export "main") (result i32)
10-
;; Call host.add(42, 8)
1110
i32.const 42
1211
i32.const 8
1312
call $host_add
14-
15-
;; Print the result
1613
call $print
17-
18-
;; Return 0
1914
i32.const 0)
2015

21-
;; Generate and print a random number
22-
(func $print_random (export "print_random") (result i32)
23-
;; Get random number
16+
(func $sequence (export "sequence") (result i32)
17+
(local i32)
2418
call $random
25-
26-
;; Print it
19+
local.tee 0
2720
call $print
2821

29-
;; Return 0
30-
i32.const 0)
31-
32-
;; Calculate using random numbers
33-
(func $random_calc (export "random_calculation") (result i32)
34-
;; Get two random numbers and add them
35-
call $random
36-
call $random
22+
local.get 0
23+
i32.const 100
3724
call $host_add
38-
39-
;; Print result
4025
call $print
4126

42-
;; Return the result
4327
call $random
28+
i32.const 2
29+
call $host_mul
4430
call $random
31+
i32.const 3
32+
call $host_mul
4533
call $host_add)
34+
35+
(func $helper_double (param i32) (result i32)
36+
local.get 0
37+
i32.const 2
38+
call $host_mul)
39+
40+
(func $helper_triple (param i32) (result i32)
41+
local.get 0
42+
i32.const 3
43+
call $host_mul)
44+
45+
(func $nested_calls (export "nested_calls") (result i32)
46+
(local i32)
47+
call $random
48+
call $helper_double
49+
call $helper_triple
50+
local.tee 0
51+
call $print
52+
local.get 0)
53+
54+
(func $stateful (export "stateful") (result i32)
55+
(local i32)
56+
call $counter_inc
57+
call $print
58+
call $counter_inc
59+
call $print
60+
call $counter_inc
61+
call $print
62+
63+
call $counter_get
64+
call $random
65+
call $host_add
66+
local.tee 0
67+
call $print
68+
local.get 0)
4669
)

src/bin/wagmi_example_host.rs

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,90 +8,154 @@ use utils::load_resource_module;
88

99
struct HostState {
1010
call_count: RefCell<u32>,
11-
last_printed: RefCell<Option<i32>>,
11+
counter: RefCell<i32>,
12+
call_sequence: RefCell<Vec<String>>,
1213
}
1314

1415
fn main() -> Result<(), Box<dyn std::error::Error>> {
1516
let host_state = Rc::new(HostState {
1617
call_count: RefCell::new(0),
17-
last_printed: RefCell::new(None),
18+
counter: RefCell::new(0),
19+
call_sequence: RefCell::new(Vec::new()),
1820
});
1921

2022
let state_clone = host_state.clone();
2123
let print_fn = RuntimeFunction::new_host(
22-
vec![ValType::I32], // params
23-
None, // no result
24+
vec![ValType::I32],
25+
None,
2426
move |args| {
2527
let value = args[0].as_i32();
26-
println!(" [Host Print] Value: {}", value);
27-
*state_clone.last_printed.borrow_mut() = Some(value);
28+
println!(" [Host:print] {}", value);
29+
state_clone.call_sequence.borrow_mut().push(format!("print({})", value));
2830
*state_clone.call_count.borrow_mut() += 1;
2931
None
3032
}
3133
);
3234

35+
let state_clone = host_state.clone();
3336
let random_fn = RuntimeFunction::new_host(
34-
vec![], // no params
35-
Some(ValType::I32), // returns i32
36-
|_args| {
37+
vec![],
38+
Some(ValType::I32),
39+
move |_args| {
3740
use std::time::{SystemTime, UNIX_EPOCH};
3841
let seed = SystemTime::now()
3942
.duration_since(UNIX_EPOCH)
4043
.unwrap()
4144
.subsec_nanos() as i32;
42-
let random = (seed ^ 0x5DEECE66Di64 as i32) % 100;
43-
println!(" [Host Random] Generated: {}", random);
45+
let random = ((seed ^ 0x5DEECE66Di64 as i32) % 50).abs();
46+
println!(" [Host:random] → {}", random);
47+
state_clone.call_sequence.borrow_mut().push(format!("random() -> {}", random));
48+
*state_clone.call_count.borrow_mut() += 1;
4449
Some(WasmValue::from_i32(random))
4550
}
4651
);
4752

53+
let state_clone = host_state.clone();
4854
let add_fn = RuntimeFunction::new_host(
49-
vec![ValType::I32, ValType::I32], // two i32 params
50-
Some(ValType::I32), // returns i32
51-
|args| {
55+
vec![ValType::I32, ValType::I32],
56+
Some(ValType::I32),
57+
move |args| {
5258
let a = args[0].as_i32();
5359
let b = args[1].as_i32();
5460
let result = a + b;
55-
println!(" [Host Add] {} + {} = {}", a, b, result);
61+
println!(" [Host:add] {} + {} = {}", a, b, result);
62+
state_clone.call_sequence.borrow_mut().push(format!("add({}, {}) -> {}", a, b, result));
63+
*state_clone.call_count.borrow_mut() += 1;
64+
Some(WasmValue::from_i32(result))
65+
}
66+
);
67+
68+
let state_clone = host_state.clone();
69+
let mul_fn = RuntimeFunction::new_host(
70+
vec![ValType::I32, ValType::I32],
71+
Some(ValType::I32),
72+
move |args| {
73+
let a = args[0].as_i32();
74+
let b = args[1].as_i32();
75+
let result = a * b;
76+
println!(" [Host:mul] {} * {} = {}", a, b, result);
77+
state_clone.call_sequence.borrow_mut().push(format!("mul({}, {}) -> {}", a, b, result));
78+
*state_clone.call_count.borrow_mut() += 1;
5679
Some(WasmValue::from_i32(result))
5780
}
5881
);
5982

83+
let state_clone = host_state.clone();
84+
let counter_inc_fn = RuntimeFunction::new_host(
85+
vec![],
86+
Some(ValType::I32),
87+
move |_args| {
88+
let mut counter = state_clone.counter.borrow_mut();
89+
*counter += 1;
90+
let value = *counter;
91+
println!(" [Host:counter++] → {}", value);
92+
state_clone.call_sequence.borrow_mut().push(format!("counter++ -> {}", value));
93+
*state_clone.call_count.borrow_mut() += 1;
94+
Some(WasmValue::from_i32(value))
95+
}
96+
);
97+
98+
let state_clone = host_state.clone();
99+
let counter_get_fn = RuntimeFunction::new_host(
100+
vec![],
101+
Some(ValType::I32),
102+
move |_args| {
103+
let value = *state_clone.counter.borrow();
104+
println!(" [Host:counter] → {}", value);
105+
state_clone.call_sequence.borrow_mut().push(format!("counter -> {}", value));
106+
*state_clone.call_count.borrow_mut() += 1;
107+
Some(WasmValue::from_i32(value))
108+
}
109+
);
110+
60111
let mut imports = Imports::new();
61112
let mut host_module = HashMap::new();
62113
host_module.insert("print".to_string(), ExportValue::Function(print_fn));
63114
host_module.insert("random".to_string(), ExportValue::Function(random_fn));
64115
host_module.insert("add".to_string(), ExportValue::Function(add_fn));
116+
host_module.insert("mul".to_string(), ExportValue::Function(mul_fn));
117+
host_module.insert("counter_inc".to_string(), ExportValue::Function(counter_inc_fn));
118+
host_module.insert("counter_get".to_string(), ExportValue::Function(counter_get_fn));
65119
imports.insert("host".to_string(), host_module);
66120

67121
let wasm_bytes = load_resource_module("host_imports")?;
68122
let module = Module::compile(wasm_bytes)?;
69123
let module = Rc::new(module);
70124
let instance = Instance::instantiate(module, &imports)?;
71125

72-
73126
if let Some(ExportValue::Function(main_func)) = instance.exports.get("main") {
127+
println!("Calling main():");
74128
let results = instance.invoke(main_func, &[])?;
75-
println!("main() returned: {}", results[0].as_i32());
129+
println!(" returned: {}\n", results[0].as_i32());
76130
}
77131

78-
if let Some(ExportValue::Function(print_random)) = instance.exports.get("print_random") {
79-
let results = instance.invoke(print_random, &[])?;
80-
println!("print_random() returned: {}", results[0].as_i32());
81-
82-
let results = instance.invoke(print_random, &[])?;
83-
println!("print_random() returned: {}", results[0].as_i32());
132+
if let Some(ExportValue::Function(func)) = instance.exports.get("sequence") {
133+
println!("Calling sequence():");
134+
let results = instance.invoke(func, &[])?;
135+
println!("→ returned: {}\n", results[0].as_i32());
84136
}
85137

86-
if let Some(ExportValue::Function(random_calc)) = instance.exports.get("random_calculation") {
87-
let results = instance.invoke(random_calc, &[])?;
88-
println!("random_calculation() returned: {}", results[0].as_i32());
138+
if let Some(ExportValue::Function(func)) = instance.exports.get("nested_calls") {
139+
println!("Calling nested_calls():");
140+
let results = instance.invoke(func, &[])?;
141+
println!("→ returned: {}\n", results[0].as_i32());
89142
}
90143

144+
if let Some(ExportValue::Function(func)) = instance.exports.get("stateful") {
145+
println!("Calling stateful():");
146+
let results = instance.invoke(func, &[])?;
147+
println!("→ returned: {}\n", results[0].as_i32());
148+
}
149+
150+
println!("=== Summary ===");
151+
println!("Total host calls: {}", *host_state.call_count.borrow());
152+
println!("Final counter: {}", *host_state.counter.borrow());
91153

92-
println!("Total host.print() calls: {}", *host_state.call_count.borrow());
93-
if let Some(last) = *host_state.last_printed.borrow() {
94-
println!("Last printed value: {}", last);
154+
if !host_state.call_sequence.borrow().is_empty() {
155+
println!("\nCall sequence:");
156+
for (i, call) in host_state.call_sequence.borrow().iter().enumerate() {
157+
println!(" {}. {}", i + 1, call);
158+
}
95159
}
96160

97161
Ok(())

0 commit comments

Comments
 (0)