cairo_lang_sierra/extensions/modules/
mem.rs1use super::uninitialized::UninitializedType;
2use super::utils::reinterpret_cast_signature;
3use crate::define_libfunc_hierarchy;
4use crate::extensions::lib_func::{
5 LibfuncSignature, OutputVarInfo, ParamSignature, SierraApChange,
6 SignatureAndTypeGenericLibfunc, SignatureOnlyGenericLibfunc, SignatureSpecializationContext,
7 WrapSignatureAndTypeGenericLibfunc,
8};
9use crate::extensions::{
10 NamedType, NoGenericArgsGenericLibfunc, OutputVarReferenceInfo, SpecializationError,
11 args_as_single_type,
12};
13use crate::ids::ConcreteTypeId;
14use crate::program::GenericArg;
15
16define_libfunc_hierarchy! {
17 pub enum MemLibfunc {
18 StoreTemp(StoreTempLibfunc),
19 StoreLocal(StoreLocalLibfunc),
20 FinalizeLocals(FinalizeLocalsLibfunc),
21 AllocLocal(AllocLocalLibfunc),
22 Rename(RenameLibfunc),
23 }, MemConcreteLibfunc
24}
25
26#[derive(Default)]
28pub struct StoreTempLibfuncWrapped {}
29impl SignatureAndTypeGenericLibfunc for StoreTempLibfuncWrapped {
30 const STR_ID: &'static str = "store_temp";
31
32 fn specialize_signature(
33 &self,
34 context: &dyn SignatureSpecializationContext,
35 ty: ConcreteTypeId,
36 ) -> Result<LibfuncSignature, SpecializationError> {
37 let type_info = context.as_type_specialization_context().get_type_info(ty.clone())?;
38 if !type_info.storable {
39 return Err(SpecializationError::UnsupportedGenericArg);
40 }
41 Ok(LibfuncSignature::new_non_branch_ex(
42 vec![ParamSignature {
43 ty: ty.clone(),
44 allow_deferred: true,
45 allow_add_const: true,
46 allow_const: true,
47 }],
48 vec![OutputVarInfo {
49 ty,
50 ref_info: if type_info.zero_sized {
51 OutputVarReferenceInfo::ZeroSized
52 } else {
53 OutputVarReferenceInfo::NewTempVar { idx: 0 }
54 },
55 }],
56 SierraApChange::Known { new_vars_only: true },
57 ))
58 }
59}
60pub type StoreTempLibfunc = WrapSignatureAndTypeGenericLibfunc<StoreTempLibfuncWrapped>;
61
62#[derive(Default)]
64pub struct StoreLocalLibfuncWrapped {}
65impl SignatureAndTypeGenericLibfunc for StoreLocalLibfuncWrapped {
66 const STR_ID: &'static str = "store_local";
67
68 fn specialize_signature(
69 &self,
70 context: &dyn SignatureSpecializationContext,
71 ty: ConcreteTypeId,
72 ) -> Result<LibfuncSignature, SpecializationError> {
73 let uninitialized_type =
74 context.get_wrapped_concrete_type(UninitializedType::id(), ty.clone())?;
75 let type_info = context.as_type_specialization_context().get_type_info(ty.clone())?;
76 if !type_info.storable {
77 return Err(SpecializationError::UnsupportedGenericArg);
78 }
79 Ok(LibfuncSignature::new_non_branch_ex(
80 vec![ParamSignature::new(uninitialized_type), ParamSignature {
81 ty: ty.clone(),
82 allow_deferred: true,
83 allow_add_const: true,
84 allow_const: true,
85 }],
86 vec![OutputVarInfo {
87 ty,
88 ref_info: if type_info.zero_sized {
89 OutputVarReferenceInfo::ZeroSized
90 } else {
91 OutputVarReferenceInfo::NewLocalVar
92 },
93 }],
94 SierraApChange::Known { new_vars_only: true },
95 ))
96 }
97}
98pub type StoreLocalLibfunc = WrapSignatureAndTypeGenericLibfunc<StoreLocalLibfuncWrapped>;
99
100#[derive(Default)]
102pub struct FinalizeLocalsLibfunc {}
103impl NoGenericArgsGenericLibfunc for FinalizeLocalsLibfunc {
104 const STR_ID: &'static str = "finalize_locals";
105
106 fn specialize_signature(
107 &self,
108 _context: &dyn SignatureSpecializationContext,
109 ) -> Result<LibfuncSignature, SpecializationError> {
110 Ok(LibfuncSignature::new_non_branch(vec![], vec![], SierraApChange::Known {
111 new_vars_only: false,
112 }))
113 }
114}
115
116#[derive(Default)]
118pub struct AllocLocalLibfuncWrapped {}
119impl SignatureAndTypeGenericLibfunc for AllocLocalLibfuncWrapped {
120 const STR_ID: &'static str = "alloc_local";
121
122 fn specialize_signature(
123 &self,
124 context: &dyn SignatureSpecializationContext,
125 ty: ConcreteTypeId,
126 ) -> Result<LibfuncSignature, SpecializationError> {
127 let type_info = context.as_type_specialization_context().get_type_info(ty.clone())?;
128 Ok(LibfuncSignature::new_non_branch(
129 vec![],
130 vec![OutputVarInfo {
131 ty: context.get_wrapped_concrete_type(UninitializedType::id(), ty)?,
132 ref_info: if type_info.zero_sized {
133 OutputVarReferenceInfo::ZeroSized
134 } else {
135 OutputVarReferenceInfo::NewLocalVar
136 },
137 }],
138 SierraApChange::Known { new_vars_only: true },
139 ))
140 }
141}
142pub type AllocLocalLibfunc = WrapSignatureAndTypeGenericLibfunc<AllocLocalLibfuncWrapped>;
143
144#[derive(Default)]
146pub struct RenameLibfunc {}
147impl SignatureOnlyGenericLibfunc for RenameLibfunc {
148 const STR_ID: &'static str = "rename";
149
150 fn specialize_signature(
151 &self,
152 _context: &dyn SignatureSpecializationContext,
153 args: &[GenericArg],
154 ) -> Result<LibfuncSignature, SpecializationError> {
155 let ty = args_as_single_type(args)?;
156 Ok(reinterpret_cast_signature(ty.clone(), ty))
157 }
158}