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

updated vm (breaking compatibility)

- updated vm
- new actor scheduler
- updated tonlib
- updated DNS smartcontract
This commit is contained in:
ton 2020-02-28 14:28:47 +04:00
parent 9e4816e7f6
commit e27fb1e09c
100 changed files with 3692 additions and 1299 deletions

View file

@ -138,7 +138,7 @@ void VarDescr::show(std::ostream& os, const char* name) const {
}
void VarDescr::set_const(long long value) {
return set_const(td::RefInt256{true, value});
return set_const(td::make_refint(value));
}
void VarDescr::set_const(td::RefInt256 value) {
@ -169,7 +169,7 @@ void VarDescr::set_const(td::RefInt256 value) {
}
void VarDescr::set_const_nan() {
set_const(td::RefInt256{true});
set_const(td::make_refint());
}
void VarDescr::operator|=(const VarDescr& y) {

View file

@ -628,7 +628,7 @@ AsmOp compile_mod(std::vector<VarDescr>& res, std::vector<VarDescr>& args, int r
if ((*y.int_const == 1 || *y.int_const == -1) && x.always_finite()) {
x.unused();
y.unused();
r.set_const(td::RefInt256{true, 0});
r.set_const(td::zero_refint());
return push_const(r.int_const);
}
int k = is_pos_pow2(y.int_const);

View file

@ -934,7 +934,7 @@ struct AsmOp {
void out_indent_nl(std::ostream& os, bool no_nl = false) const;
std::string to_string() const;
void compute_gconst() {
gconst = (is_custom() && (op == "PUSHNULL" || op == "NEWC"));
gconst = (is_custom() && (op == "PUSHNULL" || op == "NEWC" || op == "NEWB" || op == "TRUE" || op == "FALSE"));
}
bool is_nop() const {
return t == a_none && op.empty();
@ -975,6 +975,9 @@ struct AsmOp {
*y = b;
return is_xchg();
}
bool is_xchg_short() const {
return is_xchg() && (a <= 1 || b <= 1);
}
bool is_swap() const {
return is_xchg(0, 1);
}
@ -1265,10 +1268,14 @@ struct StackTransform {
}
bool is_xchg(int i, int j) const;
bool is_xchg(int* i, int* j) const;
bool is_xchg_xchg(int i, int j, int k, int l) const;
bool is_xchg_xchg(int* i, int* j, int* k, int* l) const;
bool is_push(int i) const;
bool is_push(int* i) const;
bool is_pop(int i) const;
bool is_pop(int* i) const;
bool is_pop_pop(int i, int j) const;
bool is_pop_pop(int* i, int* j) const;
bool is_rot() const;
bool is_rotrev() const;
bool is_push_rot(int i) const;
@ -1407,8 +1414,10 @@ struct Optimizer {
bool is_2swap();
bool is_2over();
bool is_xchg(int* i, int* j);
bool is_xchg_xchg(int* i, int* j, int* k, int* l);
bool is_push(int* i);
bool is_pop(int* i);
bool is_pop_pop(int* i, int* j);
bool is_nop();
bool is_push_rot(int* i);
bool is_push_rotrev(int* i);

View file

@ -393,6 +393,13 @@ bool Optimizer::is_xchg(int* i, int* j) {
return is_pred([i, j](const auto& t) { return t.is_xchg(i, j) && ((*i < 16 && *j < 16) || (!*i && *j < 256)); });
}
bool Optimizer::is_xchg_xchg(int* i, int* j, int* k, int* l) {
return is_pred([i, j, k, l](const auto& t) {
return t.is_xchg_xchg(i, j, k, l) && (*i < 2 && *j < (*i ? 16 : 256) && *k < 2 && *l < (*k ? 16 : 256));
}) &&
(!(p_ == 2 && op_[0]->is_xchg(*i, *j) && op_[1]->is_xchg(*k, *l)));
}
bool Optimizer::is_push(int* i) {
return is_pred([i](const auto& t) { return t.is_push(i) && *i < 256; });
}
@ -401,6 +408,10 @@ bool Optimizer::is_pop(int* i) {
return is_pred([i](const auto& t) { return t.is_pop(i) && *i < 256; });
}
bool Optimizer::is_pop_pop(int* i, int* j) {
return is_pred([i, j](const auto& t) { return t.is_pop_pop(i, j) && *i < 256 && *j < 256; }, 3);
}
bool Optimizer::is_push_rot(int* i) {
return is_pred([i](const auto& t) { return t.is_push_rot(i) && *i < 16; }, 3);
}
@ -543,12 +554,13 @@ bool Optimizer::find_at_least(int pb) {
p_ = q_ = 0;
pb_ = pb;
// show_stack_transforms();
int i = -100, j = -100, k = -100, c = 0;
int i, j, k, l, c;
return (is_push_const(&i, &c) && rewrite_push_const(i, c)) || (is_nop() && rewrite_nop()) ||
(!(mode_ & 1) && is_const_rot(&c) && rewrite_const_rot(c)) ||
(is_const_push_xchgs() && rewrite_const_push_xchgs()) || (is_const_pop(&c, &i) && rewrite_const_pop(c, i)) ||
(is_xchg(&i, &j) && rewrite(AsmOp::Xchg(i, j))) || (is_push(&i) && rewrite(AsmOp::Push(i))) ||
(is_pop(&i) && rewrite(AsmOp::Pop(i))) ||
(is_pop(&i) && rewrite(AsmOp::Pop(i))) || (is_pop_pop(&i, &j) && rewrite(AsmOp::Pop(i), AsmOp::Pop(j))) ||
(is_xchg_xchg(&i, &j, &k, &l) && rewrite(AsmOp::Xchg(i, j), AsmOp::Xchg(k, l))) ||
(!(mode_ & 1) &&
((is_rot() && rewrite(AsmOp::Custom("ROT", 3, 3))) || (is_rotrev() && rewrite(AsmOp::Custom("-ROT", 3, 3))) ||
(is_2dup() && rewrite(AsmOp::Custom("2DUP", 2, 4))) ||
@ -629,10 +641,9 @@ void optimize_code(AsmOpList& ops) {
for (auto it = ops.list_.rbegin(); it < ops.list_.rend(); ++it) {
op_list = AsmOpCons::cons(std::make_unique<AsmOp>(std::move(*it)), std::move(op_list));
}
op_list = optimize_code(std::move(op_list), 1);
op_list = optimize_code(std::move(op_list), 1);
op_list = optimize_code(std::move(op_list), 0);
op_list = optimize_code(std::move(op_list), 0);
for (int mode : {1, 1, 1, 1, 0, 0, 0, 0}) {
op_list = optimize_code(std::move(op_list), mode);
}
ops.list_.clear();
while (op_list) {
ops.list_.push_back(std::move(*(op_list->car)));

View file

@ -401,6 +401,57 @@ bool StackTransform::is_xchg(int *i, int *j) const {
return true;
}
bool StackTransform::is_xchg_xchg(int i, int j, int k, int l) const {
if (is_valid() && !d && n <= 4 && (i | j | k | l) >= 0) {
StackTransform t;
return t.apply_xchg(i, j) && t.apply_xchg(k, l) && t <= *this;
} else {
return false;
}
}
bool StackTransform::is_xchg_xchg(int *i, int *j, int *k, int *l) const {
if (!is_valid() || d || n > 4 || !dp || !is_permutation()) {
return false;
}
if (!n) {
*i = *j = *k = *l = 0;
return true;
}
if (n <= 2) {
*k = *l = 0;
return is_xchg(i, j);
}
if (n == 3) {
// rotation: a -> b -> c -> a
int a = A[0].first;
int b = A[0].second;
int s = (b == A[2].first ? 2 : 1);
int c = A[s].second;
if (b != A[s].first || c != A[3 - s].first || a != A[3 - s].second) {
return false;
}
// implement as XCHG s(a),s(c) ; XCHG s(a),s(b)
*i = *k = a;
*j = c;
*l = b;
return is_xchg_xchg(*i, *j, *k, *l);
}
*i = A[0].first;
*j = A[0].second;
if (get(*j) != *i) {
return false;
}
for (int s = 1; s < 4; s++) {
if (A[s].first != *j) {
*k = A[s].first;
*l = A[s].second;
return get(*l) == *k && is_xchg_xchg(*i, *j, *k, *l);
}
}
return false;
}
bool StackTransform::is_push(int i) const {
return is_valid() && d == -1 && n == 1 && A[0].first == -1 && A[0].second == i;
}
@ -418,6 +469,7 @@ bool StackTransform::is_push(int *i) const {
// 0 2 3 4 .. = pop1
// 1 0 3 4 .. = pop2
// 1 2 0 4 .. = pop3
// POP s(i) : 1 2 ... i-1 0 i+1 ... ; d=1, n=1, {(i,0)}
bool StackTransform::is_pop(int i) const {
if (!is_valid() || d != 1 || n > 1 || i < 0) {
return false;
@ -443,6 +495,38 @@ bool StackTransform::is_pop(int *i) const {
return false;
}
// POP s(i) ; POP s(j) : 2 ... i-1 0 i+1 ... j 1 j+2 ... ; d=2, n=2, {(i,0),(j+1,1)} if i <> j+1
bool StackTransform::is_pop_pop(int i, int j) const {
if (is_valid() && d == 2 && n <= 2 && i >= 0 && j >= 0) {
StackTransform t;
return t.apply_pop(i) && t.apply_pop(j) && t <= *this;
} else {
return false;
}
}
bool StackTransform::is_pop_pop(int *i, int *j) const {
if (!is_valid() || d != 2 || n > 2) {
return false;
}
if (!n) {
*i = *j = 0; // 2DROP
} else if (n == 2) {
*i = A[0].first - A[0].second;
*j = A[1].first - A[1].second;
if (A[0].second > A[1].second) {
std::swap(*i, *j);
}
} else if (!A[0].second) {
*i = A[0].first;
*j = 0;
} else {
*i = 0;
*j = A[0].first - 1;
}
return is_pop_pop(*i, *j);
}
const StackTransform StackTransform::rot{2, 0, 1, 3};
const StackTransform StackTransform::rot_rev{1, 2, 0, 3};
@ -519,10 +603,9 @@ bool StackTransform::is_xchg2(int *i, int *j) const {
if (*i < 0 || *j < 0) {
return false;
}
if (n != 3) {
return is_xchg2(*i, *j);
}
if (*i) {
if (n == 2 && !*i) {
*j = *i; // XCHG s0,s1 = XCHG2 s0,s0
} else if (n == 3 && *i) {
// XCHG2 s(i),s(i) = XCHG s1,s(i) ; XCHG s0,s(i) : 0->1, 1->i
*j = *i;
} // XCHG2 s0,s(i) = XCHG s0,s1 ; XCHG s0,s(i) : 0->i, 1->0