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![
81 ParamSignature::new(uninitialized_type),
82 ParamSignature {
83 ty: ty.clone(),
84 allow_deferred: true,
85 allow_add_const: true,
86 allow_const: true,
87 },
88 ],
89 vec![OutputVarInfo {
90 ty,
91 ref_info: if type_info.zero_sized {
92 OutputVarReferenceInfo::ZeroSized
93 } else {
94 OutputVarReferenceInfo::NewLocalVar
95 },
96 }],
97 SierraApChange::Known { new_vars_only: true },
98 ))
99 }
100}
101pub type StoreLocalLibfunc = WrapSignatureAndTypeGenericLibfunc<StoreLocalLibfuncWrapped>;
102
103#[derive(Default)]
105pub struct FinalizeLocalsLibfunc {}
106impl NoGenericArgsGenericLibfunc for FinalizeLocalsLibfunc {
107 const STR_ID: &'static str = "finalize_locals";
108
109 fn specialize_signature(
110 &self,
111 _context: &dyn SignatureSpecializationContext,
112 ) -> Result<LibfuncSignature, SpecializationError> {
113 Ok(LibfuncSignature::new_non_branch(
114 vec![],
115 vec![],
116 SierraApChange::Known { new_vars_only: false },
117 ))
118 }
119}
120
121#[derive(Default)]
123pub struct AllocLocalLibfuncWrapped {}
124impl SignatureAndTypeGenericLibfunc for AllocLocalLibfuncWrapped {
125 const STR_ID: &'static str = "alloc_local";
126
127 fn specialize_signature(
128 &self,
129 context: &dyn SignatureSpecializationContext,
130 ty: ConcreteTypeId,
131 ) -> Result<LibfuncSignature, SpecializationError> {
132 let type_info = context.as_type_specialization_context().get_type_info(ty.clone())?;
133 Ok(LibfuncSignature::new_non_branch(
134 vec![],
135 vec![OutputVarInfo {
136 ty: context.get_wrapped_concrete_type(UninitializedType::id(), ty)?,
137 ref_info: if type_info.zero_sized {
138 OutputVarReferenceInfo::ZeroSized
139 } else {
140 OutputVarReferenceInfo::NewLocalVar
141 },
142 }],
143 SierraApChange::Known { new_vars_only: true },
144 ))
145 }
146}
147pub type AllocLocalLibfunc = WrapSignatureAndTypeGenericLibfunc<AllocLocalLibfuncWrapped>;
148
149#[derive(Default)]
151pub struct RenameLibfunc {}
152impl SignatureOnlyGenericLibfunc for RenameLibfunc {
153 const STR_ID: &'static str = "rename";
154
155 fn specialize_signature(
156 &self,
157 _context: &dyn SignatureSpecializationContext,
158 args: &[GenericArg],
159 ) -> Result<LibfuncSignature, SpecializationError> {
160 let ty = args_as_single_type(args)?;
161 Ok(reinterpret_cast_signature(ty.clone(), ty))
162 }
163}