bin-runner #36

Merged
zacheryasc merged 103 commits from bin-runner into master 2026-02-13 14:11:40 +00:00
Showing only changes of commit af5e0644bc - Show all commits

View file

@ -7768,4 +7768,149 @@ fn byte_message_various_constructors() {
assert!(msg2.0.is_empty());
let msg3 = ByteMessage(vec![0; 1024]);
assert_eq!(msg3.0.len(), 1024);
}
// ── Guest with i32.shl/shr_u shift operations ─────────────────────────────
#[test]
fn guest_uses_shift_operations() {
let wat = r#"
(module
(import "swactor" "send" (func $send (param i32 i32 i32)))
(memory (export "memory") 1)
(func (export "alloc") (param i32) (result i32) i32.const 4096)
(func (export "handle") (param $ptr i32) (param $len i32)
;; Read first payload byte, shift left by 1, store result
(i32.store8 (i32.const 200)
(i32.shl
(i32.load8_u (i32.add (local.get $ptr) (i32.const 32)))
(i32.const 1)
)
)
;; Read second payload byte, shift right by 2
(i32.store8 (i32.const 201)
(i32.shr_u
(i32.load8_u (i32.add (local.get $ptr) (i32.const 33)))
(i32.const 2)
)
)
(call $send (local.get $ptr) (i32.const 200) (i32.const 2))
)
)
"#;
let wasm = wat::parse_str(wat).unwrap();
let engine = SharedEngine::new().unwrap();
let actor = WasmActorBuilder::new(engine, wasm).build().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
let addr = rt.spawn(actor).unwrap();
rt.send_to(addr, framed_msg(inbox.addr(), &[5, 100])).unwrap();
rt.tick();
let msg = inbox.try_recv().unwrap();
assert_eq!(msg.0[0], 10, "5 << 1 = 10");
assert_eq!(msg.0[1], 25, "100 >> 2 = 25");
}
// ── Guest with i32.and/or for masking ──────────────────────────────────────
#[test]
fn guest_uses_bitwise_and_or() {
let wat = r#"
(module
(import "swactor" "send" (func $send (param i32 i32 i32)))
(memory (export "memory") 1)
(func (export "alloc") (param i32) (result i32) i32.const 4096)
(func (export "handle") (param $ptr i32) (param $len i32)
;; AND: 0xFF & 0x0F = 0x0F
(i32.store8 (i32.const 200) (i32.and (i32.const 0xFF) (i32.const 0x0F)))
;; OR: 0xF0 | 0x0F = 0xFF
(i32.store8 (i32.const 201) (i32.or (i32.const 0xF0) (i32.const 0x0F)))
(call $send (local.get $ptr) (i32.const 200) (i32.const 2))
)
)
"#;
let wasm = wat::parse_str(wat).unwrap();
let engine = SharedEngine::new().unwrap();
let actor = WasmActorBuilder::new(engine, wasm).build().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
let addr = rt.spawn(actor).unwrap();
rt.send_to(addr, framed_msg(inbox.addr(), b"mask")).unwrap();
rt.tick();
let msg = inbox.try_recv().unwrap();
assert_eq!(msg.0[0], 0x0F, "0xFF & 0x0F = 0x0F");
assert_eq!(msg.0[1], 0xFF, "0xF0 | 0x0F = 0xFF");
}
// ── Two WASM actors with different guest modules on same worker ─────────────
#[test]
fn echo_and_double_coexist_same_worker() {
let engine = SharedEngine::new().unwrap();
let echo = WasmActorBuilder::new(engine.clone(), guest_wasm("echo")).build().unwrap();
let double = WasmActorBuilder::new(engine, guest_wasm("double")).build().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
let e_addr = rt.spawn(echo).unwrap();
let d_addr = rt.spawn(double).unwrap();
rt.send_to(e_addr, framed_msg(inbox.addr(), b"E")).unwrap();
rt.send_to(d_addr, framed_msg(inbox.addr(), b"D")).unwrap();
rt.tick();
let mut msgs: Vec<Vec<u8>> = Vec::new();
while let Some(msg) = inbox.try_recv() {
msgs.push(msg.0);
}
msgs.sort();
// Echo: "E" (1x), Double: "D" (2x)
assert_eq!(msgs, vec![b"D".to_vec(), b"D".to_vec(), b"E".to_vec()]);
}
// ── Guest reads i16 from payload (i32.load16_u) ────────────────────────────
#[test]
fn guest_reads_i16_from_payload() {
let wat = r#"
(module
(import "swactor" "send" (func $send (param i32 i32 i32)))
(memory (export "memory") 1)
(func (export "alloc") (param i32) (result i32) i32.const 4096)
(func (export "handle") (param $ptr i32) (param $len i32)
;; Read 2-byte LE value from first payload bytes
(local $val i32)
(local.set $val
(i32.load16_u (i32.add (local.get $ptr) (i32.const 32)))
)
;; Store low byte of the i16 value
(i32.store8 (i32.const 200) (local.get $val))
;; Store high byte
(i32.store8 (i32.const 201) (i32.shr_u (local.get $val) (i32.const 8)))
(call $send (local.get $ptr) (i32.const 200) (i32.const 2))
)
)
"#;
let wasm = wat::parse_str(wat).unwrap();
let engine = SharedEngine::new().unwrap();
let actor = WasmActorBuilder::new(engine, wasm).build().unwrap();
let rt = Runtime::new(RuntimeConfig::default());
let inbox = rt.new_inbox::<ByteMessage>().unwrap();
let addr = rt.spawn(actor).unwrap();
// Send 0x0102 as little-endian: [0x02, 0x01]
rt.send_to(addr, framed_msg(inbox.addr(), &[0x02, 0x01])).unwrap();
rt.tick();
let msg = inbox.try_recv().unwrap();
// i32.load16_u reads LE: 0x0102
assert_eq!(msg.0[0], 0x02, "low byte of 0x0102");
assert_eq!(msg.0[1], 0x01, "high byte of 0x0102");
}