aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/embind/emval.js28
-rwxr-xr-xsystem/include/emscripten/bind.h10
-rw-r--r--system/include/emscripten/val.h21
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;
}