mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
updated smartcontract code
- updated smartcontract code - fixed bug in liteserver listening socket - updated documentation
This commit is contained in:
parent
38c3e39066
commit
b978e27b2f
63 changed files with 3185 additions and 81 deletions
|
@ -205,6 +205,9 @@ void VarDescr::clear_value() {
|
|||
}
|
||||
|
||||
void VarDescrList::show(std::ostream& os) const {
|
||||
if (unreachable) {
|
||||
os << "<unreachable> ";
|
||||
}
|
||||
os << "[";
|
||||
for (const auto& v : list) {
|
||||
os << ' ' << v;
|
||||
|
|
|
@ -272,6 +272,12 @@ VarDescrList& VarDescrList::operator+=(const VarDescrList& y) {
|
|||
}
|
||||
|
||||
VarDescrList VarDescrList::operator|(const VarDescrList& y) const {
|
||||
if (y.unreachable) {
|
||||
return *this;
|
||||
}
|
||||
if (unreachable) {
|
||||
return y;
|
||||
}
|
||||
VarDescrList res;
|
||||
auto it1 = list.cbegin();
|
||||
auto it2 = y.list.cbegin();
|
||||
|
@ -289,7 +295,11 @@ VarDescrList VarDescrList::operator|(const VarDescrList& y) const {
|
|||
}
|
||||
|
||||
VarDescrList& VarDescrList::operator|=(const VarDescrList& y) {
|
||||
return *this = *this | y;
|
||||
if (y.unreachable) {
|
||||
return *this;
|
||||
} else {
|
||||
return *this = *this | y;
|
||||
}
|
||||
}
|
||||
|
||||
VarDescrList& VarDescrList::operator&=(const VarDescrList& values) {
|
||||
|
@ -299,16 +309,22 @@ VarDescrList& VarDescrList::operator&=(const VarDescrList& values) {
|
|||
*item &= vd;
|
||||
}
|
||||
}
|
||||
unreachable |= values.unreachable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VarDescrList& VarDescrList::import_values(const VarDescrList& values) {
|
||||
for (const VarDescr& vd : values.list) {
|
||||
VarDescr* item = operator[](vd.idx);
|
||||
if (item) {
|
||||
item->set_value(vd);
|
||||
if (values.unreachable) {
|
||||
set_unreachable();
|
||||
} else
|
||||
for (auto& vd : list) {
|
||||
auto new_vd = values[vd.idx];
|
||||
if (new_vd) {
|
||||
vd.set_value(*new_vd);
|
||||
} else {
|
||||
vd.clear_value();
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -658,8 +674,11 @@ void Op::prepare_args(VarDescrList values) {
|
|||
const VarDescr* val = values[right[i]];
|
||||
if (val) {
|
||||
args[i].set_value(*val);
|
||||
args[i].clear_unused();
|
||||
// args[i].clear_unused();
|
||||
} else {
|
||||
args[i].clear_value();
|
||||
}
|
||||
args[i].clear_unused();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -670,7 +689,7 @@ VarDescrList Op::fwd_analyze(VarDescrList values) {
|
|||
case _Import:
|
||||
break;
|
||||
case _Return:
|
||||
values.list.clear();
|
||||
values.set_unreachable();
|
||||
break;
|
||||
case _IntConst: {
|
||||
values.add_newval(left[0]).set_const(int_const);
|
||||
|
|
|
@ -668,6 +668,7 @@ AsmOp compile_cmp_int(std::vector<VarDescr>& res, std::vector<VarDescr>& args, i
|
|||
return mode == 7 ? push_const(r.int_const) : AsmOp::BoolConst(v != 0);
|
||||
}
|
||||
int v = compute_compare(x, y, mode);
|
||||
// std::cerr << "compute_compare(" << x << ", " << y << ", " << mode << ") = " << v << std::endl;
|
||||
assert(v);
|
||||
if (!(v & (v - 1))) {
|
||||
r.set_const(v - (v >> 2) - 2);
|
||||
|
@ -685,6 +686,7 @@ AsmOp compile_cmp_int(std::vector<VarDescr>& res, std::vector<VarDescr>& args, i
|
|||
if (v & 4) {
|
||||
r.val &= VarDescr::ConstOne;
|
||||
}
|
||||
// std::cerr << "result: " << r << std::endl;
|
||||
static const char* cmp_int_names[] = {"", "GTINT", "EQINT", "GTINT", "LESSINT", "NEQINT", "LESSINT"};
|
||||
static const char* cmp_names[] = {"", "GREATER", "EQUAL", "GEQ", "LESS", "NEQ", "LEQ", "CMP"};
|
||||
static int cmp_int_delta[] = {0, 0, 0, -1, 0, 0, 1};
|
||||
|
@ -911,6 +913,7 @@ void define_builtins() {
|
|||
define_builtin_func("false", Int, /* AsmOp::Const("FALSE") */ std::bind(compile_bool_const, _1, _2, false));
|
||||
// define_builtin_func("null", Null, AsmOp::Const("PUSHNULL"));
|
||||
define_builtin_func("nil", Tuple, AsmOp::Const("PUSHNULL"));
|
||||
define_builtin_func("Nil", Tuple, AsmOp::Const("NIL"));
|
||||
define_builtin_func("null?", TypeExpr::new_forall({X}, TypeExpr::new_map(X, Int)), compile_is_null);
|
||||
define_builtin_func("cons", TypeExpr::new_forall({X}, TypeExpr::new_map(TypeExpr::new_tensor(X, Tuple), Tuple)),
|
||||
AsmOp::Custom("CONS", 2, 1));
|
||||
|
@ -932,6 +935,10 @@ void define_builtins() {
|
|||
AsmOp::Custom("4 TUPLE", 4, 1));
|
||||
define_builtin_func("untuple4", TypeExpr::new_forall({X, Y, Z, T}, TypeExpr::new_map(Tuple, XYZT)),
|
||||
AsmOp::Custom("4 UNTUPLE", 1, 4));
|
||||
define_builtin_func("first", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("FIRST", 1, 1));
|
||||
define_builtin_func("second", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("SECOND", 1, 1));
|
||||
define_builtin_func("third", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("THIRD", 1, 1));
|
||||
define_builtin_func("fourth", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("3 INDEX", 1, 1));
|
||||
define_builtin_func("throw", impure_un_op, compile_throw, true);
|
||||
define_builtin_func("throw_if", impure_bin_op, std::bind(compile_cond_throw, _1, _2, true), true);
|
||||
define_builtin_func("throw_unless", impure_bin_op, std::bind(compile_cond_throw, _1, _2, false), true);
|
||||
|
@ -947,7 +954,7 @@ void define_builtins() {
|
|||
define_builtin_func("preload_bits", prefetch_slice_op, std::bind(compile_fetch_slice, _1, _2, false));
|
||||
define_builtin_func("int_at", TypeExpr::new_map(TupleInt, Int), compile_tuple_at);
|
||||
define_builtin_func("cell_at", TypeExpr::new_map(TupleInt, Cell), compile_tuple_at);
|
||||
define_builtin_func("slice_at", TypeExpr::new_map(TupleInt, Cell), compile_tuple_at);
|
||||
define_builtin_func("slice_at", TypeExpr::new_map(TupleInt, Slice), compile_tuple_at);
|
||||
define_builtin_func("tuple_at", TypeExpr::new_map(TupleInt, Tuple), compile_tuple_at);
|
||||
define_builtin_func("at", TypeExpr::new_forall({X}, TypeExpr::new_map(TupleInt, X)), compile_tuple_at);
|
||||
define_builtin_func("touch", TypeExpr::new_forall({X}, TypeExpr::new_map(X, X)), AsmOp::Nop());
|
||||
|
|
|
@ -60,21 +60,36 @@ void generate_output_func(SymDef* func_sym) {
|
|||
code.print(std::cerr, 9);
|
||||
}
|
||||
code.simplify_var_types();
|
||||
// std::cerr << "after simplify_var_types: \n"; code.print(std::cerr, 0);
|
||||
if (verbosity >= 5) {
|
||||
std::cerr << "after simplify_var_types: \n";
|
||||
code.print(std::cerr, 0);
|
||||
}
|
||||
code.prune_unreachable_code();
|
||||
// std::cerr << "after prune_unreachable: \n"; code.print(std::cerr, 0);
|
||||
if (verbosity >= 5) {
|
||||
std::cerr << "after prune_unreachable: \n";
|
||||
code.print(std::cerr, 0);
|
||||
}
|
||||
code.split_vars(true);
|
||||
// std::cerr << "after split_vars: \n"; code.print(std::cerr, 0);
|
||||
if (verbosity >= 5) {
|
||||
std::cerr << "after split_vars: \n";
|
||||
code.print(std::cerr, 0);
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
code.compute_used_code_vars();
|
||||
if (verbosity >= 5) {
|
||||
if (verbosity >= 4) {
|
||||
std::cerr << "after compute_used_vars: \n";
|
||||
code.print(std::cerr, 6);
|
||||
}
|
||||
code.fwd_analyze();
|
||||
// std::cerr << "after fwd_analyze: \n"; code.print(std::cerr, 6);
|
||||
if (verbosity >= 5) {
|
||||
std::cerr << "after fwd_analyze: \n";
|
||||
code.print(std::cerr, 6);
|
||||
}
|
||||
code.prune_unreachable_code();
|
||||
// std::cerr << "after prune_unreachable: \n"; code.print(std::cerr, 6);
|
||||
if (verbosity >= 5) {
|
||||
std::cerr << "after prune_unreachable: \n";
|
||||
code.print(std::cerr, 6);
|
||||
}
|
||||
}
|
||||
code.mark_noreturn();
|
||||
if (verbosity >= 3) {
|
||||
|
|
|
@ -397,6 +397,7 @@ inline std::ostream& operator<<(std::ostream& os, const VarDescr& vd) {
|
|||
|
||||
struct VarDescrList {
|
||||
std::vector<VarDescr> list;
|
||||
bool unreachable{false};
|
||||
VarDescrList() : list() {
|
||||
}
|
||||
VarDescrList(const std::vector<VarDescr>& _list) : list(_list) {
|
||||
|
@ -430,6 +431,10 @@ struct VarDescrList {
|
|||
VarDescrList operator|(const VarDescrList& y) const;
|
||||
VarDescrList& operator|=(const VarDescrList& values);
|
||||
void show(std::ostream& os) const;
|
||||
void set_unreachable() {
|
||||
list.clear();
|
||||
unreachable = true;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const VarDescrList& values) {
|
||||
|
|
13
crypto/func/test/w3.fc
Normal file
13
crypto/func/test/w3.fc
Normal file
|
@ -0,0 +1,13 @@
|
|||
() main(cs) impure {
|
||||
int i = 0;
|
||||
if (cs.slice_refs()) {
|
||||
do {
|
||||
i = i + 1;
|
||||
} until(i > 10);
|
||||
}
|
||||
set_data(begin_cell()
|
||||
.store_uint(1, 32)
|
||||
.store_uint(2, 32)
|
||||
.store_uint(i, 32)
|
||||
.end_cell());
|
||||
}
|
13
crypto/func/test/w4.fc
Normal file
13
crypto/func/test/w4.fc
Normal file
|
@ -0,0 +1,13 @@
|
|||
_ main(cell dict, int t3) {
|
||||
int index = -1;
|
||||
do {
|
||||
(index, slice value, int found) = dict.udict_get_next?(32, index);
|
||||
if (found) {
|
||||
(int temp1, int temp2) = (value~load_uint(16), value~load_uint(32));
|
||||
if (t3 > temp2) {
|
||||
dict~udict_delete_get?(32, index);
|
||||
}
|
||||
}
|
||||
} until ( ~ found);
|
||||
return dict;
|
||||
}
|
14
crypto/func/test/w5.fc
Normal file
14
crypto/func/test/w5.fc
Normal file
|
@ -0,0 +1,14 @@
|
|||
(cell) recv_external(slice in_msg) impure {
|
||||
cell mydict = new_dict();
|
||||
builder r = begin_cell().store_int(10, 16);
|
||||
mydict~udict_set_builder(32, 1, r );
|
||||
int index = -1;
|
||||
do {
|
||||
(var index, var value, var found) = mydict.udict_get_next?(32, index);
|
||||
} until ( ~ found );
|
||||
return mydict;
|
||||
}
|
||||
|
||||
() recv_internal() impure {
|
||||
;; Nothing
|
||||
}
|
12
crypto/func/test/w6.fc
Normal file
12
crypto/func/test/w6.fc
Normal file
|
@ -0,0 +1,12 @@
|
|||
int test(int x) method_id {
|
||||
int i = 0;
|
||||
;; int f = false;
|
||||
do {
|
||||
i = i + 1;
|
||||
if (i > 5) {
|
||||
return 1;
|
||||
}
|
||||
int f = (i * i == 64);
|
||||
} until (f);
|
||||
return -1;
|
||||
}
|
14
crypto/func/test/w7.fc
Normal file
14
crypto/func/test/w7.fc
Normal file
|
@ -0,0 +1,14 @@
|
|||
int test(int y) {
|
||||
int x = 1;
|
||||
if (y > 0) {
|
||||
return 1;
|
||||
}
|
||||
return x > 0;
|
||||
}
|
||||
|
||||
int f(int y) {
|
||||
if (y > 0) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue