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
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "tlbc-gen-cpp.h"
|
||||
#include "td/utils/bits.h"
|
||||
|
@ -94,6 +94,7 @@ void init_forbidden_cpp_idents() {
|
|||
l.insert("get_size");
|
||||
l.insert("pack");
|
||||
l.insert("unpack");
|
||||
l.insert("ops");
|
||||
l.insert("cs");
|
||||
l.insert("cb");
|
||||
l.insert("cell_ref");
|
||||
|
@ -2014,7 +2015,7 @@ void CppTypeCode::generate_skip_field(const Constructor& constr, const Field& fi
|
|||
output_cpp_expr(ss, expr, 100, true);
|
||||
ss << '.';
|
||||
}
|
||||
ss << (validating ? "validate_skip(cs, weak" : "skip(cs");
|
||||
ss << (validating ? "validate_skip(ops, cs, weak" : "skip(cs");
|
||||
output_negative_type_arguments(ss, expr);
|
||||
ss << ")";
|
||||
actions += Action{std::move(ss)};
|
||||
|
@ -2054,7 +2055,7 @@ void CppTypeCode::generate_skip_field(const Constructor& constr, const Field& fi
|
|||
output_cpp_expr(ss, expr, 100);
|
||||
ss << '.';
|
||||
}
|
||||
ss << (validating ? "validate_skip(cs, weak)" : "skip(cs)") << tail;
|
||||
ss << (validating ? "validate_skip(ops, cs, weak)" : "skip(cs)") << tail;
|
||||
actions += Action{std::move(ss)};
|
||||
return;
|
||||
}
|
||||
|
@ -2074,7 +2075,7 @@ void CppTypeCode::generate_skip_field(const Constructor& constr, const Field& fi
|
|||
output_cpp_expr(ss, expr, 100);
|
||||
ss << '.';
|
||||
}
|
||||
ss << "validate_skip_ref(cs, weak)" << tail;
|
||||
ss << "validate_skip_ref(ops, cs, weak)" << tail;
|
||||
actions += Action{ss.str()};
|
||||
}
|
||||
|
||||
|
@ -2101,8 +2102,8 @@ void CppTypeCode::generate_skip_cons_method(std::ostream& os, std::string nl, in
|
|||
void CppTypeCode::generate_skip_method(std::ostream& os, int options) {
|
||||
bool validate = options & 1;
|
||||
bool ret_ext = options & 2;
|
||||
os << "\nbool " << cpp_type_class_name << "::" << (validate ? "validate_" : "") << "skip(vm::CellSlice& cs"
|
||||
<< (validate ? ", bool weak" : "");
|
||||
os << "\nbool " << cpp_type_class_name
|
||||
<< "::" << (validate ? "validate_skip(int* ops, vm::CellSlice& cs, bool weak" : "skip(vm::CellSlice& cs");
|
||||
if (ret_ext) {
|
||||
os << skip_extra_args;
|
||||
}
|
||||
|
@ -2470,7 +2471,7 @@ void CppTypeCode::generate_unpack_field(const CppTypeCode::ConsField& fi, const
|
|||
output_cpp_expr(ss, expr, 100, true);
|
||||
ss << '.';
|
||||
}
|
||||
ss << (validating ? "validate_fetch_to(cs, weak, " : "fetch_to(cs, ") << field_vars.at(i);
|
||||
ss << (validating ? "validate_fetch_to(ops, cs, weak, " : "fetch_to(cs, ") << field_vars.at(i);
|
||||
output_negative_type_arguments(ss, expr);
|
||||
ss << ")";
|
||||
actions += Action{std::move(ss)};
|
||||
|
@ -2514,8 +2515,8 @@ void CppTypeCode::generate_unpack_field(const CppTypeCode::ConsField& fi, const
|
|||
output_cpp_expr(ss, expr, 100);
|
||||
ss << '.';
|
||||
}
|
||||
ss << (validating ? "validate_" : "") << "fetch_" << (cvt == ct_enum ? "enum_" : "") << "to(cs, "
|
||||
<< (validating ? "weak, " : "") << field_vars.at(i) << ")" << tail;
|
||||
ss << (validating ? "validate_" : "") << "fetch_" << (cvt == ct_enum ? "enum_" : "")
|
||||
<< (validating ? "to(ops, cs, weak, " : "to(cs, ") << field_vars.at(i) << ")" << tail;
|
||||
field_var_set[i] = true;
|
||||
actions += Action{std::move(ss)};
|
||||
return;
|
||||
|
@ -2540,7 +2541,7 @@ void CppTypeCode::generate_unpack_field(const CppTypeCode::ConsField& fi, const
|
|||
output_cpp_expr(ss, expr, 100);
|
||||
ss << '.';
|
||||
}
|
||||
ss << "validate_ref(" << field_vars.at(i) << "))" << tail;
|
||||
ss << "validate_ref(ops, " << field_vars.at(i) << "))" << tail;
|
||||
actions += Action{ss.str()};
|
||||
}
|
||||
|
||||
|
@ -2559,7 +2560,11 @@ void CppTypeCode::generate_unpack_method(std::ostream& os, CppTypeCode::ConsReco
|
|||
<< "\n auto cs = load_cell_slice(std::move(cell_ref));"
|
||||
<< "\n return " << (options & 1 ? "validate_" : "") << "unpack";
|
||||
if (!(options & 8)) {
|
||||
os << "(cs, data";
|
||||
os << "(";
|
||||
if (options & 1) {
|
||||
os << "ops, ";
|
||||
}
|
||||
os << "cs, data";
|
||||
} else {
|
||||
os << "_" << cons_enum_name.at(rec.cons_idx) << "(cs";
|
||||
for (const auto& f : rec.cpp_fields) {
|
||||
|
@ -2773,7 +2778,7 @@ void CppTypeCode::generate_pack_field(const CppTypeCode::ConsField& fi, const Co
|
|||
output_cpp_expr(ss, expr, 100);
|
||||
ss << '.';
|
||||
}
|
||||
ss << "validate_ref(" << field_vars.at(i) << "))" << tail;
|
||||
ss << "validate_ref(ops, " << field_vars.at(i) << "))" << tail;
|
||||
actions += Action{ss.str()};
|
||||
}
|
||||
|
||||
|
@ -3093,7 +3098,7 @@ void CppTypeCode::generate_header(std::ostream& os, int options) {
|
|||
if (ret_params) {
|
||||
os << " bool skip(vm::CellSlice& cs" << skip_extra_args << ") const;\n";
|
||||
}
|
||||
os << " bool validate_skip(vm::CellSlice& cs, bool weak = false) const override";
|
||||
os << " bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override";
|
||||
if (!inline_validate_skip) {
|
||||
os << ";\n";
|
||||
} else if (sz) {
|
||||
|
@ -3102,7 +3107,7 @@ void CppTypeCode::generate_header(std::ostream& os, int options) {
|
|||
os << " {\n return true;\n }\n";
|
||||
}
|
||||
if (ret_params) {
|
||||
os << " bool validate_skip(vm::CellSlice& cs, bool weak" << skip_extra_args << ") const;\n";
|
||||
os << " bool validate_skip(int *ops, vm::CellSlice& cs, bool weak" << skip_extra_args << ") const;\n";
|
||||
os << " bool fetch_to(vm::CellSlice& cs, Ref<vm::CellSlice>& res" << skip_extra_args << ") const;\n";
|
||||
}
|
||||
if (type.is_simple_enum) {
|
||||
|
|
|
@ -114,38 +114,43 @@ bool TupleT::skip(vm::CellSlice& cs) const {
|
|||
return !i;
|
||||
}
|
||||
|
||||
bool TupleT::validate_skip(vm::CellSlice& cs, bool weak) const {
|
||||
bool TupleT::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const {
|
||||
int i = n;
|
||||
for (; i > 0; --i) {
|
||||
if (!X.validate_skip(cs, weak)) {
|
||||
if (!X.validate_skip(ops, cs, weak)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return !i;
|
||||
}
|
||||
|
||||
bool TLB::validate_ref_internal(Ref<vm::Cell> cell_ref, bool weak) const {
|
||||
bool TLB::validate_ref_internal(int* ops, Ref<vm::Cell> cell_ref, bool weak) const {
|
||||
if (ops && --*ops < 0) {
|
||||
return false;
|
||||
}
|
||||
bool is_special;
|
||||
auto cs = load_cell_slice_special(std::move(cell_ref), is_special);
|
||||
return always_special() ? is_special : (is_special ? weak : (validate_skip(cs) && cs.empty_ext()));
|
||||
return always_special() ? is_special : (is_special ? weak : (validate_skip(ops, cs) && cs.empty_ext()));
|
||||
}
|
||||
|
||||
bool TLB::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const {
|
||||
pp.open("raw@");
|
||||
pp << *this << ' ';
|
||||
vm::CellSlice cs_copy{cs};
|
||||
if (!validate_skip(cs) || !cs_copy.cut_tail(cs)) {
|
||||
int size_limit = pp.limit;
|
||||
if (!validate_skip(&size_limit, cs) || !cs_copy.cut_tail(cs)) {
|
||||
return pp.fail("invalid value");
|
||||
}
|
||||
pp.raw_nl();
|
||||
return cs_copy.print_rec(pp.os, &pp.limit, pp.indent) && pp.mkindent() && pp.close();
|
||||
return (cs_copy.print_rec(pp.os, &pp.limit, pp.indent) && pp.mkindent() && pp.close()) ||
|
||||
pp.fail("raw value too long");
|
||||
}
|
||||
|
||||
bool TLB::print_special(PrettyPrinter& pp, vm::CellSlice& cs) const {
|
||||
pp.open("raw@");
|
||||
pp << *this << ' ';
|
||||
pp.raw_nl();
|
||||
return cs.print_rec(pp.os, &pp.limit, pp.indent) && pp.mkindent() && pp.close();
|
||||
return (cs.print_rec(pp.os, &pp.limit, pp.indent) && pp.mkindent() && pp.close()) || pp.fail("raw value too long");
|
||||
}
|
||||
|
||||
bool TLB::print_ref(PrettyPrinter& pp, Ref<vm::Cell> cell_ref) const {
|
||||
|
@ -217,7 +222,7 @@ PrettyPrinter::~PrettyPrinter() {
|
|||
}
|
||||
|
||||
bool PrettyPrinter::fail(std::string msg) {
|
||||
os << "<FATAL: " << msg << ">";
|
||||
os << "<FATAL: " << msg << ">" << std::endl;
|
||||
failed = true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ struct PrettyPrinter;
|
|||
|
||||
class TLB {
|
||||
public:
|
||||
enum { default_validate_max_cells = 1024 };
|
||||
virtual ~TLB() = default;
|
||||
virtual int get_size(const vm::CellSlice& cs) const {
|
||||
return -1;
|
||||
|
@ -37,14 +38,26 @@ class TLB {
|
|||
virtual bool skip(vm::CellSlice& cs) const {
|
||||
return cs.skip_ext(get_size(cs));
|
||||
}
|
||||
virtual bool validate(const vm::CellSlice& cs, bool weak = false) const {
|
||||
virtual bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
return cs.have_ext(get_size(cs));
|
||||
}
|
||||
virtual bool validate_exact(const vm::CellSlice& cs, bool weak = false) const {
|
||||
virtual bool validate_exact(int* ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
return (int)cs.size_ext() == get_size(cs);
|
||||
}
|
||||
bool validate_upto(int ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(&ops, cs, weak);
|
||||
}
|
||||
bool validate_exact_upto(int ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate_exact(&ops, cs, weak);
|
||||
}
|
||||
bool validate_csr(int* ops, Ref<vm::CellSlice> cs_ref, bool weak = false) const {
|
||||
return cs_ref.not_null() && validate_skip_exact(ops, cs_ref.write(), weak);
|
||||
}
|
||||
bool validate_csr(int ops, Ref<vm::CellSlice> cs_ref, bool weak = false) const {
|
||||
return validate_csr(&ops, std::move(cs_ref), weak);
|
||||
}
|
||||
bool validate_csr(Ref<vm::CellSlice> cs_ref, bool weak = false) const {
|
||||
return cs_ref.not_null() && validate_skip_exact(cs_ref.write(), weak);
|
||||
return validate_csr(default_validate_max_cells, std::move(cs_ref), weak);
|
||||
}
|
||||
Ref<vm::CellSlice> fetch(vm::CellSlice& cs) const {
|
||||
return cs.fetch_subslice_ext(get_size(cs));
|
||||
|
@ -52,67 +65,71 @@ class TLB {
|
|||
Ref<vm::CellSlice> prefetch(const vm::CellSlice& cs) const {
|
||||
return cs.prefetch_subslice_ext(get_size(cs));
|
||||
}
|
||||
virtual Ref<vm::CellSlice> validate_fetch(vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(cs, weak) ? cs.fetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
|
||||
virtual Ref<vm::CellSlice> validate_fetch(int* ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(ops, cs, weak) ? cs.fetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
|
||||
}
|
||||
virtual Ref<vm::CellSlice> validate_prefetch(const vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(cs, weak) ? cs.prefetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
|
||||
virtual Ref<vm::CellSlice> validate_prefetch(int* ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(ops, cs, weak) ? cs.prefetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
|
||||
}
|
||||
bool fetch_to(vm::CellSlice& cs, Ref<vm::CellSlice>& res) const {
|
||||
return (res = fetch(cs)).not_null();
|
||||
}
|
||||
bool validate_fetch_to(vm::CellSlice& cs, Ref<vm::CellSlice>& res, bool weak = false) const {
|
||||
return (res = validate_fetch(cs, weak)).not_null();
|
||||
bool validate_fetch_to(int* ops, vm::CellSlice& cs, Ref<vm::CellSlice>& res, bool weak = false) const {
|
||||
return (res = validate_fetch(ops, cs, weak)).not_null();
|
||||
}
|
||||
bool store_from(vm::CellBuilder& cb, Ref<vm::CellSlice> field) const {
|
||||
return field.not_null() && get_size(*field) == (int)field->size_ext() && cb.append_cellslice_bool(std::move(field));
|
||||
}
|
||||
bool validate_store_from(vm::CellBuilder& cb, Ref<vm::CellSlice> field, bool weak = false) const {
|
||||
bool validate_store_from(int* ops, vm::CellBuilder& cb, Ref<vm::CellSlice> field, bool weak = false) const {
|
||||
if (field.is_null()) {
|
||||
return false;
|
||||
}
|
||||
vm::CellSlice cs{*field};
|
||||
return validate_skip(cs, weak) && cs.empty_ext() && cb.append_cellslice_bool(std::move(field));
|
||||
return validate_skip(ops, cs, weak) && cs.empty_ext() && cb.append_cellslice_bool(std::move(field));
|
||||
}
|
||||
virtual bool extract(vm::CellSlice& cs) const {
|
||||
return cs.only_ext(get_size(cs));
|
||||
}
|
||||
virtual bool validate_extract(vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(cs, weak) && extract(cs);
|
||||
virtual bool validate_extract(int* ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(ops, cs, weak) && extract(cs);
|
||||
}
|
||||
int get_size_by_skip(const vm::CellSlice& cs) const {
|
||||
vm::CellSlice copy{cs};
|
||||
return skip(copy) ? copy.subtract_base_ext(cs) : -1;
|
||||
}
|
||||
virtual bool validate_skip(vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(cs, weak) && skip(cs);
|
||||
virtual bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate(ops, cs, weak) && skip(cs);
|
||||
}
|
||||
bool validate_skip_exact(vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate_skip(cs, weak) && cs.empty_ext();
|
||||
bool validate_skip_upto(int ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate_skip(&ops, cs, weak);
|
||||
}
|
||||
bool validate_by_skip(const vm::CellSlice& cs, bool weak = false) const {
|
||||
bool validate_skip_exact(int* ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate_skip(ops, cs, weak) && cs.empty_ext();
|
||||
}
|
||||
bool validate_by_skip(int* ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
vm::CellSlice copy{cs};
|
||||
return validate_skip(copy, weak);
|
||||
return validate_skip(ops, copy, weak);
|
||||
}
|
||||
bool validate_by_skip_exact(const vm::CellSlice& cs, bool weak = false) const {
|
||||
bool validate_by_skip_exact(int* ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
vm::CellSlice copy{cs};
|
||||
return validate_skip_exact(copy, weak);
|
||||
return validate_skip_exact(ops, copy, weak);
|
||||
}
|
||||
bool extract_by_skip(vm::CellSlice& cs) const {
|
||||
vm::CellSlice copy{cs};
|
||||
return skip(copy) && cs.cut_tail(copy);
|
||||
}
|
||||
bool validate_extract_by_skip(vm::CellSlice& cs, bool weak = false) const {
|
||||
bool validate_extract_by_skip(int* ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
vm::CellSlice copy{cs};
|
||||
return validate_skip(copy, weak) && cs.cut_tail(copy);
|
||||
return validate_skip(ops, copy, weak) && cs.cut_tail(copy);
|
||||
}
|
||||
Ref<vm::CellSlice> validate_fetch_by_skip(vm::CellSlice& cs, bool weak = false) const {
|
||||
Ref<vm::CellSlice> validate_fetch_by_skip(int* ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
Ref<vm::CellSlice> copy{true, cs};
|
||||
return validate_skip(cs, weak) && copy.unique_write().cut_tail(cs) ? copy : Ref<vm::CellSlice>{};
|
||||
return validate_skip(ops, cs, weak) && copy.unique_write().cut_tail(cs) ? copy : Ref<vm::CellSlice>{};
|
||||
}
|
||||
Ref<vm::CellSlice> validate_prefetch_by_skip(const vm::CellSlice& cs, bool weak = false) const {
|
||||
Ref<vm::CellSlice> validate_prefetch_by_skip(int* ops, const vm::CellSlice& cs, bool weak = false) const {
|
||||
vm::CellSlice copy{cs};
|
||||
return validate_skip(copy, false) ? cs.prefetch_subslice_ext(copy.subtract_base_ext(cs)) : Ref<vm::CellSlice>{};
|
||||
return validate_skip(ops, copy, false) ? cs.prefetch_subslice_ext(copy.subtract_base_ext(cs))
|
||||
: Ref<vm::CellSlice>{};
|
||||
}
|
||||
virtual bool skip_copy(vm::CellBuilder& cb, vm::CellSlice& cs) const {
|
||||
return cb.append_cellslice_bool(fetch(cs));
|
||||
|
@ -156,14 +173,29 @@ class TLB {
|
|||
bool as_integer_to(Ref<vm::CellSlice> cs_ref, td::RefInt256& res) const {
|
||||
return (res = as_integer(std::move(cs_ref))).not_null();
|
||||
}
|
||||
bool validate_ref(int* ops, Ref<vm::Cell> cell_ref, bool weak = false) const {
|
||||
return cell_ref.not_null() && validate_ref_internal(ops, std::move(cell_ref), weak);
|
||||
}
|
||||
bool validate_ref(int ops, Ref<vm::Cell> cell_ref, bool weak = false) const {
|
||||
return validate_ref(&ops, std::move(cell_ref), weak);
|
||||
}
|
||||
bool validate_ref(Ref<vm::Cell> cell_ref, bool weak = false) const {
|
||||
return cell_ref.not_null() && validate_ref_internal(std::move(cell_ref), weak);
|
||||
return validate_ref(default_validate_max_cells, std::move(cell_ref), weak);
|
||||
}
|
||||
bool force_validate_ref(int* ops, Ref<vm::Cell> cell_ref) const {
|
||||
return cell_ref.not_null() && validate_ref_internal(ops, std::move(cell_ref), false);
|
||||
}
|
||||
bool force_validate_ref(int ops, Ref<vm::Cell> cell_ref) const {
|
||||
return force_validate_ref(&ops, std::move(cell_ref));
|
||||
}
|
||||
bool force_validate_ref(Ref<vm::Cell> cell_ref) const {
|
||||
return cell_ref.not_null() && validate_ref_internal(std::move(cell_ref), false);
|
||||
return force_validate_ref(default_validate_max_cells, std::move(cell_ref));
|
||||
}
|
||||
bool validate_skip_ref(vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate_ref(cs.fetch_ref(), weak);
|
||||
bool validate_skip_ref(int* ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate_ref(ops, cs.fetch_ref(), weak);
|
||||
}
|
||||
bool validate_skip_ref(int ops, vm::CellSlice& cs, bool weak = false) const {
|
||||
return validate_skip_ref(&ops, cs, weak);
|
||||
}
|
||||
virtual bool null_value(vm::CellBuilder& cb) const {
|
||||
return false;
|
||||
|
@ -214,6 +246,9 @@ class TLB {
|
|||
return print(os, *cs_ref, indent, rec_limit);
|
||||
}
|
||||
bool print_ref(std::ostream& os, Ref<vm::Cell> cell_ref, int indent = 0, int rec_limit = 0) const;
|
||||
bool print_ref(int rec_limit, std::ostream& os, Ref<vm::Cell> cell_ref, int indent = 0) const {
|
||||
return print_ref(os, std::move(cell_ref), indent, rec_limit);
|
||||
}
|
||||
std::string as_string_skip(vm::CellSlice& cs, int indent = 0) const;
|
||||
std::string as_string(const vm::CellSlice& cs, int indent = 0) const;
|
||||
std::string as_string(Ref<vm::CellSlice> cs_ref, int indent = 0) const {
|
||||
|
@ -225,7 +260,7 @@ class TLB {
|
|||
}
|
||||
|
||||
protected:
|
||||
bool validate_ref_internal(Ref<vm::Cell> cell_ref, bool weak = false) const;
|
||||
bool validate_ref_internal(int* ops, Ref<vm::Cell> cell_ref, bool weak = false) const;
|
||||
};
|
||||
|
||||
static inline std::ostream& operator<<(std::ostream& os, const TLB& type) {
|
||||
|
@ -234,29 +269,29 @@ static inline std::ostream& operator<<(std::ostream& os, const TLB& type) {
|
|||
|
||||
struct TLB_Complex : TLB {
|
||||
bool skip(vm::CellSlice& cs) const override {
|
||||
return validate_skip(cs);
|
||||
return validate_skip(nullptr, cs);
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override = 0;
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override = 0;
|
||||
int get_size(const vm::CellSlice& cs) const override {
|
||||
return get_size_by_skip(cs);
|
||||
}
|
||||
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_by_skip(cs, weak);
|
||||
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_by_skip(ops, cs, weak);
|
||||
}
|
||||
bool validate_exact(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_by_skip_exact(cs, weak);
|
||||
bool validate_exact(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_by_skip_exact(ops, cs, weak);
|
||||
}
|
||||
bool extract(vm::CellSlice& cs) const override {
|
||||
return extract_by_skip(cs);
|
||||
}
|
||||
bool validate_extract(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_extract_by_skip(cs, weak);
|
||||
bool validate_extract(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_extract_by_skip(ops, cs, weak);
|
||||
}
|
||||
Ref<vm::CellSlice> validate_fetch(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_fetch_by_skip(cs, weak);
|
||||
Ref<vm::CellSlice> validate_fetch(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_fetch_by_skip(ops, cs, weak);
|
||||
}
|
||||
Ref<vm::CellSlice> validate_prefetch(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_prefetch_by_skip(cs, weak);
|
||||
Ref<vm::CellSlice> validate_prefetch(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return validate_prefetch_by_skip(ops, cs, weak);
|
||||
}
|
||||
td::RefInt256 as_integer(const vm::CellSlice& cs) const override {
|
||||
vm::CellSlice copy{cs};
|
||||
|
@ -615,23 +650,23 @@ struct FwdT final : TLB {
|
|||
bool skip(vm::CellSlice& cs) const override {
|
||||
return X.skip(cs);
|
||||
}
|
||||
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate(cs, weak);
|
||||
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate(ops, cs, weak);
|
||||
}
|
||||
Ref<vm::CellSlice> validate_fetch(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_fetch(cs, weak);
|
||||
Ref<vm::CellSlice> validate_fetch(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_fetch(ops, cs, weak);
|
||||
}
|
||||
Ref<vm::CellSlice> validate_prefetch(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_prefetch(cs, weak);
|
||||
Ref<vm::CellSlice> validate_prefetch(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_prefetch(ops, cs, weak);
|
||||
}
|
||||
bool extract(vm::CellSlice& cs) const override {
|
||||
return X.extract(cs);
|
||||
}
|
||||
bool validate_extract(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_extract(cs, weak);
|
||||
bool validate_extract(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_extract(ops, cs, weak);
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_skip(cs, weak);
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_skip(ops, cs, weak);
|
||||
}
|
||||
bool skip_copy(vm::CellBuilder& cb, vm::CellSlice& cs) const override {
|
||||
return X.skip_copy(cb, cs);
|
||||
|
@ -726,10 +761,10 @@ struct NatLess final : TLB {
|
|||
int get_size(const vm::CellSlice& cs) const override {
|
||||
return n >= 0 ? w : -1;
|
||||
}
|
||||
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return n >= 0 && (unsigned)cs.prefetch_ulong(w) <= (unsigned)n;
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return n >= 0 && (unsigned)cs.fetch_ulong(w) <= (unsigned)n;
|
||||
}
|
||||
unsigned long long as_uint(const vm::CellSlice& cs) const override {
|
||||
|
@ -749,10 +784,10 @@ struct NatLeq final : TLB {
|
|||
int get_size(const vm::CellSlice& cs) const override {
|
||||
return n >= 0 ? w : -1;
|
||||
}
|
||||
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return n >= 0 && (unsigned)cs.prefetch_ulong(w) <= (unsigned)n;
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return n >= 0 && (unsigned)cs.fetch_ulong(w) <= (unsigned)n;
|
||||
}
|
||||
unsigned long long as_uint(const vm::CellSlice& cs) const override {
|
||||
|
@ -771,7 +806,7 @@ struct TupleT final : TLB_Complex {
|
|||
TupleT(int _n, const TLB& _X) : n(_n), X(_X) {
|
||||
}
|
||||
bool skip(vm::CellSlice& cs) const override;
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override;
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override;
|
||||
int get_tag(const vm::CellSlice& cs) const override {
|
||||
return 0;
|
||||
}
|
||||
|
@ -786,8 +821,8 @@ struct CondT final : TLB_Complex {
|
|||
bool skip(vm::CellSlice& cs) const override {
|
||||
return !n || X.skip(cs);
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return !n || (n > 0 && X.validate_skip(cs, weak));
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return !n || (n > 0 && X.validate_skip(ops, cs, weak));
|
||||
}
|
||||
int get_tag(const vm::CellSlice& cs) const override {
|
||||
return 0;
|
||||
|
@ -808,8 +843,8 @@ struct Cond final : TLB_Complex {
|
|||
bool skip(vm::CellSlice& cs) const override {
|
||||
return !n || field_type.skip(cs);
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return !n || (n > 0 && field_type.validate_skip(cs, weak));
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return !n || (n > 0 && field_type.validate_skip(ops, cs, weak));
|
||||
}
|
||||
int get_tag(const vm::CellSlice& cs) const override {
|
||||
return 0;
|
||||
|
@ -905,7 +940,7 @@ struct Maybe : TLB_Complex {
|
|||
Maybe(Args... args) : field_type(args...) {
|
||||
}
|
||||
bool skip(vm::CellSlice& cs) const override;
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override;
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override;
|
||||
int get_tag(const vm::CellSlice& cs) const override {
|
||||
return cs.have(1) ? (int)cs.prefetch_ulong(1) : -1;
|
||||
}
|
||||
|
@ -928,10 +963,10 @@ bool Maybe<T>::skip(vm::CellSlice& cs) const {
|
|||
}
|
||||
|
||||
template <class T>
|
||||
bool Maybe<T>::validate_skip(vm::CellSlice& cs, bool weak) const {
|
||||
bool Maybe<T>::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const {
|
||||
int t = get_tag(cs);
|
||||
if (t > 0) {
|
||||
return cs.advance(1) && field_type.validate_skip(cs, weak);
|
||||
return cs.advance(1) && field_type.validate_skip(ops, cs, weak);
|
||||
} else if (!t) {
|
||||
return cs.advance(1);
|
||||
} else {
|
||||
|
@ -979,11 +1014,11 @@ struct RefTo final : TLB {
|
|||
int get_size(const vm::CellSlice& cs) const override {
|
||||
return 0x10000;
|
||||
}
|
||||
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return cs.size_refs() ? ref_type.validate_ref(cs.prefetch_ref(), weak) : false;
|
||||
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return cs.size_refs() ? ref_type.validate_ref(ops, cs.prefetch_ref(), weak) : false;
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return ref_type.validate_skip_ref(cs, weak);
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return ref_type.validate_skip_ref(ops, cs, weak);
|
||||
}
|
||||
std::ostream& print_type(std::ostream& os) const override {
|
||||
return os << '^' << ref_type;
|
||||
|
@ -1000,11 +1035,11 @@ struct RefT final : TLB {
|
|||
int get_size(const vm::CellSlice& cs) const override {
|
||||
return 0x10000;
|
||||
}
|
||||
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_ref(cs.prefetch_ref(), weak);
|
||||
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_ref(ops, cs.prefetch_ref(), weak);
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_skip_ref(cs, weak);
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return X.validate_skip_ref(ops, cs, weak);
|
||||
}
|
||||
std::ostream& print_type(std::ostream& os) const override {
|
||||
return os << '^' << X;
|
||||
|
@ -1021,9 +1056,10 @@ struct Either final : TLB_Complex {
|
|||
bool skip(vm::CellSlice& cs) const override {
|
||||
return cs.have(1) ? (cs.fetch_ulong(1) ? right_type.skip(cs) : left_type.skip(cs)) : false;
|
||||
}
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
|
||||
return cs.have(1) ? (cs.fetch_ulong(1) ? right_type.validate_skip(cs, weak) : left_type.validate_skip(cs, weak))
|
||||
: false;
|
||||
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
|
||||
return cs.have(1)
|
||||
? (cs.fetch_ulong(1) ? right_type.validate_skip(ops, cs, weak) : left_type.validate_skip(ops, cs, weak))
|
||||
: false;
|
||||
}
|
||||
int get_tag(const vm::CellSlice& cs) const override {
|
||||
return (int)cs.prefetch_ulong(1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue