Skip to content

Commit 3f4d687

Browse files
author
Gilad Chase
committed
Add box tests for local_into_box
1 parent 847c438 commit 3f4d687

File tree

4 files changed

+140
-9
lines changed

4 files changed

+140
-9
lines changed

corelib/src/test.cairo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mod to_byte_array_test;
3737
/// Tests for language features, without mixing implementations within the corelib.
3838
mod language_features {
3939
mod block_level_items_test;
40+
mod box_test;
4041
mod closure_test;
4142
mod const_folding_test;
4243
mod const_test;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
extern fn local_into_box<T>(value: T) -> Box<T> nopanic;
2+
3+
/// Boxes a value by storing it in a local variable first (via calling conventions), then delegating
4+
/// to `local_into_box` which expects a local.
5+
#[inline(never)]
6+
pub fn into_box<T>(value: T) -> Box<T> {
7+
local_into_box(value)
8+
}
9+
10+
#[test]
11+
fn test_local_into_box() {
12+
assert_eq!(into_box((1, 2_u256, 3)).unbox(), (1, 2, 3));
13+
assert_eq!(into_box(()).unbox(), ());
14+
assert_eq!(into_box(Some(6_u8)).unbox(), Some(6));
15+
assert_eq!(into_box(None::<u8>).unbox(), None);
16+
assert_eq!(into_box(Ok::<u16, u256>(7)).unbox(), Ok(7));
17+
assert_eq!(into_box(Err::<u16, u256>(8)).unbox(), Err(8));
18+
}

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,20 @@ fn build_local_into_box(
6363
) -> Result<CompiledInvocation, InvocationError> {
6464
let [operand] = builder.try_get_refs()?;
6565

66-
let base_offset = match &operand.cells[..] {
67-
[] => 0,
68-
[CellExpression::Deref(cell), ..] if cell.register == Register::FP => cell.offset.into(),
69-
_ => return Err(InvocationError::InvalidReferenceExpressionForArgument),
70-
};
7166
let cell = CellRef { register: Register::AP, offset: -2 };
72-
let addr = CellExpression::BinOp {
73-
op: CellOperator::Add,
74-
a: cell,
75-
b: DerefOrImmediate::Immediate(base_offset.into()),
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+
79+
_ => return Err(InvocationError::InvalidReferenceExpressionForArgument),
7680
};
7781
Ok(builder.build(
7882
casm!(call rel 0;).instructions,

tests/e2e_test_data/libfuncs/box

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,3 +728,111 @@ return([3]);
728728

729729
test::helper@F0() -> (Box<test::A>);
730730
test::foo@F1() -> (Tuple<Box<core::integer::u256>, Box<core::integer::u256>>);
731+
732+
//! > ==========================================================================
733+
734+
//! > local_into_box with fp-based variable
735+
736+
//! > test_runner_name
737+
SmallE2ETestRunner
738+
739+
//! > cairo_code
740+
extern fn local_into_box<T>(value: T) -> Box<T> nopanic;
741+
fn foo(x: felt252) -> Box<felt252> {
742+
local_into_box(x)
743+
}
744+
745+
//! > casm
746+
call rel 5;
747+
[ap + 0] = [ap + -2] + -3, ap++;
748+
ret;
749+
750+
//! > function_costs
751+
test::foo: SmallOrderedMap({Const: 400})
752+
753+
//! > sierra_code
754+
type felt252 = felt252 [storable: true, drop: true, dup: true, zero_sized: false];
755+
type Box<felt252> = Box<felt252> [storable: true, drop: true, dup: true, zero_sized: false];
756+
757+
libfunc local_into_box<felt252> = local_into_box<felt252>;
758+
libfunc store_temp<Box<felt252>> = store_temp<Box<felt252>>;
759+
760+
F0:
761+
local_into_box<felt252>([0]) -> ([1]);
762+
store_temp<Box<felt252>>([1]) -> ([1]);
763+
return([1]);
764+
765+
test::foo@F0([0]: felt252) -> (Box<felt252>);
766+
767+
//! > ==========================================================================
768+
769+
//! > reference operator with zero-sized type
770+
771+
//! > test_runner_name
772+
SmallE2ETestRunner
773+
774+
//! > cairo_code
775+
extern fn local_into_box<T>(value: T) -> Box<T> nopanic;
776+
fn foo(x: ()) -> Box<()> {
777+
local_into_box(x)
778+
}
779+
780+
//! > casm
781+
call rel 4;
782+
[ap + 0] = [ap + -2], ap++;
783+
ret;
784+
785+
//! > function_costs
786+
test::foo: SmallOrderedMap({Const: 400})
787+
788+
//! > sierra_code
789+
type Unit = Struct<ut@Tuple> [storable: true, drop: true, dup: true, zero_sized: true];
790+
type Box<Unit> = Box<Unit> [storable: true, drop: true, dup: true, zero_sized: false];
791+
792+
libfunc local_into_box<Unit> = local_into_box<Unit>;
793+
libfunc store_temp<Box<Unit>> = store_temp<Box<Unit>>;
794+
795+
F0:
796+
local_into_box<Unit>([0]) -> ([1]);
797+
store_temp<Box<Unit>>([1]) -> ([1]);
798+
return([1]);
799+
800+
test::foo@F0([0]: Unit) -> (Box<Unit>);
801+
802+
//! > ==========================================================================
803+
804+
//! > reference operator non-local zero-sized type
805+
806+
//! > test_runner_name
807+
SmallE2ETestRunner
808+
809+
//! > cairo_code
810+
extern fn local_into_box<T>(value: T) -> Box<T> nopanic;
811+
812+
fn foo() -> Box<()> {
813+
local_into_box(())
814+
}
815+
816+
//! > casm
817+
call rel 4;
818+
[ap + 0] = [ap + -2], ap++;
819+
ret;
820+
821+
//! > sierra_code
822+
type Unit = Struct<ut@Tuple> [storable: true, drop: true, dup: true, zero_sized: true];
823+
type Box<Unit> = Box<Unit> [storable: true, drop: true, dup: true, zero_sized: false];
824+
825+
libfunc struct_construct<Unit> = struct_construct<Unit>;
826+
libfunc local_into_box<Unit> = local_into_box<Unit>;
827+
libfunc store_temp<Box<Unit>> = store_temp<Box<Unit>>;
828+
829+
F0:
830+
struct_construct<Unit>() -> ([0]);
831+
local_into_box<Unit>([0]) -> ([1]);
832+
store_temp<Box<Unit>>([1]) -> ([1]);
833+
return([1]);
834+
835+
test::foo@F0() -> (Box<Unit>);
836+
837+
//! > function_costs
838+
test::foo: SmallOrderedMap({Const: 400})

0 commit comments

Comments
 (0)