Skip to content

Commit 17593ef

Browse files
committed
fix(vmbc): restore metadata-reserved root locals
1 parent 92e3759 commit 17593ef

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

src/vmbc.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,26 @@ pub fn decode_program(bytes: &[u8]) -> Result<Program, WireError> {
322322
program.function_regions = function_regions;
323323
program.root_callable_bindings = root_callable_bindings;
324324
program.exported_callables = exported_callables;
325+
let type_map_local_count = program
326+
.type_map
327+
.as_ref()
328+
.map_or(0, |type_map| type_map.local_types.len());
329+
let callable_local_count = program
330+
.root_callable_bindings
331+
.iter()
332+
.map(|binding| binding.local_slot as usize + 1)
333+
.chain(
334+
program
335+
.exported_callables
336+
.iter()
337+
.map(|exported| exported.local_slot as usize + 1),
338+
)
339+
.max()
340+
.unwrap_or(0);
341+
program.local_count = program
342+
.local_count
343+
.max(type_map_local_count)
344+
.max(callable_local_count);
325345
Ok(program)
326346
}
327347

tests/wire/wire_tests.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,25 @@ fn wire_roundtrip_preserves_constants_and_code() {
6565
assert_eq!(decoded.type_map, program.type_map);
6666
}
6767

68+
#[test]
69+
fn wire_roundtrip_recovers_locals_reserved_by_type_metadata() {
70+
let local_count = 8;
71+
let program = Program::new(Vec::new(), vec![vm::OpCode::Ret as u8])
72+
.with_local_count(local_count)
73+
.with_type_map(TypeMap {
74+
strict_types: true,
75+
local_types: vec![ValueType::Unknown; local_count],
76+
local_schemas: vec![None; local_count],
77+
callable_slots: vec![false; local_count],
78+
optional_slots: vec![false; local_count],
79+
operand_types: HashMap::new(),
80+
});
81+
82+
let encoded = encode_program(&program).expect("encode reserved locals");
83+
let decoded = decode_program(&encoded).expect("decode reserved locals");
84+
assert_eq!(decoded.local_count, local_count);
85+
}
86+
6887
#[test]
6988
fn decode_rejects_invalid_magic_version_and_truncation() {
7089
let program = Program::new(vec![Value::Int(7)], vec![0x01]);

0 commit comments

Comments
 (0)