mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
vm: bugfixes
This commit is contained in:
parent
27aaa11524
commit
ba76f1404e
30 changed files with 396 additions and 178 deletions
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue