Changeset 233760 in webkit


Ignore:
Timestamp:
Jul 11, 2018 10:18:20 PM (6 years ago)
Author:
Carlos Garcia Campos
Message:

[GLIB] Add API to allow creating variadic functions
https://bugs.webkit.org/show_bug.cgi?id=187517

Reviewed by Michael Catanzaro.

Source/JavaScriptCore:

Add a _variadic alternate method for jsc_class_add_constructor, jsc_class_add_method and
jsc_value_new_function. In that case the callback always receives a GPtrArray of JSCValue.

  • API/glib/JSCCallbackFunction.cpp:

(JSC::JSCCallbackFunction::create): Make the parameters optional.
(JSC::JSCCallbackFunction::JSCCallbackFunction): Ditto.
(JSC::JSCCallbackFunction::call): Handle the case of parameters being nullopt by creating a GPtrArray of
JSCValue for the arguments.
(JSC::JSCCallbackFunction::construct): Ditto.

  • API/glib/JSCCallbackFunction.h:
  • API/glib/JSCClass.cpp:

(jscClassCreateConstructor): Make the parameters optional.
(jsc_class_add_constructor_variadic): Pass nullopt as parameters to jscClassCreateConstructor.
(jscClassAddMethod): Make the parameters optional.
(jsc_class_add_method_variadic): Pass nullopt as parameters to jscClassAddMethod.

  • API/glib/JSCClass.h:
  • API/glib/JSCValue.cpp:

(jsc_value_object_define_property_accessor): Update now that parameters are optional.
(jscValueFunctionCreate): Make the parameters optional.
(jsc_value_new_function_variadic): Pass nullopt as parameters to jscValueFunctionCreate.

  • API/glib/JSCValue.h:
  • API/glib/docs/jsc-glib-4.0-sections.txt:

Tools:

Add test cases.

  • TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp:

