aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rwxr-xr-x[-rw-r--r--]system/include/emscripten/bind.h1227
-rw-r--r--system/include/emscripten/val.h224
-rwxr-xr-x[-rw-r--r--]system/include/emscripten/wire.h267
-rwxr-xr-xsystem/lib/embind/bind.cpp83
4 files changed, 1328 insertions, 473 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 55fda986..57e44c0c 100644..100755
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -3,11 +3,20 @@
#include <stddef.h>
#include <assert.h>
#include <string>
+#include <functional>
+#include <vector>
+#include <map>
#include <type_traits>
#include <emscripten/val.h>
#include <emscripten/wire.h>
namespace emscripten {
+ enum class sharing_policy {
+ NONE = 0,
+ INTRUSIVE = 1,
+ BY_EMVAL = 2,
+ };
+
namespace internal {
typedef void (*GenericFunction)();
typedef long GenericEnumValue;
@@ -19,150 +28,205 @@ namespace emscripten {
const char* payload) __attribute__((noreturn));
void _embind_register_void(
- TypeID voidType,
+ TYPEID voidType,
const char* name);
void _embind_register_bool(
- TypeID boolType,
+ TYPEID boolType,
const char* name,
bool trueValue,
bool falseValue);
void _embind_register_integer(
- TypeID integerType,
- const char* name);
+ TYPEID integerType,
+ const char* name,
+ long minRange,
+ unsigned long maxRange);
void _embind_register_float(
- TypeID floatType,
+ TYPEID floatType,
const char* name);
void _embind_register_cstring(
- TypeID stringType,
+ TYPEID stringType,
const char* name);
void _embind_register_emval(
- TypeID emvalType,
+ TYPEID emvalType,
const char* name);
void _embind_register_function(
const char* name,
- TypeID returnType,
unsigned argCount,
- TypeID argTypes[],
+ TYPEID argTypes[],
GenericFunction invoker,
GenericFunction function);
void _embind_register_tuple(
- TypeID tupleType,
+ TYPEID tupleType,
const char* name,
GenericFunction constructor,
GenericFunction destructor);
void _embind_register_tuple_element(
- TypeID tupleType,
- TypeID elementType,
+ TYPEID tupleType,
+ TYPEID getterReturnType,
GenericFunction getter,
+ void* getterContext,
+ TYPEID setterArgumentType,
GenericFunction setter,
- size_t memberPointerSize,
- void* memberPointer);
-
- void _embind_register_tuple_element_accessor(
- TypeID tupleType,
- TypeID elementType,
- GenericFunction staticGetter,
- size_t getterSize,
- void* getter,
- GenericFunction staticSetter,
- size_t setterSize,
- void* setter);
+ void* setterContext);
+
+ void _embind_finalize_tuple(TYPEID tupleType);
void _embind_register_struct(
- TypeID structType,
- const char* name,
+ TYPEID structType,
+ const char* fieldName,
GenericFunction constructor,
GenericFunction destructor);
void _embind_register_struct_field(
- TypeID structType,
- const char* name,
- TypeID fieldType,
+ TYPEID structType,
+ const char* fieldName,
+ TYPEID getterReturnType,
GenericFunction getter,
+ void* getterContext,
+ TYPEID setterArgumentType,
GenericFunction setter,
- size_t memberPointerSize,
- void* memberPointer);
+ void* setterContext);
+
+ void _embind_finalize_struct(TYPEID structType);
+
+ void _embind_register_smart_ptr(
+ TYPEID pointerType,
+ TYPEID pointeeType,
+ const char* pointerName,
+ sharing_policy sharingPolicy,
+ GenericFunction getPointee,
+ GenericFunction constructor,
+ GenericFunction share,
+ GenericFunction destructor);
void _embind_register_class(
- TypeID classType,
+ TYPEID classType,
+ TYPEID pointerType,
+ TYPEID constPointerType,
+ TYPEID baseClassType,
+ GenericFunction getActualType,
+ GenericFunction upcast,
+ GenericFunction downcast,
const char* className,
GenericFunction destructor);
void _embind_register_class_constructor(
- TypeID classType,
+ TYPEID classType,
unsigned argCount,
- TypeID argTypes[],
+ TYPEID argTypes[],
+ GenericFunction invoker,
GenericFunction constructor);
- void _embind_register_class_method(
- TypeID classType,
+ void _embind_register_class_function(
+ TYPEID classType,
const char* methodName,
- TypeID returnType,
unsigned argCount,
- TypeID argTypes[],
+ TYPEID argTypes[],
GenericFunction invoker,
- size_t memberFunctionSize,
- void* memberFunction);
+ void* context);
- void _embind_register_class_field(
- TypeID classType,
+ void _embind_register_class_property(
+ TYPEID classType,
const char* fieldName,
- TypeID fieldType,
+ TYPEID fieldType,
GenericFunction getter,
GenericFunction setter,
- size_t memberPointerSize,
- void* memberPointer);
+ void* context);
- void _embind_register_class_classmethod(
- TypeID classType,
+ void _embind_register_class_class_function(
+ TYPEID classType,
const char* methodName,
- TypeID returnType,
unsigned argCount,
- TypeID argTypes[],
+ TYPEID argTypes[],
+ GenericFunction invoker,
GenericFunction method);
void _embind_register_enum(
- TypeID enumType,
+ TYPEID enumType,
const char* name);
void _embind_register_enum_value(
- TypeID enumType,
+ TYPEID enumType,
const char* valueName,
GenericEnumValue value);
void _embind_register_interface(
- TypeID interfaceType,
+ TYPEID interfaceType,
const char* name,
GenericFunction constructor,
GenericFunction destructor);
+
+ void _embind_register_constant(
+ const char* name,
+ TYPEID constantType,
+ uintptr_t value);
}
+ }
+}
- extern void registerStandardTypes();
+namespace emscripten {
+ ////////////////////////////////////////////////////////////////////////////////
+ // POLICIES
+ ////////////////////////////////////////////////////////////////////////////////
- class BindingsDefinition {
- public:
- template<typename Function>
- BindingsDefinition(Function fn) {
- fn();
- }
+ template<int Index>
+ struct arg {
+ static constexpr int index = Index + 1;
+ };
+
+ struct ret_val {
+ static constexpr int index = 0;
+ };
+
+ /*
+ 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;
+ };
+ };
+ */
+
+ // 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;
};
+ };
+
+ // this is temporary until arg policies are reworked
+ template<typename Slot>
+ struct allow_raw_pointer : public allow_raw_pointers {
+ };
+
+ template<typename Signature>
+ typename std::add_pointer<Signature>::type select_overload(typename std::add_pointer<Signature>::type fn) {
+ return fn;
}
-}
-namespace emscripten {
namespace internal {
template<typename ReturnType, typename... Args>
struct Invoker {
static typename internal::BindingType<ReturnType>::WireType invoke(
- ReturnType (fn)(Args...),
+ ReturnType (*fn)(Args...),
typename internal::BindingType<Args>::WireType... args
) {
return internal::BindingType<ReturnType>::toWireType(
@@ -176,7 +240,7 @@ namespace emscripten {
template<typename... Args>
struct Invoker<void, Args...> {
static void invoke(
- void (fn)(Args...),
+ void (*fn)(Args...),
typename internal::BindingType<Args>::WireType... args
) {
return fn(
@@ -186,22 +250,38 @@ namespace emscripten {
};
}
- template<typename ReturnType, typename... Args>
- void function(const char* name, ReturnType (fn)(Args...)) {
- internal::registerStandardTypes();
+ ////////////////////////////////////////////////////////////////////////////////
+ // FUNCTIONS
+ ////////////////////////////////////////////////////////////////////////////////
+
+ extern "C" {
+ void* __getDynamicPointerType(void* p);
+ }
- internal::ArgTypeList<Args...> args;
- internal::_embind_register_function(
+ template<typename ReturnType, typename... Args, typename... Policies>
+ void function(const char* name, ReturnType (*fn)(Args...), Policies...) {
+ using namespace internal;
+ typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
+ _embind_register_function(
name,
- internal::getTypeID<ReturnType>(),
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 {
template<typename ClassType, typename... Args>
+ ClassType* operator_new(Args... args) {
+ return new ClassType(args...);
+ }
+
+ template<typename WrapperType, typename ClassType, typename... Args>
+ WrapperType wrapped_new(Args... args) {
+ return WrapperType(new ClassType(args...));
+ }
+
+ template<typename ClassType, typename... Args>
ClassType* raw_constructor(
typename internal::BindingType<Args>::WireType... args
) {
@@ -215,302 +295,812 @@ namespace emscripten {
delete ptr;
}
- template<typename ClassType, typename ReturnType, typename... Args>
- struct MethodInvoker {
- typedef ReturnType (ClassType::*MemberPointer)(Args...);
+ template<typename FunctionPointerType, typename ReturnType, typename ThisType, typename... Args>
+ struct FunctionInvoker {
static typename internal::BindingType<ReturnType>::WireType invoke(
- ClassType* ptr,
- const MemberPointer& method,
+ FunctionPointerType* function,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
return internal::BindingType<ReturnType>::toWireType(
- (ptr->*method)(
- internal::BindingType<Args>::fromWireType(args)...
- )
+ (*function)(
+ internal::BindingType<ThisType>::fromWireType(wireThis),
+ internal::BindingType<Args>::fromWireType(args)...)
);
}
};
- template<typename ClassType, typename... Args>
- struct MethodInvoker<ClassType, void, Args...> {
- typedef void (ClassType::*MemberPointer)(Args...);
+ template<typename FunctionPointerType, typename ThisType, typename... Args>
+ struct FunctionInvoker<FunctionPointerType, void, ThisType, Args...> {
static void invoke(
- ClassType* ptr,
- const MemberPointer& method,
+ FunctionPointerType* function,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
- return (ptr->*method)(
- internal::BindingType<Args>::fromWireType(args)...
- );
+ (*function)(
+ internal::BindingType<ThisType>::fromWireType(wireThis),
+ internal::BindingType<Args>::fromWireType(args)...);
}
};
- template<typename ClassType, typename ReturnType, typename... Args>
- struct ConstMethodInvoker {
- typedef ReturnType (ClassType::*MemberPointer)(Args...) const;
+ template<typename MemberPointer,
+ typename ReturnType,
+ typename ThisType,
+ typename... Args>
+ struct MethodInvoker {
static typename internal::BindingType<ReturnType>::WireType invoke(
- const ClassType* ptr,
const MemberPointer& method,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
return internal::BindingType<ReturnType>::toWireType(
- (ptr->*method)(
+ (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
internal::BindingType<Args>::fromWireType(args)...
)
);
}
};
- template<typename ClassType, typename... Args>
- struct ConstMethodInvoker<ClassType, void, Args...> {
- typedef void (ClassType::*MemberPointer)(Args...) const;
+ template<typename MemberPointer,
+ typename ThisType,
+ typename... Args>
+ struct MethodInvoker<MemberPointer, void, ThisType, Args...> {
static void invoke(
- const ClassType* ptr,
const MemberPointer& method,
+ typename internal::BindingType<ThisType>::WireType wireThis,
typename internal::BindingType<Args>::WireType... args
) {
- return (ptr->*method)(
+ return (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
internal::BindingType<Args>::fromWireType(args)...
);
}
};
- template<typename ClassType, typename FieldType>
- struct FieldAccess {
- typedef FieldType ClassType::*MemberPointer;
- typedef internal::BindingType<FieldType> FieldBinding;
- typedef typename FieldBinding::WireType WireType;
+ template<typename InstanceType, typename MemberType>
+ struct MemberAccess {
+ typedef MemberType InstanceType::*MemberPointer;
+ typedef internal::BindingType<MemberType> MemberBinding;
+ typedef typename MemberBinding::WireType WireType;
- static WireType get(
- ClassType& ptr,
- const MemberPointer& field
+ template<typename ClassType>
+ static WireType getWire(
+ const MemberPointer& field,
+ const ClassType& ptr
) {
- return FieldBinding::toWireType(ptr.*field);
+ return MemberBinding::toWireType(ptr.*field);
}
- static void set(
- ClassType& ptr,
+ template<typename ClassType>
+ static void setWire(
const MemberPointer& field,
+ ClassType& ptr,
WireType value
) {
- ptr.*field = FieldBinding::fromWireType(value);
+ ptr.*field = MemberBinding::fromWireType(value);
}
+ };
- template<typename Getter>
- static WireType propertyGet(
- ClassType& ptr,
- const Getter& getter
- ) {
- return FieldBinding::toWireType(getter(ptr));
+ // TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
+ template<typename T>
+ inline void* getContext(const T& t) {
+ // not a leak because this is called once per binding
+ void* p = malloc(sizeof(T));
+ assert(p);
+ memcpy(p, &t, sizeof(T));
+ return p;
+ }
+
+ template<typename T>
+ struct GetterPolicy;
+
+ template<typename GetterReturnType, typename GetterThisType>
+ struct GetterPolicy<GetterReturnType (GetterThisType::*)() const> {
+ typedef GetterReturnType ReturnType;
+ typedef GetterReturnType (GetterThisType::*Context)() const;
+
+ typedef internal::BindingType<ReturnType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static WireType get(const Context& context, const ClassType& ptr) {
+ return Binding::toWireType((ptr.*context)());
}
- template<typename Setter>
- static void propertySet(
- ClassType& ptr,
- const Setter& setter,
- WireType value
- ) {
- setter(ptr, FieldBinding::fromWireType(value));
+ static void* getContext(Context context) {
+ return internal::getContext(context);
+ }
+ };
+
+ template<typename GetterReturnType, typename GetterThisType>
+ struct GetterPolicy<GetterReturnType (*)(const GetterThisType&)> {
+ typedef GetterReturnType ReturnType;
+ typedef GetterReturnType (*Context)(const GetterThisType&);
+
+ typedef internal::BindingType<ReturnType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static WireType get(const Context& context, const ClassType& ptr) {
+ return Binding::toWireType(context(ptr));
+ }
+
+ static void* getContext(Context context) {
+ return internal::getContext(context);
+ }
+ };
+
+ template<typename T>
+ struct SetterPolicy;
+
+ template<typename SetterThisType, typename SetterArgumentType>
+ struct SetterPolicy<void (SetterThisType::*)(SetterArgumentType)> {
+ typedef SetterArgumentType ArgumentType;
+ typedef void (SetterThisType::*Context)(SetterArgumentType);
+
+ typedef internal::BindingType<SetterArgumentType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static void set(const Context& context, ClassType& ptr, WireType wt) {
+ (ptr.*context)(Binding::fromWireType(wt));
+ }
+
+ static void* getContext(Context context) {
+ return internal::getContext(context);
+ }
+ };
+
+ template<typename SetterThisType, typename SetterArgumentType>
+ struct SetterPolicy<void (*)(SetterThisType&, SetterArgumentType)> {
+ typedef SetterArgumentType ArgumentType;
+ typedef void (*Context)(SetterThisType&, SetterArgumentType);
+
+ typedef internal::BindingType<SetterArgumentType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static void set(const Context& context, ClassType& ptr, WireType wt) {
+ context(ptr, Binding::fromWireType(wt));
+ }
+
+ static void* getContext(Context context) {
+ return internal::getContext(context);
}
};
+
+ class noncopyable {
+ protected:
+ noncopyable() {}
+ ~noncopyable() {}
+ private:
+ noncopyable(const noncopyable&) = delete;
+ const noncopyable& operator=(const noncopyable&) = delete;
+ };
+
+ template<typename ClassType, typename ElementType>
+ typename BindingType<ElementType>::WireType get_by_index(int index, ClassType& ptr) {
+ return BindingType<ElementType>::toWireType(ptr[index]);
+ }
+
+ template<typename ClassType, typename ElementType>
+ void set_by_index(int index, ClassType& ptr, typename BindingType<ElementType>::WireType wt) {
+ ptr[index] = BindingType<ElementType>::fromWireType(wt);
+ }
}
+ template<int Index>
+ struct index {
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // VALUE TUPLES
+ ////////////////////////////////////////////////////////////////////////////////
+
template<typename ClassType>
- class value_tuple {
+ class value_tuple : public internal::noncopyable {
public:
value_tuple(const char* name) {
- internal::registerStandardTypes();
- internal::_embind_register_tuple(
- internal::getTypeID<ClassType>(),
+ using namespace internal;
+ _embind_register_tuple(
+ TypeID<ClassType>::get(),
name,
- reinterpret_cast<internal::GenericFunction>(&internal::raw_constructor<ClassType>),
- reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<ClassType>));
- }
-
- template<typename ElementType>
- value_tuple& element(ElementType ClassType::*field) {
- internal::_embind_register_tuple_element(
- internal::getTypeID<ClassType>(),
- internal::getTypeID<ElementType>(),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::get),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::set),
- sizeof(field),
- &field);
-
- return *this;
+ reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
+ reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
}
- template<typename ElementType>
- value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, ElementType)) {
- internal::_embind_register_tuple_element_accessor(
- internal::getTypeID<ClassType>(),
- internal::getTypeID<ElementType>(),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>),
- sizeof(getter),
- &getter,
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>),
- sizeof(setter),
- &setter);
- return *this;
+ ~value_tuple() {
+ using namespace internal;
+ _embind_finalize_tuple(TypeID<ClassType>::get());
}
- template<typename ElementType>
- value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, const ElementType&)) {
- internal::_embind_register_tuple_element_accessor(
- internal::getTypeID<ClassType>(),
- internal::getTypeID<ElementType>(),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>),
- sizeof(getter),
- &getter,
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>),
- sizeof(setter),
- &setter);
+ template<typename InstanceType, typename ElementType>
+ value_tuple& element(ElementType InstanceType::*field) {
+ using namespace internal;
+ _embind_register_tuple_element(
+ TypeID<ClassType>::get(),
+ TypeID<ElementType>::get(),
+ reinterpret_cast<GenericFunction>(
+ &MemberAccess<InstanceType, ElementType>
+ ::template getWire<ClassType>),
+ getContext(field),
+ TypeID<ElementType>::get(),
+ reinterpret_cast<GenericFunction>(
+ &MemberAccess<InstanceType, ElementType>
+ ::template setWire<ClassType>),
+ getContext(field));
return *this;
}
- template<typename ElementType>
- value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, const ElementType&&)) {
- internal::_embind_register_tuple_element_accessor(
- internal::getTypeID<ClassType>(),
- internal::getTypeID<ElementType>(),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>),
- sizeof(getter),
- &getter,
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>),
- sizeof(setter),
- &setter);
+ template<typename Getter, typename Setter>
+ value_tuple& element(Getter getter, Setter setter) {
+ using namespace internal;
+ typedef GetterPolicy<Getter> GP;
+ typedef SetterPolicy<Setter> SP;
+ _embind_register_tuple_element(
+ TypeID<ClassType>::get(),
+ TypeID<typename GP::ReturnType>::get(),
+ reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
+ GP::getContext(getter),
+ TypeID<typename SP::ArgumentType>::get(),
+ reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
+ SP::getContext(setter));
return *this;
}
- template<typename ElementType>
- value_tuple& element(ElementType (*getter)(const ClassType&), void (*setter)(ClassType&, ElementType&)) {
- internal::_embind_register_tuple_element_accessor(
- internal::getTypeID<ClassType>(),
- internal::getTypeID<ElementType>(),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertyGet<ElementType(const ClassType&)>),
- sizeof(getter),
- &getter,
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, ElementType>::template propertySet<void(ClassType&, ElementType)>),
- sizeof(setter),
- &setter);
+ template<int Index>
+ value_tuple& element(index<Index>) {
+ using namespace internal;
+ ClassType* null = 0;
+ typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
+ _embind_register_tuple_element(
+ TypeID<ClassType>::get(),
+ TypeID<ElementType>::get(),
+ reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>),
+ reinterpret_cast<void*>(Index),
+ TypeID<ElementType>::get(),
+ reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>),
+ reinterpret_cast<void*>(Index));
return *this;
}
};
+ ////////////////////////////////////////////////////////////////////////////////
+ // VALUE STRUCTS
+ ////////////////////////////////////////////////////////////////////////////////
+
template<typename ClassType>
- class value_struct {
+ class value_struct : public internal::noncopyable {
public:
value_struct(const char* name) {
- internal::registerStandardTypes();
- internal::_embind_register_struct(
- internal::getTypeID<ClassType>(),
+ using namespace internal;
+ _embind_register_struct(
+ TypeID<ClassType>::get(),
name,
- reinterpret_cast<internal::GenericFunction>(&internal::raw_constructor<ClassType>),
- reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<ClassType>));
+ reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
+ reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
}
- template<typename FieldType>
- value_struct& field(const char* fieldName, FieldType ClassType::*field) {
- internal::_embind_register_struct_field(
- internal::getTypeID<ClassType>(),
+ ~value_struct() {
+ _embind_finalize_struct(internal::TypeID<ClassType>::get());
+ }
+
+ template<typename InstanceType, typename FieldType>
+ value_struct& field(const char* fieldName, FieldType InstanceType::*field) {
+ using namespace internal;
+ _embind_register_struct_field(
+ TypeID<ClassType>::get(),
fieldName,
- internal::getTypeID<FieldType>(),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, FieldType>::get),
- reinterpret_cast<internal::GenericFunction>(&internal::FieldAccess<ClassType, FieldType>::set),
- sizeof(field),
- &field);
-
+ TypeID<FieldType>::get(),
+ reinterpret_cast<GenericFunction>(
+ &MemberAccess<InstanceType, FieldType>
+ ::template getWire<ClassType>),
+ getContext(field),
+ TypeID<FieldType>::get(),
+ reinterpret_cast<GenericFunction>(
+ &MemberAccess<InstanceType, FieldType>
+ ::template setWire<ClassType>),
+ getContext(field));
+ return *this;
+ }
+
+ template<typename Getter, typename Setter>
+ value_struct& field(
+ const char* fieldName,
+ Getter getter,
+ Setter setter
+ ) {
+ using namespace internal;
+ typedef GetterPolicy<Getter> GP;
+ typedef SetterPolicy<Setter> SP;
+ _embind_register_struct_field(
+ TypeID<ClassType>::get(),
+ fieldName,
+ TypeID<typename GP::ReturnType>::get(),
+ reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
+ GP::getContext(getter),
+ TypeID<typename SP::ArgumentType>::get(),
+ reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
+ SP::getContext(setter));
+ return *this;
+ }
+
+ template<int Index>
+ value_struct& field(const char* fieldName, index<Index>) {
+ using namespace internal;
+ ClassType* null = 0;
+ typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
+ _embind_register_struct_field(
+ TypeID<ClassType>::get(),
+ fieldName,
+ TypeID<ElementType>::get(),
+ reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>),
+ reinterpret_cast<void*>(Index),
+ TypeID<ElementType>::get(),
+ reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>),
+ reinterpret_cast<void*>(Index));
return *this;
}
};
- // TODO: support class definitions without constructors.
- // TODO: support external class constructors
- template<typename ClassType>
+ ////////////////////////////////////////////////////////////////////////////////
+ // SMART POINTERS
+ ////////////////////////////////////////////////////////////////////////////////
+
+ template<typename PointerType>
+ struct default_smart_ptr_trait {
+ static sharing_policy get_sharing_policy() {
+ return sharing_policy::NONE;
+ }
+
+ static void* share(void* v) {
+ return 0; // no sharing
+ }
+ };
+
+ // specialize if you have a different pointer type
+ template<typename PointerType>
+ struct smart_ptr_trait : public default_smart_ptr_trait<PointerType> {
+ typedef typename PointerType::element_type element_type;
+
+ static element_type* get(const PointerType& ptr) {
+ return ptr.get();
+ }
+ };
+
+ template<typename PointeeType>
+ struct smart_ptr_trait<std::shared_ptr<PointeeType>> {
+ typedef std::shared_ptr<PointeeType> PointerType;
+ typedef typename PointerType::element_type element_type;
+
+ static element_type* get(const PointerType& ptr) {
+ return ptr.get();
+ }
+
+ static sharing_policy get_sharing_policy() {
+ return sharing_policy::BY_EMVAL;
+ }
+
+ static std::shared_ptr<PointeeType>* share(PointeeType* p, internal::EM_VAL v) {
+ return new std::shared_ptr<PointeeType>(
+ p,
+ val_deleter(val::take_ownership(v)));
+ }
+
+ private:
+ class val_deleter {
+ public:
+ val_deleter() = delete;
+ explicit val_deleter(val v)
+ : v(v)
+ {}
+ void operator()(void const*) {
+ v();
+ // eventually we'll need to support emptied out val
+ v = val::undefined();
+ }
+ private:
+ val v;
+ };
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // CLASSES
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // abstract classes
+ template<typename T></