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