diff options
Diffstat (limited to 'system')
-rw-r--r-- | system/include/emscripten/bind.h | 129 | ||||
-rw-r--r-- | system/include/emscripten/wire.h | 115 |
2 files changed, 187 insertions, 57 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 69d1f08c..f2e70b31 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -165,6 +165,27 @@ namespace emscripten { } namespace emscripten { + //////////////////////////////////////////////////////////////////////////////// + // POLICIES + //////////////////////////////////////////////////////////////////////////////// + + template<int Index> + struct arg { + static constexpr int index = Index; + }; + + template<typename Slot> + struct allow_raw_pointer { + template<typename InputType, int Index> + struct Transform { + typedef typename std::conditional< + Index == Slot::index, + internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>, + InputType + >::type type; + }; + }; + namespace internal { template<typename ReturnType, typename... Args> struct Invoker { @@ -193,6 +214,10 @@ namespace emscripten { }; } + //////////////////////////////////////////////////////////////////////////////// + // FUNCTIONS + //////////////////////////////////////////////////////////////////////////////// + template<typename ReturnType, typename... Args> void function(const char* name, ReturnType (fn)(Args...)) { internal::registerStandardTypes(); @@ -328,6 +353,10 @@ namespace emscripten { }; } + //////////////////////////////////////////////////////////////////////////////// + // VALUE TUPLES + //////////////////////////////////////////////////////////////////////////////// + template<typename ClassType> class value_tuple { public: @@ -410,6 +439,10 @@ namespace emscripten { } }; + //////////////////////////////////////////////////////////////////////////////// + // VALUE STRUCTS + //////////////////////////////////////////////////////////////////////////////// + template<typename ClassType> class value_struct { public: @@ -437,6 +470,10 @@ namespace emscripten { } }; + //////////////////////////////////////////////////////////////////////////////// + // SMART POINTERS + //////////////////////////////////////////////////////////////////////////////// + template<typename PointerType> inline void register_smart_ptr(const char* name) { typedef typename PointerType::element_type PointeeType; @@ -450,55 +487,67 @@ namespace emscripten { reinterpret_cast<internal::GenericFunction>(&internal::get_pointee<PointerType>)); } + //////////////////////////////////////////////////////////////////////////////// + // CLASSES + //////////////////////////////////////////////////////////////////////////////// + // TODO: support class definitions without constructors. // TODO: support external class constructors template<typename ClassType> class class_ { public: class_(const char* name) { - internal::registerStandardTypes(); - internal::_embind_register_class( - internal::TypeID<ClassType>::get(), + using namespace internal; + + registerStandardTypes(); + _embind_register_class( + TypeID<ClassType>::get(), name, - reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<ClassType>)); + reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); } template<typename... ConstructorArgs> class_& constructor() { - internal::ArgTypeList<ConstructorArgs...> args; - internal::_embind_register_class_constructor( - internal::TypeID<ClassType>::get(), + using namespace internal; + + ArgTypeList<ConstructorArgs...> args; + _embind_register_class_constructor( + TypeID<ClassType>::get(), args.count, args.types, - reinterpret_cast<internal::GenericFunction>(&internal::raw_constructor<ClassType, ConstructorArgs...>)); + reinterpret_cast<GenericFunction>(&raw_constructor<ClassType, ConstructorArgs...>)); return *this; } - template<typename ReturnType, typename... Args> - class_& method(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...)) { - internal::ArgTypeList<Args...> args; - internal::_embind_register_class_method( - internal::TypeID<ClassType>::get(), + template<typename ReturnType, typename... Args, typename... Policies> + class_& method(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) { + using namespace internal; + + typename WithPolicies<Policies...>::template ArgTypeList<Args...> args; + _embind_register_class_method( + TypeID<ClassType>::get(), methodName, - internal::TypeID<ReturnType>::get(), + TypeID<ReturnType>::get(), args.count, args.types, - reinterpret_cast<internal::GenericFunction>(&internal::MethodInvoker<ClassType, ReturnType, Args...>::invoke), + reinterpret_cast<GenericFunction>(&MethodInvoker<ClassType, ReturnType, Args...>::invoke), sizeof(memberFunction), &memberFunction); return *this; } - template<typename ReturnType, typename... Args> - class_& method(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const) { - internal::ArgTypeList<Args...> args; - internal::_embind_register_class_method( - internal::TypeID<ClassType>::get(), + template<typename ReturnType, typename... Args, typename... Policies> + class_& method(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) { + using namespace internal; + + typename WithPolicies<Policies...>::template ArgTypeList<Args...> args; + _embind_register_class_method( + TypeID<ClassType>::get(), methodName, - internal::TypeID<ReturnType>::get(), + TypeID<ReturnType>::get(), args.count, args.types, - reinterpret_cast<internal::GenericFunction>(&internal::ConstMethodInvoker<ClassType, ReturnType, Args...>::invoke), + reinterpret_cast<GenericFunction>(&ConstMethodInvoker<ClassType, ReturnType, Args...>::invoke), sizeof(memberFunction), &memberFunction); return *this; @@ -506,31 +555,39 @@ namespace emscripten { template<typename FieldType> class_& field(const char* fieldName, FieldType ClassType::*field) { - internal::_embind_register_class_field( - internal::TypeID<ClassType>::get(), + using namespace internal; + + _embind_register_class_field( + TypeID<ClassType>::get(), fieldName, - internal::TypeID<FieldType>::get(), - reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, FieldType>::get), - reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, FieldType>::set), + TypeID<FieldType>::get(), + reinterpret_cast<GenericFunction>(&FieldAccess<ClassType, FieldType>::get), + reinterpret_cast<GenericFunction>(&FieldAccess<ClassType, FieldType>::set), sizeof(field), &field); return *this; } - template<typename ReturnType, typename... Args> - class_& classmethod(const char* methodName, ReturnType (*classMethod)(Args...)) { - internal::ArgTypeList<Args...> args; - internal::_embind_register_class_classmethod( - internal::TypeID<ClassType>::get(), + template<typename ReturnType, typename... Args, typename... Policies> + class_& classmethod(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) { + using namespace internal; + + typename WithPolicies<Policies...>::template ArgTypeList<Args...> args; + _embind_register_class_classmethod( + TypeID<ClassType>::get(), methodName, - internal::TypeID<ReturnType>::get(), + TypeID<ReturnType>::get(), args.count, args.types, - reinterpret_cast<internal::GenericFunction>(classMethod)); + reinterpret_cast<GenericFunction>(classMethod)); return *this; } }; + //////////////////////////////////////////////////////////////////////////////// + // ENUMS + //////////////////////////////////////////////////////////////////////////////// + template<typename EnumType> class enum_ { public: @@ -597,6 +654,10 @@ namespace emscripten { }; } + //////////////////////////////////////////////////////////////////////////////// + // INTERFACES + //////////////////////////////////////////////////////////////////////////////// + template<typename InterfaceType> class wrapper : public InterfaceType { public: diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index ceabd280..ba78906b 100644 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -11,12 +11,19 @@ namespace emscripten { namespace internal { typedef const struct _TYPEID* TYPEID; + extern "C" { + void _embind_register_raw_pointer( + TYPEID pointee, + TYPEID pointer); + } + // This implementation is technically not legal, as it's not // required that two calls to typeid produce the same exact - // std::type_info instance. That said, it's likely to work. - // Should it not work in the future: replace TypeID with - // an int, and store all TypeInfo we see in a map, allocating - // new TypeIDs as we add new items to the map. + // std::type_info instance. That said, it's likely to work + // given Emscripten compiles everything into one binary. + // Should it not work in the future: replace TypeID with an + // int, and store all TypeInfo we see in a map, allocating new + // TypeIDs as we add new items to the map. template<typename T> struct TypeID { static TYPEID get() { @@ -30,6 +37,24 @@ namespace emscripten { return TypeID<T>::get(); } }; + + template<typename T> + struct TypeID<T*> { + static_assert(!std::is_pointer<T*>::value, "Implicitly binding raw pointers is illegal. Specify ???"); + }; + + template<typename T> + struct AllowedRawPointer { + }; + + template<typename T> + struct TypeID<AllowedRawPointer<T>> { + static TYPEID get() { + TYPEID ptype = reinterpret_cast<TYPEID>(&typeid(T*)); + _embind_register_raw_pointer(TypeID<T>::get(), ptype); + return ptype; + } + }; // count<> @@ -38,44 +63,81 @@ namespace emscripten { template<> struct count<> { - enum { value = 0 }; + constexpr static unsigned value = 0; }; template<typename T, typename... Args> struct count<T, Args...> { - enum { value = 1 + count<Args...>::value }; + constexpr static unsigned value = 1 + count<Args...>::value; }; - // ArgTypeList<> + // ExecutePolicies<> - template<typename... Args> - struct ArgTypes; + template<typename... Policies> + struct ExecutePolicies; template<> - struct ArgTypes<> { + struct ExecutePolicies<> { + template<typename T, int Index> + struct With { + typedef T type; + }; + }; + + template<typename Policy, typename... Remaining> + struct ExecutePolicies<Policy, Remaining...> { + template<typename T, int Index> + struct With { + typedef typename Policy::template Transform< + typename ExecutePolicies<Remaining...>::template With<T, Index>::type, + Index + >::type type; + }; + }; + + // ArgTypes<> + + template<int Index, typename... Args> + struct ArgTypes; + + template<int Index> + struct ArgTypes<Index> { + template<typename... Policies> static void fill(TYPEID* argTypes) { } }; - template<typename T, typename... Args> - struct ArgTypes<T, Args...> { + template<int Index, typename T, typename... Remaining> + struct ArgTypes<Index, T, Remaining...> { + template<typename... Policies> static void fill(TYPEID* argTypes) { - *argTypes = TypeID<T>::get(); - return ArgTypes<Args...>::fill(argTypes + 1); + typedef typename ExecutePolicies<Policies...>::template With<T, Index>::type TransformT; + + *argTypes = TypeID<TransformT>::get(); + return ArgTypes<Index + 1, Remaining...>::fill(argTypes + 1); } }; - template<typename... Args> - struct ArgTypeList { - enum { args_count = count<Args...>::value }; + // WithPolicies<...>::ArgTypeList<...> + template<typename... Policies> + struct WithPolicies { + template<typename... Args> + struct ArgTypeList { + enum { args_count = count<Args...>::value }; - ArgTypeList() { - count = args_count; - ArgTypes<Args...>::fill(types); - } + ArgTypeList() { + count = args_count; + ArgTypes<0, Args...>::template fill<Policies...>(types); + } - unsigned count; - TYPEID types[args_count]; + unsigned count; + TYPEID types[args_count]; + }; + }; + + // TODO: kill this and make every signature support policies + template<typename... Args> + struct ArgTypeList : WithPolicies<>::ArgTypeList<Args...> { }; // BindingType<T> @@ -149,6 +211,13 @@ namespace emscripten { } }; + template<typename T> + struct BindingType<T*>; + + template<typename T> + struct BindingType<AllowedRawPointer<T>> { + }; + template<typename Enum> struct EnumBindingType { typedef Enum WireType; |