aboutsummaryrefslogtreecommitdiff
path: root/system/include
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-04-14 14:06:52 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-04-14 14:06:52 -0700
commit512b7bd6689699a16a5afb6d38c786d17ec45c91 (patch)
treeb1fb3c871b626d16b92ef3818fc05d3caf23430c /system/include
parent411e6287c76d0cf7ff869fa6fc97237ad8be1b1d (diff)
parent1838f123d3fcd45453b6ca373dce94cc40621d77 (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.h22
-rw-r--r--system/include/emscripten/wire.h64
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();
}
};