diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h index 81e7c0d2e88f2..9721f66f7999e 100644 --- a/system/include/emscripten/val.h +++ b/system/include/emscripten/val.h @@ -49,7 +49,8 @@ enum { _EMVAL_UNDEFINED = 2, _EMVAL_NULL = 4, _EMVAL_TRUE = 6, - _EMVAL_FALSE = 8 + _EMVAL_FALSE = 8, + _EMVAL_LAST_RESERVED_HANDLE = 8, }; typedef struct _EM_DESTRUCTORS* EM_DESTRUCTORS; @@ -385,11 +386,13 @@ class val { } val(const val& v) : val(v.as_handle()) { - internal::_emval_incref(handle); + if (uses_ref_count()) { + internal::_emval_incref(handle); + } } ~val() { - if (handle) { + if (uses_ref_count()) { internal::_emval_decref(as_handle()); handle = 0; } @@ -402,6 +405,13 @@ class val { return handle; } + // Takes ownership of the handle away from, and invalidates, this instance. + EM_VAL release_ownership() { + EM_VAL taken = as_handle(); + handle = 0; + return taken; + } + val& operator=(val&& v) & { val tmp(std::move(v)); this->~val(); @@ -630,6 +640,12 @@ class val { : handle(handle), thread(pthread_self()) {} + // Whether this value is a uses incref/decref (true) or is a special reserved + // value (false). + bool uses_ref_count() const { + return handle > reinterpret_cast(internal::_EMVAL_LAST_RESERVED_HANDLE); + } + template friend val internal::wrapped_extend(const std::string& , const val& ); @@ -786,9 +802,20 @@ template struct BindingType::value && !std::is_const::value>::type> { typedef EM_VAL WireType; + + // Marshall to JS with move semantics when we can invalidate the temporary val + // object. + static WireType toWireType(val&& v) { + return v.release_ownership(); + } + + // Marshal to JS with copy semantics when we cannot transfer the val objects + // reference count. static WireType toWireType(const val& v) { EM_VAL handle = v.as_handle(); - _emval_incref(handle); + if (v.uses_ref_count()) { + _emval_incref(handle); + } return handle; } static T fromWireType(WireType v) { diff --git a/test/code_size/embind_val_wasm.json b/test/code_size/embind_val_wasm.json index 43f4200146319..8f7f51e0dd8ed 100644 --- a/test/code_size/embind_val_wasm.json +++ b/test/code_size/embind_val_wasm.json @@ -3,8 +3,8 @@ "a.html.gz": 431, "a.js": 7080, "a.js.gz": 2999, - "a.wasm": 11428, - "a.wasm.gz": 5724, - "total": 19181, - "total_gz": 9154 + "a.wasm": 11431, + "a.wasm.gz": 5727, + "total": 19184, + "total_gz": 9157 }