1use crate::*;
2use super::*;
3
4#[repr(C)]
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21#[derive(Debug, Clone, Eq, PartialEq)]
22pub struct ByteCodeHeader {
23 pub magic: [u8; 4], pub version: u8, pub mech_ver: u16, pub flags: u16, pub reg_count: u32, pub instr_count: u32, pub feature_count: u32, pub feature_off: u64, pub types_count: u32, pub types_off: u64, pub const_count: u32, pub const_tbl_off: u64, pub const_tbl_len: u64, pub const_blob_off: u64, pub const_blob_len: u64, pub symbols_len: u64, pub symbols_off: u64, pub instr_off: u64, pub instr_len: u64, pub dict_off: u64, pub dict_len: u64, pub reserved: u32, }
53
54impl ByteCodeHeader {
55 pub const HEADER_SIZE: usize = 4 + 1 + 2 + 2 + 4 + 4 + 4 + 8 + 4 + 8 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 4; pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
82 w.write_all(&self.magic)?;
84
85 w.write_u8(self.version)?;
87 w.write_u16::<LittleEndian>(self.mech_ver)?;
88 w.write_u16::<LittleEndian>(self.flags)?;
89
90 w.write_u32::<LittleEndian>(self.reg_count)?;
92 w.write_u32::<LittleEndian>(self.instr_count)?;
93
94 w.write_u32::<LittleEndian>(self.feature_count)?;
96 w.write_u64::<LittleEndian>(self.feature_off)?;
97
98 w.write_u32::<LittleEndian>(self.types_count)?;
100 w.write_u64::<LittleEndian>(self.types_off)?;
101
102 w.write_u32::<LittleEndian>(self.const_count)?;
104 w.write_u64::<LittleEndian>(self.const_tbl_off)?;
105 w.write_u64::<LittleEndian>(self.const_tbl_len)?;
106 w.write_u64::<LittleEndian>(self.const_blob_off)?;
107 w.write_u64::<LittleEndian>(self.const_blob_len)?;
108
109 w.write_u64::<LittleEndian>(self.symbols_len)?;
111 w.write_u64::<LittleEndian>(self.symbols_off)?;
112
113 w.write_u64::<LittleEndian>(self.instr_off)?;
115 w.write_u64::<LittleEndian>(self.instr_len)?;
116
117 w.write_u64::<LittleEndian>(self.dict_off)?;
119 w.write_u64::<LittleEndian>(self.dict_len)?;
120
121 w.write_u32::<LittleEndian>(self.reserved)?;
123 Ok(())
124 }
125
126 pub fn read_from(r: &mut impl Read) -> MResult<Self> {
128 let mut magic = [0u8; 4];
129 r.read_exact(&mut magic)?;
130
131 let version = r.read_u8()?;
132 let mech_ver = r.read_u16::<LittleEndian>()?;
133 let flags = r.read_u16::<LittleEndian>()?;
134
135 let reg_count = r.read_u32::<LittleEndian>()?;
136 let instr_count = r.read_u32::<LittleEndian>()?;
137
138 let feature_count = r.read_u32::<LittleEndian>()?;
139 let feature_off = r.read_u64::<LittleEndian>()?;
140
141 let types_count = r.read_u32::<LittleEndian>()?;
142 let types_off = r.read_u64::<LittleEndian>()?;
143
144 let const_count = r.read_u32::<LittleEndian>()?;
145 let const_tbl_off = r.read_u64::<LittleEndian>()?;
146 let const_tbl_len = r.read_u64::<LittleEndian>()?;
147 let const_blob_off = r.read_u64::<LittleEndian>()?;
148 let const_blob_len = r.read_u64::<LittleEndian>()?;
149
150 let symbols_len = r.read_u64::<LittleEndian>()?;
151 let symbols_off = r.read_u64::<LittleEndian>()?;
152
153 let instr_off = r.read_u64::<LittleEndian>()?;
154 let instr_len = r.read_u64::<LittleEndian>()?;
155
156 let dict_off = r.read_u64::<LittleEndian>()?;
157 let dict_len = r.read_u64::<LittleEndian>()?;
158
159 let reserved = r.read_u32::<LittleEndian>()?;
160
161 Ok(Self {
162 magic,
163 version,
164 mech_ver,
165 flags,
166 reg_count,
167 instr_count,
168 feature_count,
169 feature_off,
170 types_count,
171 types_off,
172 const_count,
173 const_tbl_off,
174 const_tbl_len,
175 const_blob_off,
176 const_blob_len,
177 instr_off,
178 instr_len,
179 symbols_len,
180 symbols_off,
181 dict_off,
182 dict_len,
183 reserved,
184 })
185 }
186
187 pub fn validate_magic(&self, expected: &[u8;4]) -> bool {
189 &self.magic == expected
190 }
191}
192
193#[repr(u16)]
197#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
198pub enum FeatureKind {
199 I8=1, I16, I32, I64, I128,
200 U8, U16, U32, U64, U128,
201
202 F32, F64, C64, R64, Index,
203 String, Bool, Atom, Set, Map,
204
205 Table, Tuple, Record, Enum,
206 VariableDefine, VariableAssign, KindDefine,
207 KindAnnotation, SubscriptRange, SubscriptFormula,
208
209 RangeInclusive, RangeExclusive,
210 DotIndexing, Swizzle, LogicalIndexing,
211 Matrix1, Matrix2, Matrix3, Matrix4, Matrix2x3,
212
213 Matrix3x2, RowVector2, RowVector3, RowVector4,
214 Vector2, Vector3, Vector4, VectorD, MatrixD, RowVectorD,
215
216 HorzCat, VertCat,
217 Compiler, PrettyPrint, Serde,
218 MatMul, Transpose, Dot, Cross, Solve,
219
220 Add, Sub, Mul, Div, Pow, Mod,
221 Neg, OpAssign, LT, LTE, GT,
222
223 GTE, EQ, NEQ, And, Or,
224 Xor, Not, Convert, Assign, Access,
225 Min, Max,
226
227 Union, Intersection, Difference, Complement, Subset,
228 Superset, ProperSubset, ProperSuperset, ElementOf, NotElementOf,
229 SetComprehensions,
230
231 Concat,
232
233 Functions, Formulas,
234 Custom = 0xFFFF,
235}
236
237impl FeatureKind {
238
239 pub fn as_string(&self) -> String {
240 match self {
241 FeatureKind::I8 => "i8".to_string(),
242 FeatureKind::I16 => "i16".to_string(),
243 FeatureKind::I32 => "i32".to_string(),
244 FeatureKind::I64 => "i64".to_string(),
245 FeatureKind::I128 => "i128".to_string(),
246 FeatureKind::U8 => "u8".to_string(),
247 FeatureKind::U16 => "u16".to_string(),
248 FeatureKind::U32 => "u32".to_string(),
249 FeatureKind::U64 => "u64".to_string(),
250 FeatureKind::U128 => "u128".to_string(),
251 FeatureKind::F32 => "f32".to_string(),
252 FeatureKind::F64 => "f64".to_string(),
253 FeatureKind::C64 => "c64".to_string(),
254 FeatureKind::R64 => "r64".to_string(),
255 FeatureKind::Index => "index".to_string(),
256 FeatureKind::String => "string".to_string(),
257 FeatureKind::Bool => "bool".to_string(),
258 FeatureKind::Atom => "atom".to_string(),
259 FeatureKind::Set => "set".to_string(),
260 FeatureKind::Map => "map".to_string(),
261 FeatureKind::Table => "table".to_string(),
262 FeatureKind::Tuple => "tuple".to_string(),
263 FeatureKind::Record => "record".to_string(),
264 FeatureKind::Enum => "enum".to_string(),
265 FeatureKind::VariableDefine => "variable_define".to_string(),
266 FeatureKind::VariableAssign => "variable_assign".to_string(),
267 FeatureKind::KindDefine => "kind_define".to_string(),
268 FeatureKind::KindAnnotation => "kind_annotation".to_string(),
269 FeatureKind::SubscriptRange => "subscript_range".to_string(),
270 FeatureKind::SubscriptFormula => "subscript_formula".to_string(),
271 FeatureKind::RangeInclusive => "range_inclusive".to_string(),
272 FeatureKind::RangeExclusive => "range_exclusive".to_string(),
273 FeatureKind::DotIndexing => "dot_indexing".to_string(),
274 FeatureKind::Swizzle => "swizzle".to_string(),
275 FeatureKind::LogicalIndexing => "logical_indexing".to_string(),
276 FeatureKind::Matrix1 => "matrix1".to_string(),
277 FeatureKind::Matrix2 => "matrix2".to_string(),
278 FeatureKind::Matrix3 => "matrix3".to_string(),
279 FeatureKind::Matrix4 => "matrix4".to_string(),
280 FeatureKind::Matrix2x3 => "matrix2x3".to_string(),
281 FeatureKind::Matrix3x2 => "matrix3x2".to_string(),
282 FeatureKind::RowVector2 => "row_vector2".to_string(),
283 FeatureKind::RowVector3 => "row_vector3".to_string(),
284 FeatureKind::RowVector4 => "row_vector4".to_string(),
285 FeatureKind::Vector2 => "vector2".to_string(),
286 FeatureKind::Vector3 => "vector3".to_string(),
287 FeatureKind::Vector4 => "vector4".to_string(),
288 FeatureKind::VectorD => "vectord".to_string(),
289 FeatureKind::MatrixD => "matrixd".to_string(),
290 FeatureKind::RowVectorD => "row_vectord".to_string(),
291 FeatureKind::HorzCat => "matrix_horzcat".to_string(),
292 FeatureKind::VertCat => "matrix_vertcat".to_string(),
293 FeatureKind::Compiler => "compiler".to_string(),
294 FeatureKind::PrettyPrint => "pretty_print".to_string(),
295 FeatureKind::Serde => "serde".to_string(),
296 FeatureKind::MatMul => "matrix_matmul".to_string(),
297 FeatureKind::Transpose => "matrix_transpose".to_string(),
298 FeatureKind::Dot => "matrix_dot".to_string(),
299 FeatureKind::Solve => "matrix_solve".to_string(),
300 FeatureKind::Cross => "matrix_cross".to_string(),
301 FeatureKind::Add => "math_add".to_string(),
302 FeatureKind::Sub => "math_sub".to_string(),
303 FeatureKind::Mul => "math_mul".to_string(),
304 FeatureKind::Div => "math_div".to_string(),
305 FeatureKind::Pow => "math_pow".to_string(),
306 FeatureKind::Mod => "math_mod".to_string(),
307 FeatureKind::Neg => "math_neg".to_string(),
308 FeatureKind::OpAssign => "math_opassign".to_string(),
309 FeatureKind::LT => "compare_lt".to_string(),
310 FeatureKind::LTE => "compare_lte".to_string(),
311 FeatureKind::GT => "compare_gt".to_string(),
312 FeatureKind::GTE => "compare_gte".to_string(),
313 FeatureKind::EQ => "compare_eq".to_string(),
314 FeatureKind::NEQ => "compare_neq".to_string(),
315 FeatureKind::Min => "compare_min".to_string(),
316 FeatureKind::Max => "compare_max".to_string(),
317 FeatureKind::And => "logic_and".to_string(),
318 FeatureKind::Or => "logic_or".to_string(),
319 FeatureKind::Xor => "logic_xor".to_string(),
320 FeatureKind::Not => "logic_not".to_string(),
321 FeatureKind::Convert => "convert".to_string(),
322 FeatureKind::Assign => "assign".to_string(),
323 FeatureKind::Access => "access".to_string(),
324 FeatureKind::Union => "set_union".to_string(),
325 FeatureKind::Intersection => "set_intersection".to_string(),
326 FeatureKind::Difference => "set_difference".to_string(),
327 FeatureKind::Complement => "set_complement".to_string(),
328 FeatureKind::Subset => "set_subset".to_string(),
329 FeatureKind::Superset => "set_superset".to_string(),
330 FeatureKind::ProperSubset => "set_proper_subset".to_string(),
331 FeatureKind::ProperSuperset => "set_proper_superset".to_string(),
332 FeatureKind::ElementOf => "set_element_of".to_string(),
333 FeatureKind::NotElementOf => "set_not_element_of".to_string(),
334 FeatureKind::SetComprehensions => "set_comprehensions".to_string(),
335 FeatureKind::Functions => "functions".to_string(),
336 FeatureKind::Formulas => "formulas".to_string(),
337 FeatureKind::Concat => "string_concat".to_string(),
338 FeatureKind::Custom => "custom".to_string(),
339 }
340 }
341}
342
343#[derive(Debug, Clone, PartialEq, Eq, Hash)]
344pub enum FeatureFlag {
345 Builtin(FeatureKind),
346 Custom(u64),
347}
348
349impl FeatureFlag {
350
351 pub fn as_string(&self) -> String {
352 match self {
353 FeatureFlag::Builtin(f) => f.as_string(),
354 FeatureFlag::Custom(c) => format!("custom({})", c),
355 }
356 }
357}
358
359impl FeatureFlag {
360 pub fn as_u64(&self) -> u64 {
361 match self {
362 FeatureFlag::Builtin(f) => *f as u64,
363 FeatureFlag::Custom(c) => *c,
364 }
365 }
366}
367
368#[repr(u16)]
372#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
373#[derive(Debug, Clone, Copy, Eq, PartialEq)]
374pub enum TypeTag {
375 U8=1, U16, U32, U64, U128, I8, I16, I32, I64, I128,
376 F32, F64, C64, R64, String, Bool, Id, Index, Empty, Any,
377 MatrixU8, MatrixU16, MatrixU32, MatrixU64, MatrixU128,
378 MatrixI8, MatrixI16, MatrixI32, MatrixI64, MatrixI128,
379 MatrixF32, MatrixF64, MatrixC64, MatrixR64, MatrixBool,
380 MatrixString, MatrixIndex,
381 EnumTag, Record, Map, Atom,
382 Table, Tuple, Reference, Set, OptionT, Kind, None,
383}
384
385impl TypeTag {
386 pub fn from_u16(tag: u16) -> Option<Self> {
387 match tag {
388 1 => Some(TypeTag::U8), 2 => Some(TypeTag::U16), 3 => Some(TypeTag::U32), 4 => Some(TypeTag::U64), 5 => Some(TypeTag::U128),
389 6 => Some(TypeTag::I8), 7 => Some(TypeTag::I16), 8 => Some(TypeTag::I32), 9 => Some(TypeTag::I64), 10 => Some(TypeTag::I128),
390 11 => Some(TypeTag::F32), 12 => Some(TypeTag::F64), 13 => Some(TypeTag::C64), 14 => Some(TypeTag::R64),
391 15 => Some(TypeTag::String), 16 => Some(TypeTag::Bool), 17 => Some(TypeTag::Id), 18 => Some(TypeTag::Index), 19 => Some(TypeTag::Empty), 20 => Some(TypeTag::Any),
392 21 => Some(TypeTag::MatrixU8), 22 => Some(TypeTag::MatrixU16), 23 => Some(TypeTag::MatrixU32), 24 => Some(TypeTag::MatrixU64), 25 => Some(TypeTag::MatrixU128),
393 26 => Some(TypeTag::MatrixI8), 27 => Some(TypeTag::MatrixI16), 28 => Some(TypeTag::MatrixI32), 29 => Some(TypeTag::MatrixI64), 30 => Some(TypeTag::MatrixI128),
394 31 => Some(TypeTag::MatrixF32), 32 => Some(TypeTag::MatrixF64), 33 => Some(TypeTag::MatrixC64), 34 => Some(TypeTag::MatrixR64), 35 => Some(TypeTag::MatrixBool),
395 36 => Some(TypeTag::MatrixString), 37 => Some(TypeTag::MatrixIndex),
396 38 => Some(TypeTag::EnumTag), 39 => Some(TypeTag::Record), 40 => Some(TypeTag::Map), 41 => Some(TypeTag::Atom),
397 42 => Some(TypeTag::Table), 43 => Some(TypeTag::Tuple), 44 => Some(TypeTag::Reference), 45 => Some(TypeTag::Set), 46 => Some(TypeTag::OptionT), 47 => Some(TypeTag::Kind), 48 => Some(TypeTag::None),
398 _ => None,
399 }
400 }
401}
402
403#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
404#[derive(Debug, Clone, Eq, PartialEq)]
405pub struct TypeEntry {
406 pub tag: TypeTag,
407 pub bytes: Vec<u8>,
408}
409impl TypeEntry {
410 pub fn byte_len(&self) -> u64 {
411 2 + self.bytes.len() as u64
412 }
413}
414
415pub type TypeId = u32;
416
417#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
418#[derive(Default, Debug, Clone, Eq, PartialEq)]
419pub struct TypeSection {
420 pub interner: HashMap<ValueKind, TypeId>,
421 pub entries: Vec<TypeEntry>, }
423
424impl TypeSection {
425
426 pub fn new() -> Self {
427 Self { interner: HashMap::new(), entries: Vec::new() }
428 }
429
430 pub fn get_or_intern(&mut self, vk: &ValueKind) -> TypeId {
431 if let Some(id) = self.interner.get(vk) { return *id; }
432 let (tag, mut bytes) = encode_value_kind(self, vk);
434 let id = self.entries.len() as u32;
435 self.entries.push(TypeEntry { tag, bytes });
436 self.interner.insert(vk.clone(), id);
437 id
438 }
439
440 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
441 w.write_u32::<LittleEndian>(self.entries.len() as u32)?;
442 for e in &self.entries {
443 w.write_u16::<LittleEndian>(e.tag as u16)?;
444 w.write_u16::<LittleEndian>(0)?;
445 w.write_u32::<LittleEndian>(1)?;
446 w.write_u32::<LittleEndian>(e.bytes.len() as u32)?;
447 w.write_all(&e.bytes)?;
448 }
449 Ok(())
450 }
451
452 pub fn byte_len(&self) -> u64 {
453 4 + self.entries.iter().map(|e| 12 + e.bytes.len() as u64).sum::<u64>()
454 }
455}
456
457#[repr(u8)]
461#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
462#[derive(Debug, Clone, Copy, Eq, PartialEq)]
463pub enum ConstEncoding {
464 Inline = 1
465}
466
467#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
468#[derive(Debug, Clone, Eq, PartialEq)]
469pub struct ConstEntry {
470 pub type_id: u32,
471 pub enc: ConstEncoding,
472 pub align: u8,
473 pub flags: u8,
474 pub reserved:u16,
475 pub offset: u64,
476 pub length: u64,
477}
478
479impl ConstEntry {
480 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
481 w.write_u32::<LittleEndian>(self.type_id)?;
482 w.write_u8(self.enc as u8)?;
483 w.write_u8(self.align)?;
484 w.write_u8(self.flags)?;
485 w.write_u8(0)?; w.write_u64::<LittleEndian>(self.offset)?;
487 w.write_u64::<LittleEndian>(self.length)?;
488 Ok(())
489 }
490 pub fn byte_len() -> u64 { 4 + 1 + 1 + 1 + 1 + 8 + 8 } }
492
493pub struct SymbolEntry {
497 pub id: u64, pub mutable: bool,
499 pub reg: Register, }
501
502impl SymbolEntry {
503
504 pub fn new(id: u64, mutable: bool, reg: Register) -> Self {
505 Self { id, mutable, reg }
506 }
507
508 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
509 w.write_u64::<LittleEndian>(self.id)?;
510 w.write_u8(if self.mutable { 1 } else { 0 })?;
511 w.write_u32::<LittleEndian>(self.reg)?;
512 Ok(())
513 }
514}
515
516#[repr(u8)]
520#[derive(Debug, Clone, Copy, PartialEq, Eq)]
521pub enum OpCode {
522 ConstLoad = 0x01,
523 NullOp = 0x10,
524 Unop = 0x20,
525 Binop = 0x30,
526 Ternop = 0x40,
527 Quadop = 0x50,
528 VarArg = 0x60,
529 Return = 0xFF,
530}
531
532impl std::fmt::Display for OpCode {
533 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
534 let s = match self {
535 OpCode::ConstLoad => "ConstLoad",
536 OpCode::NullOp => "NullOp",
537 OpCode::Unop => "Unop",
538 OpCode::Binop => "Binop",
539 OpCode::Ternop => "Ternop",
540 OpCode::Quadop => "Quadop",
541 OpCode::VarArg => "VarArg",
542 OpCode::Return => "Return",
543 };
544 write!(f, "{}", s)
545 }
546}
547
548impl OpCode {
549 pub fn from_u8(num: u8) -> Option<OpCode> {
550 match num {
551 0x01 => Some(OpCode::ConstLoad),
552 0x10 => Some(OpCode::NullOp),
553 0x20 => Some(OpCode::Unop),
554 0x30 => Some(OpCode::Binop),
555 0x40 => Some(OpCode::Ternop),
556 0x50 => Some(OpCode::Quadop),
557 0x60 => Some(OpCode::VarArg),
558 0xFF => Some(OpCode::Return),
559 _ => None,
560 }
561 }
562}
563
564#[derive(Debug, Clone)]
565pub enum EncodedInstr {
566 ConstLoad { dst: u32, const_id: u32 }, NullOp { fxn_id: u64, dst: u32 }, UnOp { fxn_id: u64, dst: u32, src: u32 }, BinOp { fxn_id: u64, dst: u32, lhs: u32, rhs: u32 }, TernOp { fxn_id: u64, dst: u32, a: u32, b: u32, c: u32 }, QuadOp { fxn_id: u64, dst: u32, a: u32, b: u32, c: u32, d: u32 }, VarArg { fxn_id: u64, dst: u32, args: Vec<u32> }, Ret { src: u32 }, }
575
576impl EncodedInstr {
577 pub fn byte_len(&self) -> u64 {
578 match self {
579 EncodedInstr::ConstLoad{..} => 1 + 4 + 4,
580 EncodedInstr::NullOp{..} => 1 + 8 + 4,
581 EncodedInstr::UnOp{..} => 1 + 8 + 4 + 4,
582 EncodedInstr::BinOp{..} => 1 + 8 + 4 + 4 + 4,
583 EncodedInstr::TernOp{..} => 1 + 8 + 4 + 4 + 4 + 4,
584 EncodedInstr::QuadOp{..} => 1 + 8 + 4 + 4 + 4 + 4 + 4,
585 EncodedInstr::VarArg{ args, .. } => 1 + 8 + 4 + 4 + (4 * args.len() as u64),
586 EncodedInstr::Ret{..} => 1 + 4,
587 }
588 }
589 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
590 match self {
591 EncodedInstr::ConstLoad{ dst, const_id } => {
592 w.write_u8(OpCode::ConstLoad as u8)?;
593 w.write_u32::<LittleEndian>(*dst)?;
594 w.write_u32::<LittleEndian>(*const_id)?;
595 }
596 EncodedInstr::NullOp{ fxn_id, dst } => {
597 w.write_u8(OpCode::NullOp as u8)?;
598 w.write_u64::<LittleEndian>(*fxn_id)?;
599 w.write_u32::<LittleEndian>(*dst)?;
600 }
601 EncodedInstr::UnOp{ fxn_id, dst, src } => {
602 w.write_u8(OpCode::Unop as u8)?;
603 w.write_u64::<LittleEndian>(*fxn_id)?;
604 w.write_u32::<LittleEndian>(*dst)?;
605 w.write_u32::<LittleEndian>(*src)?;
606 }
607 EncodedInstr::BinOp{ fxn_id, dst, lhs, rhs } => {
608 w.write_u8(OpCode::Binop as u8)?;
609 w.write_u64::<LittleEndian>(*fxn_id)?;
610 w.write_u32::<LittleEndian>(*dst)?;
611 w.write_u32::<LittleEndian>(*lhs)?;
612 w.write_u32::<LittleEndian>(*rhs)?;
613 }
614 EncodedInstr::TernOp{ fxn_id, dst, a, b, c } => {
615 w.write_u8(OpCode::Ternop as u8)?;
616 w.write_u64::<LittleEndian>(*fxn_id)?;
617 w.write_u32::<LittleEndian>(*dst)?;
618 w.write_u32::<LittleEndian>(*a)?;
619 w.write_u32::<LittleEndian>(*b)?;
620 w.write_u32::<LittleEndian>(*c)?;
621 }
622 EncodedInstr::QuadOp{ fxn_id, dst, a, b, c, d } => {
623 w.write_u8(OpCode::Quadop as u8)?;
624 w.write_u64::<LittleEndian>(*fxn_id)?;
625 w.write_u32::<LittleEndian>(*dst)?;
626 w.write_u32::<LittleEndian>(*a)?;
627 w.write_u32::<LittleEndian>(*b)?;
628 w.write_u32::<LittleEndian>(*c)?;
629 w.write_u32::<LittleEndian>(*d)?;
630 }
631 EncodedInstr::VarArg{ fxn_id, dst, args } => {
632 w.write_u8(OpCode::VarArg as u8)?;
633 w.write_u64::<LittleEndian>(*fxn_id)?;
634 w.write_u32::<LittleEndian>(*dst)?;
635 w.write_u32::<LittleEndian>(args.len() as u32)?;
636 for a in args {
637 w.write_u32::<LittleEndian>(*a)?;
638 }
639 }
640 EncodedInstr::Ret{ src } => {
641 w.write_u8(OpCode::Return as u8)?;
642 w.write_u32::<LittleEndian>(*src)?;
643 }
644 }
645 Ok(())
646 }
647}
648
649#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
653#[derive(Debug, Clone, Eq, PartialEq)]
654pub struct DictEntry {
655 pub id: u64, pub name: String, }
658
659impl DictEntry {
660 pub fn new(id: u64, name: &str) -> Self {
661 Self { id, name: name.to_string() }
662 }
663
664 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
665 w.write_u64::<LittleEndian>(self.id)?;
666 let name_bytes = self.name.as_bytes();
667 w.write_u32::<LittleEndian>(name_bytes.len() as u32)?;
668 w.write_all(name_bytes)?;
669 Ok(())
670 }
671}
672
673