Skip to content

Commit

Permalink
Fix dict deserialization. (#672)
Browse files Browse the repository at this point in the history
* Fix dict deserialization.

* Remove commented line.

* Fix and enable fixed tests.

* Add tests for dicts of structs and enums.
  • Loading branch information
azteca1998 authored Jun 6, 2024
1 parent 67f42fb commit e90c4ce
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 37 deletions.
31 changes: 7 additions & 24 deletions src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use starknet_types_core::felt::Felt;
use std::{
alloc::Layout,
arch::global_asm,
ptr::{null_mut, NonNull},
ptr::{addr_of_mut, null_mut, NonNull},
rc::Rc,
};

Expand Down Expand Up @@ -820,29 +820,12 @@ fn parse_result(
Ok(JitValue::from_jit(return_ptr.unwrap(), type_id, registry))
}
}
CoreTypeConcrete::Felt252Dict(_) => match return_ptr {
Some(return_ptr) => Ok(JitValue::from_jit(
unsafe { *return_ptr.cast::<NonNull<()>>().as_ref() },
type_id,
registry,
)),
None => Ok(JitValue::from_jit(
NonNull::new(ret_registers[0] as *mut ()).unwrap(),
type_id,
registry,
)),
},
CoreTypeConcrete::SquashedFelt252Dict(_) => match return_ptr {
Some(return_ptr) => Ok(JitValue::from_jit(
unsafe { *return_ptr.cast::<NonNull<()>>().as_ref() },
type_id,
registry,
)),
None => Ok(JitValue::from_jit(
NonNull::new(ret_registers[0] as *mut ()).unwrap(),
type_id,
registry,
)),
CoreTypeConcrete::Felt252Dict(_) | CoreTypeConcrete::SquashedFelt252Dict(_) => unsafe {
let ptr = return_ptr.unwrap_or(NonNull::new_unchecked(
addr_of_mut!(ret_registers[0]) as *mut ()
));
let value = JitValue::from_jit(ptr, type_id, registry);
Ok(value)
},

// Builtins are handled before the call to parse_result
Expand Down
98 changes: 97 additions & 1 deletion src/libfuncs/felt252_dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ pub fn build_squash<'ctx, 'this>(

#[cfg(test)]
mod test {
use crate::utils::test::{jit_dict, jit_struct, load_cairo, run_program_assert_output};
use crate::{
utils::test::{jit_dict, jit_enum, jit_struct, load_cairo, run_program_assert_output},
values::JitValue,
};

#[test]
fn run_dict_new() {
Expand Down Expand Up @@ -208,4 +211,97 @@ mod test {
),
);
}

#[test]
fn run_dict_deserialize2() {
let program = load_cairo!(
use traits::Default;
use dict::Felt252DictTrait;

fn run_test(mut dict: Felt252Dict<u32>) -> (felt252, Felt252Dict<u32>) {
(0, dict)
}
);

run_program_assert_output(
&program,
"run_test",
&[jit_dict!(
1 => 2u32,
2 => 3u32,
3 => 4u32,
4 => 5u32,
5 => 6u32,
)],
jit_struct!(
JitValue::Felt252(0.into()),
jit_dict!(
1 => 2u32,
2 => 3u32,
3 => 4u32,
4 => 5u32,
5 => 6u32,
)
),
);
}

#[test]
fn run_dict_deserialize_struct() {
let program = load_cairo! {
use core::{dict::Felt252DictTrait, nullable::Nullable};

fn run_test() -> Felt252Dict<Nullable<(u32, u64, u128)>> {
let mut x: Felt252Dict<Nullable<(u32, u64, u128)>> = Default::default();
x.insert(0, NullableTrait::new((1_u32, 2_u64, 3_u128)));
x.insert(1, NullableTrait::new((2_u32, 3_u64, 4_u128)));
x.insert(2, NullableTrait::new((3_u32, 4_u64, 5_u128)));
x
}
};

run_program_assert_output(
&program,
"run_test",
&[],
jit_dict!(
0 => jit_struct!(1u32.into(), 2u64.into(), 3u128.into()),
1 => jit_struct!(2u32.into(), 3u64.into(), 4u128.into()),
2 => jit_struct!(3u32.into(), 4u64.into(), 5u128.into()),
),
);
}

#[test]
fn run_dict_deserialize_enum() {
let program = load_cairo! {
use core::{dict::Felt252DictTrait, nullable::Nullable};

#[derive(Drop)]
enum MyEnum {
A: u32,
B: u64,
C: u128,
}

fn run_test() -> Felt252Dict<Nullable<MyEnum>> {
let mut x: Felt252Dict<Nullable<MyEnum>> = Default::default();
x.insert(0, NullableTrait::new(MyEnum::A(1)));
x.insert(1, NullableTrait::new(MyEnum::B(2)));
x.insert(2, NullableTrait::new(MyEnum::C(3)));
x
}
};

run_program_assert_output(
&program,
"run_test",
&[],
jit_dict!(
0 => jit_enum!(0, 1u32.into()),
1 => jit_enum!(1, 2u64.into()),
2 => jit_enum!(2, 3u128.into()),
),
);
}
}
3 changes: 0 additions & 3 deletions src/types/squashed_felt252_dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,5 @@ pub fn build<'ctx>(
_metadata: &mut MetadataStorage,
_info: WithSelf<InfoAndTypeConcreteType>,
) -> Result<Type<'ctx>> {
//let inner = registry.get_type(&info.ty)?;
//let layout = inner.layout(registry)?;

