@crossbind/core-embind-jsi 2.0.0-beta.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/cpp/CMakeLists.txt +16 -0
- package/cpp/src/emscripten/bind.cpp +1158 -0
- package/cpp/src/emscripten/bind.h +2880 -0
- package/cpp/src/emscripten/em_macros.h +43 -0
- package/cpp/src/emscripten/val.h +708 -0
- package/cpp/src/emscripten/wire.h +610 -0
- package/crossbind.config.mjs +5 -0
- package/js/embind.js +4908 -0
- package/package.json +27 -0
|
@@ -0,0 +1,2880 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2012 The Emscripten Authors. All rights reserved.
|
|
3
|
+
* Emscripten is available under two separate licenses, the MIT license and the
|
|
4
|
+
* University of Illinois/NCSA Open Source License. Both these licenses can be
|
|
5
|
+
* found in the LICENSE file.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __cplusplus < 201103L
|
|
11
|
+
#error Including <./bind.h> requires building with -std=c++11 or newer!
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
#include <cassert>
|
|
15
|
+
#include <cstddef>
|
|
16
|
+
#include <functional>
|
|
17
|
+
#include <map>
|
|
18
|
+
#include <string>
|
|
19
|
+
#include <type_traits>
|
|
20
|
+
#include <vector>
|
|
21
|
+
|
|
22
|
+
#include "./em_macros.h"
|
|
23
|
+
#include "./val.h"
|
|
24
|
+
#include "./wire.h"
|
|
25
|
+
|
|
26
|
+
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
|
|
27
|
+
#include <sanitizer/lsan_interface.h>
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
#include "jsi/jsi.h"
|
|
31
|
+
|
|
32
|
+
// #include <android/log.h>
|
|
33
|
+
// #define APPNAME "react-native-crossbind"
|
|
34
|
+
|
|
35
|
+
namespace emscripten {
|
|
36
|
+
extern facebook::jsi::Runtime* jsRuntime;
|
|
37
|
+
|
|
38
|
+
enum class sharing_policy {
|
|
39
|
+
NONE = 0,
|
|
40
|
+
INTRUSIVE = 1,
|
|
41
|
+
BY_EMVAL = 2,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
namespace internal {
|
|
45
|
+
EMSCRIPTEN_KEEPALIVE void _embind_initialize_bindings(facebook::jsi::Runtime& rt, std::string path);
|
|
46
|
+
|
|
47
|
+
typedef int32_t GenericEnumValue;
|
|
48
|
+
|
|
49
|
+
typedef void* GenericFunction;
|
|
50
|
+
typedef void (*VoidFunctionPtr)(void);
|
|
51
|
+
|
|
52
|
+
// Implemented in JavaScript. Don't call these directly.
|
|
53
|
+
|
|
54
|
+
void _embind_fatal_error(
|
|
55
|
+
const char* name,
|
|
56
|
+
const char* payload) __attribute__((__noreturn__));
|
|
57
|
+
|
|
58
|
+
void _embind_register_void(
|
|
59
|
+
TYPEID voidType,
|
|
60
|
+
const char* name);
|
|
61
|
+
|
|
62
|
+
void _embind_register_bool(
|
|
63
|
+
TYPEID boolType,
|
|
64
|
+
const char* name,
|
|
65
|
+
size_t size,
|
|
66
|
+
bool trueValue,
|
|
67
|
+
bool falseValue);
|
|
68
|
+
|
|
69
|
+
void _embind_register_integer(
|
|
70
|
+
TYPEID integerType,
|
|
71
|
+
const char* name,
|
|
72
|
+
size_t size,
|
|
73
|
+
int32_t minRange,
|
|
74
|
+
uint32_t maxRange);
|
|
75
|
+
|
|
76
|
+
void _embind_register_bigint(
|
|
77
|
+
TYPEID integerType,
|
|
78
|
+
const char* name,
|
|
79
|
+
size_t size,
|
|
80
|
+
int64_t minRange,
|
|
81
|
+
uint64_t maxRange);
|
|
82
|
+
|
|
83
|
+
void _embind_register_float(
|
|
84
|
+
TYPEID floatType,
|
|
85
|
+
const char* name,
|
|
86
|
+
size_t size);
|
|
87
|
+
|
|
88
|
+
void _embind_register_std_string(
|
|
89
|
+
TYPEID stringType,
|
|
90
|
+
const char* name);
|
|
91
|
+
|
|
92
|
+
void _embind_register_std_wstring(
|
|
93
|
+
TYPEID stringType,
|
|
94
|
+
size_t charSize,
|
|
95
|
+
const char* name);
|
|
96
|
+
|
|
97
|
+
void _embind_register_emval(
|
|
98
|
+
TYPEID emvalType,
|
|
99
|
+
const char* name);
|
|
100
|
+
|
|
101
|
+
void _embind_register_memory_view(
|
|
102
|
+
TYPEID memoryViewType,
|
|
103
|
+
unsigned typedArrayIndex,
|
|
104
|
+
const char* name);
|
|
105
|
+
|
|
106
|
+
void _embind_register_function(
|
|
107
|
+
const char* name,
|
|
108
|
+
unsigned argCount,
|
|
109
|
+
const TYPEID argTypes[],
|
|
110
|
+
const char* signature,
|
|
111
|
+
facebook::jsi::Function& invoker,
|
|
112
|
+
GenericFunction function,
|
|
113
|
+
bool isAsync);
|
|
114
|
+
|
|
115
|
+
void _embind_register_optional(
|
|
116
|
+
TYPEID optionalType,
|
|
117
|
+
TYPEID type);
|
|
118
|
+
|
|
119
|
+
void _embind_register_value_array(
|
|
120
|
+
TYPEID tupleType,
|
|
121
|
+
const char* name,
|
|
122
|
+
const char* constructorSignature,
|
|
123
|
+
facebook::jsi::Function& constructor,
|
|
124
|
+
const char* destructorSignature,
|
|
125
|
+
facebook::jsi::Function& destructor);
|
|
126
|
+
|
|
127
|
+
void _embind_register_value_array_element(
|
|
128
|
+
TYPEID tupleType,
|
|
129
|
+
TYPEID getterReturnType,
|
|
130
|
+
const char* getterSignature,
|
|
131
|
+
facebook::jsi::Function& getter,
|
|
132
|
+
void* getterContext,
|
|
133
|
+
TYPEID setterArgumentType,
|
|
134
|
+
const char* setterSignature,
|
|
135
|
+
facebook::jsi::Function& setter,
|
|
136
|
+
void* setterContext);
|
|
137
|
+
|
|
138
|
+
void _embind_finalize_value_array(TYPEID tupleType);
|
|
139
|
+
|
|
140
|
+
void _embind_register_value_object(
|
|
141
|
+
TYPEID structType,
|
|
142
|
+
const char* fieldName,
|
|
143
|
+
const char* constructorSignature,
|
|
144
|
+
facebook::jsi::Function& constructor,
|
|
145
|
+
const char* destructorSignature,
|
|
146
|
+
facebook::jsi::Function& destructor);
|
|
147
|
+
|
|
148
|
+
void _embind_register_value_object_field(
|
|
149
|
+
TYPEID structType,
|
|
150
|
+
const char* fieldName,
|
|
151
|
+
TYPEID getterReturnType,
|
|
152
|
+
const char* getterSignature,
|
|
153
|
+
facebook::jsi::Function& getter,
|
|
154
|
+
void* getterContext,
|
|
155
|
+
TYPEID setterArgumentType,
|
|
156
|
+
const char* setterSignature,
|
|
157
|
+
facebook::jsi::Function& setter,
|
|
158
|
+
void* setterContext);
|
|
159
|
+
|
|
160
|
+
void _embind_finalize_value_object(TYPEID structType);
|
|
161
|
+
|
|
162
|
+
void _embind_register_class(
|
|
163
|
+
TYPEID classType,
|
|
164
|
+
TYPEID pointerType,
|
|
165
|
+
TYPEID constPointerType,
|
|
166
|
+
TYPEID baseClassType,
|
|
167
|
+
const char* getActualTypeSignature,
|
|
168
|
+
facebook::jsi::Function& getActualType,
|
|
169
|
+
const char* upcastSignature,
|
|
170
|
+
facebook::jsi::Function& upcast,
|
|
171
|
+
const char* downcastSignature,
|
|
172
|
+
facebook::jsi::Function& downcast,
|
|
173
|
+
const char* className,
|
|
174
|
+
const char* destructorSignature,
|
|
175
|
+
facebook::jsi::Function& destructor);
|
|
176
|
+
|
|
177
|
+
void _embind_register_class_constructor(
|
|
178
|
+
TYPEID classType,
|
|
179
|
+
unsigned argCount,
|
|
180
|
+
const TYPEID argTypes[],
|
|
181
|
+
const char* invokerSignature,
|
|
182
|
+
facebook::jsi::Function& invoker,
|
|
183
|
+
GenericFunction constructor);
|
|
184
|
+
|
|
185
|
+
void _embind_register_class_function(
|
|
186
|
+
TYPEID classType,
|
|
187
|
+
const char* methodName,
|
|
188
|
+
unsigned argCount,
|
|
189
|
+
const TYPEID argTypes[],
|
|
190
|
+
const char* invokerSignature,
|
|
191
|
+
facebook::jsi::Function& invoker,
|
|
192
|
+
void* context,
|
|
193
|
+
unsigned isPureVirtual,
|
|
194
|
+
bool isAsync);
|
|
195
|
+
|
|
196
|
+
void _embind_register_class_property(
|
|
197
|
+
TYPEID classType,
|
|
198
|
+
const char* fieldName,
|
|
199
|
+
TYPEID getterReturnType,
|
|
200
|
+
const char* getterSignature,
|
|
201
|
+
facebook::jsi::Function& getter,
|
|
202
|
+
void* getterContext,
|
|
203
|
+
TYPEID setterArgumentType,
|
|
204
|
+
const char* setterSignature,
|
|
205
|
+
facebook::jsi::Function& setter,
|
|
206
|
+
void* setterContext);
|
|
207
|
+
|
|
208
|
+
void _embind_register_class_class_function(
|
|
209
|
+
TYPEID classType,
|
|
210
|
+
const char* methodName,
|
|
211
|
+
unsigned argCount,
|
|
212
|
+
const TYPEID argTypes[],
|
|
213
|
+
const char* invokerSignature,
|
|
214
|
+
facebook::jsi::Function& invoker,
|
|
215
|
+
GenericFunction method,
|
|
216
|
+
bool isAsync);
|
|
217
|
+
|
|
218
|
+
void _embind_register_class_class_property(
|
|
219
|
+
TYPEID classType,
|
|
220
|
+
const char* fieldName,
|
|
221
|
+
TYPEID fieldType,
|
|
222
|
+
void* fieldContext,
|
|
223
|
+
const char* getterSignature,
|
|
224
|
+
facebook::jsi::Function& getter,
|
|
225
|
+
const char* setterSignature,
|
|
226
|
+
facebook::jsi::Function& setter);
|
|
227
|
+
|
|
228
|
+
EM_VAL _embind_create_inheriting_constructor(
|
|
229
|
+
const char* constructorName,
|
|
230
|
+
TYPEID wrapperType,
|
|
231
|
+
EM_VAL properties);
|
|
232
|
+
|
|
233
|
+
void _embind_register_enum(
|
|
234
|
+
TYPEID enumType,
|
|
235
|
+
const char* name,
|
|
236
|
+
size_t size,
|
|
237
|
+
bool isSigned);
|
|
238
|
+
|
|
239
|
+
void _embind_register_smart_ptr(
|
|
240
|
+
TYPEID pointerType,
|
|
241
|
+
TYPEID pointeeType,
|
|
242
|
+
const char* pointerName,
|
|
243
|
+
sharing_policy sharingPolicy,
|
|
244
|
+
const char* getPointeeSignature,
|
|
245
|
+
facebook::jsi::Function& getPointee,
|
|
246
|
+
const char* constructorSignature,
|
|
247
|
+
facebook::jsi::Function& constructor,
|
|
248
|
+
const char* shareSignature,
|
|
249
|
+
facebook::jsi::Function& share,
|
|
250
|
+
const char* destructorSignature,
|
|
251
|
+
facebook::jsi::Function& destructor);
|
|
252
|
+
|
|
253
|
+
void _embind_register_enum_value(
|
|
254
|
+
TYPEID enumType,
|
|
255
|
+
const char* valueName,
|
|
256
|
+
GenericEnumValue value);
|
|
257
|
+
|
|
258
|
+
void _embind_register_constant(
|
|
259
|
+
const char* name,
|
|
260
|
+
TYPEID constantType,
|
|
261
|
+
const facebook::jsi::Value value);
|
|
262
|
+
|
|
263
|
+
// Register an InitFunc in the global linked list of init functions.
|
|
264
|
+
void _embind_register_bindings(struct InitFunc* f);
|
|
265
|
+
|
|
266
|
+
// Binding initialization functions registerd by EMSCRIPTEN_BINDINGS macro
|
|
267
|
+
// below. Stored as linked list of static data object avoiding std containers
|
|
268
|
+
// to avoid static contructor ordering issues.
|
|
269
|
+
struct InitFunc {
|
|
270
|
+
InitFunc(void (*init_func)()) : init_func(init_func) {
|
|
271
|
+
// This the function immediately upon constructions, and also register
|
|
272
|
+
// it so that it can be called again on each worker that starts.
|
|
273
|
+
// init_func();
|
|
274
|
+
_embind_register_bindings(this);
|
|
275
|
+
}
|
|
276
|
+
void (*init_func)();
|
|
277
|
+
InitFunc* next = nullptr;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
} // end namespace internal
|
|
282
|
+
|
|
283
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
284
|
+
// POLICIES
|
|
285
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
286
|
+
|
|
287
|
+
template<int Index>
|
|
288
|
+
struct arg {
|
|
289
|
+
static constexpr int index = Index + 1;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
struct ret_val {
|
|
293
|
+
static constexpr int index = 0;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/*
|
|
297
|
+
template<typename Slot>
|
|
298
|
+
struct allow_raw_pointer {
|
|
299
|
+
template<typename InputType, int Index>
|
|
300
|
+
struct Transform {
|
|
301
|
+
typedef typename std::conditional<
|
|
302
|
+
Index == Slot::index,
|
|
303
|
+
internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>,
|
|
304
|
+
InputType
|
|
305
|
+
>::type type;
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
*/
|
|
309
|
+
|
|
310
|
+
// allow all raw pointers
|
|
311
|
+
struct allow_raw_pointers {
|
|
312
|
+
template<typename InputType, int Index>
|
|
313
|
+
struct Transform {
|
|
314
|
+
typedef typename std::conditional<
|
|
315
|
+
std::is_pointer<InputType>::value,
|
|
316
|
+
internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>,
|
|
317
|
+
InputType
|
|
318
|
+
>::type type;
|
|
319
|
+
};
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// this is temporary until arg policies are reworked
|
|
323
|
+
template<typename Slot>
|
|
324
|
+
struct allow_raw_pointer : public allow_raw_pointers {
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
struct async {
|
|
328
|
+
template<typename InputType, int Index>
|
|
329
|
+
struct Transform {
|
|
330
|
+
typedef InputType type;
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
namespace internal {
|
|
335
|
+
|
|
336
|
+
template<typename... Policies>
|
|
337
|
+
struct isAsync;
|
|
338
|
+
|
|
339
|
+
template<typename... Rest>
|
|
340
|
+
struct isAsync<async, Rest...> {
|
|
341
|
+
static constexpr bool value = true;
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
template<typename T, typename... Rest>
|
|
345
|
+
struct isAsync<T, Rest...> {
|
|
346
|
+
static constexpr bool value = isAsync<Rest...>::value;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
template<>
|
|
350
|
+
struct isAsync<> {
|
|
351
|
+
static constexpr bool value = false;
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
357
|
+
// select_overload and select_const
|
|
358
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
359
|
+
|
|
360
|
+
template<typename Signature>
|
|
361
|
+
Signature* select_overload(Signature* fn) {
|
|
362
|
+
return fn;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
template<typename Signature, typename ClassType>
|
|
366
|
+
auto select_overload(Signature (ClassType::*fn)) -> decltype(fn) {
|
|
367
|
+
return fn;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
template<typename ClassType, typename ReturnType, typename... Args>
|
|
371
|
+
auto select_const(ReturnType (ClassType::*method)(Args...) const) -> decltype(method) {
|
|
372
|
+
return method;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
namespace internal {
|
|
376
|
+
// this should be in <type_traits>, but alas, it's not
|
|
377
|
+
template<typename T> struct remove_class;
|
|
378
|
+
template<typename C, typename R, typename... A>
|
|
379
|
+
struct remove_class<R(C::*)(A...)> { using type = R(A...); };
|
|
380
|
+
template<typename C, typename R, typename... A>
|
|
381
|
+
struct remove_class<R(C::*)(A...) const> { using type = R(A...); };
|
|
382
|
+
template<typename C, typename R, typename... A>
|
|
383
|
+
struct remove_class<R(C::*)(A...) volatile> { using type = R(A...); };
|
|
384
|
+
template<typename C, typename R, typename... A>
|
|
385
|
+
struct remove_class<R(C::*)(A...) const volatile> { using type = R(A...); };
|
|
386
|
+
|
|
387
|
+
template<typename LambdaType>
|
|
388
|
+
using LambdaSignature = typename remove_class<
|
|
389
|
+
decltype(&LambdaType::operator())
|
|
390
|
+
>::type;
|
|
391
|
+
} // end namespace internal
|
|
392
|
+
|
|
393
|
+
// requires captureless lambda because implicitly coerces to function pointer
|
|
394
|
+
template<typename LambdaType>
|
|
395
|
+
internal::LambdaSignature<LambdaType>* optional_override(const LambdaType& fp) {
|
|
396
|
+
return fp;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
400
|
+
// Invoker
|
|
401
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
402
|
+
|
|
403
|
+
namespace internal {
|
|
404
|
+
|
|
405
|
+
// C++ exceptions escaping a host function reach JS engine-dependently (often with
|
|
406
|
+
// the what() text dropped); rethrowing as JSError guarantees e.message everywhere.
|
|
407
|
+
template<typename F>
|
|
408
|
+
inline decltype(auto) rethrowAsJsError(facebook::jsi::Runtime& rt, F&& call) {
|
|
409
|
+
try {
|
|
410
|
+
return std::forward<F>(call)();
|
|
411
|
+
} catch (const facebook::jsi::JSError&) {
|
|
412
|
+
throw;
|
|
413
|
+
} catch (const std::exception& e) {
|
|
414
|
+
throw facebook::jsi::JSError(rt, std::string(e.what()));
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
template<typename ReturnType, typename... Args>
|
|
419
|
+
struct Invoker {
|
|
420
|
+
static typename internal::BindingType<ReturnType>::WireType invoke(
|
|
421
|
+
ReturnType (*fn)(Args...),
|
|
422
|
+
typename internal::BindingType<Args>::WireType... args
|
|
423
|
+
) {
|
|
424
|
+
return internal::BindingType<ReturnType>::toWireType(
|
|
425
|
+
fn(
|
|
426
|
+
internal::BindingType<Args>::fromWireType(args)...
|
|
427
|
+
)
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
static typename internal::BindingType<ReturnType>::WireType2 invoke2(
|
|
432
|
+
facebook::jsi::Runtime& rt,
|
|
433
|
+
ReturnType (*fn)(Args...),
|
|
434
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
435
|
+
) {
|
|
436
|
+
return rethrowAsJsError(rt, [&]() -> typename internal::BindingType<ReturnType>::WireType2 {
|
|
437
|
+
return internal::BindingType<ReturnType>::toWireType2(rt,
|
|
438
|
+
fn(
|
|
439
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...
|
|
440
|
+
)
|
|
441
|
+
);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
template<typename... Args>
|
|
447
|
+
struct Invoker<void, Args...> {
|
|
448
|
+
static void invoke(
|
|
449
|
+
void (*fn)(Args...),
|
|
450
|
+
typename internal::BindingType<Args>::WireType... args
|
|
451
|
+
) {
|
|
452
|
+
return fn(
|
|
453
|
+
internal::BindingType<Args>::fromWireType(args)...
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
static void invoke2(
|
|
458
|
+
facebook::jsi::Runtime& rt,
|
|
459
|
+
void (*fn)(Args...),
|
|
460
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
461
|
+
) {
|
|
462
|
+
return rethrowAsJsError(rt, [&]() -> void {
|
|
463
|
+
fn(
|
|
464
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...
|
|
465
|
+
);
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
namespace async {
|
|
471
|
+
|
|
472
|
+
template<typename F, F f> struct Wrapper;
|
|
473
|
+
template<typename ReturnType, typename... Args, ReturnType(*f)(Args...)>
|
|
474
|
+
struct Wrapper<ReturnType(*)(Args...), f> {
|
|
475
|
+
EMSCRIPTEN_KEEPALIVE static ReturnType invoke(Args... args) {
|
|
476
|
+
return f(args...);
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
} // end namespace async
|
|
481
|
+
|
|
482
|
+
template<typename T, typename... Policies>
|
|
483
|
+
using maybe_wrap_async = typename std::conditional<
|
|
484
|
+
isAsync<Policies...>::value,
|
|
485
|
+
async::Wrapper<decltype(&T::invoke2), &T::invoke2>,
|
|
486
|
+
T
|
|
487
|
+
>::type;
|
|
488
|
+
|
|
489
|
+
template<typename FunctorType, typename ReturnType, typename... Args>
|
|
490
|
+
struct FunctorInvoker {
|
|
491
|
+
static typename internal::BindingType<ReturnType>::WireType invoke(
|
|
492
|
+
FunctorType& function,
|
|
493
|
+
typename internal::BindingType<Args>::WireType... args
|
|
494
|
+
) {
|
|
495
|
+
return internal::BindingType<ReturnType>::toWireType(
|
|
496
|
+
function(
|
|
497
|
+
internal::BindingType<Args>::fromWireType(args)...)
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
static typename internal::BindingType<ReturnType>::WireType2 invoke2(
|
|
502
|
+
facebook::jsi::Runtime& rt,
|
|
503
|
+
FunctorType& function,
|
|
504
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
505
|
+
) {
|
|
506
|
+
return rethrowAsJsError(rt, [&]() -> typename internal::BindingType<ReturnType>::WireType2 {
|
|
507
|
+
return internal::BindingType<ReturnType>::toWireType2(
|
|
508
|
+
rt,
|
|
509
|
+
function(
|
|
510
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...)
|
|
511
|
+
);
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
template<typename FunctorType, typename... Args>
|
|
517
|
+
struct FunctorInvoker<FunctorType, void, Args...> {
|
|
518
|
+
static void invoke(
|
|
519
|
+
FunctorType& function,
|
|
520
|
+
typename internal::BindingType<Args>::WireType... args
|
|
521
|
+
) {
|
|
522
|
+
function(
|
|
523
|
+
internal::BindingType<Args>::fromWireType(args)...);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
static void invoke2(
|
|
527
|
+
facebook::jsi::Runtime& rt,
|
|
528
|
+
FunctorType& function,
|
|
529
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
530
|
+
) {
|
|
531
|
+
rethrowAsJsError(rt, [&]() -> void {
|
|
532
|
+
function(
|
|
533
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...);
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
} // end namespace internal
|
|
539
|
+
|
|
540
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
541
|
+
// SignatureCode, SignatureString
|
|
542
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
543
|
+
|
|
544
|
+
namespace internal {
|
|
545
|
+
|
|
546
|
+
template<typename T>
|
|
547
|
+
struct SignatureCode {};
|
|
548
|
+
|
|
549
|
+
template<>
|
|
550
|
+
struct SignatureCode<int> {
|
|
551
|
+
static constexpr char get() {
|
|
552
|
+
return 'i';
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
template<>
|
|
557
|
+
struct SignatureCode<void> {
|
|
558
|
+
static constexpr char get() {
|
|
559
|
+
return 'v';
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
template<>
|
|
564
|
+
struct SignatureCode<float> {
|
|
565
|
+
static constexpr char get() {
|
|
566
|
+
return 'f';
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
template<>
|
|
571
|
+
struct SignatureCode<double> {
|
|
572
|
+
static constexpr char get() {
|
|
573
|
+
return 'd';
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
#ifdef __wasm64__
|
|
578
|
+
// With wasm32 we can fallback to 'i' for pointer types but we need special
|
|
579
|
+
// handling with wasm64.
|
|
580
|
+
template<>
|
|
581
|
+
struct SignatureCode<void*> {
|
|
582
|
+
static constexpr char get() {
|
|
583
|
+
return 'p';
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
template<>
|
|
587
|
+
struct SignatureCode<size_t> {
|
|
588
|
+
static constexpr char get() {
|
|
589
|
+
return 'p';
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
#endif
|
|
593
|
+
|
|
594
|
+
template<typename... Args>
|
|
595
|
+
const char* getGenericSignature() {
|
|
596
|
+
static constexpr char signature[] = { SignatureCode<Args>::get()..., 0 };
|
|
597
|
+
return signature;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
template<typename T> struct SignatureTranslator { using type = int; };
|
|
601
|
+
template<> struct SignatureTranslator<void> { using type = void; };
|
|
602
|
+
template<> struct SignatureTranslator<float> { using type = float; };
|
|
603
|
+
template<> struct SignatureTranslator<double> { using type = double; };
|
|
604
|
+
#ifdef __wasm64__
|
|
605
|
+
template<> struct SignatureTranslator<size_t> { using type = size_t; };
|
|
606
|
+
template<typename PtrType>
|
|
607
|
+
struct SignatureTranslator<PtrType*> { using type = void*; };
|
|
608
|
+
template<typename PtrType>
|
|
609
|
+
struct SignatureTranslator<PtrType&> { using type = void*; };
|
|
610
|
+
template<typename ReturnType, typename... Args>
|
|
611
|
+
struct SignatureTranslator<ReturnType (*)(Args...)> { using type = void*; };
|
|
612
|
+
#endif
|
|
613
|
+
|
|
614
|
+
template<typename... Args>
|
|
615
|
+
EMSCRIPTEN_ALWAYS_INLINE const char* getSpecificSignature() {
|
|
616
|
+
return getGenericSignature<typename SignatureTranslator<Args>::type...>();
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
template<typename Return, typename... Args>
|
|
620
|
+
EMSCRIPTEN_ALWAYS_INLINE const char* getSignature(Return (*)(Args...)) {
|
|
621
|
+
return getSpecificSignature<Return, Args...>();
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
} // end namespace internal
|
|
625
|
+
|
|
626
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
627
|
+
// FUNCTIONS
|
|
628
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
629
|
+
|
|
630
|
+
#define call_invoke_4 ({return invoke(fn, args[0], args[1], args[2], args[3]);})
|
|
631
|
+
#define call_invoke(count) (call_invoke_##count)
|
|
632
|
+
|
|
633
|
+
#define callInvoke(count, invokeVar, fnVar) ({ \
|
|
634
|
+
if constexpr (count == 1) { return invokeVar(rt, fnVar, args[0]); }\
|
|
635
|
+
else if constexpr (count == 2) { return invokeVar(rt, fnVar, args[0], args[1]); }\
|
|
636
|
+
else if constexpr (count == 3) { return invokeVar(rt, fnVar, args[0], args[1], args[2]); }\
|
|
637
|
+
else if constexpr (count == 4) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3]); }\
|
|
638
|
+
else if constexpr (count == 5) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4]); }\
|
|
639
|
+
else if constexpr (count == 6) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5]); }\
|
|
640
|
+
else if constexpr (count == 7) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); }\
|
|
641
|
+
else if constexpr (count == 8) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); }\
|
|
642
|
+
else if constexpr (count == 9) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); }\
|
|
643
|
+
else if constexpr (count == 10) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); }\
|
|
644
|
+
else if constexpr (count == 11) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]); }\
|
|
645
|
+
else if constexpr (count == 12) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11]); }\
|
|
646
|
+
else if constexpr (count == 13) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12]); }\
|
|
647
|
+
else if constexpr (count == 14) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13]); }\
|
|
648
|
+
else if constexpr (count == 15) { return invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13], args[14]); }\
|
|
649
|
+
else { return invokeVar(rt, fnVar); } \
|
|
650
|
+
})
|
|
651
|
+
|
|
652
|
+
#define callInvokeVoid(count, invokeVar, fnVar) ({ \
|
|
653
|
+
if constexpr (count == 1) { invokeVar(rt, fnVar, args[0]); }\
|
|
654
|
+
else if constexpr (count == 2) { invokeVar(rt, fnVar, args[0], args[1]); }\
|
|
655
|
+
else if constexpr (count == 3) { invokeVar(rt, fnVar, args[0], args[1], args[2]); }\
|
|
656
|
+
else if constexpr (count == 4) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3]); }\
|
|
657
|
+
else if constexpr (count == 5) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4]); }\
|
|
658
|
+
else if constexpr (count == 6) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5]); }\
|
|
659
|
+
else if constexpr (count == 7) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); }\
|
|
660
|
+
else if constexpr (count == 8) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); }\
|
|
661
|
+
else if constexpr (count == 9) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); }\
|
|
662
|
+
else if constexpr (count == 10) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); }\
|
|
663
|
+
else if constexpr (count == 11) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]); }\
|
|
664
|
+
else if constexpr (count == 12) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11]); }\
|
|
665
|
+
else if constexpr (count == 13) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12]); }\
|
|
666
|
+
else if constexpr (count == 14) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13]); }\
|
|
667
|
+
else if constexpr (count == 15) { invokeVar(rt, fnVar, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13], args[14]); }\
|
|
668
|
+
else { invokeVar(rt, fnVar); } \
|
|
669
|
+
})
|
|
670
|
+
|
|
671
|
+
template<typename ReturnType, typename... Args, typename... Policies>
|
|
672
|
+
void function(const char* name, ReturnType (*fn)(Args...), Policies...) {
|
|
673
|
+
using namespace internal;
|
|
674
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
|
|
675
|
+
using OriginalInvoker = Invoker<ReturnType, Args...>;
|
|
676
|
+
auto invoke = &maybe_wrap_async<OriginalInvoker, Policies...>::invoke2;
|
|
677
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
678
|
+
*jsRuntime,
|
|
679
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_"+getSignature(invoke)),
|
|
680
|
+
args.getCount(),
|
|
681
|
+
[invoke, fn](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
682
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
683
|
+
callInvokeVoid(sizeof...(Args), invoke, fn);
|
|
684
|
+
return nullptr;
|
|
685
|
+
} else {
|
|
686
|
+
callInvoke(sizeof...(Args), invoke, fn);
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
_embind_register_function(
|
|
690
|
+
name,
|
|
691
|
+
args.getCount(),
|
|
692
|
+
args.getTypes(),
|
|
693
|
+
getSignature(invoke),
|
|
694
|
+
invokeJSIFunc,
|
|
695
|
+
reinterpret_cast<GenericFunction>(fn),
|
|
696
|
+
isAsync<Policies...>::value);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
namespace internal {
|
|
700
|
+
|
|
701
|
+
template<typename ClassType, typename... Args>
|
|
702
|
+
ClassType* operator_new(Args&&... args) {
|
|
703
|
+
return new ClassType(std::forward<Args>(args)...);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
template<typename WrapperType, typename ClassType, typename... Args>
|
|
707
|
+
WrapperType wrapped_new(Args&&... args) {
|
|
708
|
+
return WrapperType(new ClassType(std::forward<Args>(args)...));
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
template<typename ClassType, typename... Args>
|
|
712
|
+
ClassType* raw_constructor(
|
|
713
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
714
|
+
) {
|
|
715
|
+
return new ClassType(
|
|
716
|
+
internal::BindingType<Args>::fromWireType2(*jsRuntime, args)...
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
template<typename ClassType>
|
|
721
|
+
void raw_destructor(ClassType* ptr) {
|
|
722
|
+
delete ptr;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
template<typename FunctionPointerType, typename ReturnType, typename ThisType, typename... Args>
|
|
726
|
+
struct FunctionInvoker {
|
|
727
|
+
static typename internal::BindingType<ReturnType>::WireType invoke(
|
|
728
|
+
FunctionPointerType* function,
|
|
729
|
+
typename internal::BindingType<ThisType>::WireType wireThis,
|
|
730
|
+
typename internal::BindingType<Args>::WireType... args
|
|
731
|
+
) {
|
|
732
|
+
return internal::BindingType<ReturnType>::toWireType(
|
|
733
|
+
(*function)(
|
|
734
|
+
internal::BindingType<ThisType>::fromWireType(wireThis),
|
|
735
|
+
internal::BindingType<Args>::fromWireType(args)...)
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
static typename internal::BindingType<ReturnType>::WireType2 invoke2(
|
|
740
|
+
facebook::jsi::Runtime& rt,
|
|
741
|
+
FunctionPointerType* function,
|
|
742
|
+
typename internal::BindingType<ThisType>::WireType2& wireThis,
|
|
743
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
744
|
+
) {
|
|
745
|
+
return rethrowAsJsError(rt, [&]() -> typename internal::BindingType<ReturnType>::WireType2 {
|
|
746
|
+
return internal::BindingType<ReturnType>::toWireType2(
|
|
747
|
+
rt,
|
|
748
|
+
(*function)(
|
|
749
|
+
internal::BindingType<ThisType>::fromWireType2(rt, wireThis),
|
|
750
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...)
|
|
751
|
+
);
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
template<typename FunctionPointerType, typename ThisType, typename... Args>
|
|
757
|
+
struct FunctionInvoker<FunctionPointerType, void, ThisType, Args...> {
|
|
758
|
+
static void invoke(
|
|
759
|
+
FunctionPointerType* function,
|
|
760
|
+
typename internal::BindingType<ThisType>::WireType wireThis,
|
|
761
|
+
typename internal::BindingType<Args>::WireType... args
|
|
762
|
+
) {
|
|
763
|
+
(*function)(
|
|
764
|
+
internal::BindingType<ThisType>::fromWireType(wireThis),
|
|
765
|
+
internal::BindingType<Args>::fromWireType(args)...);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
static void invoke2(
|
|
769
|
+
facebook::jsi::Runtime& rt,
|
|
770
|
+
FunctionPointerType* function,
|
|
771
|
+
typename internal::BindingType<ThisType>::WireType2& wireThis,
|
|
772
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
773
|
+
) {
|
|
774
|
+
rethrowAsJsError(rt, [&]() -> void {
|
|
775
|
+
(*function)(
|
|
776
|
+
internal::BindingType<ThisType>::fromWireType2(rt, wireThis),
|
|
777
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...);
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
template<typename MemberPointer,
|
|
783
|
+
typename ReturnType,
|
|
784
|
+
typename ThisType,
|
|
785
|
+
typename... Args>
|
|
786
|
+
struct MethodInvoker {
|
|
787
|
+
static typename internal::BindingType<ReturnType>::WireType invoke(
|
|
788
|
+
const MemberPointer& method,
|
|
789
|
+
typename internal::BindingType<ThisType>::WireType wireThis,
|
|
790
|
+
typename internal::BindingType<Args>::WireType... args
|
|
791
|
+
) {
|
|
792
|
+
return internal::BindingType<ReturnType>::toWireType(
|
|
793
|
+
(internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
|
|
794
|
+
internal::BindingType<Args>::fromWireType(args)...
|
|
795
|
+
)
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
static typename internal::BindingType<ReturnType>::WireType2 invoke2(
|
|
800
|
+
facebook::jsi::Runtime& rt,
|
|
801
|
+
const MemberPointer& method,
|
|
802
|
+
typename internal::BindingType<ThisType>::WireType2& wireThis,
|
|
803
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
804
|
+
) {
|
|
805
|
+
return rethrowAsJsError(rt, [&]() -> typename internal::BindingType<ReturnType>::WireType2 {
|
|
806
|
+
return internal::BindingType<ReturnType>::toWireType2(rt,
|
|
807
|
+
(internal::BindingType<ThisType>::fromWireType2(rt, wireThis)->*method)(
|
|
808
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...
|
|
809
|
+
)
|
|
810
|
+
);
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
template<typename MemberPointer,
|
|
816
|
+
typename ThisType,
|
|
817
|
+
typename... Args>
|
|
818
|
+
struct MethodInvoker<MemberPointer, void, ThisType, Args...> {
|
|
819
|
+
static void invoke(
|
|
820
|
+
const MemberPointer& method,
|
|
821
|
+
typename internal::BindingType<ThisType>::WireType wireThis,
|
|
822
|
+
typename internal::BindingType<Args>::WireType... args
|
|
823
|
+
) {
|
|
824
|
+
return (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
|
|
825
|
+
internal::BindingType<Args>::fromWireType(args)...
|
|
826
|
+
);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
static void invoke2(
|
|
830
|
+
facebook::jsi::Runtime& rt,
|
|
831
|
+
const MemberPointer& method,
|
|
832
|
+
typename internal::BindingType<ThisType>::WireType2& wireThis,
|
|
833
|
+
typename internal::BindingType<Args>::WireType2&... args
|
|
834
|
+
) {
|
|
835
|
+
rethrowAsJsError(rt, [&]() -> void {
|
|
836
|
+
(internal::BindingType<ThisType>::fromWireType2(rt, wireThis)->*method)(
|
|
837
|
+
internal::BindingType<Args>::fromWireType2(rt, args)...
|
|
838
|
+
);
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
template<typename InstanceType, typename MemberType>
|
|
844
|
+
struct MemberAccess {
|
|
845
|
+
typedef MemberType InstanceType::*MemberPointer;
|
|
846
|
+
typedef internal::BindingType<MemberType> MemberBinding;
|
|
847
|
+
typedef typename MemberBinding::WireType WireType;
|
|
848
|
+
typedef typename MemberBinding::WireType2 WireType2;
|
|
849
|
+
|
|
850
|
+
template<typename ClassType>
|
|
851
|
+
static WireType getWire(
|
|
852
|
+
const MemberPointer& field,
|
|
853
|
+
const ClassType& ptr
|
|
854
|
+
) {
|
|
855
|
+
return MemberBinding::toWireType(ptr.*field);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
template<typename ClassType>
|
|
859
|
+
static void setWire(
|
|
860
|
+
const MemberPointer& field,
|
|
861
|
+
ClassType& ptr,
|
|
862
|
+
WireType value
|
|
863
|
+
) {
|
|
864
|
+
ptr.*field = MemberBinding::fromWireType(value);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
template<typename ClassType>
|
|
868
|
+
static WireType2 getWire2(
|
|
869
|
+
const MemberPointer& field,
|
|
870
|
+
const ClassType& ptr
|
|
871
|
+
) {
|
|
872
|
+
return MemberBinding::toWireType2(*jsRuntime, ptr.*field);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
template<typename ClassType>
|
|
876
|
+
static void setWire2(
|
|
877
|
+
const MemberPointer& field,
|
|
878
|
+
ClassType& ptr,
|
|
879
|
+
WireType2& value
|
|
880
|
+
) {
|
|
881
|
+
ptr.*field = MemberBinding::fromWireType2(*jsRuntime, value);
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
template<typename FieldType>
|
|
886
|
+
struct GlobalAccess {
|
|
887
|
+
typedef internal::BindingType<FieldType> MemberBinding;
|
|
888
|
+
typedef typename MemberBinding::WireType WireType;
|
|
889
|
+
typedef typename MemberBinding::WireType2 WireType2;
|
|
890
|
+
|
|
891
|
+
static WireType get(FieldType* context) {
|
|
892
|
+
return MemberBinding::toWireType(*context);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
static void set(FieldType* context, WireType value) {
|
|
896
|
+
*context = MemberBinding::fromWireType(value);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
static WireType2 get2(FieldType* context) {
|
|
900
|
+
return MemberBinding::toWireType2(*jsRuntime, *context);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
static void set2(FieldType* context, WireType2& value) {
|
|
904
|
+
*context = MemberBinding::fromWireType2(*jsRuntime, value);
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
// TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
|
|
909
|
+
template<typename T>
|
|
910
|
+
inline T* getContext(const T& t) {
|
|
911
|
+
// not a leak because this is called once per binding
|
|
912
|
+
auto* ret = new T(t);
|
|
913
|
+
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
|
|
914
|
+
__lsan_ignore_object(ret);
|
|
915
|
+
#endif
|
|
916
|
+
return ret;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
template<typename Accessor, typename ValueType>
|
|
920
|
+
struct PropertyTag {};
|
|
921
|
+
|
|
922
|
+
template<typename T>
|
|
923
|
+
struct GetterPolicy;
|
|
924
|
+
|
|
925
|
+
template<typename GetterReturnType, typename GetterThisType>
|
|
926
|
+
struct GetterPolicy<GetterReturnType (GetterThisType::*)() const> {
|
|
927
|
+
typedef GetterReturnType ReturnType;
|
|
928
|
+
typedef GetterReturnType (GetterThisType::*Context)() const;
|
|
929
|
+
|
|
930
|
+
typedef internal::BindingType<ReturnType> Binding;
|
|
931
|
+
typedef typename Binding::WireType WireType;
|
|
932
|
+
typedef typename Binding::WireType2 WireType2;
|
|
933
|
+
|
|
934
|
+
template<typename ClassType>
|
|
935
|
+
static WireType get(const Context& context, const ClassType& ptr) {
|
|
936
|
+
return Binding::toWireType((ptr.*context)());
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
template<typename ClassType>
|
|
940
|
+
static WireType2 get2(const Context& context, const ClassType& ptr) {
|
|
941
|
+
return Binding::toWireType2(*jsRuntime, (ptr.*context)());
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
static void* getContext(Context context) {
|
|
945
|
+
return internal::getContext(context);
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
|
|
949
|
+
#ifdef __cpp_noexcept_function_type
|
|
950
|
+
template<typename GetterReturnType, typename GetterThisType>
|
|
951
|
+
struct GetterPolicy<GetterReturnType (GetterThisType::*)() const noexcept>
|
|
952
|
+
: GetterPolicy<GetterReturnType (GetterThisType::*)() const> {};
|
|
953
|
+
#endif
|
|
954
|
+
|
|
955
|
+
template<typename GetterReturnType, typename GetterThisType>
|
|
956
|
+
struct GetterPolicy<GetterReturnType (*)(const GetterThisType&)> {
|
|
957
|
+
typedef GetterReturnType ReturnType;
|
|
958
|
+
typedef GetterReturnType (*Context)(const GetterThisType&);
|
|
959
|
+
|
|
960
|
+
typedef internal::BindingType<ReturnType> Binding;
|
|
961
|
+
typedef typename Binding::WireType WireType;
|
|
962
|
+
typedef typename Binding::WireType2 WireType2;
|
|
963
|
+
|
|
964
|
+
template<typename ClassType>
|
|
965
|
+
static WireType get(const Context& context, const ClassType& ptr) {
|
|
966
|
+
return Binding::toWireType(context(ptr));
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
template<typename ClassType>
|
|
970
|
+
static WireType2 get2(const Context& context, const ClassType& ptr) {
|
|
971
|
+
return Binding::toWireType2(*jsRuntime, context(ptr));
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
static void* getContext(Context context) {
|
|
975
|
+
return internal::getContext(context);
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
|
|
979
|
+
template<typename GetterReturnType, typename GetterThisType>
|
|
980
|
+
struct GetterPolicy<std::function<GetterReturnType(const GetterThisType&)>> {
|
|
981
|
+
typedef GetterReturnType ReturnType;
|
|
982
|
+
typedef std::function<GetterReturnType(const GetterThisType&)> Context;
|
|
983
|
+
|
|
984
|
+
typedef internal::BindingType<ReturnType> Binding;
|
|
985
|
+
typedef typename Binding::WireType WireType;
|
|
986
|
+
typedef typename Binding::WireType2 WireType2;
|
|
987
|
+
|
|
988
|
+
template<typename ClassType>
|
|
989
|
+
static WireType get(const Context& context, const ClassType& ptr) {
|
|
990
|
+
return Binding::toWireType(context(ptr));
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
template<typename ClassType>
|
|
994
|
+
static WireType2 get2(const Context& context, const ClassType& ptr) {
|
|
995
|
+
return Binding::toWireType2(*jsRuntime, context(ptr));
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
static void* getContext(const Context& context) {
|
|
999
|
+
return internal::getContext(context);
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
|
|
1003
|
+
template<typename Getter, typename GetterReturnType>
|
|
1004
|
+
struct GetterPolicy<PropertyTag<Getter, GetterReturnType>> {
|
|
1005
|
+
typedef GetterReturnType ReturnType;
|
|
1006
|
+
typedef Getter Context;
|
|
1007
|
+
|
|
1008
|
+
typedef internal::BindingType<ReturnType> Binding;
|
|
1009
|
+
typedef typename Binding::WireType WireType;
|
|
1010
|
+
typedef typename Binding::WireType2 WireType2;
|
|
1011
|
+
|
|
1012
|
+
template<typename ClassType>
|
|
1013
|
+
static WireType get(const Context& context, const ClassType& ptr) {
|
|
1014
|
+
return Binding::toWireType(context(ptr));
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
template<typename ClassType>
|
|
1018
|
+
static WireType2 get2(const Context& context, const ClassType& ptr) {
|
|
1019
|
+
return Binding::toWireType2(*jsRuntime, context(ptr));
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
static void* getContext(const Context& context) {
|
|
1023
|
+
return internal::getContext(context);
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
template<typename T>
|
|
1028
|
+
struct SetterPolicy;
|
|
1029
|
+
|
|
1030
|
+
template<typename SetterReturnType, typename SetterThisType, typename SetterArgumentType>
|
|
1031
|
+
struct SetterPolicy<SetterReturnType (SetterThisType::*)(SetterArgumentType)> {
|
|
1032
|
+
typedef SetterArgumentType ArgumentType;
|
|
1033
|
+
typedef SetterReturnType (SetterThisType::*Context)(SetterArgumentType);
|
|
1034
|
+
|
|
1035
|
+
typedef internal::BindingType<SetterArgumentType> Binding;
|
|
1036
|
+
typedef typename Binding::WireType WireType;
|
|
1037
|
+
typedef typename Binding::WireType2 WireType2;
|
|
1038
|
+
|
|
1039
|
+
template<typename ClassType>
|
|
1040
|
+
static void set(const Context& context, ClassType& ptr, WireType wt) {
|
|
1041
|
+
(ptr.*context)(Binding::fromWireType(wt));
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
template<typename ClassType>
|
|
1045
|
+
static void set2(const Context& context, ClassType& ptr, WireType2& wt) {
|
|
1046
|
+
(ptr.*context)(Binding::fromWireType2(*jsRuntime, wt));
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
static void* getContext(Context context) {
|
|
1050
|
+
return internal::getContext(context);
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
#ifdef __cpp_noexcept_function_type
|
|
1055
|
+
template<typename SetterReturnType, typename SetterThisType, typename SetterArgumentType>
|
|
1056
|
+
struct SetterPolicy<SetterReturnType (SetterThisType::*)(SetterArgumentType) noexcept>
|
|
1057
|
+
: SetterPolicy<SetterReturnType (SetterThisType::*)(SetterArgumentType)> {};
|
|
1058
|
+
#endif
|
|
1059
|
+
|
|
1060
|
+
template<typename SetterReturnType, typename SetterThisType, typename SetterArgumentType>
|
|
1061
|
+
struct SetterPolicy<SetterReturnType (*)(SetterThisType&, SetterArgumentType)> {
|
|
1062
|
+
typedef SetterArgumentType ArgumentType;
|
|
1063
|
+
typedef SetterReturnType (*Context)(SetterThisType&, SetterArgumentType);
|
|
1064
|
+
|
|
1065
|
+
typedef internal::BindingType<SetterArgumentType> Binding;
|
|
1066
|
+
typedef typename Binding::WireType WireType;
|
|
1067
|
+
typedef typename Binding::WireType2 WireType2;
|
|
1068
|
+
|
|
1069
|
+
template<typename ClassType>
|
|
1070
|
+
static void set(const Context& context, ClassType& ptr, WireType wt) {
|
|
1071
|
+
context(ptr, Binding::fromWireType(wt));
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
template<typename ClassType>
|
|
1075
|
+
static void set2(const Context& context, ClassType& ptr, WireType2& wt) {
|
|
1076
|
+
context(ptr, Binding::fromWireType2(*jsRuntime, wt));
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
static void* getContext(Context context) {
|
|
1080
|
+
return internal::getContext(context);
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
template<typename SetterReturnType, typename SetterThisType, typename SetterArgumentType>
|
|
1085
|
+
struct SetterPolicy<std::function<SetterReturnType(SetterThisType&, SetterArgumentType)>> {
|
|
1086
|
+
typedef SetterArgumentType ArgumentType;
|
|
1087
|
+
typedef std::function<SetterReturnType(SetterThisType&, SetterArgumentType)> Context;
|
|
1088
|
+
|
|
1089
|
+
typedef internal::BindingType<SetterArgumentType> Binding;
|
|
1090
|
+
typedef typename Binding::WireType WireType;
|
|
1091
|
+
typedef typename Binding::WireType2 WireType2;
|
|
1092
|
+
|
|
1093
|
+
template<typename ClassType>
|
|
1094
|
+
static void set(const Context& context, ClassType& ptr, WireType wt) {
|
|
1095
|
+
context(ptr, Binding::fromWireType(wt));
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
template<typename ClassType>
|
|
1099
|
+
static void set2(const Context& context, ClassType& ptr, WireType2& wt) {
|
|
1100
|
+
context(ptr, Binding::fromWireType2(*jsRuntime, wt));
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
static void* getContext(const Context& context) {
|
|
1104
|
+
return internal::getContext(context);
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
template<typename Setter, typename SetterArgumentType>
|
|
1109
|
+
struct SetterPolicy<PropertyTag<Setter, SetterArgumentType>> {
|
|
1110
|
+
typedef SetterArgumentType ArgumentType;
|
|
1111
|
+
typedef Setter Context;
|
|
1112
|
+
|
|
1113
|
+
typedef internal::BindingType<SetterArgumentType> Binding;
|
|
1114
|
+
typedef typename Binding::WireType WireType;
|
|
1115
|
+
typedef typename Binding::WireType2 WireType2;
|
|
1116
|
+
|
|
1117
|
+
template<typename ClassType>
|
|
1118
|
+
static void set(const Context& context, ClassType& ptr, WireType wt) {
|
|
1119
|
+
context(ptr, Binding::fromWireType(wt));
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
template<typename ClassType>
|
|
1123
|
+
static void set2(const Context& context, ClassType& ptr, WireType2& wt) {
|
|
1124
|
+
context(ptr, Binding::fromWireType2(*jsRuntime, wt));
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
static void* getContext(const Context& context) {
|
|
1128
|
+
return internal::getContext(context);
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
class noncopyable {
|
|
1133
|
+
protected:
|
|
1134
|
+
noncopyable() {}
|
|
1135
|
+
~noncopyable() {}
|
|
1136
|
+
private:
|
|
1137
|
+
noncopyable(const noncopyable&) = delete;
|
|
1138
|
+
const noncopyable& operator=(const noncopyable&) = delete;
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
template<typename ClassType, typename ElementType>
|
|
1142
|
+
typename BindingType<ElementType>::WireType2 get_by_index(int index, ClassType& ptr) {
|
|
1143
|
+
return BindingType<ElementType>::toWireType2(*jsRuntime, ptr[index]);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
template<typename ClassType, typename ElementType>
|
|
1147
|
+
void set_by_index(int index, ClassType& ptr, typename BindingType<ElementType>::WireType2& wt) {
|
|
1148
|
+
ptr[index] = BindingType<ElementType>::fromWireType2(*jsRuntime, wt);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
} // end namespace internal
|
|
1152
|
+
|
|
1153
|
+
template<int Index>
|
|
1154
|
+
struct index {
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1158
|
+
// VALUE TUPLES
|
|
1159
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1160
|
+
|
|
1161
|
+
template<typename ClassType>
|
|
1162
|
+
class value_array : public internal::noncopyable {
|
|
1163
|
+
public:
|
|
1164
|
+
typedef ClassType class_type;
|
|
1165
|
+
|
|
1166
|
+
value_array(const char* name) {
|
|
1167
|
+
using namespace internal;
|
|
1168
|
+
|
|
1169
|
+
auto constructor = &raw_constructor<ClassType>;
|
|
1170
|
+
auto destructor = &raw_destructor<ClassType>;
|
|
1171
|
+
|
|
1172
|
+
facebook::jsi::Function constructorJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1173
|
+
*jsRuntime,
|
|
1174
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_constructor"),
|
|
1175
|
+
0,
|
|
1176
|
+
[constructor](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1177
|
+
ClassType* t = constructor();
|
|
1178
|
+
return facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(t));
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
facebook::jsi::Function destructorJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1182
|
+
*jsRuntime,
|
|
1183
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_constructor"),
|
|
1184
|
+
1,
|
|
1185
|
+
[destructor](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1186
|
+
ClassType* t = reinterpret_cast<ClassType*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1187
|
+
destructor(t);
|
|
1188
|
+
return facebook::jsi::Value::undefined();
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1191
|
+
_embind_register_value_array(
|
|
1192
|
+
TypeID<ClassType>::get(),
|
|
1193
|
+
name,
|
|
1194
|
+
getSignature(constructor),
|
|
1195
|
+
constructorJSIFunc,
|
|
1196
|
+
getSignature(destructor),
|
|
1197
|
+
destructorJSIFunc);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
~value_array() {
|
|
1201
|
+
using namespace internal;
|
|
1202
|
+
_embind_finalize_value_array(TypeID<ClassType>::get());
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
template<typename InstanceType, typename ElementType>
|
|
1206
|
+
value_array& element(ElementType InstanceType::*field) {
|
|
1207
|
+
using namespace internal;
|
|
1208
|
+
|
|
1209
|
+
auto getter = &MemberAccess<InstanceType, ElementType>
|
|
1210
|
+
::template getWire2<ClassType>;
|
|
1211
|
+
auto setter = &MemberAccess<InstanceType, ElementType>
|
|
1212
|
+
::template setWire2<ClassType>;
|
|
1213
|
+
|
|
1214
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1215
|
+
*jsRuntime,
|
|
1216
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_array_element_gter1"),
|
|
1217
|
+
2,
|
|
1218
|
+
[getter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1219
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1220
|
+
return getter(field, *t2);
|
|
1221
|
+
});
|
|
1222
|
+
|
|
1223
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1224
|
+
*jsRuntime,
|
|
1225
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_array_element_ster1"),
|
|
1226
|
+
3,
|
|
1227
|
+
[setter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1228
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1229
|
+
setter(field, *t2, args[2]);
|
|
1230
|
+
return facebook::jsi::Value::undefined();
|
|
1231
|
+
});
|
|
1232
|
+
|
|
1233
|
+
_embind_register_value_array_element(
|
|
1234
|
+
TypeID<ClassType>::get(),
|
|
1235
|
+
TypeID<ElementType>::get(),
|
|
1236
|
+
getSignature(getter),
|
|
1237
|
+
getterJSIFunc,
|
|
1238
|
+
getContext(field),
|
|
1239
|
+
TypeID<ElementType>::get(),
|
|
1240
|
+
getSignature(setter),
|
|
1241
|
+
setterJSIFunc,
|
|
1242
|
+
getContext(field));
|
|
1243
|
+
return *this;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
template<typename Getter, typename Setter>
|
|
1247
|
+
value_array& element(Getter getter, Setter setter) {
|
|
1248
|
+
using namespace internal;
|
|
1249
|
+
typedef GetterPolicy<Getter> GP;
|
|
1250
|
+
typedef SetterPolicy<Setter> SP;
|
|
1251
|
+
|
|
1252
|
+
auto g = &GP::template get2<ClassType>;
|
|
1253
|
+
auto s = &SP::template set2<ClassType>;
|
|
1254
|
+
|
|
1255
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1256
|
+
*jsRuntime,
|
|
1257
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_array_element_gter2"),
|
|
1258
|
+
2,
|
|
1259
|
+
[g, getter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1260
|
+
Getter* t = reinterpret_cast<Getter*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1261
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1262
|
+
return g(getter, *t2);
|
|
1263
|
+
});
|
|
1264
|
+
|
|
1265
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1266
|
+
*jsRuntime,
|
|
1267
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_array_element_ster2"),
|
|
1268
|
+
3,
|
|
1269
|
+
[s](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1270
|
+
Setter* t = reinterpret_cast<Setter*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1271
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1272
|
+
s(*t, *t2, args[2]);
|
|
1273
|
+
return facebook::jsi::Value::undefined();
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
_embind_register_value_array_element(
|
|
1277
|
+
TypeID<ClassType>::get(),
|
|
1278
|
+
TypeID<typename GP::ReturnType>::get(),
|
|
1279
|
+
getSignature(g),
|
|
1280
|
+
getterJSIFunc,
|
|
1281
|
+
GP::getContext(getter),
|
|
1282
|
+
TypeID<typename SP::ArgumentType>::get(),
|
|
1283
|
+
getSignature(s),
|
|
1284
|
+
setterJSIFunc,
|
|
1285
|
+
SP::getContext(setter));
|
|
1286
|
+
return *this;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
template<int Index>
|
|
1290
|
+
value_array& element(index<Index>) {
|
|
1291
|
+
using namespace internal;
|
|
1292
|
+
ClassType* null = 0;
|
|
1293
|
+
typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
|
|
1294
|
+
auto getter = &internal::get_by_index<ClassType, ElementType>;
|
|
1295
|
+
auto setter = &internal::set_by_index<ClassType, ElementType>;
|
|
1296
|
+
|
|
1297
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1298
|
+
*jsRuntime,
|
|
1299
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_array_element_gter3"),
|
|
1300
|
+
2,
|
|
1301
|
+
[getter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1302
|
+
int t1 = static_cast<int>(args[0].asBigInt(rt).asUint64(rt));
|
|
1303
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1304
|
+
return getter(t1, *t2);
|
|
1305
|
+
});
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1309
|
+
*jsRuntime,
|
|
1310
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_array_element_ster3"),
|
|
1311
|
+
3,
|
|
1312
|
+
[setter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1313
|
+
int t1 = static_cast<int>(args[0].asBigInt(rt).asUint64(rt));
|
|
1314
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1315
|
+
setter(t1, *t2, args[2]);
|
|
1316
|
+
return facebook::jsi::Value::undefined();
|
|
1317
|
+
});
|
|
1318
|
+
|
|
1319
|
+
_embind_register_value_array_element(
|
|
1320
|
+
TypeID<ClassType>::get(),
|
|
1321
|
+
TypeID<ElementType>::get(),
|
|
1322
|
+
getSignature(getter),
|
|
1323
|
+
getterJSIFunc,
|
|
1324
|
+
reinterpret_cast<void*>(Index),
|
|
1325
|
+
TypeID<ElementType>::get(),
|
|
1326
|
+
getSignature(setter),
|
|
1327
|
+
setterJSIFunc,
|
|
1328
|
+
reinterpret_cast<void*>(Index));
|
|
1329
|
+
return *this;
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
|
|
1333
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1334
|
+
// VALUE STRUCTS
|
|
1335
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1336
|
+
|
|
1337
|
+
template<typename ClassType>
|
|
1338
|
+
class value_object : public internal::noncopyable {
|
|
1339
|
+
public:
|
|
1340
|
+
typedef ClassType class_type;
|
|
1341
|
+
|
|
1342
|
+
value_object(const char* name) {
|
|
1343
|
+
using namespace internal;
|
|
1344
|
+
|
|
1345
|
+
auto ctor = &raw_constructor<ClassType>;
|
|
1346
|
+
auto dtor = &raw_destructor<ClassType>;
|
|
1347
|
+
|
|
1348
|
+
facebook::jsi::Function constructorJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1349
|
+
*jsRuntime,
|
|
1350
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_constructor"),
|
|
1351
|
+
0,
|
|
1352
|
+
[ctor](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1353
|
+
ClassType* t = ctor();
|
|
1354
|
+
return facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(t));
|
|
1355
|
+
});
|
|
1356
|
+
|
|
1357
|
+
facebook::jsi::Function destructorJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1358
|
+
*jsRuntime,
|
|
1359
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_constructor"),
|
|
1360
|
+
1,
|
|
1361
|
+
[dtor](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1362
|
+
ClassType* t = reinterpret_cast<ClassType*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1363
|
+
dtor(t);
|
|
1364
|
+
return facebook::jsi::Value::undefined();
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
_embind_register_value_object(
|
|
1368
|
+
TypeID<ClassType>::get(),
|
|
1369
|
+
name,
|
|
1370
|
+
getSignature(ctor),
|
|
1371
|
+
constructorJSIFunc,
|
|
1372
|
+
getSignature(dtor),
|
|
1373
|
+
destructorJSIFunc);
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
~value_object() {
|
|
1377
|
+
using namespace internal;
|
|
1378
|
+
_embind_finalize_value_object(internal::TypeID<ClassType>::get());
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
template<typename InstanceType, typename FieldType>
|
|
1382
|
+
value_object& field(const char* fieldName, FieldType InstanceType::*field) {
|
|
1383
|
+
using namespace internal;
|
|
1384
|
+
|
|
1385
|
+
auto getter = &MemberAccess<InstanceType, FieldType>
|
|
1386
|
+
::template getWire2<ClassType>;
|
|
1387
|
+
auto setter = &MemberAccess<InstanceType, FieldType>
|
|
1388
|
+
::template setWire2<ClassType>;
|
|
1389
|
+
|
|
1390
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1391
|
+
*jsRuntime,
|
|
1392
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_gter1"),
|
|
1393
|
+
2,
|
|
1394
|
+
[getter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1395
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1396
|
+
return getter(field, *t2);
|
|
1397
|
+
});
|
|
1398
|
+
|
|
1399
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1400
|
+
*jsRuntime,
|
|
1401
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_ster1"),
|
|
1402
|
+
3,
|
|
1403
|
+
[setter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1404
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1405
|
+
setter(field, *t2, args[2]);
|
|
1406
|
+
return facebook::jsi::Value::undefined();
|
|
1407
|
+
});
|
|
1408
|
+
|
|
1409
|
+
_embind_register_value_object_field(
|
|
1410
|
+
TypeID<ClassType>::get(),
|
|
1411
|
+
fieldName,
|
|
1412
|
+
TypeID<FieldType>::get(),
|
|
1413
|
+
getSignature(getter),
|
|
1414
|
+
getterJSIFunc,
|
|
1415
|
+
getContext(field),
|
|
1416
|
+
TypeID<FieldType>::get(),
|
|
1417
|
+
getSignature(setter),
|
|
1418
|
+
setterJSIFunc,
|
|
1419
|
+
getContext(field));
|
|
1420
|
+
return *this;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
template<typename InstanceType, typename ElementType, int N>
|
|
1424
|
+
value_object& field(const char* fieldName, ElementType (InstanceType::*field)[N]) {
|
|
1425
|
+
using namespace internal;
|
|
1426
|
+
|
|
1427
|
+
typedef std::array<ElementType, N> FieldType;
|
|
1428
|
+
static_assert(sizeof(FieldType) == sizeof(ElementType[N]));
|
|
1429
|
+
|
|
1430
|
+
auto getter = &MemberAccess<InstanceType, FieldType>
|
|
1431
|
+
::template getWire2<ClassType>;
|
|
1432
|
+
auto setter = &MemberAccess<InstanceType, FieldType>
|
|
1433
|
+
::template setWire2<ClassType>;
|
|
1434
|
+
|
|
1435
|
+
typedef FieldType InstanceType::*MemberPointer;
|
|
1436
|
+
|
|
1437
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1438
|
+
*jsRuntime,
|
|
1439
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_gter1"),
|
|
1440
|
+
2,
|
|
1441
|
+
[getter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1442
|
+
const MemberPointer* t1 = reinterpret_cast<MemberPointer*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1443
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1444
|
+
return getter(*t1, *t2);
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1448
|
+
*jsRuntime,
|
|
1449
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_ster1"),
|
|
1450
|
+
3,
|
|
1451
|
+
[setter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1452
|
+
const MemberPointer* t1 = reinterpret_cast<MemberPointer*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1453
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1454
|
+
setter(*t1, *t2, args[2]);
|
|
1455
|
+
return facebook::jsi::Value::undefined();
|
|
1456
|
+
});
|
|
1457
|
+
|
|
1458
|
+
_embind_register_value_object_field(
|
|
1459
|
+
TypeID<ClassType>::get(),
|
|
1460
|
+
fieldName,
|
|
1461
|
+
TypeID<FieldType>::get(),
|
|
1462
|
+
getSignature(getter),
|
|
1463
|
+
getterJSIFunc,
|
|
1464
|
+
getContext(field),
|
|
1465
|
+
TypeID<FieldType>::get(),
|
|
1466
|
+
getSignature(setter),
|
|
1467
|
+
setterJSIFunc,
|
|
1468
|
+
getContext(field));
|
|
1469
|
+
return *this;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
template<typename Getter, typename Setter>
|
|
1473
|
+
value_object& field(
|
|
1474
|
+
const char* fieldName,
|
|
1475
|
+
Getter getter,
|
|
1476
|
+
Setter setter
|
|
1477
|
+
) {
|
|
1478
|
+
using namespace internal;
|
|
1479
|
+
typedef GetterPolicy<Getter> GP;
|
|
1480
|
+
typedef SetterPolicy<Setter> SP;
|
|
1481
|
+
|
|
1482
|
+
auto g = &GP::template get2<ClassType>;
|
|
1483
|
+
auto s = &SP::template set2<ClassType>;
|
|
1484
|
+
|
|
1485
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1486
|
+
*jsRuntime,
|
|
1487
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_gter2"),
|
|
1488
|
+
2,
|
|
1489
|
+
[g, getter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1490
|
+
Getter* t = reinterpret_cast<Getter*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1491
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1492
|
+
return g(getter, *t2);
|
|
1493
|
+
});
|
|
1494
|
+
|
|
1495
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1496
|
+
*jsRuntime,
|
|
1497
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_ster2"),
|
|
1498
|
+
3,
|
|
1499
|
+
[s](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1500
|
+
Setter* t = reinterpret_cast<Setter*>(args[0].asBigInt(rt).asUint64(rt));
|
|
1501
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1502
|
+
s(*t, *t2, args[2]);
|
|
1503
|
+
return facebook::jsi::Value::undefined();
|
|
1504
|
+
});
|
|
1505
|
+
|
|
1506
|
+
_embind_register_value_object_field(
|
|
1507
|
+
TypeID<ClassType>::get(),
|
|
1508
|
+
fieldName,
|
|
1509
|
+
TypeID<typename GP::ReturnType>::get(),
|
|
1510
|
+
getSignature(g),
|
|
1511
|
+
getterJSIFunc,
|
|
1512
|
+
GP::getContext(getter),
|
|
1513
|
+
TypeID<typename SP::ArgumentType>::get(),
|
|
1514
|
+
getSignature(s),
|
|
1515
|
+
setterJSIFunc,
|
|
1516
|
+
SP::getContext(setter));
|
|
1517
|
+
return *this;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
template<int Index>
|
|
1521
|
+
value_object& field(const char* fieldName, index<Index>) {
|
|
1522
|
+
using namespace internal;
|
|
1523
|
+
ClassType* null = 0;
|
|
1524
|
+
typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
|
|
1525
|
+
|
|
1526
|
+
auto getter = &internal::get_by_index<ClassType, ElementType>;
|
|
1527
|
+
auto setter = &internal::set_by_index<ClassType, ElementType>;
|
|
1528
|
+
|
|
1529
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1530
|
+
*jsRuntime,
|
|
1531
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_gter3"),
|
|
1532
|
+
2,
|
|
1533
|
+
[getter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1534
|
+
int t1 = static_cast<int>(args[0].asBigInt(rt).asUint64(rt));
|
|
1535
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1536
|
+
return getter(t1, *t2);
|
|
1537
|
+
});
|
|
1538
|
+
|
|
1539
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1540
|
+
*jsRuntime,
|
|
1541
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, "value_object_element_ster3"),
|
|
1542
|
+
3,
|
|
1543
|
+
[setter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1544
|
+
int t1 = static_cast<int>(args[0].asBigInt(rt).asUint64(rt));
|
|
1545
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
1546
|
+
setter(t1, *t2, args[2]);
|
|
1547
|
+
return facebook::jsi::Value::undefined();
|
|
1548
|
+
});
|
|
1549
|
+
|
|
1550
|
+
_embind_register_value_object_field(
|
|
1551
|
+
TypeID<ClassType>::get(),
|
|
1552
|
+
fieldName,
|
|
1553
|
+
TypeID<ElementType>::get(),
|
|
1554
|
+
getSignature(getter),
|
|
1555
|
+
getterJSIFunc,
|
|
1556
|
+
reinterpret_cast<void*>(Index),
|
|
1557
|
+
TypeID<ElementType>::get(),
|
|
1558
|
+
getSignature(setter),
|
|
1559
|
+
setterJSIFunc,
|
|
1560
|
+
reinterpret_cast<void*>(Index));
|
|
1561
|
+
return *this;
|
|
1562
|
+
}
|
|
1563
|
+
};
|
|
1564
|
+
|
|
1565
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1566
|
+
// SMART POINTERS
|
|
1567
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1568
|
+
|
|
1569
|
+
template<typename PointerType>
|
|
1570
|
+
struct default_smart_ptr_trait {
|
|
1571
|
+
static sharing_policy get_sharing_policy() {
|
|
1572
|
+
return sharing_policy::NONE;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
static void* share(void* v) {
|
|
1576
|
+
return 0; // no sharing
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
static PointerType* construct_null() {
|
|
1580
|
+
return new PointerType;
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
|
|
1584
|
+
// specialize if you have a different pointer type
|
|
1585
|
+
template<typename PointerType>
|
|
1586
|
+
struct smart_ptr_trait : public default_smart_ptr_trait<PointerType> {
|
|
1587
|
+
typedef typename PointerType::element_type element_type;
|
|
1588
|
+
|
|
1589
|
+
static element_type* get(const PointerType& ptr) {
|
|
1590
|
+
return ptr.get();
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1593
|
+
|
|
1594
|
+
template<typename PointeeType>
|
|
1595
|
+
struct smart_ptr_trait<std::shared_ptr<PointeeType>> {
|
|
1596
|
+
typedef std::shared_ptr<PointeeType> PointerType;
|
|
1597
|
+
typedef typename PointerType::element_type element_type;
|
|
1598
|
+
|
|
1599
|
+
static element_type* get(const PointerType& ptr) {
|
|
1600
|
+
return ptr.get();
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
static sharing_policy get_sharing_policy() {
|
|
1604
|
+
return sharing_policy::BY_EMVAL;
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
static std::shared_ptr<PointeeType>* share(PointeeType* p, EM_VAL v) {
|
|
1608
|
+
return new std::shared_ptr<PointeeType>(
|
|
1609
|
+
p,
|
|
1610
|
+
val_deleter(val::take_ownership(v)));
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
static PointerType* construct_null() {
|
|
1614
|
+
return new PointerType;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
private:
|
|
1618
|
+
class val_deleter {
|
|
1619
|
+
public:
|
|
1620
|
+
val_deleter() = delete;
|
|
1621
|
+
explicit val_deleter(val v)
|
|
1622
|
+
: v(v)
|
|
1623
|
+
{}
|
|
1624
|
+
void operator()(void const*) {
|
|
1625
|
+
v();
|
|
1626
|
+
// eventually we'll need to support emptied out val
|
|
1627
|
+
v = val::undefined();
|
|
1628
|
+
}
|
|
1629
|
+
private:
|
|
1630
|
+
val v;
|
|
1631
|
+
};
|
|
1632
|
+
};
|
|
1633
|
+
|
|
1634
|
+
|
|
1635
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1636
|
+
// CLASSES
|
|
1637
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
1638
|
+
|
|
1639
|
+
namespace internal {
|
|
1640
|
+
|
|
1641
|
+
class WrapperBase {
|
|
1642
|
+
public:
|
|
1643
|
+
void setNotifyJSOnDestruction(bool notify) {
|
|
1644
|
+
notifyJSOnDestruction = notify;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
protected:
|
|
1648
|
+
bool notifyJSOnDestruction = false;
|
|
1649
|
+
};
|
|
1650
|
+
|
|
1651
|
+
} // end namespace internal
|
|
1652
|
+
|
|
1653
|
+
// abstract classes
|
|
1654
|
+
template<typename T>
|
|
1655
|
+
class wrapper : public T, public internal::WrapperBase {
|
|
1656
|
+
public:
|
|
1657
|
+
typedef T class_type;
|
|
1658
|
+
|
|
1659
|
+
template<typename... Args>
|
|
1660
|
+
explicit wrapper(val&& wrapped, Args&&... args)
|
|
1661
|
+
: T(std::forward<Args>(args)...)
|
|
1662
|
+
, wrapped(std::forward<val>(wrapped))
|
|
1663
|
+
{}
|
|
1664
|
+
|
|
1665
|
+
~wrapper() {
|
|
1666
|
+
if (notifyJSOnDestruction) {
|
|
1667
|
+
call<void>("__destruct");
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
template<typename ReturnType, typename... Args>
|
|
1672
|
+
ReturnType call(const char* name, Args&&... args) const {
|
|
1673
|
+
return wrapped.call<ReturnType>(name, std::forward<Args>(args)...);
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
private:
|
|
1677
|
+
val wrapped;
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1680
|
+
#define EMSCRIPTEN_WRAPPER(T) \
|
|
1681
|
+
template<typename... Args> \
|
|
1682
|
+
T(::emscripten::val&& v, Args&&... args) \
|
|
1683
|
+
: wrapper(std::forward<::emscripten::val>(v), std::forward<Args>(args)...) \
|
|
1684
|
+
{}
|
|
1685
|
+
|
|
1686
|
+
namespace internal {
|
|
1687
|
+
|
|
1688
|
+
struct NoBaseClass {
|
|
1689
|
+
template<typename ClassType>
|
|
1690
|
+
static void verify() {
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
static TYPEID get() {
|
|
1694
|
+
return nullptr;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
template<typename ClassType>
|
|
1698
|
+
static VoidFunctionPtr getUpcaster() {
|
|
1699
|
+
return nullptr;
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
template<typename ClassType>
|
|
1703
|
+
static VoidFunctionPtr getDowncaster() {
|
|
1704
|
+
return nullptr;
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
|
|
1708
|
+
// NOTE: this returns the class type, not the pointer type
|
|
1709
|
+
template<typename T>
|
|
1710
|
+
inline TYPEID getActualType(T* ptr) {
|
|
1711
|
+
return getLightTypeID(*ptr);
|
|
1712
|
+
};
|
|
1713
|
+
|
|
1714
|
+
} // end namespace internal
|
|
1715
|
+
|
|
1716
|
+
template<typename BaseClass>
|
|
1717
|
+
struct base {
|
|
1718
|
+
typedef BaseClass class_type;
|
|
1719
|
+
|
|
1720
|
+
template<typename ClassType>
|
|
1721
|
+
static void verify() {
|
|
1722
|
+
static_assert(!std::is_same<ClassType, BaseClass>::value, "Base must not have same type as class");
|
|
1723
|
+
static_assert(std::is_base_of<BaseClass, ClassType>::value, "Derived class must derive from base");
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
static internal::TYPEID get() {
|
|
1727
|
+
return internal::TypeID<BaseClass>::get();
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
template<typename ClassType>
|
|
1731
|
+
using Upcaster = BaseClass* (*)(ClassType*);
|
|
1732
|
+
|
|
1733
|
+
template<typename ClassType>
|
|
1734
|
+
using Downcaster = ClassType* (*)(BaseClass*);
|
|
1735
|
+
|
|
1736
|
+
template<typename ClassType>
|
|
1737
|
+
static Upcaster<ClassType> getUpcaster() {
|
|
1738
|
+
return &convertPointer<ClassType, BaseClass>;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
template<typename ClassType>
|
|
1742
|
+
static Downcaster<ClassType> getDowncaster() {
|
|
1743
|
+
return &convertPointer<BaseClass, ClassType>;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
template<typename From, typename To>
|
|
1747
|
+
static To* convertPointer(From* ptr) {
|
|
1748
|
+
return static_cast<To*>(ptr);
|
|
1749
|
+
}
|
|
1750
|
+
};
|
|
1751
|
+
|
|
1752
|
+
namespace internal {
|
|
1753
|
+
|
|
1754
|
+
template<typename WrapperType>
|
|
1755
|
+
val wrapped_extend(const std::string& name, const val& properties) {
|
|
1756
|
+
return val::take_ownership(_embind_create_inheriting_constructor(
|
|
1757
|
+
name.c_str(),
|
|
1758
|
+
TypeID<WrapperType>::get(),
|
|
1759
|
+
properties.as_handle()));
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
} // end namespace internal
|
|
1763
|
+
|
|
1764
|
+
struct pure_virtual {
|
|
1765
|
+
template<typename InputType, int Index>
|
|
1766
|
+
struct Transform {
|
|
1767
|
+
typedef InputType type;
|
|
1768
|
+
};
|
|
1769
|
+
};
|
|
1770
|
+
|
|
1771
|
+
namespace internal {
|
|
1772
|
+
|
|
1773
|
+
template<typename... Policies>
|
|
1774
|
+
struct isPureVirtual;
|
|
1775
|
+
|
|
1776
|
+
template<typename... Rest>
|
|
1777
|
+
struct isPureVirtual<pure_virtual, Rest...> {
|
|
1778
|
+
static constexpr bool value = true;
|
|
1779
|
+
};
|
|
1780
|
+
|
|
1781
|
+
template<typename T, typename... Rest>
|
|
1782
|
+
struct isPureVirtual<T, Rest...> {
|
|
1783
|
+
static constexpr bool value = isPureVirtual<Rest...>::value;
|
|
1784
|
+
};
|
|
1785
|
+
|
|
1786
|
+
template<>
|
|
1787
|
+
struct isPureVirtual<> {
|
|
1788
|
+
static constexpr bool value = false;
|
|
1789
|
+
};
|
|
1790
|
+
|
|
1791
|
+
struct DeduceArgumentsTag {};
|
|
1792
|
+
|
|
1793
|
+
////////////////////////////////////////////////////////////////////////////
|
|
1794
|
+
// RegisterClassConstructor
|
|
1795
|
+
////////////////////////////////////////////////////////////////////////////
|
|
1796
|
+
|
|
1797
|
+
template <typename T>
|
|
1798
|
+
struct RegisterClassConstructor;
|
|
1799
|
+
|
|
1800
|
+
template<typename ReturnType, typename... Args>
|
|
1801
|
+
struct RegisterClassConstructor<ReturnType (*)(Args...)> {
|
|
1802
|
+
|
|
1803
|
+
template <typename ClassType, typename... Policies>
|
|
1804
|
+
static void invoke(ReturnType (*factory)(Args...)) {
|
|
1805
|
+
typename WithPolicies<allow_raw_pointers, Policies...>::template ArgTypeList<ReturnType, Args...> args;
|
|
1806
|
+
auto invoke = &Invoker<ReturnType, Args...>::invoke2;
|
|
1807
|
+
|
|
1808
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1809
|
+
*jsRuntime,
|
|
1810
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string("RegisterClassConstructor_invoke_")+getSignature(invoke)),
|
|
1811
|
+
args.getCount() - 1,
|
|
1812
|
+
[invoke, factory](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1813
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
1814
|
+
callInvokeVoid(sizeof...(Args), invoke, factory);
|
|
1815
|
+
return nullptr;
|
|
1816
|
+
} else {
|
|
1817
|
+
callInvoke(sizeof...(Args), invoke, factory);
|
|
1818
|
+
}
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1821
|
+
_embind_register_class_constructor(
|
|
1822
|
+
TypeID<ClassType>::get(),
|
|
1823
|
+
args.getCount(),
|
|
1824
|
+
args.getTypes(),
|
|
1825
|
+
getSignature(invoke),
|
|
1826
|
+
invokeJSIFunc,
|
|
1827
|
+
reinterpret_cast<GenericFunction>(factory));
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
|
|
1831
|
+
template<typename ReturnType, typename... Args>
|
|
1832
|
+
struct RegisterClassConstructor<std::function<ReturnType (Args...)>> {
|
|
1833
|
+
|
|
1834
|
+
template <typename ClassType, typename... Policies>
|
|
1835
|
+
static void invoke(std::function<ReturnType (Args...)> factory) {
|
|
1836
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
|
|
1837
|
+
auto invoke = &FunctorInvoker<decltype(factory), ReturnType, Args...>::invoke2;
|
|
1838
|
+
|
|
1839
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1840
|
+
*jsRuntime,
|
|
1841
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string("RegisterClassConstructor_invoke_")+getSignature(invoke)),
|
|
1842
|
+
args.getCount() - 1,
|
|
1843
|
+
[invoke, factory](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1844
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
1845
|
+
callInvokeVoid(sizeof...(Args), invoke, factory);
|
|
1846
|
+
return nullptr;
|
|
1847
|
+
} else {
|
|
1848
|
+
callInvoke(sizeof...(Args), invoke, factory);
|
|
1849
|
+
}
|
|
1850
|
+
});
|
|
1851
|
+
|
|
1852
|
+
_embind_register_class_constructor(
|
|
1853
|
+
TypeID<ClassType>::get(),
|
|
1854
|
+
args.getCount(),
|
|
1855
|
+
args.getTypes(),
|
|
1856
|
+
getSignature(invoke),
|
|
1857
|
+
invokeJSIFunc,
|
|
1858
|
+
reinterpret_cast<GenericFunction>(getContext(factory)));
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
|
|
1862
|
+
template<typename ReturnType, typename... Args>
|
|
1863
|
+
struct RegisterClassConstructor<ReturnType (Args...)> {
|
|
1864
|
+
|
|
1865
|
+
template <typename ClassType, typename Callable, typename... Policies>
|
|
1866
|
+
static void invoke(Callable& factory) {
|
|
1867
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
|
|
1868
|
+
auto invoke = &FunctorInvoker<decltype(factory), ReturnType, Args...>::invoke2;
|
|
1869
|
+
|
|
1870
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1871
|
+
*jsRuntime,
|
|
1872
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string("RegisterClassConstructor_invoke_")+getSignature(invoke)),
|
|
1873
|
+
args.getCount() - 1,
|
|
1874
|
+
[invoke, factory](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1875
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
1876
|
+
callInvokeVoid(sizeof...(Args), invoke, getContext(factory));
|
|
1877
|
+
return nullptr;
|
|
1878
|
+
} else {
|
|
1879
|
+
callInvoke(sizeof...(Args), invoke, getContext(factory));
|
|
1880
|
+
}
|
|
1881
|
+
});
|
|
1882
|
+
|
|
1883
|
+
_embind_register_class_constructor(
|
|
1884
|
+
TypeID<ClassType>::get(),
|
|
1885
|
+
args.getCount(),
|
|
1886
|
+
args.getTypes(),
|
|
1887
|
+
getSignature(invoke),
|
|
1888
|
+
invokeJSIFunc,
|
|
1889
|
+
reinterpret_cast<GenericFunction>(getContext(factory)));
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
|
|
1893
|
+
////////////////////////////////////////////////////////////////////////////
|
|
1894
|
+
// RegisterClassMethod
|
|
1895
|
+
////////////////////////////////////////////////////////////////////////////
|
|
1896
|
+
|
|
1897
|
+
template <typename T>
|
|
1898
|
+
struct RegisterClassMethod;
|
|
1899
|
+
|
|
1900
|
+
template<typename ClassType, typename ReturnType, typename... Args>
|
|
1901
|
+
struct RegisterClassMethod<ReturnType (ClassType::*)(Args...)> {
|
|
1902
|
+
|
|
1903
|
+
template <typename CT, typename... Policies>
|
|
1904
|
+
static void invoke(facebook::jsi::Runtime* rt, const char* methodName,
|
|
1905
|
+
ReturnType (ClassType::*memberFunction)(Args...)) {
|
|
1906
|
+
using OriginalInvoker = MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>;
|
|
1907
|
+
auto invoke = &maybe_wrap_async<OriginalInvoker, Policies...>::invoke2;
|
|
1908
|
+
|
|
1909
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args;
|
|
1910
|
+
auto a = getContext(memberFunction);
|
|
1911
|
+
|
|
1912
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1913
|
+
*rt,
|
|
1914
|
+
facebook::jsi::PropNameID::forAscii(*rt, std::string(methodName)+"_"+getSignature(invoke)),
|
|
1915
|
+
args.getCount() + 1,
|
|
1916
|
+
[invoke, a, memberFunction](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1917
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
1918
|
+
callInvokeVoid(sizeof...(Args) + 1, invoke, memberFunction);
|
|
1919
|
+
return nullptr;
|
|
1920
|
+
} else {
|
|
1921
|
+
callInvoke(sizeof...(Args) + 1, invoke, memberFunction);
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
|
|
1925
|
+
_embind_register_class_function(
|
|
1926
|
+
TypeID<ClassType>::get(),
|
|
1927
|
+
methodName,
|
|
1928
|
+
args.getCount(),
|
|
1929
|
+
args.getTypes(),
|
|
1930
|
+
getSignature(invoke),
|
|
1931
|
+
invokeJSIFunc,
|
|
1932
|
+
getContext(memberFunction),
|
|
1933
|
+
isPureVirtual<Policies...>::value,
|
|
1934
|
+
isAsync<Policies...>::value);
|
|
1935
|
+
}
|
|
1936
|
+
};
|
|
1937
|
+
|
|
1938
|
+
#ifdef __cpp_noexcept_function_type
|
|
1939
|
+
template<typename ClassType, typename ReturnType, typename... Args>
|
|
1940
|
+
struct RegisterClassMethod<ReturnType (ClassType::*)(Args...) noexcept>
|
|
1941
|
+
: RegisterClassMethod<ReturnType (ClassType::*)(Args...)> {};
|
|
1942
|
+
#endif
|
|
1943
|
+
|
|
1944
|
+
template<typename ClassType, typename ReturnType, typename... Args>
|
|
1945
|
+
struct RegisterClassMethod<ReturnType (ClassType::*)(Args...) const> {
|
|
1946
|
+
|
|
1947
|
+
template <typename CT, typename... Policies>
|
|
1948
|
+
static void invoke(facebook::jsi::Runtime* rt, const char* methodName,
|
|
1949
|
+
ReturnType (ClassType::*memberFunction)(Args...) const) {
|
|
1950
|
+
using OriginalInvoker = MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>;
|
|
1951
|
+
auto invoke = &maybe_wrap_async<OriginalInvoker, Policies...>::invoke2;
|
|
1952
|
+
|
|
1953
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args;
|
|
1954
|
+
auto a = getContext(memberFunction);
|
|
1955
|
+
|
|
1956
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1957
|
+
*rt,
|
|
1958
|
+
facebook::jsi::PropNameID::forAscii(*rt, std::string(methodName)+"_"+getSignature(invoke)),
|
|
1959
|
+
args.getCount() + 1,
|
|
1960
|
+
[invoke, a, memberFunction](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
1961
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
1962
|
+
callInvokeVoid(sizeof...(Args) + 1, invoke, memberFunction);
|
|
1963
|
+
return nullptr;
|
|
1964
|
+
} else {
|
|
1965
|
+
callInvoke(sizeof...(Args) + 1, invoke, memberFunction);
|
|
1966
|
+
}
|
|
1967
|
+
});
|
|
1968
|
+
|
|
1969
|
+
_embind_register_class_function(
|
|
1970
|
+
TypeID<ClassType>::get(),
|
|
1971
|
+
methodName,
|
|
1972
|
+
args.getCount(),
|
|
1973
|
+
args.getTypes(),
|
|
1974
|
+
getSignature(invoke),
|
|
1975
|
+
invokeJSIFunc,
|
|
1976
|
+
getContext(memberFunction),
|
|
1977
|
+
isPureVirtual<Policies...>::value,
|
|
1978
|
+
isAsync<Policies...>::value);
|
|
1979
|
+
}
|
|
1980
|
+
};
|
|
1981
|
+
|
|
1982
|
+
#ifdef __cpp_noexcept_function_type
|
|
1983
|
+
template<typename ClassType, typename ReturnType, typename... Args>
|
|
1984
|
+
struct RegisterClassMethod<ReturnType (ClassType::*)(Args...) const noexcept>
|
|
1985
|
+
: RegisterClassMethod<ReturnType (ClassType::*)(Args...) const> {};
|
|
1986
|
+
#endif
|
|
1987
|
+
|
|
1988
|
+
template<typename ReturnType, typename ThisType, typename... Args>
|
|
1989
|
+
struct RegisterClassMethod<ReturnType (*)(ThisType, Args...)> {
|
|
1990
|
+
|
|
1991
|
+
template <typename ClassType, typename... Policies>
|
|
1992
|
+
static void invoke(facebook::jsi::Runtime* rt, const char* methodName,
|
|
1993
|
+
ReturnType (*function)(ThisType, Args...)) {
|
|
1994
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args;
|
|
1995
|
+
using OriginalInvoker = FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>;
|
|
1996
|
+
auto invoke = &maybe_wrap_async<OriginalInvoker, Policies...>::invoke2;
|
|
1997
|
+
|
|
1998
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
1999
|
+
*rt,
|
|
2000
|
+
facebook::jsi::PropNameID::forAscii(*rt, std::string(methodName)+"_"+getSignature(invoke)),
|
|
2001
|
+
args.getCount() + 1,
|
|
2002
|
+
[invoke, function](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2003
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
2004
|
+
callInvokeVoid(sizeof...(Args) + 1, invoke, getContext(function));
|
|
2005
|
+
return nullptr;
|
|
2006
|
+
} else {
|
|
2007
|
+
callInvoke(sizeof...(Args) + 1, invoke, getContext(function));
|
|
2008
|
+
}
|
|
2009
|
+
});
|
|
2010
|
+
|
|
2011
|
+
_embind_register_class_function(
|
|
2012
|
+
TypeID<ClassType>::get(),
|
|
2013
|
+
methodName,
|
|
2014
|
+
args.getCount(),
|
|
2015
|
+
args.getTypes(),
|
|
2016
|
+
getSignature(invoke),
|
|
2017
|
+
invokeJSIFunc,
|
|
2018
|
+
getContext(function),
|
|
2019
|
+
false,
|
|
2020
|
+
isAsync<Policies...>::value);
|
|
2021
|
+
}
|
|
2022
|
+
};
|
|
2023
|
+
|
|
2024
|
+
#ifdef __cpp_noexcept_function_type
|
|
2025
|
+
template<typename ReturnType, typename ThisType, typename... Args>
|
|
2026
|
+
struct RegisterClassMethod<ReturnType (*)(ThisType, Args...) noexcept>
|
|
2027
|
+
: RegisterClassMethod<ReturnType (*)(ThisType, Args...)> {};
|
|
2028
|
+
#endif
|
|
2029
|
+
|
|
2030
|
+
template<typename ReturnType, typename ThisType, typename... Args>
|
|
2031
|
+
struct RegisterClassMethod<std::function<ReturnType (ThisType, Args...)>> {
|
|
2032
|
+
|
|
2033
|
+
template <typename ClassType, typename... Policies>
|
|
2034
|
+
static void invoke(facebook::jsi::Runtime* rt, const char* methodName,
|
|
2035
|
+
std::function<ReturnType (ThisType, Args...)> function) {
|
|
2036
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args;
|
|
2037
|
+
using OriginalInvoker = FunctorInvoker<decltype(function), ReturnType, ThisType, Args...>;
|
|
2038
|
+
auto invoke = &maybe_wrap_async<OriginalInvoker, Policies...>::invoke2;
|
|
2039
|
+
|
|
2040
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2041
|
+
*rt,
|
|
2042
|
+
facebook::jsi::PropNameID::forAscii(*rt, std::string(methodName)+"_"+getSignature(invoke)),
|
|
2043
|
+
args.getCount() + 1,
|
|
2044
|
+
[invoke, function](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2045
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
2046
|
+
callInvokeVoid(sizeof...(Args) + 1, invoke, function);
|
|
2047
|
+
return nullptr;
|
|
2048
|
+
} else {
|
|
2049
|
+
callInvoke(sizeof...(Args) + 1, invoke, function);
|
|
2050
|
+
}
|
|
2051
|
+
});
|
|
2052
|
+
|
|
2053
|
+
_embind_register_class_function(
|
|
2054
|
+
TypeID<ClassType>::get(),
|
|
2055
|
+
methodName,
|
|
2056
|
+
args.getCount(),
|
|
2057
|
+
args.getTypes(),
|
|
2058
|
+
getSignature(invoke),
|
|
2059
|
+
invokeJSIFunc,
|
|
2060
|
+
getContext(function),
|
|
2061
|
+
false,
|
|
2062
|
+
isAsync<Policies...>::value);
|
|
2063
|
+
}
|
|
2064
|
+
};
|
|
2065
|
+
|
|
2066
|
+
template<typename ReturnType, typename ThisType, typename... Args>
|
|
2067
|
+
struct RegisterClassMethod<ReturnType (ThisType, Args...)> {
|
|
2068
|
+
|
|
2069
|
+
template <typename ClassType, typename Callable, typename... Policies>
|
|
2070
|
+
static void invoke(facebook::jsi::Runtime* rt, const char* methodName,
|
|
2071
|
+
Callable& callable) {
|
|
2072
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args;
|
|
2073
|
+
using OriginalInvoker = FunctorInvoker<decltype(callable), ReturnType, ThisType, Args...>;
|
|
2074
|
+
auto invoke = &maybe_wrap_async<OriginalInvoker, Policies...>::invoke2;
|
|
2075
|
+
|
|
2076
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2077
|
+
*rt,
|
|
2078
|
+
facebook::jsi::PropNameID::forAscii(*rt, std::string(methodName)+"_"+getSignature(invoke)),
|
|
2079
|
+
args.getCount() + 1,
|
|
2080
|
+
[invoke, callable](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2081
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
2082
|
+
callInvokeVoid(sizeof...(Args) + 1, invoke, callable);
|
|
2083
|
+
return nullptr;
|
|
2084
|
+
} else {
|
|
2085
|
+
callInvoke(sizeof...(Args) + 1, invoke, callable);
|
|
2086
|
+
}
|
|
2087
|
+
});
|
|
2088
|
+
|
|
2089
|
+
_embind_register_class_function(
|
|
2090
|
+
TypeID<ClassType>::get(),
|
|
2091
|
+
methodName,
|
|
2092
|
+
args.getCount(),
|
|
2093
|
+
args.getTypes(),
|
|
2094
|
+
getSignature(invoke),
|
|
2095
|
+
invokeJSIFunc,
|
|
2096
|
+
getContext(callable),
|
|
2097
|
+
false,
|
|
2098
|
+
isAsync<Policies...>::value);
|
|
2099
|
+
}
|
|
2100
|
+
};
|
|
2101
|
+
|
|
2102
|
+
} // end namespace internal
|
|
2103
|
+
|
|
2104
|
+
template<typename... ConstructorArgs>
|
|
2105
|
+
struct constructor {
|
|
2106
|
+
};
|
|
2107
|
+
|
|
2108
|
+
template<typename ClassType, typename BaseSpecifier>
|
|
2109
|
+
facebook::jsi::Value dsadsa(facebook::jsi::Runtime& rt, ClassType* rawValue, BaseSpecifier*);
|
|
2110
|
+
|
|
2111
|
+
template<typename ClassType, typename BaseSpecifier>
|
|
2112
|
+
facebook::jsi::Value dsadsa(facebook::jsi::Runtime& rt, ClassType* rawValue, BaseSpecifier*) {
|
|
2113
|
+
auto upcast = BaseSpecifier::template getUpcaster<ClassType>();
|
|
2114
|
+
auto r = upcast(rawValue);
|
|
2115
|
+
return facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(r));
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
template<typename ClassType, typename BaseSpecifier>
|
|
2119
|
+
facebook::jsi::Value dsadsa(facebook::jsi::Runtime& rt, ClassType* rawValue, internal::NoBaseClass*) {
|
|
2120
|
+
return facebook::jsi::Value::undefined();
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
|
|
2124
|
+
template<typename ClassType, typename BaseSpecifier>
|
|
2125
|
+
facebook::jsi::Value downcastHelper(facebook::jsi::Runtime& rt, ClassType* rawValue, BaseSpecifier*);
|
|
2126
|
+
|
|
2127
|
+
template<typename ClassType, typename BaseSpecifier>
|
|
2128
|
+
facebook::jsi::Value downcastHelper(facebook::jsi::Runtime& rt, ClassType* rawValue, BaseSpecifier*) {
|
|
2129
|
+
auto downcast = BaseSpecifier::template getDowncaster<ClassType>();
|
|
2130
|
+
auto r = downcast(rawValue);
|
|
2131
|
+
return facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(r));
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
template<typename ClassType, typename BaseSpecifier>
|
|
2135
|
+
facebook::jsi::Value downcastHelper(facebook::jsi::Runtime& rt, ClassType* rawValue, internal::NoBaseClass*) {
|
|
2136
|
+
return facebook::jsi::Value::undefined();
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
template<typename ClassType, typename BaseSpecifier = internal::NoBaseClass>
|
|
2140
|
+
class class_ {
|
|
2141
|
+
public:
|
|
2142
|
+
typedef ClassType class_type;
|
|
2143
|
+
typedef BaseSpecifier base_specifier;
|
|
2144
|
+
|
|
2145
|
+
class_() = delete;
|
|
2146
|
+
|
|
2147
|
+
EMSCRIPTEN_ALWAYS_INLINE explicit class_(const char* name) {
|
|
2148
|
+
using namespace internal;
|
|
2149
|
+
|
|
2150
|
+
BaseSpecifier::template verify<ClassType>();
|
|
2151
|
+
|
|
2152
|
+
auto _getActualType = &getActualType<ClassType>;
|
|
2153
|
+
auto upcast = BaseSpecifier::template getUpcaster<ClassType>();
|
|
2154
|
+
auto downcast = BaseSpecifier::template getDowncaster<ClassType>();
|
|
2155
|
+
auto destructor = &raw_destructor<ClassType>;
|
|
2156
|
+
|
|
2157
|
+
facebook::jsi::Function _getActualTypeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2158
|
+
*jsRuntime,
|
|
2159
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"__getActualType"),
|
|
2160
|
+
1,
|
|
2161
|
+
[_getActualType](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2162
|
+
auto returnValue = _getActualType(reinterpret_cast<ClassType*>(args[0].asBigInt(rt).asUint64(rt)));
|
|
2163
|
+
return facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(returnValue));
|
|
2164
|
+
});
|
|
2165
|
+
|
|
2166
|
+
facebook::jsi::Function upcastJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2167
|
+
*jsRuntime,
|
|
2168
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_upcast"),
|
|
2169
|
+
1,
|
|
2170
|
+
[upcast](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2171
|
+
ClassType* t = reinterpret_cast<ClassType*>(args[0].asBigInt(rt).asUint64(rt));
|
|
2172
|
+
BaseSpecifier* a = nullptr;
|
|
2173
|
+
return dsadsa<ClassType, BaseSpecifier>(rt, t, a);
|
|
2174
|
+
});
|
|
2175
|
+
|
|
2176
|
+
facebook::jsi::Function downcastJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2177
|
+
*jsRuntime,
|
|
2178
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_downcast"),
|
|
2179
|
+
1,
|
|
2180
|
+
[downcast](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2181
|
+
ClassType* t = reinterpret_cast<ClassType*>(args[0].asBigInt(rt).asUint64(rt));
|
|
2182
|
+
BaseSpecifier* a = nullptr;
|
|
2183
|
+
return downcastHelper<ClassType, BaseSpecifier>(rt, t, a);
|
|
2184
|
+
});
|
|
2185
|
+
|
|
2186
|
+
facebook::jsi::Function destructorJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2187
|
+
*jsRuntime,
|
|
2188
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_destructor"),
|
|
2189
|
+
1,
|
|
2190
|
+
[destructor](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2191
|
+
destructor(reinterpret_cast<ClassType*>(args[0].asBigInt(rt).asUint64(rt)));
|
|
2192
|
+
return facebook::jsi::Value::undefined();
|
|
2193
|
+
});
|
|
2194
|
+
|
|
2195
|
+
_embind_register_class(
|
|
2196
|
+
TypeID<ClassType>::get(),
|
|
2197
|
+
TypeID<AllowedRawPointer<ClassType>>::get(),
|
|
2198
|
+
TypeID<AllowedRawPointer<const ClassType>>::get(),
|
|
2199
|
+
BaseSpecifier::get(),
|
|
2200
|
+
getSignature(_getActualType),
|
|
2201
|
+
_getActualTypeJSIFunc,
|
|
2202
|
+
getSignature(upcast),
|
|
2203
|
+
upcastJSIFunc,
|
|
2204
|
+
getSignature(downcast),
|
|
2205
|
+
downcastJSIFunc,
|
|
2206
|
+
name,
|
|
2207
|
+
getSignature(destructor),
|
|
2208
|
+
destructorJSIFunc);
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
template<typename PointerType>
|
|
2212
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& smart_ptr(const char* name) const {
|
|
2213
|
+
using namespace internal;
|
|
2214
|
+
|
|
2215
|
+
typedef smart_ptr_trait<PointerType> PointerTrait;
|
|
2216
|
+
typedef typename PointerTrait::element_type PointeeType;
|
|
2217
|
+
|
|
2218
|
+
static_assert(std::is_same<ClassType, typename std::remove_cv<PointeeType>::type>::value, "smart pointer must point to this class");
|
|
2219
|
+
|
|
2220
|
+
auto get = &PointerTrait::get;
|
|
2221
|
+
auto construct_null = &PointerTrait::construct_null;
|
|
2222
|
+
auto share = &PointerTrait::share;
|
|
2223
|
+
auto destructor = &raw_destructor<PointerType>;
|
|
2224
|
+
|
|
2225
|
+
facebook::jsi::Function getJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2226
|
+
*jsRuntime,
|
|
2227
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_get"),
|
|
2228
|
+
1,
|
|
2229
|
+
[get](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2230
|
+
uint64_t ptrNumber = args[0].asBigInt(rt).asUint64(rt);
|
|
2231
|
+
auto b = *reinterpret_cast<PointerType*>(ptrNumber);
|
|
2232
|
+
auto a = get(b);
|
|
2233
|
+
return facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(a));
|
|
2234
|
+
});
|
|
2235
|
+
|
|
2236
|
+
facebook::jsi::Function construct_nullJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2237
|
+
*jsRuntime,
|
|
2238
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_construct_null"),
|
|
2239
|
+
1,
|
|
2240
|
+
[construct_null](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2241
|
+
auto a = construct_null();
|
|
2242
|
+
return facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(a));
|
|
2243
|
+
});
|
|
2244
|
+
|
|
2245
|
+
facebook::jsi::Function shareJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2246
|
+
*jsRuntime,
|
|
2247
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_share"),
|
|
2248
|
+
2,
|
|
2249
|
+
[share](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2250
|
+
uint64_t pNumber = args[0].asBigInt(rt).asUint64(rt);
|
|
2251
|
+
auto p = reinterpret_cast<PointeeType*>(pNumber);
|
|
2252
|
+
// uint64_t vNumber = (uint64_t) args[1].getNumber();
|
|
2253
|
+
uint64_t vNumber = args[1].asBigInt(rt).asUint64(rt);
|
|
2254
|
+
EM_VAL v = reinterpret_cast<EM_VAL>(vNumber);
|
|
2255
|
+
auto a = share(p, v);
|
|
2256
|
+
auto e = facebook::jsi::BigInt::fromUint64(rt, reinterpret_cast<uint64_t>(a));
|
|
2257
|
+
return e;
|
|
2258
|
+
});
|
|
2259
|
+
|
|
2260
|
+
facebook::jsi::Function destructorJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2261
|
+
*jsRuntime,
|
|
2262
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_destructor"),
|
|
2263
|
+
1,
|
|
2264
|
+
[destructor](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2265
|
+
uint64_t ptrNumber = args[0].asBigInt(rt).asUint64(rt);
|
|
2266
|
+
auto b = reinterpret_cast<PointerType*>(ptrNumber);
|
|
2267
|
+
destructor(b);
|
|
2268
|
+
return facebook::jsi::Value::undefined();
|
|
2269
|
+
});
|
|
2270
|
+
|
|
2271
|
+
_embind_register_smart_ptr(
|
|
2272
|
+
TypeID<PointerType>::get(),
|
|
2273
|
+
TypeID<PointeeType>::get(),
|
|
2274
|
+
name,
|
|
2275
|
+
PointerTrait::get_sharing_policy(),
|
|
2276
|
+
getSignature(get),
|
|
2277
|
+
getJSIFunc,
|
|
2278
|
+
getSignature(construct_null),
|
|
2279
|
+
construct_nullJSIFunc,
|
|
2280
|
+
getSignature(share),
|
|
2281
|
+
shareJSIFunc,
|
|
2282
|
+
getSignature(destructor),
|
|
2283
|
+
destructorJSIFunc);
|
|
2284
|
+
return *this;
|
|
2285
|
+
};
|
|
2286
|
+
|
|
2287
|
+
template<typename... ConstructorArgs, typename... Policies>
|
|
2288
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& constructor(Policies... policies) const {
|
|
2289
|
+
return constructor(
|
|
2290
|
+
&internal::operator_new<ClassType, ConstructorArgs...>,
|
|
2291
|
+
policies...);
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
template<typename Signature = internal::DeduceArgumentsTag, typename Callable, typename... Policies>
|
|
2295
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& constructor(Callable callable, Policies...) const {
|
|
2296
|
+
|
|
2297
|
+
using invoker = internal::RegisterClassConstructor<
|
|
2298
|
+
typename std::conditional<std::is_same<Signature, internal::DeduceArgumentsTag>::value,
|
|
2299
|
+
Callable,
|
|
2300
|
+
Signature>::type>;
|
|
2301
|
+
|
|
2302
|
+
invoker::template invoke<ClassType, Policies...>(callable);
|
|
2303
|
+
return *this;
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
template<typename SmartPtr, typename... Args, typename... Policies>
|
|
2307
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& smart_ptr_constructor(const char* smartPtrName, SmartPtr (*factory)(Args...), Policies...) const {
|
|
2308
|
+
using namespace internal;
|
|
2309
|
+
|
|
2310
|
+
// smart_ptr<SmartPtr>(smartPtrName);
|
|
2311
|
+
|
|
2312
|
+
typename WithPolicies<Policies...>::template ArgTypeList<SmartPtr, Args...> args;
|
|
2313
|
+
auto invoke = &Invoker<SmartPtr, Args...>::invoke2;
|
|
2314
|
+
|
|
2315
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2316
|
+
*jsRuntime,
|
|
2317
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(smartPtrName)+"_"+getSignature(invoke)),
|
|
2318
|
+
args.getCount() - 1,
|
|
2319
|
+
[invoke, factory](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2320
|
+
callInvoke(sizeof...(Args), invoke, factory);
|
|
2321
|
+
});
|
|
2322
|
+
|
|
2323
|
+
_embind_register_class_constructor(
|
|
2324
|
+
TypeID<ClassType>::get(),
|
|
2325
|
+
args.getCount(),
|
|
2326
|
+
args.getTypes(),
|
|
2327
|
+
getSignature(invoke),
|
|
2328
|
+
invokeJSIFunc,
|
|
2329
|
+
reinterpret_cast<GenericFunction>(factory));
|
|
2330
|
+
return *this;
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
template<typename WrapperType, typename... ConstructorArgs>
|
|
2334
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& allow_subclass(
|
|
2335
|
+
const char* wrapperClassName,
|
|
2336
|
+
::emscripten::constructor<ConstructorArgs...> = ::emscripten::constructor<>()
|
|
2337
|
+
) const {
|
|
2338
|
+
using namespace internal;
|
|
2339
|
+
|
|
2340
|
+
auto cls = class_<WrapperType, base<ClassType>>(wrapperClassName)
|
|
2341
|
+
.function("notifyOnDestruction", select_overload<void(WrapperType&)>([](WrapperType& wrapper) {
|
|
2342
|
+
wrapper.setNotifyJSOnDestruction(true);
|
|
2343
|
+
}))
|
|
2344
|
+
;
|
|
2345
|
+
|
|
2346
|
+
return
|
|
2347
|
+
class_function(
|
|
2348
|
+
"implement",
|
|
2349
|
+
&wrapped_new<WrapperType*, WrapperType, val, ConstructorArgs...>,
|
|
2350
|
+
allow_raw_pointer<ret_val>())
|
|
2351
|
+
.class_function(
|
|
2352
|
+
"extend",
|
|
2353
|
+
&wrapped_extend<WrapperType>)
|
|
2354
|
+
;
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
template<typename WrapperType, typename PointerType, typename... ConstructorArgs>
|
|
2358
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& allow_subclass(
|
|
2359
|
+
const char* wrapperClassName,
|
|
2360
|
+
const char* pointerName,
|
|
2361
|
+
::emscripten::constructor<ConstructorArgs...> = ::emscripten::constructor<>()
|
|
2362
|
+
) const {
|
|
2363
|
+
using namespace internal;
|
|
2364
|
+
|
|
2365
|
+
auto cls = class_<WrapperType, base<ClassType>>(wrapperClassName)
|
|
2366
|
+
.function("notifyOnDestruction", select_overload<void(WrapperType&)>([](WrapperType& wrapper) {
|
|
2367
|
+
wrapper.setNotifyJSOnDestruction(true);
|
|
2368
|
+
}))
|
|
2369
|
+
.template smart_ptr<PointerType>(pointerName)
|
|
2370
|
+
;
|
|
2371
|
+
|
|
2372
|
+
return
|
|
2373
|
+
class_function(
|
|
2374
|
+
"implement",
|
|
2375
|
+
&wrapped_new<PointerType, WrapperType, val, ConstructorArgs...>,
|
|
2376
|
+
allow_raw_pointer<ret_val>())
|
|
2377
|
+
.class_function(
|
|
2378
|
+
"extend",
|
|
2379
|
+
&wrapped_extend<WrapperType>)
|
|
2380
|
+
;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
template<typename Signature = internal::DeduceArgumentsTag, typename Callable, typename... Policies>
|
|
2384
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& function(const char* methodName, Callable callable, Policies...) const {
|
|
2385
|
+
using invoker = internal::RegisterClassMethod<
|
|
2386
|
+
typename std::conditional<std::is_same<Signature, internal::DeduceArgumentsTag>::value,
|
|
2387
|
+
Callable,
|
|
2388
|
+
Signature>::type>;
|
|
2389
|
+
|
|
2390
|
+
invoker::template invoke<ClassType, Policies...>(jsRuntime, methodName, callable);
|
|
2391
|
+
return *this;
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
|
|
2395
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, const FieldType ClassType::*field) const {
|
|
2396
|
+
using namespace internal;
|
|
2397
|
+
|
|
2398
|
+
auto getter = &MemberAccess<ClassType, FieldType>::template getWire2<ClassType>;
|
|
2399
|
+
FieldType ClassType::* a = const_cast<FieldType ClassType::*>(field);
|
|
2400
|
+
|
|
2401
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2402
|
+
*jsRuntime,
|
|
2403
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName)+"_gter"),
|
|
2404
|
+
2,
|
|
2405
|
+
[getter, a](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2406
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
2407
|
+
return getter(a, *t2);
|
|
2408
|
+
});
|
|
2409
|
+
|
|
2410
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2411
|
+
*jsRuntime,
|
|
2412
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName)+"_ster"),
|
|
2413
|
+
0,
|
|
2414
|
+
[](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2415
|
+
return facebook::jsi::Value::undefined();
|
|
2416
|
+
});
|
|
2417
|
+
|
|
2418
|
+
_embind_register_class_property(
|
|
2419
|
+
TypeID<ClassType>::get(),
|
|
2420
|
+
fieldName,
|
|
2421
|
+
TypeID<FieldType>::get(),
|
|
2422
|
+
getSignature(getter),
|
|
2423
|
+
getterJSIFunc,
|
|
2424
|
+
getContext(field),
|
|
2425
|
+
0,
|
|
2426
|
+
"",
|
|
2427
|
+
setterJSIFunc,
|
|
2428
|
+
0);
|
|
2429
|
+
return *this;
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
|
|
2433
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, FieldType ClassType::*field) const {
|
|
2434
|
+
using namespace internal;
|
|
2435
|
+
|
|
2436
|
+
auto getter = &MemberAccess<ClassType, FieldType>::template getWire2<ClassType>;
|
|
2437
|
+
auto setter = &MemberAccess<ClassType, FieldType>::template setWire2<ClassType>;
|
|
2438
|
+
|
|
2439
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2440
|
+
*jsRuntime,
|
|
2441
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName)+"_gter"),
|
|
2442
|
+
2,
|
|
2443
|
+
[getter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2444
|
+
FieldType* t = reinterpret_cast<FieldType*>(args[0].asBigInt(rt).asUint64(rt));
|
|
2445
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
2446
|
+
return getter(field, *t2);
|
|
2447
|
+
});
|
|
2448
|
+
|
|
2449
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2450
|
+
*jsRuntime,
|
|
2451
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName)+"_ster"),
|
|
2452
|
+
3,
|
|
2453
|
+
[setter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2454
|
+
FieldType* t = reinterpret_cast<FieldType*>(args[0].asBigInt(rt).asUint64(rt));
|
|
2455
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
2456
|
+
setter(field, *t2, args[2]);
|
|
2457
|
+
return facebook::jsi::Value::undefined();
|
|
2458
|
+
});
|
|
2459
|
+
|
|
2460
|
+
_embind_register_class_property(
|
|
2461
|
+
TypeID<ClassType>::get(),
|
|
2462
|
+
fieldName,
|
|
2463
|
+
TypeID<FieldType>::get(),
|
|
2464
|
+
getSignature(getter),
|
|
2465
|
+
getterJSIFunc,
|
|
2466
|
+
getContext(field),
|
|
2467
|
+
TypeID<FieldType>::get(),
|
|
2468
|
+
getSignature(setter),
|
|
2469
|
+
setterJSIFunc,
|
|
2470
|
+
getContext(field));
|
|
2471
|
+
return *this;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
template<typename PropertyType = internal::DeduceArgumentsTag, typename Getter>
|
|
2475
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, Getter getter) const {
|
|
2476
|
+
using namespace internal;
|
|
2477
|
+
|
|
2478
|
+
typedef GetterPolicy<
|
|
2479
|
+
typename std::conditional<std::is_same<PropertyType, internal::DeduceArgumentsTag>::value,
|
|
2480
|
+
Getter,
|
|
2481
|
+
PropertyTag<Getter, PropertyType>>::type> GP;
|
|
2482
|
+
|
|
2483
|
+
auto gter = &GP::template get2<ClassType>;
|
|
2484
|
+
|
|
2485
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2486
|
+
*jsRuntime,
|
|
2487
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName) + "_gter"),
|
|
2488
|
+
2,
|
|
2489
|
+
[gter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2490
|
+
Getter* t = reinterpret_cast<Getter*>(args[0].asBigInt(rt).asUint64(rt));
|
|
2491
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
2492
|
+
return gter(*t, *t2);
|
|
2493
|
+
});
|
|
2494
|
+
|
|
2495
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2496
|
+
*jsRuntime,
|
|
2497
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName)+"_ster"),
|
|
2498
|
+
3,
|
|
2499
|
+
[](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2500
|
+
return facebook::jsi::Value::undefined();
|
|
2501
|
+
});
|
|
2502
|
+
|
|
2503
|
+
_embind_register_class_property(
|
|
2504
|
+
TypeID<ClassType>::get(),
|
|
2505
|
+
fieldName,
|
|
2506
|
+
TypeID<typename GP::ReturnType>::get(),
|
|
2507
|
+
getSignature(gter),
|
|
2508
|
+
getterJSIFunc,
|
|
2509
|
+
GP::getContext(getter),
|
|
2510
|
+
0,
|
|
2511
|
+
"",
|
|
2512
|
+
setterJSIFunc,
|
|
2513
|
+
0);
|
|
2514
|
+
return *this;
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
template<typename PropertyType = internal::DeduceArgumentsTag, typename Getter, typename Setter>
|
|
2518
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, Getter getter, Setter setter) const {
|
|
2519
|
+
using namespace internal;
|
|
2520
|
+
|
|
2521
|
+
typedef GetterPolicy<
|
|
2522
|
+
typename std::conditional<std::is_same<PropertyType, internal::DeduceArgumentsTag>::value,
|
|
2523
|
+
Getter,
|
|
2524
|
+
PropertyTag<Getter, PropertyType>>::type> GP;
|
|
2525
|
+
typedef SetterPolicy<
|
|
2526
|
+
typename std::conditional<std::is_same<PropertyType, internal::DeduceArgumentsTag>::value,
|
|
2527
|
+
Setter,
|
|
2528
|
+
PropertyTag<Setter, PropertyType>>::type> SP;
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
auto gter = &GP::template get2<ClassType>;
|
|
2532
|
+
auto ster = &SP::template set2<ClassType>;
|
|
2533
|
+
|
|
2534
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2535
|
+
*jsRuntime,
|
|
2536
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName)+"_gter"),
|
|
2537
|
+
2,
|
|
2538
|
+
[gter](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2539
|
+
Getter* t = reinterpret_cast<Getter*>(args[0].asBigInt(rt).asUint64(rt));
|
|
2540
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
2541
|
+
return gter(*t, *t2);
|
|
2542
|
+
});
|
|
2543
|
+
|
|
2544
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2545
|
+
*jsRuntime,
|
|
2546
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(fieldName)+"_ster"),
|
|
2547
|
+
3,
|
|
2548
|
+
[ster](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2549
|
+
Setter* t = reinterpret_cast<Setter*>(args[0].asBigInt(rt).asUint64(rt));
|
|
2550
|
+
ClassType* t2 = reinterpret_cast<ClassType*>(args[1].asBigInt(rt).asUint64(rt));
|
|
2551
|
+
ster(*t, *t2, args[2]);
|
|
2552
|
+
return facebook::jsi::Value::undefined();
|
|
2553
|
+
});
|
|
2554
|
+
|
|
2555
|
+
_embind_register_class_property(
|
|
2556
|
+
TypeID<ClassType>::get(),
|
|
2557
|
+
fieldName,
|
|
2558
|
+
TypeID<typename GP::ReturnType>::get(),
|
|
2559
|
+
getSignature(gter),
|
|
2560
|
+
getterJSIFunc,
|
|
2561
|
+
GP::getContext(getter),
|
|
2562
|
+
TypeID<typename SP::ArgumentType>::get(),
|
|
2563
|
+
getSignature(ster),
|
|
2564
|
+
setterJSIFunc,
|
|
2565
|
+
SP::getContext(setter));
|
|
2566
|
+
return *this;
|
|
2567
|
+
}
|
|
2568
|
+
|
|
2569
|
+
template<typename ReturnType, typename... Args, typename... Policies>
|
|
2570
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) const {
|
|
2571
|
+
using namespace internal;
|
|
2572
|
+
|
|
2573
|
+
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
|
|
2574
|
+
using OriginalInvoker = internal::Invoker<ReturnType, Args...>;
|
|
2575
|
+
auto invoke = &maybe_wrap_async<OriginalInvoker, Policies...>::invoke2;
|
|
2576
|
+
|
|
2577
|
+
facebook::jsi::Function invokeJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2578
|
+
*jsRuntime,
|
|
2579
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(methodName)+"_"+getSignature(invoke)),
|
|
2580
|
+
args.getCount() - 1,
|
|
2581
|
+
[invoke, classMethod](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2582
|
+
if constexpr (std::is_same<ReturnType, void>::value) {
|
|
2583
|
+
callInvokeVoid(sizeof...(Args), invoke, classMethod);
|
|
2584
|
+
return nullptr;
|
|
2585
|
+
} else {
|
|
2586
|
+
callInvoke(sizeof...(Args), invoke, classMethod);
|
|
2587
|
+
}
|
|
2588
|
+
});
|
|
2589
|
+
|
|
2590
|
+
_embind_register_class_class_function(
|
|
2591
|
+
TypeID<ClassType>::get(),
|
|
2592
|
+
methodName,
|
|
2593
|
+
args.getCount(),
|
|
2594
|
+
args.getTypes(),
|
|
2595
|
+
getSignature(invoke),
|
|
2596
|
+
invokeJSIFunc,
|
|
2597
|
+
reinterpret_cast<GenericFunction>(classMethod),
|
|
2598
|
+
isAsync<Policies...>::value);
|
|
2599
|
+
return *this;
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
template<typename FieldType>
|
|
2603
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& class_property(const char* name, const FieldType* field) const {
|
|
2604
|
+
using namespace internal;
|
|
2605
|
+
|
|
2606
|
+
auto getter = &GlobalAccess<FieldType>::get2;
|
|
2607
|
+
|
|
2608
|
+
FieldType* a = const_cast<FieldType*>(field);
|
|
2609
|
+
|
|
2610
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2611
|
+
*jsRuntime,
|
|
2612
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_"+getSignature(getter)),
|
|
2613
|
+
1,
|
|
2614
|
+
[getter, a](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2615
|
+
return getter(a);
|
|
2616
|
+
});
|
|
2617
|
+
|
|
2618
|
+
|
|
2619
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2620
|
+
*jsRuntime,
|
|
2621
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_null_setter"),
|
|
2622
|
+
2,
|
|
2623
|
+
[](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2624
|
+
return facebook::jsi::Value::undefined();
|
|
2625
|
+
});
|
|
2626
|
+
|
|
2627
|
+
_embind_register_class_class_property(
|
|
2628
|
+
TypeID<ClassType>::get(),
|
|
2629
|
+
name,
|
|
2630
|
+
TypeID<FieldType>::get(),
|
|
2631
|
+
a,
|
|
2632
|
+
getSignature(getter),
|
|
2633
|
+
getterJSIFunc,
|
|
2634
|
+
"",
|
|
2635
|
+
setterJSIFunc);
|
|
2636
|
+
return *this;
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
template<typename FieldType>
|
|
2640
|
+
EMSCRIPTEN_ALWAYS_INLINE const class_& class_property(const char* name, FieldType* field) const {
|
|
2641
|
+
using namespace internal;
|
|
2642
|
+
|
|
2643
|
+
auto getter = &GlobalAccess<FieldType>::get2;
|
|
2644
|
+
auto setter = &GlobalAccess<FieldType>::set2;
|
|
2645
|
+
|
|
2646
|
+
facebook::jsi::Function getterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2647
|
+
*jsRuntime,
|
|
2648
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_"+getSignature(getter)),
|
|
2649
|
+
1,
|
|
2650
|
+
[getter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2651
|
+
return getter(field);
|
|
2652
|
+
});
|
|
2653
|
+
|
|
2654
|
+
|
|
2655
|
+
facebook::jsi::Function setterJSIFunc = facebook::jsi::Function::createFromHostFunction(
|
|
2656
|
+
*jsRuntime,
|
|
2657
|
+
facebook::jsi::PropNameID::forAscii(*jsRuntime, std::string(name)+"_"+getSignature(setter)),
|
|
2658
|
+
2,
|
|
2659
|
+
[setter, field](facebook::jsi::Runtime& rt, const facebook::jsi::Value& thisVal, const facebook::jsi::Value* args, size_t count) {
|
|
2660
|
+
setter(field, args[1]);
|
|
2661
|
+
return facebook::jsi::Value::undefined();
|
|
2662
|
+
});
|
|
2663
|
+
|
|
2664
|
+
_embind_register_class_class_property(
|
|
2665
|
+
TypeID<ClassType>::get(),
|
|
2666
|
+
name,
|
|
2667
|
+
TypeID<FieldType>::get(),
|
|
2668
|
+
field,
|
|
2669
|
+
getSignature(getter),
|
|
2670
|
+
getterJSIFunc,
|
|
2671
|
+
getSignature(setter),
|
|
2672
|
+
setterJSIFunc);
|
|
2673
|
+
return *this;
|
|
2674
|
+
}
|
|
2675
|
+
};
|
|
2676
|
+
|
|
2677
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2678
|
+
// VECTORS
|
|
2679
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2680
|
+
|
|
2681
|
+
namespace internal {
|
|
2682
|
+
|
|
2683
|
+
template<typename VectorType, typename Type>
|
|
2684
|
+
struct VectorAccess {
|
|
2685
|
+
static val get(
|
|
2686
|
+
const VectorType& v,
|
|
2687
|
+
int index
|
|
2688
|
+
) {
|
|
2689
|
+
if (index < v.size()) {
|
|
2690
|
+
return val(v[index]);
|
|
2691
|
+
} else {
|
|
2692
|
+
return val::undefined();
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2696
|
+
static bool set(
|
|
2697
|
+
VectorType& v,
|
|
2698
|
+
int index,
|
|
2699
|
+
const typename VectorType::value_type& value
|
|
2700
|
+
) {
|
|
2701
|
+
v[index] = value;
|
|
2702
|
+
return true;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
static int size(VectorType& v) {
|
|
2706
|
+
return (int) v.size();
|
|
2707
|
+
}
|
|
2708
|
+
};
|
|
2709
|
+
|
|
2710
|
+
} // end namespace internal
|
|
2711
|
+
|
|
2712
|
+
template<typename T>
|
|
2713
|
+
void register_optional() {
|
|
2714
|
+
// Mirrors upstream embind: the optional<T> TYPEID resolves to a JS converter that
|
|
2715
|
+
// delegates to T's converter, with no-value crossing as undefined.
|
|
2716
|
+
internal::_embind_register_optional(
|
|
2717
|
+
internal::TypeID<std::optional<T>>::get(),
|
|
2718
|
+
internal::TypeID<T>::get());
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
template<typename T>
|
|
2722
|
+
class_<std::vector<T>> register_vector(const char* name) {
|
|
2723
|
+
typedef std::vector<T> VecType;
|
|
2724
|
+
// Upstream registers the element's optional alongside the vector; matching it keeps
|
|
2725
|
+
// optional<T> usable wherever a vector of T is registered (the common bridge case).
|
|
2726
|
+
register_optional<T>();
|
|
2727
|
+
|
|
2728
|
+
void (VecType::*push_back)(const T&) = &VecType::push_back;
|
|
2729
|
+
void (VecType::*resize)(const size_t, const T&) = &VecType::resize;
|
|
2730
|
+
// size_t (VecType::*size)() const = &VecType::size;
|
|
2731
|
+
return class_<std::vector<T>>(name)
|
|
2732
|
+
.template constructor<>()
|
|
2733
|
+
.function("push_back", push_back)
|
|
2734
|
+
.function("resize", resize)
|
|
2735
|
+
.function("size", &internal::VectorAccess<VecType, T>::size)
|
|
2736
|
+
.function("get", &internal::VectorAccess<VecType, T>::get)
|
|
2737
|
+
.function("set", &internal::VectorAccess<VecType, T>::set)
|
|
2738
|
+
;
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2742
|
+
// MAPS
|
|
2743
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2744
|
+
|
|
2745
|
+
namespace internal {
|
|
2746
|
+
|
|
2747
|
+
template<typename MapType>
|
|
2748
|
+
struct MapAccess {
|
|
2749
|
+
static val get(
|
|
2750
|
+
const MapType& m,
|
|
2751
|
+
const typename MapType::key_type& k
|
|
2752
|
+
) {
|
|
2753
|
+
auto i = m.find(k);
|
|
2754
|
+
if (i == m.end()) {
|
|
2755
|
+
return val::undefined();
|
|
2756
|
+
} else {
|
|
2757
|
+
return val(i->second);
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
static void set(
|
|
2762
|
+
MapType& m,
|
|
2763
|
+
const typename MapType::key_type& k,
|
|
2764
|
+
const typename MapType::mapped_type& v
|
|
2765
|
+
) {
|
|
2766
|
+
m[k] = v;
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
static std::vector<typename MapType::key_type> keys(
|
|
2770
|
+
const MapType& m
|
|
2771
|
+
) {
|
|
2772
|
+
std::vector<typename MapType::key_type> keys;
|
|
2773
|
+
keys.reserve(m.size());
|
|
2774
|
+
for (const auto& pair : m) {
|
|
2775
|
+
keys.push_back(pair.first);
|
|
2776
|
+
}
|
|
2777
|
+
return keys;
|
|
2778
|
+
}
|
|
2779
|
+
};
|
|
2780
|
+
|
|
2781
|
+
} // end namespace internal
|
|
2782
|
+
|
|
2783
|
+
template<typename K, typename V>
|
|
2784
|
+
class_<std::map<K, V>> register_map(const char* name) {
|
|
2785
|
+
typedef std::map<K,V> MapType;
|
|
2786
|
+
|
|
2787
|
+
size_t (MapType::*size)() const = &MapType::size;
|
|
2788
|
+
return class_<MapType>(name)
|
|
2789
|
+
.template constructor<>()
|
|
2790
|
+
.function("size", size)
|
|
2791
|
+
.function("get", internal::MapAccess<MapType>::get)
|
|
2792
|
+
.function("set", internal::MapAccess<MapType>::set)
|
|
2793
|
+
.function("keys", internal::MapAccess<MapType>::keys)
|
|
2794
|
+
;
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
|
|
2798
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2799
|
+
// ENUMS
|
|
2800
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2801
|
+
|
|
2802
|
+
template<typename EnumType>
|
|
2803
|
+
class enum_ {
|
|
2804
|
+
public:
|
|
2805
|
+
typedef EnumType enum_type;
|
|
2806
|
+
|
|
2807
|
+
enum_(const char* name) {
|
|
2808
|
+
using namespace internal;
|
|
2809
|
+
_embind_register_enum(
|
|
2810
|
+
internal::TypeID<EnumType>::get(),
|
|
2811
|
+
name,
|
|
2812
|
+
sizeof(EnumType),
|
|
2813
|
+
std::is_signed<typename std::underlying_type<EnumType>::type>::value);
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
enum_& value(const char* name, EnumType value) {
|
|
2817
|
+
using namespace internal;
|
|
2818
|
+
// TODO: there's still an issue here.
|
|
2819
|
+
// if EnumType is an unsigned long, then JS may receive it as a signed long
|
|
2820
|
+
static_assert(sizeof(value) <= sizeof(internal::GenericEnumValue), "enum type must fit in a GenericEnumValue");
|
|
2821
|
+
|
|
2822
|
+
_embind_register_enum_value(
|
|
2823
|
+
internal::TypeID<EnumType>::get(),
|
|
2824
|
+
name,
|
|
2825
|
+
static_cast<internal::GenericEnumValue>(value));
|
|
2826
|
+
return *this;
|
|
2827
|
+
}
|
|
2828
|
+
};
|
|
2829
|
+
|
|
2830
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2831
|
+
// CONSTANTS
|
|
2832
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2833
|
+
|
|
2834
|
+
namespace internal {
|
|
2835
|
+
|
|
2836
|
+
template<typename T> double asGenericValue(T t) {
|
|
2837
|
+
return static_cast<double>(t);
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
template<typename T> uint64_t asGenericValue(T* p) {
|
|
2841
|
+
return reinterpret_cast<uint64_t>(p);
|
|
2842
|
+
}
|
|
2843
|
+
|
|
2844
|
+
template<typename T> std::string asGenericValue(std::string p) {
|
|
2845
|
+
return p;
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
template<typename ConstantType>
|
|
2851
|
+
void constant(const char* name, const ConstantType& v) {
|
|
2852
|
+
using namespace internal;
|
|
2853
|
+
typedef BindingType<const ConstantType&> BT;
|
|
2854
|
+
_embind_register_constant(
|
|
2855
|
+
name,
|
|
2856
|
+
TypeID<const ConstantType&>::get(),
|
|
2857
|
+
BT::toWireType2(*jsRuntime, v)
|
|
2858
|
+
);
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
// EMSCRIPTEN_BINDINGS creates a static struct to initialize the binding which
|
|
2862
|
+
// will get included in the program if the translation unit in which it is
|
|
2863
|
+
// defined gets linked into the program. Using a C++ constructor here ensures it
|
|
2864
|
+
// occurs after any other C++ constructors in this file, which is not true for
|
|
2865
|
+
// __attribute__((constructor)) (they run before C++ constructors in the same
|
|
2866
|
+
// file).
|
|
2867
|
+
#define EMSCRIPTEN_BINDINGS(name) \
|
|
2868
|
+
static void embind_init_##name(); \
|
|
2869
|
+
static struct EmBindInit_##name : emscripten::internal::InitFunc { \
|
|
2870
|
+
EmBindInit_##name() : InitFunc(embind_init_##name) {} \
|
|
2871
|
+
} EmBindInit_##name##_instance; \
|
|
2872
|
+
static void embind_init_##name()
|
|
2873
|
+
|
|
2874
|
+
} // end namespace emscripten
|
|
2875
|
+
|
|
2876
|
+
class Crossbind {
|
|
2877
|
+
public:
|
|
2878
|
+
static int setEnv(std::string key, std::string value, bool overwrite);
|
|
2879
|
+
static std::string getEnv(std::string key);
|
|
2880
|
+
};
|