Skip to content

Commit e5719f8

Browse files
committed
[GLIB] Handle G_TYPE_STRV in glib API
https://bugs.webkit.org/show_bug.cgi?id=187512 Reviewed by Michael Catanzaro. Source/JavaScriptCore: 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/JavaScriptCore/glib/TestJSC.cpp: (testJSCTypes): (joinFunction): (testJSCFunction): Canonical link: https://commits.webkit.org/202809@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233758 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 03189cd commit e5719f8

7 files changed

Lines changed: 180 additions & 0 deletions

File tree

‎Source/JavaScriptCore/API/glib/JSCContext.cpp‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,48 @@ static GRefPtr<GPtrArray> jscContextJSArrayToGArray(JSCContext* context, JSValue
327327
return gArray;
328328
}
329329

330+
GUniquePtr<char*> jscContextJSArrayToGStrv(JSCContext* context, JSValueRef jsArray, JSValueRef* exception)
331+
{
332+
JSCContextPrivate* priv = context->priv;
333+
if (JSValueIsNull(priv->jsContext.get(), jsArray))
334+
return nullptr;
335+
336+
if (!JSValueIsArray(priv->jsContext.get(), jsArray)) {
337+
*exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid js type for GStrv")));
338+
return nullptr;
339+
}
340+
341+
auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
342+
if (*exception)
343+
return nullptr;
344+
345+
JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
346+
auto* jsLength = JSObjectGetProperty(priv->jsContext.get(), jsArrayObject, lengthString.get(), exception);
347+
if (*exception)
348+
return nullptr;
349+
350+
auto length = JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsLength, exception));
351+
if (*exception)
352+
return nullptr;
353+
354+
GUniquePtr<char*> strv(static_cast<char**>(g_new0(char*, length + 1)));
355+
for (unsigned i = 0; i < length; ++i) {
356+
auto* jsItem = JSObjectGetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, exception);
357+
if (*exception)
358+
return nullptr;
359+
360+
auto jsValueItem = jscContextGetOrCreateValue(context, jsItem);
361+
if (!jsc_value_is_string(jsValueItem.get())) {
362+
*exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), makeString("invalid js type for GStrv: item ", String::number(i), " is not a string")));
363+
return nullptr;
364+
}
365+
366+
strv.get()[i] = jsc_value_to_string(jsValueItem.get());
367+
}
368+
369+
return strv;
370+
}
371+
330372
JSValueRef jscContextGValueToJSValue(JSCContext* context, const GValue* value, JSValueRef* exception)
331373
{
332374
JSCContextPrivate* priv = context->priv;
@@ -377,6 +419,15 @@ JSValueRef jscContextGValueToJSValue(JSCContext* context, const GValue* value, J
377419

378420
if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY))
379421
return jscContextGArrayToJSArray(context, static_cast<GPtrArray*>(ptr), exception);
422+
423+
if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
424+
auto** strv = static_cast<char**>(ptr);
425+
auto strvLength = g_strv_length(strv);
426+
GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_full(strvLength, g_object_unref));
427+
for (unsigned i = 0; i < strvLength; i++)
428+
g_ptr_array_add(gArray.get(), jsc_value_new_string(context, strv[i]));
429+
return jscContextGArrayToJSArray(context, gArray.get(), exception);
430+
}
380431
} else
381432
return JSValueMakeNull(priv->jsContext.get());
382433

@@ -463,6 +514,13 @@ void jscContextJSValueToGValue(JSCContext* context, JSValueRef jsValue, GType ty
463514
return;
464515
}
465516

517+
if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
518+
auto strv = jscContextJSArrayToGStrv(context, jsValue, exception);
519+
if (!*exception)
520+
g_value_take_boxed(value, strv.release());
521+
return;
522+
}
523+
466524
*exception = toRef(JSC::createTypeError(toJS(priv->jsContext.get()), "invalid pointer type"_s));
467525
return;
468526
}

‎Source/JavaScriptCore/API/glib/JSCValue.cpp‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,31 @@ JSCValue* jsc_value_new_array_from_garray(JSCContext* context, GPtrArray* gArray
543543
return jscContextGetOrCreateValue(context, jsArray).leakRef();
544544
}
545545

