Skip to content

Commit 0e7cdac

Browse files
lvellaleonardoaltclaude
authored
Startup code (#19)
* Implement ALLOCATE_FRAME and COPY_INTO_FRAME instructions - Add two separate instructions as requested (not combined) - ALLOCATE_FRAME: allocates memory and returns pointer - COPY_INTO_FRAME: copies value into frame-relative address - Adapters live in circuit/src/adapters/ following existing patterns - Core implementations in their respective instruction modules - Frame pointer flows through execution (not shared state) - All tests passing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix copy_into_frame adapter and improve variable names - Add frame-relative addressing comments (to be implemented in full version) - Use more descriptive variable names in both adapters: - allocate_frame: target_reg_offset, allocation_size, target_reg_ptr - copy_into_frame: value_reg_ptr, frame_ptr_reg_ptr, destination_ptr, offset_within_frame - Fix allocate_frame test (removed duplicate instruction) - Keep absolute addressing in mock implementation for test compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * bug * Fixing allocate frame. * New instructions being translated. * Startup code to call the entry point function. * fix copy_into_frame and tests * do not use outputs in copy_into_frame adapter * simplify core * simplify core more --------- Co-authored-by: Leo Alt <leo@powdrlabs.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 846b52b commit 0e7cdac

File tree

1 file changed

+25
-23
lines changed

1 file changed

+25
-23
lines changed

integration/src/womir_translation.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{collections::HashMap, vec};
22

3+
use crate::instruction_builder as ib;
34
use openvm_instructions::{exe::VmExe, instruction::Instruction, program::Program};
45
use openvm_stark_backend::p3_field::PrimeField32;
56
use womir::{
@@ -8,9 +9,7 @@ use womir::{
89
loader::{flattening::WriteOnceASM, func_idx_to_label},
910
};
1011

11-
use crate::instruction_builder;
12-
13-
pub fn program_from_wasm<F: PrimeField32>(wasm_path: &str, _entry_point: &str) -> VmExe<F> {
12+
pub fn program_from_wasm<F: PrimeField32>(wasm_path: &str, entry_point: &str) -> VmExe<F> {
1413
let wasm_bytes = std::fs::read(wasm_path).expect("Failed to read WASM file");
1514
let ir_program = womir::loader::load_wasm(GenericIrSetting, &wasm_bytes).unwrap();
1615

@@ -38,9 +37,22 @@ pub fn program_from_wasm<F: PrimeField32>(wasm_path: &str, _entry_point: &str) -
3837
.filter_map(|d| d.into_instruction(&label_map))
3938
.collect::<Vec<_>>();
4039

40+
// Sanity check the entry point function.
41+
let entry_point = &label_map[entry_point];
42+
let entry_point_func_type = ir_program.c.get_func_type(entry_point.func_idx.unwrap());
43+
assert!(
44+
entry_point_func_type.ty.params().is_empty(),
45+
"Entry point function should not have parameters"
46+
);
47+
4148
// Now we need a little bit of startup code to call the entry point function.
49+
// We assume the initial frame has space for at least one word: the frame pointer
50+
// to the entry point function.
4251
let start_offset = linked_program.len();
43-
linked_program.extend([/* TODO */]);
52+
linked_program.extend([
53+
ib::allocate_frame_imm(0, entry_point.frame_size.unwrap() as usize),
54+
ib::call(0, 1, entry_point.pc as usize, 0),
55+
]);
4456

4557
// TODO: make womir read and carry debug info
4658
// Skip the first instruction, which is a nop inserted by the linker, and adjust pc_base accordingly.
@@ -141,52 +153,43 @@ impl<F: PrimeField32> Directive<F> {
141153
result_ptr,
142154
} => {
143155
let frame_size = label_map.get(&target_frame).unwrap().frame_size.unwrap();
144-
Some(instruction_builder::allocate_frame_imm(
156+
Some(ib::allocate_frame_imm(
145157
result_ptr as usize,
146158
frame_size as usize,
147159
))
148160
}
149161
Directive::Jump { target } => {
150162
let pc = label_map.get(&target).unwrap().pc;
151-
Some(instruction_builder::jump(pc as usize))
163+
Some(ib::jump(pc as usize))
152164
}
153165
Directive::JumpIf {
154166
target,
155167
condition_reg,
156168
} => {
157169
let pc = label_map.get(&target)?.pc;
158-
Some(instruction_builder::jump_if(
159-
condition_reg as usize,
160-
pc as usize,
161-
))
170+
Some(ib::jump_if(condition_reg as usize, pc as usize))
162171
}
163172
Directive::_JumpIfZero {
164173
target,
165174
condition_reg,
166175
} => {
167176
let pc = label_map.get(&target)?.pc;
168-
Some(instruction_builder::jump_if_zero(
169-
condition_reg as usize,
170-
pc as usize,
171-
))
177+
Some(ib::jump_if_zero(condition_reg as usize, pc as usize))
172178
}
173179
Directive::Jaaf {
174180
target,
175181
new_frame_ptr,
176182
} => {
177183
let pc = label_map.get(&target)?.pc;
178-
Some(instruction_builder::jaaf(
179-
pc as usize,
180-
new_frame_ptr as usize,
181-
))
184+
Some(ib::jaaf(pc as usize, new_frame_ptr as usize))
182185
}
183186
Directive::JaafSave {
184187
target,
185188
new_frame_ptr,
186189
saved_caller_fp,
187190
} => {
188191
let pc = label_map.get(&target)?.pc;
189-
Some(instruction_builder::jaaf_save(
192+
Some(ib::jaaf_save(
190193
saved_caller_fp as usize,
191194
pc as usize,
192195
new_frame_ptr as usize,
@@ -199,7 +202,7 @@ impl<F: PrimeField32> Directive<F> {
199202
saved_caller_fp,
200203
} => {
201204
let pc = label_map.get(&target_pc)?.pc;
202-
Some(instruction_builder::call(
205+
Some(ib::call(
203206
pc as usize,
204207
new_frame_ptr as usize,
205208
saved_ret_pc as usize,
@@ -231,7 +234,6 @@ impl<F: Clone> womir::linker::Directive for Directive<F> {
231234
fn translate_directives<F: PrimeField32>(
232235
directive: womir::generic_ir::Directive,
233236
) -> Vec<Directive<F>> {
234-
use instruction_builder as ib;
235237
use womir::generic_ir::Directive as W;
236238

237239
match directive {
@@ -287,7 +289,7 @@ fn translate_directives<F: PrimeField32>(
287289
}
288290
}]
289291
}
290-
W::Return { ret_pc, ret_fp } => vec![Directive::Instruction(instruction_builder::ret(
292+
W::Return { ret_pc, ret_fp } => vec![Directive::Instruction(ib::ret(
291293
ret_pc as usize,
292294
ret_fp as usize,
293295
))],
@@ -307,7 +309,7 @@ fn translate_directives<F: PrimeField32>(
307309
new_frame_ptr,
308310
saved_ret_pc,
309311
saved_caller_fp,
310-
} => vec![Directive::Instruction(instruction_builder::call(
312+
} => vec![Directive::Instruction(ib::call(
311313
saved_ret_pc as usize,
312314
saved_caller_fp as usize,
313315
target_pc as usize,

0 commit comments

Comments
 (0)