diff options
-rwxr-xr-x | src/embind/emval.js | 28 | ||||
-rwxr-xr-x | system/include/emscripten/bind.h | 10 | ||||
-rw-r--r-- | system/include/emscripten/val.h | 21 |
3 files changed, 44 insertions, 15 deletions
diff --git a/src/embind/emval.js b/src/embind/emval.js index c4f06503..68b613f3 100755 --- a/src/embind/emval.js +++ b/src/embind/emval.js @@ -1,9 +1,9 @@ /*global Module*/ /*global HEAP32*/ /*global readLatin1String, writeStringToMemory*/ -/*global requireRegisteredType*/ +/*global requireRegisteredType, throwBindingError*/ -var _emval_handle_array = []; +var _emval_handle_array = [{}]; // reserve zero var _emval_free_list = []; // Public JS API @@ -11,7 +11,7 @@ var _emval_free_list = []; /** @expose */ Module.count_emval_handles = function() { var count = 0; - for (var i = 0; i < _emval_handle_array.length; ++i) { + for (var i = 1; i < _emval_handle_array.length; ++i) { if (_emval_handle_array[i] !== undefined) { ++count; } @@ -21,7 +21,7 @@ Module.count_emval_handles = function() { /** @expose */ Module.get_first_emval = function() { - for (var i = 0; i < _emval_handle_array.length; ++i) { + for (var i = 1; i < _emval_handle_array.length; ++i) { if (_emval_handle_array[i] !== undefined) { return _emval_handle_array[i]; } @@ -31,6 +31,12 @@ Module.get_first_emval = function() { // Private C++ API +function requireHandle(handle) { + if (!handle) { + throwBindingError('Cannot use deleted val. handle = ' + handle); + } +} + function __emval_register(value) { var handle = _emval_free_list.length ? _emval_free_list.pop() : @@ -41,11 +47,13 @@ function __emval_register(value) { } function __emval_incref(handle) { - _emval_handle_array[handle].refcount += 1; + if (handle) { + _emval_handle_array[handle].refcount += 1; + } } function __emval_decref(handle) { - if (0 === --_emval_handle_array[handle].refcount) { + if (handle && 0 === --_emval_handle_array[handle].refcount) { delete _emval_handle_array[handle]; _emval_free_list.push(handle); @@ -86,6 +94,8 @@ function __emval_take_value(type, v) { var __newers = {}; // arity -> function function __emval_new(handle, argCount, argTypes) { + requireHandle(handle); + var args = parseParameters( argCount, argTypes, @@ -137,14 +147,17 @@ function __emval_get_module_property(name) { } function __emval_get_property(handle, key) { + requireHandle(handle); return __emval_register(_emval_handle_array[handle].value[_emval_handle_array[key].value]); } function __emval_set_property(handle, key, value) { + requireHandle(handle); _emval_handle_array[handle].value[_emval_handle_array[key].value] = _emval_handle_array[value].value; } function __emval_as(handle, returnType) { + requireHandle(handle); returnType = requireRegisteredType(returnType, 'emval::as'); var destructors = []; // caller owns destructing @@ -163,6 +176,7 @@ function parseParameters(argCount, argTypes, argWireTypes) { } function __emval_call(handle, argCount, argTypes) { + requireHandle(handle); var fn = _emval_handle_array[handle].value; var args = parseParameters( argCount, @@ -173,6 +187,7 @@ function __emval_call(handle, argCount, argTypes) { } function __emval_call_method(handle, name, argCount, argTypes) { + requireHandle(handle); name = readLatin1String(name); var args = parseParameters( @@ -185,6 +200,7 @@ function __emval_call_method(handle, name, argCount, argTypes) { } function __emval_call_void_method(handle, name, argCount, argTypes) { + requireHandle(handle); name = readLatin1String(name); var args = parseParameters( diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 894586a6..a3886031 100755 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -284,8 +284,8 @@ namespace emscripten { } template<typename WrapperType, typename ClassType, typename... Args> - WrapperType wrapped_new(Args... args) { - return WrapperType(new ClassType(args...)); + WrapperType wrapped_new(Args&&... args) { + return WrapperType(new ClassType(std::forward<Args>(args)...)); } template<typename ClassType, typename... Args> @@ -718,8 +718,8 @@ namespace emscripten { template<typename T> class wrapper : public T { public: - explicit wrapper(const val& wrapped) - : wrapped(wrapped) + explicit wrapper(val&& wrapped) + : wrapped(std::forward<val>(wrapped)) {} template<typename ReturnType, typename... Args> @@ -760,7 +760,7 @@ namespace emscripten { }; #define EMSCRIPTEN_WRAPPER(T) \ - T(const ::emscripten::val& v): wrapper(v) {} + T(::emscripten::val&& v): wrapper(std::forward<::emscripten::val>(v)) {} namespace internal { struct NoBaseClass { diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h index d32c9650..1fccd434 100644 --- a/system/include/emscripten/val.h +++ b/system/include/emscripten/val.h @@ -101,18 +101,24 @@ namespace emscripten { } template<typename T> - explicit val(const T& value) { + explicit val(T&& value) { typedef internal::BindingType<T> BT; auto taker = reinterpret_cast<internal::EM_VAL (*)(internal::TYPEID, typename BT::WireType)>(&internal::_emval_take_value); - handle = taker(internal::TypeID<T>::get(), BT::toWireType(value)); + handle = taker(internal::TypeID<T>::get(), BT::toWireType(std::forward<T>(value))); } val() = delete; - val(const char* v) + explicit val(const char* v) : handle(internal::_emval_new_cstring(v)) {} + val(val&& v) + : handle(v.handle) + { + v.handle = 0; + } + val(const val& v) : handle(v.handle) { @@ -123,6 +129,13 @@ namespace emscripten { internal::_emval_decref(handle); } + val& operator=(val&& v) { + internal::_emval_decref(handle); + handle = v.handle; + v.handle = 0; + return *this; + } + val& operator=(const val& v) { internal::_emval_incref(v.handle); internal::_emval_decref(handle); @@ -260,7 +273,7 @@ namespace emscripten { template<> struct BindingType<val> { typedef internal::EM_VAL WireType; - static WireType toWireType(val v) { + static WireType toWireType(const val& v) { _emval_incref(v.handle); return v.handle; } |