1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Add namespaces to Fift (#641)

* Add fift-based disassembler

* Fift improvements: namespaces, hashmaps, flow controls

* Fift: add lib with better block structuring and more

* Minor changes in fift HashMap + tests (#643)

* Minor changes in fift HashMap

* Add tests for extended fift

---------

Co-authored-by: OmicronTau <omicron@ton.org>
Co-authored-by: Tolya <1449561+tolya-yanot@users.noreply.github.com>
Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
EmelyanenkoK 2023-03-10 14:16:29 +03:00 committed by GitHub
parent 4590ed381b
commit 865ebfce8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 2323 additions and 699 deletions

View file

@ -38,8 +38,8 @@ int exec_push_tinyint4(VmState* st, unsigned args) {
std::string dump_push_tinyint4(CellSlice&, unsigned args) {
int x = (int)((args + 5) & 15) - 5;
std::ostringstream os{"PUSHINT "};
os << x;
std::ostringstream os;
os << "PUSHINT " << x;
return os.str();
}
@ -53,8 +53,8 @@ int exec_push_tinyint8(VmState* st, unsigned args) {
std::string dump_op_tinyint8(const char* op_prefix, CellSlice&, unsigned args) {
int x = (signed char)args;
std::ostringstream os{op_prefix};
os << x;
std::ostringstream os;
os << op_prefix << x;
return os.str();
}
@ -68,8 +68,8 @@ int exec_push_smallint(VmState* st, unsigned args) {
std::string dump_push_smallint(CellSlice&, unsigned args) {
int x = (short)args;
std::ostringstream os{"PUSHINT "};
os << x;
std::ostringstream os;
os << "PUSHINT " << x;
return os.str();
}
@ -93,8 +93,8 @@ std::string dump_push_int(CellSlice& cs, unsigned args, int pfx_bits) {
}
cs.advance(pfx_bits);
td::RefInt256 x = cs.fetch_int256(3 + l * 8);
std::ostringstream os{"PUSHINT "};
os << x;
std::ostringstream os;
os << "PUSHINT " << x;
return os.str();
}
@ -302,7 +302,7 @@ std::string dump_divmod(CellSlice&, unsigned args, bool quiet) {
if (quiet) {
s = "Q" + s;
}
return s + "FRC"[round_mode];
return round_mode ? s + "FRC"[round_mode] : s;
}
int exec_shrmod(VmState* st, unsigned args, int mode) {
@ -352,28 +352,28 @@ std::string dump_shrmod(CellSlice&, unsigned args, int mode) {
if (!(args & 12) || round_mode == 3) {
return "";
}
std::string s;
std::ostringstream os;
if (mode & 1) {
os << 'Q';
}
switch (args & 12) {
case 4:
s = "RSHIFT";
os << "RSHIFT";
break;
case 8:
s = "MODPOW2";
os << "MODPOW2";
break;
case 12:
s = "RSHIFTMOD";
os << "RSHIFTMOD";
break;
}
if (mode & 1) {
s = "Q" + s;
if (round_mode) {
os << "FRC"[round_mode];
}
s += "FRC"[round_mode];
if (mode & 2) {
char buff[8];
sprintf(buff, " %d", y);
s += buff;
os << ' ' << y;
}
return s;
return os.str();
}
int exec_muldivmod(VmState* st, unsigned args, int quiet) {
@ -417,7 +417,7 @@ std::string dump_muldivmod(CellSlice&, unsigned args, bool quiet) {
if (quiet) {
s = "Q" + s;
}
return s + "FRC"[round_mode];
return round_mode ? s + "FRC"[round_mode] : s;
}
int exec_mulshrmod(VmState* st, unsigned args, int mode) {
@ -474,28 +474,28 @@ std::string dump_mulshrmod(CellSlice&, unsigned args, int mode) {
if (!(args & 12) || round_mode == 3) {
return "";
}
std::string s;
std::ostringstream os;
if (mode & 1) {
os << 'Q';
}
switch (args & 12) {
case 4:
s = "MULRSHIFT";
os << "MULRSHIFT";
break;
case 8:
s = "MULMODPOW2";
os << "MULMODPOW2";
break;
case 12:
s = "MULRSHIFTMOD";
os << "MULRSHIFTMOD";
break;
}
if (mode & 1) {
s = "Q" + s;
if (round_mode) {
os << "FRC"[round_mode];
}
s += "FRC"[round_mode];
if (mode & 2) {
char buff[8];
sprintf(buff, " %d", y);
s += buff;
os << ' ' << y;
}
return s;
return os.str();
}
int exec_shldivmod(VmState* st, unsigned args, int mode) {
@ -542,19 +542,25 @@ int exec_shldivmod(VmState* st, unsigned args, int mode) {
return 0;
}
std::string dump_shldivmod(CellSlice&, unsigned args, bool quiet) {
std::string dump_shldivmod(CellSlice&, unsigned args, int mode) {
int y = -1;
if (mode & 2) {
y = (args & 0xff) + 1;
args >>= 8;
}
int round_mode = (int)(args & 3);
if (!(args & 12) || round_mode == 3) {
return "";
}
std::string s = (args & 4) ? "LSHIFTDIV" : "LSHIFT";
if (args & 8) {
s += "MOD";
std::ostringstream os;
os << (mode & 1 ? "Q" : "") << (args & 4 ? "LSHIFTDIV" : "LSHIFT") << (args & 8 ? "MOD" : "");
if (round_mode) {
os << "FRC"[round_mode];
}
if (quiet) {
s = "Q" + s;
if (y >= 0) {
os << ' ' << y;
}
return s + "FRC"[round_mode];
return os.str();
}
void register_div_ops(OpcodeTable& cp0) {

View file

@ -30,7 +30,7 @@ class Box : public td::CntObject {
Box(const Box&) = default;
Box(Box&&) = default;
template <typename... Args>
Box(Args... args) : data_{std::move(args...)} {
Box(Args&&... args) : data_{std::forward<Args>(args)...} {
}
~Box() override = default;
Box(const StackEntry& data) : data_(data) {

View file

@ -103,7 +103,8 @@ std::string dump_push_slice_common(CellSlice& cs, unsigned data_bits, unsigned r
cs.advance(pfx_bits);
auto slice = cs.fetch_subslice(data_bits, refs);
slice.unique_write().remove_trailing();
std::ostringstream os{name};
std::ostringstream os;
os << name;
slice->dump_hex(os, 1, false);
return os.str();
}
@ -188,7 +189,8 @@ std::string dump_push_cont(CellSlice& cs, unsigned args, int pfx_bits) {
}
cs.advance(pfx_bits);
auto slice = cs.fetch_subslice(data_bits, refs);
std::ostringstream os{"PUSHCONT "};
std::ostringstream os;
os << "PUSHCONT ";
slice->dump_hex(os, 1, false);
return os.str();
}
@ -219,7 +221,8 @@ std::string dump_push_cont_simple(CellSlice& cs, unsigned args, int pfx_bits) {
}
cs.advance(pfx_bits);
auto slice = cs.fetch_subslice(data_bits);
std::ostringstream os{"PUSHCONT "};
std::ostringstream os;
os << "PUSHCONT ";
slice->dump_hex(os, 1, false);
return os.str();
}
@ -1060,8 +1063,8 @@ int exec_load_int_fixed2(VmState* st, unsigned args) {
}
std::string dump_load_int_fixed2(CellSlice&, unsigned args) {
std::ostringstream os{args & 0x200 ? "PLD" : "LD"};
os << (args & 0x100 ? 'U' : 'I');
std::ostringstream os;
os << (args & 0x200 ? "PLD" : "LD") << (args & 0x100 ? 'U' : 'I');
if (args & 0x400) {
os << 'Q';
}
@ -1081,9 +1084,9 @@ int exec_preload_uint_fixed_0e(VmState* st, unsigned args) {
}
std::string dump_preload_uint_fixed_0e(CellSlice&, unsigned args) {
std::ostringstream os{"PLDUZ "};
std::ostringstream os;
unsigned bits = ((args & 7) + 1) << 5;
os << bits;
os << "PLDUZ " << bits;
return os.str();
}
@ -1108,7 +1111,8 @@ int exec_load_slice_fixed2(VmState* st, unsigned args) {
std::string dump_load_slice_fixed2(CellSlice&, unsigned args) {
unsigned bits = (args & 0xff) + 1;
std::ostringstream os{args & 0x100 ? "PLDSLICE" : "LDSLICE"};
std::ostringstream os;
os << (args & 0x100 ? "PLDSLICE" : "LDSLICE");
if (args & 0x200) {
os << 'Q';
}

View file

@ -378,8 +378,8 @@ int exec_if_bit_jmp(VmState* st, unsigned args) {
}
std::string dump_if_bit_jmp(CellSlice& cs, unsigned args) {
std::ostringstream os{args & 0x20 ? "IFN" : " IF"};
os << "BITJMP " << (args & 0x1f);
std::ostringstream os;
os << "IF" << (args & 0x20 ? "N" : "") << "BITJMP " << (args & 0x1f);
return os.str();
}
@ -408,8 +408,8 @@ std::string dump_if_bit_jmpref(CellSlice& cs, unsigned args, int pfx_bits) {
}
cs.advance(pfx_bits);
cs.advance_refs(1);
std::ostringstream os{args & 0x20 ? "IFN" : " IF"};
os << "BITJMPREF " << (args & 0x1f);
std::ostringstream os;
os << "IF" << (args & 0x20 ? "N" : "") << "BITJMPREF " << (args & 0x1f);
return os.str();
}
@ -597,8 +597,8 @@ int exec_setcontargs(VmState* st, unsigned args) {
std::string dump_setcontargs(CellSlice& cs, unsigned args, const char* name) {
int copy = (args >> 4) & 15, more = ((args + 1) & 15) - 1;
std::ostringstream os{name};
os << ' ' << copy << ',' << more;
std::ostringstream os;
os << name << ' ' << copy << ',' << more;
return os.str();
}
@ -1065,8 +1065,8 @@ std::string dump_throw_any(CellSlice& cs, unsigned args) {
bool has_param = args & 1;
bool has_cond = args & 6;
bool throw_cond = args & 2;
std::ostringstream os{has_param ? "THROWARG" : "THROW"};
os << "ANY";
std::ostringstream os;
os << "THROW" << (has_param ? "ARG" : "") << "ANY";
if (has_cond) {
os << (throw_cond ? "IF" : "IFNOT");
}

View file

@ -172,7 +172,8 @@ int exec_load_dict(VmState* st, unsigned args) {
}
std::string dump_dictop(unsigned args, const char* name) {
std::ostringstream os{"DICT"};
std::ostringstream os;
os << "DICT";
if (args & 4) {
os << (args & 2 ? 'U' : 'I');
}
@ -184,7 +185,8 @@ std::string dump_dictop(unsigned args, const char* name) {
}
std::string dump_dictop2(unsigned args, const char* name) {
std::ostringstream os{"DICT"};
std::ostringstream os;
os << "DICT";
if (args & 2) {
os << (args & 1 ? 'U' : 'I');
}
@ -193,7 +195,8 @@ std::string dump_dictop2(unsigned args, const char* name) {
}
std::string dump_subdictop2(unsigned args, const char* name) {
std::ostringstream os{"SUBDICT"};
std::ostringstream os;
os << "SUBDICT";
if (args & 2) {
os << (args & 1 ? 'U' : 'I');
}
@ -508,7 +511,8 @@ int exec_dict_getmin(VmState* st, unsigned args) {
}
std::string dump_dictop_getnear(CellSlice& cs, unsigned args) {
std::ostringstream os{"DICT"};
std::ostringstream os;
os << "DICT";
if (args & 8) {
os << (args & 4 ? 'U' : 'I');
}
@ -637,8 +641,8 @@ std::string dump_push_const_dict(CellSlice& cs, int pfx_bits, const char* name)
cs.advance(pfx_bits - 11);
auto slice = cs.fetch_subslice(1, 1);
int n = (int)cs.fetch_ulong(10);
std::ostringstream os{name};
os << ' ' << n << " (";
std::ostringstream os;
os << name << ' ' << n << " (";
slice->dump_hex(os, false);
os << ')';
return os.str();

View file

@ -357,32 +357,32 @@ using namespace std::placeholders;
dump_arg_instr_func_t dump_1sr(std::string prefix, std::string suffix) {
return [prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << 's' << (args & 15) << suffix;
std::ostringstream os;
os << prefix << 's' << (args & 15) << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_1sr_l(std::string prefix, std::string suffix) {
return [prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << 's' << (args & 255) << suffix;
std::ostringstream os;
os << prefix << 's' << (args & 255) << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_2sr(std::string prefix, std::string suffix) {
return [prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << 's' << ((args >> 4) & 15) << ",s" << (args & 15) << suffix;
std::ostringstream os;
os << prefix << 's' << ((args >> 4) & 15) << ",s" << (args & 15) << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_2sr_adj(unsigned adj, std::string prefix, std::string suffix) {
return [adj, prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << 's' << (int)((args >> 4) & 15) - (int)((adj >> 4) & 15) << ",s" << (int)(args & 15) - (int)(adj & 15)
std::ostringstream os;
os << prefix << 's' << (int)((args >> 4) & 15) - (int)((adj >> 4) & 15) << ",s" << (int)(args & 15) - (int)(adj & 15)
<< suffix;
return os.str();
};
@ -390,16 +390,16 @@ dump_arg_instr_func_t dump_2sr_adj(unsigned adj, std::string prefix, std::string
dump_arg_instr_func_t dump_3sr(std::string prefix, std::string suffix) {
return [prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << 's' << ((args >> 8) & 15) << ",s" << ((args >> 4) & 15) << ",s" << (args & 15) << suffix;
std::ostringstream os;
os << prefix << 's' << ((args >> 8) & 15) << ",s" << ((args >> 4) & 15) << ",s" << (args & 15) << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_3sr_adj(unsigned adj, std::string prefix, std::string suffix) {
return [adj, prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << 's' << (int)((args >> 8) & 15) - (int)((adj >> 8) & 15) << ",s"
std::ostringstream os;
os << prefix << 's' << (int)((args >> 8) & 15) - (int)((adj >> 8) & 15) << ",s"
<< (int)((args >> 4) & 15) - (int)((adj >> 4) & 15) << ",s" << (int)(args & 15) - (int)(adj & 15) << suffix;
return os.str();
};
@ -407,40 +407,40 @@ dump_arg_instr_func_t dump_3sr_adj(unsigned adj, std::string prefix, std::string
dump_arg_instr_func_t dump_1c(std::string prefix, std::string suffix) {
return [prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << (args & 15) << suffix;
std::ostringstream os;
os << prefix << (args & 15) << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_1c_l_add(int adj, std::string prefix, std::string suffix) {
return [adj, prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << (int)(args & 255) + adj << suffix;
std::ostringstream os;
os << prefix << (int)(args & 255) + adj << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_1c_and(unsigned mask, std::string prefix, std::string suffix) {
return [mask, prefix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << (args & mask) << suffix;
std::ostringstream os;
os << prefix << (args & mask) << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_2c(std::string prefix, std::string interfix, std::string suffix) {
return [prefix, interfix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << ((args >> 4) & 15) << interfix << (args & 15) << suffix;
std::ostringstream os;
os << prefix << ((args >> 4) & 15) << interfix << (args & 15) << suffix;
return os.str();
};
}
dump_arg_instr_func_t dump_2c_add(unsigned add, std::string prefix, std::string interfix, std::string suffix) {
return [add, prefix, interfix, suffix](CellSlice&, unsigned args) -> std::string {
std::ostringstream os{prefix};
os << ((args >> 4) & 15) + ((add >> 4) & 15) << interfix << (args & 15) + (add & 15) << suffix;
std::ostringstream os;
os << prefix << ((args >> 4) & 15) + ((add >> 4) & 15) << interfix << (args & 15) + (add & 15) << suffix;
return os.str();
};
}

View file

@ -103,6 +103,9 @@ class StackEntry {
}
StackEntry(td::RefInt256 int_ref) : ref(std::move(int_ref)), tp(t_int) {
}
StackEntry(Ref<Cnt<std::string>> str_ref, bool bytes = false)
: ref(std::move(str_ref)), tp(bytes ? t_bytes : t_string) {
}
StackEntry(std::string str, bool bytes = false) : ref(), tp(bytes ? t_bytes : t_string) {
ref = Ref<Cnt<std::string>>{true, std::move(str)};
}

View file

@ -75,8 +75,8 @@ std::string dump_xchg(CellSlice&, unsigned args) {
if (!x || x >= y) {
return "";
}
std::ostringstream os{"XCHG s"};
os << x << ",s" << y;
std::ostringstream os;
os << "XCHG s" << x << ",s" << y;
return os.str();
}
@ -92,7 +92,7 @@ int exec_xchg1(VmState* st, unsigned args) {
int exec_dup(VmState* st) {
Stack& stack = st->get_stack();
VM_LOG(st) << "execute DUP\n";
VM_LOG(st) << "execute DUP";
stack.check_underflow(1);
stack.push(stack.fetch(0));
return 0;
@ -100,7 +100,7 @@ int exec_dup(VmState* st) {
int exec_over(VmState* st) {
Stack& stack = st->get_stack();
VM_LOG(st) << "execute OVER\n";
VM_LOG(st) << "execute OVER";
stack.check_underflow(2);
stack.push(stack.fetch(1));
return 0;
@ -126,7 +126,7 @@ int exec_push_l(VmState* st, unsigned args) {
int exec_drop(VmState* st) {
Stack& stack = st->get_stack();
VM_LOG(st) << "execute DROP\n";
VM_LOG(st) << "execute DROP";
stack.check_underflow(1);
stack.pop();
return 0;
@ -134,7 +134,7 @@ int exec_drop(VmState* st) {
int exec_nip(VmState* st) {
Stack& stack = st->get_stack();
VM_LOG(st) << "execute NIP\n";
VM_LOG(st) << "execute NIP";
stack.check_underflow(2);
stack.pop(stack[1]);
return 0;