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:
parent
9e4816e7f6
commit
e27fb1e09c
100 changed files with 3692 additions and 1299 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue