-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
228 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
// 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; | ||
using namespace internal; | ||
|
||
static char* pointerToHexString(const void* ptr) { | ||
static const char hexDigits[] = "0123456789abcdef"; | ||
uintptr_t address = reinterpret_cast<uintptr_t>(ptr); | ||
char str[20] = "0x"; // Includes the "0x" prefix | ||
int index = 2; | ||
bool leadingZero = true; // Used to skip leading zeros | ||
|
||
// Convert the address to a hexadecimal string | ||
for (int i = (sizeof(address) * 2) - 1; i >= 0; --i) { | ||
char hexChar = hexDigits[(address >> (i * 4)) & 0xF]; | ||
if (hexChar != '0' || !leadingZero || i == 0) { // Ensures at least one zero in the final character | ||
str[index++] = hexChar; | ||
leadingZero = false; | ||
} | ||
} | ||
str[index] = '\0'; | ||
|
||
return strdup(str); | ||
} | ||
|
||
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 { | ||
//cjh char str[80]; | ||
// sprintf(str, "%p", reinterpret_cast<const void*>(ti)); | ||
// return strdup(str); | ||
return pointerToHexString(reinterpret_cast<const void*>(ti)); | ||
} | ||
} | ||
|
||
static InitFunc* init_funcs = nullptr; | ||
|
||
EMSCRIPTEN_KEEPALIVE void _embind_initialize_bindings() { | ||
for (auto* f = init_funcs; f; f = f->next) { | ||
f->init_func(); | ||
} | ||
} | ||
|
||
void _embind_register_bindings(InitFunc* f) { | ||
f->next = init_funcs; | ||
init_funcs = f; | ||
} | ||
|
||
} | ||
|
||
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 | ||
|
||
EMSCRIPTEN_BINDINGS(builtin) { | ||
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"); | ||
#if __wasm64__ | ||
register_bigint<signed long>("long"); | ||
register_bigint<unsigned long>("unsigned long"); | ||
#else | ||
register_integer<signed long>("long"); | ||
register_integer<unsigned long>("unsigned long"); | ||
#endif | ||
|
||
register_bigint<int64_t>("int64_t"); | ||
register_bigint<uint64_t>("uint64_t"); | ||
|
||
register_float<float>("float"); | ||
register_float<double>("double"); | ||
|
||
/*cjh | ||
_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"); | ||
/*cjh | ||
// 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<int64_t>("emscripten::memory_view<int64_t>"); | ||
register_memory_view<uint64_t>("emscripten::memory_view<uint64_t>"); | ||
register_memory_view<float>("emscripten::memory_view<float>"); | ||
register_memory_view<double>("emscripten::memory_view<double>"); | ||
*/ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters