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