aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/embind/embind.js21
-rwxr-xr-xsystem/include/emscripten/bind.h4
-rwxr-xr-xsystem/lib/embind/bind.cpp60
3 files changed, 73 insertions, 12 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 5ceaf246..643ce728 100755
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -372,7 +372,7 @@ function __embind_register_smart_ptr(
getPointee
) {
name = Pointer_stringify(name);
- pointeeType = requireRegisteredType(pointeeType, 'class');
+ var pointeeTypeImpl = requireRegisteredType(pointeeType, 'class');
destructor = FUNCTION_TABLE[destructor];
getPointee = FUNCTION_TABLE[getPointee];
@@ -384,11 +384,11 @@ function __embind_register_smart_ptr(
// TODO: test for SmartPtr.prototype.constructor property?
// We likely want it distinct from pointeeType.prototype.constructor
- Handle.prototype = Object.create(pointeeType.Handle.prototype);
+ Handle.prototype = Object.create(pointeeTypeImpl.Handle.prototype);
Handle.prototype.clone = function() {
if (!this.ptr) {
- throw new BindingError(pointeeType.name + ' instance already deleted');
+ throw new BindingError(pointeeTypeImpl.name + ' instance already deleted');
}
var clone = Object.create(Handle.prototype);
@@ -402,7 +402,7 @@ function __embind_register_smart_ptr(
Handle.prototype['delete'] = function() {
if (!this.ptr) {
- throw new BindingError(pointeeType.name + ' instance already deleted');
+ throw new BindingError(pointeeTypeImpl.name + ' instance already deleted');
}
this.count.value -= 1;
@@ -695,20 +695,21 @@ function __embind_register_class_method(
};
}
+/*global ___staticPointerCast: false*/
function __embind_register_cast_method(
classType,
methodName,
returnType,
invoker
) {
- classType = requireRegisteredType(classType, 'class');
+ var classTypeImpl = requireRegisteredType(classType, 'class');
methodName = Pointer_stringify(methodName);
- var humanName = classType.name + '.' + methodName;
+ var humanName = classTypeImpl.name + '.' + methodName;
- returnType = requireRegisteredType(returnType, 'method ' + humanName + ' return value');
+ var returnTypeImpl = requireRegisteredType(returnType, 'method ' + humanName + ' return value');
invoker = FUNCTION_TABLE[invoker];
- classType.Handle.prototype[methodName] = function() {
+ classTypeImpl.Handle.prototype[methodName] = function() {
if (!this.ptr) {
throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object');
}
@@ -718,7 +719,9 @@ function __embind_register_cast_method(
var args = new Array(1);
args[0] = this.ptr;
- var rv = returnType.fromWireType(invoker.apply(null, args)); // in case ptr needs to be adjusted for multiple inheritance
+ var rv = returnTypeImpl.fromWireType(invoker.apply(null, args));
+ rv.count = this.count; // the cast value shares the reference count of the original pointer, but does not increment it
+ this.count.value ++;
return rv;
};
}
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 48da7528..48a0fd58 100755
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -279,7 +279,7 @@ namespace emscripten {
template<typename FromRawType, typename ToRawType>
std::shared_ptr<ToRawType> performPointerCast(std::shared_ptr<FromRawType> from) {
- return std::shared_ptr<ToRawType>(from, dynamic_cast<ToRawType*>(from.get()));
+ return std::shared_ptr<ToRawType>(from, static_cast<ToRawType*>(from.get()));
};
template<typename ReturnType, typename... Args, typename... Policies>
@@ -613,7 +613,7 @@ namespace emscripten {
TypeID<PointerType>::get(),
methodName,
TypeID<ReturnType>::get(),
- reinterpret_cast<GenericFunction>(&performPointerCast<PointeeType,ReturnPointeeType>));
+ reinterpret_cast<GenericFunction>(&performPointerCast<PointeeType,ReturnPointeeType>));
return *this;
}
};
diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp
index 9663ad51..de03052a 100755
--- a/system/lib/embind/bind.cpp
+++ b/system/lib/embind/bind.cpp
@@ -27,6 +27,21 @@ namespace __cxxabiv1 {
return bases;
}
+ int __getBaseOffset(const __class_type_info* ctiDv, const __class_type_info* ctiBs) {
+ int offset = 0;
+
+ const __vmi_class_type_info* vcti = dynamic_cast<const __vmi_class_type_info*>(ctiDv);
+ if (vcti) {
+ for (int i = 0; i < vcti->__base_count; i++) {
+ if (vcti->__base_info[i].__base_type == ctiBs) {
+ offset = vcti->__base_info[i].__offset_flags >> __base_class_type_info::__offset_shift;
+ break;
+ }
+ }
+ }
+ return offset;
+ }
+
void __getDerivationPaths(const __class_type_info* dv, const __class_type_info* bs, std::vector<const __class_type_info*>path, std::vector<std::vector<const __class_type_info*>>& paths) {
std::vector<const __class_type_info*> newPath(path);
newPath.emplace_back(dv);
@@ -39,6 +54,14 @@ namespace __cxxabiv1 {
}
}
}
+
+ int __pathOffset(std::vector<const __cxxabiv1::__class_type_info*> path) {
+ int offset = 0;
+ for (int i = 0; i < path.size()-1; i++) {
+ offset += __getBaseOffset(path[i], path[i+1]);
+ }
+ return offset;
+ }
}
namespace emscripten {
@@ -112,10 +135,45 @@ namespace emscripten {
}
}
}
-
return derivationPath;
}
+ void* EMSCRIPTEN_KEEPALIVE __staticPointerCast(void* p, int dv, int bs) {
+ std::vector<std::vector<const __cxxabiv1::__class_type_info*>> paths;
+ int direction = 1;
+
+ const std::type_info* dv1 = (std::type_info*)dv;
+ const std::type_info* bs1 = (std::type_info*)bs;
+ const __cxxabiv1::__class_type_info* dv2 = dynamic_cast<const __cxxabiv1::__class_type_info*>(dv1);
+ const __cxxabiv1::__class_type_info* bs2 = dynamic_cast<const __cxxabiv1::__class_type_info*>(bs1);
+
+ if (dv2 && bs2) {
+ __cxxabiv1::__getDerivationPaths(dv2, bs2, std::vector<const __cxxabiv1::__class_type_info*>(), paths);
+ if (paths.size() == 0) {
+ __cxxabiv1::__getDerivationPaths(bs2, dv2, std::vector<const __cxxabiv1::__class_type_info*>(), paths);
+ direction = -1;
+ }
+ }
+
+ int offset = -1;
+ for (int i = 0; i < paths.size(); i++) {
+ if (offset < 0) {
+ offset = __cxxabiv1::__pathOffset(paths[i]);
+ } else {
+ if (offset != __cxxabiv1::__pathOffset(paths[i])) {
+ return (void *)-2; // ambiguous cast -- throw instead?
+ }
+ }
+ }
+ if (offset < 0) {
+ return (void *)-1; // types are not related -- throw instead?
+ }
+ if (p == 0) {
+ return (void *)0;
+ }
+ return (void *)((int)p + offset * direction);
+ }
+
// __getDynamicPointerType returns (for polymorphic types only!) the type of the instance actually
// pointed to.
int EMSCRIPTEN_KEEPALIVE __getDynamicPointerType(int p) {