diff options
author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2020-10-01 21:26:53 +0200 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2020-10-12 20:03:35 -0700 |
commit | 7256c368e509cb070a7d338cd330542796de7851 (patch) | |
tree | 6ba5b750317cc262c7d91cfeab499bb1677e1995 | |
parent | e531302968dee2087352d141292f5983c82ac7de (diff) | |
download | gjs-7256c368e509cb070a7d338cd330542796de7851.tar.gz |
arg: Don't create temporary values when array types have direct conversion
So far when associating JS arrays to C ones we were always creating a
temporary variable to store the value, before casting it to the final
type, but in case we're handling arrays of types for which we've a
direct conversion function, we don't need to do this, so in such case
let's just call the conversion function on the array element.
-rw-r--r-- | gi/arg.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -36,6 +36,7 @@ #include "gi/gerror.h" #include "gi/gtype.h" #include "gi/interface.h" +#include "gi/js-value-inl.h" #include "gi/object.h" #include "gi/param.h" #include "gi/union.h" @@ -703,6 +704,20 @@ constexpr void array_free_func(T* array) { g_free(array); } +template <GITypeTag TAG, typename T> +GJS_JSAPI_RETURN_CONVENTION static bool js_value_to_c_strict( + JSContext* cx, const JS::HandleValue& value, T* out) { + using ValueHolderT = Gjs::JsValueHolder::Strict<T, TAG>; + if constexpr (Gjs::type_has_js_getter<T, ValueHolderT>()) + return Gjs::js_value_to_c<TAG>(cx, value, out); + + ValueHolderT v; + bool ret = Gjs::js_value_to_c<TAG>(cx, value, &v); + *out = v; + + return ret; +} + template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID> GJS_JSAPI_RETURN_CONVENTION static bool gjs_array_to_auto_array( JSContext* cx, JS::Value array_value, size_t length, void** arr_p) { @@ -715,20 +730,17 @@ GJS_JSAPI_RETURN_CONVENTION static bool gjs_array_to_auto_array( for (size_t i = 0; i < length; ++i) { elem = JS::UndefinedValue(); - Gjs::JsValueHolder::Strict<T, TAG> value; if (!JS_GetElement(cx, array, i, &elem)) { gjs_throw(cx, "Missing array element %" G_GSIZE_FORMAT, i); return false; } - if (!Gjs::js_value_to_c<TAG>(cx, elem, &value)) { + if (!js_value_to_c_strict<TAG>(cx, elem, &result[i])) { gjs_throw(cx, "Invalid element in %s array", Gjs::static_type_name<T, TAG>()); return false; } - - result[i] = value; } *arr_p = result.release(); |