Ok(llvm::r#type::pointer(context, 0))
}
6 changes: 4 additions & 2 deletions src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,8 +705,10 @@ impl JitValue {
}
CoreTypeConcrete::Felt252Dict(info)
| CoreTypeConcrete::SquashedFelt252Dict(info) => {
let map = Box::from_raw(
ptr.cast::<HashMap<[u8; 32], NonNull<std::ffi::c_void>>>()
let (map, _) = *Box::from_raw(
ptr.cast::<NonNull<()>>()
.as_ref()
.cast::<(HashMap<[u8; 32], NonNull<std::ffi::c_void>>, u64)>()
.as_ptr(),
);

Expand Down
30 changes: 25 additions & 5 deletions tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,7 @@ pub fn load_cairo_path(program_path: &str) -> (String, Program, SierraCasmRunner
let mut db = RootDatabase::default();
init_dev_corelib(
&mut db,
Path::new(
&var("CARGO_MANIFEST_DIR")
.unwrap_or_else(|_| "/Users/esteve/Documents/LambdaClass/cairo_native".to_string()),
)
.join("corelib/src"),
Path::new(&var("CARGO_MANIFEST_DIR").unwrap()).join("corelib/src"),
);
let main_crate_ids = setup_project(&mut db, program_file).unwrap();
let program = compile_prepared_db(
Expand Down Expand Up @@ -312,6 +308,7 @@ pub fn compare_outputs(
| CoreTypeConcrete::Sint32(_)
| CoreTypeConcrete::Sint16(_)
| CoreTypeConcrete::Sint8(_)
| CoreTypeConcrete::Box(_)
| CoreTypeConcrete::Nullable(_) => 1,
CoreTypeConcrete::Enum(info) => {
1 + info
Expand All @@ -331,6 +328,7 @@ pub fn compare_outputs(
CoreTypeConcrete::Snapshot(info) => {
map_vm_sizes(size_cache, registry, &info.ty)
}
CoreTypeConcrete::SquashedFelt252Dict(_) => 2,
x => todo!("vm size not yet implemented: {:?}", x.info()),
};
size_cache.insert(ty.clone(), type_size);
Expand Down Expand Up @@ -495,6 +493,28 @@ pub fn compare_outputs(
),
}
}
CoreTypeConcrete::Box(info) => {
assert_eq!(values.len(), 1);

let ty_size = map_vm_sizes(size_cache, registry, &info.ty);
match values[0].to_usize().unwrap() {
ptr if ty_size == 0 => {
assert_eq!(ptr, 1);
map_vm_values(size_cache, registry, memory, &[], &info.ty)
}
ptr => map_vm_values(
size_cache,
registry,
memory,
&memory[ptr..ptr + ty_size]
.iter()
.cloned()
.map(Option::unwrap)
.collect::<Vec<_>>(),
&info.ty,
),
}
}
CoreTypeConcrete::NonZero(info) => {
map_vm_values(size_cache, registry, memory, values, &info.ty)
}
Expand Down
4 changes: 2 additions & 2 deletions tests/tests/cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ use test_case::test_case;
#[test_case("tests/cases/cairo_vm/hello.cairo")]
#[test_case("tests/cases/cairo_vm/my_rectangle.cairo")]
#[test_case("tests/cases/cairo_vm/null_ret.cairo")]
// #[test_case("tests/cases/cairo_vm/nullable_box_vec.cairo")]
// #[test_case("tests/cases/cairo_vm/nullable_dict.cairo")]
#[test_case("tests/cases/cairo_vm/nullable_box_vec.cairo")]
#[test_case("tests/cases/cairo_vm/nullable_dict.cairo")]
#[test_case("tests/cases/cairo_vm/ops.cairo")]
#[test_case("tests/cases/cairo_vm/pedersen_example.cairo")]
#[test_case("tests/cases/cairo_vm/poseidon.cairo")]
Expand Down

0 comments on commit e90c4ce

Please sign in to comment.