1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
// Copyright 2012 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License. Both these licenses can be
// found in the LICENSE file.
#include <emscripten/bind.h>
#ifdef USE_CXA_DEMANGLE
#include <../lib/libcxxabi/include/cxxabi.h>
#endif
#include <algorithm>
#include <climits>
#include <emscripten/emscripten.h>
#include <emscripten/wire.h>
#include <limits>
#include <list>
#include <typeinfo>
#include <vector>
using namespace emscripten;
extern "C" {
const char* EMSCRIPTEN_KEEPALIVE __getTypeName(const std::type_info* ti) {
if (has_unbound_type_names) {
#ifdef USE_CXA_DEMANGLE
int stat;
char* demangled = abi::__cxa_demangle(ti->name(), NULL, NULL, &stat);
if (stat == 0 && demangled) {
return demangled;
}
switch (stat) {
case -1:
return strdup("<allocation failure>");
case -2:
return strdup("<invalid C++ symbol>");
case -3:
return strdup("<invalid argument>");
default:
return strdup("<unknown error>");
}
#else
return strdup(ti->name());
#endif
} else {
char str[80];
sprintf(str, "%p", reinterpret_cast<const void*>(ti));
return strdup(str);
}
}
}
namespace {
template <typename T> static void register_integer(const char* name) {
using namespace internal;
_embind_register_integer(TypeID<T>::get(), name, sizeof(T), std::numeric_limits<T>::min(),
std::numeric_limits<T>::max());
}
template <typename T> static void register_bigint(const char* name) {
using namespace internal;
_embind_register_bigint(TypeID<T>::get(), name, sizeof(T), std::numeric_limits<T>::min(),
std::numeric_limits<T>::max());
}
template <typename T> static void register_float(const char* name) {
using namespace internal;
_embind_register_float(TypeID<T>::get(), name, sizeof(T));
}
// matches typeMapping in embind.js
enum TypedArrayIndex {
Int8Array,
Uint8Array,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array,
// Only available if WASM_BIGINT
Int64Array,
Uint64Array,
};
template <typename T> constexpr TypedArrayIndex getTypedArrayIndex() {
static_assert(internal::typeSupportsMemoryView<T>(), "type does not map to a typed array");
return std::is_floating_point<T>::value
? (sizeof(T) == 4 ? Float32Array : Float64Array)
: (sizeof(T) == 1
? (std::is_signed<T>::value ? Int8Array : Uint8Array)
: (sizeof(T) == 2 ? (std::is_signed<T>::value ? Int16Array : Uint16Array)
: (sizeof(T) == 4 ? (std::is_signed<T>::value ? Int32Array : Uint32Array)
: (std::is_signed<T>::value ? Int64Array : Uint64Array))));
}
template <typename T> static void register_memory_view(const char* name) {
using namespace internal;
_embind_register_memory_view(TypeID<memory_view<T>>::get(), getTypedArrayIndex<T>(), name);
}
} // namespace
extern "C" {
// Normal initialization, executed through a global constructor. This
// happens on the main thread; pthreads will call it manually, so make
// sure we also export it (via EMSCRIPTEN_KEEPALIVE).
EMSCRIPTEN_KEEPALIVE __attribute__((constructor))
void __embind_register_native_and_builtin_types() {
using namespace emscripten::internal;
_embind_register_void(TypeID<void>::get(), "void");
_embind_register_bool(TypeID<bool>::get(), "bool", sizeof(bool), true, false);
register_integer<char>("char");
register_integer<signed char>("signed char");
register_integer<unsigned char>("unsigned char");
register_integer<signed short>("short");
register_integer<unsigned short>("unsigned short");
register_integer<signed int>("int");
register_integer<unsigned int>("unsigned int");
register_integer<signed long>("long");
register_integer<unsigned long>("unsigned long");
register_bigint<int64_t>("int64_t");
register_bigint<uint64_t>("uint64_t");
register_float<float>("float");
register_float<double>("double");
_embind_register_std_string(TypeID<std::string>::get(), "std::string");
_embind_register_std_string(
TypeID<std::basic_string<unsigned char>>::get(), "std::basic_string<unsigned char>");
_embind_register_std_wstring(TypeID<std::wstring>::get(), sizeof(wchar_t), "std::wstring");
_embind_register_std_wstring(TypeID<std::u16string>::get(), sizeof(char16_t), "std::u16string");
_embind_register_std_wstring(TypeID<std::u32string>::get(), sizeof(char32_t), "std::u32string");
_embind_register_emval(TypeID<val>::get(), "emscripten::val");
// Some of these types are aliases for each other. Luckily,
// embind.js's _embind_register_memory_view ignores duplicate
// registrations rather than asserting, so the first
// register_memory_view call for a particular type will take
// precedence.
register_memory_view<char>("emscripten::memory_view<char>");
register_memory_view<signed char>("emscripten::memory_view<signed char>");
register_memory_view<unsigned char>("emscripten::memory_view<unsigned char>");
register_memory_view<short>("emscripten::memory_view<short>");
register_memory_view<unsigned short>("emscripten::memory_view<unsigned short>");
register_memory_view<int>("emscripten::memory_view<int>");
register_memory_view<unsigned int>("emscripten::memory_view<unsigned int>");
register_memory_view<long>("emscripten::memory_view<long>");
register_memory_view<unsigned long>("emscripten::memory_view<unsigned long>");
register_memory_view<int8_t>("emscripten::memory_view<int8_t>");
register_memory_view<uint8_t>("emscripten::memory_view<uint8_t>");
register_memory_view<int16_t>("emscripten::memory_view<int16_t>");
register_memory_view<uint16_t>("emscripten::memory_view<uint16_t>");
register_memory_view<int32_t>("emscripten::memory_view<int32_t>");
register_memory_view<uint32_t>("emscripten::memory_view<uint32_t>");
register_memory_view<float>("emscripten::memory_view<float>");
register_memory_view<double>("emscripten::memory_view<double>");
#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__
register_memory_view<long double>("emscripten::memory_view<long double>");
#endif
}
} // extern "C"
|