1use num::{FromPrimitive, ToPrimitive};
2
3#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4pub enum Instruction {
5 Add,
7 Sub,
8 Mul,
9 Div,
10 IntDiv,
11 Mod,
12 Plus,
14 Minus,
15 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
164pub(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
455pub 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}