diff options
-rwxr-xr-x | src/embind/embind.js | 88 | ||||
-rwxr-xr-x | system/lib/embind/bind.cpp | 14 |
2 files changed, 98 insertions, 4 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index 39e120e0..d6464d12 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -36,6 +36,89 @@ function _embind_repr(v) { var typeRegistry = {}; +function resolveType(type) { + function createInheritedFunctionOrProperty(baseClassName, name, baseClassPrototype) { + if (!type.Handle.prototype.hasOwnProperty(name)) { + var desc = Object.getOwnPropertyDescriptor(baseClassPrototype, baseClassName); + if (desc) { // some names in the list may not be present in this particular base class + if ('get' in desc || 'put' in desc) { + Object.defineProperty(type.Handle.prototype, name, desc); + } else { + type.Handle.prototype[name] = createNamedFunction(name, function() { + return baseClassPrototype[baseClassName].apply(this, arguments); // todo: need to upcast "this" pointer + }); + } + } + } + } + if (!type.resolved) { + var i, j, rawBaseClassType, baseClassType, name; + var names = []; + var qualifiedNames = {}; + var rawBaseClassTypes = Module.__getBaseClasses(type.rawType); + for (i = 0; i < rawBaseClassTypes.size(); i++) { + rawBaseClassType = rawBaseClassTypes.at(i); + baseClassType = typeRegistry[rawBaseClassType]; + if (baseClassType) { + resolveType(baseClassType); + var proto = baseClassType.Handle.prototype; + for (name in proto) { + if (proto.hasOwnProperty(name)) { + var qualifiedName = baseClassType.name + "_" + name; + // todo: figure out how to exclude casting functions + if (['clone', 'move', 'delete'].indexOf(name) < 0) { + if (type.Handle.prototype.hasOwnProperty(qualifiedName)) { + if (names.indexOf(name) < 0) { + names.push(name); + } + if (names.indexOf(qualifiedName) < 0) { + qualifiedNames[name] = qualifiedName; + } + } else { + if (names.indexOf(name) >= 0) { + if (names.indexOf(qualifiedName) < 0) { + qualifiedNames[name] = qualifiedName; + } + } else { + names.push(name); + if (type.Handle.prototype.hasOwnProperty(name) && names.indexOf(qualifiedName) < 0) { + qualifiedNames[name] = qualifiedName; + } + } + } + } + } + } + } + } + for (i = 0; i < rawBaseClassTypes.size(); i++) { + rawBaseClassType = rawBaseClassTypes.at(i); + baseClassType = typeRegistry[rawBaseClassType]; + if (baseClassType) { + proto = baseClassType.Handle.prototype; + for (name in qualifiedNames) { + if (qualifiedNames.hasOwnProperty(name)) { + createInheritedFunctionOrProperty(name, qualifiedNames[name], proto); + } + } + for (j = 0; j < names.length; j++) { + name = names[j]; + if (!(name in qualifiedNames)) { + createInheritedFunctionOrProperty(name, name, proto); + } + } + } + } + type.resolved = true; + } +} + +function resolveBindings() { + for (var rawType in typeRegistry) { + resolveType(typeRegistry[rawType]); + } +} + function registerType(rawType, name, registeredInstance) { if (!rawType) { throw new BindingError('type "' + name + '" must have a positive integer typeid pointer'); @@ -731,8 +814,8 @@ function __embind_register_class( var dp = Object.getOwnPropertyDescriptor(Handle.prototype, prop); Object.defineProperty(h, prop, dp); } - - return h; + + return h; }); Handle.prototype.clone = function() { @@ -772,6 +855,7 @@ function __embind_register_class( var registeredClass = new RegisteredPointer(Handle, isPolymorphic, false); var type = registerType(rawType, name, registeredClass); registeredClass.pointeeType = type; + var registeredClass = new RegisteredPointer(Handle, isPolymorphic, false); registerType(rawPointerType, name + '*', registeredClass); registeredClass.pointeeType = type; diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index a4b67fa5..5e82bb7e 100755 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -10,7 +10,7 @@ using namespace emscripten;
namespace __cxxabiv1 {
- std::vector<const __class_type_info*> __getBaseClasses(const __class_type_info* cti) {
+ std::vector<const __class_type_info*> __internalGetBaseClasses(const __class_type_info* cti) {
std::vector<const __class_type_info*> bases;
const __si_class_type_info* scti = dynamic_cast<const __si_class_type_info*>(cti);
@@ -48,7 +48,7 @@ namespace __cxxabiv1 { if (dv == bs) {
paths.emplace_back(newPath);
} else {
- std::vector<const __class_type_info*> bases = __getBaseClasses(dv);
+ std::vector<const __class_type_info*> bases = __internalGetBaseClasses(dv);
for (int i = 0; i < bases.size(); i++) {
__getDerivationPaths(bases[i], bs, newPath, paths);
}
@@ -212,6 +212,15 @@ namespace emscripten { return name;
}
+ 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;
+ }
+
int EMSCRIPTEN_KEEPALIVE __peek32(int p) {
return *(int *)p;
}
@@ -221,6 +230,7 @@ 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);
}));
}
|