Skip to main content

nyar_assembler/program/
instructions.rs

1use gaia_binary::{BinaryReader, BinaryWriter, Leb128};
2use gaia_types::GaiaError;
3use std::io::Cursor;
4use super::types::{NyarInstruction, NyarOpcode, NyarUpvalueRef};
5
6/// Codec trait for Nyar instructions
7pub trait NyarCodec: Sized {
8    /// Encode to binary stream
9    fn encode(&self, writer: &mut BinaryWriter<Vec<u8>, Leb128>) -> std::io::Result<()>;
10    /// Decode from binary stream
11    fn decode(reader: &mut BinaryReader<Cursor<&[u8]>, Leb128>) -> Result<Self, GaiaError>;
12}
13
14impl NyarCodec for NyarInstruction {
15    fn encode(&self, writer: &mut BinaryWriter<Vec<u8>, Leb128>) -> std::io::Result<()> {
16        match self {
17            Self::Nop => writer.write_u8(NyarOpcode::Nop as u8)?,
18            Self::Push(v) => {
19                writer.write_u8(NyarOpcode::Push as u8)?;
20                writer.write_u16(*v)?;
21            }
22            Self::PushNone => writer.write_u8(NyarOpcode::PushNone as u8)?,
23            Self::Pop => writer.write_u8(NyarOpcode::Pop as u8)?,
24            Self::Dup(v) => {
25                writer.write_u8(NyarOpcode::Dup as u8)?;
26                writer.write_u8(*v)?;
27            }
28            Self::Swap(v) => {
29                writer.write_u8(NyarOpcode::Swap as u8)?;
30                writer.write_u8(*v)?;
31            }
32            Self::LoadLocal(v) => {
33                writer.write_u8(NyarOpcode::LoadLocal as u8)?;
34                writer.write_u8(*v)?;
35            }
36            Self::StoreLocal(v) => {
37                writer.write_u8(NyarOpcode::StoreLocal as u8)?;
38                writer.write_u8(*v)?;
39            }
40            Self::LoadGlobal(v) => {
41                writer.write_u8(NyarOpcode::LoadGlobal as u8)?;
42                writer.write_u16(*v)?;
43            }
44            Self::StoreGlobal(v) => {
45                writer.write_u8(NyarOpcode::StoreGlobal as u8)?;
46                writer.write_u16(*v)?;
47            }
48            Self::LoadUpvalue(v) => {
49                writer.write_u8(NyarOpcode::LoadUpvalue as u8)?;
50                writer.write_u8(*v)?;
51            }
52            Self::StoreUpvalue(v) => {
53                writer.write_u8(NyarOpcode::StoreUpvalue as u8)?;
54                writer.write_u8(*v)?;
55            }
56            Self::CloseUpvalues => writer.write_u8(NyarOpcode::CloseUpvalues as u8)?,
57            Self::Jump(v) => {
58                writer.write_u8(NyarOpcode::Jump as u8)?;
59                writer.write_i16(*v)?;
60            }
61            Self::JumpIfFalse(v) => {
62                writer.write_u8(NyarOpcode::JumpIfFalse as u8)?;
63                writer.write_i16(*v)?;
64            }
65            Self::JumpIfTrue(v) => {
66                writer.write_u8(NyarOpcode::JumpIfTrue as u8)?;
67                writer.write_i16(*v)?;
68            }
69            Self::JumpIfNull(v) => {
70                writer.write_u8(NyarOpcode::JumpIfNull as u8)?;
71                writer.write_i16(*v)?;
72            }
73            Self::Return => writer.write_u8(NyarOpcode::Return as u8)?,
74            Self::MakeClosure(idx, ups) => {
75                writer.write_u8(NyarOpcode::MakeClosure as u8)?;
76                writer.write_u16(*idx)?;
77                writer.write_u8(ups.len() as u8)?;
78                for up in ups {
79                    writer.write_u8(if up.is_local { 1 } else { 0 })?;
80                    writer.write_u8(up.index)?;
81                }
82            }
83            Self::TailCall(idx, argc) => {
84                writer.write_u8(NyarOpcode::TailCall as u8)?;
85                writer.write_u16(*idx)?;
86                writer.write_u8(*argc)?;
87            }
88            Self::TailCallClosure(argc) => {
89                writer.write_u8(NyarOpcode::TailCallClosure as u8)?;
90                writer.write_u8(*argc)?;
91            }
92            Self::Call(idx, argc) => {
93                writer.write_u8(NyarOpcode::Call as u8)?;
94                writer.write_u16(*idx)?;
95                writer.write_u8(*argc)?;
96            }
97            Self::CallVirtual(idx, argc) => {
98                writer.write_u8(NyarOpcode::CallVirtual as u8)?;
99                writer.write_u16(*idx)?;
100                writer.write_u8(*argc)?;
101            }
102            Self::CallDynamic(idx, argc) => {
103                writer.write_u8(NyarOpcode::CallDynamic as u8)?;
104                writer.write_u16(*idx)?;
105                writer.write_u8(*argc)?;
106            }
107            Self::CallClosure(argc) => {
108                writer.write_u8(NyarOpcode::CallClosure as u8)?;
109                writer.write_u8(*argc)?;
110            }
111            Self::InvokeMethod(idx, argc) => {
112                writer.write_u8(NyarOpcode::InvokeMethod as u8)?;
113                writer.write_u16(*idx)?;
114                writer.write_u8(*argc)?;
115            }
116            Self::CallSymbol(idx, argc) => {
117                writer.write_u8(NyarOpcode::CallSymbol as u8)?;
118                writer.write_u16(*idx)?;
119                writer.write_u8(*argc)?;
120            }
121            Self::GetField(idx) => {
122                writer.write_u8(NyarOpcode::GetField as u8)?;
123                writer.write_u16(*idx)?;
124            }
125            Self::SetField(idx) => {
126                writer.write_u8(NyarOpcode::SetField as u8)?;
127                writer.write_u16(*idx)?;
128            }
129            Self::NewObject(idx) => {
130                writer.write_u8(NyarOpcode::NewObject as u8)?;
131                writer.write_u16(*idx)?;
132            }
133            Self::NewArray(len) => {
134                writer.write_u8(NyarOpcode::NewArray as u8)?;
135                writer.write_u16(*len)?;
136            }
137            Self::GetElement => writer.write_u8(NyarOpcode::GetElement as u8)?,
138            Self::SetElement => writer.write_u8(NyarOpcode::SetElement as u8)?,
139            Self::NewDynObject => writer.write_u8(NyarOpcode::NewDynObject as u8)?,
140            Self::RemoveKey => writer.write_u8(NyarOpcode::RemoveKey as u8)?,
141            Self::Initiate(v) => {
142                writer.write_u8(NyarOpcode::Initiate as u8)?;
143                writer.write_u8(*v)?;
144            }
145            Self::Finalize => writer.write_u8(NyarOpcode::Finalize as u8)?,
146            Self::NewList(len) => {
147                writer.write_u8(NyarOpcode::NewList as u8)?;
148                writer.write_u16(*len)?;
149            }
150            Self::PushElementLeft => writer.write_u8(NyarOpcode::PushElementLeft as u8)?,
151            Self::PopElementLeft => writer.write_u8(NyarOpcode::PopElementLeft as u8)?,
152            Self::PushElementRight => writer.write_u8(NyarOpcode::PushElementRight as u8)?,
153            Self::PopElementRight => writer.write_u8(NyarOpcode::PopElementRight as u8)?,
154            Self::MakeTuple(v) => {
155                writer.write_u8(NyarOpcode::MakeTuple as u8)?;
156                writer.write_u8(*v)?;
157            }
158            Self::HasKey => writer.write_u8(NyarOpcode::HasKey as u8)?,
159            Self::MatchVariant(v) => {
160                writer.write_u8(NyarOpcode::MatchVariant as u8)?;
161                writer.write_u16(*v)?;
162            }
163            Self::SizeOf => writer.write_u8(NyarOpcode::SizeOf as u8)?,
164            Self::TypeOf => writer.write_u8(NyarOpcode::TypeOf as u8)?,
165            Self::InstanceOf(idx) => {
166                writer.write_u8(NyarOpcode::InstanceOf as u8)?;
167                writer.write_u16(*idx)?;
168            }
169            Self::CheckCast(idx) => {
170                writer.write_u8(NyarOpcode::CheckCast as u8)?;
171                writer.write_u16(*idx)?;
172            }
173            Self::Cast(idx) => {
174                writer.write_u8(NyarOpcode::Cast as u8)?;
175                writer.write_u16(*idx)?;
176            }
177            Self::Perform(idx, argc) => {
178                writer.write_u8(NyarOpcode::Perform as u8)?;
179                writer.write_u16(*idx)?;
180                writer.write_u8(*argc)?;
181            }
182            Self::WithHandler(idx) => {
183                writer.write_u8(NyarOpcode::WithHandler as u8)?;
184                writer.write_u16(*idx)?;
185            }
186            Self::ResumeWith => writer.write_u8(NyarOpcode::ResumeWith as u8)?,
187            Self::CaptureCont => writer.write_u8(NyarOpcode::CaptureCont as u8)?,
188            Self::Await => writer.write_u8(NyarOpcode::Await as u8)?,
189            Self::BlockOn => writer.write_u8(NyarOpcode::BlockOn as u8)?,
190            Self::MatchEffect(idx) => {
191                writer.write_u8(NyarOpcode::MatchEffect as u8)?;
192                writer.write_u16(*idx)?;
193            }
194            Self::GetWitnessTable(v1, v2) => {
195                writer.write_u8(NyarOpcode::GetWitnessTable as u8)?;
196                writer.write_u16(*v1)?;
197                writer.write_u16(*v2)?;
198            }
199            Self::WitnessMethod(v) => {
200                writer.write_u8(NyarOpcode::WitnessMethod as u8)?;
201                writer.write_u16(*v)?;
202            }
203            Self::OpenExistential => writer.write_u8(NyarOpcode::OpenExistential as u8)?,
204            Self::CloseExistential => writer.write_u8(NyarOpcode::CloseExistential as u8)?,
205            Self::Quote(v) => {
206                writer.write_u8(NyarOpcode::Quote as u8)?;
207                writer.write_u32(*v)?;
208            }
209            Self::Splice => writer.write_u8(NyarOpcode::Splice as u8)?,
210            Self::Eval(v) => {
211                writer.write_u8(NyarOpcode::Eval as u8)?;
212                writer.write_u8(*v)?;
213            }
214            Self::ExpandMacro(idx, argc) => {
215                writer.write_u8(NyarOpcode::ExpandMacro as u8)?;
216                writer.write_u16(*idx)?;
217                writer.write_u8(*argc)?;
218            }
219            Self::FFICall(idx, argc) => {
220                writer.write_u8(NyarOpcode::FFICall as u8)?;
221                writer.write_u16(*idx)?;
222                writer.write_u8(*argc)?;
223            }
224            Self::Halt => writer.write_u8(NyarOpcode::Halt as u8)?,
225
226            // --- I32 Extensions ---
227            Self::I32Const(v) => {
228                writer.write_u8(NyarOpcode::I32Ext as u8)?;
229                writer.write_u8(0x00)?;
230                writer.write_i32(*v)?;
231            }
232            Self::I32Add => {
233                writer.write_u8(NyarOpcode::I32Ext as u8)?;
234                writer.write_u8(0x01)?;
235            }
236            Self::I32Sub => {
237                writer.write_u8(NyarOpcode::I32Ext as u8)?;
238                writer.write_u8(0x02)?;
239            }
240            Self::I32Mul => {
241                writer.write_u8(NyarOpcode::I32Ext as u8)?;
242                writer.write_u8(0x03)?;
243            }
244            Self::I32DivS => {
245                writer.write_u8(NyarOpcode::I32Ext as u8)?;
246                writer.write_u8(0x04)?;
247            }
248            Self::I32DivU => {
249                writer.write_u8(NyarOpcode::I32Ext as u8)?;
250                writer.write_u8(0x05)?;
251            }
252            Self::I32RemS => {
253                writer.write_u8(NyarOpcode::I32Ext as u8)?;
254                writer.write_u8(0x06)?;
255            }
256            Self::I32RemU => {
257                writer.write_u8(NyarOpcode::I32Ext as u8)?;
258                writer.write_u8(0x07)?;
259            }
260            Self::I32Neg => {
261                writer.write_u8(NyarOpcode::I32Ext as u8)?;
262                writer.write_u8(0x08)?;
263            }
264            Self::I32And => {
265                writer.write_u8(NyarOpcode::I32Ext as u8)?;
266                writer.write_u8(0x09)?;
267            }
268            Self::I32Or => {
269                writer.write_u8(NyarOpcode::I32Ext as u8)?;
270                writer.write_u8(0x0A)?;
271            }
272            Self::I32Xor => {
273                writer.write_u8(NyarOpcode::I32Ext as u8)?;
274                writer.write_u8(0x0B)?;
275            }
276            Self::I32Shl => {
277                writer.write_u8(NyarOpcode::I32Ext as u8)?;
278                writer.write_u8(0x0C)?;
279            }
280            Self::I32ShrS => {
281                writer.write_u8(NyarOpcode::I32Ext as u8)?;
282                writer.write_u8(0x0D)?;
283            }
284            Self::I32ShrU => {
285                writer.write_u8(NyarOpcode::I32Ext as u8)?;
286                writer.write_u8(0x0E)?;
287            }
288            Self::I32Not => {
289                writer.write_u8(NyarOpcode::I32Ext as u8)?;
290                writer.write_u8(0x0F)?;
291            }
292            Self::I32Eq => {
293                writer.write_u8(NyarOpcode::I32Ext as u8)?;
294                writer.write_u8(0x10)?;
295            }
296            Self::I32Ne => {
297                writer.write_u8(NyarOpcode::I32Ext as u8)?;
298                writer.write_u8(0x11)?;
299            }
300            Self::I32LtS => {
301                writer.write_u8(NyarOpcode::I32Ext as u8)?;
302                writer.write_u8(0x12)?;
303            }
304            Self::I32LtU => {
305                writer.write_u8(NyarOpcode::I32Ext as u8)?;
306                writer.write_u8(0x13)?;
307            }
308            Self::I32LeS => {
309                writer.write_u8(NyarOpcode::I32Ext as u8)?;
310                writer.write_u8(0x14)?;
311            }
312            Self::I32LeU => {
313                writer.write_u8(NyarOpcode::I32Ext as u8)?;
314                writer.write_u8(0x15)?;
315            }
316            Self::I32GtS => {
317                writer.write_u8(NyarOpcode::I32Ext as u8)?;
318                writer.write_u8(0x16)?;
319            }
320            Self::I32GtU => {
321                writer.write_u8(NyarOpcode::I32Ext as u8)?;
322                writer.write_u8(0x17)?;
323            }
324            Self::I32GeS => {
325                writer.write_u8(NyarOpcode::I32Ext as u8)?;
326                writer.write_u8(0x18)?;
327            }
328            Self::I32GeU => {
329                writer.write_u8(NyarOpcode::I32Ext as u8)?;
330                writer.write_u8(0x19)?;
331            }
332            Self::I32Extend64S => {
333                writer.write_u8(NyarOpcode::I32Ext as u8)?;
334                writer.write_u8(0x1A)?;
335            }
336            Self::I32Extend64U => {
337                writer.write_u8(NyarOpcode::I32Ext as u8)?;
338                writer.write_u8(0x1B)?;
339            }
340            Self::I32Trunc64SLow => {
341                writer.write_u8(NyarOpcode::I32Ext as u8)?;
342                writer.write_u8(0x1C)?;
343            }
344            Self::I32Trunc64S => {
345                writer.write_u8(NyarOpcode::I32Ext as u8)?;
346                writer.write_u8(0x1D)?;
347            }
348            Self::I32Trunc64U => {
349                writer.write_u8(NyarOpcode::I32Ext as u8)?;
350                writer.write_u8(0x1E)?;
351            }
352            Self::I32ToF32S => {
353                writer.write_u8(NyarOpcode::I32Ext as u8)?;
354                writer.write_u8(0x1F)?;
355            }
356            Self::I32ToF32U => {
357                writer.write_u8(NyarOpcode::I32Ext as u8)?;
358                writer.write_u8(0x20)?;
359            }
360            Self::I32ToF64S => {
361                writer.write_u8(NyarOpcode::I32Ext as u8)?;
362                writer.write_u8(0x21)?;
363            }
364            Self::I32ToF64U => {
365                writer.write_u8(NyarOpcode::I32Ext as u8)?;
366                writer.write_u8(0x22)?;
367            }
368            Self::I32AddSatS => {
369                writer.write_u8(NyarOpcode::I32Ext as u8)?;
370                writer.write_u8(0x23)?;
371            }
372            Self::I32AddSatU => {
373                writer.write_u8(NyarOpcode::I32Ext as u8)?;
374                writer.write_u8(0x24)?;
375            }
376            Self::I32SubSatS => {
377                writer.write_u8(NyarOpcode::I32Ext as u8)?;
378                writer.write_u8(0x25)?;
379            }
380            Self::I32SubSatU => {
381                writer.write_u8(NyarOpcode::I32Ext as u8)?;
382                writer.write_u8(0x26)?;
383            }
384
385            // --- I64 Extensions ---
386            Self::I64Const(v) => {
387                writer.write_u8(NyarOpcode::I64Ext as u8)?;
388                writer.write_u8(0x00)?;
389                writer.write_i64(*v)?;
390            }
391            Self::I64Add => {
392                writer.write_u8(NyarOpcode::I64Ext as u8)?;
393                writer.write_u8(0x01)?;
394            }
395            Self::I64Sub => {
396                writer.write_u8(NyarOpcode::I64Ext as u8)?;
397                writer.write_u8(0x02)?;
398            }
399            Self::I64Mul => {
400                writer.write_u8(NyarOpcode::I64Ext as u8)?;
401                writer.write_u8(0x03)?;
402            }
403            Self::I64DivS => {
404                writer.write_u8(NyarOpcode::I64Ext as u8)?;
405                writer.write_u8(0x04)?;
406            }
407            Self::I64DivU => {
408                writer.write_u8(NyarOpcode::I64Ext as u8)?;
409                writer.write_u8(0x05)?;
410            }
411            Self::I64RemS => {
412                writer.write_u8(NyarOpcode::I64Ext as u8)?;
413                writer.write_u8(0x06)?;
414            }
415            Self::I64RemU => {
416                writer.write_u8(NyarOpcode::I64Ext as u8)?;
417                writer.write_u8(0x07)?;
418            }
419            Self::I64Neg => {
420                writer.write_u8(NyarOpcode::I64Ext as u8)?;
421                writer.write_u8(0x08)?;
422            }
423            Self::I64And => {
424                writer.write_u8(NyarOpcode::I64Ext as u8)?;
425                writer.write_u8(0x09)?;
426            }
427            Self::I64Or => {
428                writer.write_u8(NyarOpcode::I64Ext as u8)?;
429                writer.write_u8(0x0A)?;
430            }
431            Self::I64Xor => {
432                writer.write_u8(NyarOpcode::I64Ext as u8)?;
433                writer.write_u8(0x0B)?;
434            }
435            Self::I64Shl => {
436                writer.write_u8(NyarOpcode::I64Ext as u8)?;
437                writer.write_u8(0x0C)?;
438            }
439            Self::I64ShrS => {
440                writer.write_u8(NyarOpcode::I64Ext as u8)?;
441                writer.write_u8(0x0D)?;
442            }
443            Self::I64ShrU => {
444                writer.write_u8(NyarOpcode::I64Ext as u8)?;
445                writer.write_u8(0x0E)?;
446            }
447            Self::I64Not => {
448                writer.write_u8(NyarOpcode::I64Ext as u8)?;
449                writer.write_u8(0x0F)?;
450            }
451            Self::I64Eq => {
452                writer.write_u8(NyarOpcode::I64Ext as u8)?;
453                writer.write_u8(0x10)?;
454            }
455            Self::I64Ne => {
456                writer.write_u8(NyarOpcode::I64Ext as u8)?;
457                writer.write_u8(0x11)?;
458            }
459            Self::I64LtS => {
460                writer.write_u8(NyarOpcode::I64Ext as u8)?;
461                writer.write_u8(0x12)?;
462            }
463            Self::I64LtU => {
464                writer.write_u8(NyarOpcode::I64Ext as u8)?;
465                writer.write_u8(0x13)?;
466            }
467            Self::I64LeS => {
468                writer.write_u8(NyarOpcode::I64Ext as u8)?;
469                writer.write_u8(0x14)?;
470            }
471            Self::I64LeU => {
472                writer.write_u8(NyarOpcode::I64Ext as u8)?;
473                writer.write_u8(0x15)?;
474            }
475            Self::I64GtS => {
476                writer.write_u8(NyarOpcode::I64Ext as u8)?;
477                writer.write_u8(0x16)?;
478            }
479            Self::I64GtU => {
480                writer.write_u8(NyarOpcode::I64Ext as u8)?;
481                writer.write_u8(0x17)?;
482            }
483            Self::I64GeS => {
484                writer.write_u8(NyarOpcode::I64Ext as u8)?;
485                writer.write_u8(0x18)?;
486            }
487            Self::I64GeU => {
488                writer.write_u8(NyarOpcode::I64Ext as u8)?;
489                writer.write_u8(0x19)?;
490            }
491            Self::I64ToF32S => {
492                writer.write_u8(NyarOpcode::I64Ext as u8)?;
493                writer.write_u8(0x1A)?;
494            }
495            Self::I64ToF32U => {
496                writer.write_u8(NyarOpcode::I64Ext as u8)?;
497                writer.write_u8(0x1B)?;
498            }
499            Self::I64ToF64S => {
500                writer.write_u8(NyarOpcode::I64Ext as u8)?;
501                writer.write_u8(0x1C)?;
502            }
503            Self::I64ToF64U => {
504                writer.write_u8(NyarOpcode::I64Ext as u8)?;
505                writer.write_u8(0x1D)?;
506            }
507            Self::I64AddSatS => {
508                writer.write_u8(NyarOpcode::I64Ext as u8)?;
509                writer.write_u8(0x1E)?;
510            }
511            Self::I64AddSatU => {
512                writer.write_u8(NyarOpcode::I64Ext as u8)?;
513                writer.write_u8(0x1F)?;
514            }
515
516            // --- F32 Extensions ---
517            Self::F32Const(v) => {
518                writer.write_u8(NyarOpcode::F32Ext as u8)?;
519                writer.write_u8(0x00)?;
520                writer.write_f32(*v)?;
521            }
522            Self::F32Add => {
523                writer.write_u8(NyarOpcode::F32Ext as u8)?;
524                writer.write_u8(0x01)?;
525            }
526            Self::F32Sub => {
527                writer.write_u8(NyarOpcode::F32Ext as u8)?;
528                writer.write_u8(0x02)?;
529            }
530            Self::F32Mul => {
531                writer.write_u8(NyarOpcode::F32Ext as u8)?;
532                writer.write_u8(0x03)?;
533            }
534            Self::F32Div => {
535                writer.write_u8(NyarOpcode::F32Ext as u8)?;
536                writer.write_u8(0x04)?;
537            }
538            Self::F32Neg => {
539                writer.write_u8(NyarOpcode::F32Ext as u8)?;
540                writer.write_u8(0x08)?;
541            }
542            Self::F32Eq => {
543                writer.write_u8(NyarOpcode::F32Ext as u8)?;
544                writer.write_u8(0x10)?;
545            }
546            Self::F32Ne => {
547                writer.write_u8(NyarOpcode::F32Ext as u8)?;
548                writer.write_u8(0x11)?;
549            }
550            Self::F32Lt => {
551                writer.write_u8(NyarOpcode::F32Ext as u8)?;
552                writer.write_u8(0x12)?;
553            }
554            Self::F32Le => {
555                writer.write_u8(NyarOpcode::F32Ext as u8)?;
556                writer.write_u8(0x14)?;
557            }
558            Self::F32Gt => {
559                writer.write_u8(NyarOpcode::F32Ext as u8)?;
560                writer.write_u8(0x16)?;
561            }
562            Self::F32Ge => {
563                writer.write_u8(NyarOpcode::F32Ext as u8)?;
564                writer.write_u8(0x18)?;
565            }
566            Self::F32ToI32S => {
567                writer.write_u8(NyarOpcode::F32Ext as u8)?;
568                writer.write_u8(0x1A)?;
569            }
570            Self::F32ToI32U => {
571                writer.write_u8(NyarOpcode::F32Ext as u8)?;
572                writer.write_u8(0x1B)?;
573            }
574            Self::F32ToI64S => {
575                writer.write_u8(NyarOpcode::F32Ext as u8)?;
576                writer.write_u8(0x1C)?;
577            }
578            Self::F32ToI64U => {
579                writer.write_u8(NyarOpcode::F32Ext as u8)?;
580                writer.write_u8(0x1D)?;
581            }
582            Self::F32ToF64 => {
583                writer.write_u8(NyarOpcode::F32Ext as u8)?;
584                writer.write_u8(0x1E)?;
585            }
586
587            // --- F64 Extensions ---
588            Self::F64Const(v) => {
589                writer.write_u8(NyarOpcode::F64Ext as u8)?;
590                writer.write_u8(0x00)?;
591                writer.write_f64(*v)?;
592            }
593            Self::F64Add => {
594                writer.write_u8(NyarOpcode::F64Ext as u8)?;
595                writer.write_u8(0x01)?;
596            }
597            Self::F64Sub => {
598                writer.write_u8(NyarOpcode::F64Ext as u8)?;
599                writer.write_u8(0x02)?;
600            }
601            Self::F64Mul => {
602                writer.write_u8(NyarOpcode::F64Ext as u8)?;
603                writer.write_u8(0x03)?;
604            }
605            Self::F64Div => {
606                writer.write_u8(NyarOpcode::F64Ext as u8)?;
607                writer.write_u8(0x04)?;
608            }
609            Self::F64Neg => {
610                writer.write_u8(NyarOpcode::F64Ext as u8)?;
611                writer.write_u8(0x08)?;
612            }
613            Self::F64Eq => {
614                writer.write_u8(NyarOpcode::F64Ext as u8)?;
615                writer.write_u8(0x10)?;
616            }
617            Self::F64Ne => {
618                writer.write_u8(NyarOpcode::F64Ext as u8)?;
619                writer.write_u8(0x11)?;
620            }
621            Self::F64Lt => {
622                writer.write_u8(NyarOpcode::F64Ext as u8)?;
623                writer.write_u8(0x12)?;
624            }
625            Self::F64Le => {
626                writer.write_u8(NyarOpcode::F64Ext as u8)?;
627                writer.write_u8(0x14)?;
628            }
629            Self::F64Gt => {
630                writer.write_u8(NyarOpcode::F64Ext as u8)?;
631                writer.write_u8(0x16)?;
632            }
633            Self::F64Ge => {
634                writer.write_u8(NyarOpcode::F64Ext as u8)?;
635                writer.write_u8(0x18)?;
636            }
637            Self::F64ToI32S => {
638                writer.write_u8(NyarOpcode::F64Ext as u8)?;
639                writer.write_u8(0x1A)?;
640            }
641            Self::F64ToI32U => {
642                writer.write_u8(NyarOpcode::F64Ext as u8)?;
643                writer.write_u8(0x1B)?;
644            }
645            Self::F64ToI64S => {
646                writer.write_u8(NyarOpcode::F64Ext as u8)?;
647                writer.write_u8(0x1C)?;
648            }
649            Self::F64ToI64U => {
650                writer.write_u8(NyarOpcode::F64Ext as u8)?;
651                writer.write_u8(0x1D)?;
652            }
653            Self::F64ToF32 => {
654                writer.write_u8(NyarOpcode::F64Ext as u8)?;
655                writer.write_u8(0x1E)?;
656            }
657
658            // --- BigInt Extensions ---
659            Self::BigIntConst { sign, bytes } => {
660                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
661                writer.write_u8(0x00)?;
662                writer.write_u8(*sign)?;
663                writer.write_u32(bytes.len() as u32)?;
664                writer.write_bytes(bytes)?;
665            }
666            Self::BigIntAdd => {
667                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
668                writer.write_u8(0x01)?;
669            }
670            Self::BigIntSub => {
671                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
672                writer.write_u8(0x02)?;
673            }
674            Self::BigIntMul => {
675                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
676                writer.write_u8(0x03)?;
677            }
678            Self::BigIntDiv => {
679                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
680                writer.write_u8(0x04)?;
681            }
682            Self::BigIntMod => {
683                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
684                writer.write_u8(0x05)?;
685            }
686            Self::BigIntNeg => {
687                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
688                writer.write_u8(0x08)?;
689            }
690            Self::BigIntEq => {
691                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
692                writer.write_u8(0x10)?;
693            }
694            Self::BigIntNe => {
695                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
696                writer.write_u8(0x11)?;
697            }
698            Self::BigIntLt => {
699                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
700                writer.write_u8(0x12)?;
701            }
702            Self::BigIntLe => {
703                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
704                writer.write_u8(0x14)?;
705            }
706            Self::BigIntGt => {
707                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
708                writer.write_u8(0x16)?;
709            }
710            Self::BigIntGe => {
711                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
712                writer.write_u8(0x18)?;
713            }
714            Self::BigIntToI64 => {
715                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
716                writer.write_u8(0x1A)?;
717            }
718            Self::BigIntFromI64 => {
719                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
720                writer.write_u8(0x1B)?;
721            }
722            Self::BigIntToString => {
723                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
724                writer.write_u8(0x1C)?;
725            }
726
727            // --- String Extensions ---
728            Self::StringConst(s) => {
729                writer.write_u8(NyarOpcode::StringExt as u8)?;
730                writer.write_u8(0x00)?;
731                let bytes = s.as_bytes();
732                writer.write_u32(bytes.len() as u32)?;
733                writer.write_bytes(bytes)?;
734            }
735            Self::StringConcat => {
736                writer.write_u8(NyarOpcode::StringExt as u8)?;
737                writer.write_u8(0x01)?;
738            }
739            Self::StringLenBytes => {
740                writer.write_u8(NyarOpcode::StringExt as u8)?;
741                writer.write_u8(0x02)?;
742            }
743            Self::StringLenChars => {
744                writer.write_u8(NyarOpcode::StringExt as u8)?;
745                writer.write_u8(0x0A)?;
746            }
747            Self::StringEq => {
748                writer.write_u8(NyarOpcode::StringExt as u8)?;
749                writer.write_u8(0x04)?;
750            }
751            Self::StringNe => {
752                writer.write_u8(NyarOpcode::StringExt as u8)?;
753                writer.write_u8(0x05)?;
754            }
755            Self::StringLt => {
756                writer.write_u8(NyarOpcode::StringExt as u8)?;
757                writer.write_u8(0x06)?;
758            }
759            Self::StringLe => {
760                writer.write_u8(NyarOpcode::StringExt as u8)?;
761                writer.write_u8(0x07)?;
762            }
763            Self::StringGt => {
764                writer.write_u8(NyarOpcode::StringExt as u8)?;
765                writer.write_u8(0x08)?;
766            }
767            Self::StringGe => {
768                writer.write_u8(NyarOpcode::StringExt as u8)?;
769                writer.write_u8(0x09)?;
770            }
771            Self::StringSubstr => {
772                writer.write_u8(NyarOpcode::StringExt as u8)?;
773                writer.write_u8(0x03)?;
774            }
775
776            // --- Channel Extensions ---
777            Self::NewChannel(v) => {
778                writer.write_u8(0x57)?;
779                writer.write_u16(*v)?;
780            }
781            Self::SendChannel => {
782                writer.write_u8(0x58)?;
783            }
784            Self::RecvChannel => {
785                writer.write_u8(0x59)?;
786            }
787            Self::SelectChannel(v) => {
788                writer.write_u8(0x5A)?;
789                writer.write_u8(*v)?;
790            }
791
792            // --- Query Extensions ---
793            Self::NewQuery(v) => {
794                writer.write_u8(0x5B)?;
795                writer.write_u16(*v)?;
796            }
797            Self::QueryExec => {
798                writer.write_u8(0x5C)?;
799            }
800
801            // --- Clock Extensions ---
802            Self::NewClock => {
803                writer.write_u8(0x5D)?;
804            }
805            Self::ClockWait => {
806                writer.write_u8(0x5E)?;
807            }
808        }
809        Ok(())
810    }
811
812    fn decode(reader: &mut BinaryReader<Cursor<&[u8]>, Leb128>) -> Result<Self, GaiaError> {
813        let opcode_u8 = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
814        let opcode = match opcode_u8 {
815            0x00 => NyarOpcode::Nop,
816            0x01 => NyarOpcode::Push,
817            0x10 => NyarOpcode::PushNone,
818            0x02 => NyarOpcode::Pop,
819            0x03 => NyarOpcode::Dup,
820            0x04 => NyarOpcode::Swap,
821            0x05 => NyarOpcode::LoadLocal,
822            0x06 => NyarOpcode::StoreLocal,
823            0x07 => NyarOpcode::LoadGlobal,
824            0x08 => NyarOpcode::StoreGlobal,
825            0x09 => NyarOpcode::LoadUpvalue,
826            0x0A => NyarOpcode::StoreUpvalue,
827            0x0B => NyarOpcode::CloseUpvalues,
828            0x0C => NyarOpcode::Jump,
829            0x0D => NyarOpcode::JumpIfFalse,
830            0x0E => NyarOpcode::JumpIfTrue,
831            0x0F => NyarOpcode::JumpIfNull,
832            0x13 => NyarOpcode::Return,
833            0x15 => NyarOpcode::MakeClosure,
834            0x20 => NyarOpcode::Call,
835            0x21 => NyarOpcode::CallVirtual,
836            0x22 => NyarOpcode::CallDynamic,
837            0x23 => NyarOpcode::CallClosure,
838            0x24 => NyarOpcode::InvokeMethod,
839            0x25 => NyarOpcode::CallSymbol,
840            0x30 => NyarOpcode::GetField,
841            0x31 => NyarOpcode::SetField,
842            0x32 => NyarOpcode::NewObject,
843            0x33 => NyarOpcode::NewArray,
844            0x34 => NyarOpcode::GetElement,
845            0x35 => NyarOpcode::SetElement,
846            0x36 => NyarOpcode::MakeTuple,
847            0x37 => NyarOpcode::HasKey,
848            0x38 => NyarOpcode::MatchVariant,
849            0x39 => NyarOpcode::SizeOf,
850            0x3A => NyarOpcode::NewDynObject,
851            0x3B => NyarOpcode::RemoveKey,
852            0x3C => NyarOpcode::NewList,
853            0x3D => NyarOpcode::PushElementLeft,
854            0x3E => NyarOpcode::PopElementLeft,
855            0x3F => NyarOpcode::PushElementRight,
856            0x40 => NyarOpcode::PopElementRight,
857            0x41 => NyarOpcode::TypeOf,
858            0x42 => NyarOpcode::InstanceOf,
859            0x43 => NyarOpcode::CheckCast,
860            0x44 => NyarOpcode::Cast,
861            0x45 => NyarOpcode::Initiate,
862            0x46 => NyarOpcode::Finalize,
863            0x50 => NyarOpcode::Perform,
864            0x51 => NyarOpcode::WithHandler,
865            0x52 => NyarOpcode::ResumeWith,
866            0x53 => NyarOpcode::CaptureCont,
867            0x54 => NyarOpcode::Await,
868            0x55 => NyarOpcode::BlockOn,
869            0x56 => NyarOpcode::MatchEffect,
870            0x60 => NyarOpcode::GetWitnessTable,
871            0x61 => NyarOpcode::WitnessMethod,
872            0x62 => NyarOpcode::OpenExistential,
873            0x63 => NyarOpcode::CloseExistential,
874            0x70 => NyarOpcode::Quote,
875            0x71 => NyarOpcode::Splice,
876            0x72 => NyarOpcode::Eval,
877            0x73 => NyarOpcode::ExpandMacro,
878            0xC1 => NyarOpcode::I32Ext,
879            0xC2 => NyarOpcode::I64Ext,
880            0xC3 => NyarOpcode::F32Ext,
881            0xC4 => NyarOpcode::F64Ext,
882            0xC5 => NyarOpcode::BigIntExt,
883            0xC6 => NyarOpcode::StringExt,
884            0xF0 => NyarOpcode::FFICall,
885            0x14 => NyarOpcode::TailCall,
886            0x16 => NyarOpcode::TailCallClosure,
887            0xFF => NyarOpcode::Halt,
888            0x57 => return Ok(Self::NewChannel(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
889            0x58 => return Ok(Self::SendChannel),
890            0x59 => return Ok(Self::RecvChannel),
891            0x5A => return Ok(Self::SelectChannel(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
892            0x5B => return Ok(Self::NewQuery(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
893            0x5C => return Ok(Self::QueryExec),
894            0x5D => return Ok(Self::NewClock),
895            0x5E => return Ok(Self::ClockWait),
896            _ => return Err(GaiaError::invalid_data(opcode_u8)),
897        };
898
899        match opcode {
900            NyarOpcode::Nop => Ok(Self::Nop),
901            NyarOpcode::Push => Ok(Self::Push(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
902            NyarOpcode::PushNone => Ok(Self::PushNone),
903            NyarOpcode::Pop => Ok(Self::Pop),
904            NyarOpcode::Dup => Ok(Self::Dup(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
905            NyarOpcode::Swap => Ok(Self::Swap(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
906            NyarOpcode::LoadLocal => Ok(Self::LoadLocal(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
907            NyarOpcode::StoreLocal => Ok(Self::StoreLocal(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
908            NyarOpcode::LoadGlobal => Ok(Self::LoadGlobal(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
909            NyarOpcode::StoreGlobal => Ok(Self::StoreGlobal(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
910            NyarOpcode::LoadUpvalue => Ok(Self::LoadUpvalue(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
911            NyarOpcode::StoreUpvalue => Ok(Self::StoreUpvalue(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
912            NyarOpcode::CloseUpvalues => Ok(Self::CloseUpvalues),
913            NyarOpcode::Jump => Ok(Self::Jump(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
914            NyarOpcode::JumpIfFalse => Ok(Self::JumpIfFalse(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
915            NyarOpcode::JumpIfTrue => Ok(Self::JumpIfTrue(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
916            NyarOpcode::JumpIfNull => Ok(Self::JumpIfNull(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
917            NyarOpcode::Return => Ok(Self::Return),
918            NyarOpcode::MakeClosure => {
919                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
920                let count = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))? as usize;
921                let mut ups = Vec::with_capacity(count);
922                for _ in 0..count {
923                    let is_local = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))? != 0;
924                    let index = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
925                    ups.push(NyarUpvalueRef { is_local, index });
926                }
927                Ok(Self::MakeClosure(idx, ups))
928            }
929            NyarOpcode::TailCall => {
930                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
931                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
932                Ok(Self::TailCall(idx, argc))
933            }
934            NyarOpcode::TailCallClosure => {
935                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
936                Ok(Self::TailCallClosure(argc))
937            }
938            NyarOpcode::Call => {
939                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
940                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
941                Ok(Self::Call(idx, argc))
942            }
943            NyarOpcode::CallVirtual => {
944                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
945                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
946                Ok(Self::CallVirtual(idx, argc))
947            }
948            NyarOpcode::CallDynamic => {
949                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
950                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
951                Ok(Self::CallDynamic(idx, argc))
952            }
953            NyarOpcode::CallClosure => {
954                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
955                Ok(Self::CallClosure(argc))
956            }
957            NyarOpcode::InvokeMethod => {
958                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
959                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
960                Ok(Self::InvokeMethod(idx, argc))
961            }
962            NyarOpcode::CallSymbol => {
963                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
964                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
965                Ok(Self::CallSymbol(idx, argc))
966            }
967            NyarOpcode::GetField => Ok(Self::GetField(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
968            NyarOpcode::SetField => Ok(Self::SetField(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
969            NyarOpcode::NewObject => Ok(Self::NewObject(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
970            NyarOpcode::NewArray => Ok(Self::NewArray(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
971            NyarOpcode::GetElement => Ok(Self::GetElement),
972            NyarOpcode::SetElement => Ok(Self::SetElement),
973            NyarOpcode::NewDynObject => Ok(Self::NewDynObject),
974            NyarOpcode::RemoveKey => Ok(Self::RemoveKey),
975            NyarOpcode::Initiate => Ok(Self::Initiate(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
976            NyarOpcode::Finalize => Ok(Self::Finalize),
977            NyarOpcode::NewList => Ok(Self::NewList(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
978            NyarOpcode::PushElementLeft => Ok(Self::PushElementLeft),
979            NyarOpcode::PopElementLeft => Ok(Self::PopElementLeft),
980            NyarOpcode::PushElementRight => Ok(Self::PushElementRight),
981            NyarOpcode::PopElementRight => Ok(Self::PopElementRight),
982            NyarOpcode::MakeTuple => Ok(Self::MakeTuple(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
983            NyarOpcode::HasKey => Ok(Self::HasKey),
984            NyarOpcode::MatchVariant => Ok(Self::MatchVariant(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
985            NyarOpcode::SizeOf => Ok(Self::SizeOf),
986            NyarOpcode::TypeOf => Ok(Self::TypeOf),
987            NyarOpcode::InstanceOf => Ok(Self::InstanceOf(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
988            NyarOpcode::CheckCast => Ok(Self::CheckCast(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
989            NyarOpcode::Cast => Ok(Self::Cast(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
990            NyarOpcode::Perform => {
991                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
992                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
993                Ok(Self::Perform(idx, argc))
994            }
995            NyarOpcode::WithHandler => Ok(Self::WithHandler(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
996            NyarOpcode::ResumeWith => Ok(Self::ResumeWith),
997            NyarOpcode::CaptureCont => Ok(Self::CaptureCont),
998            NyarOpcode::Await => Ok(Self::Await),
999            NyarOpcode::BlockOn => Ok(Self::BlockOn),
1000            NyarOpcode::MatchEffect => Ok(Self::MatchEffect(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1001            NyarOpcode::GetWitnessTable => {
1002                let v1 = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1003                let v2 = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1004                Ok(Self::GetWitnessTable(v1, v2))
1005            }
1006            NyarOpcode::WitnessMethod => Ok(Self::WitnessMethod(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1007            NyarOpcode::OpenExistential => Ok(Self::OpenExistential),
1008            NyarOpcode::CloseExistential => Ok(Self::CloseExistential),
1009            NyarOpcode::Quote => Ok(Self::Quote(reader.read_u32().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1010            NyarOpcode::Splice => Ok(Self::Splice),
1011            NyarOpcode::Eval => Ok(Self::Eval(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1012            NyarOpcode::ExpandMacro => {
1013                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1014                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1015                Ok(Self::ExpandMacro(idx, argc))
1016            }
1017            NyarOpcode::FFICall => {
1018                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1019                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1020                Ok(Self::FFICall(idx, argc))
1021            }
1022            NyarOpcode::Halt => Ok(Self::Halt),
1023            NyarOpcode::I32Ext => {
1024                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1025                match ext {
1026                    0x00 => Ok(Self::I32Const(reader.read_i32().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1027                    0x01 => Ok(Self::I32Add),
1028                    0x02 => Ok(Self::I32Sub),
1029                    0x03 => Ok(Self::I32Mul),
1030                    0x04 => Ok(Self::I32DivS),
1031                    0x05 => Ok(Self::I32DivU),
1032                    0x06 => Ok(Self::I32RemS),
1033                    0x07 => Ok(Self::I32RemU),
1034                    0x08 => Ok(Self::I32Neg),
1035                    0x09 => Ok(Self::I32And),
1036                    0x0A => Ok(Self::I32Or),
1037                    0x0B => Ok(Self::I32Xor),
1038                    0x0C => Ok(Self::I32Shl),
1039                    0x0D => Ok(Self::I32ShrS),
1040                    0x0E => Ok(Self::I32ShrU),
1041                    0x0F => Ok(Self::I32Not),
1042                    0x10 => Ok(Self::I32Eq),
1043                    0x11 => Ok(Self::I32Ne),
1044                    0x12 => Ok(Self::I32LtS),
1045                    0x13 => Ok(Self::I32LtU),
1046                    0x14 => Ok(Self::I32LeS),
1047                    0x15 => Ok(Self::I32LeU),
1048                    0x16 => Ok(Self::I32GtS),
1049                    0x17 => Ok(Self::I32GtU),
1050                    0x18 => Ok(Self::I32GeS),
1051                    0x19 => Ok(Self::I32GeU),
1052                    0x1F => Ok(Self::I32ToF32S),
1053                    0x20 => Ok(Self::I32ToF32U),
1054                    0x21 => Ok(Self::I32ToF64S),
1055                    0x22 => Ok(Self::I32ToF64U),
1056                    0x23 => Ok(Self::I32AddSatS),
1057                    0x24 => Ok(Self::I32AddSatU),
1058                    0x25 => Ok(Self::I32SubSatS),
1059                    0x26 => Ok(Self::I32SubSatU),
1060                    0x1A => Ok(Self::I32Extend64S),
1061                    0x1B => Ok(Self::I32Extend64U),
1062                    0x1C => Ok(Self::I32Trunc64SLow),
1063                    0x1D => Ok(Self::I32Trunc64S),
1064                    0x1E => Ok(Self::I32Trunc64U),
1065                    _ => Err(GaiaError::invalid_data(ext)),
1066                }
1067            }
1068            NyarOpcode::I64Ext => {
1069                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1070                match ext {
1071                    0x00 => Ok(Self::I64Const(reader.read_i64().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1072                    0x01 => Ok(Self::I64Add),
1073                    0x02 => Ok(Self::I64Sub),
1074                    0x03 => Ok(Self::I64Mul),
1075                    0x04 => Ok(Self::I64DivS),
1076                    0x05 => Ok(Self::I64DivU),
1077                    0x06 => Ok(Self::I64RemS),
1078                    0x07 => Ok(Self::I64RemU),
1079                    0x08 => Ok(Self::I64Neg),
1080                    0x09 => Ok(Self::I64And),
1081                    0x0A => Ok(Self::I64Or),
1082                    0x0B => Ok(Self::I64Xor),
1083                    0x0C => Ok(Self::I64Shl),
1084                    0x0D => Ok(Self::I64ShrS),
1085                    0x0E => Ok(Self::I64ShrU),
1086                    0x0F => Ok(Self::I64Not),
1087                    0x10 => Ok(Self::I64Eq),
1088                    0x11 => Ok(Self::I64Ne),
1089                    0x12 => Ok(Self::I64LtS),
1090                    0x13 => Ok(Self::I64LtU),
1091                    0x14 => Ok(Self::I64LeS),
1092                    0x15 => Ok(Self::I64LeU),
1093                    0x16 => Ok(Self::I64GtS),
1094                    0x17 => Ok(Self::I64GtU),
1095                    0x18 => Ok(Self::I64GeS),
1096                    0x19 => Ok(Self::I64GeU),
1097                    0x1A => Ok(Self::I64ToF32S),
1098                    0x1B => Ok(Self::I64ToF32U),
1099                    0x1C => Ok(Self::I64ToF64S),
1100                    0x1D => Ok(Self::I64ToF64U),
1101                    0x1E => Ok(Self::I64AddSatS),
1102                    0x1F => Ok(Self::I64AddSatU),
1103                    _ => Err(GaiaError::invalid_data(ext)),
1104                }
1105            }
1106            NyarOpcode::F32Ext => {
1107                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1108                match ext {
1109                    0x00 => Ok(Self::F32Const(reader.read_f32().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1110                    0x01 => Ok(Self::F32Add),
1111                    0x02 => Ok(Self::F32Sub),
1112                    0x03 => Ok(Self::F32Mul),
1113                    0x04 => Ok(Self::F32Div),
1114                    0x08 => Ok(Self::F32Neg),
1115                    0x10 => Ok(Self::F32Eq),
1116                    0x11 => Ok(Self::F32Ne),
1117                    0x12 => Ok(Self::F32Lt),
1118                    0x14 => Ok(Self::F32Le),
1119                    0x16 => Ok(Self::F32Gt),
1120                    0x18 => Ok(Self::F32Ge),
1121                    0x1A => Ok(Self::F32ToI32S),
1122                    0x1B => Ok(Self::F32ToI32U),
1123                    0x1C => Ok(Self::F32ToI64S),
1124                    0x1D => Ok(Self::F32ToI64U),
1125                    0x1E => Ok(Self::F32ToF64),
1126                    _ => Err(GaiaError::invalid_data(ext)),
1127                }
1128            }
1129            NyarOpcode::F64Ext => {
1130                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1131                match ext {
1132                    0x00 => Ok(Self::F64Const(reader.read_f64().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1133                    0x01 => Ok(Self::F64Add),
1134                    0x02 => Ok(Self::F64Sub),
1135                    0x03 => Ok(Self::F64Mul),
1136                    0x04 => Ok(Self::F64Div),
1137                    0x08 => Ok(Self::F64Neg),
1138                    0x10 => Ok(Self::F64Eq),
1139                    0x11 => Ok(Self::F64Ne),
1140                    0x12 => Ok(Self::F64Lt),
1141                    0x14 => Ok(Self::F64Le),
1142                    0x16 => Ok(Self::F64Gt),
1143                    0x18 => Ok(Self::F64Ge),
1144                    0x1A => Ok(Self::F64ToI32S),
1145                    0x1B => Ok(Self::F64ToI32U),
1146                    0x1C => Ok(Self::F64ToI64S),
1147                    0x1D => Ok(Self::F64ToI64U),
1148                    0x1E => Ok(Self::F64ToF32),
1149                    _ => Err(GaiaError::invalid_data(ext)),
1150                }
1151            }
1152            NyarOpcode::BigIntExt => {
1153                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1154                match ext {
1155                    0x00 => {
1156                        let sign = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1157                        let len = reader.read_u32().map_err(|_| GaiaError::invalid_data("Data truncated"))? as usize;
1158                        let mut bytes = vec![0u8; len];
1159                        for i in 0..len {
1160                            bytes[i] = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1161                        }
1162                        Ok(Self::BigIntConst { sign, bytes })
1163                    }
1164                    0x01 => Ok(Self::BigIntAdd),
1165                    0x02 => Ok(Self::BigIntSub),
1166                    0x03 => Ok(Self::BigIntMul),
1167                    0x04 => Ok(Self::BigIntDiv),
1168                    0x05 => Ok(Self::BigIntMod),
1169                    0x08 => Ok(Self::BigIntNeg),
1170                    0x10 => Ok(Self::BigIntEq),
1171                    0x11 => Ok(Self::BigIntNe),
1172                    0x12 => Ok(Self::BigIntLt),
1173                    0x14 => Ok(Self::BigIntLe),
1174                    0x16 => Ok(Self::BigIntGt),
1175                    0x18 => Ok(Self::BigIntGe),
1176                    0x1A => Ok(Self::BigIntToI64),
1177                    0x1B => Ok(Self::BigIntFromI64),
1178                    0x1C => Ok(Self::BigIntToString),
1179                    _ => Err(GaiaError::invalid_data(ext)),
1180                }
1181            }
1182            NyarOpcode::StringExt => {
1183                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1184                match ext {
1185                    0x00 => {
1186                        let len = reader.read_u32().map_err(|_| GaiaError::invalid_data("Data truncated"))? as usize;
1187                        let mut bytes = vec![0u8; len];
1188                        for i in 0..len {
1189                            bytes[i] = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1190                        }
1191                        let s = String::from_utf8(bytes).map_err(|_| GaiaError::invalid_data("Text parse error"))?;
1192                        Ok(Self::StringConst(s))
1193                    }
1194                    0x01 => Ok(Self::StringConcat),
1195                    0x02 => Ok(Self::StringLenBytes),
1196                    0x03 => Ok(Self::StringSubstr),
1197                    0x04 => Ok(Self::StringEq),
1198                    0x05 => Ok(Self::StringNe),
1199                    0x06 => Ok(Self::StringLt),
1200                    0x07 => Ok(Self::StringLe),
1201                    0x08 => Ok(Self::StringGt),
1202                    0x09 => Ok(Self::StringGe),
1203                    0x0A => Ok(Self::StringLenChars),
1204                    _ => Err(GaiaError::invalid_data(ext)),
1205                }
1206            }
1207            _ => Err(GaiaError::invalid_data(opcode_u8)),
1208        }
1209    }
1210}