aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/include/emscripten/bind.h129
-rw-r--r--system/include/emscripten/wire.h115
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;