xee_interpreter/interpreter/
instruction.rs

1use num::{FromPrimitive, ToPrimitive};
2
3#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4pub enum Instruction {
5    // binary operators
6    Add,
7    Sub,
8    Mul,
9    Div,
10    IntDiv,
11    Mod,
12    // unary operators
13    Plus,
14    Minus,
15    //
16    Concat,
17    Const(u16),
18    Closure(u16),
19    StaticClosure(u16),
20    Var(u16),
21    Set(u16),
22    ClosureVar(u16),
23    Comma,
24    CurlyArray,
25    SquareArray,
26    CurlyMap,
27    Eq,
28    Ne,
29    Lt,
30    Le,
31    Gt,
32    Ge,
33    GenEq,
34    GenNe,
35    GenLt,
36    GenLe,
37    GenGt,
38    GenGe,
39    Is,
40    Precedes,
41    Follows,
42    Union,
43    Intersect,
44    Except,
45    Jump(i16),
46    JumpIfTrue(i16),
47    JumpIfFalse(i16),
48    Call(u8),
49    Lookup,
50    WildcardLookup,
51    Step(u16),
52    Deduplicate,
53    Return,
54    ReturnConvert(u16),
55    Dup,
56    Pop,
57    LetDone,
58    Cast(u16),
59    Castable(u16),
60    InstanceOf(u16),
61    Treat(u16),
62    Range,
63    SequenceLen,
64    SequenceGet,
65    BuildNew,
66    BuildPush,
67    BuildComplete,
68    IsNumeric,
69    XmlName,
70    XmlDocument,
71    XmlElement,
72    XmlAttribute,
73    XmlNamespace,
74    XmlText,
75    XmlComment,
76    XmlProcessingInstruction,
77    XmlAppend,
78    CopyShallow,
79    CopyDeep,
80    ApplyTemplates(u16),
81    PrintTop,
82    PrintStack,
83}
84
85#[derive(Debug, ToPrimitive, FromPrimitive, Clone, PartialEq, Eq, Hash)]
86pub(crate) enum EncodedInstruction {
87    Add,
88    Sub,
89    Mul,
90    Div,
91    IntDiv,
92    Mod,
93    Plus,
94    Minus,
95    Concat,
96    Const,
97    Closure,
98    StaticClosure,
99    Var,
100    Set,
101    ClosureVar,
102    Comma,
103    CurlyArray,
104    SquareArray,
105    CurlyMap,
106    Eq,
107    Ne,
108    Lt,
109    Le,
110    Gt,
111    Ge,
112    GenEq,
113    GenNe,
114    GenLt,
115    GenLe,
116    GenGt,
117    GenGe,
118    Is,
119    Precedes,
120    Follows,
121    Union,
122    Intersect,
123    Except,
124    Jump,
125    JumpIfTrue,
126    JumpIfFalse,
127    Call,
128    Lookup,
129    WildcardLookup,
130    Step,
131    Deduplicate,
132    Return,
133    ReturnConvert,
134    Dup,
135    Pop,
136    LetDone,
137    Cast,
138    Castable,
139    InstanceOf,
140    Treat,
141    Range,
142    SequenceLen,
143    SequenceGet,
144    BuildNew,
145    BuildPush,
146    BuildComplete,
147    IsNumeric,
148    XmlName,
149    XmlDocument,
150    XmlElement,
151    XmlAttribute,
152    XmlNamespace,
153    XmlText,
154    XmlComment,
155    XmlProcessingInstruction,
156    XmlAppend,
157    ApplyTemplates,
158    CopyShallow,
159    CopyDeep,
160    PrintTop,
161    PrintStack,
162}
163
164// decode a single instruction from the slice
165pub(crate) fn decode_instruction(bytes: &[u8]) -> (Instruction, usize) {
166    let encoded_instruction = EncodedInstruction::from_u8(bytes[0]).unwrap();
167    match encoded_instruction {
168        EncodedInstruction::Add => (Instruction::Add, 1),
169        EncodedInstruction::Sub => (Instruction::Sub, 1),
170        EncodedInstruction::Mul => (Instruction::Mul, 1),
171        EncodedInstruction::Div => (Instruction::Div, 1),
172        EncodedInstruction::IntDiv => (Instruction::IntDiv, 1),
173        EncodedInstruction::Mod => (Instruction::Mod, 1),
174        EncodedInstruction::Plus => (Instruction::Plus, 1),
175        EncodedInstruction::Minus => (Instruction::Minus, 1),
176        EncodedInstruction::Concat => (Instruction::Concat, 1),
177        EncodedInstruction::Const => {
178            let constant = u16::from_le_bytes([bytes[1], bytes[2]]);
179            (Instruction::Const(constant), 3)
180        }
181        EncodedInstruction::Closure => {
182            let function = u16::from_le_bytes([bytes[1], bytes[2]]);
183            (Instruction::Closure(function), 3)
184        }
185        EncodedInstruction::StaticClosure => {
186            let function = u16::from_le_bytes([bytes[1], bytes[2]]);
187            (Instruction::StaticClosure(function), 3)
188        }
189        EncodedInstruction::Var => {
190            let variable = u16::from_le_bytes([bytes[1], bytes[2]]);
191            (Instruction::Var(variable), 3)
192        }
193        EncodedInstruction::Set => {
194            let variable = u16::from_le_bytes([bytes[1], bytes[2]]);
195            (Instruction::Set(variable), 3)
196        }
197        EncodedInstruction::ClosureVar => {
198            let variable = u16::from_le_bytes([bytes[1], bytes[2]]);
199            (Instruction::ClosureVar(variable), 3)
200        }
201        EncodedInstruction::Comma => (Instruction::Comma, 1),
202        EncodedInstruction::CurlyArray => (Instruction::CurlyArray, 1),
203        EncodedInstruction::SquareArray => (Instruction::SquareArray, 1),
204        EncodedInstruction::CurlyMap => (Instruction::CurlyMap, 1),
205        EncodedInstruction::Eq => (Instruction::Eq, 1),
206        EncodedInstruction::Ne => (Instruction::Ne, 1),
207        EncodedInstruction::Lt => (Instruction::Lt, 1),
208        EncodedInstruction::Le => (Instruction::Le, 1),
209        EncodedInstruction::Gt => (Instruction::Gt, 1),
210        EncodedInstruction::Ge => (Instruction::Ge, 1),
211        EncodedInstruction::GenEq => (Instruction::GenEq, 1),
212        EncodedInstruction::GenNe => (Instruction::GenNe, 1),
213        EncodedInstruction::GenLt => (Instruction::GenLt, 1),
214        EncodedInstruction::GenLe => (Instruction::GenLe, 1),
215        EncodedInstruction::GenGt => (Instruction::GenGt, 1),
216        EncodedInstruction::GenGe => (Instruction::GenGe, 1),
217        EncodedInstruction::Is => (Instruction::Is, 1),
218        EncodedInstruction::Precedes => (Instruction::Precedes, 1),
219        EncodedInstruction::Follows => (Instruction::Follows, 1),
220        EncodedInstruction::Union => (Instruction::Union, 1),
221        EncodedInstruction::Intersect => (Instruction::Intersect, 1),
222        EncodedInstruction::Except => (Instruction::Except, 1),
223        EncodedInstruction::Jump => {
224            let displacement = i16::from_le_bytes([bytes[1], bytes[2]]);
225            (Instruction::Jump(displacement), 3)
226        }
227        EncodedInstruction::JumpIfTrue => {
228            let displacement = i16::from_le_bytes([bytes[1], bytes[2]]);
229            (Instruction::JumpIfTrue(displacement), 3)
230        }
231        EncodedInstruction::JumpIfFalse => {
232            let displacement = i16::from_le_bytes([bytes[1], bytes[2]]);
233            (Instruction::JumpIfFalse(displacement), 3)
234        }
235        EncodedInstruction::Call => {
236            let arity = bytes[1];
237            (Instruction::Call(arity), 2)
238        }
239        EncodedInstruction::Lookup => (Instruction::Lookup, 1),
240        EncodedInstruction::WildcardLookup => (Instruction::WildcardLookup, 1),
241        EncodedInstruction::Step => {
242            let step = u16::from_le_bytes([bytes[1], bytes[2]]);
243            (Instruction::Step(step), 3)
244        }
245        EncodedInstruction::Deduplicate => (Instruction::Deduplicate, 1),
246        EncodedInstruction::Cast => {
247            let type_id = u16::from_le_bytes([bytes[1], bytes[2]]);
248            (Instruction::Cast(type_id), 3)
249        }
250        EncodedInstruction::Castable => {
251            let type_id = u16::from_le_bytes([bytes[1], bytes[2]]);
252            (Instruction::Castable(type_id), 3)
253        }
254        EncodedInstruction::InstanceOf => {
255            let sequence_type_id = u16::from_le_bytes([bytes[1], bytes[2]]);
256            (Instruction::InstanceOf(sequence_type_id), 3)
257        }
258        EncodedInstruction::Treat => {
259            let sequence_type_id = u16::from_le_bytes([bytes[1], bytes[2]]);
260            (Instruction::Treat(sequence_type_id), 3)
261        }
262        EncodedInstruction::Return => (Instruction::Return, 1),
263        EncodedInstruction::ReturnConvert => {
264            let sequence_type_id = u16::from_le_bytes([bytes[1], bytes[2]]);
265            (Instruction::ReturnConvert(sequence_type_id), 3)
266        }
267        EncodedInstruction::Dup => (Instruction::Dup, 1),
268        EncodedInstruction::Pop => (Instruction::Pop, 1),
269        EncodedInstruction::LetDone => (Instruction::LetDone, 1),
270        EncodedInstruction::Range => (Instruction::Range, 1),
271        EncodedInstruction::SequenceLen => (Instruction::SequenceLen, 1),
272        EncodedInstruction::SequenceGet => (Instruction::SequenceGet, 1),
273        EncodedInstruction::BuildNew => (Instruction::BuildNew, 1),
274        EncodedInstruction::BuildPush => (Instruction::BuildPush, 1),
275        EncodedInstruction::BuildComplete => (Instruction::BuildComplete, 1),
276        EncodedInstruction::IsNumeric => (Instruction::IsNumeric, 1),
277        EncodedInstruction::XmlName => (Instruction::XmlName, 1),
278        EncodedInstruction::XmlDocument => (Instruction::XmlDocument, 1),
279        EncodedInstruction::XmlElement => (Instruction::XmlElement, 1),
280        EncodedInstruction::XmlAttribute => (Instruction::XmlAttribute, 1),
281        EncodedInstruction::XmlNamespace => (Instruction::XmlNamespace, 1),
282        EncodedInstruction::XmlText => (Instruction::XmlText, 1),
283        EncodedInstruction::XmlComment => (Instruction::XmlComment, 1),
284        EncodedInstruction::XmlProcessingInstruction => (Instruction::XmlProcessingInstruction, 1),
285        EncodedInstruction::XmlAppend => (Instruction::XmlAppend, 1),
286        EncodedInstruction::CopyShallow => (Instruction::CopyShallow, 1),
287        EncodedInstruction::CopyDeep => (Instruction::CopyDeep, 1),
288        EncodedInstruction::ApplyTemplates => {
289            let mode_id = u16::from_le_bytes([bytes[1], bytes[2]]);
290            (Instruction::ApplyTemplates(mode_id), 3)
291        }
292        EncodedInstruction::PrintTop => (Instruction::PrintTop, 1),
293        EncodedInstruction::PrintStack => (Instruction::PrintStack, 1),
294    }
295}
296
297pub fn decode_instructions(bytes: &[u8]) -> Vec<Instruction> {
298    let mut instructions = Vec::new();
299    let mut ip = 0;
300    while ip < bytes.len() {
301        let (instruction, instruction_size) = decode_instruction(&bytes[ip..]);
302        instructions.push(instruction);
303        ip += instruction_size;
304    }
305    instructions
306}
307
308pub fn encode_instruction(instruction: Instruction, bytes: &mut Vec<u8>) {
309    match instruction {
310        Instruction::Add => bytes.push(EncodedInstruction::Add.to_u8().unwrap()),
311        Instruction::Sub => bytes.push(EncodedInstruction::Sub.to_u8().unwrap()),
312        Instruction::Mul => bytes.push(EncodedInstruction::Mul.to_u8().unwrap()),
313        Instruction::Div => bytes.push(EncodedInstruction::Div.to_u8().unwrap()),
314        Instruction::IntDiv => bytes.push(EncodedInstruction::IntDiv.to_u8().unwrap()),
315        Instruction::Mod => bytes.push(EncodedInstruction::Mod.to_u8().unwrap()),
316        Instruction::Plus => bytes.push(EncodedInstruction::Plus.to_u8().unwrap()),
317        Instruction::Minus => bytes.push(EncodedInstruction::Minus.to_u8().unwrap()),
318        Instruction::Concat => bytes.push(EncodedInstruction::Concat.to_u8().unwrap()),
319        Instruction::Const(constant) => {
320            bytes.push(EncodedInstruction::Const.to_u8().unwrap());
321            bytes.extend_from_slice(&constant.to_le_bytes());
322        }
323        Instruction::Closure(function_id) => {
324            bytes.push(EncodedInstruction::Closure.to_u8().unwrap());
325            bytes.extend_from_slice(&function_id.to_le_bytes());
326        }
327        Instruction::StaticClosure(function_id) => {
328            bytes.push(EncodedInstruction::StaticClosure.to_u8().unwrap());
329            bytes.extend_from_slice(&function_id.to_le_bytes());
330        }
331        Instruction::Var(variable) => {
332            bytes.push(EncodedInstruction::Var.to_u8().unwrap());
333            bytes.extend_from_slice(&variable.to_le_bytes());
334        }
335        Instruction::Set(variable) => {
336            bytes.push(EncodedInstruction::Set.to_u8().unwrap());
337            bytes.extend_from_slice(&variable.to_le_bytes());
338        }
339        Instruction::ClosureVar(variable) => {
340            bytes.push(EncodedInstruction::ClosureVar.to_u8().unwrap());
341            bytes.extend_from_slice(&variable.to_le_bytes());
342        }
343        Instruction::Comma => bytes.push(EncodedInstruction::Comma.to_u8().unwrap()),
344        Instruction::CurlyArray => bytes.push(EncodedInstruction::CurlyArray.to_u8().unwrap()),
345        Instruction::SquareArray => bytes.push(EncodedInstruction::SquareArray.to_u8().unwrap()),
346        Instruction::CurlyMap => bytes.push(EncodedInstruction::CurlyMap.to_u8().unwrap()),
347        Instruction::Eq => bytes.push(EncodedInstruction::Eq.to_u8().unwrap()),
348        Instruction::Ne => bytes.push(EncodedInstruction::Ne.to_u8().unwrap()),
349        Instruction::Lt => bytes.push(EncodedInstruction::Lt.to_u8().unwrap()),
350        Instruction::Le => bytes.push(EncodedInstruction::Le.to_u8().unwrap()),
351        Instruction::Gt => bytes.push(EncodedInstruction::Gt.to_u8().unwrap()),
352        Instruction::Ge => bytes.push(EncodedInstruction::Ge.to_u8().unwrap()),
353        Instruction::GenEq => bytes.push(EncodedInstruction::GenEq.to_u8().unwrap()),
354        Instruction::GenNe => bytes.push(EncodedInstruction::GenNe.to_u8().unwrap()),
355        Instruction::GenLt => bytes.push(EncodedInstruction::GenLt.to_u8().unwrap()),
356        Instruction::GenLe => bytes.push(EncodedInstruction::GenLe.to_u8().unwrap()),
357        Instruction::GenGt => bytes.push(EncodedInstruction::GenGt.to_u8().unwrap()),
358        Instruction::GenGe => bytes.push(EncodedInstruction::GenGe.to_u8().unwrap()),
359        Instruction::Is => bytes.push(EncodedInstruction::Is.to_u8().unwrap()),
360        Instruction::Precedes => bytes.push(EncodedInstruction::Precedes.to_u8().unwrap()),
361        Instruction::Follows => bytes.push(EncodedInstruction::Follows.to_u8().unwrap()),
362        Instruction::Union => bytes.push(EncodedInstruction::Union.to_u8().unwrap()),
363        Instruction::Intersect => bytes.push(EncodedInstruction::Intersect.to_u8().unwrap()),
364        Instruction::Except => bytes.push(EncodedInstruction::Except.to_u8().unwrap()),
365        Instruction::Jump(displacement) => {
366            bytes.push(EncodedInstruction::Jump.to_u8().unwrap());
367            bytes.extend_from_slice(&displacement.to_le_bytes());
368        }
369        Instruction::JumpIfTrue(displacement) => {
370            bytes.push(EncodedInstruction::JumpIfTrue.to_u8().unwrap());
371            bytes.extend_from_slice(&displacement.to_le_bytes());
372        }
373        Instruction::JumpIfFalse(displacement) => {
374            bytes.push(EncodedInstruction::JumpIfFalse.to_u8().unwrap());
375            bytes.extend_from_slice(&displacement.to_le_bytes());
376        }
377        Instruction::Call(arity) => {
378            bytes.push(EncodedInstruction::Call.to_u8().unwrap());
379            bytes.push(arity);
380        }
381        Instruction::Lookup => bytes.push(EncodedInstruction::Lookup.to_u8().unwrap()),
382        Instruction::WildcardLookup => {
383            bytes.push(EncodedInstruction::WildcardLookup.to_u8().unwrap())
384        }
385        Instruction::Step(step_id) => {
386            bytes.push(EncodedInstruction::Step.to_u8().unwrap());
387            bytes.extend_from_slice(&step_id.to_le_bytes());
388        }
389        Instruction::Deduplicate => {
390            bytes.push(EncodedInstruction::Deduplicate.to_u8().unwrap());
391        }
392        Instruction::Return => bytes.push(EncodedInstruction::Return.to_u8().unwrap()),
393        Instruction::ReturnConvert(sequence_type_id) => {
394            bytes.push(EncodedInstruction::ReturnConvert.to_u8().unwrap());
395            bytes.extend_from_slice(&sequence_type_id.to_le_bytes());
396        }
397        Instruction::Dup => bytes.push(EncodedInstruction::Dup.to_u8().unwrap()),
398        Instruction::Pop => bytes.push(EncodedInstruction::Pop.to_u8().unwrap()),
399        Instruction::LetDone => bytes.push(EncodedInstruction::LetDone.to_u8().unwrap()),
400        Instruction::Cast(type_id) => {
401            bytes.push(EncodedInstruction::Cast.to_u8().unwrap());
402            bytes.extend_from_slice(&type_id.to_le_bytes());
403        }
404        Instruction::Castable(type_id) => {
405            bytes.push(EncodedInstruction::Castable.to_u8().unwrap());
406            bytes.extend_from_slice(&type_id.to_le_bytes());
407        }
408        Instruction::InstanceOf(sequence_type_id) => {
409            bytes.push(EncodedInstruction::InstanceOf.to_u8().unwrap());
410            bytes.extend_from_slice(&sequence_type_id.to_le_bytes());
411        }
412        Instruction::Treat(sequence_type_id) => {
413            bytes.push(EncodedInstruction::Treat.to_u8().unwrap());
414            bytes.extend_from_slice(&sequence_type_id.to_le_bytes());
415        }
416        Instruction::Range => bytes.push(EncodedInstruction::Range.to_u8().unwrap()),
417        Instruction::SequenceLen => bytes.push(EncodedInstruction::SequenceLen.to_u8().unwrap()),
418        Instruction::SequenceGet => bytes.push(EncodedInstruction::SequenceGet.to_u8().unwrap()),
419        Instruction::BuildNew => bytes.push(EncodedInstruction::BuildNew.to_u8().unwrap()),
420        Instruction::BuildPush => bytes.push(EncodedInstruction::BuildPush.to_u8().unwrap()),
421        Instruction::BuildComplete => {
422            bytes.push(EncodedInstruction::BuildComplete.to_u8().unwrap())
423        }
424        Instruction::IsNumeric => bytes.push(EncodedInstruction::IsNumeric.to_u8().unwrap()),
425        Instruction::XmlName => bytes.push(EncodedInstruction::XmlName.to_u8().unwrap()),
426        Instruction::XmlDocument => bytes.push(EncodedInstruction::XmlDocument.to_u8().unwrap()),
427        Instruction::XmlElement => bytes.push(EncodedInstruction::XmlElement.to_u8().unwrap()),
428        Instruction::XmlAttribute => bytes.push(EncodedInstruction::XmlAttribute.to_u8().unwrap()),
429        Instruction::XmlNamespace => bytes.push(EncodedInstruction::XmlNamespace.to_u8().unwrap()),
430        Instruction::XmlText => bytes.push(EncodedInstruction::XmlText.to_u8().unwrap()),
431        Instruction::XmlComment => bytes.push(EncodedInstruction::XmlComment.to_u8().unwrap()),
432        Instruction::XmlProcessingInstruction => bytes.push(
433            EncodedInstruction::XmlProcessingInstruction
434                .to_u8()
435                .unwrap(),
436        ),
437        Instruction::XmlAppend => bytes.push(EncodedInstruction::XmlAppend.to_u8().unwrap()),
438        Instruction::CopyShallow => bytes.push(EncodedInstruction::CopyShallow.to_u8().unwrap()),
439        Instruction::CopyDeep => bytes.push(EncodedInstruction::CopyDeep.to_u8().unwrap()),
440        Instruction::ApplyTemplates(mode_id) => {
441            bytes.push(EncodedInstruction::ApplyTemplates.to_u8().unwrap());
442            bytes.extend_from_slice(&mode_id.to_le_bytes());
443        }
444        Instruction::PrintTop => bytes.push(EncodedInstruction::PrintTop.to_u8().unwrap()),
445        Instruction::PrintStack => bytes.push(EncodedInstruction::PrintStack.to_u8().unwrap()),
446    }
447}
448
449pub(crate) fn encode_instructions(instructions: Vec<Instruction>, bytes: &mut Vec<u8>) {
450    for instruction in instructions {
451        encode_instruction(instruction, bytes);
452    }
453}
454
455// size in bytes for an instruction
456pub fn instruction_size(instruction: &Instruction) -> usize {
457    match instruction {
458        Instruction::Add
459        | Instruction::Sub
460        | Instruction::Mul
461        | Instruction::Div
462        | Instruction::IntDiv
463        | Instruction::Mod
464        | Instruction::Plus
465        | Instruction::Minus
466        | Instruction::Concat
467        | Instruction::Comma
468        | Instruction::CurlyArray
469        | Instruction::SquareArray
470        | Instruction::CurlyMap
471        | Instruction::Eq
472        | Instruction::Ne
473        | Instruction::Lt
474        | Instruction::Le
475        | Instruction::Gt
476        | Instruction::Ge
477        | Instruction::GenEq
478        | Instruction::GenNe
479        | Instruction::GenLt
480        | Instruction::GenLe
481        | Instruction::GenGt
482        | Instruction::GenGe
483        | Instruction::Is
484        | Instruction::Precedes
485        | Instruction::Follows
486        | Instruction::Union
487        | Instruction::Intersect
488        | Instruction::Except
489        | Instruction::Return
490        | Instruction::Dup
491        | Instruction::Pop
492        | Instruction::LetDone
493        | Instruction::Range
494        | Instruction::SequenceLen
495        | Instruction::SequenceGet
496        | Instruction::BuildNew
497        | Instruction::BuildPush
498        | Instruction::BuildComplete
499        | Instruction::IsNumeric
500        | Instruction::Deduplicate
501        | Instruction::Lookup
502        | Instruction::WildcardLookup
503        | Instruction::XmlName
504        | Instruction::XmlDocument
505        | Instruction::XmlElement
506        | Instruction::XmlAttribute
507        | Instruction::XmlNamespace
508        | Instruction::XmlText
509        | Instruction::XmlComment
510        | Instruction::XmlProcessingInstruction
511        | Instruction::XmlAppend
512        | Instruction::CopyShallow
513        | Instruction::CopyDeep
514        | Instruction::PrintTop
515        | Instruction::PrintStack => 1,
516        Instruction::Call(_) => 2,
517        Instruction::Const(_)
518        | Instruction::Closure(_)
519        | Instruction::StaticClosure(_)
520        | Instruction::Var(_)
521        | Instruction::Set(_)
522        | Instruction::ClosureVar(_)
523        | Instruction::Jump(_)
524        | Instruction::JumpIfTrue(_)
525        | Instruction::Step(_)
526        | Instruction::Cast(_)
527        | Instruction::Castable(_)
528        | Instruction::InstanceOf(_)
529        | Instruction::Treat(_)
530        | Instruction::ReturnConvert(_)
531        | Instruction::JumpIfFalse(_) => 3,
532        Instruction::ApplyTemplates(_) => 3,
533    }
534}
535
536pub(crate) fn read_instruction(bytes: &[u8], ip: &mut usize) -> EncodedInstruction {
537    let byte = bytes[*ip];
538    *ip += 1;
539    EncodedInstruction::from_u8(byte).unwrap()
540}
541
542pub(crate) fn read_u16(bytes: &[u8], ip: &mut usize) -> u16 {
543    let bytes = &bytes[*ip..*ip + 2];
544    *ip += 2;
545    u16::from_le_bytes([bytes[0], bytes[1]])
546}
547
548pub(crate) fn read_i16(bytes: &[u8], ip: &mut usize) -> i16 {
549    let bytes = &bytes[*ip..*ip + 2];
550    *ip += 2;
551    i16::from_le_bytes([bytes[0], bytes[1]])
552}
553
554pub(crate) fn read_u8(bytes: &[u8], ip: &mut usize) -> u8 {
555    let byte = bytes[*ip];
556    *ip += 1;
557    byte
558}
559
560use crate::function::InlineFunction;
561
562impl InlineFunction {
563    pub fn decoded(&self) -> Vec<Instruction> {
564        decode_instructions(&self.chunk)
565    }
566}