(testJSCFunction):
(fooCreateWithFooV):
(multiplyFooV):

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/glib/JSCCallbackFunction.cpp

    r233122 r233760  
    5454const ClassInfo JSCCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCCallbackFunction) };
    5555
    56 JSCCallbackFunction* JSCCallbackFunction::create(VM& vm, JSGlobalObject* globalObject, const String& name, Type type, JSCClass* jscClass, GRefPtr<GClosure>&& closure, GType returnType, Vector<GType>&& parameters)
     56JSCCallbackFunction* JSCCallbackFunction::create(VM& vm, JSGlobalObject* globalObject, const String& name, Type type, JSCClass* jscClass, GRefPtr<GClosure>&& closure, GType returnType, std::optional<Vector<GType>>&& parameters)
    5757{
    5858    Structure* structure = globalObject->glibCallbackFunctionStructure();
     
    6262}
    6363
    64 JSCCallbackFunction::JSCCallbackFunction(VM& vm, Structure* structure, Type type, JSCClass* jscClass, GRefPtr<GClosure>&& closure, GType returnType, Vector<GType>&& parameters)
     64JSCCallbackFunction::JSCCallbackFunction(VM& vm, Structure* structure, Type type, JSCClass* jscClass, GRefPtr<GClosure>&& closure, GType returnType, std::optional<Vector<GType>>&& parameters)
    6565    : InternalFunction(vm, structure, APICallbackFunction::call<JSCCallbackFunction>, type == Type::Constructor ? APICallbackFunction::construct<JSCCallbackFunction> : nullptr)
    6666    , m_functionCallback(callAsFunction)
     
    100100
    101101    // GClosure always expect to have at least the instance parameter.
    102     bool addInstance = instance || m_parameters.isEmpty();
    103 
    104     auto parameterCount = std::min(m_parameters.size(), argumentCount);
     102    bool addInstance = instance || (m_parameters && m_parameters->isEmpty());
     103
     104    auto parameterCount = m_parameters ? std::min(m_parameters->size(), argumentCount) : 1;
    105105    if (addInstance)
    106106        parameterCount++;
     
    114114        firstParameter = 1;
    115115    }
    116     for (size_t i = firstParameter; i < parameterCount && !*exception; ++i)
    117         jscContextJSValueToGValue(context.get(), arguments[i - firstParameter], m_parameters[i - firstParameter], &values[i], exception);
     116    if (m_parameters) {
     117        for (size_t i = firstParameter; i < parameterCount && !*exception; ++i)
     118            jscContextJSValueToGValue(context.get(), arguments[i - firstParameter], m_parameters.value()[i - firstParameter], &values[i], exception);
     119    } else {
     120        auto* parameters = g_ptr_array_new_full(argumentCount, g_object_unref);
     121        for (size_t i = 0; i < argumentCount; ++i)
     122            g_ptr_array_add(parameters, jscContextGetOrCreateValue(context.get(), arguments[i]).leakRef());
     123        g_value_init(&values[firstParameter], G_TYPE_PTR_ARRAY);
     124        g_value_take_boxed(&values[firstParameter], parameters);
     125    }
    118126
    119127    GValue returnValue = G_VALUE_INIT;
     
    156164    g_value_init(&returnValue, m_returnType);
    157165
    158     if (m_parameters.isEmpty()) {
     166    if (m_parameters && m_parameters->isEmpty()) {
    159167        // GClosure always expect to have at least the instance parameter.
    160168        GValue dummyValue = G_VALUE_INIT;
     
    163171        g_value_unset(&dummyValue);
    164172    } else {
    165         auto parameterCount = std::min(m_parameters.size(), argumentCount);
     173        auto parameterCount = m_parameters ? std::min(m_parameters->size(), argumentCount) : 1;
    166174        auto* values = static_cast<GValue*>(g_alloca(sizeof(GValue) * parameterCount));
    167175        memset(values, 0, sizeof(GValue) * parameterCount);
    168176
    169         for (size_t i = 0; i < parameterCount && !*exception; ++i)
    170             jscContextJSValueToGValue(context.get(), arguments[i], m_parameters[i], &values[i], exception);
     177        if (m_parameters) {
     178            for (size_t i = 0; i < parameterCount && !*exception; ++i)
     179                jscContextJSValueToGValue(context.get(), arguments[i], m_parameters.value()[i], &values[i], exception);
     180        } else {
     181            auto* parameters = g_ptr_array_new_full(argumentCount, g_object_unref);
     182            for (size_t i = 0; i < argumentCount; ++i)
     183                g_ptr_array_add(parameters, jscContextGetOrCreateValue(context.get(), arguments[i]).leakRef());
     184            g_value_init(&values[0], G_TYPE_PTR_ARRAY);
     185            g_value_take_boxed(&values[0], parameters);
     186        }
    171187
    172188        if (!*exception)
  • trunk/Source/JavaScriptCore/API/glib/JSCCallbackFunction.h

    r230813 r233760  
    5353    };
    5454
    55     static JSCCallbackFunction* create(VM&, JSGlobalObject*, const String& name, Type, JSCClass*, GRefPtr<GClosure>&&, GType, Vector<GType>&&);
     55    static JSCCallbackFunction* create(VM&, JSGlobalObject*, const String& name, Type, JSCClass*, GRefPtr<GClosure>&&, GType, std::optional<Vector<GType>>&&);
    5656    static void destroy(JSCell*);
    5757
     
    7070    static IsoSubspace* subspaceForImpl(VM&);
    7171   
    72     JSCCallbackFunction(VM&, Structure*, Type, JSCClass*, GRefPtr<GClosure>&&, GType, Vector<GType>&&);
     72    JSCCallbackFunction(VM&, Structure*, Type, JSCClass*, GRefPtr<GClosure>&&, GType, std::optional<Vector<GType>>&&);
    7373
    7474    JSObjectCallAsFunctionCallback functionCallback() { return m_functionCallback; }
     
    8181    GRefPtr<GClosure> m_closure;
    8282    GType m_returnType;
    83     Vector<GType> m_parameters;
     83    std::optional<Vector<GType>> m_parameters;
    8484};
    8585
  • trunk/Source/JavaScriptCore/API/glib/JSCClass.cpp

    r231693 r233760  
    522522}
    523523
    524 static GRefPtr<JSCValue> jscClassCreateConstructor(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, Vector<GType>&& parameters)
     524static GRefPtr<JSCValue> jscClassCreateConstructor(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, std::optional<Vector<GType>>&& parameters)
    525525{
    526526    JSCClassPrivate* priv = jscClass->priv;
     
    556556 * @destroy_notify is called with @user_data as parameter.
    557557 *
    558  * This function creates the constructor, that needs to be added to an object as a property to be able to use it. Use
     558 * This function creates the constructor, which needs to be added to an object as a property to be able to use it. Use
    559559 * jsc_context_set_value() to make the constructor available in the global object.
    560560 *
     
    602602 * @destroy_notify is called with @user_data as parameter.
    603603 *
    604  * This function creates the constructor, that needs to be added to an object as a property to be able to use it. Use
     604 * This function creates the constructor, which needs to be added to an object as a property to be able to use it. Use
    605605 * jsc_context_set_value() to make the constructor available in the global object.
    606606 *
     
    629629}
    630630
    631 static void jscClassAddMethod(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, Vector<GType>&& parameters)
     631/**
     632 * jsc_class_add_constructor_variadic:
     633 * @jsc_class: a #JSCClass
     634 * @name: (nullable): the constructor name or %NULL
     635 * @callback: (scope async): a #GCallback to be called to create an instance of @jsc_class
     636 * @user_data: (closure): user data to pass to @callback
     637 * @destroy_notify: (nullable): destroy notifier for @user_data
     638 * @return_type: the #GType of the constructor return value
     639 *
     640 * Add a constructor to @jsc_class. If @name is %NULL, the class name will be used. When <function>new</function>
     641 * is used with the constructor or jsc_value_constructor_call() is called, @callback is invoked receiving
     642 * a #GPtrArray of #JSCValue<!-- -->s as arguments and @user_data as the last parameter. When the constructor object
     643 * is cleared in the #JSCClass context, @destroy_notify is called with @user_data as parameter.
     644 *
     645 * This function creates the constructor, which needs to be added to an object as a property to be able to use it. Use
     646 * jsc_context_set_value() to make the constructor available in the global object.
     647 *
     648 * Returns: (transfer full): a #JSCValue representing the class constructor.
     649 */
     650JSCValue* jsc_class_add_constructor_variadic(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType)
     651{
     652    g_return_val_if_fail(JSC_IS_CLASS(jscClass), nullptr);
     653    g_return_val_if_fail(callback, nullptr);
     654
     655    JSCClassPrivate* priv = jscClass->priv;
     656    g_return_val_if_fail(jscClass->priv->context, nullptr);
     657
     658    if (!name)
     659        name = priv->name.data();
     660
     661    return jscClassCreateConstructor(jscClass, name ? name : priv->name.data(), callback, userData, destroyNotify, returnType, std::nullopt).leakRef();
     662}
     663
     664static void jscClassAddMethod(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, std::optional<Vector<GType>>&& parameters)
    632665{
    633666    JSCClassPrivate* priv = jscClass->priv;
     
    715748
    716749/**
     750 * jsc_class_add_method_variadic:
     751 * @jsc_class: a #JSCClass
     752 * @name: the method name
     753 * @callback: (scope async): a #GCallback to be called to invoke method @name of @jsc_class
     754 * @user_data: (closure): user data to pass to @callback
     755 * @destroy_notify: (nullable): destroy notifier for @user_data
     756 * @return_type: the #GType of the method return value, or %G_TYPE_NONE if the method is void.
     757 *
     758 * Add method with @name to @jsc_class. When the method is called by JavaScript or jsc_value_object_invoke_method(),
     759 * @callback is called receiving the class instance as first parameter, followed by a #GPtrArray of #JSCValue<!-- -->s
     760 * with the method arguments and then @user_data as last parameter. When the method is cleared in the #JSCClass context,
     761 * @destroy_notify is called with @user_data as parameter.
     762 */
     763void jsc_class_add_method_variadic(JSCClass* jscClass, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType)
     764{
     765    g_return_if_fail(JSC_IS_CLASS(jscClass));
     766    g_return_if_fail(name);
     767    g_return_if_fail(callback);
     768    g_return_if_fail(jscClass->priv->context);
     769
     770    jscClassAddMethod(jscClass, name, callback, userData, destroyNotify, returnType, std::nullopt);
     771}
     772
     773/**
    717774 * jsc_class_add_property:
    718775 * @jsc_class: a #JSCClass
  • trunk/Source/JavaScriptCore/API/glib/JSCClass.h

    r231693 r233760  
    7777
    7878JSC_API GType
    79 jsc_class_get_type         (void);
     79jsc_class_get_type                 (void);
    8080
    8181JSC_API const char *
    82 jsc_class_get_name         (JSCClass      *jsc_class);
     82jsc_class_get_name                 (JSCClass      *jsc_class);
    8383
    8484JSC_API JSCClass *
    85 jsc_class_get_parent       (JSCClass      *jsc_class);
     85jsc_class_get_parent               (JSCClass      *jsc_class);
    8686
    8787JSC_API JSCValue *
    88 jsc_class_add_constructor  (JSCClass      *jsc_class,
    89                             const char    *name,
    90                             GCallback      callback,
    91                             gpointer       user_data,
    92                             GDestroyNotify destroy_notify,
    93                             GType          return_type,
    94                             guint          n_params,
    95                             ...);
     88jsc_class_add_constructor          (JSCClass      *jsc_class,
     89                                    const char    *name,
     90                                    GCallback      callback,
     91                                    gpointer       user_data,
     92                                    GDestroyNotify destroy_notify,
     93                                    GType          return_type,
     94                                    guint          n_params,
     95                                    ...);
    9696
    9797JSC_API JSCValue *
    98 jsc_class_add_constructorv (JSCClass      *jsc_class,
    99                             const char    *name,
    100                             GCallback      callback,
    101                             gpointer       user_data,
    102                             GDestroyNotify destroy_notify,
    103                             GType          return_type,
    104                             guint          n_parameters,
    105                             GType         *parameter_types);
     98jsc_class_add_constructorv         (JSCClass      *jsc_class,
     99                                    const char    *name,
     100                                    GCallback      callback,
     101                                    gpointer       user_data,
     102                                    GDestroyNotify destroy_notify,
     103                                    GType          return_type,
     104                                    guint          n_parameters,
     105                                    GType         *parameter_types);
     106
     107JSC_API JSCValue *
     108jsc_class_add_constructor_variadic (JSCClass      *jsc_class,
     109                                    const char    *name,
     110                                    GCallback      callback,
     111                                    gpointer       user_data,
     112                                    GDestroyNotify destroy_notify,
     113                                    GType          return_type);
    106114
    107115JSC_API void
    108 jsc_class_add_method       (JSCClass      *jsc_class,
    109                             const char    *name,
    110                             GCallback      callback,
    111                             gpointer       user_data,
    112                             GDestroyNotify destroy_notify,
    113                             GType          return_type,
    114                             guint          n_params,
    115                             ...);
     116jsc_class_add_method               (JSCClass      *jsc_class,
     117                                    const char    *name,
     118                                    GCallback      callback,
     119                                    gpointer       user_data,
     120                                    GDestroyNotify destroy_notify,
     121                                    GType          return_type,
     122                                    guint          n_params,
     123                                    ...);
    116124
    117125JSC_API void
    118 jsc_class_add_methodv      (JSCClass      *jsc_class,
    119                             const char    *name,
    120                             GCallback      callback,
    121                             gpointer       user_data,
    122                             GDestroyNotify destroy_notify,
    123                             GType          return_type,
    124                             guint          n_parameters,
    125                             GType         *parameter_types);
     126jsc_class_add_methodv              (JSCClass      *jsc_class,
     127                                    const char    *name,
     128                                    GCallback      callback,
     129                                    gpointer       user_data,
     130                                    GDestroyNotify destroy_notify,
     131                                    GType          return_type,
     132                                    guint          n_parameters,
     133                                    GType         *parameter_types);
    126134
    127135JSC_API void
    128 jsc_class_add_property     (JSCClass      *jsc_class,
    129                             const char    *name,
    130                             GType          property_type,
    131                             GCallback      getter,
    132                             GCallback      setter,
    133                             gpointer       user_data,
    134                             GDestroyNotify destroy_notify);
     136jsc_class_add_method_variadic      (JSCClass      *jsc_class,
     137                                    const char    *name,
     138                                    GCallback      callback,
     139                                    gpointer       user_data,
     140                                    GDestroyNotify destroy_notify,
     141                                    GType          return_type);
     142
     143JSC_API void
     144jsc_class_add_property             (JSCClass      *jsc_class,
     145                                    const char    *name,
     146                                    GType          property_type,
     147                                    GCallback      getter,
     148                                    GCallback      setter,
     149                                    gpointer       user_data,
     150                                    GDestroyNotify destroy_notify);
    135151
    136152G_END_DECLS
  • trunk/Source/JavaScriptCore/API/glib/JSCValue.cpp

    r233758 r233760  
    10901090        GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(getter, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify))));
    10911091        auto* functionObject = toRef(JSC::JSCCallbackFunction::create(vm, exec->lexicalGlobalObject(), "get"_s,
    1092             JSC::JSCCallbackFunction::Type::Method, nullptr, WTFMove(closure), propertyType, { }));
     1092            JSC::JSCCallbackFunction::Type::Method, nullptr, WTFMove(closure), propertyType, Vector<GType> { }));
    10931093        GRefPtr<JSCValue> function = jscContextGetOrCreateValue(priv->context.get(), functionObject);
    10941094        jsc_value_object_set_property(descriptor.get(), "get", function.get());
     
    10971097        GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(setter, userData, getter ? nullptr : reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify))));
    10981098        auto* functionObject = toRef(JSC::JSCCallbackFunction::create(vm, exec->lexicalGlobalObject(), "set"_s,
    1099             JSC::JSCCallbackFunction::Type::Method, nullptr, WTFMove(closure), G_TYPE_NONE, { propertyType }));
     1099            JSC::JSCCallbackFunction::Type::Method, nullptr, WTFMove(closure), G_TYPE_NONE, Vector<GType> { propertyType }));
    11001100        GRefPtr<JSCValue> function = jscContextGetOrCreateValue(priv->context.get(), functionObject);
    11011101        jsc_value_object_set_property(descriptor.get(), "set", function.get());
     
    11061106}
    11071107
    1108 static GRefPtr<JSCValue> jscValueFunctionCreate(JSCContext* context, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, Vector<GType>&& parameters)
     1108static GRefPtr<JSCValue> jscValueFunctionCreate(JSCContext* context, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType, std::optional<Vector<GType>>&& parameters)
    11091109{
    11101110    GRefPtr<GClosure> closure = adoptGRef(g_cclosure_new(callback, userData, reinterpret_cast<GClosureNotify>(reinterpret_cast<GCallback>(destroyNotify))));
     
    11551155/**
    11561156 * jsc_value_new_functionv: (rename-to jsc_value_new_function)
    1157  * @context: a #JSCContext:
     1157 * @context: a #JSCContext
    11581158 * @name: (nullable): the function name or %NULL
    11591159 * @callback: (scope async): a #GCallback.
     
    11881188
    11891189/**
     1190 * jsc_value_new_function_variadic:
     1191 * @context: a #JSCContext
     1192 * @name: (nullable): the function name or %NULL
     1193 * @callback: (scope async): a #GCallback.
     1194 * @user_data: (closure): user data to pass to @callback.
     1195 * @destroy_notify: (nullable): destroy notifier for @user_data
     1196 * @return_type: the #GType of the function return value, or %G_TYPE_NONE if the function is void.
     1197 *
     1198 * Create a function in @context. If @name is %NULL an anonymous function will be created.
     1199 * When the function is called by JavaScript or jsc_value_function_call(), @callback is called
     1200 * receiving an #GPtrArray of #JSCValue<!-- -->s with the arguments and then @user_data as last parameter.
     1201 * When the function is cleared in @context, @destroy_notify is called with @user_data as parameter.
     1202 *
     1203 * Returns: (transfer full): a #JSCValue.
     1204 */
     1205JSCValue* jsc_value_new_function_variadic(JSCContext* context, const char* name, GCallback callback, gpointer userData, GDestroyNotify destroyNotify, GType returnType)
     1206{
     1207    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
     1208    g_return_val_if_fail(callback, nullptr);
     1209
     1210    return jscValueFunctionCreate(context, name, callback, userData, destroyNotify, returnType, std::nullopt).leakRef();
     1211}
     1212
     1213/**
    11901214 * jsc_value_is_function:
    11911215 * @value: a #JSCValue
  • trunk/Source/JavaScriptCore/API/glib/JSCValue.h

    r233758 r233760  
    227227                                           GType                *parameter_types);
    228228
     229JSC_API JSCValue *
     230jsc_value_new_function_variadic           (JSCContext           *context,
     231                                           const char           *name,
     232                                           GCallback             callback,
     233                                           gpointer              user_data,
     234                                           GDestroyNotify        destroy_notify,
     235                                           GType                 return_type);
     236
    229237JSC_API gboolean
    230238jsc_value_is_function                     (JSCValue             *value);
  • trunk/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt

    r233759 r233760  
    100100jsc_value_new_function
    101101jsc_value_new_functionv
     102jsc_value_new_function_variadic
    102103jsc_value_is_function
    103104jsc_value_function_call
     
    179180jsc_class_add_constructor
    180181jsc_class_add_constructorv
     182jsc_class_add_constructor_variadic
    181183jsc_class_add_method
    182184jsc_class_add_methodv
     185jsc_class_add_method_variadic
    183186jsc_class_add_property
    184187
  • trunk/Source/JavaScriptCore/ChangeLog

    r233759 r233760  
     12018-07-11  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GLIB] Add API to allow creating variadic functions
     4        https://bugs.webkit.org/show_bug.cgi?id=187517
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Add a _variadic alternate method for jsc_class_add_constructor, jsc_class_add_method and
     9        jsc_value_new_function. In that case the callback always receives a GPtrArray of JSCValue.
     10
     11        * API/glib/JSCCallbackFunction.cpp:
     12        (JSC::JSCCallbackFunction::create): Make the parameters optional.
     13        (JSC::JSCCallbackFunction::JSCCallbackFunction): Ditto.
     14        (JSC::JSCCallbackFunction::call): Handle the case of parameters being nullopt by creating a GPtrArray of
     15        JSCValue for the arguments.
     16        (JSC::JSCCallbackFunction::construct): Ditto.
     17        * API/glib/JSCCallbackFunction.h:
     18        * API/glib/JSCClass.cpp:
     19        (jscClassCreateConstructor): Make the parameters optional.
     20        (jsc_class_add_constructor_variadic): Pass nullopt as parameters to jscClassCreateConstructor.
     21        (jscClassAddMethod): Make the parameters optional.
     22        (jsc_class_add_method_variadic): Pass nullopt as parameters to jscClassAddMethod.
     23        * API/glib/JSCClass.h:
     24        * API/glib/JSCValue.cpp:
     25        (jsc_value_object_define_property_accessor): Update now that parameters are optional.
     26        (jscValueFunctionCreate): Make the parameters optional.
     27        (jsc_value_new_function_variadic): Pass nullopt as parameters to jscValueFunctionCreate.
     28        * API/glib/JSCValue.h:
     29        * API/glib/docs/jsc-glib-4.0-sections.txt:
     30
    1312018-07-11  Carlos Garcia Campos  <cgarcia@igalia.com>
    232
  • trunk/Tools/ChangeLog

    r233759 r233760  
     12018-07-11  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GLIB] Add API to allow creating variadic functions
     4        https://bugs.webkit.org/show_bug.cgi?id=187517
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Add test cases.
     9
     10        * TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp:
     11        (testJSCFunction):
     12        (fooCreateWithFooV):
     13        (multiplyFooV):
     14
    1152018-07-11  Carlos Garcia Campos  <cgarcia@igalia.com>
    216
  • trunk/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp

    r233759 r233760  
    868868        g_assert_did_throw(exceptionHandler, didThrow);
    869869    }
     870
     871    {
     872        LeakChecker checker;
     873        GRefPtr<JSCContext> context = adoptGRef(jsc_context_new());
     874        checker.watch(context.get());
     875        ExceptionHandler exceptionHandler(context.get());
     876
     877        GRefPtr<JSCValue> function = adoptGRef(jsc_value_new_function_variadic(context.get(), "sumFunction", G_CALLBACK(sumFunction), nullptr, nullptr, G_TYPE_INT));
     878        checker.watch(function.get());
     879        jsc_context_set_value(context.get(), "sumFunction", function.get());
     880
     881        GRefPtr<JSCValue> value = adoptGRef(jsc_context_evaluate(context.get(), "sumFunction(2,4,6)", -1));
     882        checker.watch(value.get());
     883        g_assert_true(jsc_value_is_number(value.get()));
     884        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 12);
     885
     886        value = adoptGRef(jsc_context_evaluate(context.get(), "sumFunction()", -1));
     887        checker.watch(value.get());
     888        g_assert_true(jsc_value_is_number(value.get()));
     889        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 0);
     890    }
    870891}
    871892
     
    11601181}
    11611182
     1183static Foo* fooCreateWithFooV(GPtrArray* values)
     1184{
     1185    auto* f = fooCreate();
     1186    g_ptr_array_foreach(values, [](gpointer data, gpointer userData) {
     1187        g_assert_true(JSC_IS_VALUE(data));
     1188        JSCValue* item = JSC_VALUE(data);
     1189        g_assert_true(jsc_value_is_number(item));
     1190        auto* foo = static_cast<Foo*>(userData);
     1191        foo->foo += jsc_value_to_int32(item);
     1192    }, f);
     1193    return f;
     1194}
     1195
    11621196static void fooFree(Foo* foo)
    11631197{
     
    11891223{
    11901224    foo->foo *= multiplier;
     1225}
     1226
     1227static void multiplyFooV(Foo* foo, GPtrArray* multipliers)
     1228{
     1229    g_ptr_array_foreach(multipliers, [](gpointer data, gpointer userData) {
     1230        g_assert_true(JSC_IS_VALUE(data));
     1231        JSCValue* item = JSC_VALUE(data);
     1232        g_assert_true(jsc_value_is_number(item));
     1233        auto* foo = static_cast<Foo*>(userData);
     1234        foo->foo *= jsc_value_to_int32(item);
     1235    }, foo);
    11911236}
    11921237
     
    14141459        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 45);
    14151460
     1461        jsc_class_add_method_variadic(jscClass, "multiply", G_CALLBACK(multiplyFooV), nullptr, nullptr, G_TYPE_NONE);
     1462        g_assert_true(jsc_value_object_has_property(foo.get(), "multiply"));
     1463        value = adoptGRef(jsc_context_evaluate(context.get(), "f.setFoo(1); f.multiply(1,2,3);", -1));
     1464        checker.watch(value.get());
     1465        value = adoptGRef(jsc_value_object_invoke_method(foo.get(), "getFoo", G_TYPE_NONE));
     1466        checker.watch(value.get());
     1467        g_assert_true(jsc_value_is_number(value.get()));
     1468        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 6);
     1469        value = adoptGRef(jsc_context_evaluate(context.get(), "f.multiply()", -1));
     1470        checker.watch(value.get());
     1471        value = adoptGRef(jsc_value_object_invoke_method(foo.get(), "getFoo", G_TYPE_NONE));
     1472        checker.watch(value.get());
     1473        g_assert_true(jsc_value_is_number(value.get()));
     1474        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 6);
     1475
    14161476        GRefPtr<JSCValue> constructor2 = adoptGRef(jsc_class_add_constructorv(jscClass, "CreateWithFoo", G_CALLBACK(fooCreateWithFoo), nullptr, nullptr, G_TYPE_POINTER, 1, parameterTypes));
    14171477        checker.watch(constructor2.get());
     
    14501510        g_assert_true(jsc_value_is_number(value.get()));
    14511511        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 52);
     1512
     1513        GRefPtr<JSCValue> constructorV = adoptGRef(jsc_class_add_constructor_variadic(jscClass, "CreateWithFoo", G_CALLBACK(fooCreateWithFooV), nullptr, nullptr, G_TYPE_POINTER));
     1514        checker.watch(constructorV.get());
     1515        g_assert_true(jsc_value_is_constructor(constructorV.get()));
     1516        jsc_value_object_set_property(constructor.get(), "CreateWithFooV", constructorV.get());
     1517
     1518        GRefPtr<JSCValue> foo3 = adoptGRef(jsc_context_evaluate(context.get(), "f3 = new Foo.CreateWithFooV(10,20,30,40);", -1));
     1519        checker.watch(foo3.get());
     1520        g_assert_true(jsc_value_is_object(foo3.get()));
     1521        g_assert_true(jsc_value_object_is_instance_of(foo3.get(), jsc_class_get_name(jscClass)));
     1522        value = adoptGRef(jsc_context_evaluate(context.get(), "f3.foo", -1));
     1523        checker.watch(value.get());
     1524        g_assert_true(jsc_value_is_number(value.get()));
     1525        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 100);
     1526
     1527        GRefPtr<JSCValue> foo4 = adoptGRef(jsc_context_evaluate(context.get(), "f4 = new Foo.CreateWithFooV();", -1));
     1528        checker.watch(foo4.get());
     1529        g_assert_true(jsc_value_is_object(foo4.get()));
     1530        g_assert_true(jsc_value_object_is_instance_of(foo3.get(), jsc_class_get_name(jscClass)));
     1531        value = adoptGRef(jsc_context_evaluate(context.get(), "f4.foo", -1));
     1532        checker.watch(value.get());
     1533        g_assert_true(jsc_value_is_number(value.get()));
     1534        g_assert_cmpint(jsc_value_to_int32(value.get()), ==, 0);
    14521535
    14531536        JSCClass* otherClass = jsc_context_register_class(context.get(), "Baz", nullptr, nullptr, g_free);
Note: See TracChangeset for help on using the changeset viewer.