diff options
author | Chad Austin <chad@chadaustin.me> | 2012-11-01 19:33:42 -0700 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-12 14:21:35 +0300 |
commit | 8691fb1726c63263f99e86b8dd29d1a90d639579 (patch) | |
tree | 30a1b6e2b314e25cd17a8b42145bd5aff5d5b613 | |
parent | 6014feed714b61f57f26254de6a2d2c7d89363e5 (diff) |
Allow multiple pointer arguments and allow multiple functions taking the same raw pointer type
-rw-r--r-- | src/embind/embind.js | 32 | ||||
-rw-r--r-- | system/include/emscripten/bind.h | 38 | ||||
-rw-r--r-- | system/include/emscripten/val.h | 62 | ||||
-rw-r--r-- | system/include/emscripten/wire.h | 19 |
4 files changed, 84 insertions, 67 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index 8cfb87c8..bbbeb96c 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -420,22 +420,10 @@ function __embind_register_smart_ptr( }); } -function __embind_register_raw_pointer( - pointeeType, - pointerType -) { - pointeeType = requireRegisteredType(pointeeType, 'class'); - var name = pointeeType.name + '*'; - registerType(pointerType, name, { - name: name, - toWireType: function(destructors, o) { - return o.ptr; - } - }); -} - function __embind_register_class( classType, + pointerType, + constPointerType, name, destructor ) { @@ -496,6 +484,22 @@ function __embind_register_class( } }); + var pointerName = name + '*'; + registerType(pointerType, pointerName, { + name: pointerName, + toWireType: function(destructors, o) { + return o.ptr; + } + }); + + var constPointerName = name + ' const*'; + registerType(constPointerType, constPointerName, { + name: constPointerName, + toWireType: function(destructors, o) { + return o.ptr; + } + }); + exposePublicSymbol(name, constructor); } diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index e48be414..9bfef10b 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -100,6 +100,8 @@ namespace emscripten { void _embind_register_class( TYPEID classType, + TYPEID pointerType, + TYPEID constPointerType, const char* className, GenericFunction destructor); @@ -187,6 +189,18 @@ namespace emscripten { }; }; + // whitelist all raw pointers + struct allow_raw_pointers { + template<typename InputType, int Index> + struct Transform { + typedef typename std::conditional< + std::is_pointer<InputType>::value, + internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>, + InputType + >::type type; + }; + }; + namespace internal { template<typename ReturnType, typename... Args> struct Invoker { @@ -219,18 +233,20 @@ namespace emscripten { // FUNCTIONS //////////////////////////////////////////////////////////////////////////////// - template<typename ReturnType, typename... Args> + template<typename ReturnType, typename... Args, typename... Policies> void function(const char* name, ReturnType (fn)(Args...)) { - internal::registerStandardTypes(); + using namespace internal; + + registerStandardTypes(); - internal::ArgTypeList<Args...> args; - internal::_embind_register_function( + typename WithPolicies<Policies...>::template ArgTypeList<Args...> args; + _embind_register_function( name, - internal::TypeID<ReturnType>::get(), + TypeID<ReturnType>::get(), args.count, args.types, - reinterpret_cast<internal::GenericFunction>(&internal::Invoker<ReturnType, Args...>::invoke), - reinterpret_cast<internal::GenericFunction>(fn)); + reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke), + reinterpret_cast<GenericFunction>(fn)); } namespace internal { @@ -503,15 +519,17 @@ namespace emscripten { registerStandardTypes(); _embind_register_class( TypeID<ClassType>::get(), + TypeID<AllowedRawPointer<ClassType>>::get(), + TypeID<AllowedRawPointer<const ClassType>>::get(), name, reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); } - template<typename... ConstructorArgs> - class_& constructor() { + template<typename... ConstructorArgs, typename... Policies> + class_& constructor(Policies...) { using namespace internal; - ArgTypeList<ConstructorArgs...> args; + typename WithPolicies<Policies...>::template ArgTypeList<ConstructorArgs...> args; _embind_register_class_constructor( TypeID<ClassType>::get(), args.count, diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h index 8369caf7..e3e57901 100644 --- a/system/include/emscripten/val.h +++ b/system/include/emscripten/val.h @@ -19,7 +19,7 @@ namespace emscripten { EM_VAL _emval_get_property_by_unsigned_long(EM_VAL object, unsigned long key); void _emval_set_property(EM_VAL object, const char* key, EM_VAL value); void _emval_set_property_by_int(EM_VAL object, long key, EM_VAL value); - void _emval_as(EM_VAL value, emscripten::internal::TYPEID returnType); + void _emval_as(EM_VAL value, TYPEID returnType); EM_VAL _emval_call( EM_VAL value, unsigned argCount, @@ -108,69 +108,77 @@ namespace emscripten { template<typename ...Args> val operator()(Args... args) { - internal::ArgTypeList<Args...> argList; - typedef internal::EM_VAL (*TypedCall)( - internal::EM_VAL, + using namespace internal; + + WithPolicies<>::ArgTypeList<Args...> argList; + typedef EM_VAL (*TypedCall)( + EM_VAL, unsigned, - internal::TYPEID argTypes[], - typename internal::BindingType<Args>::WireType...); - TypedCall typedCall = reinterpret_cast<TypedCall>(&internal::_emval_call); + TYPEID argTypes[], + typename BindingType<Args>::WireType...); + TypedCall typedCall = reinterpret_cast<TypedCall>(&_emval_call); return val( typedCall( handle, argList.count, argList.types, - internal::toWireType(args)...)); + toWireType(args)...)); } template<typename ...Args> val call(const char* name, Args... args) { - internal::ArgTypeList<Args...> argList; - typedef internal::EM_VAL (*TypedCall)( - internal::EM_VAL, + using namespace internal; + + WithPolicies<>::ArgTypeList<Args...> argList; + typedef EM_VAL (*TypedCall)( + EM_VAL, const char* name, unsigned, - internal::TYPEID argTypes[], - typename internal::BindingType<Args>::WireType...); - TypedCall typedCall = reinterpret_cast<TypedCall>(&internal::_emval_call_method); + TYPEID argTypes[], + typename BindingType<Args>::WireType...); + TypedCall typedCall = reinterpret_cast<TypedCall>(&_emval_call_method); return val( typedCall( handle, name, argList.count, argList.types, - internal::toWireType(args)...)); + toWireType(args)...)); } template<typename ...Args> void call_void(const char* name, Args... args) { - internal::ArgTypeList<Args...> argList; + using namespace internal; + + WithPolicies<>::ArgTypeList<Args...> argList; typedef void (*TypedCall)( - internal::EM_VAL, + EM_VAL, const char* name, unsigned, - internal::TYPEID argTypes[], - typename internal::BindingType<Args>::WireType...); - TypedCall typedCall = reinterpret_cast<TypedCall>(&internal::_emval_call_void_method); + TYPEID argTypes[], + typename BindingType<Args>::WireType...); + TypedCall typedCall = reinterpret_cast<TypedCall>(&_emval_call_void_method); return typedCall( handle, name, argList.count, argList.types, - internal::toWireType(args)...); + toWireType(args)...); } template<typename T> T as() const { - typedef internal::BindingType<T> BT; + using namespace internal; + + typedef BindingType<T> BT; typedef typename BT::WireType (*TypedAs)( - internal::EM_VAL value, - emscripten::internal::TYPEID returnType); - TypedAs typedAs = reinterpret_cast<TypedAs>(&internal::_emval_as); + EM_VAL value, + TYPEID returnType); + TypedAs typedAs = reinterpret_cast<TypedAs>(&_emval_as); - typename BT::WireType wt = typedAs(handle, internal::TypeID<T>::get()); - internal::WireDeleter<T> deleter(wt); + typename BT::WireType wt = typedAs(handle, TypeID<T>::get()); + WireDeleter<T> deleter(wt); return BT::fromWireType(wt); } diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index 276042aa..cee0f539 100644 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -11,12 +11,6 @@ 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 @@ -40,7 +34,7 @@ namespace emscripten { template<typename T> struct TypeID<T*> { - static_assert(!std::is_pointer<T*>::value, "Implicitly binding raw pointers is illegal. Specify ???"); + static_assert(!std::is_pointer<T*>::value, "Implicitly binding raw pointers is illegal. Specify allow_raw_pointer<arg<?>>"); }; template<typename T> @@ -50,9 +44,7 @@ namespace emscripten { 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; + return reinterpret_cast<TYPEID>(&typeid(T*)); } }; @@ -114,7 +106,7 @@ namespace emscripten { typedef typename ExecutePolicies<Policies...>::template With<T, Index>::type TransformT; *argTypes = TypeID<TransformT>::get(); - return ArgTypes<Index + 1, Remaining...>::fill(argTypes + 1); + return ArgTypes<Index + 1, Remaining...>::template fill<Policies...>(argTypes + 1); } }; @@ -135,11 +127,6 @@ namespace emscripten { }; }; - // TODO: kill this and make every signature support policies - template<typename... Args> - struct ArgTypeList : WithPolicies<>::ArgTypeList<Args...> { - }; - // BindingType<T> template<typename T> |