avm_rs/opcodes/
function.rs1use crate::error::AvmResult;
4use crate::vm::EvalContext;
5
6pub fn op_proto(ctx: &mut EvalContext) -> AvmResult<()> {
8 ctx.advance_pc(1)?; let args = ctx.read_bytes(1)?[0] as usize;
10 ctx.advance_pc(1)?; let returns = ctx.read_bytes(1)?[0] as usize;
12 ctx.advance_pc(1)?; ctx.set_function_prototype(args, returns)?;
17
18 Ok(())
19}
20
21pub fn op_frame_dig(ctx: &mut EvalContext) -> AvmResult<()> {
23 ctx.advance_pc(1)?; let depth = ctx.read_bytes(1)?[0] as i8;
25 ctx.advance_pc(1)?; let value = ctx.frame_dig(depth)?;
28 ctx.push(value)?;
29
30 Ok(())
31}
32
33pub fn op_frame_bury(ctx: &mut EvalContext) -> AvmResult<()> {
35 ctx.advance_pc(1)?; let depth = ctx.read_bytes(1)?[0] as i8;
37 ctx.advance_pc(1)?; let value = ctx.pop()?;
40 ctx.frame_bury(depth, value)?;
41
42 Ok(())
43}
44
45pub fn op_switch(ctx: &mut EvalContext) -> AvmResult<()> {
47 ctx.advance_pc(1)?; let num_targets = ctx.read_bytes(1)?[0] as usize;
51 ctx.advance_pc(1)?; let mut targets = Vec::new();
55 for _ in 0..num_targets {
56 let target_bytes = ctx.read_bytes(2)?;
57 let target = i16::from_be_bytes([target_bytes[0], target_bytes[1]]);
58 targets.push(target);
59 ctx.advance_pc(2)?;
60 }
61
62 let switch_value = ctx.pop()?;
64 let index = switch_value.as_uint()? as usize;
65
66 if index < targets.len() {
68 let target = targets[index];
69 ctx.branch(target)?;
70 }
71 Ok(())
74}
75
76pub fn op_match(ctx: &mut EvalContext) -> AvmResult<()> {
78 ctx.advance_pc(1)?; let num_cases = ctx.read_bytes(1)?[0] as usize;
82 ctx.advance_pc(1)?; let mut cases = Vec::new();
86 for _ in 0..num_cases {
87 let value_bytes = ctx.read_bytes(8)?;
89 let match_value = u64::from_be_bytes([
90 value_bytes[0],
91 value_bytes[1],
92 value_bytes[2],
93 value_bytes[3],
94 value_bytes[4],
95 value_bytes[5],
96 value_bytes[6],
97 value_bytes[7],
98 ]);
99 ctx.advance_pc(8)?;
100
101 let target_bytes = ctx.read_bytes(2)?;
103 let target = i16::from_be_bytes([target_bytes[0], target_bytes[1]]);
104 ctx.advance_pc(2)?;
105
106 cases.push((match_value, target));
107 }
108
109 let match_value = ctx.pop()?;
111 let value = match_value.as_uint()?;
112
113 for (case_value, target) in cases {
115 if value == case_value {
116 ctx.branch(target)?;
117 return Ok(());
118 }
119 }
120
121 Ok(())
123}