10
#include <emscripten/val.h>
11
#include <emscripten/wire.h>
13
namespace emscripten {
14
enum class sharing_policy {
21
typedef void (*GenericFunction)();
22
typedef long GenericEnumValue;
24
// Implemented in JavaScript. Don't call these directly.
26
void _embind_fatal_error(
28
const char* payload) __attribute__((noreturn));
30
void _embind_register_void(
34
void _embind_register_bool(
40
void _embind_register_integer(
44
unsigned long maxRange);
46
void _embind_register_float(
50
void _embind_register_std_string(
54
void _embind_register_std_wstring(
59
void _embind_register_emval(
63
void _embind_register_function(
67
GenericFunction invoker,
68
GenericFunction function);
70
void _embind_register_tuple(
73
GenericFunction constructor,
74
GenericFunction destructor);
76
void _embind_register_tuple_element(
78
TYPEID getterReturnType,
79
GenericFunction getter,
81
TYPEID setterArgumentType,
82
GenericFunction setter,
85
void _embind_finalize_tuple(TYPEID tupleType);
87
void _embind_register_struct(
89
const char* fieldName,
90
GenericFunction constructor,
91
GenericFunction destructor);
93
void _embind_register_struct_field(
95
const char* fieldName,
96
TYPEID getterReturnType,
97
GenericFunction getter,
99
TYPEID setterArgumentType,
100
GenericFunction setter,
101
void* setterContext);
103
void _embind_finalize_struct(TYPEID structType);
105
void _embind_register_smart_ptr(
108
const char* pointerName,
109
sharing_policy sharingPolicy,
110
GenericFunction getPointee,
111
GenericFunction constructor,
112
GenericFunction share,
113
GenericFunction destructor);
115
void _embind_register_class(
118
TYPEID constPointerType,
119
TYPEID baseClassType,
120
GenericFunction getActualType,
121
GenericFunction upcast,
122
GenericFunction downcast,
123
const char* className,
124
GenericFunction destructor);
126
void _embind_register_class_constructor(
130
GenericFunction invoker,
131
GenericFunction constructor);
133
void _embind_register_class_function(
135
const char* methodName,
138
GenericFunction invoker,
141
void _embind_register_class_property(
143
const char* fieldName,
144
TYPEID getterReturnType,
145
GenericFunction getter,
147
TYPEID setterArgumentType,
148
GenericFunction setter,
149
void* setterContext);
151
void _embind_register_class_class_function(
153
const char* methodName,
156
GenericFunction invoker,
157
GenericFunction method);
159
void _embind_register_enum(
163
void _embind_register_enum_value(
165
const char* valueName,
166
GenericEnumValue value);
168
void _embind_register_interface(
169
TYPEID interfaceType,
171
GenericFunction constructor,
172
GenericFunction destructor);
174
void _embind_register_constant(
182
namespace emscripten {
183
////////////////////////////////////////////////////////////////////////////////
185
////////////////////////////////////////////////////////////////////////////////
189
static constexpr int index = Index + 1;
193
static constexpr int index = 0;
197
template<typename Slot>
198
struct allow_raw_pointer {
199
template<typename InputType, int Index>
201
typedef typename std::conditional<
202
Index == Slot::index,
203
internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>,
210
// whitelist all raw pointers
211
struct allow_raw_pointers {
212
template<typename InputType, int Index>
214
typedef typename std::conditional<
215
std::is_pointer<InputType>::value,
216
internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>,
222
// this is temporary until arg policies are reworked
223
template<typename Slot>
224
struct allow_raw_pointer : public allow_raw_pointers {
227
template<typename Signature>
228
typename std::add_pointer<Signature>::type select_overload(typename std::add_pointer<Signature>::type fn) {
233
template<typename ClassType, typename Signature>
234
struct MemberFunctionType {
235
typedef Signature (ClassType::*type);
239
template<typename Signature, typename ClassType>
240
typename internal::MemberFunctionType<ClassType, Signature>::type select_overload(Signature (ClassType::*fn)) {
245
template<typename ReturnType, typename... Args>
247
static typename internal::BindingType<ReturnType>::WireType invoke(
248
ReturnType (*fn)(Args...),
249
typename internal::BindingType<Args>::WireType... args
251
return internal::BindingType<ReturnType>::toWireType(
253
internal::BindingType<Args>::fromWireType(args)...
259
template<typename... Args>
260
struct Invoker<void, Args...> {
263
typename internal::BindingType<Args>::WireType... args
266
internal::BindingType<Args>::fromWireType(args)...
272
////////////////////////////////////////////////////////////////////////////////
274
////////////////////////////////////////////////////////////////////////////////
277
void* __getDynamicPointerType(void* p);
280
template<typename ReturnType, typename... Args, typename... Policies>
281
void function(const char* name, ReturnType (*fn)(Args...), Policies...) {
282
using namespace internal;
283
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
284
_embind_register_function(
288
reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke),
289
reinterpret_cast<GenericFunction>(fn));
293
template<typename ClassType, typename... Args>
294
ClassType* operator_new(Args... args) {
295
return new ClassType(args...);
298
template<typename WrapperType, typename ClassType, typename... Args>
299
WrapperType wrapped_new(Args&&... args) {
300
return WrapperType(new ClassType(std::forward<Args>(args)...));
303
template<typename ClassType, typename... Args>
304
ClassType* raw_constructor(
305
typename internal::BindingType<Args>::WireType... args
307
return new ClassType(
308
internal::BindingType<Args>::fromWireType(args)...
312
template<typename ClassType>
313
void raw_destructor(ClassType* ptr) {
317
template<typename FunctionPointerType, typename ReturnType, typename ThisType, typename... Args>
318
struct FunctionInvoker {
319
static typename internal::BindingType<ReturnType>::WireType invoke(
320
FunctionPointerType* function,
321
typename internal::BindingType<ThisType>::WireType wireThis,
322
typename internal::BindingType<Args>::WireType... args
324
return internal::BindingType<ReturnType>::toWireType(
326
internal::BindingType<ThisType>::fromWireType(wireThis),
327
internal::BindingType<Args>::fromWireType(args)...)
332
template<typename FunctionPointerType, typename ThisType, typename... Args>
333
struct FunctionInvoker<FunctionPointerType, void, ThisType, Args...> {
335
FunctionPointerType* function,
336
typename internal::BindingType<ThisType>::WireType wireThis,
337
typename internal::BindingType<Args>::WireType... args
340
internal::BindingType<ThisType>::fromWireType(wireThis),
341
internal::BindingType<Args>::fromWireType(args)...);
345
template<typename MemberPointer,
349
struct MethodInvoker {
350
static typename internal::BindingType<ReturnType>::WireType invoke(
351
const MemberPointer& method,
352
typename internal::BindingType<ThisType>::WireType wireThis,
353
typename internal::BindingType<Args>::WireType... args
355
return internal::BindingType<ReturnType>::toWireType(
356
(internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
357
internal::BindingType<Args>::fromWireType(args)...
363
template<typename MemberPointer,
366
struct MethodInvoker<MemberPointer, void, ThisType, Args...> {
368
const MemberPointer& method,
369
typename internal::BindingType<ThisType>::WireType wireThis,
370
typename internal::BindingType<Args>::WireType... args
372
return (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
373
internal::BindingType<Args>::fromWireType(args)...
378
template<typename InstanceType, typename MemberType>
379
struct MemberAccess {
380
typedef MemberType InstanceType::*MemberPointer;
381
typedef internal::BindingType<MemberType> MemberBinding;
382
typedef typename MemberBinding::WireType WireType;
384
template<typename ClassType>
385
static WireType getWire(
386
const MemberPointer& field,
389
return MemberBinding::toWireType(ptr.*field);
392
template<typename ClassType>
394
const MemberPointer& field,
398
ptr.*field = MemberBinding::fromWireType(value);
402
// TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
404
inline void* getContext(const T& t) {
405
// not a leak because this is called once per binding
406
void* p = malloc(sizeof(T));
408
memcpy(p, &t, sizeof(T));
415
template<typename GetterReturnType, typename GetterThisType>
416
struct GetterPolicy<GetterReturnType (GetterThisType::*)() const> {
417
typedef GetterReturnType ReturnType;
418
typedef GetterReturnType (GetterThisType::*Context)() const;
420
typedef internal::BindingType<ReturnType> Binding;
421
typedef typename Binding::WireType WireType;
423
template<typename ClassType>
424
static WireType get(const Context& context, const ClassType& ptr) {
425
return Binding::toWireType((ptr.*context)());
428
static void* getContext(Context context) {
429
return internal::getContext(context);
433
template<typename GetterReturnType, typename GetterThisType>
434
struct GetterPolicy<GetterReturnType (*)(const GetterThisType&)> {
435
typedef GetterReturnType ReturnType;
436
typedef GetterReturnType (*Context)(const GetterThisType&);
438
typedef internal::BindingType<ReturnType> Binding;
439
typedef typename Binding::WireType WireType;
441
template<typename ClassType>
442
static WireType get(const Context& context, const ClassType& ptr) {
443
return Binding::toWireType(context(ptr));
446
static void* getContext(Context context) {
447
return internal::getContext(context);
454
template<typename SetterThisType, typename SetterArgumentType>
455
struct SetterPolicy<void (SetterThisType::*)(SetterArgumentType)> {
456
typedef SetterArgumentType ArgumentType;
457
typedef void (SetterThisType::*Context)(SetterArgumentType);
459
typedef internal::BindingType<SetterArgumentType> Binding;
460
typedef typename Binding::WireType WireType;
462
template<typename ClassType>
463
static void set(const Context& context, ClassType& ptr, WireType wt) {
464
(ptr.*context)(Binding::fromWireType(wt));
467
static void* getContext(Context context) {
468
return internal::getContext(context);
472
template<typename SetterThisType, typename SetterArgumentType>
473
struct SetterPolicy<void (*)(SetterThisType&, SetterArgumentType)> {
474
typedef SetterArgumentType ArgumentType;
475
typedef void (*Context)(SetterThisType&, SetterArgumentType);
477
typedef internal::BindingType<SetterArgumentType> Binding;
478
typedef typename Binding::WireType WireType;
480
template<typename ClassType>
481
static void set(const Context& context, ClassType& ptr, WireType wt) {
482
context(ptr, Binding::fromWireType(wt));
485
static void* getContext(Context context) {
486
return internal::getContext(context);
495
noncopyable(const noncopyable&) = delete;
496
const noncopyable& operator=(const noncopyable&) = delete;
499
template<typename ClassType, typename ElementType>
500
typename BindingType<ElementType>::WireType get_by_index(int index, ClassType& ptr) {
501
return BindingType<ElementType>::toWireType(ptr[index]);
504
template<typename ClassType, typename ElementType>
505
void set_by_index(int index, ClassType& ptr, typename BindingType<ElementType>::WireType wt) {
506
ptr[index] = BindingType<ElementType>::fromWireType(wt);
514
////////////////////////////////////////////////////////////////////////////////
516
////////////////////////////////////////////////////////////////////////////////
518
template<typename ClassType>
519
class value_tuple : public internal::noncopyable {
521
value_tuple(const char* name) {
522
using namespace internal;
523
_embind_register_tuple(
524
TypeID<ClassType>::get(),
526
reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
527
reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
531
using namespace internal;
532
_embind_finalize_tuple(TypeID<ClassType>::get());
535
template<typename InstanceType, typename ElementType>
536
value_tuple& element(ElementType InstanceType::*field) {
537
using namespace internal;
538
_embind_register_tuple_element(
539
TypeID<ClassType>::get(),
540
TypeID<ElementType>::get(),
541
reinterpret_cast<GenericFunction>(
542
&MemberAccess<InstanceType, ElementType>
543
::template getWire<ClassType>),
545
TypeID<ElementType>::get(),
546
reinterpret_cast<GenericFunction>(
547
&MemberAccess<InstanceType, ElementType>
548
::template setWire<ClassType>),
553
template<typename Getter, typename Setter>
554
value_tuple& element(Getter getter, Setter setter) {
555
using namespace internal;
556
typedef GetterPolicy<Getter> GP;
557
typedef SetterPolicy<Setter> SP;
558
_embind_register_tuple_element(
559
TypeID<ClassType>::get(),
560
TypeID<typename GP::ReturnType>::get(),
561
reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
562
GP::getContext(getter),
563
TypeID<typename SP::ArgumentType>::get(),
564
reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
565
SP::getContext(setter));
570
value_tuple& element(index<Index>) {
571
using namespace internal;
573
typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
574
_embind_register_tuple_element(
575
TypeID<ClassType>::get(),
576
TypeID<ElementType>::get(),
577
reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>),
578
reinterpret_cast<void*>(Index),
579
TypeID<ElementType>::get(),
580
reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>),
581
reinterpret_cast<void*>(Index));
586
////////////////////////////////////////////////////////////////////////////////
588
////////////////////////////////////////////////////////////////////////////////
590
template<typename ClassType>
591
class value_struct : public internal::noncopyable {
593
value_struct(const char* name) {
594
using namespace internal;
595
_embind_register_struct(
596
TypeID<ClassType>::get(),
598
reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
599
reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
603
_embind_finalize_struct(internal::TypeID<ClassType>::get());
606
template<typename InstanceType, typename FieldType>
607
value_struct& field(const char* fieldName, FieldType InstanceType::*field) {
608
using namespace internal;
609
_embind_register_struct_field(
610
TypeID<ClassType>::get(),
612
TypeID<FieldType>::get(),
613
reinterpret_cast<GenericFunction>(
614
&MemberAccess<InstanceType, FieldType>
615
::template getWire<ClassType>),
617
TypeID<FieldType>::get(),
618
reinterpret_cast<GenericFunction>(
619
&MemberAccess<InstanceType, FieldType>
620
::template setWire<ClassType>),
625
template<typename Getter, typename Setter>
627
const char* fieldName,
631
using namespace internal;
632
typedef GetterPolicy<Getter> GP;
633
typedef SetterPolicy<Setter> SP;
634
_embind_register_struct_field(
635
TypeID<ClassType>::get(),
637
TypeID<typename GP::ReturnType>::get(),
638
reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
639
GP::getContext(getter),
640
TypeID<typename SP::ArgumentType>::get(),
641
reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
642
SP::getContext(setter));
647
value_struct& field(const char* fieldName, index<Index>) {
648
using namespace internal;
650
typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
651
_embind_register_struct_field(
652
TypeID<ClassType>::get(),
654
TypeID<ElementType>::get(),
655
reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>),
656
reinterpret_cast<void*>(Index),
657
TypeID<ElementType>::get(),
658
reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>),
659
reinterpret_cast<void*>(Index));
664
////////////////////////////////////////////////////////////////////////////////
666
////////////////////////////////////////////////////////////////////////////////
668
template<typename PointerType>
669
struct default_smart_ptr_trait {
670
static sharing_policy get_sharing_policy() {
671
return sharing_policy::NONE;
674
static void* share(void* v) {
675
return 0; // no sharing
679
// specialize if you have a different pointer type
680
template<typename PointerType>
681
struct smart_ptr_trait : public default_smart_ptr_trait<PointerType> {
682
typedef typename PointerType::element_type element_type;
684
static element_type* get(const PointerType& ptr) {
689
template<typename PointeeType>
690
struct smart_ptr_trait<std::shared_ptr<PointeeType>> {
691
typedef std::shared_ptr<PointeeType> PointerType;
692
typedef typename PointerType::element_type element_type;
694
static element_type* get(const PointerType& ptr) {
698
static sharing_policy get_sharing_policy() {
699
return sharing_policy::BY_EMVAL;
702
static std::shared_ptr<PointeeType>* share(PointeeType* p, internal::EM_VAL v) {
703
return new std::shared_ptr<PointeeType>(
705
val_deleter(val::take_ownership(v)));
711
val_deleter() = delete;
712
explicit val_deleter(val v)
715
void operator()(void const*) {
717
// eventually we'll need to support emptied out val
718
v = val::undefined();
725
////////////////////////////////////////////////////////////////////////////////
727
////////////////////////////////////////////////////////////////////////////////
731
class wrapper : public T {
733
explicit wrapper(val&& wrapped)
734
: wrapped(std::forward<val>(wrapped))
737
template<typename ReturnType, typename... Args>
738
ReturnType call(const char* name, Args&&... args) const {
739
return Caller<ReturnType, Args...>::call(wrapped, name, std::forward<Args>(args)...);
742
template<typename ReturnType, typename... Args, typename Default>
743
ReturnType optional_call(const char* name, Default def, Args&&... args) const {
744
if (has_function(name)) {
745
return Caller<ReturnType, Args...>::call(wrapped, name, std::forward<Args>(args)...);
752
bool has_function(const char* name) const {
753
return wrapped.has_function(name);
756
// this class only exists because you can't partially specialize function templates
757
template<typename ReturnType, typename... Args>
759
static ReturnType call(const val& v, const char* name, Args&&... args) {
760
return v.call(name, std::forward<Args>(args)...).template as<ReturnType>();
764
template<typename... Args>
765
struct Caller<void, Args...> {
766
static void call(const val& v, const char* name, Args&&... args) {
767
v.call_void(name, std::forward<Args>(args)...);
774
#define EMSCRIPTEN_WRAPPER(T) \
775
T(::emscripten::val&& v): wrapper(std::forward<::emscripten::val>(v)) {}
779
template<typename ClassType>
780
static void verify() {
783
static TYPEID get() {
787
template<typename ClassType>
788
static GenericFunction getUpcaster() {
792
template<typename ClassType>
793
static GenericFunction getDowncaster() {
798
// NOTE: this returns the class type, not the pointer type
800
inline TYPEID getActualType(T* ptr) {
802
return reinterpret_cast<TYPEID>(&typeid(*ptr));
806
template<typename BaseClass>
808
template<typename ClassType>
809
static void verify() {
810
static_assert(!std::is_same<ClassType, BaseClass>::value, "Base must not have same type as class");
811
static_assert(std::is_base_of<BaseClass, ClassType>::value, "Derived class must derive from base");
814
static internal::TYPEID get() {
815
return internal::TypeID<BaseClass>::get();
818
template<typename ClassType>
819
static internal::GenericFunction getUpcaster() {
820
return reinterpret_cast<internal::GenericFunction>(&convertPointer<ClassType, BaseClass>);
823
template<typename ClassType>
824
static internal::GenericFunction getDowncaster() {
825
return reinterpret_cast<internal::GenericFunction>(&convertPointer<BaseClass, ClassType>);
828
template<typename From, typename To>
829
static To* convertPointer(From* ptr) {
830
return static_cast<To*>(ptr);
834
template<typename PointerType>
836
typedef PointerType pointer_type;
842
enum { value = false };
846
struct is_ptr<ptr<T>> {
847
enum { value = true };
851
struct SmartPtrIfNeeded {
853
SmartPtrIfNeeded(U& cls) {
854
cls.template smart_ptr<T>();
859
struct SmartPtrIfNeeded<T*> {
861
SmartPtrIfNeeded(U&) {
866
template<typename ClassType, typename BaseSpecifier = internal::NoBaseClass>
871
template<typename = typename std::enable_if<!internal::is_ptr<ClassType>::value>::type>
872
explicit class_(const char* name) {
873
using namespace internal;
875
BaseSpecifier::template verify<ClassType>();
877
_embind_register_class(
878
TypeID<ClassType>::get(),
879
TypeID<AllowedRawPointer<ClassType>>::get(),
880
TypeID<AllowedRawPointer<const ClassType>>::get(),
881
BaseSpecifier::get(),
882
reinterpret_cast<GenericFunction>(&getActualType<ClassType>),
883
BaseSpecifier::template getUpcaster<ClassType>(),
884
BaseSpecifier::template getDowncaster<ClassType>(),
886
reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
889
template<typename PointerType>
890
class_& smart_ptr() {
891
using namespace internal;
893
typedef smart_ptr_trait<PointerType> PointerTrait;
894
typedef typename PointerTrait::element_type PointeeType;
896
static_assert(std::is_same<ClassType, typename std::remove_cv<PointeeType>::type>::value, "smart pointer must point to this class");
898
_embind_register_smart_ptr(
899
TypeID<PointerType>::get(),
900
TypeID<PointeeType>::get(),
901
typeid(PointerType).name(),
902
PointerTrait::get_sharing_policy(),
903
reinterpret_cast<GenericFunction>(&PointerTrait::get),
904
reinterpret_cast<GenericFunction>(&operator_new<PointerType>),
905
reinterpret_cast<GenericFunction>(&PointerTrait::share),
906
reinterpret_cast<GenericFunction>(&raw_destructor<PointerType>));
910
template<typename... ConstructorArgs, typename... Policies>
911
class_& constructor(Policies... policies) {
913
&internal::operator_new<ClassType, ConstructorArgs...>,
917
template<typename... Args, typename... Policies>
918
class_& constructor(ClassType* (*factory)(Args...), Policies...) {
919
using namespace internal;
921
typename WithPolicies<Policies...>::template ArgTypeList<AllowedRawPointer<ClassType>, Args...> args;
922
_embind_register_class_constructor(
923
TypeID<ClassType>::get(),
926
reinterpret_cast<GenericFunction>(&Invoker<ClassType*, Args...>::invoke),
927
reinterpret_cast<GenericFunction>(factory));
931
template<typename SmartPtr, typename... Args, typename... Policies>
932
class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) {
933
using namespace internal;
935
smart_ptr<SmartPtr>();
937
typename WithPolicies<Policies...>::template ArgTypeList<SmartPtr, Args...> args;
938
_embind_register_class_constructor(
939
TypeID<ClassType>::get(),
942
reinterpret_cast<GenericFunction>(&Invoker<SmartPtr, Args...>::invoke),
943
reinterpret_cast<GenericFunction>(factory));
947
template<typename WrapperType, typename PointerType = WrapperType*>
948
class_& allow_subclass() {
949
using namespace internal;
951
auto cls = class_<WrapperType, base<ClassType>>(typeid(WrapperType).name())
953
SmartPtrIfNeeded<PointerType> _(cls);
955
return class_function(
957
&wrapped_new<PointerType, WrapperType, val>,
958
allow_raw_pointer<ret_val>());
961
template<typename ReturnType, typename... Args, typename... Policies>
962
class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) {
963
using namespace internal;
965
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args;
966
_embind_register_class_function(
967
TypeID<ClassType>::get(),
971
reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke),
972
getContext(memberFunction));
976
template<typename ReturnType, typename... Args, typename... Policies>
977
class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) {
978
using namespace internal;
980
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args;
981
_embind_register_class_function(
982
TypeID<ClassType>::get(),
986
reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke),
987
getContext(memberFunction));
991
template<typename ReturnType, typename ThisType, typename... Args, typename... Policies>
992
class_& function(const char* methodName, ReturnType (*function)(ThisType, Args...), Policies...) {
993
using namespace internal;
995
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args;
996
_embind_register_class_function(
997
TypeID<ClassType>::get(),
1001
reinterpret_cast<GenericFunction>(&FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>::invoke),
1002
getContext(function));
1006
template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
1007
class_& property(const char* fieldName, const FieldType ClassType::*field) {
1008
using namespace internal;
1010
_embind_register_class_property(
1011
TypeID<ClassType>::get(),
1013
TypeID<FieldType>::get(),
1014
reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>),
1022
template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
1023
class_& property(const char* fieldName, FieldType ClassType::*field) {
1024
using namespace internal;
1026
_embind_register_class_property(
1027
TypeID<ClassType>::get(),
1029
TypeID<FieldType>::get(),
1030
reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>),
1032
TypeID<FieldType>::get(),
1033
reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template setWire<ClassType>),
1038
template<typename Getter>
1039
class_& property(const char* fieldName, Getter getter) {
1040
using namespace internal;
1041
typedef GetterPolicy<Getter> GP;
1042
_embind_register_class_property(
1043
TypeID<ClassType>::get(),
1045
TypeID<typename GP::ReturnType>::get(),
1046
reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
1047
GP::getContext(getter),
1054
template<typename Getter, typename Setter>
1055
class_& property(const char* fieldName, Getter getter, Setter setter) {
1056
using namespace internal;
1057
typedef GetterPolicy<Getter> GP;
1058
typedef SetterPolicy<Setter> SP;
1059
_embind_register_class_property(
1060
TypeID<ClassType>::get(),
1062
TypeID<typename GP::ReturnType>::get(),
1063
reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
1064
GP::getContext(getter),
1065
TypeID<typename SP::ArgumentType>::get(),
1066
reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
1067
SP::getContext(setter));
1071
template<typename ReturnType, typename... Args, typename... Policies>
1072
class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) {
1073
using namespace internal;
1075
typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
1076
_embind_register_class_class_function(
1077
TypeID<ClassType>::get(),
1081
reinterpret_cast<internal::GenericFunction>(&internal::Invoker<ReturnType, Args...>::invoke),
1082
reinterpret_cast<GenericFunction>(classMethod));
1087
////////////////////////////////////////////////////////////////////////////////
1089
////////////////////////////////////////////////////////////////////////////////
1091
namespace internal {
1092
template<typename VectorType>
1093
struct VectorAccess {
1095
const VectorType& v,
1096
typename VectorType::size_type index
1098
if (index < v.size()) {
1099
return val(v[index]);
1101
return val::undefined();
1107
typename VectorType::size_type index,
1108
const typename VectorType::value_type& value
1116
template<typename T>
1117
class_<std::vector<T>> register_vector(const char* name) {
1118
typedef std::vector<T> VecType;
1120
void (VecType::*push_back)(const T&) = &VecType::push_back;
1121
return class_<std::vector<T>>(name)
1122
.template constructor<>()
1123
.function("push_back", push_back)
1124
.function("size", &VecType::size)
1125
.function("get", &internal::VectorAccess<VecType>::get)
1126
.function("set", &internal::VectorAccess<VecType>::set)
1130
////////////////////////////////////////////////////////////////////////////////
1132
////////////////////////////////////////////////////////////////////////////////
1134
namespace internal {
1135
template<typename MapType>
1139
const typename MapType::key_type& k
1143
return val::undefined();
1145
return val(i->second);
1151
const typename MapType::key_type& k,
1152
const typename MapType::mapped_type& v
1159
template<typename K, typename V>
1160
class_<std::map<K, V>> register_map(const char* name) {
1161
typedef std::map<K,V> MapType;
1163
return class_<MapType>(name)
1164
.template constructor<>()
1165
.function("size", &MapType::size)
1166
.function("get", internal::MapAccess<MapType>::get)
1167
.function("set", internal::MapAccess<MapType>::set)
1172
////////////////////////////////////////////////////////////////////////////////
1174
////////////////////////////////////////////////////////////////////////////////
1176
template<typename EnumType>
1179
enum_(const char* name) {
1180
_embind_register_enum(
1181
internal::TypeID<EnumType>::get(),
1185
enum_& value(const char* name, EnumType value) {
1186
// TODO: there's still an issue here.
1187
// if EnumType is an unsigned long, then JS may receive it as a signed long
1188
static_assert(sizeof(value) <= sizeof(internal::GenericEnumValue), "enum type must fit in a GenericEnumValue");
1190
_embind_register_enum_value(
1191
internal::TypeID<EnumType>::get(),
1193
static_cast<internal::GenericEnumValue>(value));
1198
////////////////////////////////////////////////////////////////////////////////
1200
////////////////////////////////////////////////////////////////////////////////
1202
namespace internal {
1203
template<typename T>
1204
uintptr_t asGenericValue(T t) {
1205
return static_cast<uintptr_t>(t);
1208
template<typename T>
1209
uintptr_t asGenericValue(T* p) {
1210
return reinterpret_cast<uintptr_t>(p);
1214
template<typename ConstantType>
1215
void constant(const char* name, const ConstantType& v) {
1216
using namespace internal;
1217
typedef BindingType<const ConstantType&> BT;
1218
_embind_register_constant(
1220
TypeID<const ConstantType&>::get(),
1221
asGenericValue(BindingType<const ConstantType&>::toWireType(v)));
1224
namespace internal {
1225
template<typename T>
1229
: initialized(false)
1238
optional(const optional& rhs)
1239
: initialized(false)
1245
assert(initialized);
1249
const T& operator*() const {
1250
assert(initialized);
1254
explicit operator bool() const {
1258
optional& operator=(const T& v) {
1267
optional& operator=(const optional& o) {
1271
if (o.initialized) {
1274
initialized = o.initialized;
1280
return reinterpret_cast<T*>(&data);
1283
T const* get() const {
1284
return reinterpret_cast<T const*>(&data);
1288
typename std::aligned_storage<sizeof(T)>::type data;
1293
namespace emscripten {
1294
namespace internal {
1295
class BindingsDefinition {
1297
template<typename Function>
1298
BindingsDefinition(Function fn) {
1305
#define EMSCRIPTEN_BINDINGS(name) \
1306
static struct BindingInitializer_##name { \
1307
BindingInitializer_##name(); \
1308
} BindingInitializer_##name##_instance; \
1309
BindingInitializer_##name::BindingInitializer_##name()