Skip to content

Commit 902d2d9

Browse files
(refactor): Build jump and jump table to support prepended instructions.
SIERRA_UPDATE_MINOR_CHANGE_TAG=Refactored jump table building functions
1 parent a793aa3 commit 902d2d9

File tree

1 file changed

+38
-4
lines changed
  • crates/cairo-lang-sierra-to-casm/src/invocations

1 file changed

+38
-4
lines changed

crates/cairo-lang-sierra-to-casm/src/invocations/enm.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use cairo_lang_casm::builder::CasmBuilder;
22
use cairo_lang_casm::cell_expression::CellExpression;
3+
use cairo_lang_casm::instructions::Instruction;
34
use cairo_lang_casm::operand::CellRef;
45
use cairo_lang_casm::{casm, casm_build_extend, casm_extend};
56
use cairo_lang_sierra::extensions::ConcreteLibfunc;
@@ -230,8 +231,20 @@ fn build_enum_match_short(
230231
Item = impl ExactSizeIterator<Item = ReferenceExpression>,
231232
>,
232233
) -> Result<CompiledInvocation, InvocationError> {
233-
let mut instructions = Vec::new();
234+
build_enum_match_short_ex(builder, variant_selector, output_expressions, Vec::with_capacity(1))
235+
}
236+
237+
/// Extended version of `build_enum_match_short` that allows prepending instructions.
238+
fn build_enum_match_short_ex(
239+
builder: CompiledInvocationBuilder<'_>,
240+
variant_selector: CellRef,
241+
output_expressions: impl ExactSizeIterator<
242+
Item = impl ExactSizeIterator<Item = ReferenceExpression>,
243+
>,
244+
mut instructions: Vec<Instruction>,
245+
) -> Result<CompiledInvocation, InvocationError> {
234246
let mut relocations = Vec::new();
247+
let base_instruction_count = instructions.len();
235248

236249
// First branch is fallthrough. If there is only one branch, this `match` statement is
237250
// translated to nothing in Casm.
@@ -245,7 +258,7 @@ fn build_enum_match_short(
245258

246259
instructions.extend(casm! { jmp rel 0 if variant_selector != 0; }.instructions);
247260
relocations.push(RelocationEntry {
248-
instruction_idx: 0,
261+
instruction_idx: base_instruction_count,
249262
relocation: Relocation::RelativeStatementId(statement_id),
250263
});
251264
}
@@ -284,12 +297,32 @@ fn build_enum_match_long(
284297
output_expressions: impl ExactSizeIterator<
285298
Item = impl ExactSizeIterator<Item = ReferenceExpression>,
286299
>,
300+
) -> Result<CompiledInvocation, InvocationError> {
301+
let expected_instruction_count = builder.invocation.branches.len() + 1;
302+
build_enum_match_long_ex(
303+
builder,
304+
variant_selector,
305+
output_expressions,
306+
Vec::with_capacity(expected_instruction_count),
307+
)
308+
}
309+
310+
/// Extended version of `build_enum_match_long` that allows prepending instructions.
311+
fn build_enum_match_long_ex(
312+
builder: CompiledInvocationBuilder<'_>,
313+
variant_selector: CellRef,
314+
output_expressions: impl ExactSizeIterator<
315+
Item = impl ExactSizeIterator<Item = ReferenceExpression>,
316+
>,
317+
mut instructions: Vec<Instruction>,
287318
) -> Result<CompiledInvocation, InvocationError> {
288319
let target_statement_ids = builder.invocation.branches[1..].iter().map(|b| match b {
289320
BranchInfo { target: BranchTarget::Statement(stmnt_id), .. } => *stmnt_id,
290321
_ => panic!("malformed invocation"),
291322
});
292323

324+
let base_instruction_count = instructions.len();
325+
293326
// The first instruction is the jmp to the relevant index in the jmp table.
294327
let mut ctx = casm! { jmp rel variant_selector; };
295328
let mut relocations = Vec::new();
@@ -300,12 +333,13 @@ fn build_enum_match_long(
300333
// Add the jump instruction to the relevant target.
301334
casm_extend!(ctx, jmp rel 0;);
302335
relocations.push(RelocationEntry {
303-
instruction_idx: i + 1,
336+
instruction_idx: base_instruction_count + i + 1,
304337
relocation: Relocation::RelativeStatementId(stmnt_id),
305338
});
306339
}
307340

308-
Ok(builder.build(ctx.instructions, relocations, output_expressions))
341+
instructions.extend(ctx.instructions);
342+
Ok(builder.build(instructions, relocations, output_expressions))
309343
}
310344

311345
/// A struct representing an actual enum value in the Sierra program.

0 commit comments

Comments
 (0)