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