Title: [233758] trunk
Revision
233758
Author
carlo...@webkit.org
Date
2018-07-11 22:11:55 -0700 (Wed, 11 Jul 2018)

Log Message

[GLIB] Handle G_TYPE_STRV in glib API
https://bugs.webkit.org/show_bug.cgi?id=187512

Reviewed by Michael Catanzaro.

Source/_javascript_Core:

Add jsc_value_new_array_from_strv() and handle G_TYPE_STRV types in function parameters.

* API/glib/JSCContext.cpp:
(jscContextGValueToJSValue):
(jscContextJSValueToGValue):
* API/glib/JSCValue.cpp:
(jsc_value_new_array_from_strv):
* API/glib/JSCValue.h:
* API/glib/docs/jsc-glib-4.0-sections.txt:

Tools:

Add test cases.

* TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp:
(testJSCTypes):
(joinFunction):
(testJSCFunction):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/glib/JSCContext.cpp (233757 => 233758)


--- trunk/Source/_javascript_Core/API/glib/JSCContext.cpp	2018-07-12 04:08:20 UTC (rev 233757)
+++ trunk/Source/_javascript_Core/API/glib/JSCContext.cpp	2018-07-12 05:11:55 UTC (rev 233758)
@@ -327,6 +327,48 @@
     return gArray;
 }
 
+GUniquePtr<char*> jscContextJSArrayToGStrv(JSCContext* context, JSValueRef jsArray, JSValueRef* exception)
+{
+    JSCContextPrivate* priv = context->priv;
+    if (JSValueIsNull(priv->jsContext.get(), jsArray))
+        return nullptr;
+
+    if (!JSValueIsArray(priv->jsContext.get(), jsArray)) {
+        *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid js type for GStrv")));
+        return nullptr;
+    }
+
+    auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
+    if (*exception)
+        return nullptr;
+
+    JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
+    auto* jsLength = JSObjectGetProperty(priv->jsContext.get(), jsArrayObject, lengthString.get(), exception);
+    if (*exception)
+        return nullptr;
+
+    auto length = JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsLength, exception));
+    if (*exception)
+        return nullptr;
+
+    GUniquePtr<char*> strv(static_cast<char**>(g_new0(char*, length + 1)));
+    for (unsigned i = 0; i < length; ++i) {
+        auto* jsItem = JSObjectGetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, exception);
+        if (*exception)
+            return nullptr;
+
+        auto jsValueItem = jscContextGetOrCreateValue(context, jsItem);
+        if (!jsc_value_is_string(jsValueItem.get())) {
+            *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid js type for GStrv: item ", String::number(i), " is not a string")));
+            return nullptr;
+        }
+
+        strv.get()[i] = jsc_value_to_string(jsValueItem.get());
+    }
+
+    return strv;
+}
+
 JSValueRef jscContextGValueToJSValue(JSCContext* context, const GValue* value, JSValueRef* exception)
 {
     JSCContextPrivate* priv = context->priv;
@@ -377,6 +419,15 @@
 
             if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY))
                 return jscContextGArrayToJSArray(context, static_cast<GPtrArray*>(ptr), exception);
+
+            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
+                auto** strv = static_cast<char**>(ptr);
+                auto strvLength = g_strv_length(strv);
+                GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_full(strvLength, g_object_unref));
+                for (unsigned i = 0; i < strvLength; i++)
+                    g_ptr_array_add(gArray.get(), jsc_value_new_string(context, strv[i]));
+                return jscContextGArrayToJSArray(context, gArray.get(), exception);
+            }
         } else
             return JSValueMakeNull(priv->jsContext.get());
 
@@ -463,6 +514,13 @@
                     return;
                 }
 
+                if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
+                    auto strv = jscContextJSArrayToGStrv(context, jsValue, exception);
+                    if (!*exception)
+                        g_value_take_boxed(value, strv.release());
+                    return;
+                }
+
                 *exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), "invalid pointer type"_s));
                 return;
             }

Modified: trunk/Source/_javascript_Core/API/glib/JSCValue.cpp (233757 => 233758)


