Diff
Added: trunk/Source/_javascript_Core/API/glib/JSCOptions.cpp (0 => 240431)
--- trunk/Source/_javascript_Core/API/glib/JSCOptions.cpp (rev 0)
+++ trunk/Source/_javascript_Core/API/glib/JSCOptions.cpp 2019-01-24 11:09:54 UTC (rev 240431)
@@ -0,0 +1,722 @@
+/*
+ * Copyright (C) 2019 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 changing 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 debugging.
+ * Only a few of them are documented; you can use the undocumented options at
+ * your own risk. (You can find the list of options in the 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;
+
+using int32 = int32_t;
+using size = size_t;
+
+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 <emphasis>[!]<low>[:<high>]</emphasis> where low and high are #guint values.
+ * Values between low and high (both included) will be considered in
+ * the range, unless <emphasis>!</emphasis> 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 <emphasis>[!]<low>[:<high>]</emphasis> where low and high are #guint values.
+ * Values between low and high (both included) will be considered in
+ * the range, unless <emphasis>!</emphasis> 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.
+ *
+ * Not that @description string is not localized.
+ *
+ * Returns: %TRUE to stop 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
+ * <emphasis>--jsc-<option>=<value></emphasis>.
+ * Each entry in the returned #GOptionGroup is configured to apply the
+ * corresponding option during command line parsing. Applications only need to
+ * pass the returned group to g_option_context_add_group(), and the rest will
+ * be taken care for automatically.
+ *
+ * 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;
+}
+
+/**
+ * JSC_OPTIONS_USE_JIT:
+ *
+ * Allows the executable pages to be allocated for JIT and thunks if %TRUE.
+ * Option type: %JSC_OPTION_BOOLEAN
+ * Default value: %TRUE.
+ *
+ * Since: 2.24
+ */
+
+/**
+ * JSC_OPTIONS_USE_DFG:
+ *
+ * Allows the DFG JIT to be used if %TRUE.
+ * Option type: %JSC_OPTION_BOOLEAN
+ * Default value: %TRUE.
+ *
+ * Since: 2.24
+ */
+
+/**
+ * JSC_OPTIONS_USE_FTL:
+ *
+ * Allows the FTL JIT to be used if %TRUE.
+ * Option type: %JSC_OPTION_BOOLEAN
+ * Default value: %TRUE.
+ *
+ * Since: 2.24
+ */
+
+/**
+ * JSC_OPTIONS_USE_LLINT:
+ *
+ * Allows the LLINT to be used if %TRUE.
+ * Option type: %JSC_OPTION_BOOLEAN
+ * Default value: %TRUE.
+ *
+ * Since: 2.24
+ */
Added: trunk/Source/_javascript_Core/API/glib/JSCOptions.h (0 => 240431)
--- trunk/Source/_javascript_Core/API/glib/JSCOptions.h (rev 0)
+++ trunk/Source/_javascript_Core/API/glib/JSCOptions.h 2019-01-24 11:09:54 UTC (rev 240431)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 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
+
+#define JSC_OPTIONS_USE_JIT "useJIT"
+#define JSC_OPTIONS_USE_DFG "useDFGJIT"
+#define JSC_OPTIONS_USE_FTL "useFTLJIT"
+#define JSC_OPTIONS_USE_LLINT "useLLInt"
+
+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 */
Modified: trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-4.0-sections.txt (240430 => 240431)
--- trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-4.0-sections.txt 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-4.0-sections.txt 2019-01-24 11:09:54 UTC (rev 240431)
@@ -212,6 +212,36 @@
</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
+<SUBSECTION>
+JSC_OPTIONS_USE_JIT
+JSC_OPTIONS_USE_DFG
+JSC_OPTIONS_USE_FTL
+JSC_OPTIONS_USE_LLINT
+</SECTION>
+
+<SECTION>
<FILE>JSCVersion</FILE>
<TITLE>JSCVersion</TITLE>
jsc_get_major_version
Modified: trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-docs.sgml (240430 => 240431)
--- trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-docs.sgml 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Source/_javascript_Core/API/glib/docs/jsc-glib-docs.sgml 2019-01-24 11:09:54 UTC (rev 240431)
@@ -17,6 +17,7 @@
<xi:include href=""
<xi:include href=""
<xi:include href=""
+ <xi:include href=""
<xi:include href=""
</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="" /></xi:include>
+ </index>
+
<xi:include href="" /></xi:include>
</book>
Modified: trunk/Source/_javascript_Core/API/glib/jsc.h (240430 => 240431)
--- trunk/Source/_javascript_Core/API/glib/jsc.h 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Source/_javascript_Core/API/glib/jsc.h 2019-01-24 11:09:54 UTC (rev 240431)
@@ -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>
Modified: trunk/Source/_javascript_Core/ChangeLog (240430 => 240431)
--- trunk/Source/_javascript_Core/ChangeLog 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-01-24 11:09:54 UTC (rev 240431)
@@ -1,3 +1,41 @@
+2019-01-24 Carlos Garcia Campos <[email protected]>
+
+ [GLIB] Expose _javascript_Core options in GLib public API
+ https://bugs.webkit.org/show_bug.cgi?id=188742
+
+ Reviewed by Michael Catanzaro.
+
+ Add new API to set, get and iterate JSC options.
+
+ * API/glib/JSCOptions.cpp: Added.
+ (valueFromGValue):
+ (valueToGValue):
+ (jscOptionsSetValue):
+ (jscOptionsGetValue):
+ (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):
+ (jscOptionsType):
+ (jsc_options_foreach):
+ (setOptionEntry):
+ (jsc_options_get_option_group):
+ * API/glib/JSCOptions.h: Added.
+ * API/glib/docs/jsc-glib-4.0-sections.txt:
+ * API/glib/docs/jsc-glib-docs.sgml:
+ * API/glib/jsc.h:
+ * GLib.cmake:
+
2019-01-23 Mark Lam <[email protected]>
ARM64E should not ENABLE(SEPARATED_WX_HEAP).
Modified: trunk/Source/_javascript_Core/GLib.cmake (240430 => 240431)
--- trunk/Source/_javascript_Core/GLib.cmake 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Source/_javascript_Core/GLib.cmake 2019-01-24 11:09:54 UTC (rev 240431)
@@ -8,6 +8,7 @@
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 @@
${_javascript_CORE_DIR}/API/glib/JSCContext.h
${_javascript_CORE_DIR}/API/glib/JSCDefines.h
${_javascript_CORE_DIR}/API/glib/JSCException.h
+ ${_javascript_CORE_DIR}/API/glib/JSCOptions.h
${_javascript_CORE_DIR}/API/glib/JSCValue.h
${_javascript_CORE_DIR}/API/glib/JSCVirtualMachine.h
${_javascript_CORE_DIR}/API/glib/JSCWeakValue.h
Modified: trunk/Source/WebCore/platform/gtk/po/ChangeLog (240430 => 240431)
--- trunk/Source/WebCore/platform/gtk/po/ChangeLog 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Source/WebCore/platform/gtk/po/ChangeLog 2019-01-24 11:09:54 UTC (rev 240431)
@@ -1,3 +1,12 @@
+2019-01-24 Carlos Garcia Campos <[email protected]>
+
+ [GLIB] Expose _javascript_Core options in GLib public API
+ https://bugs.webkit.org/show_bug.cgi?id=188742
+
+ Reviewed by Michael Catanzaro.
+
+ * POTFILES.in: Add JSCOptions.cpp
+
2019-01-08 Josef Andersson <[email protected]>
[GTK] Updated Swedish translation
Modified: trunk/Source/WebCore/platform/gtk/po/POTFILES.in (240430 => 240431)
--- trunk/Source/WebCore/platform/gtk/po/POTFILES.in 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Source/WebCore/platform/gtk/po/POTFILES.in 2019-01-24 11:09:54 UTC (rev 240431)
@@ -2,6 +2,7 @@
LocalizedStringsGtk.cpp
../LocalizedStrings.cpp
../network/soup/NetworkStorageSessionSoup.cpp
+../../../_javascript_Core/API/glib/JSCOptions.cpp
../../../WebKit/Shared/API/glib/WebKitHitTestResult.cpp
../../../WebKit/Shared/API/glib/WebKitURIRequest.cpp
../../../WebKit/Shared/API/glib/WebKitURIResponse.cpp
Modified: trunk/Tools/ChangeLog (240430 => 240431)
--- trunk/Tools/ChangeLog 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Tools/ChangeLog 2019-01-24 11:09:54 UTC (rev 240431)
@@ -1,5 +1,18 @@
2019-01-24 Carlos Garcia Campos <[email protected]>
+ [GLIB] Expose _javascript_Core options in GLib public API
+ https://bugs.webkit.org/show_bug.cgi?id=188742
+
+ Reviewed by Michael Catanzaro.
+
+ Add a test for the new API.
+
+ * TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp:
+ (testsJSCOptions):
+ (main):
+
+2019-01-24 Carlos Garcia Campos <[email protected]>
+
[GTK][WPE] Support JPEG 2000 images
https://bugs.webkit.org/show_bug.cgi?id=186272
Modified: trunk/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp (240430 => 240431)
--- trunk/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp 2019-01-24 10:59:47 UTC (rev 240430)
+++ trunk/Tools/TestWebKitAPI/Tests/_javascript_Core/glib/TestJSC.cpp 2019-01-24 11:09:54 UTC (rev 240431)
@@ -3227,6 +3227,211 @@
}
}
+static void testsJSCOptions()
+{
+ gboolean useJIT;
+ g_assert_true(jsc_options_get_boolean(JSC_OPTIONS_USE_JIT, &useJIT));
+ g_assert_true(useJIT);
+ g_assert_true(jsc_options_set_boolean(JSC_OPTIONS_USE_JIT, FALSE));
+ g_assert_true(jsc_options_get_boolean(JSC_OPTIONS_USE_JIT, &useJIT));
+ g_assert_false(useJIT);
+ g_assert_true(jsc_options_set_boolean(JSC_OPTIONS_USE_JIT, 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(JSC_OPTIONS_USE_JIT, &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(JSC_OPTIONS_USE_JIT, 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(JSC_OPTIONS_USE_JIT, &useJIT));
+ g_assert_true(useJIT);
+}
+
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
static void testsJSCAutocleanups()
{
@@ -3270,6 +3475,7 @@
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