aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2013-03-06 03:17:51 -0800
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:24:57 +0300
commit8be7ebc9ccc6281a9e7481340d28255567608920 (patch)
treec3052e9d64bbca72010a06680e7315bf36d2bb7b
parentc1114a970b3eb8cb022aad9345289c81279c3c38 (diff)
Explicitly specify base classes. Alas, but it must be done for instanceof :(
-rwxr-xr-xsrc/embind/embind.js17
-rwxr-xr-xsystem/include/emscripten/bind.h34
-rwxr-xr-xsystem/lib/embind/bind.cpp10
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());
}));
}