Skip to main content

nyar_assembler/program/
instructions.rs

1use gaia_binary::{BinaryReader, BinaryWriter, Leb128};
2use gaia_types::GaiaError;
3use serde::{Deserialize, Serialize};
4use std::io::Cursor;
5
6/// 上值引用
7#[repr(C)]
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub struct NyarUpvalueRef {
10    /// 是否为局部变量
11    pub is_local: bool,
12    /// 索引
13    pub index: u8,
14}
15
16/// Nyar 指令枚举
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub enum NyarInstruction {
19    /// 无操作
20    Nop,
21    /// 入栈常量,参数为常量池索引
22    Push(u16),
23    /// 入栈空值
24    PushNone,
25    /// 栈顶出栈
26    Pop,
27    /// 复制栈顶元素,参数为相对于栈顶的深度
28    Dup(u8),
29    /// 交换栈顶两个元素,参数为相对于栈顶的深度
30    Swap(u8),
31    /// 加载局部变量,参数为局部变量索引
32    LoadLocal(u8),
33    /// 存储局部变量,参数为局部变量索引
34    StoreLocal(u8),
35    /// 加载全局变量,参数为全局变量名索引
36    LoadGlobal(u16),
37    /// 存储全局变量,参数为全局变量名索引
38    StoreGlobal(u16),
39    /// 加载上值,参数为上值索引
40    LoadUpvalue(u8),
41    /// 存储上值,参数为上值索引
42    StoreUpvalue(u8),
43    /// 关闭所有开启的上值
44    CloseUpvalues,
45    /// 无条件跳转,参数为相对偏移量
46    Jump(i16),
47    /// 如果栈顶为假则跳转
48    JumpIfFalse(i16),
49    /// 如果栈顶为真则跳转
50    JumpIfTrue(i16),
51    /// 如果栈顶为空则跳转
52    JumpIfNull(i16),
53    /// 函数返回
54    Return,
55    /// 创建闭包,参数为函数体索引和上值引用列表
56    MakeClosure(u16, Vec<NyarUpvalueRef>),
57    /// 尾递归调用,参数为函数名索引和参数数量
58    TailCall(u16, u8),
59    /// 闭包尾递归调用,参数为参数数量
60    TailCallClosure(u8),
61    /// 函数调用,参数为函数名索引和参数数量
62    Call(u16, u8),
63    /// 虚函数调用,参数为函数名索引和参数数量
64    CallVirtual(u16, u8),
65    /// 动态调用,参数为函数名索引和参数数量
66    CallDynamic(u16, u8),
67    /// 闭包调用,参数为参数数量
68    CallClosure(u8),
69    /// 方法调用,参数为函数名索引和参数数量
70    InvokeMethod(u16, u8),
71    /// 符号调用,参数为符号名索引和参数数量
72    CallSymbol(u16, u8),
73    /// 获取对象字段,参数为字段名索引
74    GetField(u16),
75    /// 设置对象字段,参数为字段名索引
76    SetField(u16),
77    /// 创建新对象,参数为类型名索引
78    NewObject(u16),
79    /// 创建新数组,参数为长度
80    NewArray(u16),
81    /// 获取容器元素
82    GetElement,
83    /// 设置容器元素
84    SetElement,
85    /// 创建动态对象
86    NewDynObject,
87    /// 移除容器中的键
88    RemoveKey,
89    /// 初始化对象
90    Initiate(u8),
91    /// 终止对象生命周期
92    Finalize,
93    /// 创建新列表
94    NewList(u16),
95    /// 元素入队左侧
96    PushElementLeft,
97    /// 元素出队左侧
98    PopElementLeft,
99    /// 元素入队右侧
100    PushElementRight,
101    /// 元素出队右侧
102    PopElementRight,
103    /// 创建元组,参数为元素数量
104    MakeTuple(u8),
105    /// Check if key exists
106    HasKey,
107    /// Match enum variant
108    MatchVariant(u16),
109    /// Get container size
110    SizeOf,
111    /// Get element type
112    TypeOf,
113    /// Check if value is instance of type
114    InstanceOf(u16),
115    /// Check type cast validity
116    CheckCast(u16),
117    /// Perform type cast
118    Cast(u16),
119    /// Perform side effect
120    Perform(u16, u8),
121    /// Register side effect handler
122    WithHandler(u16),
123    /// Resume continuation
124    ResumeWith,
125    /// Capture continuation
126    CaptureCont,
127    /// Await async operation
128    Await,
129    /// Blocking await async operation
130    BlockOn,
131    /// Match side effect result
132    MatchEffect(u16),
133    /// Get vtable index
134    GetWitnessTable(u16, u16),
135    /// Call vtable method
136    WitnessMethod(u16),
137    /// Open existential type
138    OpenExistential,
139    /// Close existential type
140    CloseExistential,
141    /// Reference LIR code block
142    Quote(u32),
143    /// Splice LIR expression
144    Splice,
145    /// Evaluate LIR expression
146    Eval(u8),
147    /// Expand macro
148    ExpandMacro(u16, u8),
149    /// FFI call
150    FFICall(u16, u8),
151    /// Halt execution
152    Halt,
153
154    // --- Arithmetic and Logic Extensions ---
155    /// I32 constant
156    I32Const(i32),
157    /// I32 addition
158    I32Add,
159    /// I32 subtraction
160    I32Sub,
161    /// I32 multiplication
162    I32Mul,
163    /// I32 signed division
164    I32DivS,
165    /// I32 unsigned division
166    I32DivU,
167    /// I32 signed remainder
168    I32RemS,
169    /// I32 unsigned remainder
170    I32RemU,
171    /// I32 bitwise AND
172    I32And,
173    /// I32 bitwise OR
174    I32Or,
175    /// I32 bitwise XOR
176    I32Xor,
177    /// I32 left shift
178    I32Shl,
179    /// I32 signed right shift
180    I32ShrS,
181    /// I32 unsigned right shift
182    I32ShrU,
183    /// I32 bitwise NOT
184    I32Not,
185    /// I32 negate
186    I32Neg,
187    /// I32 equal
188    I32Eq,
189    /// I32 not equal
190    I32Ne,
191    /// I32 signed less than
192    I32LtS,
193    /// I32 unsigned less than
194    I32LtU,
195    /// I32 signed less than or equal
196    I32LeS,
197    /// I32 unsigned less than or equal
198    I32LeU,
199    /// I32 signed greater than
200    I32GtS,
201    /// I32 unsigned greater than
202    I32GtU,
203    /// I32 signed greater than or equal
204    I32GeS,
205    /// I32 unsigned greater than or equal
206    I32GeU,
207    /// I32 to F32 (signed)
208    I32ToF32S,
209    /// I32 to F32 (unsigned)
210    I32ToF32U,
211    /// I32 to F64 (signed)
212    I32ToF64S,
213    /// I32 to F64 (unsigned)
214    I32ToF64U,
215    /// I32 addition (saturated signed)
216    I32AddSatS,
217    /// I32 addition (saturated unsigned)
218    I32AddSatU,
219    /// I32 subtraction (saturated signed)
220    I32SubSatS,
221    /// I32 subtraction (saturated unsigned)
222    I32SubSatU,
223    /// I32 sign extend to I64
224    I32Extend64S,
225    /// I32 zero extend to I64
226    I32Extend64U,
227    /// I32 truncate I64 (low)
228    I32Trunc64SLow,
229    /// I32 truncate I64 (signed)
230    I32Trunc64S,
231    /// I32 truncate I64 (unsigned)
232    I32Trunc64U,
233
234    /// I64 常量
235    I64Const(i64),
236    /// I64 加法
237    I64Add,
238    /// I64 减法
239    I64Sub,
240    /// I64 乘法
241    I64Mul,
242    /// I64 有符号除法
243    I64DivS,
244    /// I64 无符号除法
245    I64DivU,
246    /// I64 有符号取模
247    I64RemS,
248    /// I64 无符号取模
249    I64RemU,
250    /// I64 按位与
251    I64And,
252    /// I64 按位或
253    I64Or,
254    /// I64 按位异或
255    I64Xor,
256    /// I64 左移
257    I64Shl,
258    /// I64 有符号右移
259    I64ShrS,
260    /// I64 无符号右移
261    I64ShrU,
262    /// I64 按位取反
263    I64Not,
264    /// I64 取负
265    I64Neg,
266    /// I64 等于
267    I64Eq,
268    /// I64 不等于
269    I64Ne,
270    /// I64 有符号小于
271    I64LtS,
272    /// I64 无符号小于
273    I64LtU,
274    /// I64 有符号小于等于
275    I64LeS,
276    /// I64 无符号小于等于
277    I64LeU,
278    /// I64 有符号大于
279    I64GtS,
280    /// I64 无符号大于
281    I64GtU,
282    /// I64 有符号大于等于
283    I64GeS,
284    /// I64 无符号大于等于
285    I64GeU,
286    /// I64 转 F32 (有符号)
287    I64ToF32S,
288    /// I64 转 F32 (无符号)
289    I64ToF32U,
290    /// I64 转 F64 (有符号)
291    I64ToF64S,
292    /// I64 转 F64 (无符号)
293    I64ToF64U,
294    /// I64 加法 (饱和有符号)
295    I64AddSatS,
296    /// I64 加法 (饱和无符号)
297    I64AddSatU,
298
299    /// F32 常量
300    F32Const(f32),
301    /// F32 加法
302    F32Add,
303    /// F32 减法
304    F32Sub,
305    /// F32 乘法
306    F32Mul,
307    /// F32 除法
308    F32Div,
309    /// F32 取负
310    F32Neg,
311    /// F32 等于
312    F32Eq,
313    /// F32 不等于
314    F32Ne,
315    /// F32 小于
316    F32Lt,
317    /// F32 小于等于
318    F32Le,
319    /// F32 大于
320    F32Gt,
321    /// F32 大于等于
322    F32Ge,
323    /// F32 转 I32 (有符号)
324    F32ToI32S,
325    /// F32 转 I32 (无符号)
326    F32ToI32U,
327    /// F32 转 I64 (有符号)
328    F32ToI64S,
329    /// F32 转 I64 (无符号)
330    F32ToI64U,
331    /// F32 转 F64
332    F32ToF64,
333
334    /// F64 常量
335    F64Const(f64),
336    /// F64 加法
337    F64Add,
338    /// F64 减法
339    F64Sub,
340    /// F64 乘法
341    F64Mul,
342    /// F64 除法
343    F64Div,
344    /// F64 取负
345    F64Neg,
346    /// F64 等于
347    F64Eq,
348    /// F64 不等于
349    F64Ne,
350    /// F64 小于
351    F64Lt,
352    /// F64 小于等于
353    F64Le,
354    /// F64 大于
355    F64Gt,
356    /// F64 大于等于
357    F64Ge,
358    /// F64 转 I32 (有符号)
359    F64ToI32S,
360    /// F64 转 I32 (无符号)
361    F64ToI32U,
362    /// F64 转 I64 (有符号)
363    F64ToI64S,
364    /// F64 转 I64 (无符号)
365    F64ToI64U,
366    /// F64 转 F32
367    F64ToF32,
368
369    /// 大整数常量
370    BigIntConst {
371        /// 符号 (0: 正, 1: 负)
372        sign: u8,
373        /// 原始字节数据
374        bytes: Vec<u8>,
375    },
376    /// 大整数加法
377    BigIntAdd,
378    /// 大整数减法
379    BigIntSub,
380    /// 大整数乘法
381    BigIntMul,
382    /// 大整数除法
383    BigIntDiv,
384    /// 大整数取模
385    BigIntMod,
386    /// 大整数取负
387    BigIntNeg,
388    /// 大整数等于
389    BigIntEq,
390    /// 大整数不等于
391    BigIntNe,
392    /// 大整数小于
393    BigIntLt,
394    /// 大整数小于等于
395    BigIntLe,
396    /// 大整数大于
397    BigIntGt,
398    /// 大整数大于等于
399    BigIntGe,
400    /// 大整数转 I64
401    BigIntToI64,
402    /// I64 转 大整数
403    BigIntFromI64,
404    /// 大整数转字符串
405    BigIntToString,
406
407    /// 字符串常量
408    StringConst(String),
409    /// 字符串拼接
410    StringConcat,
411    /// 字符串长度 (字节)
412    StringLenBytes,
413    /// 字符串长度 (字符)
414    StringLenChars,
415    /// 字符串等于
416    StringEq,
417    /// 字符串不等于
418    StringNe,
419    /// 字符串小于
420    StringLt,
421    /// 字符串小于等于
422    StringLe,
423    /// 字符串大于
424    StringGt,
425    /// 字符串大于等于
426    StringGe,
427    /// 字符串截取
428    StringSubstr,
429
430    /// 新建通道
431    NewChannel(u16),
432    /// 发送通道消息
433    SendChannel,
434    /// 接收通道消息
435    RecvChannel,
436    /// 选择通道
437    SelectChannel(u8),
438    /// 新建查询
439    NewQuery(u16),
440    /// 执行查询
441    QueryExec,
442    /// 新建时钟
443    NewClock,
444    /// 时钟等待
445    ClockWait,
446}
447
448/// Nyar 操作码枚举
449#[repr(u8)]
450#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
451pub enum NyarOpcode {
452    /// 无操作
453    Nop = 0x00,
454    /// 入栈
455    Push = 0x01,
456    /// 出栈
457    Pop = 0x02,
458    /// 复制栈顶
459    Dup = 0x03,
460    /// 交换栈顶
461    Swap = 0x04,
462    /// 加载局部变量
463    LoadLocal = 0x05,
464    /// 存储局部变量
465    StoreLocal = 0x06,
466    /// 加载全局变量
467    LoadGlobal = 0x07,
468    /// 存储全局变量
469    StoreGlobal = 0x08,
470    /// 加载上值 (Upvalue)
471    LoadUpvalue = 0x09,
472    /// 存储上值 (Upvalue)
473    StoreUpvalue = 0x0A,
474    /// 关闭上值
475    CloseUpvalues = 0x0B,
476    /// 无条件跳转
477    Jump = 0x0C,
478    /// 为假时跳转
479    JumpIfFalse = 0x0D,
480    /// 为真时跳转
481    JumpIfTrue = 0x0E,
482    /// 为空时跳转
483    JumpIfNull = 0x0F,
484    /// 入栈空值
485    PushNone = 0x10,
486    /// 返回
487    Return = 0x13,
488    /// 创建闭包
489    MakeClosure = 0x15,
490
491    /// 函数调用
492    Call = 0x20,
493    /// 虚函数调用
494    CallVirtual = 0x21,
495    /// 动态调用
496    CallDynamic = 0x22,
497    /// 闭包调用
498    CallClosure = 0x23,
499    /// 方法调用
500    InvokeMethod = 0x24,
501    /// 符号调用
502    CallSymbol = 0x25,
503    /// FFI 调用
504    FFICall = 0xF0,
505    /// 尾调用
506    TailCall = 0x14,
507    /// 闭包尾调用
508    TailCallClosure = 0x16,
509
510    /// 获取字段
511    GetField = 0x30,
512    /// 设置字段
513    SetField = 0x31,
514    /// 创建对象
515    NewObject = 0x32,
516    /// 创建数组
517    NewArray = 0x33,
518    /// 获取元素
519    GetElement = 0x34,
520    /// 设置元素
521    SetElement = 0x35,
522    /// 创建元组
523    MakeTuple = 0x36,
524    /// 是否存在键
525    HasKey = 0x37,
526    /// 匹配变体
527    MatchVariant = 0x38,
528    /// 获取大小
529    SizeOf = 0x39,
530    /// 创建动态对象
531    NewDynObject = 0x3A,
532    /// 移除键
533    RemoveKey = 0x3B,
534    /// 创建列表
535    NewList = 0x3C,
536    /// 左侧入队
537    PushElementLeft = 0x3D,
538    /// 左侧出队
539    PopElementLeft = 0x3E,
540    /// 元素入队右侧
541    PushElementRight = 0x3F,
542    /// 元素出队右侧
543    PopElementRight = 0x40,
544    /// 获取类型
545    TypeOf = 0x41,
546    /// 类型实例判断
547    InstanceOf = 0x42,
548    /// 检查转换
549    CheckCast = 0x43,
550    /// 类型转换
551    Cast = 0x44,
552    /// 初始化
553    Initiate = 0x45,
554    /// 终止
555    Finalize = 0x46,
556    /// 执行副作用 (Effect)
557    Perform = 0x50,
558    /// 注册副作用处理器
559    WithHandler = 0x51,
560    /// 继续副作用执行
561    ResumeWith = 0x52,
562    /// 捕获延续 (Continuation)
563    CaptureCont = 0x53,
564    /// 等待 (Await)
565    Await = 0x54,
566    /// 阻塞等待 (BlockOn)
567    BlockOn = 0x55,
568    /// 匹配副作用
569    MatchEffect = 0x56,
570    /// 获取虚表
571    GetWitnessTable = 0x60,
572    /// 虚表方法调用
573    WitnessMethod = 0x61,
574    /// 打开存在类型
575    OpenExistential = 0x62,
576    /// 关闭存在类型
577    CloseExistential = 0x63,
578    /// 引用 (Quote)
579    Quote = 0x70,
580    /// 拼接 (Splice)
581    Splice = 0x71,
582    /// 求值 (Eval)
583    Eval = 0x72,
584    /// 宏展开
585    ExpandMacro = 0x73,
586
587    /// 新建通道
588    NewChannel = 0x57,
589    /// 发送通道消息
590    SendChannel = 0x58,
591    /// 接收通道消息
592    RecvChannel = 0x59,
593    /// 选择通道
594    SelectChannel = 0x5A,
595    /// 新建查询
596    NewQuery = 0x5B,
597    /// 执行查询
598    QueryExec = 0x5C,
599    /// 新建时钟
600    NewClock = 0x5D,
601    /// 时钟等待
602    ClockWait = 0x5E,
603
604    /// I32 扩展指令
605    I32Ext = 0xC1,
606    /// I64 扩展指令
607    I64Ext = 0xC2,
608    /// F32 扩展指令
609    F32Ext = 0xC3,
610    /// F64 扩展指令
611    F64Ext = 0xC4,
612    /// 大整数扩展指令
613    BigIntExt = 0xC5,
614    /// 字符串扩展指令
615    StringExt = 0xC6,
616
617    /// 停机
618    Halt = 0xFF,
619}
620
621/// Codec trait for Nyar instructions
622pub trait NyarCodec: Sized {
623    /// Encode to binary stream
624    fn encode(&self, writer: &mut BinaryWriter<Vec<u8>, Leb128>) -> Result<(), GaiaError>;
625    /// Decode from binary stream
626    fn decode(reader: &mut BinaryReader<Cursor<&[u8]>, Leb128>) -> Result<Self, GaiaError>;
627}
628
629impl NyarCodec for NyarInstruction {
630    fn encode(&self, writer: &mut BinaryWriter<Vec<u8>, Leb128>) -> Result<(), GaiaError> {
631        match self {
632            Self::Nop => writer.write_u8(NyarOpcode::Nop as u8)?,
633            Self::Push(v) => {
634                writer.write_u8(NyarOpcode::Push as u8)?;
635                writer.write_u16(*v)?;
636            }
637            Self::PushNone => writer.write_u8(NyarOpcode::PushNone as u8)?,
638            Self::Pop => writer.write_u8(NyarOpcode::Pop as u8)?,
639            Self::Dup(v) => {
640                writer.write_u8(NyarOpcode::Dup as u8)?;
641                writer.write_u8(*v)?;
642            }
643            Self::Swap(v) => {
644                writer.write_u8(NyarOpcode::Swap as u8)?;
645                writer.write_u8(*v)?;
646            }
647            Self::LoadLocal(v) => {
648                writer.write_u8(NyarOpcode::LoadLocal as u8)?;
649                writer.write_u8(*v)?;
650            }
651            Self::StoreLocal(v) => {
652                writer.write_u8(NyarOpcode::StoreLocal as u8)?;
653                writer.write_u8(*v)?;
654            }
655            Self::LoadGlobal(v) => {
656                writer.write_u8(NyarOpcode::LoadGlobal as u8)?;
657                writer.write_u16(*v)?;
658            }
659            Self::StoreGlobal(v) => {
660                writer.write_u8(NyarOpcode::StoreGlobal as u8)?;
661                writer.write_u16(*v)?;
662            }
663            Self::LoadUpvalue(v) => {
664                writer.write_u8(NyarOpcode::LoadUpvalue as u8)?;
665                writer.write_u8(*v)?;
666            }
667            Self::StoreUpvalue(v) => {
668                writer.write_u8(NyarOpcode::StoreUpvalue as u8)?;
669                writer.write_u8(*v)?;
670            }
671            Self::CloseUpvalues => writer.write_u8(NyarOpcode::CloseUpvalues as u8)?,
672            Self::Jump(v) => {
673                writer.write_u8(NyarOpcode::Jump as u8)?;
674                writer.write_i16(*v)?;
675            }
676            Self::JumpIfFalse(v) => {
677                writer.write_u8(NyarOpcode::JumpIfFalse as u8)?;
678                writer.write_i16(*v)?;
679            }
680            Self::JumpIfTrue(v) => {
681                writer.write_u8(NyarOpcode::JumpIfTrue as u8)?;
682                writer.write_i16(*v)?;
683            }
684            Self::JumpIfNull(v) => {
685                writer.write_u8(NyarOpcode::JumpIfNull as u8)?;
686                writer.write_i16(*v)?;
687            }
688            Self::Return => writer.write_u8(NyarOpcode::Return as u8)?,
689            Self::MakeClosure(idx, ups) => {
690                writer.write_u8(NyarOpcode::MakeClosure as u8)?;
691                writer.write_u16(*idx)?;
692                writer.write_u8(ups.len() as u8)?;
693                for up in ups {
694                    writer.write_u8(if up.is_local { 1 } else { 0 })?;
695                    writer.write_u8(up.index)?;
696                }
697            }
698            Self::TailCall(idx, argc) => {
699                writer.write_u8(NyarOpcode::TailCall as u8)?;
700                writer.write_u16(*idx)?;
701                writer.write_u8(*argc)?;
702            }
703            Self::TailCallClosure(argc) => {
704                writer.write_u8(NyarOpcode::TailCallClosure as u8)?;
705                writer.write_u8(*argc)?;
706            }
707            Self::Call(idx, argc) => {
708                writer.write_u8(NyarOpcode::Call as u8)?;
709                writer.write_u16(*idx)?;
710                writer.write_u8(*argc)?;
711            }
712            Self::CallVirtual(idx, argc) => {
713                writer.write_u8(NyarOpcode::CallVirtual as u8)?;
714                writer.write_u16(*idx)?;
715                writer.write_u8(*argc)?;
716            }
717            Self::CallDynamic(idx, argc) => {
718                writer.write_u8(NyarOpcode::CallDynamic as u8)?;
719                writer.write_u16(*idx)?;
720                writer.write_u8(*argc)?;
721            }
722            Self::CallClosure(argc) => {
723                writer.write_u8(NyarOpcode::CallClosure as u8)?;
724                writer.write_u8(*argc)?;
725            }
726            Self::InvokeMethod(idx, argc) => {
727                writer.write_u8(NyarOpcode::InvokeMethod as u8)?;
728                writer.write_u16(*idx)?;
729                writer.write_u8(*argc)?;
730            }
731            Self::CallSymbol(idx, argc) => {
732                writer.write_u8(NyarOpcode::CallSymbol as u8)?;
733                writer.write_u16(*idx)?;
734                writer.write_u8(*argc)?;
735            }
736            Self::GetField(idx) => {
737                writer.write_u8(NyarOpcode::GetField as u8)?;
738                writer.write_u16(*idx)?;
739            }
740            Self::SetField(idx) => {
741                writer.write_u8(NyarOpcode::SetField as u8)?;
742                writer.write_u16(*idx)?;
743            }
744            Self::NewObject(idx) => {
745                writer.write_u8(NyarOpcode::NewObject as u8)?;
746                writer.write_u16(*idx)?;
747            }
748            Self::NewArray(len) => {
749                writer.write_u8(NyarOpcode::NewArray as u8)?;
750                writer.write_u16(*len)?;
751            }
752            Self::GetElement => writer.write_u8(NyarOpcode::GetElement as u8)?,
753            Self::SetElement => writer.write_u8(NyarOpcode::SetElement as u8)?,
754            Self::NewDynObject => writer.write_u8(NyarOpcode::NewDynObject as u8)?,
755            Self::RemoveKey => writer.write_u8(NyarOpcode::RemoveKey as u8)?,
756            Self::Initiate(v) => {
757                writer.write_u8(NyarOpcode::Initiate as u8)?;
758                writer.write_u8(*v)?;
759            }
760            Self::Finalize => writer.write_u8(NyarOpcode::Finalize as u8)?,
761            Self::NewList(len) => {
762                writer.write_u8(NyarOpcode::NewList as u8)?;
763                writer.write_u16(*len)?;
764            }
765            Self::PushElementLeft => writer.write_u8(NyarOpcode::PushElementLeft as u8)?,
766            Self::PopElementLeft => writer.write_u8(NyarOpcode::PopElementLeft as u8)?,
767            Self::PushElementRight => writer.write_u8(NyarOpcode::PushElementRight as u8)?,
768            Self::PopElementRight => writer.write_u8(NyarOpcode::PopElementRight as u8)?,
769            Self::MakeTuple(v) => {
770                writer.write_u8(NyarOpcode::MakeTuple as u8)?;
771                writer.write_u8(*v)?;
772            }
773            Self::HasKey => writer.write_u8(NyarOpcode::HasKey as u8)?,
774            Self::MatchVariant(v) => {
775                writer.write_u8(NyarOpcode::MatchVariant as u8)?;
776                writer.write_u16(*v)?;
777            }
778            Self::SizeOf => writer.write_u8(NyarOpcode::SizeOf as u8)?,
779            Self::TypeOf => writer.write_u8(NyarOpcode::TypeOf as u8)?,
780            Self::InstanceOf(idx) => {
781                writer.write_u8(NyarOpcode::InstanceOf as u8)?;
782                writer.write_u16(*idx)?;
783            }
784            Self::CheckCast(idx) => {
785                writer.write_u8(NyarOpcode::CheckCast as u8)?;
786                writer.write_u16(*idx)?;
787            }
788            Self::Cast(idx) => {
789                writer.write_u8(NyarOpcode::Cast as u8)?;
790                writer.write_u16(*idx)?;
791            }
792            Self::Perform(idx, argc) => {
793                writer.write_u8(NyarOpcode::Perform as u8)?;
794                writer.write_u16(*idx)?;
795                writer.write_u8(*argc)?;
796            }
797            Self::WithHandler(idx) => {
798                writer.write_u8(NyarOpcode::WithHandler as u8)?;
799                writer.write_u16(*idx)?;
800            }
801            Self::ResumeWith => writer.write_u8(NyarOpcode::ResumeWith as u8)?,
802            Self::CaptureCont => writer.write_u8(NyarOpcode::CaptureCont as u8)?,
803            Self::Await => writer.write_u8(NyarOpcode::Await as u8)?,
804            Self::BlockOn => writer.write_u8(NyarOpcode::BlockOn as u8)?,
805            Self::MatchEffect(idx) => {
806                writer.write_u8(NyarOpcode::MatchEffect as u8)?;
807                writer.write_u16(*idx)?;
808            }
809            Self::GetWitnessTable(v1, v2) => {
810                writer.write_u8(NyarOpcode::GetWitnessTable as u8)?;
811                writer.write_u16(*v1)?;
812                writer.write_u16(*v2)?;
813            }
814            Self::WitnessMethod(v) => {
815                writer.write_u8(NyarOpcode::WitnessMethod as u8)?;
816                writer.write_u16(*v)?;
817            }
818            Self::OpenExistential => writer.write_u8(NyarOpcode::OpenExistential as u8)?,
819            Self::CloseExistential => writer.write_u8(NyarOpcode::CloseExistential as u8)?,
820            Self::Quote(v) => {
821                writer.write_u8(NyarOpcode::Quote as u8)?;
822                writer.write_u32(*v)?;
823            }
824            Self::Splice => writer.write_u8(NyarOpcode::Splice as u8)?,
825            Self::Eval(v) => {
826                writer.write_u8(NyarOpcode::Eval as u8)?;
827                writer.write_u8(*v)?;
828            }
829            Self::ExpandMacro(idx, argc) => {
830                writer.write_u8(NyarOpcode::ExpandMacro as u8)?;
831                writer.write_u16(*idx)?;
832                writer.write_u8(*argc)?;
833            }
834            Self::FFICall(idx, argc) => {
835                writer.write_u8(NyarOpcode::FFICall as u8)?;
836                writer.write_u16(*idx)?;
837                writer.write_u8(*argc)?;
838            }
839            Self::Halt => writer.write_u8(NyarOpcode::Halt as u8)?,
840
841            // --- I32 Extensions ---
842            Self::I32Const(v) => {
843                writer.write_u8(NyarOpcode::I32Ext as u8)?;
844                writer.write_u8(0x00)?;
845                writer.write_i32(*v)?;
846            }
847            Self::I32Add => {
848                writer.write_u8(NyarOpcode::I32Ext as u8)?;
849                writer.write_u8(0x01)?;
850            }
851            Self::I32Sub => {
852                writer.write_u8(NyarOpcode::I32Ext as u8)?;
853                writer.write_u8(0x02)?;
854            }
855            Self::I32Mul => {
856                writer.write_u8(NyarOpcode::I32Ext as u8)?;
857                writer.write_u8(0x03)?;
858            }
859            Self::I32DivS => {
860                writer.write_u8(NyarOpcode::I32Ext as u8)?;
861                writer.write_u8(0x04)?;
862            }
863            Self::I32DivU => {
864                writer.write_u8(NyarOpcode::I32Ext as u8)?;
865                writer.write_u8(0x05)?;
866            }
867            Self::I32RemS => {
868                writer.write_u8(NyarOpcode::I32Ext as u8)?;
869                writer.write_u8(0x06)?;
870            }
871            Self::I32RemU => {
872                writer.write_u8(NyarOpcode::I32Ext as u8)?;
873                writer.write_u8(0x07)?;
874            }
875            Self::I32Neg => {
876                writer.write_u8(NyarOpcode::I32Ext as u8)?;
877                writer.write_u8(0x08)?;
878            }
879            Self::I32And => {
880                writer.write_u8(NyarOpcode::I32Ext as u8)?;
881                writer.write_u8(0x09)?;
882            }
883            Self::I32Or => {
884                writer.write_u8(NyarOpcode::I32Ext as u8)?;
885                writer.write_u8(0x0A)?;
886            }
887            Self::I32Xor => {
888                writer.write_u8(NyarOpcode::I32Ext as u8)?;
889                writer.write_u8(0x0B)?;
890            }
891            Self::I32Shl => {
892                writer.write_u8(NyarOpcode::I32Ext as u8)?;
893                writer.write_u8(0x0C)?;
894            }
895            Self::I32ShrS => {
896                writer.write_u8(NyarOpcode::I32Ext as u8)?;
897                writer.write_u8(0x0D)?;
898            }
899            Self::I32ShrU => {
900                writer.write_u8(NyarOpcode::I32Ext as u8)?;
901                writer.write_u8(0x0E)?;
902            }
903            Self::I32Not => {
904                writer.write_u8(NyarOpcode::I32Ext as u8)?;
905                writer.write_u8(0x0F)?;
906            }
907            Self::I32Eq => {
908                writer.write_u8(NyarOpcode::I32Ext as u8)?;
909                writer.write_u8(0x10)?;
910            }
911            Self::I32Ne => {
912                writer.write_u8(NyarOpcode::I32Ext as u8)?;
913                writer.write_u8(0x11)?;
914            }
915            Self::I32LtS => {
916                writer.write_u8(NyarOpcode::I32Ext as u8)?;
917                writer.write_u8(0x12)?;
918            }
919            Self::I32LtU => {
920                writer.write_u8(NyarOpcode::I32Ext as u8)?;
921                writer.write_u8(0x13)?;
922            }
923            Self::I32LeS => {
924                writer.write_u8(NyarOpcode::I32Ext as u8)?;
925                writer.write_u8(0x14)?;
926            }
927            Self::I32LeU => {
928                writer.write_u8(NyarOpcode::I32Ext as u8)?;
929                writer.write_u8(0x15)?;
930            }
931            Self::I32GtS => {
932                writer.write_u8(NyarOpcode::I32Ext as u8)?;
933                writer.write_u8(0x16)?;
934            }
935            Self::I32GtU => {
936                writer.write_u8(NyarOpcode::I32Ext as u8)?;
937                writer.write_u8(0x17)?;
938            }
939            Self::I32GeS => {
940                writer.write_u8(NyarOpcode::I32Ext as u8)?;
941                writer.write_u8(0x18)?;
942            }
943            Self::I32GeU => {
944                writer.write_u8(NyarOpcode::I32Ext as u8)?;
945                writer.write_u8(0x19)?;
946            }
947            Self::I32Extend64S => {
948                writer.write_u8(NyarOpcode::I32Ext as u8)?;
949                writer.write_u8(0x1A)?;
950            }
951            Self::I32Extend64U => {
952                writer.write_u8(NyarOpcode::I32Ext as u8)?;
953                writer.write_u8(0x1B)?;
954            }
955            Self::I32Trunc64SLow => {
956                writer.write_u8(NyarOpcode::I32Ext as u8)?;
957                writer.write_u8(0x1C)?;
958            }
959            Self::I32Trunc64S => {
960                writer.write_u8(NyarOpcode::I32Ext as u8)?;
961                writer.write_u8(0x1D)?;
962            }
963            Self::I32Trunc64U => {
964                writer.write_u8(NyarOpcode::I32Ext as u8)?;
965                writer.write_u8(0x1E)?;
966            }
967            Self::I32ToF32S => {
968                writer.write_u8(NyarOpcode::I32Ext as u8)?;
969                writer.write_u8(0x1F)?;
970            }
971            Self::I32ToF32U => {
972                writer.write_u8(NyarOpcode::I32Ext as u8)?;
973                writer.write_u8(0x20)?;
974            }
975            Self::I32ToF64S => {
976                writer.write_u8(NyarOpcode::I32Ext as u8)?;
977                writer.write_u8(0x21)?;
978            }
979            Self::I32ToF64U => {
980                writer.write_u8(NyarOpcode::I32Ext as u8)?;
981                writer.write_u8(0x22)?;
982            }
983            Self::I32AddSatS => {
984                writer.write_u8(NyarOpcode::I32Ext as u8)?;
985                writer.write_u8(0x23)?;
986            }
987            Self::I32AddSatU => {
988                writer.write_u8(NyarOpcode::I32Ext as u8)?;
989                writer.write_u8(0x24)?;
990            }
991            Self::I32SubSatS => {
992                writer.write_u8(NyarOpcode::I32Ext as u8)?;
993                writer.write_u8(0x25)?;
994            }
995            Self::I32SubSatU => {
996                writer.write_u8(NyarOpcode::I32Ext as u8)?;
997                writer.write_u8(0x26)?;
998            }
999
1000            // --- I64 Extensions ---
1001            Self::I64Const(v) => {
1002                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1003                writer.write_u8(0x00)?;
1004                writer.write_i64(*v)?;
1005            }
1006            Self::I64Add => {
1007                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1008                writer.write_u8(0x01)?;
1009            }
1010            Self::I64Sub => {
1011                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1012                writer.write_u8(0x02)?;
1013            }
1014            Self::I64Mul => {
1015                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1016                writer.write_u8(0x03)?;
1017            }
1018            Self::I64DivS => {
1019                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1020                writer.write_u8(0x04)?;
1021            }
1022            Self::I64DivU => {
1023                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1024                writer.write_u8(0x05)?;
1025            }
1026            Self::I64RemS => {
1027                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1028                writer.write_u8(0x06)?;
1029            }
1030            Self::I64RemU => {
1031                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1032                writer.write_u8(0x07)?;
1033            }
1034            Self::I64Neg => {
1035                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1036                writer.write_u8(0x08)?;
1037            }
1038            Self::I64And => {
1039                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1040                writer.write_u8(0x09)?;
1041            }
1042            Self::I64Or => {
1043                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1044                writer.write_u8(0x0A)?;
1045            }
1046            Self::I64Xor => {
1047                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1048                writer.write_u8(0x0B)?;
1049            }
1050            Self::I64Shl => {
1051                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1052                writer.write_u8(0x0C)?;
1053            }
1054            Self::I64ShrS => {
1055                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1056                writer.write_u8(0x0D)?;
1057            }
1058            Self::I64ShrU => {
1059                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1060                writer.write_u8(0x0E)?;
1061            }
1062            Self::I64Not => {
1063                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1064                writer.write_u8(0x0F)?;
1065            }
1066            Self::I64Eq => {
1067                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1068                writer.write_u8(0x10)?;
1069            }
1070            Self::I64Ne => {
1071                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1072                writer.write_u8(0x11)?;
1073            }
1074            Self::I64LtS => {
1075                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1076                writer.write_u8(0x12)?;
1077            }
1078            Self::I64LtU => {
1079                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1080                writer.write_u8(0x13)?;
1081            }
1082            Self::I64LeS => {
1083                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1084                writer.write_u8(0x14)?;
1085            }
1086            Self::I64LeU => {
1087                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1088                writer.write_u8(0x15)?;
1089            }
1090            Self::I64GtS => {
1091                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1092                writer.write_u8(0x16)?;
1093            }
1094            Self::I64GtU => {
1095                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1096                writer.write_u8(0x17)?;
1097            }
1098            Self::I64GeS => {
1099                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1100                writer.write_u8(0x18)?;
1101            }
1102            Self::I64GeU => {
1103                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1104                writer.write_u8(0x19)?;
1105            }
1106            Self::I64ToF32S => {
1107                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1108                writer.write_u8(0x1A)?;
1109            }
1110            Self::I64ToF32U => {
1111                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1112                writer.write_u8(0x1B)?;
1113            }
1114            Self::I64ToF64S => {
1115                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1116                writer.write_u8(0x1C)?;
1117            }
1118            Self::I64ToF64U => {
1119                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1120                writer.write_u8(0x1D)?;
1121            }
1122            Self::I64AddSatS => {
1123                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1124                writer.write_u8(0x1E)?;
1125            }
1126            Self::I64AddSatU => {
1127                writer.write_u8(NyarOpcode::I64Ext as u8)?;
1128                writer.write_u8(0x1F)?;
1129            }
1130
1131            // --- F32 Extensions ---
1132            Self::F32Const(v) => {
1133                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1134                writer.write_u8(0x00)?;
1135                writer.write_f32(*v)?;
1136            }
1137            Self::F32Add => {
1138                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1139                writer.write_u8(0x01)?;
1140            }
1141            Self::F32Sub => {
1142                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1143                writer.write_u8(0x02)?;
1144            }
1145            Self::F32Mul => {
1146                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1147                writer.write_u8(0x03)?;
1148            }
1149            Self::F32Div => {
1150                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1151                writer.write_u8(0x04)?;
1152            }
1153            Self::F32Neg => {
1154                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1155                writer.write_u8(0x08)?;
1156            }
1157            Self::F32Eq => {
1158                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1159                writer.write_u8(0x10)?;
1160            }
1161            Self::F32Ne => {
1162                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1163                writer.write_u8(0x11)?;
1164            }
1165            Self::F32Lt => {
1166                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1167                writer.write_u8(0x12)?;
1168            }
1169            Self::F32Le => {
1170                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1171                writer.write_u8(0x14)?;
1172            }
1173            Self::F32Gt => {
1174                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1175                writer.write_u8(0x16)?;
1176            }
1177            Self::F32Ge => {
1178                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1179                writer.write_u8(0x18)?;
1180            }
1181            Self::F32ToI32S => {
1182                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1183                writer.write_u8(0x1A)?;
1184            }
1185            Self::F32ToI32U => {
1186                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1187                writer.write_u8(0x1B)?;
1188            }
1189            Self::F32ToI64S => {
1190                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1191                writer.write_u8(0x1C)?;
1192            }
1193            Self::F32ToI64U => {
1194                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1195                writer.write_u8(0x1D)?;
1196            }
1197            Self::F32ToF64 => {
1198                writer.write_u8(NyarOpcode::F32Ext as u8)?;
1199                writer.write_u8(0x1E)?;
1200            }
1201
1202            // --- F64 Extensions ---
1203            Self::F64Const(v) => {
1204                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1205                writer.write_u8(0x00)?;
1206                writer.write_f64(*v)?;
1207            }
1208            Self::F64Add => {
1209                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1210                writer.write_u8(0x01)?;
1211            }
1212            Self::F64Sub => {
1213                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1214                writer.write_u8(0x02)?;
1215            }
1216            Self::F64Mul => {
1217                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1218                writer.write_u8(0x03)?;
1219            }
1220            Self::F64Div => {
1221                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1222                writer.write_u8(0x04)?;
1223            }
1224            Self::F64Neg => {
1225                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1226                writer.write_u8(0x08)?;
1227            }
1228            Self::F64Eq => {
1229                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1230                writer.write_u8(0x10)?;
1231            }
1232            Self::F64Ne => {
1233                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1234                writer.write_u8(0x11)?;
1235            }
1236            Self::F64Lt => {
1237                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1238                writer.write_u8(0x12)?;
1239            }
1240            Self::F64Le => {
1241                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1242                writer.write_u8(0x14)?;
1243            }
1244            Self::F64Gt => {
1245                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1246                writer.write_u8(0x16)?;
1247            }
1248            Self::F64Ge => {
1249                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1250                writer.write_u8(0x18)?;
1251            }
1252            Self::F64ToI32S => {
1253                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1254                writer.write_u8(0x1A)?;
1255            }
1256            Self::F64ToI32U => {
1257                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1258                writer.write_u8(0x1B)?;
1259            }
1260            Self::F64ToI64S => {
1261                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1262                writer.write_u8(0x1C)?;
1263            }
1264            Self::F64ToI64U => {
1265                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1266                writer.write_u8(0x1D)?;
1267            }
1268            Self::F64ToF32 => {
1269                writer.write_u8(NyarOpcode::F64Ext as u8)?;
1270                writer.write_u8(0x1E)?;
1271            }
1272
1273            // --- BigInt Extensions ---
1274            Self::BigIntConst { sign, bytes } => {
1275                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1276                writer.write_u8(0x00)?;
1277                writer.write_u8(*sign)?;
1278                writer.write_u32(bytes.len() as u32)?;
1279                writer.write_bytes(bytes)?;
1280            }
1281            Self::BigIntAdd => {
1282                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1283                writer.write_u8(0x01)?;
1284            }
1285            Self::BigIntSub => {
1286                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1287                writer.write_u8(0x02)?;
1288            }
1289            Self::BigIntMul => {
1290                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1291                writer.write_u8(0x03)?;
1292            }
1293            Self::BigIntDiv => {
1294                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1295                writer.write_u8(0x04)?;
1296            }
1297            Self::BigIntMod => {
1298                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1299                writer.write_u8(0x05)?;
1300            }
1301            Self::BigIntNeg => {
1302                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1303                writer.write_u8(0x08)?;
1304            }
1305            Self::BigIntEq => {
1306                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1307                writer.write_u8(0x10)?;
1308            }
1309            Self::BigIntNe => {
1310                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1311                writer.write_u8(0x11)?;
1312            }
1313            Self::BigIntLt => {
1314                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1315                writer.write_u8(0x12)?;
1316            }
1317            Self::BigIntLe => {
1318                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1319                writer.write_u8(0x14)?;
1320            }
1321            Self::BigIntGt => {
1322                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1323                writer.write_u8(0x16)?;
1324            }
1325            Self::BigIntGe => {
1326                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1327                writer.write_u8(0x18)?;
1328            }
1329            Self::BigIntToI64 => {
1330                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1331                writer.write_u8(0x1A)?;
1332            }
1333            Self::BigIntFromI64 => {
1334                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1335                writer.write_u8(0x1B)?;
1336            }
1337            Self::BigIntToString => {
1338                writer.write_u8(NyarOpcode::BigIntExt as u8)?;
1339                writer.write_u8(0x1C)?;
1340            }
1341
1342            // --- String Extensions ---
1343            Self::StringConst(s) => {
1344                writer.write_u8(NyarOpcode::StringExt as u8)?;
1345                writer.write_u8(0x00)?;
1346                let bytes = s.as_bytes();
1347                writer.write_u32(bytes.len() as u32)?;
1348                writer.write_bytes(bytes)?;
1349            }
1350            Self::StringConcat => {
1351                writer.write_u8(NyarOpcode::StringExt as u8)?;
1352                writer.write_u8(0x01)?;
1353            }
1354            Self::StringLenBytes => {
1355                writer.write_u8(NyarOpcode::StringExt as u8)?;
1356                writer.write_u8(0x02)?;
1357            }
1358            Self::StringLenChars => {
1359                writer.write_u8(NyarOpcode::StringExt as u8)?;
1360                writer.write_u8(0x0A)?;
1361            }
1362            Self::StringEq => {
1363                writer.write_u8(NyarOpcode::StringExt as u8)?;
1364                writer.write_u8(0x04)?;
1365            }
1366            Self::StringNe => {
1367                writer.write_u8(NyarOpcode::StringExt as u8)?;
1368                writer.write_u8(0x05)?;
1369            }
1370            Self::StringLt => {
1371                writer.write_u8(NyarOpcode::StringExt as u8)?;
1372                writer.write_u8(0x06)?;
1373            }
1374            Self::StringLe => {
1375                writer.write_u8(NyarOpcode::StringExt as u8)?;
1376                writer.write_u8(0x07)?;
1377            }
1378            Self::StringGt => {
1379                writer.write_u8(NyarOpcode::StringExt as u8)?;
1380                writer.write_u8(0x08)?;
1381            }
1382            Self::StringGe => {
1383                writer.write_u8(NyarOpcode::StringExt as u8)?;
1384                writer.write_u8(0x09)?;
1385            }
1386            Self::StringSubstr => {
1387                writer.write_u8(NyarOpcode::StringExt as u8)?;
1388                writer.write_u8(0x03)?;
1389            }
1390
1391            // --- Channel Extensions ---
1392            Self::NewChannel(v) => {
1393                writer.write_u8(0x57)?;
1394                writer.write_u16(*v)?;
1395            }
1396            Self::SendChannel => {
1397                writer.write_u8(0x58)?;
1398            }
1399            Self::RecvChannel => {
1400                writer.write_u8(0x59)?;
1401            }
1402            Self::SelectChannel(v) => {
1403                writer.write_u8(0x5A)?;
1404                writer.write_u8(*v)?;
1405            }
1406
1407            // --- Query Extensions ---
1408            Self::NewQuery(v) => {
1409                writer.write_u8(0x5B)?;
1410                writer.write_u16(*v)?;
1411            }
1412            Self::QueryExec => {
1413                writer.write_u8(0x5C)?;
1414            }
1415
1416            // --- Clock Extensions ---
1417            Self::NewClock => {
1418                writer.write_u8(0x5D)?;
1419            }
1420            Self::ClockWait => {
1421                writer.write_u8(0x5E)?;
1422            }
1423        }
1424        Ok(())
1425    }
1426
1427    fn decode(reader: &mut BinaryReader<Cursor<&[u8]>, Leb128>) -> Result<Self, GaiaError> {
1428        let opcode_u8 = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1429        let opcode = match opcode_u8 {
1430            0x00 => NyarOpcode::Nop,
1431            0x01 => NyarOpcode::Push,
1432            0x10 => NyarOpcode::PushNone,
1433            0x02 => NyarOpcode::Pop,
1434            0x03 => NyarOpcode::Dup,
1435            0x04 => NyarOpcode::Swap,
1436            0x05 => NyarOpcode::LoadLocal,
1437            0x06 => NyarOpcode::StoreLocal,
1438            0x07 => NyarOpcode::LoadGlobal,
1439            0x08 => NyarOpcode::StoreGlobal,
1440            0x09 => NyarOpcode::LoadUpvalue,
1441            0x0A => NyarOpcode::StoreUpvalue,
1442            0x0B => NyarOpcode::CloseUpvalues,
1443            0x0C => NyarOpcode::Jump,
1444            0x0D => NyarOpcode::JumpIfFalse,
1445            0x0E => NyarOpcode::JumpIfTrue,
1446            0x0F => NyarOpcode::JumpIfNull,
1447            0x13 => NyarOpcode::Return,
1448            0x15 => NyarOpcode::MakeClosure,
1449            0x20 => NyarOpcode::Call,
1450            0x21 => NyarOpcode::CallVirtual,
1451            0x22 => NyarOpcode::CallDynamic,
1452            0x23 => NyarOpcode::CallClosure,
1453            0x24 => NyarOpcode::InvokeMethod,
1454            0x25 => NyarOpcode::CallSymbol,
1455            0x30 => NyarOpcode::GetField,
1456            0x31 => NyarOpcode::SetField,
1457            0x32 => NyarOpcode::NewObject,
1458            0x33 => NyarOpcode::NewArray,
1459            0x34 => NyarOpcode::GetElement,
1460            0x35 => NyarOpcode::SetElement,
1461            0x36 => NyarOpcode::MakeTuple,
1462            0x37 => NyarOpcode::HasKey,
1463            0x38 => NyarOpcode::MatchVariant,
1464            0x39 => NyarOpcode::SizeOf,
1465            0x3A => NyarOpcode::NewDynObject,
1466            0x3B => NyarOpcode::RemoveKey,
1467            0x3C => NyarOpcode::NewList,
1468            0x3D => NyarOpcode::PushElementLeft,
1469            0x3E => NyarOpcode::PopElementLeft,
1470            0x3F => NyarOpcode::PushElementRight,
1471            0x40 => NyarOpcode::PopElementRight,
1472            0x41 => NyarOpcode::TypeOf,
1473            0x42 => NyarOpcode::InstanceOf,
1474            0x43 => NyarOpcode::CheckCast,
1475            0x44 => NyarOpcode::Cast,
1476            0x45 => NyarOpcode::Initiate,
1477            0x46 => NyarOpcode::Finalize,
1478            0x50 => NyarOpcode::Perform,
1479            0x51 => NyarOpcode::WithHandler,
1480            0x52 => NyarOpcode::ResumeWith,
1481            0x53 => NyarOpcode::CaptureCont,
1482            0x54 => NyarOpcode::Await,
1483            0x55 => NyarOpcode::BlockOn,
1484            0x56 => NyarOpcode::MatchEffect,
1485            0x60 => NyarOpcode::GetWitnessTable,
1486            0x61 => NyarOpcode::WitnessMethod,
1487            0x62 => NyarOpcode::OpenExistential,
1488            0x63 => NyarOpcode::CloseExistential,
1489            0x70 => NyarOpcode::Quote,
1490            0x71 => NyarOpcode::Splice,
1491            0x72 => NyarOpcode::Eval,
1492            0x73 => NyarOpcode::ExpandMacro,
1493            0xC1 => NyarOpcode::I32Ext,
1494            0xC2 => NyarOpcode::I64Ext,
1495            0xC3 => NyarOpcode::F32Ext,
1496            0xC4 => NyarOpcode::F64Ext,
1497            0xC5 => NyarOpcode::BigIntExt,
1498            0xC6 => NyarOpcode::StringExt,
1499            0xF0 => NyarOpcode::FFICall,
1500            0x14 => NyarOpcode::TailCall,
1501            0x16 => NyarOpcode::TailCallClosure,
1502            0xFF => NyarOpcode::Halt,
1503            0x57 => return Ok(Self::NewChannel(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1504            0x58 => return Ok(Self::SendChannel),
1505            0x59 => return Ok(Self::RecvChannel),
1506            0x5A => return Ok(Self::SelectChannel(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1507            0x5B => return Ok(Self::NewQuery(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1508            0x5C => return Ok(Self::QueryExec),
1509            0x5D => return Ok(Self::NewClock),
1510            0x5E => return Ok(Self::ClockWait),
1511            _ => return Err(GaiaError::invalid_data(opcode_u8)),
1512        };
1513
1514        match opcode {
1515            NyarOpcode::Nop => Ok(Self::Nop),
1516            NyarOpcode::Push => Ok(Self::Push(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1517            NyarOpcode::PushNone => Ok(Self::PushNone),
1518            NyarOpcode::Pop => Ok(Self::Pop),
1519            NyarOpcode::Dup => Ok(Self::Dup(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1520            NyarOpcode::Swap => Ok(Self::Swap(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1521            NyarOpcode::LoadLocal => {
1522                Ok(Self::LoadLocal(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1523            }
1524            NyarOpcode::StoreLocal => {
1525                Ok(Self::StoreLocal(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1526            }
1527            NyarOpcode::LoadGlobal => {
1528                Ok(Self::LoadGlobal(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1529            }
1530            NyarOpcode::StoreGlobal => {
1531                Ok(Self::StoreGlobal(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1532            }
1533            NyarOpcode::LoadUpvalue => {
1534                Ok(Self::LoadUpvalue(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1535            }
1536            NyarOpcode::StoreUpvalue => {
1537                Ok(Self::StoreUpvalue(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1538            }
1539            NyarOpcode::CloseUpvalues => Ok(Self::CloseUpvalues),
1540            NyarOpcode::Jump => Ok(Self::Jump(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1541            NyarOpcode::JumpIfFalse => {
1542                Ok(Self::JumpIfFalse(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1543            }
1544            NyarOpcode::JumpIfTrue => {
1545                Ok(Self::JumpIfTrue(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1546            }
1547            NyarOpcode::JumpIfNull => {
1548                Ok(Self::JumpIfNull(reader.read_i16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1549            }
1550            NyarOpcode::Return => Ok(Self::Return),
1551            NyarOpcode::MakeClosure => {
1552                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1553                let count = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))? as usize;
1554                let mut ups = Vec::with_capacity(count);
1555                for _ in 0..count {
1556                    let is_local = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))? != 0;
1557                    let index = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1558                    ups.push(NyarUpvalueRef { is_local, index });
1559                }
1560                Ok(Self::MakeClosure(idx, ups))
1561            }
1562            NyarOpcode::TailCall => {
1563                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1564                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1565                Ok(Self::TailCall(idx, argc))
1566            }
1567            NyarOpcode::TailCallClosure => {
1568                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1569                Ok(Self::TailCallClosure(argc))
1570            }
1571            NyarOpcode::Call => {
1572                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1573                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1574                Ok(Self::Call(idx, argc))
1575            }
1576            NyarOpcode::CallVirtual => {
1577                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1578                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1579                Ok(Self::CallVirtual(idx, argc))
1580            }
1581            NyarOpcode::CallDynamic => {
1582                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1583                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1584                Ok(Self::CallDynamic(idx, argc))
1585            }
1586            NyarOpcode::CallClosure => {
1587                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1588                Ok(Self::CallClosure(argc))
1589            }
1590            NyarOpcode::InvokeMethod => {
1591                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1592                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1593                Ok(Self::InvokeMethod(idx, argc))
1594            }
1595            NyarOpcode::CallSymbol => {
1596                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1597                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1598                Ok(Self::CallSymbol(idx, argc))
1599            }
1600            NyarOpcode::GetField => {
1601                Ok(Self::GetField(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1602            }
1603            NyarOpcode::SetField => {
1604                Ok(Self::SetField(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1605            }
1606            NyarOpcode::NewObject => {
1607                Ok(Self::NewObject(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1608            }
1609            NyarOpcode::NewArray => {
1610                Ok(Self::NewArray(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1611            }
1612            NyarOpcode::GetElement => Ok(Self::GetElement),
1613            NyarOpcode::SetElement => Ok(Self::SetElement),
1614            NyarOpcode::NewDynObject => Ok(Self::NewDynObject),
1615            NyarOpcode::RemoveKey => Ok(Self::RemoveKey),
1616            NyarOpcode::Initiate => {
1617                Ok(Self::Initiate(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1618            }
1619            NyarOpcode::Finalize => Ok(Self::Finalize),
1620            NyarOpcode::NewList => Ok(Self::NewList(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1621            NyarOpcode::PushElementLeft => Ok(Self::PushElementLeft),
1622            NyarOpcode::PopElementLeft => Ok(Self::PopElementLeft),
1623            NyarOpcode::PushElementRight => Ok(Self::PushElementRight),
1624            NyarOpcode::PopElementRight => Ok(Self::PopElementRight),
1625            NyarOpcode::MakeTuple => {
1626                Ok(Self::MakeTuple(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1627            }
1628            NyarOpcode::HasKey => Ok(Self::HasKey),
1629            NyarOpcode::MatchVariant => {
1630                Ok(Self::MatchVariant(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1631            }
1632            NyarOpcode::SizeOf => Ok(Self::SizeOf),
1633            NyarOpcode::TypeOf => Ok(Self::TypeOf),
1634            NyarOpcode::InstanceOf => {
1635                Ok(Self::InstanceOf(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1636            }
1637            NyarOpcode::CheckCast => {
1638                Ok(Self::CheckCast(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1639            }
1640            NyarOpcode::Cast => Ok(Self::Cast(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1641            NyarOpcode::Perform => {
1642                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1643                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1644                Ok(Self::Perform(idx, argc))
1645            }
1646            NyarOpcode::WithHandler => {
1647                Ok(Self::WithHandler(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1648            }
1649            NyarOpcode::ResumeWith => Ok(Self::ResumeWith),
1650            NyarOpcode::CaptureCont => Ok(Self::CaptureCont),
1651            NyarOpcode::Await => Ok(Self::Await),
1652            NyarOpcode::BlockOn => Ok(Self::BlockOn),
1653            NyarOpcode::MatchEffect => {
1654                Ok(Self::MatchEffect(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1655            }
1656            NyarOpcode::GetWitnessTable => {
1657                let v1 = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1658                let v2 = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1659                Ok(Self::GetWitnessTable(v1, v2))
1660            }
1661            NyarOpcode::WitnessMethod => {
1662                Ok(Self::WitnessMethod(reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?))
1663            }
1664            NyarOpcode::OpenExistential => Ok(Self::OpenExistential),
1665            NyarOpcode::CloseExistential => Ok(Self::CloseExistential),
1666            NyarOpcode::Quote => Ok(Self::Quote(reader.read_u32().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1667            NyarOpcode::Splice => Ok(Self::Splice),
1668            NyarOpcode::Eval => Ok(Self::Eval(reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1669            NyarOpcode::ExpandMacro => {
1670                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1671                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1672                Ok(Self::ExpandMacro(idx, argc))
1673            }
1674            NyarOpcode::FFICall => {
1675                let idx = reader.read_u16().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1676                let argc = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1677                Ok(Self::FFICall(idx, argc))
1678            }
1679            NyarOpcode::Halt => Ok(Self::Halt),
1680            NyarOpcode::I32Ext => {
1681                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1682                match ext {
1683                    0x00 => Ok(Self::I32Const(reader.read_i32().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1684                    0x01 => Ok(Self::I32Add),
1685                    0x02 => Ok(Self::I32Sub),
1686                    0x03 => Ok(Self::I32Mul),
1687                    0x04 => Ok(Self::I32DivS),
1688                    0x05 => Ok(Self::I32DivU),
1689                    0x06 => Ok(Self::I32RemS),
1690                    0x07 => Ok(Self::I32RemU),
1691                    0x08 => Ok(Self::I32Neg),
1692                    0x09 => Ok(Self::I32And),
1693                    0x0A => Ok(Self::I32Or),
1694                    0x0B => Ok(Self::I32Xor),
1695                    0x0C => Ok(Self::I32Shl),
1696                    0x0D => Ok(Self::I32ShrS),
1697                    0x0E => Ok(Self::I32ShrU),
1698                    0x0F => Ok(Self::I32Not),
1699                    0x10 => Ok(Self::I32Eq),
1700                    0x11 => Ok(Self::I32Ne),
1701                    0x12 => Ok(Self::I32LtS),
1702                    0x13 => Ok(Self::I32LtU),
1703                    0x14 => Ok(Self::I32LeS),
1704                    0x15 => Ok(Self::I32LeU),
1705                    0x16 => Ok(Self::I32GtS),
1706                    0x17 => Ok(Self::I32GtU),
1707                    0x18 => Ok(Self::I32GeS),
1708                    0x19 => Ok(Self::I32GeU),
1709                    0x1F => Ok(Self::I32ToF32S),
1710                    0x20 => Ok(Self::I32ToF32U),
1711                    0x21 => Ok(Self::I32ToF64S),
1712                    0x22 => Ok(Self::I32ToF64U),
1713                    0x23 => Ok(Self::I32AddSatS),
1714                    0x24 => Ok(Self::I32AddSatU),
1715                    0x25 => Ok(Self::I32SubSatS),
1716                    0x26 => Ok(Self::I32SubSatU),
1717                    0x1A => Ok(Self::I32Extend64S),
1718                    0x1B => Ok(Self::I32Extend64U),
1719                    0x1C => Ok(Self::I32Trunc64SLow),
1720                    0x1D => Ok(Self::I32Trunc64S),
1721                    0x1E => Ok(Self::I32Trunc64U),
1722                    _ => Err(GaiaError::invalid_data(ext)),
1723                }
1724            }
1725            NyarOpcode::I64Ext => {
1726                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1727                match ext {
1728                    0x00 => Ok(Self::I64Const(reader.read_i64().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1729                    0x01 => Ok(Self::I64Add),
1730                    0x02 => Ok(Self::I64Sub),
1731                    0x03 => Ok(Self::I64Mul),
1732                    0x04 => Ok(Self::I64DivS),
1733                    0x05 => Ok(Self::I64DivU),
1734                    0x06 => Ok(Self::I64RemS),
1735                    0x07 => Ok(Self::I64RemU),
1736                    0x08 => Ok(Self::I64Neg),
1737                    0x09 => Ok(Self::I64And),
1738                    0x0A => Ok(Self::I64Or),
1739                    0x0B => Ok(Self::I64Xor),
1740                    0x0C => Ok(Self::I64Shl),
1741                    0x0D => Ok(Self::I64ShrS),
1742                    0x0E => Ok(Self::I64ShrU),
1743                    0x0F => Ok(Self::I64Not),
1744                    0x10 => Ok(Self::I64Eq),
1745                    0x11 => Ok(Self::I64Ne),
1746                    0x12 => Ok(Self::I64LtS),
1747                    0x13 => Ok(Self::I64LtU),
1748                    0x14 => Ok(Self::I64LeS),
1749                    0x15 => Ok(Self::I64LeU),
1750                    0x16 => Ok(Self::I64GtS),
1751                    0x17 => Ok(Self::I64GtU),
1752                    0x18 => Ok(Self::I64GeS),
1753                    0x19 => Ok(Self::I64GeU),
1754                    0x1A => Ok(Self::I64ToF32S),
1755                    0x1B => Ok(Self::I64ToF32U),
1756                    0x1C => Ok(Self::I64ToF64S),
1757                    0x1D => Ok(Self::I64ToF64U),
1758                    0x1E => Ok(Self::I64AddSatS),
1759                    0x1F => Ok(Self::I64AddSatU),
1760                    _ => Err(GaiaError::invalid_data(ext)),
1761                }
1762            }
1763            NyarOpcode::F32Ext => {
1764                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1765                match ext {
1766                    0x00 => Ok(Self::F32Const(reader.read_f32().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1767                    0x01 => Ok(Self::F32Add),
1768                    0x02 => Ok(Self::F32Sub),
1769                    0x03 => Ok(Self::F32Mul),
1770                    0x04 => Ok(Self::F32Div),
1771                    0x08 => Ok(Self::F32Neg),
1772                    0x10 => Ok(Self::F32Eq),
1773                    0x11 => Ok(Self::F32Ne),
1774                    0x12 => Ok(Self::F32Lt),
1775                    0x14 => Ok(Self::F32Le),
1776                    0x16 => Ok(Self::F32Gt),
1777                    0x18 => Ok(Self::F32Ge),
1778                    0x1A => Ok(Self::F32ToI32S),
1779                    0x1B => Ok(Self::F32ToI32U),
1780                    0x1C => Ok(Self::F32ToI64S),
1781                    0x1D => Ok(Self::F32ToI64U),
1782                    0x1E => Ok(Self::F32ToF64),
1783                    _ => Err(GaiaError::invalid_data(ext)),
1784                }
1785            }
1786            NyarOpcode::F64Ext => {
1787                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1788                match ext {
1789                    0x00 => Ok(Self::F64Const(reader.read_f64().map_err(|_| GaiaError::invalid_data("Data truncated"))?)),
1790                    0x01 => Ok(Self::F64Add),
1791                    0x02 => Ok(Self::F64Sub),
1792                    0x03 => Ok(Self::F64Mul),
1793                    0x04 => Ok(Self::F64Div),
1794                    0x08 => Ok(Self::F64Neg),
1795                    0x10 => Ok(Self::F64Eq),
1796                    0x11 => Ok(Self::F64Ne),
1797                    0x12 => Ok(Self::F64Lt),
1798                    0x14 => Ok(Self::F64Le),
1799                    0x16 => Ok(Self::F64Gt),
1800                    0x18 => Ok(Self::F64Ge),
1801                    0x1A => Ok(Self::F64ToI32S),
1802                    0x1B => Ok(Self::F64ToI32U),
1803                    0x1C => Ok(Self::F64ToI64S),
1804                    0x1D => Ok(Self::F64ToI64U),
1805                    0x1E => Ok(Self::F64ToF32),
1806                    _ => Err(GaiaError::invalid_data(ext)),
1807                }
1808            }
1809            NyarOpcode::BigIntExt => {
1810                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1811                match ext {
1812                    0x00 => {
1813                        let sign = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1814                        let len = reader.read_u32().map_err(|_| GaiaError::invalid_data("Data truncated"))? as usize;
1815                        let mut bytes = vec![0u8; len];
1816                        for i in 0..len {
1817                            bytes[i] = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1818                        }
1819                        Ok(Self::BigIntConst { sign, bytes })
1820                    }
1821                    0x01 => Ok(Self::BigIntAdd),
1822                    0x02 => Ok(Self::BigIntSub),
1823                    0x03 => Ok(Self::BigIntMul),
1824                    0x04 => Ok(Self::BigIntDiv),
1825                    0x05 => Ok(Self::BigIntMod),
1826                    0x08 => Ok(Self::BigIntNeg),
1827                    0x10 => Ok(Self::BigIntEq),
1828                    0x11 => Ok(Self::BigIntNe),
1829                    0x12 => Ok(Self::BigIntLt),
1830                    0x14 => Ok(Self::BigIntLe),
1831                    0x16 => Ok(Self::BigIntGt),
1832                    0x18 => Ok(Self::BigIntGe),
1833                    0x1A => Ok(Self::BigIntToI64),
1834                    0x1B => Ok(Self::BigIntFromI64),
1835                    0x1C => Ok(Self::BigIntToString),
1836                    _ => Err(GaiaError::invalid_data(ext)),
1837                }
1838            }
1839            NyarOpcode::StringExt => {
1840                let ext = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1841                match ext {
1842                    0x00 => {
1843                        let len = reader.read_u32().map_err(|_| GaiaError::invalid_data("Data truncated"))? as usize;
1844                        let mut bytes = vec![0u8; len];
1845                        for i in 0..len {
1846                            bytes[i] = reader.read_u8().map_err(|_| GaiaError::invalid_data("Data truncated"))?;
1847                        }
1848                        let s = String::from_utf8(bytes).map_err(|_| GaiaError::invalid_data("Text parse error"))?;
1849                        Ok(Self::StringConst(s))
1850                    }
1851                    0x01 => Ok(Self::StringConcat),
1852                    0x02 => Ok(Self::StringLenBytes),
1853                    0x03 => Ok(Self::StringSubstr),
1854                    0x04 => Ok(Self::StringEq),
1855                    0x05 => Ok(Self::StringNe),
1856                    0x06 => Ok(Self::StringLt),
1857                    0x07 => Ok(Self::StringLe),
1858                    0x08 => Ok(Self::StringGt),
1859                    0x09 => Ok(Self::StringGe),
1860                    0x0A => Ok(Self::StringLenChars),
1861                    _ => Err(GaiaError::invalid_data(ext)),
1862                }
1863            }
1864            _ => Err(GaiaError::invalid_data(opcode_u8)),
1865        }
1866    }
1867}