aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@chadaustin.me>2012-11-01 19:33:42 -0700
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:21:35 +0300
commit8691fb1726c63263f99e86b8dd29d1a90d639579 (patch)
tree30a1b6e2b314e25cd17a8b42145bd5aff5d5b613
parent6014feed714b61f57f26254de6a2d2c7d89363e5 (diff)
Allow multiple pointer arguments and allow multiple functions taking the same raw pointer type
-rw-r--r--src/embind/embind.js32
-rw-r--r--system/include/emscripten/bind.h38
-rw-r--r--system/include/emscripten/val.h62
-rw-r--r--system/include/emscripten/wire.h19
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>