Skip to content

Commit

Permalink
rust/intrinsic: add new "catch_unwind" variant of API
Browse files Browse the repository at this point in the history
gcc/rust/ChangeLog:
        * backend/rust-compile-intrinsic.cc: add the new `catch_unwind` variant
        of the `try` intrinsic: this variant can be seen on Rust 1.78+
        and returns `()` instead of `i32`.
  • Loading branch information
liushuyu committed Dec 2, 2024
1 parent 873aaac commit f31c5c9
Showing 1 changed file with 47 additions and 10 deletions.
57 changes: 47 additions & 10 deletions gcc/rust/backend/rust-compile-intrinsic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,15 @@ expect_handler (bool likely)
}

static tree
try_handler (Context *ctx, TyTy::FnType *fntype);
try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api);

const static std::function<tree (Context *, TyTy::FnType *)>
try_handler (bool is_new_api)
{
return [is_new_api] (Context *ctx, TyTy::FnType *fntype) {
return try_handler_inner (ctx, fntype, is_new_api);
};
}

inline tree
sorry_handler (Context *ctx, TyTy::FnType *fntype)
Expand Down Expand Up @@ -245,7 +253,8 @@ static const std::map<std::string,
{"likely", expect_handler (true)},
{"unlikely", expect_handler (false)},
{"assume", assume_handler},
{"try", try_handler},
{"try", try_handler (false)},
{"catch_unwind", try_handler (true)},
};

Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
Expand Down Expand Up @@ -1272,7 +1281,7 @@ assume_handler (Context *ctx, TyTy::FnType *fntype)
}

static tree
try_handler (Context *ctx, TyTy::FnType *fntype)
try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api)
{
rust_assert (fntype->get_params ().size () == 3);

Expand All @@ -1283,6 +1292,13 @@ try_handler (Context *ctx, TyTy::FnType *fntype)

enter_intrinsic_block (ctx, fndecl);

// The following tricks are needed to make sure the try-catch blocks are not
// optimized away
TREE_READONLY (fndecl) = 0;
DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("always_inline"),
NULL_TREE, DECL_ATTRIBUTES (fndecl));

// BUILTIN try_handler FN BODY BEGIN
// setup the params
std::vector<Bvariable *> param_vars;
Expand All @@ -1296,15 +1312,31 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
tree try_fn = Backend::var_expression (param_vars[0], UNDEF_LOCATION);
tree user_data = Backend::var_expression (param_vars[1], UNDEF_LOCATION);
tree catch_fn = Backend::var_expression (param_vars[2], UNDEF_LOCATION);
tree normal_return_stmt
= Backend::return_statement (fndecl, integer_zero_node, BUILTINS_LOCATION);
tree error_return_stmt
= Backend::return_statement (fndecl, integer_one_node, BUILTINS_LOCATION);
tree normal_return_stmt = NULL_TREE;
tree error_return_stmt = NULL_TREE;
tree try_call = Backend::call_expression (try_fn, {user_data}, nullptr,
BUILTINS_LOCATION);
tree catch_call = NULL_TREE;
tree try_block = Backend::block (fndecl, enclosing_scope, {}, UNDEF_LOCATION,
UNDEF_LOCATION);

if (is_new_api)
{
auto ret_type = TyTyResolveCompile::get_unit_type ();
auto ret_expr = Backend::constructor_expression (ret_type, false, {}, -1,
UNDEF_LOCATION);
normal_return_stmt
= Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
error_return_stmt
= Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
}
else
{
normal_return_stmt = Backend::return_statement (fndecl, integer_zero_node,
BUILTINS_LOCATION);
error_return_stmt = Backend::return_statement (fndecl, integer_one_node,
BUILTINS_LOCATION);
}
Backend::block_add_statements (try_block,
std::vector<tree>{try_call,
normal_return_stmt});
Expand All @@ -1320,17 +1352,22 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
= build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER), 1,
integer_zero_node);
catch_call = Backend::call_expression (catch_fn, {user_data, eh_pointer},
nullptr, BUILTINS_LOCATION);
NULL_TREE, BUILTINS_LOCATION);

tree catch_block = Backend::block (fndecl, enclosing_scope, {},
UNDEF_LOCATION, UNDEF_LOCATION);
Backend::block_add_statements (catch_block,
std::vector<tree>{catch_call,
error_return_stmt});
// emulate what cc1plus is doing for C++ try-catch
tree inner_eh_construct
= Backend::exception_handler_statement (catch_call, NULL_TREE,
error_return_stmt,
BUILTINS_LOCATION);
// TODO(liushuyu): eh_personality needs to be implemented as a runtime thing
auto eh_construct
= Backend::exception_handler_statement (try_block, catch_block, NULL_TREE,
BUILTINS_LOCATION);
= Backend::exception_handler_statement (try_block, inner_eh_construct,
NULL_TREE, BUILTINS_LOCATION);
ctx->add_statement (eh_construct);
// BUILTIN try_handler FN BODY END
finalize_intrinsic_block (ctx, fndecl);
Expand Down

0 comments on commit f31c5c9

Please sign in to comment.