mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add TVM instructions for working with nonzero-level cells (#880)
Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
64b04e46d7
commit
51d30e2f2b
6 changed files with 156 additions and 1 deletions
|
@ -813,6 +813,12 @@ x{D761} @Defop LDONES
|
|||
x{D762} @Defop LDSAME
|
||||
x{D764} @Defop SDEPTH
|
||||
x{D765} @Defop CDEPTH
|
||||
x{D766} @Defop CLEVEL
|
||||
x{D767} @Defop CLEVELMASK
|
||||
{ <b x{D76A_} s, swap 2 u, @addopb } : CHASHI
|
||||
{ <b x{D76E_} s, swap 2 u, @addopb } : CDEPTHI
|
||||
x{D770} @Defop CHASHIX
|
||||
x{D771} @Defop CDEPTHIX
|
||||
//
|
||||
// continuation / flow control primitives
|
||||
x{D8} dup @Defop EXECUTE @Defop CALLX
|
||||
|
|
|
@ -163,3 +163,7 @@ TEST(Fift, test_bls) {
|
|||
TEST(Fift, test_bls_ops) {
|
||||
run_fift("bls_ops.fif");
|
||||
}
|
||||
|
||||
TEST(Fift, test_levels) {
|
||||
run_fift("levels.fif");
|
||||
}
|
||||
|
|
75
crypto/test/fift/levels.fif
Normal file
75
crypto/test/fift/levels.fif
Normal file
|
@ -0,0 +1,75 @@
|
|||
"Asm.fif" include
|
||||
"FiftExt.fif" include
|
||||
|
||||
{
|
||||
dup
|
||||
."Cell " .dump cr
|
||||
dup [[ <{ CLEVEL }>s ]] 0 runvmx abort"exitcode != 0" ."Level = " . cr
|
||||
dup [[ <{ CLEVELMASK }>s ]] 0 runvmx abort"exitcode != 0" ."Level mask = 0b" b. cr
|
||||
dup dup [[ <{ 0 CHASHI DUP ROT 0 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_0 = " X. cr
|
||||
dup dup [[ <{ 1 CHASHI DUP ROT 1 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_1 = " X. cr
|
||||
dup dup [[ <{ 2 CHASHI DUP ROT 2 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_2 = " X. cr
|
||||
dup dup [[ <{ 3 CHASHI DUP ROT 3 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_3 = " X. cr
|
||||
dup dup [[ <{ 0 CDEPTHI DUP ROT 0 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_0 = " . cr
|
||||
dup dup [[ <{ 1 CDEPTHI DUP ROT 1 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_1 = " . cr
|
||||
dup dup [[ <{ 2 CDEPTHI DUP ROT 2 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_2 = " . cr
|
||||
dup dup [[ <{ 3 CDEPTHI DUP ROT 3 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_3 = " . cr
|
||||
drop
|
||||
cr
|
||||
} : print-all
|
||||
|
||||
// Ordinary cell of level 0
|
||||
<b
|
||||
123 32 u,
|
||||
<b <b 22 32 u, b> ref, b> ref,
|
||||
<b b> ref,
|
||||
b>
|
||||
print-all
|
||||
|
||||
// Prunned branch of level 1
|
||||
<b
|
||||
1 8 u,
|
||||
1 8 u,
|
||||
0xabcd1111abcd1111abcd1111abcd1111abcd1111abcd1111abcd1111abcd1111 256 u,
|
||||
14 16 u,
|
||||
b>spec
|
||||
print-all
|
||||
|
||||
// Prunned branch of level 3
|
||||
<b
|
||||
1 8 u,
|
||||
7 8 u,
|
||||
0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 256 u,
|
||||
0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 256 u,
|
||||
0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 256 u,
|
||||
55 16 u,
|
||||
44 16 u,
|
||||
33 16 u,
|
||||
b>spec
|
||||
print-all
|
||||
|
||||
// Prunned branch of level 3, mask 0b101
|
||||
<b
|
||||
1 8 u,
|
||||
5 8 u,
|
||||
0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 256 u,
|
||||
0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 256 u,
|
||||
55 16 u,
|
||||
33 16 u,
|
||||
b>spec
|
||||
print-all
|
||||
|
||||
// Tree with the previous cell inside
|
||||
<b
|
||||
<b
|
||||
<b
|
||||
1 8 u,
|
||||
5 8 u,
|
||||
0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 256 u,
|
||||
0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 256 u,
|
||||
55 16 u,
|
||||
33 16 u,
|
||||
b>spec ref,
|
||||
b> ref,
|
||||
b>
|
||||
print-all
|
|
@ -1391,6 +1391,55 @@ int exec_slice_depth(VmState* st) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_level(VmState* st) {
|
||||
Stack& stack = st->get_stack();
|
||||
VM_LOG(st) << "execute CLEVEL";
|
||||
auto cell = stack.pop_cell();
|
||||
stack.push_smallint(cell->get_level());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_level_mask(VmState* st) {
|
||||
Stack& stack = st->get_stack();
|
||||
VM_LOG(st) << "execute CLEVELMASK";
|
||||
auto cell = stack.pop_cell();
|
||||
stack.push_smallint(cell->get_level_mask().get_mask());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_hash_i(VmState* st, unsigned args, bool var) {
|
||||
unsigned i;
|
||||
Stack& stack = st->get_stack();
|
||||
if (var) {
|
||||
VM_LOG(st) << "execute CHASHIX";
|
||||
i = stack.pop_smallint_range(3);
|
||||
} else {
|
||||
i = args & 3;
|
||||
VM_LOG(st) << "execute CHASHI " << i;
|
||||
}
|
||||
auto cell = stack.pop_cell();
|
||||
std::array<unsigned char, 32> hash = cell->get_hash(i).as_array();
|
||||
td::RefInt256 res{true};
|
||||
CHECK(res.write().import_bytes(hash.data(), hash.size(), false));
|
||||
stack.push_int(std::move(res));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_depth_i(VmState* st, unsigned args, bool var) {
|
||||
unsigned i;
|
||||
Stack& stack = st->get_stack();
|
||||
if (var) {
|
||||
VM_LOG(st) << "execute CDEPTHIX";
|
||||
i = stack.pop_smallint_range(3);
|
||||
} else {
|
||||
i = args & 3;
|
||||
VM_LOG(st) << "execute CDEPTHI " << i;
|
||||
}
|
||||
auto cell = stack.pop_cell();
|
||||
stack.push_smallint(cell->get_depth(i));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void register_cell_deserialize_ops(OpcodeTable& cp0) {
|
||||
using namespace std::placeholders;
|
||||
cp0.insert(OpcodeInstr::mksimple(0xd0, 8, "CTOS", exec_cell_to_slice))
|
||||
|
@ -1479,7 +1528,13 @@ void register_cell_deserialize_ops(OpcodeTable& cp0) {
|
|||
.insert(OpcodeInstr::mksimple(0xd761, 16, "LDONES", std::bind(exec_load_same, _1, "LDONES", 1)))
|
||||
.insert(OpcodeInstr::mksimple(0xd762, 16, "LDSAME", std::bind(exec_load_same, _1, "LDSAME", -1)))
|
||||
.insert(OpcodeInstr::mksimple(0xd764, 16, "SDEPTH", exec_slice_depth))
|
||||
.insert(OpcodeInstr::mksimple(0xd765, 16, "CDEPTH", exec_cell_depth));
|
||||
.insert(OpcodeInstr::mksimple(0xd765, 16, "CDEPTH", exec_cell_depth))
|
||||
.insert(OpcodeInstr::mksimple(0xd766, 16, "CLEVEL", exec_cell_level)->require_version(6))
|
||||
.insert(OpcodeInstr::mksimple(0xd767, 16, "CLEVELMASK", exec_cell_level_mask)->require_version(6))
|
||||
.insert(OpcodeInstr::mkfixed(0xd768 >> 2, 14, 2, instr::dump_1c_and(3, "CHASHI "), std::bind(exec_cell_hash_i, _1, _2, false))->require_version(6))
|
||||
.insert(OpcodeInstr::mkfixed(0xd76c >> 2, 14, 2, instr::dump_1c_and(3, "CDEPTHI "), std::bind(exec_cell_depth_i, _1, _2, false))->require_version(6))
|
||||
.insert(OpcodeInstr::mksimple(0xd770, 16, "CHASHIX ", std::bind(exec_cell_hash_i, _1, 0, true))->require_version(6))
|
||||
.insert(OpcodeInstr::mksimple(0xd771, 16, "CDEPTHIX ", std::bind(exec_cell_depth_i, _1, 0, true))->require_version(6));
|
||||
}
|
||||
|
||||
void register_cell_ops(OpcodeTable& cp0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue