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 #[serde(default)]
53 pub frame_descriptor: Option<FrameDescriptor>,
54
55 pub instructions: Vec<Instruction>,
58 pub constants: Vec<Constant>,
60 pub strings: Vec<String>,
62
63 #[serde(default = "default_permission_set")]
66 pub required_permissions: PermissionSet,
67
68 pub dependencies: Vec<FunctionHash>,
72
73 #[serde(skip, default)]
76 pub callee_names: Vec<String>,
77
78 pub type_schemas: Vec<String>,
81
82 #[serde(default)]
86 pub foreign_dependencies: Vec<[u8; 32]>,
87
88 pub source_map: Vec<(usize, u32, u32)>,
92}
93
94#[derive(Serialize)]
97struct FunctionBlobHashInput<'a> {
98 name: &'a str,
99 arity: u16,
100 param_names: &'a [String],
101 locals_count: u16,
102 is_closure: bool,
103 captures_count: u16,
104 is_async: bool,
105 ref_params: &'a [bool],
106 ref_mutates: &'a [bool],
107 mutable_captures: &'a [bool],
108 instructions: &'a [Instruction],
109 constants: &'a [Constant],
110 strings: &'a [String],
111 dependencies: &'a [FunctionHash],
112 type_schemas: &'a [String],
113 required_permission_names: Vec<&'a str>,
115 foreign_dependencies: &'a [[u8; 32]],
117}
118
119impl FunctionBlob {
120 pub fn compute_hash(&self) -> FunctionHash {
123 let perm_names: Vec<&str> = self.required_permissions.iter().map(|p| p.name()).collect();
125 let input = FunctionBlobHashInput {
126 name: &self.name,
127 arity: self.arity,
128 param_names: &self.param_names,
129 locals_count: self.locals_count,
130 is_closure: self.is_closure,
131 captures_count: self.captures_count,
132 is_async: self.is_async,
133 ref_params: &self.ref_params,
134 ref_mutates: &self.ref_mutates,
135 mutable_captures: &self.mutable_captures,
136 instructions: &self.instructions,
137 constants: &self.constants,
138 strings: &self.strings,
139 dependencies: &self.dependencies,
140 type_schemas: &self.type_schemas,
141 required_permission_names: perm_names,
142 foreign_dependencies: &self.foreign_dependencies,
143 };
144 let bytes = rmp_serde::encode::to_vec(&input)
148 .expect("FunctionBlob content serialization should not fail");
149 let digest = Sha256::digest(&bytes);
150 let mut hash = [0u8; 32];
151 hash.copy_from_slice(&digest);
152 FunctionHash(hash)
153 }
154
155 pub fn finalize(&mut self) {
157 self.content_hash = self.compute_hash();
158 }
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct Program {
167 pub entry: FunctionHash,
169
170 pub function_store: HashMap<FunctionHash, FunctionBlob>,
172
173 pub top_level_locals_count: u16,
175
176 #[serde(default)]
178 pub top_level_local_storage_hints: Vec<StorageHint>,
179
180 pub module_binding_names: Vec<String>,
182
183 #[serde(default)]
185 pub module_binding_storage_hints: Vec<StorageHint>,
186
187 #[serde(default)]
189 pub function_local_storage_hints: Vec<Vec<StorageHint>>,
190
191 #[serde(default)]
193 pub top_level_frame: Option<FrameDescriptor>,
194
195 pub data_schema: Option<DataFrameSchema>,
197
198 #[serde(default)]
200 pub type_schema_registry: shape_runtime::type_schema::TypeSchemaRegistry,
201
202 pub trait_method_symbols: HashMap<String, String>,
204
205 #[serde(default)]
207 pub foreign_functions: Vec<ForeignFunctionEntry>,
208
209 #[serde(default)]
211 pub native_struct_layouts: Vec<NativeStructLayoutEntry>,
212
213 pub debug_info: DebugInfo,
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct LinkedFunction {
223 pub blob_hash: FunctionHash,
225
226 pub entry_point: usize,
228 pub body_length: usize,
230
231 pub name: String,
233 pub arity: u16,
234 pub param_names: Vec<String>,
235 pub locals_count: u16,
236 pub is_closure: bool,
237 pub captures_count: u16,
238 pub is_async: bool,
239 #[serde(default)]
240 pub ref_params: Vec<bool>,
241 #[serde(default)]
242 pub ref_mutates: Vec<bool>,
243 #[serde(default)]
244 pub mutable_captures: Vec<bool>,
245 #[serde(default)]
247 pub frame_descriptor: Option<FrameDescriptor>,
248}
249
250#[derive(Debug, Clone, Default, Serialize, Deserialize)]
255pub struct LinkedProgram {
256 #[serde(default)]
258 pub entry: FunctionHash,
259
260 pub instructions: Vec<Instruction>,
262
263 pub constants: Vec<Constant>,
265
266 pub strings: Vec<String>,
268
269 pub functions: Vec<LinkedFunction>,
271
272 pub hash_to_id: HashMap<FunctionHash, usize>,
274
275 pub debug_info: DebugInfo,
277
278 pub data_schema: Option<DataFrameSchema>,
280
281 pub module_binding_names: Vec<String>,
283
284 pub top_level_locals_count: u16,
286
287 #[serde(default)]
289 pub top_level_local_storage_hints: Vec<StorageHint>,
290
291 #[serde(default)]
293 pub type_schema_registry: shape_runtime::type_schema::TypeSchemaRegistry,
294
295 #[serde(default)]
297 pub module_binding_storage_hints: Vec<StorageHint>,
298
299 #[serde(default)]
301 pub function_local_storage_hints: Vec<Vec<StorageHint>>,
302
303 #[serde(default)]
305 pub top_level_frame: Option<FrameDescriptor>,
306
307 pub trait_method_symbols: HashMap<String, String>,
309
310 #[serde(default)]
312 pub foreign_functions: Vec<ForeignFunctionEntry>,
313
314 #[serde(default)]
316 pub native_struct_layouts: Vec<NativeStructLayoutEntry>,
317
318 #[serde(default = "default_permission_set")]
321 pub total_required_permissions: PermissionSet,
322}