mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add try/catch to FunC (#560)
* Add try-catch * Fix 'return' bugs * Update tests * Fix 'SETCONTVARARGS' bug * Fix 'SETCONTVARARGS' bug again * Check deep stack * Add throw_arg Co-authored-by: legaii <jgates.ardux@gmail.com>
This commit is contained in:
parent
dd9cdba587
commit
e1be988df5
8 changed files with 365 additions and 0 deletions
|
@ -520,6 +520,14 @@ bool Op::compute_used_vars(const CodeBlob& code, bool edit) {
|
|||
} while (changes <= edit);
|
||||
return set_var_info(std::move(new_var_info));
|
||||
}
|
||||
case _TryCatch: {
|
||||
code.compute_used_code_vars(block0, next_var_info, edit);
|
||||
code.compute_used_code_vars(block1, next_var_info, edit);
|
||||
VarDescrList merge_info = block0->var_info + block1->var_info + next_var_info;
|
||||
merge_info -= left;
|
||||
merge_info.clear_last();
|
||||
return set_var_info(std::move(merge_info));
|
||||
}
|
||||
default:
|
||||
std::cerr << "fatal: unknown operation <??" << cl << "> in compute_used_vars()\n";
|
||||
throw src::ParseError{where, "unknown operation"};
|
||||
|
@ -645,6 +653,10 @@ bool prune_unreachable(std::unique_ptr<Op>& ops) {
|
|||
reach = true;
|
||||
break;
|
||||
}
|
||||
case Op::_TryCatch: {
|
||||
reach = prune_unreachable(op.block0) | prune_unreachable(op.block1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cerr << "fatal: unknown operation <??" << op.cl << ">\n";
|
||||
throw src::ParseError{op.where, "unknown operation in prune_unreachable()"};
|
||||
|
@ -825,6 +837,12 @@ VarDescrList Op::fwd_analyze(VarDescrList values) {
|
|||
values = block0->fwd_analyze(values);
|
||||
break;
|
||||
}
|
||||
case _TryCatch: {
|
||||
VarDescrList val1 = block0->fwd_analyze(values);
|
||||
VarDescrList val2 = block1->fwd_analyze(std::move(values));
|
||||
values = val1 | val2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cerr << "fatal: unknown operation <??" << cl << ">\n";
|
||||
throw src::ParseError{where, "unknown operation in fwd_analyze()"};
|
||||
|
@ -866,6 +884,7 @@ bool Op::mark_noreturn() {
|
|||
case _Return:
|
||||
return set_noreturn(true);
|
||||
case _If:
|
||||
case _TryCatch:
|
||||
return set_noreturn((block0->mark_noreturn() & (block1 && block1->mark_noreturn())) | next->mark_noreturn());
|
||||
case _Again:
|
||||
block0->mark_noreturn();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue