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