diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-04-14 14:06:52 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-04-14 14:06:52 -0700 |
commit | 512b7bd6689699a16a5afb6d38c786d17ec45c91 (patch) | |
tree | b1fb3c871b626d16b92ef3818fc05d3caf23430c /system/include | |
parent | 411e6287c76d0cf7ff869fa6fc97237ad8be1b1d (diff) | |
parent | 1838f123d3fcd45453b6ca373dce94cc40621d77 (diff) |
Merge pull request #2286 from chadaustin/embind-code-size-reduction
Embind code size reduction by using lightweight RTTI record for non-polymorphic types
Diffstat (limited to 'system/include')
-rw-r--r-- | system/include/emscripten/bind.h | 22 | ||||
-rw-r--r-- | system/include/emscripten/wire.h | 64 |
2 files changed, 65 insertions, 21 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 872f279b..0699715c 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -813,7 +813,7 @@ namespace emscripten { // NOTE: this returns the class type, not the pointer type template<typename T> inline TYPEID getActualType(T* ptr) { - return reinterpret_cast<TYPEID>(&typeid(*ptr)); + return getLightTypeID(*ptr); }; } @@ -851,15 +851,15 @@ namespace emscripten { template<typename T> struct SmartPtrIfNeeded { template<typename U> - SmartPtrIfNeeded(U& cls) { - cls.template smart_ptr<T>(); + SmartPtrIfNeeded(U& cls, const char* smartPtrName) { + cls.template smart_ptr<T>(smartPtrName); } }; template<typename T> struct SmartPtrIfNeeded<T*> { template<typename U> - SmartPtrIfNeeded(U&) { + SmartPtrIfNeeded(U&, const char*) { } }; }; @@ -890,7 +890,7 @@ namespace emscripten { } template<typename PointerType> - const class_& smart_ptr() const { + const class_& smart_ptr(const char* name) const { using namespace internal; typedef smart_ptr_trait<PointerType> PointerTrait; @@ -901,7 +901,7 @@ namespace emscripten { _embind_register_smart_ptr( TypeID<PointerType>::get(), TypeID<PointeeType>::get(), - typeid(PointerType).name(), + name, PointerTrait::get_sharing_policy(), reinterpret_cast<GenericFunction>(&PointerTrait::get), reinterpret_cast<GenericFunction>(&PointerTrait::construct_null), @@ -933,10 +933,10 @@ namespace emscripten { } template<typename SmartPtr, typename... Args, typename... Policies> - const class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) const { + const class_& smart_ptr_constructor(const char* smartPtrName, SmartPtr (*factory)(Args...), Policies...) const { using namespace internal; - smart_ptr<SmartPtr>(); + smart_ptr<SmartPtr>(smartPtrName); typename WithPolicies<Policies...>::template ArgTypeList<SmartPtr, Args...> args; _embind_register_class_constructor( @@ -949,12 +949,12 @@ namespace emscripten { } template<typename WrapperType, typename PointerType = WrapperType*> - const class_& allow_subclass() const { + const class_& allow_subclass(const char* wrapperClassName, const char* pointerName = "<UnknownPointerName>") const { using namespace internal; - auto cls = class_<WrapperType, base<ClassType>>(typeid(WrapperType).name()) + auto cls = class_<WrapperType, base<ClassType>>(wrapperClassName) ; - SmartPtrIfNeeded<PointerType> _(cls); + SmartPtrIfNeeded<PointerType> _(cls, pointerName); return class_function( "implement", diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h index 05b3ac33..c20e2f55 100644 --- a/system/include/emscripten/wire.h +++ b/system/include/emscripten/wire.h @@ -15,22 +15,66 @@ #define EMSCRIPTEN_ALWAYS_INLINE __attribute__((always_inline)) namespace emscripten { + #ifndef EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES + #define EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES 1 + #endif + + + #if EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES + constexpr bool has_unbound_type_names = true; + #else + constexpr bool has_unbound_type_names = false; + #endif + namespace internal { typedef void (*GenericFunction)(); - typedef const struct _TYPEID* TYPEID; + typedef const struct _TYPEID {}* TYPEID; + + + // We don't need the full std::type_info implementation. We + // just need a unique identifier per type and polymorphic type + // identification. + + template<typename T> + struct CanonicalizedID { + static TYPEID get() { + static _TYPEID c; + return &c; + } + }; + + template<typename T> + struct Canonicalized { + typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type; + }; + + template<typename T> + struct LightTypeID { + static TYPEID get() { + typedef typename Canonicalized<T>::type C; + if (has_unbound_type_names || std::is_polymorphic<C>::value) { + return reinterpret_cast<TYPEID>(&typeid(C)); + } else { + return CanonicalizedID<C>::get(); + } + } + }; + + template<typename T> + const TYPEID getLightTypeID(const T& value) { + typedef typename Canonicalized<T>::type C; + if (has_unbound_type_names || std::is_polymorphic<C>::value) { + return reinterpret_cast<TYPEID>(&typeid(value)); + } else { + return LightTypeID<T>::get(); + } + } - // 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 - // 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() { - return reinterpret_cast<TYPEID>(&typeid(T)); + return LightTypeID<T>::get(); } }; @@ -53,7 +97,7 @@ namespace emscripten { template<typename T> struct TypeID<AllowedRawPointer<T>> { static TYPEID get() { - return reinterpret_cast<TYPEID>(&typeid(T*)); + return LightTypeID<T*>::get(); } }; |