2222#include " vm/log.h"
2323#include " vm/vm.h"
2424#include " cp0.h"
25+ #include " memo.h"
26+
2527#include < sodium.h>
2628
2729namespace vm {
@@ -31,33 +33,8 @@ VmState::VmState() : cp(-1), dispatch(&dummy_dispatch_table), quit0(true, 0), qu
3133 init_cregs ();
3234}
3335
34- VmState::VmState (Ref<CellSlice> _code)
35- : code(std::move(_code)), cp(-1 ), dispatch(&dummy_dispatch_table), quit0(true , 0 ), quit1(true , 1 ) {
36- ensure_throw (init_cp (0 ));
37- init_cregs ();
38- }
39-
40- VmState::VmState (Ref<CellSlice> _code, Ref<Stack> _stack, int flags, Ref<Cell> _data, VmLog log,
41- std::vector<Ref<Cell>> _libraries, Ref<Tuple> init_c7)
42- : code(std::move(_code))
43- , stack(std::move(_stack))
44- , cp(-1 )
45- , dispatch(&dummy_dispatch_table)
46- , quit0(true , 0 )
47- , quit1(true , 1 )
48- , log(log)
49- , libraries(std::move(_libraries))
50- , stack_trace((flags >> 2 ) & 1 ) {
51- ensure_throw (init_cp (0 ));
52- set_c4 (std::move (_data));
53- if (init_c7.not_null ()) {
54- set_c7 (std::move (init_c7));
55- }
56- init_cregs (flags & 1 , flags & 2 );
57- }
58-
59- VmState::VmState (Ref<CellSlice> _code, Ref<Stack> _stack, const GasLimits& gas, int flags, Ref<Cell> _data, VmLog log,
60- std::vector<Ref<Cell>> _libraries, Ref<Tuple> init_c7)
36+ VmState::VmState (Ref<CellSlice> _code, int global_version, Ref<Stack> _stack, const GasLimits& gas, int flags,
37+ Ref<Cell> _data, VmLog log, std::vector<Ref<Cell>> _libraries, Ref<Tuple> init_c7)
6138 : code(std::move(_code))
6239 , stack(std::move(_stack))
6340 , cp(-1 )
@@ -67,7 +44,8 @@ VmState::VmState(Ref<CellSlice> _code, Ref<Stack> _stack, const GasLimits& gas,
6744 , log(log)
6845 , gas(gas)
6946 , libraries(std::move(_libraries))
70- , stack_trace((flags >> 2 ) & 1 ) {
47+ , stack_trace((flags >> 2 ) & 1 )
48+ , global_version(global_version) {
7149 ensure_throw (init_cp (0 ));
7250 set_c4 (std::move (_data));
7351 if (init_c7.not_null ()) {
@@ -102,12 +80,24 @@ void VmState::init_cregs(bool same_c3, bool push_0) {
10280 }
10381}
10482
105- Ref<CellSlice> VmState::convert_code_cell (Ref<Cell> code_cell) {
83+ Ref<CellSlice> VmState::convert_code_cell (Ref<Cell> code_cell, int global_version,
84+ const std::vector<Ref<Cell>>& libraries) {
10685 if (code_cell.is_null ()) {
10786 return {};
10887 }
109- Ref<CellSlice> csr{true , NoVmOrd (), code_cell};
110- if (csr->is_valid ()) {
88+ Ref<CellSlice> csr;
89+ if (global_version >= 9 ) {
90+ // Use DummyVmState instead of this to avoid consuming gas for cell loading
91+ DummyVmState dummy{libraries, global_version};
92+ Guard guard (&dummy);
93+ try {
94+ csr = load_cell_slice_ref (code_cell);
95+ } catch (VmError&) { // NOLINT(*-empty-catch)
96+ }
97+ } else {
98+ csr = td::Ref<CellSlice>{true , NoVmOrd (), code_cell};
99+ }
100+ if (csr.not_null () && csr->is_valid ()) {
111101 return csr;
112102 }
113103 return load_cell_slice_ref (CellBuilder{}.store_ref (std::move (code_cell)).finalize ());
@@ -577,14 +567,14 @@ int run_vm_code(Ref<CellSlice> code, Ref<Stack>& stack, int flags, Ref<Cell>* da
577567 GasLimits* gas_limits, std::vector<Ref<Cell>> libraries, Ref<Tuple> init_c7, Ref<Cell>* actions_ptr,
578568 int global_version) {
579569 VmState vm{code,
570+ global_version,
580571 std::move (stack),
581572 gas_limits ? *gas_limits : GasLimits{},
582573 flags,
583574 data_ptr ? *data_ptr : Ref<Cell>{},
584575 log,
585576 std::move (libraries),
586577 std::move (init_c7)};
587- vm.set_global_version (global_version);
588578 int res = vm.run ();
589579 stack = vm.get_stack_ref ();
590580 if (vm.committed () && data_ptr) {
0 commit comments