diff options
author | Chad Austin <chad@chadaustin.me> | 2012-10-10 01:46:12 -0700 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-12 14:21:15 +0300 |
commit | 60bae3faed65429634f1104531b08f938d20b7a3 (patch) | |
tree | 8bfec8e6eccaf97a8baeba9a483c27dba2d80d20 | |
parent | db4baa7a70f37b6e4754dacf645d8674e52dad43 (diff) |
Some simplifications and optimizations to smart pointer support
-rw-r--r-- | src/embind/embind.js | 92 | ||||
-rw-r--r-- | system/include/emscripten/bind.h | 46 |
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 |