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:
parent
4590ed381b
commit
865ebfce8d
31 changed files with 2323 additions and 699 deletions
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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)};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue