Skip to content

Commit b275fd7

Browse files
committed
Refactored Box getting libfuncs by CellExpression::add_with_const.
SIERRA_UPDATE_PATCH_CHANGE_TAG=Update of not-enabled libfuncs.
1 parent e09326b commit b275fd7

File tree

3 files changed

+51
-40
lines changed

3 files changed

+51
-40
lines changed

crates/cairo-lang-casm/src/cell_expression.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ impl CellExpression {
9999
})
100100
}
101101
}
102+
103+
/// Returns a cell expression which is the sum of `cell` and `value`.
104+
/// If the value is zero, returns the cell itself.
105+
pub fn add_with_const(cell: CellRef, value: i16) -> CellExpression {
106+
if value == 0 {
107+
CellExpression::Deref(cell)
108+
} else {
109+
CellExpression::BinOp {
110+
op: CellOperator::Add,
111+
a: cell,
112+
b: DerefOrImmediate::Immediate(value.into()),
113+
}
114+
}
115+
}
102116
}
103117

104118
impl ApplyApChange for CellExpression {

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

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use cairo_lang_casm::builder::CasmBuilder;
2-
use cairo_lang_casm::cell_expression::{CellExpression, CellOperator};
3-
use cairo_lang_casm::operand::{CellRef, DerefOrImmediate, Register};
2+
use cairo_lang_casm::cell_expression::CellExpression;
3+
use cairo_lang_casm::operand::{CellRef, Register};
44
use cairo_lang_casm::{casm, casm_build_extend};
55
use cairo_lang_sierra::extensions::boxing::BoxConcreteLibfunc;
66
use cairo_lang_sierra::ids::ConcreteTypeId;
@@ -63,25 +63,17 @@ fn build_local_into_box(
6363
) -> Result<CompiledInvocation, InvocationError> {
6464
let [operand] = builder.try_get_refs()?;
6565

66-
let cell = CellRef { register: Register::AP, offset: -2 };
67-
let addr = match operand.cells.as_slice() {
68-
[] | [CellExpression::Deref(CellRef { register: Register::FP, offset: 0 }), ..] => {
69-
CellExpression::Deref(cell)
70-
}
71-
[CellExpression::Deref(CellRef { register: Register::FP, offset }), ..] => {
72-
CellExpression::BinOp {
73-
op: CellOperator::Add,
74-
a: cell,
75-
b: DerefOrImmediate::Immediate((*offset).into()),
76-
}
77-
}
78-
66+
let fp_val = CellRef { register: Register::AP, offset: -2 };
67+
let offset = match operand.cells.as_slice() {
68+
[] => 0,
69+
[CellExpression::Deref(CellRef { register: Register::FP, offset }), ..] => *offset,
7970
_ => return Err(InvocationError::InvalidReferenceExpressionForArgument),
8071
};
72+
let ptr = CellExpression::add_with_const(fp_val, offset);
8173
Ok(builder.build(
8274
casm!(call rel 0;).instructions,
8375
vec![RelocationEntry { instruction_idx: 0, relocation: Relocation::EndOfProgram }],
84-
[[ReferenceExpression::from_cell(addr)].into_iter()].into_iter(),
76+
[[ReferenceExpression::from_cell(ptr)].into_iter()].into_iter(),
8577
))
8678
}
8779

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

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use cairo_lang_casm::cell_expression::{CellExpression, CellOperator};
2-
use cairo_lang_casm::operand::DerefOrImmediate;
1+
use cairo_lang_casm::cell_expression::CellExpression;
32
use cairo_lang_sierra::extensions::ConcreteLibfunc;
43
use cairo_lang_sierra::extensions::structure::{
54
ConcreteStructBoxedDeconstructLibfunc, StructConcreteLibfunc,
65
};
7-
use cairo_lang_utils::casts::IntoOrPanic;
6+
use cairo_lang_sierra::ids::ConcreteTypeId;
7+
use cairo_lang_sierra_type_size::TypeSizeMap;
88

99
use super::{CompiledInvocation, CompiledInvocationBuilder, InvocationError};
1010
use crate::references::ReferenceExpression;
@@ -58,28 +58,33 @@ fn build_struct_boxed_deconstruct(
5858
libfunc: &ConcreteStructBoxedDeconstructLibfunc,
5959
builder: CompiledInvocationBuilder<'_>,
6060
) -> Result<CompiledInvocation, InvocationError> {
61-
let [cell] = builder.try_get_single_cells()?;
62-
let Some((boxed_struct_addr, orig_offset)) = cell.to_deref_with_offset() else {
63-
return Err(InvocationError::InvalidReferenceExpressionForArgument);
64-
};
65-
let mut next_member_box = cell.clone();
66-
let mut outputs = vec![];
67-
let mut current_offset = orig_offset.into_or_panic::<i16>();
68-
for member_ty in &libfunc.members {
69-
outputs.push(next_member_box);
70-
let member_size = *builder
71-
.program_info
72-
.type_sizes
73-
.get(member_ty)
61+
let [input_ptr] = builder.try_get_single_cells()?;
62+
let outputs =
63+
boxed_members_cell_exprs(builder.program_info.type_sizes, &libfunc.members, input_ptr)
7464
.ok_or(InvocationError::InvalidReferenceExpressionForArgument)?;
75-
current_offset += member_size;
76-
next_member_box = CellExpression::BinOp {
77-
op: CellOperator::Add,
78-
a: boxed_struct_addr,
79-
b: DerefOrImmediate::Immediate(current_offset.into()),
80-
};
81-
}
82-
8365
Ok(builder
8466
.build_only_reference_changes(outputs.into_iter().map(ReferenceExpression::from_cell)))
8567
}
68+
69+
/// Returns a vector of cell expressions representing the memory addresses of the unboxed members of
70+
/// a boxed struct.
71+
///
72+
/// Note: All failures returning `None` in this function should never actually occur assuming the
73+
/// original boxed type containing recursively all other types (through enums or structs), had an
74+
/// `orig_offset` offset of 0, as all internal offsets are bounded by the size of the struct itself,
75+
/// which is bounded by `i16::MAX`.
76+
fn boxed_members_cell_exprs(
77+
type_sizes: &TypeSizeMap,
78+
member_tys: &[ConcreteTypeId],
79+
input_ptr: &CellExpression,
80+
) -> Option<Vec<CellExpression>> {
81+
let (boxed_struct_ptr, orig_offset) = input_ptr.to_deref_with_offset()?;
82+
let mut outputs = vec![];
83+
let mut current_offset = orig_offset.try_into().ok()?;
84+
for member_ty in member_tys {
85+
outputs.push(CellExpression::add_with_const(boxed_struct_ptr, current_offset));
86+
let member_size = *type_sizes.get(member_ty)?;
87+
current_offset = current_offset.checked_add(member_size)?;
88+
}
89+
Some(outputs)
90+
}

0 commit comments

Comments
 (0)