WebKit Bugzilla
Attachment 349005 Details for
Bug 188742
: [GLIB] Expose JavaScriptCore options in GLib public API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
jsc-glib-options.diff (text/plain), 38.38 KB, created by
Carlos Garcia Campos
on 2018-09-06 00:21:23 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Carlos Garcia Campos
Created:
2018-09-06 00:21:23 PDT
Size:
38.38 KB
patch
obsolete
>diff --git a/Source/JavaScriptCore/API/glib/JSCOptions.cpp b/Source/JavaScriptCore/API/glib/JSCOptions.cpp >new file mode 100644 >index 00000000000..12a424f89a2 >--- /dev/null >+++ b/Source/JavaScriptCore/API/glib/JSCOptions.cpp >@@ -0,0 +1,675 @@ >+/* >+ * Copyright (C) 2018 Igalia S.L. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Library General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ */ >+ >+#include "config.h" >+#include "JSCOptions.h" >+ >+#include "Options.h" >+#include <glib/gi18n-lib.h> >+#include <wtf/Vector.h> >+#include <wtf/glib/GUniquePtr.h> >+ >+/** >+ * SECTION: JSCOptions >+ * @short_description: JavaScript options >+ * @title: JSCOptions >+ * >+ * JavaScript options allow to change the behavior of the JavaScript engine. >+ * They affect the way the engine works, so it's encouraged to set the options >+ * at the very beginning of the program execution, before any other JavaScript >+ * API call. Most of the options are only useful for testing and degungging. >+ * Only a few of them are documented, you can use the undocummented options at >+ * your own risk (you can find the list of options in WebKit source code). >+ * >+ * The API allows to set and get any option using the types defined in #JSCOptionType. >+ * You can also iterate all the available options using jsc_options_foreach() and >+ * passing a #JSCOptionsFunc callback. If your application uses #GOptionContext to handle >+ * command line arguments, you can easily integrate the JSCOptions by adding the >+ * #GOptionGroup returned by jsc_options_get_option_group(). >+ * >+ * Since: 2.24 >+ */ >+ >+using namespace JSC; >+ >+typedef int32_t int32; >+typedef size_t size; >+ >+static bool valueFromGValue(const GValue* gValue, bool& value) >+{ >+ value = g_value_get_boolean(gValue); >+ return true; >+} >+ >+static void valueToGValue(bool value, GValue* gValue) >+{ >+ g_value_set_boolean(gValue, value); >+} >+ >+static bool valueFromGValue(const GValue* gValue, int32_t& value) >+{ >+ value = g_value_get_int(gValue); >+ return true; >+} >+ >+static void valueToGValue(int32_t value, GValue* gValue) >+{ >+ g_value_set_int(gValue, value); >+} >+ >+static bool valueFromGValue(const GValue* gValue, unsigned& value) >+{ >+ value = g_value_get_uint(gValue); >+ return true; >+} >+ >+static void valueToGValue(unsigned value, GValue* gValue) >+{ >+ g_value_set_uint(gValue, value); >+} >+ >+static bool valueFromGValue(const GValue* gValue, size_t& value) >+{ >+ value = GPOINTER_TO_SIZE(g_value_get_pointer(gValue)); >+ return true; >+} >+ >+static void valueToGValue(size_t value, GValue* gValue) >+{ >+ g_value_set_pointer(gValue, GSIZE_TO_POINTER(value)); >+} >+ >+static bool valueFromGValue(const GValue* gValue, const char*& value) >+{ >+ value = g_value_dup_string(gValue); >+ return true; >+} >+ >+static void valueToGValue(const char* value, GValue* gValue) >+{ >+ g_value_set_string(gValue, value); >+} >+ >+static bool valueFromGValue(const GValue* gValue, double& value) >+{ >+ value = g_value_get_double(gValue); >+ return true; >+} >+ >+static void valueToGValue(double value, GValue* gValue) >+{ >+ g_value_set_double(gValue, value); >+} >+ >+static bool valueFromGValue(const GValue* gValue, OptionRange& value) >+{ >+ return value.init(g_value_get_string(gValue) ? g_value_get_string(gValue) : "<null>"); >+} >+ >+static void valueToGValue(const OptionRange& value, GValue* gValue) >+{ >+ const char* rangeString = value.rangeString(); >+ g_value_set_string(gValue, !g_strcmp0(rangeString, "<null>") ? nullptr : rangeString); >+} >+ >+static bool valueFromGValue(const GValue* gValue, GCLogging::Level& value) >+{ >+ switch (g_value_get_uint(gValue)) { >+ case 0: >+ value = GCLogging::Level::None; >+ return true; >+ case 1: >+ value = GCLogging::Level::Basic; >+ return true; >+ case 2: >+ value = GCLogging::Level::Verbose; >+ return true; >+ default: >+ break; >+ } >+ >+ return false; >+} >+ >+static void valueToGValue(GCLogging::Level value, GValue* gValue) >+{ >+ switch (value) { >+ case GCLogging::Level::None: >+ g_value_set_uint(gValue, 0); >+ break; >+ case GCLogging::Level::Basic: >+ g_value_set_uint(gValue, 1); >+ break; >+ case GCLogging::Level::Verbose: >+ g_value_set_uint(gValue, 2); >+ break; >+ } >+} >+ >+static gboolean jscOptionsSetValue(const char* option, const GValue* value) >+{ >+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \ >+ if (!g_strcmp0(#name_, option)) { \ >+ type_ valueToSet; \ >+ if (!valueFromGValue(value, valueToSet)) \ >+ return FALSE; \ >+ Options::name_() = valueToSet; \ >+ return TRUE; \ >+ } >+ >+ Options::initialize(); >+ JSC_OPTIONS(FOR_EACH_OPTION) >+#undef FOR_EACH_OPTION >+ >+ return FALSE; >+} >+ >+static gboolean jscOptionsGetValue(const char* option, GValue* value) >+{ >+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \ >+ if (!g_strcmp0(#name_, option)) { \ >+ type_ valueToGet = Options::name_(); \ >+ valueToGValue(valueToGet, value); \ >+ return TRUE; \ >+ } >+ >+ Options::initialize(); >+ JSC_OPTIONS(FOR_EACH_OPTION) >+#undef FOR_EACH_OPTION >+ >+ return FALSE; >+} >+ >+/** >+ * jsc_options_set_boolean: >+ * @option: the option identifier >+ * @value: the value to set >+ * >+ * Set @option as a #gboolean value. >+ * >+ * Returns: %TRUE if option was correctly set or %FALSE otherwise. >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_set_boolean(const char* option, gboolean value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_BOOLEAN); >+ g_value_set_boolean(&gValue, value); >+ return jscOptionsSetValue(option, &gValue); >+} >+ >+/** >+ * jsc_options_get_boolean: >+ * @option: the option identifier >+ * @value: (out): return location for the option value >+ * >+ * Get @option as a #gboolean value. >+ * >+ * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_get_boolean(const char* option, gboolean* value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ g_return_val_if_fail(value, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_BOOLEAN); >+ if (!jscOptionsGetValue(option, &gValue)) >+ return FALSE; >+ >+ *value = g_value_get_boolean(&gValue); >+ return TRUE; >+} >+ >+/** >+ * jsc_options_set_int: >+ * @option: the option identifier >+ * @value: the value to set >+ * >+ * Set @option as a #gint value. >+ * >+ * Returns: %TRUE if option was correctly set or %FALSE otherwise. >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_set_int(const char* option, gint value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_INT); >+ g_value_set_int(&gValue, value); >+ return jscOptionsSetValue(option, &gValue); >+} >+ >+/** >+ * jsc_options_get_int: >+ * @option: the option identifier >+ * @value: (out): return location for the option value >+ * >+ * Get @option as a #gint value. >+ * >+ * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_get_int(const char* option, gint* value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ g_return_val_if_fail(value, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_INT); >+ if (!jscOptionsGetValue(option, &gValue)) >+ return FALSE; >+ >+ *value = g_value_get_int(&gValue); >+ return TRUE; >+} >+ >+/** >+ * jsc_options_set_uint: >+ * @option: the option identifier >+ * @value: the value to set >+ * >+ * Set @option as a #guint value. >+ * >+ * Returns: %TRUE if option was correctly set or %FALSE otherwise. >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_set_uint(const char* option, guint value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_UINT); >+ g_value_set_uint(&gValue, value); >+ return jscOptionsSetValue(option, &gValue); >+} >+ >+/** >+ * jsc_options_get_uint: >+ * @option: the option identifier >+ * @value: (out): return location for the option value >+ * >+ * Get @option as a #guint value. >+ * >+ * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_get_uint(const char* option, guint* value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ g_return_val_if_fail(value, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_UINT); >+ if (!jscOptionsGetValue(option, &gValue)) >+ return FALSE; >+ >+ *value = g_value_get_uint(&gValue); >+ return TRUE; >+} >+ >+/** >+ * jsc_options_set_size: >+ * @option: the option identifier >+ * @value: the value to set >+ * >+ * Set @option as a #gsize value. >+ * >+ * Returns: %TRUE if option was correctly set or %FALSE otherwise. >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_set_size(const char* option, gsize value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_POINTER); >+ g_value_set_pointer(&gValue, GSIZE_TO_POINTER(value)); >+ return jscOptionsSetValue(option, &gValue); >+} >+ >+/** >+ * jsc_options_get_size: >+ * @option: the option identifier >+ * @value: (out): return location for the option value >+ * >+ * Get @option as a #gsize value. >+ * >+ * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_get_size(const char* option, gsize* value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ g_return_val_if_fail(value, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_POINTER); >+ if (!jscOptionsGetValue(option, &gValue)) >+ return FALSE; >+ >+ *value = GPOINTER_TO_SIZE(g_value_get_pointer(&gValue)); >+ return TRUE; >+} >+ >+/** >+ * jsc_options_set_double: >+ * @option: the option identifier >+ * @value: the value to set >+ * >+ * Set @option as a #gdouble value. >+ * >+ * Returns: %TRUE if option was correctly set or %FALSE otherwise. >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_set_double(const char* option, gdouble value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_DOUBLE); >+ g_value_set_double(&gValue, value); >+ return jscOptionsSetValue(option, &gValue); >+} >+ >+/** >+ * jsc_options_get_double: >+ * @option: the option identifier >+ * @value: (out): return location for the option value >+ * >+ * Get @option as a #gdouble value. >+ * >+ * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_get_double(const char* option, gdouble* value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ g_return_val_if_fail(value, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_DOUBLE); >+ if (!jscOptionsGetValue(option, &gValue)) >+ return FALSE; >+ >+ *value = g_value_get_double(&gValue); >+ return TRUE; >+} >+ >+/** >+ * jsc_options_set_string: >+ * @option: the option identifier >+ * @value: the value to set >+ * >+ * Set @option as a string. >+ * >+ * Returns: %TRUE if option was correctly set or %FALSE otherwise. >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_set_string(const char* option, const char* value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_STRING); >+ g_value_set_string(&gValue, value); >+ bool success = jscOptionsSetValue(option, &gValue); >+ g_value_unset(&gValue); >+ return success; >+} >+ >+/** >+ * jsc_options_get_string: >+ * @option: the option identifier >+ * @value: (out): return location for the option value >+ * >+ * Get @option as a string. >+ * >+ * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_get_string(const char* option, char** value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ g_return_val_if_fail(value, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_STRING); >+ if (!jscOptionsGetValue(option, &gValue)) >+ return FALSE; >+ >+ *value = g_value_dup_string(&gValue); >+ g_value_unset(&gValue); >+ return TRUE; >+} >+ >+/** >+ * jsc_options_set_range_string: >+ * @option: the option identifier >+ * @value: the value to set >+ * >+ * Set @option as a range string. The string must be in the >+ * format [!]<low>[:<high>] where low and high are #guint values. >+ * Values between low and high (both included) will be considered in >+ * the range, unless ! is used to invert the range. >+ * >+ * Returns: %TRUE if option was correctly set or %FALSE otherwise. >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_set_range_string(const char* option, const char* value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_STRING); >+ g_value_set_string(&gValue, value); >+ bool success = jscOptionsSetValue(option, &gValue); >+ g_value_unset(&gValue); >+ return success; >+} >+ >+/** >+ * jsc_options_get_range_string: >+ * @option: the option identifier >+ * @value: (out): return location for the option value >+ * >+ * Get @option as a range string. The string must be in the >+ * format [!]<low>[:<high>] where low and high are #guint values. >+ * Values between low and high (both included) will be considered in >+ * the range, unless ! is used to invert the range. >+ * >+ * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist >+ * >+ * Since: 2.24 >+ */ >+gboolean jsc_options_get_range_string(const char* option, char** value) >+{ >+ g_return_val_if_fail(option, FALSE); >+ g_return_val_if_fail(value, FALSE); >+ >+ GValue gValue = G_VALUE_INIT; >+ g_value_init(&gValue, G_TYPE_STRING); >+ if (!jscOptionsGetValue(option, &gValue)) >+ return FALSE; >+ >+ *value = g_value_dup_string(&gValue); >+ g_value_unset(&gValue); >+ return TRUE; >+} >+ >+static JSCOptionType jscOptionsType(bool) >+{ >+ return JSC_OPTION_BOOLEAN; >+} >+ >+static JSCOptionType jscOptionsType(int) >+{ >+ return JSC_OPTION_INT; >+} >+ >+static JSCOptionType jscOptionsType(unsigned) >+{ >+ return JSC_OPTION_UINT; >+} >+ >+static JSCOptionType jscOptionsType(size_t) >+{ >+ return JSC_OPTION_SIZE; >+} >+ >+static JSCOptionType jscOptionsType(double) >+{ >+ return JSC_OPTION_DOUBLE; >+} >+ >+static JSCOptionType jscOptionsType(const char*) >+{ >+ return JSC_OPTION_STRING; >+} >+ >+static JSCOptionType jscOptionsType(const OptionRange&) >+{ >+ return JSC_OPTION_RANGE_STRING; >+} >+ >+/** >+ * JSCOptionType: >+ * @JSC_OPTION_BOOLEAN: A #gboolean option type. >+ * @JSC_OPTION_INT: A #gint option type. >+ * @JSC_OPTION_UINT: A #guint option type. >+ * @JSC_OPTION_SIZE: A #gsize options type. >+ * @JSC_OPTION_DOUBLE: A #gdouble options type. >+ * @JSC_OPTION_STRING: A string option type. >+ * @JSC_OPTION_RANGE_STRING: A range string option type. >+ * >+ * Enum values for options types. >+ * >+ * Since: 2.24 >+ */ >+ >+/** >+ * JSCOptionsFunc: >+ * @option: the option name >+ * @type: the option #JSCOptionType >+ * @description: (nullable): the option description, or %NULL >+ * @user_data: user data >+ * >+ * Function used to iterate options. >+ * >+ * Returns: %TRUE to top the iteration, or %FALSE otherwise >+ * >+ * Since: 2.24 >+ */ >+ >+/** >+ * jsc_options_foreach: >+ * @function: (scope call): a #JSCOptionsFunc callback >+ * @user_data: callback user data >+ * >+ * Iterates all available options calling @function for each one. Iteration can >+ * stop early if @function returns %FALSE. >+ * >+ * Since: 2.24 >+ */ >+void jsc_options_foreach(JSCOptionsFunc function, gpointer userData) >+{ >+ g_return_if_fail(function); >+ >+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \ >+ if (Options::Availability::availability_ == Options::Availability::Normal \ >+ || Options::isAvailable(Options::name_##ID, Options::Availability::availability_)) { \ >+ type_ defaultValue; \ >+ auto optionType = jscOptionsType(defaultValue); \ >+ if (function (#name_, optionType, description_, userData)) \ >+ return; \ >+ } >+ >+ Options::initialize(); >+ JSC_OPTIONS(FOR_EACH_OPTION) >+#undef FOR_EACH_OPTION >+} >+ >+static gboolean setOptionEntry(const char* optionNameFull, const char* value, gpointer, GError** error) >+{ >+ const char* optionName = optionNameFull + 6; // Remove the --jsc- prefix. >+ GUniquePtr<char> option(g_strdup_printf("%s=%s", optionName, value)); >+ if (!Options::setOption(option.get())) { >+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Failed parse value '%s' for %s", value, optionNameFull); >+ return FALSE; >+ } >+ return TRUE; >+} >+ >+/** >+ * jsc_options_get_option_group: >+ * >+ * Create a #GOptionGroup to handle #JSCOptions as command line arguments. >+ * The options will be exposed as command line arguments with the form >+ * jsc-<option>=<value>. The group is set up to automatically set the #JSCOptions >+ * on parsing, applications only need to pass the group to g_option_context_add_group(). >+ * >+ * Returns: (transfer full): a #GOptionGroup for the #JSCOptions >+ * >+ * Since: 2.24 >+ */ >+GOptionGroup* jsc_options_get_option_group(void) >+{ >+ // GOptionEntry works with const strings, so we need to keep the option names around. >+ auto* names = new Vector<GUniquePtr<char>>; >+ GOptionGroup* group = g_option_group_new("jsc", _("JSC Options"), _("Show JSC Options"), names, [] (gpointer data) { delete static_cast<Vector<GUniquePtr<char>>*>(data); }); >+ g_option_group_set_translation_domain(group, GETTEXT_PACKAGE); >+ >+ GArray* entries = g_array_new(TRUE, TRUE, sizeof(GOptionEntry)); >+#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \ >+ if (Options::Availability::availability_ == Options::Availability::Normal \ >+ || Options::isAvailable(Options::name_##ID, Options::Availability::availability_)) { \ >+ GUniquePtr<char> name(g_strdup_printf("jsc-%s", #name_)); \ >+ entries = g_array_set_size(entries, entries->len + 1); \ >+ GOptionEntry* entry = &g_array_index(entries, GOptionEntry, entries->len - 1); \ >+ entry->long_name = name.get(); \ >+ entry->arg = G_OPTION_ARG_CALLBACK; \ >+ entry->arg_data = reinterpret_cast<gpointer>(setOptionEntry); \ >+ entry->description = description_; \ >+ names->append(WTFMove(name)); \ >+ } >+ >+ Options::initialize(); >+ JSC_OPTIONS(FOR_EACH_OPTION) >+#undef FOR_EACH_OPTION >+ >+ g_option_group_add_entries(group, reinterpret_cast<GOptionEntry*>(entries->data)); >+ return group; >+} >diff --git a/Source/JavaScriptCore/API/glib/JSCOptions.h b/Source/JavaScriptCore/API/glib/JSCOptions.h >new file mode 100644 >index 00000000000..fadd9b750d1 >--- /dev/null >+++ b/Source/JavaScriptCore/API/glib/JSCOptions.h >@@ -0,0 +1,105 @@ >+/* >+ * Copyright (C) 2018 Igalia S.L. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Library General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ */ >+ >+#if !defined(__JSC_H_INSIDE__) && !defined(JSC_COMPILATION) && !defined(WEBKIT2_COMPILATION) >+#error "Only <jsc/jsc.h> can be included directly." >+#endif >+ >+#ifndef JSCOptions_h >+#define JSCOptions_h >+ >+#include <glib-object.h> >+#include <jsc/JSCDefines.h> >+ >+G_BEGIN_DECLS >+ >+JSC_API gboolean >+jsc_options_set_boolean (const char *option, >+ gboolean value); >+JSC_API gboolean >+jsc_options_get_boolean (const char *option, >+ gboolean *value); >+ >+JSC_API gboolean >+jsc_options_set_int (const char *option, >+ gint value); >+JSC_API gboolean >+jsc_options_get_int (const char *option, >+ gint *value); >+ >+JSC_API gboolean >+jsc_options_set_uint (const char *option, >+ guint value); >+JSC_API gboolean >+jsc_options_get_uint (const char *option, >+ guint *value); >+ >+JSC_API gboolean >+jsc_options_set_size (const char *option, >+ gsize value); >+JSC_API gboolean >+jsc_options_get_size (const char *option, >+ gsize *value); >+ >+JSC_API gboolean >+jsc_options_set_double (const char *option, >+ gdouble value); >+JSC_API gboolean >+jsc_options_get_double (const char *option, >+ gdouble *value); >+ >+JSC_API gboolean >+jsc_options_set_string (const char *option, >+ const char *value); >+JSC_API gboolean >+jsc_options_get_string (const char *option, >+ char **value); >+ >+JSC_API gboolean >+jsc_options_set_range_string (const char *option, >+ const char *value); >+JSC_API gboolean >+jsc_options_get_range_string (const char *option, >+ char **value); >+ >+typedef enum { >+ JSC_OPTION_BOOLEAN, >+ JSC_OPTION_INT, >+ JSC_OPTION_UINT, >+ JSC_OPTION_SIZE, >+ JSC_OPTION_DOUBLE, >+ JSC_OPTION_STRING, >+ JSC_OPTION_RANGE_STRING >+} JSCOptionType; >+ >+typedef gboolean (* JSCOptionsFunc) (const char *option, >+ JSCOptionType type, >+ const char *description, >+ gpointer user_data); >+ >+JSC_API void >+jsc_options_foreach (JSCOptionsFunc function, >+ gpointer user_data); >+ >+JSC_API GOptionGroup * >+jsc_options_get_option_group (void); >+ >+G_END_DECLS >+ >+#endif /* JSCOptions_h */ >diff --git a/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt b/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt >index add682a481a..9b6e701545e 100644 >--- a/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt >+++ b/Source/JavaScriptCore/API/glib/docs/jsc-glib-4.0-sections.txt >@@ -211,6 +211,31 @@ JSC_IS_CLASS > jsc_class_get_type > </SECTION> > >+<SECTION> >+<FILE>JSCOptions</FILE> >+<TITLE>JSCOptions</TITLE> >+jsc_options_set_boolean >+jsc_options_get_boolean >+jsc_options_set_int >+jsc_options_get_int >+jsc_options_set_uint >+jsc_options_get_uint >+jsc_options_set_size >+jsc_options_get_size >+jsc_options_set_double >+jsc_options_get_double >+jsc_options_set_string >+jsc_options_get_string >+jsc_options_set_range_string >+jsc_options_get_range_string >+ >+JSCOptionType >+JSCOptionsFunc >+jsc_options_foreach >+ >+jsc_options_get_option_group >+</SECTION> >+ > <SECTION> > <FILE>JSCVersion</FILE> > <TITLE>JSCVersion</TITLE> >diff --git a/Source/JavaScriptCore/API/glib/docs/jsc-glib-docs.sgml b/Source/JavaScriptCore/API/glib/docs/jsc-glib-docs.sgml >index 4853a104c6d..1c2db5c7b95 100644 >--- a/Source/JavaScriptCore/API/glib/docs/jsc-glib-docs.sgml >+++ b/Source/JavaScriptCore/API/glib/docs/jsc-glib-docs.sgml >@@ -17,6 +17,7 @@ > <xi:include href="xml/JSCWeakValue.xml"/> > <xi:include href="xml/JSCException.xml"/> > <xi:include href="xml/JSCClass.xml"/> >+ <xi:include href="xml/JSCOptions.xml"/> > <xi:include href="xml/JSCVersion.xml"/> > </chapter> > >@@ -24,5 +25,10 @@ > <title>Index</title> > </index> > >+ <index id="api-index-2-24" role="2.24"> >+ <title>Index of new symbols in 2.24</title> >+ <xi:include href="xml/api-index-2.24.xml"><xi:fallback /></xi:include> >+ </index> >+ > <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> > </book> >diff --git a/Source/JavaScriptCore/API/glib/jsc.h b/Source/JavaScriptCore/API/glib/jsc.h >index 8a2845240a8..11537f9d4a6 100644 >--- a/Source/JavaScriptCore/API/glib/jsc.h >+++ b/Source/JavaScriptCore/API/glib/jsc.h >@@ -26,6 +26,7 @@ > #include <jsc/JSCContext.h> > #include <jsc/JSCDefines.h> > #include <jsc/JSCException.h> >+#include <jsc/JSCOptions.h> > #include <jsc/JSCValue.h> > #include <jsc/JSCVersion.h> > #include <jsc/JSCVirtualMachine.h> >diff --git a/Source/JavaScriptCore/GLib.cmake b/Source/JavaScriptCore/GLib.cmake >index dc85f4e7c59..4d1ffe5d79d 100644 >--- a/Source/JavaScriptCore/GLib.cmake >+++ b/Source/JavaScriptCore/GLib.cmake >@@ -8,6 +8,7 @@ list(APPEND JavaScriptCore_SOURCES > API/glib/JSCClass.cpp > API/glib/JSCContext.cpp > API/glib/JSCException.cpp >+ API/glib/JSCOptions.cpp > API/glib/JSCValue.cpp > API/glib/JSCVersion.cpp > API/glib/JSCVirtualMachine.cpp >@@ -28,6 +29,7 @@ set(JavaScriptCore_INSTALLED_HEADERS > ${JAVASCRIPTCORE_DIR}/API/glib/JSCContext.h > ${JAVASCRIPTCORE_DIR}/API/glib/JSCDefines.h > ${JAVASCRIPTCORE_DIR}/API/glib/JSCException.h >+ ${JAVASCRIPTCORE_DIR}/API/glib/JSCOptions.h > ${JAVASCRIPTCORE_DIR}/API/glib/JSCValue.h > ${JAVASCRIPTCORE_DIR}/API/glib/JSCVirtualMachine.h > ${JAVASCRIPTCORE_DIR}/API/glib/JSCWeakValue.h >diff --git a/Source/WebCore/platform/gtk/po/POTFILES.in b/Source/WebCore/platform/gtk/po/POTFILES.in >index 9fcb86c7178..a3bcf5aff94 100644 >--- a/Source/WebCore/platform/gtk/po/POTFILES.in >+++ b/Source/WebCore/platform/gtk/po/POTFILES.in >@@ -2,6 +2,7 @@ > LocalizedStringsGtk.cpp > ../LocalizedStrings.cpp > ../network/soup/NetworkStorageSessionSoup.cpp >+../../../JavaScriptCore/API/glib/JSCOptions.cpp > ../../../WebKit/Shared/API/glib/WebKitHitTestResult.cpp > ../../../WebKit/Shared/API/glib/WebKitURIRequest.cpp > ../../../WebKit/Shared/API/glib/WebKitURIResponse.cpp >diff --git a/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp b/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp >index f7fa6aacdc3..7e74f69551c 100644 >--- a/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp >+++ b/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp >@@ -3227,6 +3227,211 @@ static void testsJSCVirtualMachine() > } > } > >+static void testsJSCOptions() >+{ >+ gboolean useJIT; >+ g_assert_true(jsc_options_get_boolean("useJIT", &useJIT)); >+ g_assert_true(useJIT); >+ g_assert_true(jsc_options_set_boolean("useJIT", FALSE)); >+ g_assert_true(jsc_options_get_boolean("useJIT", &useJIT)); >+ g_assert_false(useJIT); >+ g_assert_true(jsc_options_set_boolean("useJIT", TRUE)); >+ >+ gint thresholdForJITAfterWarmUp; >+ g_assert_true(jsc_options_get_int("thresholdForJITAfterWarmUp", &thresholdForJITAfterWarmUp)); >+ g_assert_cmpint(thresholdForJITAfterWarmUp, ==, 500); >+ g_assert_true(jsc_options_set_int("thresholdForJITAfterWarmUp", 1000)); >+ g_assert_true(jsc_options_get_int("thresholdForJITAfterWarmUp", &thresholdForJITAfterWarmUp)); >+ g_assert_cmpint(thresholdForJITAfterWarmUp, ==, 1000); >+ g_assert_true(jsc_options_set_int("thresholdForJITAfterWarmUp", 500)); >+ >+ guint maxPerThreadStackUsage; >+ g_assert_true(jsc_options_get_uint("maxPerThreadStackUsage", &maxPerThreadStackUsage)); >+ g_assert_cmpuint(maxPerThreadStackUsage, ==, 4194304); >+ g_assert_true(jsc_options_set_uint("maxPerThreadStackUsage", 4096)); >+ g_assert_true(jsc_options_get_uint("maxPerThreadStackUsage", &maxPerThreadStackUsage)); >+ g_assert_cmpuint(maxPerThreadStackUsage, ==, 4096); >+ g_assert_true(jsc_options_set_uint("maxPerThreadStackUsage", 4194304)); >+ >+ gsize webAssemblyPartialCompileLimit; >+ g_assert_true(jsc_options_get_size("webAssemblyPartialCompileLimit", &webAssemblyPartialCompileLimit)); >+ g_assert_cmpuint(webAssemblyPartialCompileLimit, ==, 5000); >+ g_assert_true(jsc_options_set_size("webAssemblyPartialCompileLimit", 6000)); >+ g_assert_true(jsc_options_get_size("webAssemblyPartialCompileLimit", &webAssemblyPartialCompileLimit)); >+ g_assert_cmpuint(webAssemblyPartialCompileLimit, ==, 6000); >+ g_assert_true(jsc_options_set_size("webAssemblyPartialCompileLimit", 5000)); >+ >+ gdouble smallHeapRAMFraction; >+ g_assert_true(jsc_options_get_double("smallHeapRAMFraction", &smallHeapRAMFraction)); >+ g_assert_cmpfloat(smallHeapRAMFraction, ==, 0.25); >+ g_assert_true(jsc_options_set_double("smallHeapRAMFraction", 0.50)); >+ g_assert_true(jsc_options_get_double("smallHeapRAMFraction", &smallHeapRAMFraction)); >+ g_assert_cmpfloat(smallHeapRAMFraction, ==, 0.50); >+ g_assert_true(jsc_options_set_double("smallHeapRAMFraction", 0.25)); >+ >+ GUniqueOutPtr<char> configFile; >+ g_assert_true(jsc_options_get_string("configFile", &configFile.outPtr())); >+ g_assert_null(configFile.get()); >+ g_assert_true(jsc_options_set_string("configFile", "/tmp/foo")); >+ g_assert_true(jsc_options_get_string("configFile", &configFile.outPtr())); >+ g_assert_cmpstr(configFile.get(), ==, "/tmp/foo"); >+ g_assert_true(jsc_options_set_string("configFile", nullptr)); >+ g_assert_true(jsc_options_get_string("configFile", &configFile.outPtr())); >+ g_assert_null(configFile.get()); >+ >+ GUniqueOutPtr<char> bytecodeRangeToJITCompile; >+ g_assert_true(jsc_options_get_range_string("bytecodeRangeToJITCompile", &bytecodeRangeToJITCompile.outPtr())); >+ g_assert_null(bytecodeRangeToJITCompile.get()); >+ g_assert_true(jsc_options_set_range_string("bytecodeRangeToJITCompile", "100")); >+ g_assert_true(jsc_options_get_range_string("bytecodeRangeToJITCompile", &bytecodeRangeToJITCompile.outPtr())); >+ g_assert_cmpstr(bytecodeRangeToJITCompile.get(), ==, "100"); >+ g_assert_true(jsc_options_set_range_string("bytecodeRangeToJITCompile", "100:200")); >+ g_assert_true(jsc_options_get_range_string("bytecodeRangeToJITCompile", &bytecodeRangeToJITCompile.outPtr())); >+ g_assert_cmpstr(bytecodeRangeToJITCompile.get(), ==, "100:200"); >+ g_assert_true(jsc_options_set_range_string("bytecodeRangeToJITCompile", "!100:200")); >+ g_assert_true(jsc_options_get_range_string("bytecodeRangeToJITCompile", &bytecodeRangeToJITCompile.outPtr())); >+ g_assert_cmpstr(bytecodeRangeToJITCompile.get(), ==, "!100:200"); >+ g_assert_false(jsc_options_set_range_string("bytecodeRangeToJITCompile", "200:100")); >+ g_assert_true(jsc_options_get_range_string("bytecodeRangeToJITCompile", &bytecodeRangeToJITCompile.outPtr())); >+ g_assert_cmpstr(bytecodeRangeToJITCompile.get(), ==, "!100:200"); >+ g_assert_true(jsc_options_set_range_string("bytecodeRangeToJITCompile", nullptr)); >+ g_assert_true(jsc_options_get_range_string("bytecodeRangeToJITCompile", &bytecodeRangeToJITCompile.outPtr())); >+ g_assert_null(bytecodeRangeToJITCompile.get()); >+ >+ guint logGC; >+ g_assert_true(jsc_options_get_uint("logGC", &logGC)); >+ g_assert_cmpuint(logGC, ==, 0); >+ g_assert_true(jsc_options_set_uint("logGC", 1)); >+ g_assert_true(jsc_options_get_uint("logGC", &logGC)); >+ g_assert_cmpuint(logGC, ==, 1); >+ g_assert_true(jsc_options_set_uint("logGC", 2)); >+ g_assert_true(jsc_options_get_uint("logGC", &logGC)); >+ g_assert_cmpuint(logGC, ==, 2); >+ g_assert_false(jsc_options_set_uint("logGC", 3)); >+ g_assert_true(jsc_options_get_uint("logGC", &logGC)); >+ g_assert_cmpuint(logGC, ==, 2); >+ g_assert_true(jsc_options_set_uint("logGC", 0)); >+ g_assert_true(jsc_options_get_uint("logGC", &logGC)); >+ g_assert_cmpuint(logGC, ==, 0); >+ >+ gboolean value = TRUE; >+ g_assert_false(jsc_options_get_boolean("InvalidOption", &value)); >+ g_assert_true(value); >+ g_assert_false(jsc_options_set_boolean("InvalidOption", TRUE)); >+ g_assert_false(jsc_options_get_boolean("InvalidOption", &value)); >+ g_assert_true(value); >+ >+ // Find a particular option. >+ bool found = false; >+ jsc_options_foreach([](const char* option, JSCOptionType type, const char* description, gpointer userData) -> gboolean { >+ if (!g_strcmp0(option, "useJIT")) { >+ *static_cast<bool*>(userData) = true; >+ return TRUE; >+ } >+ return FALSE; >+ }, &found); >+ g_assert_true(found); >+ >+ unsigned optionsCount = 0; >+ jsc_options_foreach([](const char* option, JSCOptionType type, const char* description, gpointer userData) -> gboolean { >+ (*static_cast<unsigned*>(userData))++; >+ return FALSE; >+ }, &optionsCount); >+ g_assert_cmpuint(optionsCount, >, 100); >+ g_assert_cmpuint(optionsCount, <, 500); >+ >+ optionsCount = 0; >+ jsc_options_foreach([](const char* option, JSCOptionType type, const char* description, gpointer userData) -> gboolean { >+ if (!g_strcmp0(option, "useJIT")) >+ g_assert_true(type == JSC_OPTION_BOOLEAN); >+ else if (!g_strcmp0(option, "thresholdForJITAfterWarmUp")) >+ g_assert_true(type == JSC_OPTION_INT); >+ else if (!g_strcmp0(option, "maxPerThreadStackUsage")) >+ g_assert_true(type == JSC_OPTION_UINT); >+ else if (!g_strcmp0(option, "webAssemblyPartialCompileLimit")) >+ g_assert_true(type == JSC_OPTION_SIZE); >+ else if (!g_strcmp0(option, "smallHeapRAMFraction")) >+ g_assert_true(type == JSC_OPTION_DOUBLE); >+ else if (!g_strcmp0(option, "configFile")) >+ g_assert_true(type == JSC_OPTION_STRING); >+ else if (!g_strcmp0(option, "bytecodeRangeToJITCompile")) >+ g_assert_true(type == JSC_OPTION_RANGE_STRING); >+ else >+ return FALSE; >+ >+ (*static_cast<unsigned*>(userData))++; >+ return FALSE; >+ }, &optionsCount); >+ g_assert_cmpuint(optionsCount, ==, 7); >+ >+ GOptionContext* context = g_option_context_new(nullptr); >+ g_option_context_add_group(context, jsc_options_get_option_group()); >+ static const char* argv[] = { >+ __FILE__, >+ "--jsc-useJIT=false", >+ "--jsc-thresholdForJITAfterWarmUp=2000", >+ "--jsc-maxPerThreadStackUsage=1024", >+ "--jsc-webAssemblyPartialCompileLimit=4000", >+ "--jsc-smallHeapRAMFraction=0.75", >+ "--jsc-configFile=/tmp/bar", >+ "--jsc-bytecodeRangeToJITCompile=100:300", >+ "--jsc-logGC=1", >+ nullptr >+ }; >+ GUniquePtr<char*> copy(g_strdupv(const_cast<char**>(argv))); >+ int argc = g_strv_length(copy.get()); >+ auto* copyPtr = copy.get(); >+ g_assert_true(g_option_context_parse(context, &argc, ©Ptr, nullptr)); >+ g_option_context_free(context); >+ >+ g_assert_true(jsc_options_get_boolean("useJIT", &useJIT)); >+ g_assert_false(useJIT); >+ g_assert_true(jsc_options_get_int("thresholdForJITAfterWarmUp", &thresholdForJITAfterWarmUp)); >+ g_assert_cmpint(thresholdForJITAfterWarmUp, ==, 2000); >+ g_assert_true(jsc_options_get_uint("maxPerThreadStackUsage", &maxPerThreadStackUsage)); >+ g_assert_cmpuint(maxPerThreadStackUsage, ==, 1024); >+ g_assert_true(jsc_options_get_size("webAssemblyPartialCompileLimit", &webAssemblyPartialCompileLimit)); >+ g_assert_cmpuint(webAssemblyPartialCompileLimit, ==, 4000); >+ g_assert_true(jsc_options_get_double("smallHeapRAMFraction", &smallHeapRAMFraction)); >+ g_assert_cmpfloat(smallHeapRAMFraction, ==, 0.75); >+ g_assert_true(jsc_options_get_string("configFile", &configFile.outPtr())); >+ g_assert_cmpstr(configFile.get(), ==, "/tmp/bar"); >+ g_assert_true(jsc_options_get_range_string("bytecodeRangeToJITCompile", &bytecodeRangeToJITCompile.outPtr())); >+ g_assert_cmpstr(bytecodeRangeToJITCompile.get(), ==, "100:300"); >+ g_assert_true(jsc_options_get_uint("logGC", &logGC)); >+ g_assert_cmpuint(logGC, ==, 1); >+ >+ // Restore options their default values. >+ g_assert_true(jsc_options_set_boolean("useJIT", TRUE)); >+ g_assert_true(jsc_options_set_int("thresholdForJITAfterWarmUp", 500)); >+ g_assert_true(jsc_options_set_uint("maxPerThreadStackUsage", 4194304)); >+ g_assert_true(jsc_options_set_size("webAssemblyPartialCompileLimit", 5000)); >+ g_assert_true(jsc_options_set_double("smallHeapRAMFraction", 0.25)); >+ g_assert_true(jsc_options_set_string("configFile", nullptr)); >+ g_assert_true(jsc_options_set_range_string("bytecodeRangeToJITCompile", nullptr)); >+ g_assert_true(jsc_options_set_uint("logGC", 0)); >+ >+ context = g_option_context_new(nullptr); >+ g_option_context_add_group(context, jsc_options_get_option_group()); >+ static const char* argv2[] = { __FILE__, "--jsc-InvalidOption=true", nullptr }; >+ copy.reset(g_strdupv(const_cast<char**>(argv2))); >+ argc = g_strv_length(copy.get()); >+ copyPtr = copy.get(); >+ g_assert_false(g_option_context_parse(context, &argc, ©Ptr, nullptr)); >+ g_option_context_free(context); >+ >+ context = g_option_context_new(nullptr); >+ g_option_context_add_group(context, jsc_options_get_option_group()); >+ static const char* argv3[] = { __FILE__, "--jsc-useJIT=nein", nullptr }; >+ copy.reset(g_strdupv(const_cast<char**>(argv3))); >+ argc = g_strv_length(copy.get()); >+ copyPtr = copy.get(); >+ g_assert_false(g_option_context_parse(context, &argc, ©Ptr, nullptr)); >+ g_option_context_free(context); >+ g_assert_true(jsc_options_get_boolean("useJIT", &useJIT)); >+ g_assert_true(useJIT); >+} >+ > #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC > static void testsJSCAutocleanups() > { >@@ -3270,6 +3475,7 @@ int main(int argc, char** argv) > g_test_add_func("/jsc/garbage-collector", testJSCGarbageCollector); > g_test_add_func("/jsc/weak-value", testJSCWeakValue); > g_test_add_func("/jsc/vm", testsJSCVirtualMachine); >+ g_test_add_func("/jsc/options", testsJSCOptions); > #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC > g_test_add_func("/jsc/autocleanups", testsJSCAutocleanups); > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188742
:
349005
|
349021
|
359149