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

@ -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) {

View file

@ -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;
}

View file

@ -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);