--- trunk/Source/_javascript_Core/API/glib/JSCValue.cpp	2018-07-12 04:08:20 UTC (rev 233757)
+++ trunk/Source/_javascript_Core/API/glib/JSCValue.cpp	2018-07-12 05:11:55 UTC (rev 233758)
@@ -544,6 +544,31 @@
 }
 
 /**
+ * jsc_value_new_array_from_strv:
+ * @context: a #JSCContext
+ * @strv: (array zero-terminated=1) (element-type utf8): a %NULL-terminated array of strings
+ *
+ * Create a new #JSCValue referencing an array of strings with the items from @strv. If @array
+ * is %NULL or empty a new empty array will be created.
+ *
+ * Returns: (transfer full): a #JSCValue.
+ */
+JSCValue* jsc_value_new_array_from_strv(JSCContext* context, const char* const* strv)
+{
+    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
+
+    auto strvLength = strv ? g_strv_length(const_cast<char**>(strv)) : 0;
+    if (!strvLength)
+        return jsc_value_new_array(context, G_TYPE_NONE);
+
+    GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_full(strvLength, g_object_unref));
+    for (unsigned i = 0; i < strvLength; i++)
+        g_ptr_array_add(gArray.get(), jsc_value_new_string(context, strv[i]));
+
+    return jsc_value_new_array_from_garray(context, gArray.get());
+}
+
+/**
  * jsc_value_is_array:
  * @value: a #JSCValue
  *

Modified: trunk/Source/_javascript_Core/API/glib/JSCValue.h (233757 => 233758)


--- trunk/Source/_javascript_Core/API/glib/JSCValue.h	2018-07-12 04:08:20 UTC (rev 233757)
+++ trunk/Source/_javascript_Core/API/glib/JSCValue.h	2018-07-12 05:11:55 UTC (rev 233758)
@@ -130,6 +130,10 @@
 jsc_value_new_array_from_garray           (JSCContext           *context,
                                            GPtrArray            *array);
 
+JSC_API JSCValue *
+jsc_value_new_array_from_strv             (JSCContext           *context,
+                                           const char *const    *strv);
+
 JSC_API gboolean
 jsc_value_is_array                        (JSCValue             *value);
 

Modified: trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-4.0-sections.txt (233757 => 233758)


--- trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-4.0-sections.txt	2018-07-12 04:08:20 UTC (rev 233757)
+++ trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-4.0-sections.txt	2018-07-12 05:11:55 UTC (rev 233758)
@@ -80,6 +80,7 @@
 jsc_value_to_string_as_bytes
 jsc_value_new_array
 jsc_value_new_array_from_garray
+jsc_value_new_array_from_strv
 jsc_value_is_array
 jsc_value_new_object
 jsc_value_is_object

Modified: trunk/Source/_javascript_Core/ChangeLog (233757 => 233758)


--- trunk/Source/_javascript_Core/ChangeLog	2018-07-12 04:08:20 UTC (rev 233757)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-07-12 05:11:55 UTC (rev 233758)
@@ -1,3 +1,20 @@
+2018-07-11  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        [GLIB] Handle G_TYPE_STRV in glib API
+        https://bugs.webkit.org/show_bug.cgi?id=187512
+
+        Reviewed by Michael Catanzaro.
+
+        Add jsc_value_new_array_from_strv() and handle G_TYPE_STRV types in function parameters.
+
+        * API/glib/JSCContext.cpp:
+        (jscContextGValueToJSValue):
+        (jscContextJSValueToGValue):
+        * API/glib/JSCValue.cpp:
+        (jsc_value_new_array_from_strv):
+        * API/glib/JSCValue.h:
+        * API/glib/docs/jsc-glib-4.0-sections.txt:
+
 2018-07-11  Yusuke Suzuki  <utatane....@gmail.com>
 
         Iterator of Array.keys() returns object in wrong order

Modified: trunk/Tools/ChangeLog (233757 => 233758)


--- trunk/Tools/ChangeLog	2018-07-12 04:08:20 UTC (rev 233757)
+++ trunk/Tools/ChangeLog	2018-07-12 05:11:55 UTC (rev 233758)
@@ -1,3 +1,17 @@
+2018-07-11  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        [GLIB] Handle G_TYPE_STRV in glib API
+        https://bugs.webkit.org/show_bug.cgi?id=187512
+
+        Reviewed by Michael Catanzaro.
+
+        Add test cases.
+
+        * TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp:
+        (testJSCTypes):
+        (joinFunction):
+        (testJSCFunction):
+
 2018-07-11  Aakash Jain  <aakash_j...@apple.com>
 
         [ews-build] EWS should unapply patch and re-run jsc tests when patch fails jsc tests

Modified: trunk/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp (233757 => 233758)


--- trunk/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp	2018-07-12 04:08:20 UTC (rev 233757)
+++ trunk/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp	2018-07-12 05:11:55 UTC (rev 233758)
@@ -494,6 +494,20 @@
     g_assert_true(jsc_value_is_number(arrayLength.get()));
     g_assert_cmpint(jsc_value_to_int32(arrayLength.get()), ==, gArray->len);
 
+    const char* strv[] = { "one", "two", "three", nullptr };
+    array = adoptGRef(jsc_value_new_array_from_strv(context.get(), strv));
+    checker.watch(array.get());
+    g_assert_true(jsc_value_is_array(array.get()));
+    g_assert_true(jsc_value_is_object(array.get()));
+    g_assert_true(jsc_value_to_boolean(array.get()) == TRUE);
+    g_assert_cmpint(jsc_value_to_int32(array.get()), ==, 0);
+    valueString.reset(jsc_value_to_string(array.get()));
+    g_assert_cmpstr(valueString.get(), ==, "one,two,three");
+    arrayLength = adoptGRef(jsc_value_object_get_property(array.get(), "length"));
+    checker.watch(arrayLength.get());
+    g_assert_true(jsc_value_is_number(arrayLength.get()));
+    g_assert_cmpint(jsc_value_to_int32(arrayLength.get()), ==, 3);
+
     value = adoptGRef(jsc_value_new_object(context.get(), nullptr, nullptr));
     checker.watch(value.get());
     g_assert_true(jsc_value_is_object(value.get()));
@@ -562,6 +576,11 @@
     return retval;
 }
 
+static char* joinFunction(const char* const* strv, const char* sep)
+{
+    return g_strjoinv(sep, const_cast<char**>(strv));
+}
+
 static void testJSCFunction()
 {
     {
@@ -744,6 +763,48 @@
         g_assert_true(jsc_value_is_number(value.get()));
         g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 9);
     }
+
+    {
+        LeakChecker checker;
+        GRefPtr<JSCContext> context = adoptGRef(jsc_context_new());
+        checker.watch(context.get());
+        ExceptionHandler exceptionHandler(context.get());
+
+        GRefPtr<JSCValue> function = adoptGRef(jsc_context_evaluate(context.get(),
+            "joinFunction = function(array, sep) {\n"
+            "    var result = '';\n"
+            "    for (var i in array) {\n"
+            "        result += array[i];\n"
+            "        if (i != array.length - 1) { result += sep; }\n"
+            "    }\n"
+            "    return result;\n"
+            "}", -1));
+        checker.watch(function.get());
+        g_assert_true(jsc_value_is_object(function.get()));
+
+        const char* strv[] = { "one", "two", "three", nullptr };
+        GRefPtr<JSCValue> value = adoptGRef(jsc_value_function_call(function.get(), G_TYPE_STRV, strv, G_TYPE_STRING, " ", G_TYPE_NONE));
+        checker.watch(value.get());
+        g_assert_true(jsc_value_is_string(value.get()));
+        GUniquePtr<char> valueString(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString.get(), ==, "one two three");
+
+        function = adoptGRef(jsc_value_new_function(context.get(), "joinFunction2", G_CALLBACK(joinFunction), nullptr, nullptr, G_TYPE_STRING, 2, G_TYPE_STRV, G_TYPE_STRING));
+        checker.watch(function.get());
+        jsc_context_set_value(context.get(), "joinFunction2", function.get());
+        value = adoptGRef(jsc_context_evaluate(context.get(), "joinFunction2(['one','two','three'], ' ')", -1));
+        checker.watch(value.get());
+        g_assert_true(jsc_value_is_string(value.get()));
+        GUniquePtr<char> valueString2(jsc_value_to_string(value.get()));
+        g_assert_cmpstr(valueString2.get(), ==, valueString.get());
+
+        bool didThrow = false;
+        g_assert_throw_begin(exceptionHandler, didThrow);
+        value = adoptGRef(jsc_context_evaluate(context.get(), "joinFunction2(['one',2,'three'], ' ')", -1));
+        checker.watch(value.get());
+        g_assert_true(jsc_value_is_undefined(value.get()));
+        g_assert_did_throw(exceptionHandler, didThrow);
+    }
 }
 
 static void testJSCObject()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to