1
0
Fork 0
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:
tolk-vm 2025-02-24 20:15:24 +03:00
parent 7bcb8b895f
commit ef0328837f
No known key found for this signature in database
GPG key ID: 7905DD7FE0324B12
10 changed files with 227 additions and 25 deletions

View file

@ -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);