cairo_lang_sierra/extensions/modules/
boxing.rs1use super::snapshot::snapshot_ty;
2use super::utils::reinterpret_cast_signature;
3use crate::define_libfunc_hierarchy;
4use crate::extensions::lib_func::{
5 DeferredOutputKind, LibfuncSignature, OutputVarInfo, SierraApChange,
6 SignatureAndTypeGenericLibfunc, SignatureSpecializationContext,
7 WrapSignatureAndTypeGenericLibfunc,
8};
9use crate::extensions::type_specialization_context::TypeSpecializationContext;
10use crate::extensions::types::{
11 GenericTypeArgGenericType, GenericTypeArgGenericTypeWrapper, TypeInfo,
12};
13use crate::extensions::{NamedType, OutputVarReferenceInfo, SpecializationError};
14use crate::ids::{ConcreteTypeId, GenericTypeId};
15
16#[derive(Default)]
18pub struct BoxTypeWrapped {}
19impl GenericTypeArgGenericType for BoxTypeWrapped {
20 const ID: GenericTypeId = GenericTypeId::new_inline("Box");
21
22 fn calc_info(
23 &self,
24 _context: &dyn TypeSpecializationContext,
25 long_id: crate::program::ConcreteTypeLongId,
26 TypeInfo { storable, droppable, duplicatable, .. }: TypeInfo,
27 ) -> Result<TypeInfo, SpecializationError> {
28 if storable {
29 Ok(TypeInfo { long_id, zero_sized: false, storable, droppable, duplicatable })
30 } else {
31 Err(SpecializationError::UnsupportedGenericArg)
32 }
33 }
34}
35pub type BoxType = GenericTypeArgGenericTypeWrapper<BoxTypeWrapped>;
36
37define_libfunc_hierarchy! {
38 pub enum BoxLibfunc {
39 Into(IntoBoxLibfunc),
40 Unbox(UnboxLibfunc),
41 ForwardSnapshot(BoxForwardSnapshotLibfunc),
42 }, BoxConcreteLibfunc
43}
44
45pub fn box_ty(
47 context: &dyn SignatureSpecializationContext,
48 ty: ConcreteTypeId,
49) -> Result<ConcreteTypeId, SpecializationError> {
50 context.get_wrapped_concrete_type(BoxType::id(), ty)
51}
52
53#[derive(Default)]
55pub struct IntoBoxLibfuncWrapped {}
56impl SignatureAndTypeGenericLibfunc for IntoBoxLibfuncWrapped {
57 const STR_ID: &'static str = "into_box";
58
59 fn specialize_signature(
60 &self,
61 context: &dyn SignatureSpecializationContext,
62 ty: ConcreteTypeId,
63 ) -> Result<LibfuncSignature, SpecializationError> {
64 Ok(LibfuncSignature::new_non_branch(
65 vec![ty.clone()],
66 vec![OutputVarInfo {
67 ty: box_ty(context, ty)?,
68 ref_info: OutputVarReferenceInfo::NewTempVar { idx: 0 },
69 }],
70 SierraApChange::Known { new_vars_only: true },
71 ))
72 }
73}
74pub type IntoBoxLibfunc = WrapSignatureAndTypeGenericLibfunc<IntoBoxLibfuncWrapped>;
75
76#[derive(Default)]
78pub struct UnboxLibfuncWrapped {}
79impl SignatureAndTypeGenericLibfunc for UnboxLibfuncWrapped {
80 const STR_ID: &'static str = "unbox";
81
82 fn specialize_signature(
83 &self,
84 context: &dyn SignatureSpecializationContext,
85 ty: ConcreteTypeId,
86 ) -> Result<LibfuncSignature, SpecializationError> {
87 Ok(LibfuncSignature::new_non_branch(
88 vec![box_ty(context, ty.clone())?],
89 vec![OutputVarInfo {
90 ty: ty.clone(),
91 ref_info: if context.get_type_info(ty)?.zero_sized {
92 OutputVarReferenceInfo::ZeroSized
93 } else {
94 OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic)
95 },
96 }],
97 SierraApChange::Known { new_vars_only: true },
98 ))
99 }
100}
101pub type UnboxLibfunc = WrapSignatureAndTypeGenericLibfunc<UnboxLibfuncWrapped>;
102
103#[derive(Default)]
105pub struct BoxForwardSnapshotLibfuncWrapped {}
106impl SignatureAndTypeGenericLibfunc for BoxForwardSnapshotLibfuncWrapped {
107 const STR_ID: &'static str = "box_forward_snapshot";
108 fn specialize_signature(
109 &self,
110 context: &dyn SignatureSpecializationContext,
111 ty: ConcreteTypeId,
112 ) -> Result<LibfuncSignature, SpecializationError> {
113 Ok(reinterpret_cast_signature(
114 snapshot_ty(context, box_ty(context, ty.clone())?)?,
115 box_ty(context, snapshot_ty(context, ty)?)?,
116 ))
117 }
118}
119
120pub type BoxForwardSnapshotLibfunc =
121 WrapSignatureAndTypeGenericLibfunc<BoxForwardSnapshotLibfuncWrapped>;