msvc/clang intrinsic
luncliff opened this issue · 0 comments
luncliff commented
Research about compiler intrinsics and its operation results
Reference
- https://github.com/llvm-mirror/libcxx/blob/bb716549f1a0d445616cf1d2619623a599d12bea/include/experimental/coroutine
- https://clang.llvm.org/docs/LanguageExtensions.html#c-coroutines-support-builtins
- https://llvm.org/docs/Coroutines.html#example
Frame Layout
Mostly memory alignment is multiply of 16.
// from VC++ <experimental/resumable>
template<typename T>
constexpr auto aligned_size_v = ((sizeof(T) + 16 - 1) & ~(16 - 1));
// in short this is `goto`
using procedure_t = void(__cdecl*)(void*);
Each compiler's memory layout of coroutine frame will be described below.
MSVC
| Promise | Frame Prefix | Local variables |
\
resumable_handle<void>
address: low-->high
The structure of frame prefix is like this
// - Note
// MSVC coroutine frame's prefix. See `_Resumable_frame_prefix`
struct msvc_frame_prefix final
{
procedure_t factivate;
uint16_t index;
uint16_t flag;
};
static_assert(sizeof(msvc_frame_prefix) == 16);
Clang
| Frame Prefix | Promise | ? | Local variables |
\
resumable_handle<void>
address: low-->high
?
seems like a guard. When it's corrupted, builtin intrinsics makes a crash.
The structure of frame prefix is like this
// - Note
// Clang coroutine frame's prefix. See reference docs above
struct clang_frame_prefix final
{
procedure_t factivate;
procedure_t fdestroy;
};
static_assert(sizeof(clang_frame_prefix) == 16);
Compiler Intrinsic
intrinsics and their behavior
MSVC
// <experimental/resumable>
extern "C" size_t _coro_resume(void*);
extern "C" void _coro_destroy(void*);
extern "C" size_t _coro_done(void*);
Clang
// <experimental/coroutine>
void __builtin_coro_resume(void *addr);
void __builtin_coro_destroy(void *addr);
bool __builtin_coro_done(void *addr);