summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@chadaustin.me>2012-10-10 01:46:12 -0700
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:21:15 +0300
commit60bae3faed65429634f1104531b08f938d20b7a3 (patch)
tree8bfec8e6eccaf97a8baeba9a483c27dba2d80d20
parentdb4baa7a70f37b6e4754dacf645d8674e52dad43 (diff)
Some simplifications and optimizations to smart pointer support
-rw-r--r--src/embind/embind.js92
-rw-r--r--system/include/emscripten/bind.h46
2 files changed, 62 insertions, 76 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js
index d9358afd..790c0970 100644
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -354,49 +354,36 @@ function __embind_register_struct_field(
};
}
-function __embind_register_shared_ptr(
- ptrType,
- classType,
- name,
- destructor,
- internalPtrGetter
-) {
- name = Pointer_stringify(name);
- classType = requireRegisteredType(classType, 'class');
- destructor = FUNCTION_TABLE[destructor];
- internalPtrGetter = FUNCTION_TABLE[internalPtrGetter];
-
- var Handle = createNamedFunction(name, function(ptr) {
- this.count = {value: 1};
- this.ptr = ptr;
-
- var args = new Array(1);
- args[0] = ptr;
- this.internalReference = classType.fromWireType(internalPtrGetter.apply(null, args));
- });
+function __embind_register_smart_ptr(
+ pointerType,
+ pointeeType,
+ name,
+ destructor,
+ getPointee
+) {
+ name = Pointer_stringify(name);
+ pointeeType = requireRegisteredType(pointeeType, 'class');
+ destructor = FUNCTION_TABLE[destructor];
+ getPointee = FUNCTION_TABLE[getPointee];
+
+ var Handle = createNamedFunction(name, function(ptr) {
+ this.count = {value: 1};
+ this.smartPointer = ptr;
+ this.ptr = getPointee(ptr);
+ });
+
+ // TODO: test for SmartPtr.prototype.constructor property?
+ // We likely want it distinct from pointeeType.prototype.constructor
+ Handle.prototype = Object.create(pointeeType.Handle.prototype);
- for(var prop in classType.Handle.prototype){
- if(prop === 'clone' || prop === 'move' === prop === 'delete'){
- continue;
- }
-
- function createDuplicatedFunc(prop) {
- return function() {
- console.log(arguments);
- return classType.Handle.prototype[prop].apply(this.internalReference, arguments);
- }
- }
-
- Handle.prototype[prop] = createDuplicatedFunc(prop);
- }
-
- Handle.prototype.clone = function() {
+ Handle.prototype.clone = function() {
if (!this.ptr) {
- throw new BindingError(classType.name + ' instance already deleted');
+ throw new BindingError(pointeeType.name + ' instance already deleted');
}
var clone = Object.create(Handle.prototype);
clone.count = this.count;
+ clone.smartPointer = this.smartPointer;
clone.ptr = this.ptr;
clone.count.value += 1;
@@ -408,30 +395,29 @@ function __embind_register_shared_ptr(
this.delete();
return rv;
};
-
- Handle.prototype['delete'] = function() {
- if (!this.ptr) {
- throw new BindingError(classType.name + ' instance already deleted');
+
+ Handle.prototype['delete'] = function() {
+ if (!this.ptr) {
+ throw new BindingError(pointeeType.name + ' instance already deleted');
}
-
+
this.count.value -= 1;
if (0 === this.count.value) {
- console.log(destructor);
- destructor(this.ptr);
+ destructor(this.smartPointer);
}
+ this.smartPointer = undefined;
this.ptr = undefined;
- }
-
- typeRegistry[ptrType] = {
- name: name,
- Handle: Handle,
- fromWireType: function(ptr) {
- return new Handle(ptr);
+ }
+
+ typeRegistry[pointerType] = {
+ name: name,
+ fromWireType: function(ptr) {
+ return new Handle(ptr);
},
toWireType: function(destructors, o) {
- return o.ptr;
+ return o.ptr;
}
- };
+ };
}
function __embind_register_class(
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 2b84878e..6902eb86 100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -91,12 +91,12 @@ namespace emscripten {
size_t memberPointerSize,
void* memberPointer);
- void _embind_register_shared_ptr(
- TYPEID ptrType,
- TYPEID classType,
- const char* ptrName,
- GenericFunction destructor,
- GenericFunction invoker);
+ void _embind_register_smart_ptr(
+ TYPEID pointerType,
+ TYPEID pointeeType,
+ const char* pointerName,
+ GenericFunction destructor,
+ GenericFunction getPointee);
void _embind_register_class(
TYPEID classType,
@@ -157,7 +157,7 @@ namespace emscripten {
class BindingsDefinition {
public:
template<typename Function>
- BindingsDefinition(Function fn) {
+ BindingsDefinition(Function fn) {
fn();
}
};
@@ -222,9 +222,10 @@ namespace emscripten {
delete ptr;
}
- template<typename ClassType>
- ClassType* getSharedInternalPtr(std::shared_ptr<ClassType>* ptr) {
- return ptr->get();
+ template<typename PointerType>
+ typename PointerType::element_type* get_pointee(PointerType* ptr) {
+ // TODO: replace with general pointer traits implementation
+ return ptr->get();
}
template<typename ClassType, typename ReturnType, typename... Args>
@@ -436,19 +437,18 @@ namespace emscripten {
}
};
- template<typename ClassType>
- class shared_ptr_ {
- public:
- shared_ptr_(const char* name) {
- internal::registerStandardTypes();
- internal::_embind_register_shared_ptr(
- internal::TypeID<std::shared_ptr<ClassType>>::get(),
- internal::TypeID<ClassType>::get(),
- name,
- reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<std::shared_ptr<ClassType>>),
- reinterpret_cast<internal::GenericFunction>(&internal::getSharedInternalPtr<ClassType>));
- }
- };
+ template<typename PointerType>
+ inline void register_smart_ptr(const char* name) {
+ typedef typename PointerType::element_type PointeeType;
+
+ internal::registerStandardTypes();
+ internal::_embind_register_smart_ptr(
+ internal::TypeID<PointerType>::get(),
+ internal::TypeID<PointeeType>::get(),
+ name,
+ reinterpret_cast<internal::GenericFunction>(&internal::raw_destructor<PointerType>),
+ reinterpret_cast<internal::GenericFunction>(&internal::get_pointee<PointerType>));
+ }
// TODO: support class definitions without constructors.
// TODO: support external class constructors