mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 14:00:16 +02:00
Thunks/gen: Emit metadata to check if a type has consistent data layout
This commit is contained in:
1 parent
d488592eda
commit
52419d9911
3 files changed
+39
No files matched your search
@@ -144,6 +144,9 @@ void GenerateThunkLibsAction::EmitLayoutWrappers(
|
||||
|
||||
// Opaque types don't need layout definitions
|
||||
if (type_repack_info.assumed_compatible && type_repack_info.pointers_only) {
|
||||
if (guest_abi.pointer_size != 4) {
|
||||
fmt::print(file, "template<> inline constexpr bool has_compatible_data_layout<{}*> = true;\n", struct_name);
|
||||
}
|
||||
continue;
|
||||
} else if (type_repack_info.assumed_compatible) {
|
||||
// TODO: Handle more cleanly
|
||||
@@ -280,6 +283,10 @@ void GenerateThunkLibsAction::EmitLayoutWrappers(
|
||||
}
|
||||
fmt::print(file, " return ret;\n");
|
||||
fmt::print(file, "}}\n\n");
|
||||
|
||||
if (type_compat.at(type) == TypeCompatibility::Full) {
|
||||
fmt::print(file, "template<> inline constexpr bool has_compatible_data_layout<{}> = true;\n", struct_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,35 @@ struct ParameterAnnotations {
|
||||
bool assume_compatible = false;
|
||||
};
|
||||
|
||||
// Generator emits specializations for this for each type that has compatible layout
|
||||
template<typename T>
|
||||
inline constexpr bool has_compatible_data_layout =
|
||||
std::is_integral_v<T> || std::is_enum_v<T> || std::is_floating_point_v<T>
|
||||
#ifndef IS_32BIT_THUNK
|
||||
// If none of the previous predicates matched, the thunk generator did *not* emit a specialization for T.
|
||||
// This should not happen on 64-bit with the currently thunked libraries, since their types
|
||||
// * either have fully consistent data layout across 64-bit architectures.
|
||||
// * or use custom repacking, in which case has_compatible_data_layout isn't used
|
||||
//
|
||||
// Throwing a fake exception here will trigger a build failure.
|
||||
|| (throw "Instantiated on a type that was expected to be compatible", true)
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifndef IS_32BIT_THUNK
|
||||
// Pointers have the same size, hence data layout compatibility only depends on the pointee type
|
||||
template<typename T>
|
||||
inline constexpr bool has_compatible_data_layout<T*> = has_compatible_data_layout<std::remove_cv_t<T>>;
|
||||
template<typename T>
|
||||
inline constexpr bool has_compatible_data_layout<T* const> = has_compatible_data_layout<std::remove_cv_t<T>*>;
|
||||
|
||||
// void* and void** are assumed to be compatible to simplify handling of libraries that use them ubiquitously
|
||||
template<> inline constexpr bool has_compatible_data_layout<void*> = true;
|
||||
template<> inline constexpr bool has_compatible_data_layout<const void*> = true;
|
||||
template<> inline constexpr bool has_compatible_data_layout<void**> = true;
|
||||
template<> inline constexpr bool has_compatible_data_layout<const void**> = true;
|
||||
#endif
|
||||
|
||||
// Placeholder type to indicate the given data is in guest-layout
|
||||
template<typename T>
|
||||
struct guest_layout {
|
||||
@@ -97,6 +126,8 @@ struct guest_layout {
|
||||
static_assert(!std::is_enum_v<T>, "No guest layout defined for this enum type. This is a bug in the thunk generator.");
|
||||
static_assert(!std::is_void_v<T>, "Attempted to get guest layout of void. Missing annotation for void pointer?");
|
||||
|
||||
static_assert(std::is_fundamental_v<T> || has_compatible_data_layout<T>, "Default guest_layout may not be used for non-compatible data");
|
||||
|
||||
using type = std::enable_if_t<!std::is_pointer_v<T>, T>;
|
||||
type data;
|
||||
|
||||
|
||||
@@ -281,6 +281,7 @@ SourceWithAST Fixture::run_thunkgen_host(std::string_view prelude, std::string_v
|
||||
"};\n"
|
||||
"struct ExportEntry { uint8_t* sha256; void(*fn)(void *); };\n"
|
||||
"void *dlsym_default(void* handle, const char* symbol);\n"
|
||||
"template<typename T> inline constexpr bool has_compatible_data_layout = std::is_integral_v<T> || std::is_enum_v<T>;\n"
|
||||
"template<typename T>\n"
|
||||
"struct guest_layout {\n"
|
||||
" T data;\n"
|
||||
|
||||
Reference in new issue
Block a user