aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Welden <bwelden@imvu.com>2013-01-08 10:33:53 -0800
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:23:01 +0300
commitcfb3df1b48f9e1b9c59fd27e0d2608c7fe29a78e (patch)
tree48e3be86837fb28db884ba70295add3bc0ad1d5a
parent84b49c917c177e9fa49798b45a543f3ce68bf30b (diff)
Revert "Revert "Auto upcast of pointer parameters to C++ routines.""
This reverts commit 07e0daa5aab716b38acf9041a8baec3816976579.
-rwxr-xr-xsrc/embind/embind.js39
-rwxr-xr-xsystem/include/emscripten/bind.h27
-rwxr-xr-xsystem/lib/embind/bind.cpp7
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);
}));
}