546+
/**
547+
* jsc_value_new_array_from_strv:
548+
* @context: a #JSCContext
549+
* @strv: (array zero-terminated=1) (element-type utf8): a %NULL-terminated array of strings
550+
*
551+
* Create a new #JSCValue referencing an array of strings with the items from @strv. If @array
552+
* is %NULL or empty a new empty array will be created.
553+
*
554+
* Returns: (transfer full): a #JSCValue.
555+
*/
556+
JSCValue* jsc_value_new_array_from_strv(JSCContext* context, const char* const* strv)
557+
{
558+
g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
559+
560+
auto strvLength = strv ? g_strv_length(const_cast<char**>(strv)) : 0;
561+
if (!strvLength)
562+
return jsc_value_new_array(context, G_TYPE_NONE);
563+
564+
GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_full(strvLength, g_object_unref));
565+
for (unsigned i = 0; i < strvLength; i++)
566+
g_ptr_array_add(gArray.get(), jsc_value_new_string(context, strv[i]));
567+
568+
return jsc_value_new_array_from_garray(context, gArray.get());
569+
}
570+
546571
/**
547572
* jsc_value_is_array:
548573
* @value: a #JSCValue

‎Source/JavaScriptCore/API/glib/JSCValue.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ JSC_API JSCValue *
130130
jsc_value_new_array_from_garray (JSCContext *context,
131131
GPtrArray *array);
132132

133+
JSC_API JSCValue *
134+
jsc_value_new_array_from_strv (JSCContext *context,
135+
const char *const *strv);
136+
133137
JSC_API gboolean
134138
jsc_value_is_array (JSCValue *value);
135139

‎Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ jsc_value_to_string
8080
jsc_value_to_string_as_bytes
8181
jsc_value_new_array
8282
jsc_value_new_array_from_garray
83+
jsc_value_new_array_from_strv
8384
jsc_value_is_array
8485
jsc_value_new_object
8586
jsc_value_is_object

‎Source/JavaScriptCore/ChangeLog‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
2018-07-11 Carlos Garcia Campos <cgarcia@igalia.com>
2+
3+
[GLIB] Handle G_TYPE_STRV in glib API
4+
https://bugs.webkit.org/show_bug.cgi?id=187512
5+
6+
Reviewed by Michael Catanzaro.
7+
8+
Add jsc_value_new_array_from_strv() and handle G_TYPE_STRV types in function parameters.
9+
10+
* API/glib/JSCContext.cpp:
11+
(jscContextGValueToJSValue):
12+
(jscContextJSValueToGValue):
13+
* API/glib/JSCValue.cpp:
14+
(jsc_value_new_array_from_strv):
15+
* API/glib/JSCValue.h:
16+
* API/glib/docs/jsc-glib-4.0-sections.txt:
17+
118
2018-07-11 Yusuke Suzuki <utatane.tea@gmail.com>
219

320
Iterator of Array.keys() returns object in wrong order

‎Tools/ChangeLog‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2018-07-11 Carlos Garcia Campos <cgarcia@igalia.com>
2+
3+
[GLIB] Handle G_TYPE_STRV in glib API
4+
https://bugs.webkit.org/show_bug.cgi?id=187512
5+
6+
Reviewed by Michael Catanzaro.
7+
8+
Add test cases.
9+
10+
* TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp:
11+
(testJSCTypes):
12+
(joinFunction):
13+
(testJSCFunction):
14+
115
2018-07-11 Aakash Jain <aakash_jain@apple.com>
216

317
[ews-build] EWS should unapply patch and re-run jsc tests when patch fails jsc tests

‎Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,20 @@ static void testJSCTypes()
494494
g_assert_true(jsc_value_is_number(arrayLength.get()));
495495
g_assert_cmpint(jsc_value_to_int32(arrayLength.get()), ==, gArray->len);
496496

497+
const char* strv[] = { "one", "two", "three", nullptr };
498+
array = adoptGRef(jsc_value_new_array_from_strv(context.get(), strv));
499+
checker.watch(array.get());
500+
g_assert_true(jsc_value_is_array(array.get()));
501+
g_assert_true(jsc_value_is_object(array.get()));
502+
g_assert_true(jsc_value_to_boolean(array.get()) == TRUE);
503+
g_assert_cmpint(jsc_value_to_int32(array.get()), ==, 0);
504+
valueString.reset(jsc_value_to_string(array.get()));
505+
g_assert_cmpstr(valueString.get(), ==, "one,two,three");
506+
arrayLength = adoptGRef(jsc_value_object_get_property(array.get(), "length"));
507+
checker.watch(arrayLength.get());
508+
g_assert_true(jsc_value_is_number(arrayLength.get()));
509+
g_assert_cmpint(jsc_value_to_int32(arrayLength.get()), ==, 3);
510+
497511
value = adoptGRef(jsc_value_new_object(context.get(), nullptr, nullptr));
498512
checker.watch(value.get());
499513
g_assert_true(jsc_value_is_object(value.get()));
@@ -562,6 +576,11 @@ static int sumFunction(GPtrArray* array)
562576
return retval;
563577
}
564578

579+
static char* joinFunction(const char* const* strv, const char* sep)
580+
{
581+
return g_strjoinv(sep, const_cast<char**>(strv));
582+
}
583+
565584
static void testJSCFunction()
566585
{
567586
{
@@ -744,6 +763,48 @@ static void testJSCFunction()
744763
g_assert_true(jsc_value_is_number(value.get()));
745764
g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 9);
746765
}
766+
767+
{
768+
LeakChecker checker;
769+
GRefPtr<JSCContext> context = adoptGRef(jsc_context_new());
770+
checker.watch(context.get());
771+
ExceptionHandler exceptionHandler(context.get());
772+
773+
GRefPtr<JSCValue> function = adoptGRef(jsc_context_evaluate(context.get(),
774+
"joinFunction = function(array, sep) {\n"
775+
" var result = '';\n"
776+
" for (var i in array) {\n"
777+
" result += array[i];\n"
778+
" if (i != array.length - 1) { result += sep; }\n"
779+
" }\n"
780+
" return result;\n"
781+
"}", -1));
782+
checker.watch(function.get());
783+
g_assert_true(jsc_value_is_object(function.get()));
784+
785+
const char* strv[] = { "one", "two", "three", nullptr };
786+
GRefPtr<JSCValue> value = adoptGRef(jsc_value_function_call(function.get(), G_TYPE_STRV, strv, G_TYPE_STRING, " ", G_TYPE_NONE));
787+
checker.watch(value.get());
788+
g_assert_true(jsc_value_is_string(value.get()));
789+
GUniquePtr<char> valueString(jsc_value_to_string(value.get()));
790+
g_assert_cmpstr(valueString.get(), ==, "one two three");
791+
792+
function = adoptGRef(jsc_value_new_function(context.get(), "joinFunction2", G_CALLBACK(joinFunction), nullptr, nullptr, G_TYPE_STRING, 2, G_TYPE_STRV, G_TYPE_STRING));
793+
checker.watch(function.get());
794+
jsc_context_set_value(context.get(), "joinFunction2", function.get());
795+
value = adoptGRef(jsc_context_evaluate(context.get(), "joinFunction2(['one','two','three'], ' ')", -1));
796+
checker.watch(value.get());
797+
g_assert_true(jsc_value_is_string(value.get()));
798+
GUniquePtr<char> valueString2(jsc_value_to_string(value.get()));
799+
g_assert_cmpstr(valueString2.get(), ==, valueString.get());
800+
801+
bool didThrow = false;
802+
g_assert_throw_begin(exceptionHandler, didThrow);
803+
value = adoptGRef(jsc_context_evaluate(context.get(), "joinFunction2(['one',2,'three'], ' ')", -1));
804+
checker.watch(value.get());
805+
g_assert_true(jsc_value_is_undefined(value.get()));
806+
g_assert_did_throw(exceptionHandler, didThrow);
807+
}
747808
}
748809

749810
static void testJSCObject()

0 commit comments

Comments
 (0)