Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add disasm libs #851

Open
wants to merge 6 commits into
base: testnet
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions crypto/fift/lib/Disasm.fif
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,30 @@ library TVM_Disasm
// simple TVM Disassembler
"Lists.fif" include

variable @vmlibs dictnew @vmlibs !
{ 256 u@ dup @vmlibs @ 256 udict@ } : vmlib@
{ 8 u@+ swap 2 = } : libspecial?

variable 'disasm
{ 'disasm @ execute } : disasm // disassemble a slice
{ <spec {
libspecial? {
vmlib@ {
."// LIB: " swap X. cr ref@ <s disasm
} {
drop // Lib not found
} cond
} {
drop // Only library special cell supported
} cond
} { disasm } cond } : disasmc // disassemble a cell
// usage: x{74B0} disasm

variable @dismode @dismode 0!
{ rot over @ and rot xor swap ! } : andxor!
{ -2 0 @dismode andxor! } : stack-disasm // output 's1 s4 XCHG'
{ -2 1 @dismode andxor! } : std-disasm // output 'XCHG s1, s4'
{ -3 2 @dismode andxor! } : show-vm-code
{ -3 0 @dismode andxor! } : hide-vm-code
{ @dismode @ 1 and 0= } : stack-disasm?

variable @indent @indent 0!
Expand Down Expand Up @@ -45,7 +59,7 @@ variable @indent @indent 0!
drop dup count 2 = stack-disasm? and { second `LSHIFT# swap pair } if } {
dup `RSHIFT eq? {
drop dup count 2 = stack-disasm? and { second `RSHIFT# swap pair } if } {
drop
drop
} cond } cond } cond
} : adjust-op

Expand All @@ -56,12 +70,32 @@ variable @contX variable @contY variable @cdict
{ atom>$ type } : .atom
{ dup first .atom dup count 1 > { space 0 over count 2- { 1+ 2dup [] type .", " } swap times 1+ [] type } { drop } cond } : std-show-op
{ 0 over count 1- { 1+ 2dup [] type space } swap times drop first .atom } : stk-show-op
{ @dismode @ 2 and { .indent ."// " @curop @ csr. } if } : .curop?

{ ."// LIB: " swap X. cr ref@ <s +indent +indent disasm -indent -indent } : .ilib-disasm
{
@curop @ dup 8 u@
dup dup dup 0x88 = swap 0x89 = rot 0x8A = or or { // PUSHREF, PUSHREFSLICE, PUSHREFCONT
drop ref@ <spec { libspecial? { vmlib@ { .ilib-disasm }
{ drop } cond
} { drop } cond
} { drop } cond
}
{ // add IFREFELSE, ... opcodes if needed
2drop
} cond
} : lib-disasm
{
@dismode @ 2 and { .indent ."// " @curop @ csr. } if
lib-disasm
} : .curop?
{ .curop? .indent @dismode @ 1 and ' std-show-op ' stk-show-op cond cr
} : show-simple-op
{ dup 4 u@ 9 = { 8 u@+ swap 15 and 3 << s@ } {
dup 7 u@ 0x47 = { 7 u@+ nip 2 u@+ 7 u@+ -rot 3 << swap sr@ } {
dup 8 u@ 0x8A = { ref@ <s } {
dup 8 u@ 0x8A = { ref@ <spec {
libspecial? {
vmlib@ { swap drop <s } { abort"Lib not found" } cond
} { abort"Invalid special cell" } } if } {
abort"invalid PUSHCONT"
} cond } cond } cond
} : get-cont-body
Expand Down Expand Up @@ -104,7 +138,7 @@ variable @contX variable @contY variable @cdict
.indent type ." {" cr +indent @cdict @ @cdict null! unpair
rot {
swap .indent . ."=> <{" cr +indent disasm -indent .indent ."}>" cr true
} swap ' idictforeach ' dictforeach cond drop
} swap ' idictforeach ' dictforeach cond drop
-indent .indent ."}" cr
} : show-const-dict-op

Expand Down
19 changes: 13 additions & 6 deletions crypto/fift/words.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,13 +1028,19 @@ void interpret_store_end(vm::Stack& stack, bool special) {
stack.push_cell(std::move(cell));
}

void interpret_from_cell(vm::Stack& stack) {
void interpret_from_cell(vm::Stack& stack, bool load_special) {
auto cell = stack.pop_cell();
Ref<vm::CellSlice> cs{true, vm::NoVmOrd(), std::move(cell)};
if (!cs->is_valid()) {
throw IntError{"deserializing a special cell as ordinary"};
bool is_special;
td::Ref<vm::CellSlice> cs = td::make_ref<vm::CellSlice>(vm::load_cell_slice_special(cell, is_special));
if (!load_special) {
if (is_special) {
throw IntError{"deserializing a special cell as ordinary"};
}
stack.push(cs);
} else {
stack.push(cs);
stack.push_bool(is_special);
}
stack.push(cs);
}

// cs n -- cs' x
Expand Down Expand Up @@ -3301,7 +3307,8 @@ void init_words_common(Dictionary& d) {
d.def_stack_word("hashu ", std::bind(interpret_cell_hash, _1, true));
d.def_stack_word("hashB ", std::bind(interpret_cell_hash, _1, false));
// cellslice manipulation (read from cells)
d.def_stack_word("<s ", interpret_from_cell);
d.def_stack_word("<s ", std::bind(interpret_from_cell, _1, false));
d.def_stack_word("<spec ", std::bind(interpret_from_cell, _1, true));
d.def_stack_word("i@ ", std::bind(interpret_fetch, _1, 1));
d.def_stack_word("u@ ", std::bind(interpret_fetch, _1, 0));
d.def_stack_word("i@+ ", std::bind(interpret_fetch, _1, 3));
Expand Down
29 changes: 29 additions & 0 deletions crypto/test/fift/disasm-libs.fif
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"Disasm.fif" include
"Asm.fif" include

PROGRAM{
DECLPROC foo1
DECLPROC foo4
DECLPROC main
foo1 PROC:<{ DUP 137 PUSHINT MUL PAIR }>
foo4 PROC:<{ UNPAIR SWAP DIV }>
main PROC:<{ 70 PUSHINT DIV }>
}END>c constant code-1

// add lib cell to vmlibs
<b code-1 ref, b> <s code-1 hashu @vmlibs @ 256 udict! drop @vmlibs !

// Lib in pushref
<{
<b 2 8 u, code-1 hashu 256 u, b>spec PUSHREF
}>c <s disasm cr


// Lib in pushrefslice
<{
<b 2 8 u, code-1 hashu 256 u, b>spec PUSHREFSLICE
}>c <s disasm cr

// Code cell is lib cell
<b 2 8 u, code-1 hashu 256 u, b>spec disasmc