Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factor out the Fail lambda from all trycatch calls #1112

Merged
merged 1 commit into from Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 17 additions & 11 deletions gen/src/builtin.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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"));

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
}
10 changes: 1 addition & 9 deletions gen/src/write.rs
Expand Up @@ -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, "}}");
Expand Down
23 changes: 23 additions & 0 deletions src/cxx.cc
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down