diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-02-10 15:16:14 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-02-10 15:16:14 -0800 |
commit | ed896c9c00edc7c7bdd4c4cfaca057509c3cd628 (patch) | |
tree | a4721bedbe82d57cff7f6a94dbd2ed8e5b8425dc /system | |
parent | 8eb52e34be029cd7f276871c830b02fdf53ed00c (diff) | |
parent | b5cf147e6ce7a8d3277342d87beec76290a578bf (diff) |
Merge pull request #2099 from waywardmonkeys/upstream-from-imvu
Upstream from imvu
Diffstat (limited to 'system')
-rw-r--r-- | system/include/emscripten/bind.h | 52 | ||||
-rw-r--r-- | system/include/emscripten/val.h | 55 | ||||
-rw-r--r-- | system/include/emscripten/wire.h | 32 |
3 files changed, 83 insertions, 56 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 403d8084..4d7547a1 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -533,6 +533,8 @@ namespace emscripten { template<typename ClassType> class value_array : public internal::noncopyable { public: + typedef ClassType class_type; + value_array(const char* name) { using namespace internal; _embind_register_value_array( @@ -605,6 +607,8 @@ namespace emscripten { template<typename ClassType> class value_object : public internal::noncopyable { public: + typedef ClassType class_type; + value_object(const char* name) { using namespace internal; _embind_register_value_object( @@ -689,6 +693,10 @@ namespace emscripten { static void* share(void* v) { return 0; // no sharing } + + static PointerType* construct_null() { + return new PointerType; + } }; // specialize if you have a different pointer type @@ -720,6 +728,10 @@ namespace emscripten { val_deleter(val::take_ownership(v))); } + static PointerType* construct_null() { + return new PointerType; + } + private: class val_deleter { public: @@ -745,6 +757,8 @@ namespace emscripten { template<typename T> class wrapper : public T { public: + typedef T class_type; + explicit wrapper(val&& wrapped) : wrapped(std::forward<val>(wrapped)) {} @@ -794,13 +808,14 @@ namespace emscripten { // NOTE: this returns the class type, not the pointer type template<typename T> inline TYPEID getActualType(T* ptr) { - assert(ptr); return reinterpret_cast<TYPEID>(&typeid(*ptr)); }; } template<typename BaseClass> struct base { + typedef BaseClass class_type; + template<typename ClassType> static void verify() { static_assert(!std::is_same<ClassType, BaseClass>::value, "Base must not have same type as class"); @@ -847,6 +862,9 @@ namespace emscripten { template<typename ClassType, typename BaseSpecifier = internal::NoBaseClass> class class_ { public: + typedef ClassType class_type; + typedef BaseSpecifier base_specifier; + class_() = delete; explicit class_(const char* name) { @@ -867,7 +885,7 @@ namespace emscripten { } template<typename PointerType> - class_& smart_ptr() { + const class_& smart_ptr() const { using namespace internal; typedef smart_ptr_trait<PointerType> PointerTrait; @@ -881,21 +899,21 @@ namespace emscripten { typeid(PointerType).name(), PointerTrait::get_sharing_policy(), reinterpret_cast<GenericFunction>(&PointerTrait::get), - reinterpret_cast<GenericFunction>(&operator_new<PointerType>), + reinterpret_cast<GenericFunction>(&PointerTrait::construct_null), reinterpret_cast<GenericFunction>(&PointerTrait::share), reinterpret_cast<GenericFunction>(&raw_destructor<PointerType>)); return *this; }; template<typename... ConstructorArgs, typename... Policies> - class_& constructor(Policies... policies) { + const class_& constructor(Policies... policies) const { return constructor( &internal::operator_new<ClassType, ConstructorArgs...>, policies...); } template<typename... Args, typename ReturnType, typename... Policies> - class_& constructor(ReturnType (*factory)(Args...), Policies...) { + const class_& constructor(ReturnType (*factory)(Args...), Policies...) const { using namespace internal; // TODO: allows all raw pointers... policies need a rethink @@ -910,7 +928,7 @@ namespace emscripten { } template<typename SmartPtr, typename... Args, typename... Policies> - class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) { + const class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) const { using namespace internal; smart_ptr<SmartPtr>(); @@ -926,7 +944,7 @@ namespace emscripten { } template<typename WrapperType, typename PointerType = WrapperType*> - class_& allow_subclass() { + const class_& allow_subclass() const { using namespace internal; auto cls = class_<WrapperType, base<ClassType>>(typeid(WrapperType).name()) @@ -940,7 +958,7 @@ namespace emscripten { } template<typename ReturnType, typename... Args, typename... Policies> - class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) { + const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) const { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args; @@ -955,7 +973,7 @@ namespace emscripten { } template<typename ReturnType, typename... Args, typename... Policies> - class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) { + const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) const { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args; @@ -970,7 +988,7 @@ namespace emscripten { } template<typename ReturnType, typename ThisType, typename... Args, typename... Policies> - class_& function(const char* methodName, ReturnType (*function)(ThisType, Args...), Policies...) { + const class_& function(const char* methodName, ReturnType (*function)(ThisType, Args...), Policies...) const { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args; @@ -985,7 +1003,7 @@ namespace emscripten { } template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type> - class_& property(const char* fieldName, const FieldType ClassType::*field) { + const class_& property(const char* fieldName, const FieldType ClassType::*field) const { using namespace internal; _embind_register_class_property( @@ -1001,7 +1019,7 @@ namespace emscripten { } template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type> - class_& property(const char* fieldName, FieldType ClassType::*field) { + const class_& property(const char* fieldName, FieldType ClassType::*field) const { using namespace internal; _embind_register_class_property( @@ -1017,7 +1035,7 @@ namespace emscripten { } template<typename Getter> - class_& property(const char* fieldName, Getter getter) { + const class_& property(const char* fieldName, Getter getter) const { using namespace internal; typedef GetterPolicy<Getter> GP; _embind_register_class_property( @@ -1033,7 +1051,7 @@ namespace emscripten { } template<typename Getter, typename Setter> - class_& property(const char* fieldName, Getter getter, Setter setter) { + const class_& property(const char* fieldName, Getter getter, Setter setter) const { using namespace internal; typedef GetterPolicy<Getter> GP; typedef SetterPolicy<Setter> SP; @@ -1050,7 +1068,7 @@ namespace emscripten { } template<typename ReturnType, typename... Args, typename... Policies> - class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) { + const class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) const { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args; @@ -1157,6 +1175,8 @@ namespace emscripten { template<typename EnumType> class enum_ { public: + typedef EnumType enum_type; + enum_(const char* name) { _embind_register_enum( internal::TypeID<EnumType>::get(), @@ -1199,7 +1219,7 @@ namespace emscripten { _embind_register_constant( name, TypeID<const ConstantType&>::get(), - asGenericValue(BindingType<const ConstantType&>::toWireType(v))); + asGenericValue(BT::toWireType(v))); } } diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h index b712d164..19b1beb1 100644 --- a/system/include/emscripten/val.h +++ b/system/include/emscripten/val.h @@ -11,10 +11,18 @@ namespace emscripten { void _emval_register_symbol(const char*); typedef struct _EM_VAL* EM_VAL; + typedef struct _EM_DESTRUCTORS* EM_DESTRUCTORS; + + // TODO: functions returning this are reinterpret_cast + // into the correct return type. this needs some thought + // for asm.js. + typedef void _POLYMORPHIC_RESULT; void _emval_incref(EM_VAL value); void _emval_decref(EM_VAL value); + void _emval_run_destructors(EM_DESTRUCTORS handle); + EM_VAL _emval_new_array(); EM_VAL _emval_new_object(); EM_VAL _emval_undefined(); @@ -32,7 +40,8 @@ namespace emscripten { EM_VAL _emval_get_module_property(const char* name); EM_VAL _emval_get_property(EM_VAL object, EM_VAL key); void _emval_set_property(EM_VAL object, EM_VAL key, EM_VAL value); - void _emval_as(EM_VAL value, TYPEID returnType); + _POLYMORPHIC_RESULT _emval_as(EM_VAL value, TYPEID returnType, EM_DESTRUCTORS* runDestructors); + EM_VAL _emval_call( EM_VAL value, unsigned argCount, @@ -57,7 +66,11 @@ namespace emscripten { template<typename ReturnType, typename... Args> struct Signature { - typedef typename BindingType<ReturnType>::WireType (*MethodCaller)(EM_VAL value, const char* methodName, typename BindingType<Args>::WireType...); + typedef typename BindingType<ReturnType>::WireType (*MethodCaller)( + EM_VAL value, + const char* methodName, + EM_DESTRUCTORS* destructors, + typename BindingType<Args>::WireType...); static MethodCaller get_method_caller() { static MethodCaller fp = reinterpret_cast<MethodCaller>(init_method_caller()); @@ -71,15 +84,34 @@ namespace emscripten { } }; + struct DestructorsRunner { + public: + explicit DestructorsRunner(EM_DESTRUCTORS d) + : destructors(d) + {} + ~DestructorsRunner() { + _emval_run_destructors(destructors); + } + + DestructorsRunner(const DestructorsRunner&) = delete; + void operator=(const DestructorsRunner&) = delete; + + private: + EM_DESTRUCTORS destructors; + }; + template<typename ReturnType, typename... Args> struct MethodCaller { static ReturnType call(EM_VAL handle, const char* methodName, Args&&... args) { auto caller = Signature<ReturnType, Args...>::get_method_caller(); + + EM_DESTRUCTORS destructors; auto wireType = caller( handle, methodName, + &destructors, toWireType(std::forward<Args>(args))...); - WireDeleter<ReturnType> deleter(wireType); + DestructorsRunner rd(destructors); return BindingType<ReturnType>::fromWireType(wireType); } }; @@ -88,10 +120,15 @@ namespace emscripten { struct MethodCaller<void, Args...> { static void call(EM_VAL handle, const char* methodName, Args&&... args) { auto caller = Signature<void, Args...>::get_method_caller(); - return caller( + + EM_DESTRUCTORS destructors; + caller( handle, methodName, + &destructors, toWireType(std::forward<Args>(args))...); + DestructorsRunner rd(destructors); + // void requires no translation } }; } @@ -262,11 +299,13 @@ namespace emscripten { typedef typename BT::WireType (*TypedAs)( EM_VAL value, - TYPEID returnType); + TYPEID returnType, + EM_DESTRUCTORS* runDestructors); TypedAs typedAs = reinterpret_cast<TypedAs>(&_emval_as); - typename BT::WireType wt = typedAs(handle, TypeID<T>::get()); - WireDeleter<T> deleter(wt); + EM_DESTRUCTORS destructors; + typename BT::WireType wt = typedAs(handle, TypeID<T>::get(), &destructors); + DestructorsRunner dr(destructors); return BT::fromWireType(wt); } @@ -292,8 +331,6 @@ namespace emscripten { static val fromWireType(WireType v) { return val::take_ownership(v); } - static void destroy(WireType v) { - } }; } diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index a5892216..c3ce8dd0 100644 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -7,6 +7,7 @@ // // We'll call the on-the-wire type WireType. +#include <stdio.h> #include <cstdlib> #include <memory> #include <string> @@ -130,8 +131,6 @@ namespace emscripten { constexpr static type fromWireType(WireType v) { \ return v; \ } \ - static void destroy(WireType) { \ - } \ } EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(char); @@ -160,8 +159,6 @@ namespace emscripten { static bool fromWireType(WireType wt) { return wt; } - static void destroy(WireType) { - } }; template<> @@ -179,9 +176,6 @@ namespace emscripten { static std::string fromWireType(WireType v) { return std::string(v->data, v->length); } - static void destroy(WireType v) { - free(v); - } }; template<> @@ -199,9 +193,6 @@ namespace emscripten { static std::wstring fromWireType(WireType v) { return std::wstring(v->data, v->length); } - static void destroy(WireType v) { - free(v); - } }; template<typename T> @@ -254,10 +245,6 @@ namespace emscripten { static ActualT& fromWireType(WireType p) { return *p; } - - static void destroy(WireType p) { - delete p; - } }; // Is this necessary? @@ -280,8 +267,6 @@ namespace emscripten { static Enum fromWireType(WireType v) { return v; } - static void destroy(WireType) { - } }; // catch-all generic binding @@ -296,21 +281,6 @@ namespace emscripten { auto toWireType(T&& v) -> typename BindingType<T>::WireType { return BindingType<T>::toWireType(std::forward<T>(v)); } - - template<typename T> - struct WireDeleter { - typedef typename BindingType<T>::WireType WireType; - - WireDeleter(WireType wt) - : wt(wt) - {} - - ~WireDeleter() { - BindingType<T>::destroy(wt); - } - - WireType wt; - }; } struct memory_view { |