Merge pull request #1112 from dtolnay/fail

Factor out the Fail lambda from all trycatch calls
This commit is contained in:
David Tolnay 2022-10-15 14:27:24 -07:00 committed by GitHub
commit a39652409c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 20 deletions

View File

@ -26,7 +26,6 @@ pub struct Builtins<'a> {
pub rust_str_repr: bool,
pub rust_slice_new: bool,
pub rust_slice_repr: bool,
pub exception: bool,
pub relocatable: bool,
pub relocatable_or_array: bool,
pub friend_impl: bool,
@ -138,6 +137,10 @@ pub(super) fn write(out: &mut OutFile) {
builtin.unsafe_bitcopy_t = true;
}
if builtin.trycatch {
builtin.ptr_len = true;
}
out.begin_block(Block::Namespace("rust"));
out.begin_block(Block::InlineNamespace("cxxbridge1"));
@ -251,6 +254,19 @@ pub(super) fn write(out: &mut OutFile) {
writeln!(out, "}};");
}
if builtin.trycatch {
out.next_section();
writeln!(out, "class Fail final {{");
writeln!(out, " ::rust::repr::PtrLen &throw$;");
writeln!(out, "public:");
writeln!(
out,
" Fail(::rust::repr::PtrLen &throw$) : throw$(throw$) {{}}"
);
writeln!(out, " void operator()(const char *) noexcept;");
writeln!(out, "}};");
}
out.end_block(Block::Namespace("detail"));
if builtin.manually_drop {
@ -401,14 +417,4 @@ pub(super) fn write(out: &mut OutFile) {
}
out.end_block(Block::Namespace("rust"));
if builtin.exception {
include.cstddef = true;
out.begin_block(Block::ExternC);
writeln!(
out,
"const char *cxxbridge1$exception(const char *, ::std::size_t) noexcept;",
);
out.end_block(Block::ExternC);
}
}

View File

@ -847,17 +847,9 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
}
writeln!(out, ";");
if efn.throws {
out.include.cstring = true;
out.builtin.exception = true;
writeln!(out, " throw$.ptr = nullptr;");
writeln!(out, " }},");
writeln!(out, " [&](const char *catch$) noexcept {{");
writeln!(out, " throw$.len = ::std::strlen(catch$);");
writeln!(
out,
" throw$.ptr = const_cast<char *>(::cxxbridge1$exception(catch$, throw$.len));",
);
writeln!(out, " }});");
writeln!(out, " ::rust::detail::Fail(throw$));");
writeln!(out, " return throw$;");
}
writeln!(out, "}}");

View File

@ -68,6 +68,9 @@ void cxxbridge1$slice$new(void *self, const void *ptr,
std::size_t len) noexcept;
void *cxxbridge1$slice$ptr(const void *self) noexcept;
std::size_t cxxbridge1$slice$len(const void *self) noexcept;
// try/catch
const char *cxxbridge1$exception(const char *, std::size_t len) noexcept;
} // extern "C"
namespace rust {
@ -506,6 +509,13 @@ union MaybeUninit {
};
} // namespace
namespace repr {
struct PtrLen final {
void *ptr;
std::size_t len;
};
} // namespace repr
namespace detail {
// On some platforms size_t is the same C++ type as one of the sized integer
// types; on others it is a distinct type. Only in the latter case do we need to
@ -519,6 +529,19 @@ using isize_if_unique =
typename std::conditional<std::is_same<rust::isize, int64_t>::value ||
std::is_same<rust::isize, int32_t>::value,
struct isize_ignore, rust::isize>::type;
class Fail final {
repr::PtrLen &throw$;
public:
Fail(repr::PtrLen &throw$) : throw$(throw$) {}
void operator()(const char *) noexcept;
};
void Fail::operator()(const char *catch$) noexcept {
throw$.len = std::strlen(catch$);
throw$.ptr = const_cast<char *>(cxxbridge1$exception(catch$, throw$.len));
}
} // namespace detail
} // namespace cxxbridge1