diff options
author | Bill Welden <bwelden@imvu.com> | 2013-01-08 10:33:53 -0800 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-12 14:23:01 +0300 |
commit | cfb3df1b48f9e1b9c59fd27e0d2608c7fe29a78e (patch) | |
tree | 48e3be86837fb28db884ba70295add3bc0ad1d5a | |
parent | 84b49c917c177e9fa49798b45a543f3ce68bf30b (diff) |
Revert "Revert "Auto upcast of pointer parameters to C++ routines.""
This reverts commit 07e0daa5aab716b38acf9041a8baec3816976579.
-rwxr-xr-x | src/embind/embind.js | 39 | ||||
-rwxr-xr-x | system/include/emscripten/bind.h | 27 | ||||
-rwxr-xr-x | system/lib/embind/bind.cpp | 7 |
3 files changed, 54 insertions, 19 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index b9a16fbb..e02b9e01 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -407,11 +407,12 @@ function __embind_register_struct_field( }; } -function RegisteredPointer(Handle, isPolymorphic, isSmartPointer, rawGetPointee, rawDestructor) { +function RegisteredPointer(Handle, isPolymorphic, isSmartPointer, rawGetPointee, rawConstructor, rawDestructor) { this.Handle = Handle; this.isPolymorphic = isPolymorphic; this.isSmartPointer = isSmartPointer; this.rawGetPointee = rawGetPointee; + this.rawConstructor = rawConstructor; this.rawDestructor = rawDestructor; } @@ -428,19 +429,29 @@ RegisteredPointer.prototype.toWireType = function(destructors, o) { } }; -// todo: distinguish ptr and rawPtr -RegisteredPointer.prototype.toWireTypeAutoUpcast = function(destructors, o) { - if (this.isSmartPointer) { - return this.toWireType(destructors, o); // for now +RegisteredPointer.prototype.toWireTypeAutoUpcast = function(destructors, handle) { + var fromRawType; + if (!handle) { + return null; + } + if (handle.pointeeType.isPolymorphic) { + fromRawType = handle.pointeeType.getDynamicRawPointerType(handle.ptr); } else { - if (o.pointeeType.isPolymorphic) { - var dynamicType = o.pointeeType.getDynamicRawPointerType(o.ptr); - return ___staticPointerCast(o.ptr, dynamicType, this.pointeeType.rawType); - } else { - return ___staticPointerCast(o.ptr, o.pointeeType.rawType, this.pointeeType.rawType); - } - // todo: this cast can fail + fromRawType = handle.pointeeType.rawType; } + if (fromRawType == this.pointeeType.rawType) { + return this.isSmartPointer ? handle.smartPointer : handle.ptr; + } + var ptr = ___staticPointerCast(handle.ptr, fromRawType, this.pointeeType.rawType); + if (this.isSmartPointer) { + var smartPtr = _malloc(16); + // todo: this does not create a pointer that shares the reference count !?!? + handle.pointeeType.smartPointerType.rawConstructor(smartPtr, ptr); + ptr = smartPtr; + destructors.push(handle.pointeeType.smartPointerType.rawDestructor); + destructors.push(ptr); + } + return ptr; }; RegisteredPointer.prototype.getPointee = function(ptr) { @@ -523,11 +534,13 @@ function __embind_register_smart_ptr( rawPointeeType, isPolymorphic, name, + rawConstructor, rawDestructor, rawGetPointee ) { name = Pointer_stringify(name); var pointeeType = requireRegisteredType(rawPointeeType, 'class'); + rawConstructor = FUNCTION_TABLE[rawConstructor]; rawDestructor = FUNCTION_TABLE[rawDestructor]; rawGetPointee = FUNCTION_TABLE[rawGetPointee]; @@ -568,7 +581,7 @@ function __embind_register_smart_ptr( this.smartPointer = undefined; this.ptr = undefined; }; - var registeredPointer = new RegisteredPointer(Handle, isPolymorphic, true, rawGetPointee, rawDestructor); + var registeredPointer = new RegisteredPointer(Handle, isPolymorphic, true, rawGetPointee, rawConstructor, rawDestructor); registeredPointer.pointeeType = pointeeType; pointeeType.smartPointerType = registerType(rawType, name, registeredPointer); } diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 592928f5..bbce9a93 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -98,6 +98,7 @@ namespace emscripten { TYPEID pointeeType, bool isPolymorphic, const char* pointerName, + GenericFunction constructor, GenericFunction destructor, GenericFunction getPointee); @@ -282,9 +283,18 @@ namespace emscripten { return *static_cast<ToType*>(&from); }; + template<typename FromRawType, typename ToRawType, bool isPolymorphic> + struct performShared { + static std::shared_ptr<ToRawType> cast(std::shared_ptr<FromRawType> from) { + return std::dynamic_pointer_cast<ToRawType>(from); + }; + }; + template<typename FromRawType, typename ToRawType> - std::shared_ptr<ToRawType> performSharedStaticCast(std::shared_ptr<FromRawType> from) { - return std::shared_ptr<ToRawType>(from, static_cast<ToRawType*>(from.get())); + struct performShared<FromRawType, ToRawType, false> { + static std::shared_ptr<ToRawType> cast(std::shared_ptr<FromRawType> from) { + return std::shared_ptr<ToRawType>(from, static_cast<ToRawType*>(from.get())); + }; }; template<typename ReturnType, typename... Args, typename... Policies> @@ -312,6 +322,14 @@ namespace emscripten { ); } + template<typename PointerType> + void nullDeallocator(PointerType* p) {} + + template<typename PointerType> + typename std::shared_ptr<PointerType> raw_smart_pointer_constructor(PointerType *ptr, void (PointerType*)) { + return std::shared_ptr<PointerType>(ptr, nullDeallocator<PointerType>); + } + template<typename ClassType> void raw_destructor(ClassType* ptr) { delete ptr; @@ -604,6 +622,7 @@ namespace emscripten { TypeID<PointeeType>::get(), std::is_polymorphic<PointeeType>::value, name, + reinterpret_cast<GenericFunction>(&raw_smart_pointer_constructor<PointeeType*>), reinterpret_cast<GenericFunction>(&raw_destructor<PointerType>), reinterpret_cast<GenericFunction>(&get_pointee<PointerType>)); @@ -620,8 +639,8 @@ namespace emscripten { TypeID<ReturnPointeeType>::get(), std::is_polymorphic<PointeeType>::value, methodName, - reinterpret_cast<GenericFunction>(&performSharedStaticCast<PointeeType,ReturnPointeeType>)); - return *this; + reinterpret_cast<GenericFunction>(&performShared<PointeeType, ReturnPointeeType, std::is_polymorphic<PointeeType>::value>::cast)); + return *this; } }; diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index 46924505..a4b67fa5 100755 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -190,8 +190,6 @@ namespace emscripten { // __dynamicPointerCast performs a C++ dynamic_cast<>() operation, but allowing run-time specification of
// the from and to pointer types.
int EMSCRIPTEN_KEEPALIVE __dynamicPointerCast(int p, int to) {
- // The final parameter is a place-holder for a hint, a feature which is not currently implemented
- // in the emscripten runtime. The compiler passes a dummy value of -1, and so do we.
int ret = (int)__staticPointerCast((void *)p, __getDynamicPointerType(p), to);
if (ret < 0) {
return 0;
@@ -214,11 +212,16 @@ namespace emscripten { return name;
}
+ int EMSCRIPTEN_KEEPALIVE __peek32(int p) {
+ return *(int *)p;
+ }
+
EMSCRIPTEN_BINDINGS(([]() {
// We bind __getDerivationPath in order to take advantage of the std::vector to Javascript array
// 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("__peek32", &__peek32);
}));
}
|