@@ -22,8 +22,12 @@ pub struct AvmInstruction {
22
22
/// Its usage will depend on the instruction.
23
23
pub tag : Option < AvmTypeTag > ,
24
24
25
- /// Different instructions have different numbers of operands
25
+ /// Different instructions have different numbers of operands. These operands contain
26
+ /// memory addresses.
26
27
pub operands : Vec < AvmOperand > ,
28
+
29
+ // Operands which are immediate, i.e., contain hardcoded constants.
30
+ pub immediates : Vec < AvmOperand > ,
27
31
}
28
32
29
33
impl Display for AvmInstruction {
@@ -32,35 +36,46 @@ impl Display for AvmInstruction {
32
36
if let Some ( indirect) = & self . indirect {
33
37
write ! ( f, ", indirect: {}" , indirect) ?;
34
38
}
35
- // This will be either inTag or dstTag depending on the operation
36
- if let Some ( dst_tag) = self . tag {
37
- write ! ( f, ", tag: {}" , dst_tag as u8 ) ?;
38
- }
39
39
if !self . operands . is_empty ( ) {
40
40
write ! ( f, ", operands: [" ) ?;
41
41
for operand in & self . operands {
42
42
write ! ( f, "{operand}, " ) ?;
43
43
}
44
44
write ! ( f, "]" ) ?;
45
45
} ;
46
+ // This will be either inTag or dstTag depending on the operation
47
+ if let Some ( dst_tag) = self . tag {
48
+ write ! ( f, ", tag: {}" , dst_tag as u8 ) ?;
49
+ }
50
+ if !self . immediates . is_empty ( ) {
51
+ write ! ( f, ", immediates: [" ) ?;
52
+ for immediate in & self . immediates {
53
+ write ! ( f, "{immediate}, " ) ?;
54
+ }
55
+ write ! ( f, "]" ) ?;
56
+ } ;
46
57
Ok ( ( ) )
47
58
}
48
59
}
49
60
50
61
impl AvmInstruction {
51
62
/// Bytes representation for generating AVM bytecode
63
+ /// Order: INDIRECT, OPERANDS, TAG, IMMEDIATES
52
64
pub fn to_bytes ( & self ) -> Vec < u8 > {
53
65
let mut bytes = Vec :: new ( ) ;
54
66
bytes. push ( self . opcode as u8 ) ;
55
67
if let Some ( indirect) = & self . indirect {
56
68
bytes. extend_from_slice ( & indirect. to_be_bytes ( ) ) ;
57
69
}
70
+ for operand in & self . operands {
71
+ bytes. extend_from_slice ( & operand. to_be_bytes ( ) ) ;
72
+ }
58
73
// This will be either inTag or dstTag depending on the operation
59
74
if let Some ( tag) = self . tag {
60
75
bytes. extend_from_slice ( & ( tag as u8 ) . to_be_bytes ( ) ) ;
61
76
}
62
- for operand in & self . operands {
63
- bytes. extend_from_slice ( & operand . to_be_bytes ( ) ) ;
77
+ for immediate in & self . immediates {
78
+ bytes. extend_from_slice ( & immediate . to_be_bytes ( ) ) ;
64
79
}
65
80
bytes
66
81
}
@@ -84,6 +99,7 @@ impl Default for AvmInstruction {
84
99
indirect : None ,
85
100
tag : None ,
86
101
operands : vec ! [ ] ,
102
+ immediates : vec ! [ ] ,
87
103
}
88
104
}
89
105
}
@@ -102,9 +118,8 @@ pub enum AvmTypeTag {
102
118
INVALID ,
103
119
}
104
120
105
- /// Operands are usually 32 bits (offsets or jump destinations)
106
- /// Constants (as used by the SET instruction) can have size
107
- /// different from 32 bits
121
+ /// Operands are usually 8, 16 and 32 bits (offsets)
122
+ /// Immediates (as used by the SET instruction) can have different sizes
108
123
#[ allow( non_camel_case_types) ]
109
124
pub enum AvmOperand {
110
125
U8 { value : u8 } ,
0 commit comments