summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2020-10-01 21:26:53 +0200
committerPhilip Chimento <philip.chimento@gmail.com>2020-10-12 20:03:35 -0700
commit7256c368e509cb070a7d338cd330542796de7851 (patch)
tree6ba5b750317cc262c7d91cfeab499bb1677e1995
parente531302968dee2087352d141292f5983c82ac7de (diff)
downloadgjs-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.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 5b8e5f76..4aefe7fc 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -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();