Skip to content

Commit

Permalink
Invalidate stack when deconstructing a struct as it is not supported … (
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyalesokhin-starkware authored Mar 6, 2024
1 parent 5aa90bc commit 0f85ea8
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ label_test::foo::0:
function_call<user@test::get_val>() -> ([0])
struct_deconstruct<Tuple<u32, Unit, u32>>([0]) -> ([1], [2], [3])
drop<Unit>([2]) -> ()
store_temp<u32>([1]) -> ([1])
store_temp<u32>([3]) -> ([3])
function_call<user@test::test_func>([1], [3]) -> ()
return()

Expand Down Expand Up @@ -73,7 +75,6 @@ dup<Tuple<felt252, felt252>>([0]) -> ([0], [1])
struct_deconstruct<Tuple<felt252, felt252>>([1]) -> ([2], [3])
drop<felt252>([2]) -> ()
drop<felt252>([3]) -> ()
store_temp<Tuple<felt252, felt252>>([0]) -> ([0])
return([0])

//! > ==========================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,47 +163,4 @@ impl KnownStack {
offset: new_offset,
}
}

/// Updates the stack after a variable is deconstructed.
/// input is the deconstructed variable, and outputs are the non-zero sized variables that
/// replace it.
pub fn deconstruct_variable(
&mut self,
input: &cairo_lang_sierra::ids::VarId,
outputs: &[cairo_lang_sierra::ids::VarId],
) {
let Some(input_idx) = self.variables_on_stack.swap_remove(input) else {
return;
};
let n_outputs = outputs.len();

self.variables_on_stack = std::mem::take(&mut self.variables_on_stack)
.into_iter()
.filter_map(|(var, idx)| {
// Invalidate all the variable at `input_idx` and insert `n_outputs`
// at that place.
// We lose track of the of the fact that the original variable is still on the
// stack but that situation is quite rare.

// TODO(ilya): Consider supporting items the occupy stack slots.
if input_idx == idx {
return None;
}

let mut idx = idx;
if input_idx < idx {
idx += n_outputs;
idx -= 1;
}
Some((var, idx))
})
.collect();

for (offset, output) in outputs.iter().enumerate() {
assert!(self.variables_on_stack.insert(output.clone(), input_idx + offset).is_none());
}

self.offset += n_outputs;
self.offset -= 1;
}
}
46 changes: 1 addition & 45 deletions crates/cairo-lang-sierra-generator/src/store_variables/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use itertools::zip_eq;
use sierra::extensions::function_call::{CouponCallLibfunc, FunctionCallLibfunc};
use sierra::extensions::gas::RedepositGasLibfunc;
use sierra::extensions::structure::StructDeconstructLibfunc;
use sierra::extensions::{NamedLibfunc, OutputVarReferenceInfo};
use sierra::extensions::NamedLibfunc;
use sierra::ids::GenericLibfuncId;
use sierra::program::ConcreteLibfuncLongId;
use state::{
Expand Down Expand Up @@ -147,49 +146,6 @@ impl<'a> AddStoreVariableStatements<'a> {
// arguments to a local variables.
invocation.args.iter().map(|var| state.pop_var_state(var)).collect()
}
StructDeconstructLibfunc::STR_ID => {
let arg = &invocation.args[0];
let var_state = state.pop_var_state(arg);

let results = &invocation.branches[0].results;
let mut non_zero_sized_outputs = vec![];
for (output, output_info) in
zip_eq(results, &signature.branch_signatures[0].vars)
{
let output_state = match var_state {
VarState::ZeroSizedVar => VarState::ZeroSizedVar,
_ if matches!(
output_info.ref_info,
OutputVarReferenceInfo::ZeroSized
) =>
{
VarState::ZeroSizedVar
}
VarState::TempVar { .. } => {
VarState::TempVar { ty: output_info.ty.clone() }
}
VarState::Deferred { info: DeferredVariableInfo { kind, .. } } => {
VarState::Deferred {
info: DeferredVariableInfo {
kind,
ty: output_info.ty.clone(),
},
}
}
VarState::LocalVar => VarState::LocalVar,
VarState::Removed => unreachable!(),
};

if !matches!(output_state, VarState::ZeroSizedVar) {
non_zero_sized_outputs.push(output.clone())
}

state.variables.insert(output.clone(), output_state);
}
state.known_stack.deconstruct_variable(arg, &non_zero_sized_outputs);
self.result.push(statement);
return Some(std::mem::take(state));
}
_ => self.prepare_libfunc_arguments(
state,
&invocation.args,
Expand Down

0 comments on commit 0f85ea8

Please sign in to comment.