22
22
23
23
#![ allow( clippy:: unusual_byte_groupings) ]
24
24
25
- use std:: collections:: BTreeSet ;
25
+ use std:: collections:: { BTreeSet , HashSet } ;
26
26
use std:: ops:: RangeInclusive ;
27
27
28
28
use aluvm:: isa:: { Bytecode , BytecodeError , ExecStep , InstructionSet } ;
29
29
use aluvm:: library:: { CodeEofError , LibSite , Read , Write } ;
30
- use aluvm:: reg:: { CoreRegs , Reg16 , RegA , RegS } ;
31
- use amplify:: num:: u4 ;
30
+ use aluvm:: reg:: { CoreRegs , Reg , Reg32 , RegA , RegS } ;
31
+ use amplify:: num:: { u3 , u4 } ;
32
32
use amplify:: Wrapper ;
33
33
use commit_verify:: CommitVerify ;
34
34
use strict_encoding:: StrictSerialize ;
@@ -45,22 +45,22 @@ pub enum ContractOp {
45
45
/// Counts number of inputs (previous state entries) of the provided type
46
46
/// and puts the number to the destination `a16` register.
47
47
#[ display( "cnp {0},a16{1}" ) ]
48
- CnP ( AssignmentType , Reg16 ) ,
48
+ CnP ( AssignmentType , Reg32 ) ,
49
49
50
50
/// Counts number of outputs (owned state entries) of the provided type
51
51
/// and puts the number to the destination `a16` register.
52
52
#[ display( "cns {0},a16{1}" ) ]
53
- CnS ( AssignmentType , Reg16 ) ,
53
+ CnS ( AssignmentType , Reg32 ) ,
54
54
55
55
/// Counts number of global state items of the provided type affected by the
56
56
/// current operation and puts the number to the destination `a8` register.
57
57
#[ display( "cng {0},a8{1}" ) ]
58
- CnG ( GlobalStateType , Reg16 ) ,
58
+ CnG ( GlobalStateType , Reg32 ) ,
59
59
60
60
/// Counts number of global state items of the provided type in the contract
61
61
/// state and puts the number to the destination `a16` register.
62
62
#[ display( "cnc {0},a16{1}" ) ]
63
- CnC ( AssignmentType , Reg16 ) ,
63
+ CnC ( AssignmentType , Reg32 ) ,
64
64
65
65
/// Loads input (previous) state with type id from the first argument and
66
66
/// index from the second argument into a register provided in the third
@@ -93,7 +93,7 @@ pub enum ContractOp {
93
93
///
94
94
/// If the state at the index is concealed, sets destination to `None`.
95
95
#[ display( "ldf {0},{1},a64{2}" ) ]
96
- LdF ( AssignmentType , u16 , Reg16 ) ,
96
+ LdF ( AssignmentType , u16 , Reg32 ) ,
97
97
98
98
/// Loads global state from the current operation with type id from the
99
99
/// first argument and index from the second argument into a register
@@ -158,6 +158,35 @@ impl InstructionSet for ContractOp {
158
158
159
159
fn isa_ids ( ) -> BTreeSet < & ' static str > { none ! ( ) }
160
160
161
+ fn src_regs ( & self ) -> HashSet < Reg > { set ! [ ] }
162
+
163
+ fn dst_regs ( & self ) -> HashSet < Reg > {
164
+ match self {
165
+ ContractOp :: CnP ( _, reg) |
166
+ ContractOp :: CnS ( _, reg) |
167
+ ContractOp :: CnG ( _, reg) |
168
+ ContractOp :: CnC ( _, reg) => {
169
+ set ! [ Reg :: A ( RegA :: A16 , * reg) ]
170
+ }
171
+ ContractOp :: LdF ( _, _, reg) => {
172
+ set ! [ Reg :: A ( RegA :: A64 , * reg) ]
173
+ }
174
+ ContractOp :: LdP ( _, _, reg) |
175
+ ContractOp :: LdS ( _, _, reg) |
176
+ ContractOp :: LdG ( _, _, reg) |
177
+ ContractOp :: LdC ( _, _, reg) |
178
+ ContractOp :: LdM ( reg) => {
179
+ set ! [ Reg :: S ( * reg) ]
180
+ }
181
+
182
+ ContractOp :: PcVs ( _) | ContractOp :: PcCs ( _, _) => {
183
+ set ! [ ]
184
+ }
185
+
186
+ ContractOp :: Fail ( _) => set ! [ ] ,
187
+ }
188
+ }
189
+
161
190
fn exec ( & self , regs : & mut CoreRegs , _site : LibSite , context : & Self :: Context < ' _ > ) -> ExecStep {
162
191
macro_rules! fail {
163
192
( ) => { {
@@ -204,17 +233,21 @@ impl InstructionSet for ContractOp {
204
233
205
234
match self {
206
235
ContractOp :: CnP ( state_type, reg) => {
207
- regs. set ( RegA :: A16 , * reg, context. prev_state . get ( state_type) . map ( |a| a. len_u16 ( ) ) ) ;
236
+ regs. set_n (
237
+ RegA :: A16 ,
238
+ * reg,
239
+ context. prev_state . get ( state_type) . map ( |a| a. len_u16 ( ) ) ,
240
+ ) ;
208
241
}
209
242
ContractOp :: CnS ( state_type, reg) => {
210
- regs. set (
243
+ regs. set_n (
211
244
RegA :: A16 ,
212
245
* reg,
213
246
context. owned_state . get ( * state_type) . map ( |a| a. len_u16 ( ) ) ,
214
247
) ;
215
248
}
216
249
ContractOp :: CnG ( state_type, reg) => {
217
- regs. set ( RegA :: A16 , * reg, context. global . get ( state_type) . map ( |a| a. len_u16 ( ) ) ) ;
250
+ regs. set_n ( RegA :: A16 , * reg, context. global . get ( state_type) . map ( |a| a. len_u16 ( ) ) ) ;
218
251
}
219
252
ContractOp :: CnC ( _state_type, _reg) => {
220
253
// TODO: implement global contract state
@@ -256,7 +289,7 @@ impl InstructionSet for ContractOp {
256
289
else {
257
290
fail ! ( )
258
291
} ;
259
- regs. set ( RegA :: A64 , * reg, state. map ( |s| s. value . as_u64 ( ) ) ) ;
292
+ regs. set_n ( RegA :: A64 , * reg, state. map ( |s| s. value . as_u64 ( ) ) ) ;
260
293
}
261
294
ContractOp :: LdG ( state_type, index, reg) => {
262
295
let Some ( state) = context
@@ -376,23 +409,23 @@ impl Bytecode for ContractOp {
376
409
match self {
377
410
ContractOp :: CnP ( state_type, reg) => {
378
411
writer. write_u16 ( * state_type) ?;
379
- writer. write_u4 ( reg) ?;
380
- writer. write_u4 ( u4 :: ZERO ) ?;
412
+ writer. write_u5 ( reg) ?;
413
+ writer. write_u3 ( u3 :: ZERO ) ?;
381
414
}
382
415
ContractOp :: CnS ( state_type, reg) => {
383
416
writer. write_u16 ( * state_type) ?;
384
- writer. write_u4 ( reg) ?;
385
- writer. write_u4 ( u4 :: ZERO ) ?;
417
+ writer. write_u5 ( reg) ?;
418
+ writer. write_u3 ( u3 :: ZERO ) ?;
386
419
}
387
420
ContractOp :: CnG ( state_type, reg) => {
388
421
writer. write_u16 ( * state_type) ?;
389
- writer. write_u4 ( reg) ?;
390
- writer. write_u4 ( u4 :: ZERO ) ?;
422
+ writer. write_u5 ( reg) ?;
423
+ writer. write_u3 ( u3 :: ZERO ) ?;
391
424
}
392
425
ContractOp :: CnC ( state_type, reg) => {
393
426
writer. write_u16 ( * state_type) ?;
394
- writer. write_u4 ( reg) ?;
395
- writer. write_u4 ( u4 :: ZERO ) ?;
427
+ writer. write_u5 ( reg) ?;
428
+ writer. write_u3 ( u3 :: ZERO ) ?;
396
429
}
397
430
ContractOp :: LdP ( state_type, index, reg) => {
398
431
writer. write_u16 ( * state_type) ?;
@@ -409,8 +442,8 @@ impl Bytecode for ContractOp {
409
442
ContractOp :: LdF ( state_type, index, reg) => {
410
443
writer. write_u16 ( * state_type) ?;
411
444
writer. write_u16 ( * index) ?;
412
- writer. write_u4 ( reg) ?;
413
- writer. write_u4 ( u4 :: ZERO ) ?;
445
+ writer. write_u5 ( reg) ?;
446
+ writer. write_u3 ( u3 :: ZERO ) ?;
414
447
}
415
448
ContractOp :: LdG ( state_type, index, reg) => {
416
449
writer. write_u16 ( * state_type) ?;
@@ -447,22 +480,22 @@ impl Bytecode for ContractOp {
447
480
{
448
481
Ok ( match reader. read_u8 ( ) ? {
449
482
INSTR_CNP => {
450
- let i = Self :: CnP ( reader. read_u16 ( ) ?. into ( ) , reader. read_u4 ( ) ?. into ( ) ) ;
483
+ let i = Self :: CnP ( reader. read_u16 ( ) ?. into ( ) , reader. read_u5 ( ) ?. into ( ) ) ;
451
484
reader. read_u4 ( ) ?; // Discard garbage bits
452
485
i
453
486
}
454
487
INSTR_CNS => {
455
- let i = Self :: CnS ( reader. read_u16 ( ) ?. into ( ) , reader. read_u4 ( ) ?. into ( ) ) ;
488
+ let i = Self :: CnS ( reader. read_u16 ( ) ?. into ( ) , reader. read_u5 ( ) ?. into ( ) ) ;
456
489
reader. read_u4 ( ) ?; // Discard garbage bits
457
490
i
458
491
}
459
492
INSTR_CNG => {
460
- let i = Self :: CnG ( reader. read_u16 ( ) ?. into ( ) , reader. read_u4 ( ) ?. into ( ) ) ;
493
+ let i = Self :: CnG ( reader. read_u16 ( ) ?. into ( ) , reader. read_u5 ( ) ?. into ( ) ) ;
461
494
reader. read_u4 ( ) ?; // Discard garbage bits
462
495
i
463
496
}
464
497
INSTR_CNC => {
465
- let i = Self :: CnC ( reader. read_u16 ( ) ?. into ( ) , reader. read_u4 ( ) ?. into ( ) ) ;
498
+ let i = Self :: CnC ( reader. read_u16 ( ) ?. into ( ) , reader. read_u5 ( ) ?. into ( ) ) ;
466
499
reader. read_u4 ( ) ?; // Discard garbage bits
467
500
i
468
501
}
@@ -489,7 +522,7 @@ impl Bytecode for ContractOp {
489
522
let i = Self :: LdF (
490
523
reader. read_u16 ( ) ?. into ( ) ,
491
524
reader. read_u16 ( ) ?,
492
- reader. read_u4 ( ) ?. into ( ) ,
525
+ reader. read_u5 ( ) ?. into ( ) ,
493
526
) ;
494
527
reader. read_u4 ( ) ?; // Discard garbage bits
495
528
i
0 commit comments