Skip to content

Commit fe00d12

Browse files
NathanFlurryclaude
andcommitted
feat: US-054 - Add WarmSnapshot IPC message type
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8b2bdf2 commit fe00d12

3 files changed

Lines changed: 116 additions & 2 deletions

File tree

crates/v8-runtime/src/ipc_binary.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const MSG_EXECUTE: u8 = 0x05;
2424
const MSG_BRIDGE_RESPONSE: u8 = 0x06;
2525
const MSG_STREAM_EVENT: u8 = 0x07;
2626
const MSG_TERMINATE_EXECUTION: u8 = 0x08;
27+
const MSG_WARM_SNAPSHOT: u8 = 0x09;
2728

2829
// Rust → Host message type codes
2930
const MSG_BRIDGE_CALL: u8 = 0x81;
@@ -75,6 +76,9 @@ pub enum BinaryFrame {
7576
TerminateExecution {
7677
session_id: String,
7778
},
79+
WarmSnapshot {
80+
bridge_code: String,
81+
},
7882

7983
// Rust → Host
8084
BridgeCall {
@@ -171,7 +175,7 @@ pub fn extract_session_id(raw: &[u8]) -> io::Result<Option<&str>> {
171175
return Err(io::Error::new(io::ErrorKind::InvalidData, "frame too short"));
172176
}
173177
let msg_type = raw[0];
174-
if msg_type == MSG_AUTHENTICATE {
178+
if msg_type == MSG_AUTHENTICATE || msg_type == MSG_WARM_SNAPSHOT {
175179
return Ok(None);
176180
}
177181
let sid_len = raw[1] as usize;
@@ -264,6 +268,13 @@ fn encode_body(buf: &mut Vec<u8>, frame: &BinaryFrame) {
264268
buf.push(MSG_TERMINATE_EXECUTION);
265269
write_session_id(buf, session_id);
266270
}
271+
BinaryFrame::WarmSnapshot { bridge_code } => {
272+
buf.push(MSG_WARM_SNAPSHOT);
273+
buf.push(0); // no session_id
274+
let bc_bytes = bridge_code.as_bytes();
275+
buf.extend_from_slice(&(bc_bytes.len() as u32).to_be_bytes());
276+
buf.extend_from_slice(bc_bytes);
277+
}
267278
BinaryFrame::BridgeCall {
268279
session_id,
269280
call_id,
@@ -405,6 +416,11 @@ fn decode_body(buf: &[u8]) -> io::Result<BinaryFrame> {
405416
})
406417
}
407418
MSG_TERMINATE_EXECUTION => Ok(BinaryFrame::TerminateExecution { session_id }),
419+
MSG_WARM_SNAPSHOT => {
420+
let bc_len = read_u32(buf, &mut pos)? as usize;
421+
let bridge_code = read_utf8(buf, &mut pos, bc_len)?;
422+
Ok(BinaryFrame::WarmSnapshot { bridge_code })
423+
}
408424
MSG_BRIDGE_CALL => {
409425
let call_id = read_u32(buf, &mut pos)?;
410426
let m_len = read_u16(buf, &mut pos)? as usize;
@@ -760,6 +776,41 @@ mod tests {
760776
});
761777
}
762778

779+
// -- WarmSnapshot --
780+
781+
#[test]
782+
fn roundtrip_warm_snapshot() {
783+
roundtrip(&BinaryFrame::WarmSnapshot {
784+
bridge_code: "(function(){ /* bridge IIFE */ })()".into(),
785+
});
786+
}
787+
788+
#[test]
789+
fn roundtrip_warm_snapshot_empty_bridge_code() {
790+
roundtrip(&BinaryFrame::WarmSnapshot {
791+
bridge_code: "".into(),
792+
});
793+
}
794+
795+
#[test]
796+
fn roundtrip_warm_snapshot_large_bridge_code() {
797+
roundtrip(&BinaryFrame::WarmSnapshot {
798+
bridge_code: "x".repeat(100_000),
799+
});
800+
}
801+
802+
#[test]
803+
fn extract_session_id_warm_snapshot_returns_none() {
804+
let frame = BinaryFrame::WarmSnapshot {
805+
bridge_code: "bridge()".into(),
806+
};
807+
let mut buf = Vec::new();
808+
write_frame(&mut buf, &frame).expect("write");
809+
let raw = &buf[4..];
810+
let result = extract_session_id(raw).expect("extract");
811+
assert_eq!(result, None);
812+
}
813+
763814
// -- Edge cases --
764815

765816
#[test]
@@ -1042,6 +1093,12 @@ mod tests {
10421093
},
10431094
0x08,
10441095
),
1096+
(
1097+
BinaryFrame::WarmSnapshot {
1098+
bridge_code: "bridge()".into(),
1099+
},
1100+
0x09,
1101+
),
10451102
(
10461103
BinaryFrame::BridgeCall {
10471104
session_id: "s".into(),

packages/secure-exec-v8/src/ipc-binary.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const MSG_EXECUTE = 0x05;
2525
const MSG_BRIDGE_RESPONSE = 0x06;
2626
const MSG_STREAM_EVENT = 0x07;
2727
const MSG_TERMINATE_EXECUTION = 0x08;
28+
const MSG_WARM_SNAPSHOT = 0x09;
2829

2930
// Rust → Host message type codes
3031
const MSG_BRIDGE_CALL = 0x81;
@@ -78,6 +79,7 @@ export type BinaryFrame =
7879
payload: Buffer;
7980
}
8081
| { type: "TerminateExecution"; sessionId: string }
82+
| { type: "WarmSnapshot"; bridgeCode: string }
8183
// Rust → Host
8284
| {
8385
type: "BridgeCall";
@@ -191,6 +193,12 @@ export function decodeFrame(buf: Buffer): BinaryFrame {
191193
}
192194
case MSG_TERMINATE_EXECUTION:
193195
return { type: "TerminateExecution", sessionId };
196+
case MSG_WARM_SNAPSHOT: {
197+
const bcLen = buf.readUInt32BE(pos);
198+
pos += 4;
199+
const bridgeCode = buf.toString("utf8", pos, pos + bcLen);
200+
return { type: "WarmSnapshot", bridgeCode };
201+
}
194202
case MSG_BRIDGE_CALL: {
195203
const callId = buf.readUInt32BE(pos);
196204
pos += 4;
@@ -255,7 +263,7 @@ export function extractSessionId(raw: Buffer): string | null {
255263
throw new Error("Frame too short");
256264
}
257265
const msgType = raw[0];
258-
if (msgType === MSG_AUTHENTICATE) {
266+
if (msgType === MSG_AUTHENTICATE || msgType === MSG_WARM_SNAPSHOT) {
259267
return null;
260268
}
261269
const sidLen = raw[1];
@@ -342,6 +350,15 @@ function encodeBody(frame: BinaryFrame): Buffer {
342350
parts.push(encodeSessionId(frame.sessionId));
343351
break;
344352
}
353+
case "WarmSnapshot": {
354+
parts.push(Buffer.from([MSG_WARM_SNAPSHOT, 0])); // no session_id
355+
const bcBuf = Buffer.from(frame.bridgeCode, "utf8");
356+
const bcLen = Buffer.alloc(4);
357+
bcLen.writeUInt32BE(bcBuf.length, 0);
358+
parts.push(bcLen);
359+
parts.push(bcBuf);
360+
break;
361+
}
345362
case "BridgeCall": {
346363
parts.push(Buffer.from([MSG_BRIDGE_CALL]));
347364
parts.push(encodeSessionId(frame.sessionId));

packages/secure-exec-v8/test/ipc-binary.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ describe("Host → Rust messages", () => {
119119
it("round-trips TerminateExecution", () => {
120120
roundtrip({ type: "TerminateExecution", sessionId: "sess-6" });
121121
});
122+
123+
it("round-trips WarmSnapshot", () => {
124+
roundtrip({
125+
type: "WarmSnapshot",
126+
bridgeCode: "(function(){ /* bridge IIFE */ })()",
127+
});
128+
});
129+
130+
it("round-trips WarmSnapshot with empty bridge code", () => {
131+
roundtrip({ type: "WarmSnapshot", bridgeCode: "" });
132+
});
133+
134+
it("round-trips WarmSnapshot with large bridge code", () => {
135+
roundtrip({ type: "WarmSnapshot", bridgeCode: "x".repeat(100_000) });
136+
});
122137
});
123138

124139
// -- Rust → Host message types --
@@ -400,6 +415,16 @@ describe("session_id extraction", () => {
400415
}
401416
});
402417

418+
it("returns null for WarmSnapshot", () => {
419+
const frame: BinaryFrame = {
420+
type: "WarmSnapshot",
421+
bridgeCode: "bridge()",
422+
};
423+
const encoded = encodeFrame(frame);
424+
const raw = encoded.subarray(4);
425+
expect(extractSessionId(raw)).toBeNull();
426+
});
427+
403428
it("returns null for Authenticate", () => {
404429
const frame: BinaryFrame = {
405430
type: "Authenticate",
@@ -468,6 +493,7 @@ describe("wire format interop", () => {
468493
0x07,
469494
],
470495
[{ type: "TerminateExecution", sessionId: "s" }, 0x08],
496+
[{ type: "WarmSnapshot", bridgeCode: "bridge()" }, 0x09],
471497
[
472498
{
473499
type: "BridgeCall",
@@ -559,6 +585,20 @@ describe("wire format interop", () => {
559585
); // payload
560586
});
561587

588+
it("WarmSnapshot wire format matches Rust layout", () => {
589+
const frame: BinaryFrame = {
590+
type: "WarmSnapshot",
591+
bridgeCode: "hi",
592+
};
593+
const encoded = encodeFrame(frame);
594+
const body = encoded.subarray(4);
595+
expect(body[0]).toBe(0x09); // msg_type
596+
expect(body[1]).toBe(0); // sid_len = 0
597+
expect(body.readUInt32BE(2)).toBe(2); // bridge_code_len
598+
expect(body.toString("utf8", 6, 8)).toBe("hi"); // bridge_code
599+
expect(body.length).toBe(8); // total body: 1+1+4+2
600+
});
601+
562602
it("ExecutionResult flags and error layout match Rust", () => {
563603
const frame: BinaryFrame = {
564604
type: "ExecutionResult",

0 commit comments

Comments
 (0)