Bug 1440207 - Part 5: Disable UniqueFileHandle for RUST_BINDGEN, r=emilio,glandium

Apparently rust bindgen uses a hack which assumes all specializations of
`UniquePtr` have the basic layout and use a pointer member with an empty
deleter.

This incorrect assumption unfortunately comes up for UniqueFileHandle,
which replaces the pointer type using the deleter with a file handle
helper type.

As this fails to build with RUST_BINDGEN, this patch takes the same
approach as bug 1802320, and just disables building these types when
building headers for bindgen.

This does not fix the general issue of bindgen making incorrect
assumptions about the layout of UniquePtr with non-default deleters.
Ideally, all non-default deleters should be made opaque.

Differential Revision: https://phabricator.services.mozilla.com/D223628
This commit is contained in:
Nika Layzell 2024-10-01 22:21:52 +00:00
parent 5e3609681d
commit bb85d44899

View File

@ -93,28 +93,29 @@ struct FreePolicy {
void operator()(const void* ptr) { free(const_cast<void*>(ptr)); }
};
#if defined(XP_WIN)
#if !defined(RUST_BINDGEN)
# if defined(XP_WIN)
// Can't include <windows.h> to get the actual definition of HANDLE
// because of namespace pollution.
typedef void* FileHandleType;
#elif defined(XP_UNIX)
# elif defined(XP_UNIX)
typedef int FileHandleType;
#else
# error "Unsupported OS?"
#endif
# else
# error "Unsupported OS?"
# endif
struct FileHandleHelper {
MOZ_IMPLICIT FileHandleHelper(FileHandleType aHandle) : mHandle(aHandle) {
#if defined(XP_UNIX) && (defined(DEBUG) || defined(FUZZING))
# if defined(XP_UNIX) && (defined(DEBUG) || defined(FUZZING))
MOZ_RELEASE_ASSERT(aHandle == kInvalidHandle || aHandle > 2);
#endif
# endif
}
MOZ_IMPLICIT constexpr FileHandleHelper(std::nullptr_t)
: mHandle(kInvalidHandle) {}
bool operator!=(std::nullptr_t) const {
#ifdef XP_WIN
# ifdef XP_WIN
// Windows uses both nullptr and INVALID_HANDLE_VALUE (-1 cast to
// HANDLE) in different situations, but nullptr is more reliably
// null while -1 is also valid input to some calls that take
@ -123,20 +124,20 @@ struct FileHandleHelper {
if (mHandle == (void*)-1) {
return false;
}
#endif
# endif
return mHandle != kInvalidHandle;
}
operator FileHandleType() const { return mHandle; }
#ifdef XP_WIN
# ifdef XP_WIN
// NSPR uses an integer type for PROsfd, so this conversion is
// provided for working with it without needing reinterpret casts
// everywhere.
operator std::intptr_t() const {
return reinterpret_cast<std::intptr_t>(mHandle);
}
#endif
# endif
// When there's only one user-defined conversion operator, the
// compiler will use that to derive equality, but that doesn't work
@ -148,13 +149,13 @@ struct FileHandleHelper {
private:
FileHandleType mHandle;
#ifdef XP_WIN
# ifdef XP_WIN
// See above for why this is nullptr. (Also, INVALID_HANDLE_VALUE
// can't be expressed as a constexpr.)
static constexpr FileHandleType kInvalidHandle = nullptr;
#else
# else
static constexpr FileHandleType kInvalidHandle = -1;
#endif
# endif
};
struct FileHandleDeleter {
@ -162,6 +163,7 @@ struct FileHandleDeleter {
using receiver = FileHandleType;
MFBT_API void operator()(FileHandleHelper aHelper);
};
#endif
#if defined(XP_DARWIN) && !defined(RUST_BINDGEN)
struct MachPortHelper {
@ -215,17 +217,19 @@ struct MachPortSetDeleter {
template <typename T>
using UniqueFreePtr = UniquePtr<T, detail::FreePolicy<T>>;
#if !defined(RUST_BINDGEN)
// A RAII class for the OS construct used for open files and similar
// objects: a file descriptor on Unix or a handle on Windows.
using UniqueFileHandle =
UniquePtr<detail::FileHandleType, detail::FileHandleDeleter>;
#ifndef __wasm__
# ifndef __wasm__
// WASI does not have `dup`
MFBT_API UniqueFileHandle DuplicateFileHandle(detail::FileHandleType aFile);
inline UniqueFileHandle DuplicateFileHandle(const UniqueFileHandle& aFile) {
return DuplicateFileHandle(aFile.get());
}
# endif
#endif
#if defined(XP_DARWIN) && !defined(RUST_BINDGEN)