diff options
author | Chad Austin <chad@imvu.com> | 2013-03-06 03:17:51 -0800 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-12 14:24:57 +0300 |
commit | 8be7ebc9ccc6281a9e7481340d28255567608920 (patch) | |
tree | c3052e9d64bbca72010a06680e7315bf36d2bb7b | |
parent | c1114a970b3eb8cb022aad9345289c81279c3c38 (diff) |
Explicitly specify base classes. Alas, but it must be done for instanceof :(
-rwxr-xr-x | src/embind/embind.js | 17 | ||||
-rwxr-xr-x | system/include/emscripten/bind.h | 34 | ||||
-rwxr-xr-x | system/lib/embind/bind.cpp | 10 |
3 files changed, 41 insertions, 20 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index 447bea1b..b9507d5f 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -69,6 +69,7 @@ function _embind_repr(v) { var typeRegistry = {}; var deferredRegistrations = []; +var baseClasses = {}; // rawType -> rawBaseType function requestDeferredRegistration(registrationFunction) { deferredRegistrations.push(registrationFunction); @@ -118,10 +119,10 @@ function collectRegisteredBaseClasses(rawType) { if (undefined === rawType) { return []; } - var rawBaseTypes = Module.__getBaseClasses(rawType); + var rawBaseTypes = baseClasses[rawType] || []; var baseTypes = []; - for (var i = 0; i < rawBaseTypes.size(); i++) { - var baseType = typeRegistry[rawBaseTypes.get(i)]; + for (var i = 0; i < rawBaseTypes.length; i++) { + var baseType = typeRegistry[rawBaseTypes[i]]; if (baseType) { baseTypes.push(baseType); } else { @@ -750,7 +751,7 @@ function __embind_register_smart_ptr( function ClassHandle() { } -function RegisteredClass(name, isPolymorphic, baseClass) { +function RegisteredClass(name, isPolymorphic, baseClassRawType) { this.name = name; this.isPolymorphic = isPolymorphic; } @@ -760,7 +761,7 @@ function __embind_register_class( rawType, rawPointerType, rawConstPointerType, - baseClassType, + baseClassRawType, isPolymorphic, name, rawDestructor @@ -768,7 +769,11 @@ function __embind_register_class( name = Pointer_stringify(name); rawDestructor = FUNCTION_TABLE[rawDestructor]; - var registeredClass = new RegisteredClass(name, isPolymorphic); + if (baseClassRawType) { + baseClasses[rawType] = [baseClassRawType]; + } + + var registeredClass = new RegisteredClass(name, isPolymorphic, baseClassRawType); var Handle = createNamedFunction(name, function(ptr) { Object.defineProperty(this, '$$', { diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index cbc5cb8e..24a7bf71 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -611,19 +611,45 @@ namespace emscripten { #define EMSCRIPTEN_WRAPPER(T) \ T(const ::emscripten::val& v): wrapper(v) {} - // TODO: support base class - template<typename ClassType> + namespace internal { + struct NoBaseClass { + static TYPEID get() { + return 0; + } + + template<typename ClassType> + static void verify() { + } + }; + } + + template<typename BaseClass> + struct base { + static internal::TYPEID get() { + return internal::TypeID<BaseClass>::get(); + } + + template<typename ClassType> + static void verify() { + static_assert(!std::is_same<ClassType, BaseClass>::value, "Base must not have same type as class"); + static_assert(std::is_base_of<BaseClass, ClassType>::value, "Derived class must derive from base"); + } + }; + + template<typename ClassType, typename BaseSpecifier = internal::NoBaseClass> class class_ { public: class_(const char* name) { using namespace internal; + BaseSpecifier::template verify<ClassType>(); + registerStandardTypes(); _embind_register_class( TypeID<ClassType>::get(), TypeID<AllowedRawPointer<ClassType>>::get(), TypeID<AllowedRawPointer<const ClassType>>::get(), - 0, + BaseSpecifier::get(), std::is_polymorphic<ClassType>::value, name, reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); @@ -672,7 +698,7 @@ namespace emscripten { using namespace internal; // TODO: unique or anonymous name - class_<WrapperType>("WrapperType") + class_<WrapperType, base<ClassType>>("WrapperType") .template constructor<val>() ; diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index 081db2cd..cbff7cf1 100755 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -133,15 +133,6 @@ namespace emscripten { return derivationPath;
}
- std::vector<int> __getBaseClasses(int tp) {
- std::vector<const __cxxabiv1::__class_type_info*> baseTypes = __internalGetBaseClasses((const __cxxabiv1::__class_type_info*)tp);
- std::vector<int> bases;
- for (int j = 0; j < baseTypes.size(); j++) {
- bases.emplace_back((int)baseTypes[j]);
- }
- return bases;
- }
-
extern "C" {
// These three routines constitute an extension to the compiler's support for dynamic type conversion.
// They are used by embind.js to implement automatic downcasting of return values which are pointers to
@@ -229,7 +220,6 @@ namespace emscripten { // conversion for the return value. This has the unfortunate side-effect of exposing it to third party
// developers, but perhaps the double underscore will scare them away from calling it.
function("__getDerivationPath", &__getDerivationPath);
- function("__getBaseClasses", &__getBaseClasses);
function("__peek32", &__peek32, allow_raw_pointers());
}));
}
|