cairo_lang_sierra/extensions/modules/
mem.rs

1use 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/// Libfunc for storing a value into temporary memory.
27#[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/// Libfunc for storing a value into local memory.
63#[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/// Libfunc for finalizing the locals for current function.
101#[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/// Libfunc for allocating locals for later stores.
117#[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/// Libfunc for renaming an identifier - used to align identities for flow control merge.
145#[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}