diff options
author | Bill Welden <bwelden@imvu.com> | 2013-01-28 09:12:08 -0800 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-12 14:23:37 +0300 |
commit | e5fca2885bf4d8066b9569548b4ced1b853f0414 (patch) | |
tree | 4ab2b9dd98c2acfd0991e1f83b755ca69951825c /src/embind/embind.js | |
parent | 8a12d4c1c4aa9a57fdc414b3304555de8c7158ac (diff) |
register_smart_ptr changed to .shared_ptr (mod to class definition) -- shared_ptr (outside of class definition) is still allowed
shared pointers passed by reference can be modified by the called code -- the change is now reflected at the Javascript calling level
other minor clean-up and small syntactic changes
Diffstat (limited to 'src/embind/embind.js')
-rwxr-xr-x | src/embind/embind.js | 155 |
1 files changed, 70 insertions, 85 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index d8a4a440..7210dbc1 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -5,7 +5,6 @@ /*global Pointer_stringify, writeStringToMemory*/ /*global __emval_register, _emval_handle_array, __emval_decref*/ /*global ___getDynamicPointerType: false*/ -/*global ___dynamicPointerCast: false*/ /*global ___typeName:false*/ /*global ___staticPointerCast: false*/ @@ -308,6 +307,12 @@ function runDestructors(destructors) { } } +function refreshSmartPointee(handle) { + if (handle && handle.smartPointer) { + handle.ptr = handle.type.smartPointerType.getPointee(handle.smartPointer); + } +} + function makeInvoker(name, argCount, argTypes, invoker, fn) { if (!FUNCTION_TABLE[fn]) { throw new BindingError('function '+name+' is not defined'); @@ -329,6 +334,9 @@ function makeInvoker(name, argCount, argTypes, invoker, fn) { rv = argTypes[0].fromWireType(rv); } runDestructors(destructors); + for (i = 1; i < argCount; i++) { + refreshSmartPointee(arguments[i-1]); + } return rv; }; } @@ -537,21 +545,21 @@ RegisteredPointer.prototype.toWireType = function(destructors, handle) { if (!handle) { return null; } - if (handle.pointeeType.isPolymorphic) { - fromRawType = handle.pointeeType.getDynamicRawPointerType(handle.ptr); + if (handle.type.isPolymorphic) { + fromRawType = handle.type.getDynamicRawPointerType(handle.ptr); } else { - fromRawType = handle.pointeeType.rawType; + fromRawType = handle.type.rawType; } - if (fromRawType === this.pointeeType.rawType) { + if (fromRawType === this.type.rawType) { return this.isSmartPointer ? handle.smartPointer : handle.ptr; } - var ptr = staticPointerCast(handle.ptr, fromRawType, this.pointeeType.rawType); + var ptr = staticPointerCast(handle.ptr, fromRawType, this.type.rawType); if (this.isSmartPointer) { // todo: if ptr == handle.ptr, there's no need to allocate a new smartPtr! - var smartPtr = _malloc(16); - handle.pointeeType.smartPointerType.rawConstructor(smartPtr, ptr, handle.smartPointer); + var smartPtr = _malloc(16); // todo: can we get C++ to tell us the size of the pointer? + handle.type.smartPointerType.rawConstructor(smartPtr, ptr, handle.smartPointer); ptr = smartPtr; - destructors.push(handle.pointeeType.smartPointerType.rawDestructor); + destructors.push(handle.type.smartPointerType.rawDestructor); destructors.push(ptr); } return ptr; @@ -582,7 +590,7 @@ RegisteredPointer.prototype.fromWireType = function(ptr) { RegisteredPointer.prototype.getDynamicRawPointerType = function(ptr) { var type = null; if (this.isPolymorphic) { - if (this.rawGetPointee) { + if (this.rawGetPointee) { // todo: did you mean isSmartPtr? type = ___getDynamicPointerType(this.rawGetPointee(ptr)); } else { type = ___getDynamicPointerType(ptr); @@ -594,8 +602,8 @@ RegisteredPointer.prototype.getDynamicRawPointerType = function(ptr) { RegisteredPointer.prototype.getDynamicDowncastType = function(ptr) { var downcastType = null; var type = this.getDynamicRawPointerType(ptr); - if (type && type !== this.pointeeType.rawType) { - var derivation = Module.__getDerivationPath(type, this.pointeeType.rawType); + if (type && type !== this.type.rawType) { + var derivation = Module.__getDerivationPath(type, this.type.rawType); for (var i = 0; i < derivation.size(); i++) { downcastType = typeRegistry[derivation.at(i)]; if (downcastType) { @@ -615,7 +623,7 @@ RegisteredPointer.prototype.fromWireTypeAutoDowncast = function(ptr) { // ptr is } var toType = this.getDynamicDowncastType(ptr); if (toType) { - var fromType = this.pointeeType; + var fromType = this.type; if (this.isSmartPointer) { handle = toType.smartPointerType.fromWireType(ptr); } else { @@ -641,12 +649,16 @@ function __embind_register_smart_ptr( rawConstructor = FUNCTION_TABLE[rawConstructor]; rawDestructor = FUNCTION_TABLE[rawDestructor]; rawGetPointee = FUNCTION_TABLE[rawGetPointee]; - + + if (name == "") { + name = pointeeType.name + "Ptr"; + } + var Handle = createNamedFunction(name, function(ptr) { this.count = {value: 1}; this.smartPointer = ptr; // std::shared_ptr<T>* this.ptr = rawGetPointee(ptr); // T* - this.pointeeType = pointeeType; + this.type = pointeeType; }); // TODO: test for SmartPtr.prototype.constructor property? @@ -680,7 +692,7 @@ function __embind_register_smart_ptr( this.ptr = undefined; }; var registeredPointer = new RegisteredPointer(Handle, pointeeType.isPolymorphic, true, rawGetPointee, rawConstructor, rawDestructor); - registeredPointer.pointeeType = pointeeType; + registeredPointer.type = pointeeType; pointeeType.smartPointerType = registerType(rawType, name, registeredPointer); } @@ -828,11 +840,13 @@ function __embind_register_class( h.count = {value: 1, ptr: ptr }; h.ptr = ptr; - h.pointeeType = type; // set below + h.type = type; // set below for(var prop in Handle.prototype) { - var dp = Object.getOwnPropertyDescriptor(Handle.prototype, prop); - Object.defineProperty(h, prop, dp); + if (Handle.prototype.hasOwnProperty(prop)) { + var dp = Object.getOwnPropertyDescriptor(Handle.prototype, prop); + Object.defineProperty(h, prop, dp); + } } return h; @@ -875,15 +889,15 @@ function __embind_register_class( // todo: clean this up! var registeredClass = new RegisteredPointer(Handle, isPolymorphic, false); var type = registerType(rawType, name, registeredClass); - registeredClass.pointeeType = type; + registeredClass.type = type; - var registeredClass = new RegisteredPointer(Handle, isPolymorphic, false); + registeredClass = new RegisteredPointer(Handle, isPolymorphic, false); registerType(rawPointerType, name + '*', registeredClass); - registeredClass.pointeeType = type; + registeredClass.type = type; // todo: implement const pointers (no modification Javascript side) - var registeredClass = new RegisteredPointer(Handle, isPolymorphic, false); + registeredClass = new RegisteredPointer(Handle, isPolymorphic, false); registerType(rawConstPointerType, name + ' const*', registeredClass); - registeredClass.pointeeType = type; + registeredClass.type = type; type.constructor = createNamedFunction(type.name, function() { var body = type.constructor.body; @@ -965,26 +979,32 @@ function __embind_register_class_method( rv = argTypes[0].fromWireType(rv); } runDestructors(destructors); + for (i = 1; i < argCount; i++) { + refreshSmartPointee(arguments[i-1]); + } return rv; }; classType.Handle.memberType[methodName] = "method"; }); } -// todo: cast methods should require binding of their target types -function __embind_register_raw_cast_method( +function __embind_register_cast_method( rawClassType, isPolymorphic, methodName, - rawReturnType, - rawInvoker + rawRawReturnType, + rawSharedReturnType, + rawRawCaster, + rawSharedCaster ) { requestDeferredRegistration(function() { var classType = requireRegisteredType(rawClassType, 'class'); methodName = Pointer_stringify(methodName); var humanName = classType.name + '.' + methodName; - var returnType = requireRegisteredType(rawReturnType, 'method ' + humanName + ' return value'); - rawInvoker = FUNCTION_TABLE[rawInvoker]; + var rawReturnType = requireRegisteredType(rawRawReturnType, 'method ' + humanName + ' return value'); + var sharedReturnType = requireRegisteredType(rawSharedReturnType, 'method ' + humanName + ' shared pointer return value'); + var rawCaster = FUNCTION_TABLE[rawRawCaster]; + var sharedCaster = FUNCTION_TABLE[rawSharedCaster]; classType.Handle.prototype[methodName] = function() { if (!this.ptr) { throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object'); @@ -995,11 +1015,11 @@ function __embind_register_raw_cast_method( if (isPolymorphic) { // todo: this is all only to validate the cast -- cache the result var runtimeType = ___getDynamicPointerType(this.ptr); - var derivation = Module.__getDerivationPath(rawReturnType, runtimeType); // downcast is valid + var derivation = Module.__getDerivationPath(rawRawReturnType, runtimeType); // downcast is valid var size = derivation.size(); derivation.delete(); if (size === 0) { - derivation = Module.__getDerivationPath(runtimeType, rawReturnType); // upcast is valid + derivation = Module.__getDerivationPath(runtimeType, rawRawReturnType); // upcast is valid size = derivation.size(); derivation.delete(); if (size === 0) { @@ -1007,60 +1027,25 @@ function __embind_register_raw_cast_method( } } } - var args = new Array(1); - args[0] = this.ptr; - var ptr = rawInvoker.apply(null, args); - var rv = returnType.fromWireType(ptr); - rv.count = this.count; - this.count.value ++; - return rv; - }; - }); -} - -// todo: cast methods should not be passed from the smart ptr to the contained object!! -function __embind_register_smart_cast_method( - rawPointerType, - rawReturnType, - returnPointeeType, - isPolymorphic, - methodName, - rawInvoker -) { - requestDeferredRegistration(function() { - var pointerType = requireRegisteredType(rawPointerType, 'smart pointer class'); - methodName = Pointer_stringify(methodName); - var humanName = pointerType.name + '.' + methodName; - var returnType = requireRegisteredType(rawReturnType, 'method ' + humanName + ' return value'); - rawInvoker = FUNCTION_TABLE[rawInvoker]; - pointerType.Handle.prototype[methodName] = function() { - if (!this.ptr) { - throw new BindingError('cannot call emscripten binding method ' + humanName + ' on deleted object'); - } - if (arguments.length !== 0) { - throw new BindingError('emscripten binding method ' + humanName + ' called with arguments, none expected'); - } - if (isPolymorphic) { - // todo: just validating the cast -- cache the result - var runtimeType = ___getDynamicPointerType(this.ptr); - var derivation = Module.__getDerivationPath(returnPointeeType, runtimeType); // downcast is valid - var size = derivation.size(); - derivation.delete(); - if (size === 0) { - derivation = Module.__getDerivationPath(runtimeType, returnPointeeType); // upcast is valid - size = derivation.size(); - derivation.delete(); - if (size === 0) { - throw new CastError("Pointer conversion is not available"); - } - } + var args; + var ptr; + var rv; + if (this.smartPointer) { + args = new Array(2); + ptr = _malloc(8); + args[0] = ptr; + args[1] = this.smartPointer; + sharedCaster.apply(null,args); // need a smart pointer raw invoker + rv = sharedReturnType.fromWireType(ptr); + } else { + args = new Array(1); + args[0] = this.ptr; + ptr = rawCaster.apply(null, args); + rv = rawReturnType.fromWireType(ptr); + rv.count = this.count; + this.count.value ++; } - var args = new Array(2); - var ptr = _malloc(8); - args[0] = ptr; - args[1] = this.smartPointer; - rawInvoker.apply(null,args); - return returnType.fromWireType(ptr); + return rv; }; }); } |