1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

vm: bugfixes

This commit is contained in:
ton 2020-03-02 17:52:55 +04:00
parent 27aaa11524
commit ba76f1404e
30 changed files with 396 additions and 178 deletions

View file

@ -176,8 +176,10 @@ int VmState::call(Ref<Continuation> cont, int pass_args, int ret_args) {
if (skip > 0) {
get_stack().pop_many(skip);
}
consume_stack_gas(new_stk);
} else if (copy >= 0) {
new_stk = get_stack().split_top(copy, skip);
consume_stack_gas(new_stk);
} else {
new_stk = std::move(stack);
stack.clear();
@ -196,7 +198,13 @@ int VmState::call(Ref<Continuation> cont, int pass_args, int ret_args) {
throw VmError{Excno::stk_und, "stack underflow while calling a continuation: not enough arguments on stack"};
}
// create new stack from the top `pass_args` elements of the current stack
Ref<Stack> new_stk = (pass_args >= 0 ? get_stack().split_top(pass_args) : std::move(stack));
Ref<Stack> new_stk;
if (pass_args >= 0) {
new_stk = get_stack().split_top(pass_args);
consume_stack_gas(new_stk);
} else {
new_stk = std::move(stack);
}
// create return continuation using the remainder of the current stack
Ref<OrdCont> ret = Ref<OrdCont>{true, std::move(code), cp, std::move(stack), ret_args};
ret.unique_write().get_cdata()->save.set_c0(std::move(cr.c[0]));
@ -251,10 +259,12 @@ int VmState::jump(Ref<Continuation> cont, int pass_args) {
new_stk = cont_data->stack;
}
new_stk.write().move_from_stack(get_stack(), copy);
consume_stack_gas(new_stk);
set_stack(std::move(new_stk));
} else {
if (copy >= 0) {
if (copy >= 0 && copy < stack->depth()) {
get_stack().drop_bottom(stack->depth() - copy);
consume_stack_gas(copy);
}
}
return jump_to(std::move(cont));
@ -264,8 +274,10 @@ int VmState::jump(Ref<Continuation> cont, int pass_args) {
int depth = get_stack().depth();
if (pass_args > depth) {
throw VmError{Excno::stk_und, "stack underflow while jumping to a continuation: not enough arguments on stack"};
} else if (pass_args < depth) {
get_stack().drop_bottom(depth - pass_args);
consume_stack_gas(pass_args);
}
get_stack().drop_bottom(depth - pass_args);
}
return jump_to(std::move(cont));
}
@ -303,6 +315,7 @@ Ref<OrdCont> VmState::extract_cc(int save_cr, int stack_copy, int cc_args) {
} else if (stack_copy > 0) {
stack->check_underflow(stack_copy);
new_stk = get_stack().split_top(stack_copy);
consume_stack_gas(new_stk);
} else {
new_stk = Ref<Stack>{true};
}
@ -332,7 +345,7 @@ int VmState::throw_exception(int excno) {
stack_ref.push_smallint(0);
stack_ref.push_smallint(excno);
code.clear();
consume_gas(exception_gas_price);
gas.consume_chk(exception_gas_price);
return jump(get_c2());
}
@ -342,7 +355,7 @@ int VmState::throw_exception(int excno, StackEntry&& arg) {
stack_ref.push(std::move(arg));
stack_ref.push_smallint(excno);
code.clear();
consume_gas(exception_gas_price);
gas.consume_chk(exception_gas_price);
return jump(get_c2());
}
@ -403,7 +416,6 @@ int VmState::run() {
int res;
Guard guard(this);
do {
// LOG(INFO) << "[BS] data cells: " << DataCell::get_total_data_cells();
try {
try {
try {
@ -419,12 +431,10 @@ int VmState::run() {
} catch (const VmError& vme) {
VM_LOG(this) << "handling exception code " << vme.get_errno() << ": " << vme.get_msg();
try {
// LOG(INFO) << "[EX] data cells: " << DataCell::get_total_data_cells();
++steps;
res = throw_exception(vme.get_errno());
} catch (const VmError& vme2) {
VM_LOG(this) << "exception " << vme2.get_errno() << " while handling exception: " << vme.get_msg();
// LOG(INFO) << "[EXX] data cells: " << DataCell::get_total_data_cells();
return ~vme2.get_errno();
}
}
@ -437,7 +447,6 @@ int VmState::run() {
return vmoog.get_errno(); // no ~ for unhandled exceptions (to make their faking impossible)
}
} while (!res);
// LOG(INFO) << "[EN] data cells: " << DataCell::get_total_data_cells();
if ((res | 1) == -1 && !try_commit()) {
VM_LOG(this) << "automatic commit failed (new data or action cells too deep)";
get_stack().clear();