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
230 Functions, Formulas,
231 Custom = 0xFFFF,
232}
233
234impl FeatureKind {
235
236 pub fn as_string(&self) -> String {
237 match self {
238 FeatureKind::I8 => "i8".to_string(),
239 FeatureKind::I16 => "i16".to_string(),
240 FeatureKind::I32 => "i32".to_string(),
241 FeatureKind::I64 => "i64".to_string(),
242 FeatureKind::I128 => "i128".to_string(),
243 FeatureKind::U8 => "u8".to_string(),
244 FeatureKind::U16 => "u16".to_string(),
245 FeatureKind::U32 => "u32".to_string(),
246 FeatureKind::U64 => "u64".to_string(),
247 FeatureKind::U128 => "u128".to_string(),
248 FeatureKind::F32 => "f32".to_string(),
249 FeatureKind::F64 => "f64".to_string(),
250 FeatureKind::C64 => "c64".to_string(),
251 FeatureKind::R64 => "r64".to_string(),
252 FeatureKind::Index => "index".to_string(),
253 FeatureKind::String => "string".to_string(),
254 FeatureKind::Bool => "bool".to_string(),
255 FeatureKind::Atom => "atom".to_string(),
256 FeatureKind::Set => "set".to_string(),
257 FeatureKind::Map => "map".to_string(),
258 FeatureKind::Table => "table".to_string(),
259 FeatureKind::Tuple => "tuple".to_string(),
260 FeatureKind::Record => "record".to_string(),
261 FeatureKind::Enum => "enum".to_string(),
262 FeatureKind::VariableDefine => "variable_define".to_string(),
263 FeatureKind::VariableAssign => "variable_assign".to_string(),
264 FeatureKind::KindDefine => "kind_define".to_string(),
265 FeatureKind::KindAnnotation => "kind_annotation".to_string(),
266 FeatureKind::SubscriptRange => "subscript_range".to_string(),
267 FeatureKind::SubscriptFormula => "subscript_formula".to_string(),
268 FeatureKind::RangeInclusive => "range_inclusive".to_string(),
269 FeatureKind::RangeExclusive => "range_exclusive".to_string(),
270 FeatureKind::DotIndexing => "dot_indexing".to_string(),
271 FeatureKind::Swizzle => "swizzle".to_string(),
272 FeatureKind::LogicalIndexing => "logical_indexing".to_string(),
273 FeatureKind::Matrix1 => "matrix1".to_string(),
274 FeatureKind::Matrix2 => "matrix2".to_string(),
275 FeatureKind::Matrix3 => "matrix3".to_string(),
276 FeatureKind::Matrix4 => "matrix4".to_string(),
277 FeatureKind::Matrix2x3 => "matrix2x3".to_string(),
278 FeatureKind::Matrix3x2 => "matrix3x2".to_string(),
279 FeatureKind::RowVector2 => "row_vector2".to_string(),
280 FeatureKind::RowVector3 => "row_vector3".to_string(),
281 FeatureKind::RowVector4 => "row_vector4".to_string(),
282 FeatureKind::Vector2 => "vector2".to_string(),
283 FeatureKind::Vector3 => "vector3".to_string(),
284 FeatureKind::Vector4 => "vector4".to_string(),
285 FeatureKind::VectorD => "vectord".to_string(),
286 FeatureKind::MatrixD => "matrixd".to_string(),
287 FeatureKind::RowVectorD => "row_vectord".to_string(),
288 FeatureKind::HorzCat => "matrix_horzcat".to_string(),
289 FeatureKind::VertCat => "matrix_vertcat".to_string(),
290 FeatureKind::Compiler => "compiler".to_string(),
291 FeatureKind::PrettyPrint => "pretty_print".to_string(),
292 FeatureKind::Serde => "serde".to_string(),
293 FeatureKind::MatMul => "matrix_matmul".to_string(),
294 FeatureKind::Transpose => "matrix_transpose".to_string(),
295 FeatureKind::Dot => "matrix_dot".to_string(),
296 FeatureKind::Solve => "matrix_solve".to_string(),
297 FeatureKind::Cross => "matrix_cross".to_string(),
298 FeatureKind::Add => "math_add".to_string(),
299 FeatureKind::Sub => "math_sub".to_string(),
300 FeatureKind::Mul => "math_mul".to_string(),
301 FeatureKind::Div => "math_div".to_string(),
302 FeatureKind::Pow => "math_pow".to_string(),
303 FeatureKind::Mod => "math_mod".to_string(),
304 FeatureKind::Neg => "math_neg".to_string(),
305 FeatureKind::OpAssign => "math_opassign".to_string(),
306 FeatureKind::LT => "compare_lt".to_string(),
307 FeatureKind::LTE => "compare_lte".to_string(),
308 FeatureKind::GT => "compare_gt".to_string(),
309 FeatureKind::GTE => "compare_gte".to_string(),
310 FeatureKind::EQ => "compare_eq".to_string(),
311 FeatureKind::NEQ => "compare_neq".to_string(),
312 FeatureKind::Min => "compare_min".to_string(),
313 FeatureKind::Max => "compare_max".to_string(),
314 FeatureKind::And => "logic_and".to_string(),
315 FeatureKind::Or => "logic_or".to_string(),
316 FeatureKind::Xor => "logic_xor".to_string(),
317 FeatureKind::Not => "logic_not".to_string(),
318 FeatureKind::Convert => "convert".to_string(),
319 FeatureKind::Assign => "assign".to_string(),
320 FeatureKind::Access => "access".to_string(),
321 FeatureKind::Union => "set_union".to_string(),
322 FeatureKind::Intersection => "set_intersection".to_string(),
323 FeatureKind::Difference => "set_difference".to_string(),
324 FeatureKind::Complement => "set_complement".to_string(),
325 FeatureKind::Subset => "set_subset".to_string(),
326 FeatureKind::Superset => "set_superset".to_string(),
327 FeatureKind::ProperSubset => "set_proper_subset".to_string(),
328 FeatureKind::ProperSuperset => "set_proper_superset".to_string(),
329 FeatureKind::ElementOf => "set_element_of".to_string(),
330 FeatureKind::NotElementOf => "set_not_element_of".to_string(),
331 FeatureKind::Functions => "functions".to_string(),
332 FeatureKind::Formulas => "formulas".to_string(),
333 FeatureKind::Custom => "custom".to_string(),
334 }
335 }
336}
337
338#[derive(Debug, Clone, PartialEq, Eq, Hash)]
339pub enum FeatureFlag {
340 Builtin(FeatureKind),
341 Custom(u64),
342}
343
344impl FeatureFlag {
345
346 pub fn as_string(&self) -> String {
347 match self {
348 FeatureFlag::Builtin(f) => f.as_string(),
349 FeatureFlag::Custom(c) => format!("custom({})", c),
350 }
351 }
352}
353
354impl FeatureFlag {
355 pub fn as_u64(&self) -> u64 {
356 match self {
357 FeatureFlag::Builtin(f) => *f as u64,
358 FeatureFlag::Custom(c) => *c,
359 }
360 }
361}
362
363#[repr(u16)]
367#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
368#[derive(Debug, Clone, Copy, Eq, PartialEq)]
369pub enum TypeTag {
370 U8=1, U16, U32, U64, U128, I8, I16, I32, I64, I128,
371 F32, F64, C64, R64, String, Bool, Id, Index, Empty, Any,
372 MatrixU8, MatrixU16, MatrixU32, MatrixU64, MatrixU128,
373 MatrixI8, MatrixI16, MatrixI32, MatrixI64, MatrixI128,
374 MatrixF32, MatrixF64, MatrixC64, MatrixR64, MatrixBool,
375 MatrixString, MatrixIndex,
376 EnumTag, Record, Map, Atom,
377 Table, Tuple, Reference, Set, OptionT, None,
378}
379
380impl TypeTag {
381 pub fn from_u16(tag: u16) -> Option<Self> {
382 match tag {
383 1 => Some(TypeTag::U8), 2 => Some(TypeTag::U16), 3 => Some(TypeTag::U32), 4 => Some(TypeTag::U64), 5 => Some(TypeTag::U128),
384 6 => Some(TypeTag::I8), 7 => Some(TypeTag::I16), 8 => Some(TypeTag::I32), 9 => Some(TypeTag::I64), 10 => Some(TypeTag::I128),
385 11 => Some(TypeTag::F32), 12 => Some(TypeTag::F64), 13 => Some(TypeTag::C64), 14 => Some(TypeTag::R64),
386 15 => Some(TypeTag::String), 16 => Some(TypeTag::Bool), 17 => Some(TypeTag::Id), 18 => Some(TypeTag::Index), 19 => Some(TypeTag::Empty), 20 => Some(TypeTag::Any),
387 21 => Some(TypeTag::MatrixU8), 22 => Some(TypeTag::MatrixU16), 23 => Some(TypeTag::MatrixU32), 24 => Some(TypeTag::MatrixU64), 25 => Some(TypeTag::MatrixU128),
388 26 => Some(TypeTag::MatrixI8), 27 => Some(TypeTag::MatrixI16), 28 => Some(TypeTag::MatrixI32), 29 => Some(TypeTag::MatrixI64), 30 => Some(TypeTag::MatrixI128),
389 31 => Some(TypeTag::MatrixF32), 32 => Some(TypeTag::MatrixF64), 33 => Some(TypeTag::MatrixC64), 34 => Some(TypeTag::MatrixR64), 35 => Some(TypeTag::MatrixBool),
390 36 => Some(TypeTag::MatrixString), 37 => Some(TypeTag::MatrixIndex),
391 38 => Some(TypeTag::EnumTag), 39 => Some(TypeTag::Record), 40 => Some(TypeTag::Map), 41 => Some(TypeTag::Atom),
392 42 => Some(TypeTag::Table), 43 => Some(TypeTag::Tuple), 44 => Some(TypeTag::Reference), 45 => Some(TypeTag::Set), 46 => Some(TypeTag::OptionT), 47 => Some(TypeTag::None),
393 _ => None,
394 }
395 }
396}
397
398#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
399#[derive(Debug, Clone, Eq, PartialEq)]
400pub struct TypeEntry {
401 pub tag: TypeTag,
402 pub bytes: Vec<u8>,
403}
404impl TypeEntry {
405 pub fn byte_len(&self) -> u64 {
406 2 + self.bytes.len() as u64
407 }
408}
409
410pub type TypeId = u32;
411
412#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
413#[derive(Default, Debug, Clone, Eq, PartialEq)]
414pub struct TypeSection {
415 pub interner: HashMap<ValueKind, TypeId>,
416 pub entries: Vec<TypeEntry>, }
418
419impl TypeSection {
420
421 pub fn new() -> Self {
422 Self { interner: HashMap::new(), entries: Vec::new() }
423 }
424
425 pub fn get_or_intern(&mut self, vk: &ValueKind) -> TypeId {
426 if let Some(id) = self.interner.get(vk) { return *id; }
427 let (tag, mut bytes) = encode_value_kind(self, vk);
429 let id = self.entries.len() as u32;
430 self.entries.push(TypeEntry { tag, bytes });
431 self.interner.insert(vk.clone(), id);
432 id
433 }
434
435 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
436 w.write_u32::<LittleEndian>(self.entries.len() as u32)?;
437 for e in &self.entries {
438 w.write_u16::<LittleEndian>(e.tag as u16)?;
439 w.write_u16::<LittleEndian>(0)?;
440 w.write_u32::<LittleEndian>(1)?;
441 w.write_u32::<LittleEndian>(e.bytes.len() as u32)?;
442 w.write_all(&e.bytes)?;
443 }
444 Ok(())
445 }
446
447 pub fn byte_len(&self) -> u64 {
448 4 + self.entries.iter().map(|e| 12 + e.bytes.len() as u64).sum::<u64>()
449 }
450}
451
452#[repr(u8)]
456#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
457#[derive(Debug, Clone, Copy, Eq, PartialEq)]
458pub enum ConstEncoding {
459 Inline = 1
460}
461
462#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
463#[derive(Debug, Clone, Eq, PartialEq)]
464pub struct ConstEntry {
465 pub type_id: u32,
466 pub enc: ConstEncoding,
467 pub align: u8,
468 pub flags: u8,
469 pub reserved:u16,
470 pub offset: u64,
471 pub length: u64,
472}
473
474impl ConstEntry {
475 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
476 w.write_u32::<LittleEndian>(self.type_id)?;
477 w.write_u8(self.enc as u8)?;
478 w.write_u8(self.align)?;
479 w.write_u8(self.flags)?;
480 w.write_u8(0)?; w.write_u64::<LittleEndian>(self.offset)?;
482 w.write_u64::<LittleEndian>(self.length)?;
483 Ok(())
484 }
485 pub fn byte_len() -> u64 { 4 + 1 + 1 + 1 + 1 + 8 + 8 } }
487
488pub struct SymbolEntry {
492 pub id: u64, pub mutable: bool,
494 pub reg: Register, }
496
497impl SymbolEntry {
498
499 pub fn new(id: u64, mutable: bool, reg: Register) -> Self {
500 Self { id, mutable, reg }
501 }
502
503 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
504 w.write_u64::<LittleEndian>(self.id)?;
505 w.write_u8(if self.mutable { 1 } else { 0 })?;
506 w.write_u32::<LittleEndian>(self.reg)?;
507 Ok(())
508 }
509}
510
511#[repr(u8)]
515#[derive(Debug, Clone, Copy, PartialEq, Eq)]
516pub enum OpCode {
517 ConstLoad = 0x01,
518 NullOp = 0x10,
519 Unop = 0x20,
520 Binop = 0x30,
521 Ternop = 0x40,
522 Quadop = 0x50,
523 VarArg = 0x60,
524 Return = 0xFF,
525}
526
527impl std::fmt::Display for OpCode {
528 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
529 let s = match self {
530 OpCode::ConstLoad => "ConstLoad",
531 OpCode::NullOp => "NullOp",
532 OpCode::Unop => "Unop",
533 OpCode::Binop => "Binop",
534 OpCode::Ternop => "Ternop",
535 OpCode::Quadop => "Quadop",
536 OpCode::VarArg => "VarArg",
537 OpCode::Return => "Return",
538 };
539 write!(f, "{}", s)
540 }
541}
542
543impl OpCode {
544 pub fn from_u8(num: u8) -> Option<OpCode> {
545 match num {
546 0x01 => Some(OpCode::ConstLoad),
547 0x10 => Some(OpCode::NullOp),
548 0x20 => Some(OpCode::Unop),
549 0x30 => Some(OpCode::Binop),
550 0x40 => Some(OpCode::Ternop),
551 0x50 => Some(OpCode::Quadop),
552 0x60 => Some(OpCode::VarArg),
553 0xFF => Some(OpCode::Return),
554 _ => None,
555 }
556 }
557}
558
559#[derive(Debug, Clone)]
560pub enum EncodedInstr {
561 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 }, }
570
571impl EncodedInstr {
572 pub fn byte_len(&self) -> u64 {
573 match self {
574 EncodedInstr::ConstLoad{..} => 1 + 4 + 4,
575 EncodedInstr::NullOp{..} => 1 + 8 + 4,
576 EncodedInstr::UnOp{..} => 1 + 8 + 4 + 4,
577 EncodedInstr::BinOp{..} => 1 + 8 + 4 + 4 + 4,
578 EncodedInstr::TernOp{..} => 1 + 8 + 4 + 4 + 4 + 4,
579 EncodedInstr::QuadOp{..} => 1 + 8 + 4 + 4 + 4 + 4 + 4,
580 EncodedInstr::VarArg{ args, .. } => 1 + 8 + 4 + 4 + (4 * args.len() as u64),
581 EncodedInstr::Ret{..} => 1 + 4,
582 }
583 }
584 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
585 match self {
586 EncodedInstr::ConstLoad{ dst, const_id } => {
587 w.write_u8(OpCode::ConstLoad as u8)?;
588 w.write_u32::<LittleEndian>(*dst)?;
589 w.write_u32::<LittleEndian>(*const_id)?;
590 }
591 EncodedInstr::NullOp{ fxn_id, dst } => {
592 w.write_u8(OpCode::NullOp as u8)?;
593 w.write_u64::<LittleEndian>(*fxn_id)?;
594 w.write_u32::<LittleEndian>(*dst)?;
595 }
596 EncodedInstr::UnOp{ fxn_id, dst, src } => {
597 w.write_u8(OpCode::Unop as u8)?;
598 w.write_u64::<LittleEndian>(*fxn_id)?;
599 w.write_u32::<LittleEndian>(*dst)?;
600 w.write_u32::<LittleEndian>(*src)?;
601 }
602 EncodedInstr::BinOp{ fxn_id, dst, lhs, rhs } => {
603 w.write_u8(OpCode::Binop as u8)?;
604 w.write_u64::<LittleEndian>(*fxn_id)?;
605 w.write_u32::<LittleEndian>(*dst)?;
606 w.write_u32::<LittleEndian>(*lhs)?;
607 w.write_u32::<LittleEndian>(*rhs)?;
608 }
609 EncodedInstr::TernOp{ fxn_id, dst, a, b, c } => {
610 w.write_u8(OpCode::Ternop as u8)?;
611 w.write_u64::<LittleEndian>(*fxn_id)?;
612 w.write_u32::<LittleEndian>(*dst)?;
613 w.write_u32::<LittleEndian>(*a)?;
614 w.write_u32::<LittleEndian>(*b)?;
615 w.write_u32::<LittleEndian>(*c)?;
616 }
617 EncodedInstr::QuadOp{ fxn_id, dst, a, b, c, d } => {
618 w.write_u8(OpCode::Quadop as u8)?;
619 w.write_u64::<LittleEndian>(*fxn_id)?;
620 w.write_u32::<LittleEndian>(*dst)?;
621 w.write_u32::<LittleEndian>(*a)?;
622 w.write_u32::<LittleEndian>(*b)?;
623 w.write_u32::<LittleEndian>(*c)?;
624 w.write_u32::<LittleEndian>(*d)?;
625 }
626 EncodedInstr::VarArg{ fxn_id, dst, args } => {
627 w.write_u8(OpCode::VarArg as u8)?;
628 w.write_u64::<LittleEndian>(*fxn_id)?;
629 w.write_u32::<LittleEndian>(*dst)?;
630 w.write_u32::<LittleEndian>(args.len() as u32)?;
631 for a in args {
632 w.write_u32::<LittleEndian>(*a)?;
633 }
634 }
635 EncodedInstr::Ret{ src } => {
636 w.write_u8(OpCode::Return as u8)?;
637 w.write_u32::<LittleEndian>(*src)?;
638 }
639 }
640 Ok(())
641 }
642}
643
644#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
648#[derive(Debug, Clone, Eq, PartialEq)]
649pub struct DictEntry {
650 pub id: u64, pub name: String, }
653
654impl DictEntry {
655 pub fn new(id: u64, name: &str) -> Self {
656 Self { id, name: name.to_string() }
657 }
658
659 pub fn write_to(&self, w: &mut impl Write) -> MResult<()> {
660 w.write_u64::<LittleEndian>(self.id)?;
661 let name_bytes = self.name.as_bytes();
662 w.write_u32::<LittleEndian>(name_bytes.len() as u32)?;
663 w.write_all(name_bytes)?;
664 Ok(())
665 }
666}
667
668