// 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 #ifdef USE_CXA_DEMANGLE #include <../lib/libcxxabi/include/cxxabi.h> #endif #include #include #include #include #include #include #include #include using namespace emscripten; using namespace internal; extern "C" { const char* __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(""); case -2: return strdup(""); case -3: return strdup(""); default: return strdup(""); } #else return strdup(ti->name()); #endif } else { char str[80]; sprintf(str, "%p", reinterpret_cast(ti)); return strdup(str); } } static InitFunc* init_funcs = nullptr; 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; } void _emval_coro_resume(val::awaiter* awaiter, EM_VAL result) { awaiter->resume_with(val::take_ownership(result)); } void _emval_coro_reject(val::awaiter* awaiter, EM_VAL error) { awaiter->reject_with(val::take_ownership(error)); } } namespace { template static void register_integer(const char* name) { using namespace internal; _embind_register_integer(TypeID::get(), name, sizeof(T), std::numeric_limits::min(), std::numeric_limits::max()); } template static void register_bigint(const char* name) { using namespace internal; _embind_register_bigint(TypeID::get(), name, sizeof(T), std::numeric_limits::min(), std::numeric_limits::max()); } template static void register_float(const char* name) { using namespace internal; _embind_register_float(TypeID::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 constexpr TypedArrayIndex getTypedArrayIndex() { static_assert(internal::typeSupportsMemoryView(), "type does not map to a typed array"); return std::is_floating_point::value ? (sizeof(T) == 4 ? Float32Array : Float64Array) : (sizeof(T) == 1 ? (std::is_signed::value ? Int8Array : Uint8Array) : (sizeof(T) == 2 ? (std::is_signed::value ? Int16Array : Uint16Array) : (sizeof(T) == 4 ? (std::is_signed::value ? Int32Array : Uint32Array) : (std::is_signed::value ? Int64Array : Uint64Array)))); } template static void register_memory_view(const char* name) { using namespace internal; _embind_register_memory_view(TypeID>::get(), getTypedArrayIndex(), name); } } // namespace EMSCRIPTEN_BINDINGS(builtin) { using namespace emscripten::internal; _embind_register_void(TypeID::get(), "void"); _embind_register_bool(TypeID::get(), "bool", true, false); static_assert(sizeof(bool) == 1); register_integer("char"); register_integer("signed char"); register_integer("unsigned char"); register_integer("short"); register_integer("unsigned short"); register_integer("int"); register_integer("unsigned int"); #if __wasm64__ register_bigint("long"); register_bigint("unsigned long"); #else register_integer("long"); register_integer("unsigned long"); #endif register_bigint("long long"); register_bigint("unsigned long long"); register_float("float"); register_float("double"); _embind_register_std_string(TypeID::get(), "std::string"); _embind_register_std_wstring(TypeID::get(), sizeof(wchar_t), "std::wstring"); _embind_register_std_wstring(TypeID::get(), sizeof(char16_t), "std::u16string"); _embind_register_std_wstring(TypeID::get(), sizeof(char32_t), "std::u32string"); _embind_register_emval(TypeID::get()); // 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("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); register_memory_view("emscripten::memory_view"); }