mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
[Tolk] throw
interrupts control flow; never
type
In FunC (and in Tolk before) throwing an exception is just calling a built-in function: > throw 123; // actually, __throw(123) Since it's a regular function, the compiler was not aware that execution will stop, and all following code is unreachable. For instance, `throw` in the end on function needed to be followed by `return` statement. Now, `throw` interrupts control flow, all statements after it are considered unreachable. At IR level, code Ops are also not produced. This works because a built-in __throw() now has `never` type. It can also be applied to custom functions: > fun alwaysThrow(): never { throw 123; } The code after alwaysThrow() call will also be unreachable.
This commit is contained in:
parent
7bcb8b895f
commit
ef0328837f
10 changed files with 227 additions and 25 deletions
|
@ -274,8 +274,16 @@ void Stack::rearrange_top(var_idx_t top, bool last) {
|
|||
|
||||
bool Op::generate_code_step(Stack& stack) {
|
||||
stack.opt_show();
|
||||
stack.drop_vars_except(var_info);
|
||||
stack.opt_show();
|
||||
|
||||
// detect `throw 123` (actually _IntConst 123 + _Call __throw)
|
||||
// don't clear the stack, since dropping unused elements make no sense, an exception is thrown anyway
|
||||
bool will_now_immediate_throw = (cl == _Call && f_sym->is_builtin_function() && f_sym->name == "__throw")
|
||||
|| (cl == _IntConst && next->cl == _Call && next->f_sym->is_builtin_function() && next->f_sym->name == "__throw");
|
||||
if (!will_now_immediate_throw) {
|
||||
stack.drop_vars_except(var_info);
|
||||
stack.opt_show();
|
||||
}
|
||||
|
||||
bool inline_func = stack.mode & Stack::_InlineFunc;
|
||||
switch (cl) {
|
||||
case _Nop:
|
||||
|
@ -285,6 +293,7 @@ bool Op::generate_code_step(Stack& stack) {
|
|||
stack.enforce_state(left);
|
||||
if (stack.o.retalt_ && (stack.mode & Stack::_NeedRetAlt)) {
|
||||
stack.o << "RETALT";
|
||||
stack.o.retalt_inserted_ = true;
|
||||
}
|
||||
stack.opt_show();
|
||||
return false;
|
||||
|
@ -514,7 +523,7 @@ bool Op::generate_code_step(Stack& stack) {
|
|||
int j = ret_order ? ret_order->at(i) : i;
|
||||
stack.push_new_var(left.at(j));
|
||||
}
|
||||
return true;
|
||||
return !f_sym || f_sym->declared_return_type != TypeDataNever::create();
|
||||
}
|
||||
case _SetGlob: {
|
||||
tolk_assert(g_sym);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue