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 6aeb289df0 - Show all commits

View file

@ -7145,4 +7145,137 @@ fn comprehensive_lifecycle_all_guest_types_200th() {
rt.send_to(echo_addr, framed_msg(inbox.addr(), b"gone")).ok();
rt.tick();
assert!(inbox.try_recv().is_none(), "stopped actors should not deliver");
}
// ── Guest alloc returns pointer at exact page boundary ──────────────────────
#[test]
fn alloc_at_page_boundary_works() {
// Guest alloc returns 65536 - 64 = 65472. With a 64-byte message,
// end = 65472 + 64 = 65536 = memory size. Exactly in bounds.
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 65472)
(func (export "handle") (param $ptr i32) (param $len i32)
(call $send
(local.get $ptr)
(i32.add (local.get $ptr) (i32.const 32))
(i32.sub (local.get $len) (i32.const 32))
)
)
)
"#;
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();
// 32 (addr) + 32 (payload) = 64 bytes → fits exactly at 65472..65536
let payload = vec![0xAB; 32];
rt.send_to(addr, framed_msg(inbox.addr(), &payload)).unwrap();
rt.tick();
let msg = inbox.try_recv().expect("exact page boundary should work");
assert_eq!(msg.0, payload);
}
// ── Guest alloc returns pointer 1 byte past page boundary — drops ───────────
#[test]
fn alloc_one_past_page_boundary_drops() {
// Guest alloc returns 65473. With 64-byte message:
// end = 65473 + 64 = 65537 > 65536. OOB, message dropped.
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 65473)
(func (export "handle") (param i32 i32)
unreachable
)
)
"#;
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();
let payload = vec![0xAB; 32]; // total msg = 64 bytes
rt.send_to(addr, framed_msg(inbox.addr(), &payload)).unwrap();
rt.tick();
assert!(inbox.try_recv().is_none(), "OOB alloc should drop message");
}
// ── Multiple runtimes with WASM actors independently ────────────────────────
#[test]
fn multiple_runtimes_with_wasm_actors() {
let engine = SharedEngine::new().unwrap();
// Runtime 1
let rt1 = Runtime::new(RuntimeConfig::default());
let inbox1 = rt1.new_inbox::<ByteMessage>().unwrap();
let actor1 = WasmActorBuilder::new(engine.clone(), guest_wasm("echo")).build().unwrap();
let addr1 = rt1.spawn(actor1).unwrap();
// Runtime 2
let rt2 = Runtime::new(RuntimeConfig::default());
let inbox2 = rt2.new_inbox::<ByteMessage>().unwrap();
let actor2 = WasmActorBuilder::new(engine, guest_wasm("double")).build().unwrap();
let addr2 = rt2.spawn(actor2).unwrap();
rt1.send_to(addr1, framed_msg(inbox1.addr(), b"rt1")).unwrap();
rt2.send_to(addr2, framed_msg(inbox2.addr(), b"rt2")).unwrap();
rt1.tick();
rt2.tick();
let msg1 = inbox1.try_recv().unwrap();
assert_eq!(msg1.0, b"rt1");
let d1 = inbox2.try_recv().unwrap();
let d2 = inbox2.try_recv().unwrap();
assert_eq!(d1.0, b"rt2");
assert_eq!(d2.0, b"rt2");
}
// ── Guest sends back exact copy of the full message (including address) ─────
#[test]
fn guest_mirrors_full_message() {
// Guest sends back the entire message (address + payload) to the dest.
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)
;; Send the full message (including address header) as payload
(call $send (local.get $ptr) (local.get $ptr) (local.get $len))
)
)
"#;
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();
let original_msg = framed_msg(inbox.addr(), b"mirror");
rt.send_to(addr, original_msg.clone()).unwrap();
rt.tick();
let msg = inbox.try_recv().expect("should receive mirrored full message");
// Payload = full original message (address + payload)
assert_eq!(msg.0, original_msg.0, "should receive exact copy of full message");
}