1use super::*;
2use crate::type_tracking::{FrameDescriptor, StorageHint};
3
4#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub struct FunctionHash(pub [u8; 32]);
6
7impl std::fmt::Debug for FunctionHash {
8 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9 write!(f, "FunctionHash({})", self)
10 }
11}
12
13impl std::fmt::Display for FunctionHash {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 for byte in &self.0 {
16 write!(f, "{:02x}", byte)?;
17 }
18 Ok(())
19 }
20}
21
22impl FunctionHash {
23 pub const ZERO: Self = Self([0u8; 32]);
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct FunctionBlob {
34 pub content_hash: FunctionHash,
36
37 pub name: String,
39 pub arity: u16,
40 pub param_names: Vec<String>,
41 pub locals_count: u16,
42 pub is_closure: bool,
43 pub captures_count: u16,
44 pub is_async: bool,
45 #[serde(default)]
46 pub ref_params: Vec<bool>,
47 #[serde(default)]
48 pub ref_mutates: Vec<bool>,
49 #[serde(default)]
50 pub mutable_captures: Vec<bool>,
51
52 pub instructions: Vec<Instruction>,
55 pub constants: Vec<Constant>,
57 pub strings: Vec<String>,
59
60 #[serde(default = "default_permission_set")]
63 pub required_permissions: PermissionSet,
64
65 pub dependencies: Vec<FunctionHash>,
69
70 #[serde(skip, default)]
73 pub callee_names: Vec<String>,
74
75 pub type_schemas: Vec<String>,
78
79 #[serde(default)]
83 pub foreign_dependencies: Vec<[u8; 32]>,
84
85 pub source_map: Vec<(usize, u32, u32)>,
89}
90
91#[derive(Serialize)]
94struct FunctionBlobHashInput<'a> {
95 name: &'a str,
96 arity: u16,
97 param_names: &'a [String],
98 locals_count: u16,
99 is_closure: bool,
100 captures_count: u16,
101 is_async: bool,
102 ref_params: &'a [bool],
103 ref_mutates: &'a [bool],
104 mutable_captures: &'a [bool],
105 instructions: &'a [Instruction],
106 constants: &'a [Constant],
107 strings: &'a [String],
108 dependencies: &'a [FunctionHash],
109 type_schemas: &'a [String],
110 required_permission_names: Vec<&'a str>,
112 foreign_dependencies: &'a [[u8; 32]],
114}
115
116impl FunctionBlob {
117 pub fn compute_hash(&self) -> FunctionHash {
120 let perm_names: Vec<&str> = self.required_permissions.iter().map(|p| p.name()).collect();
122 let input = FunctionBlobHashInput {
123 name: &self.name,
124 arity: self.arity,
125 param_names: &self.param_names,
126 locals_count: self.locals_count,
127 is_closure: self.is_closure,
128 captures_count: self.captures_count,
129 is_async: self.is_async,
130 ref_params: &self.ref_params,
131 ref_mutates: &self.ref_mutates,
132 mutable_captures: &self.mutable_captures,
133 instructions: &self.instructions,
134 constants: &self.constants,
135 strings: &self.strings,
136 dependencies: &self.dependencies,
137 type_schemas: &self.type_schemas,
138 required_permission_names: perm_names,
139 foreign_dependencies: &self.foreign_dependencies,
140 };
141 let bytes = rmp_serde::encode::to_vec(&input)
145 .expect("FunctionBlob content serialization should not fail");
146 let digest = Sha256::digest(&bytes);
147 let mut hash = [0u8; 32];
148 hash.copy_from_slice(&digest);
149 FunctionHash(hash)
150 }
151
152 pub fn finalize(&mut self) {
154 self.content_hash = self.compute_hash();
155 }
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct Program {
164 pub entry: FunctionHash,
166
167 pub function_store: HashMap<FunctionHash, FunctionBlob>,
169
170 pub top_level_locals_count: u16,
172
173 #[serde(default)]
175 pub top_level_local_storage_hints: Vec<StorageHint>,
176
177 pub module_binding_names: Vec<String>,
179
180 #[serde(default)]
182 pub module_binding_storage_hints: Vec<StorageHint>,
183
184 #[serde(default)]
186 pub function_local_storage_hints: Vec<Vec<StorageHint>>,
187
188 #[serde(default)]
190 pub top_level_frame: Option<FrameDescriptor>,
191
192 pub data_schema: Option<DataFrameSchema>,
194
195 #[serde(default)]
197 pub type_schema_registry: shape_runtime::type_schema::TypeSchemaRegistry,
198
199 pub trait_method_symbols: HashMap<String, String>,
201
202 #[serde(default)]
204 pub foreign_functions: Vec<ForeignFunctionEntry>,
205
206 #[serde(default)]
208 pub native_struct_layouts: Vec<NativeStructLayoutEntry>,
209
210 pub debug_info: DebugInfo,
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct LinkedFunction {
220 pub blob_hash: FunctionHash,
222
223 pub entry_point: usize,
225 pub body_length: usize,
227
228 pub name: String,
230 pub arity: u16,
231 pub param_names: Vec<String>,
232 pub locals_count: u16,
233 pub is_closure: bool,
234 pub captures_count: u16,
235 pub is_async: bool,
236 #[serde(default)]
237 pub ref_params: Vec<bool>,
238 #[serde(default)]
239 pub ref_mutates: Vec<bool>,
240 #[serde(default)]
241 pub mutable_captures: Vec<bool>,
242 #[serde(default)]
244 pub frame_descriptor: Option<FrameDescriptor>,
245}
246
247#[derive(Debug, Clone, Default, Serialize, Deserialize)]
252pub struct LinkedProgram {
253 #[serde(default)]
255 pub entry: FunctionHash,
256
257 pub instructions: Vec<Instruction>,
259
260 pub constants: Vec<Constant>,
262
263 pub strings: Vec<String>,
265
266 pub functions: Vec<LinkedFunction>,
268
269 pub hash_to_id: HashMap<FunctionHash, usize>,
271
272 pub debug_info: DebugInfo,
274
275 pub data_schema: Option<DataFrameSchema>,
277
278 pub module_binding_names: Vec<String>,
280
281 pub top_level_locals_count: u16,
283
284 #[serde(default)]
286 pub top_level_local_storage_hints: Vec<StorageHint>,
287
288 #[serde(default)]
290 pub type_schema_registry: shape_runtime::type_schema::TypeSchemaRegistry,
291
292 #[serde(default)]
294 pub module_binding_storage_hints: Vec<StorageHint>,
295
296 #[serde(default)]
298 pub function_local_storage_hints: Vec<Vec<StorageHint>>,
299
300 #[serde(default)]
302 pub top_level_frame: Option<FrameDescriptor>,
303
304 pub trait_method_symbols: HashMap<String, String>,
306
307 #[serde(default)]
309 pub foreign_functions: Vec<ForeignFunctionEntry>,
310
311 #[serde(default)]
313 pub native_struct_layouts: Vec<NativeStructLayoutEntry>,
314
315 #[serde(default = "default_permission_set")]
318 pub total_required_permissions: PermissionSet,
319}