#ifndef wasm_support_utilities_h
#define wasm_support_utilities_h
#include "compiler-support.h"
#include <cassert>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <type_traits>
#include "support/bits.h"
namespace wasm {
template<class Destination, class Source>
inline Destination bit_cast(const Source& source) {
static_assert(sizeof(Destination) == sizeof(Source),
"bit_cast needs to be between types of the same size");
static_assert(std::is_pod<Destination>::value, "non-POD bit_cast undefined");
static_assert(std::is_pod<Source>::value, "non-POD bit_cast undefined");
Destination destination;
std::memcpy(&destination, &source, sizeof(destination));
return destination;
}
inline size_t alignAddr(size_t address, size_t alignment) {
assert(alignment && Bits::isPowerOf2((uint32_t)alignment) &&
"Alignment is not a power of two!");
assert(address + alignment - 1 >= address);
return ((address + alignment - 1) & ~(alignment - 1));
}
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
class Fatal {
public:
Fatal() { std::cerr << "Fatal: "; }
template<typename T> Fatal& operator<<(T arg) {
std::cerr << arg;
return *this;
}
WASM_NORETURN ~Fatal() {
std::cerr << "\n";
_Exit(1);
}
};
WASM_NORETURN void handle_unreachable(const char* msg = nullptr,
const char* file = nullptr,
unsigned line = 0);
#ifndef NDEBUG
#define WASM_UNREACHABLE(msg) wasm::handle_unreachable(msg, __FILE__, __LINE__)
#elif defined(WASM_BUILTIN_UNREACHABLE)
#define WASM_UNREACHABLE(msg) WASM_BUILTIN_UNREACHABLE
#else
#define WASM_UNREACHABLE(msg) wasm::handle_unreachable()
#endif
}
#endif