pub const ext = @import("ext.zig");
const javascriptcore = @This();

const std = @import("std");
const compat = @import("compat");
const gobject = @import("gobject2");
const glib = @import("glib2");
/// A JSSClass represents a custom JavaScript class registered by the user in a `javascriptcore.Context`.
/// It allows to create new JavaScripts objects whose instances are created by the user using
/// this API.
/// It's possible to add constructors, properties and methods for a JSSClass by providing
/// `gobject.Callback`<!-- -->s to implement them.
pub const Class_ = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = javascriptcore.ClassClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The `javascriptcore.Context` in which the class was registered.
        pub const context = struct {
            pub const name = "context";

            pub const Type = ?*javascriptcore.Context;
        };

        /// The name of the class.
        pub const name = struct {
            pub const name = "name";

            pub const Type = ?[*:0]u8;
        };

        /// The parent class or `NULL` in case of final classes.
        pub const parent = struct {
            pub const name = "parent";

            pub const Type = ?*javascriptcore.Class_;
        };
    };

    pub const signals = struct {};

    /// Add a constructor to `jsc_class`. If `name` is `NULL`, the class name will be used. When <function>new</function>
    /// is used with the constructor or `javascriptcore.Value.constructorCall` is called, `callback` is invoked receiving the
    /// parameters and `user_data` as the last parameter. When the constructor object is cleared in the `javascriptcore.Class` context,
    /// `destroy_notify` is called with `user_data` as parameter.
    ///
    /// This function creates the constructor, which needs to be added to an object as a property to be able to use it. Use
    /// `javascriptcore.Context.setValue` to make the constructor available in the global object.
    ///
    /// Note that the value returned by `callback` is adopted by `jsc_class`, and the `glib.DestroyNotify` passed to
    /// `javascriptcore.Context.registerClass` is responsible for disposing of it.
    extern fn jsc_class_add_constructor(p_jsc_class: *Class_, p_name: ?[*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize, p_n_params: c_uint, ...) *javascriptcore.Value;
    pub const addConstructor = jsc_class_add_constructor;

    /// Add a constructor to `jsc_class`. If `name` is `NULL`, the class name will be used. When <function>new</function>
    /// is used with the constructor or `javascriptcore.Value.constructorCall` is called, `callback` is invoked receiving
    /// a `glib.PtrArray` of `javascriptcore.Value`<!-- -->s as arguments and `user_data` as the last parameter. When the constructor object
    /// is cleared in the `javascriptcore.Class` context, `destroy_notify` is called with `user_data` as parameter.
    ///
    /// This function creates the constructor, which needs to be added to an object as a property to be able to use it. Use
    /// `javascriptcore.Context.setValue` to make the constructor available in the global object.
    ///
    /// Note that the value returned by `callback` is adopted by `jsc_class`, and the `glib.DestroyNotify` passed to
    /// `javascriptcore.Context.registerClass` is responsible for disposing of it.
    extern fn jsc_class_add_constructor_variadic(p_jsc_class: *Class_, p_name: ?[*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize) *javascriptcore.Value;
    pub const addConstructorVariadic = jsc_class_add_constructor_variadic;

    /// Add a constructor to `jsc_class`. If `name` is `NULL`, the class name will be used. When <function>new</function>
    /// is used with the constructor or `javascriptcore.Value.constructorCall` is called, `callback` is invoked receiving the
    /// parameters and `user_data` as the last parameter. When the constructor object is cleared in the `javascriptcore.Class` context,
    /// `destroy_notify` is called with `user_data` as parameter.
    ///
    /// This function creates the constructor, which needs to be added to an object as a property to be able to use it. Use
    /// `javascriptcore.Context.setValue` to make the constructor available in the global object.
    ///
    /// Note that the value returned by `callback` is adopted by `jsc_class`, and the `glib.DestroyNotify` passed to
    /// `javascriptcore.Context.registerClass` is responsible for disposing of it.
    extern fn jsc_class_add_constructorv(p_jsc_class: *Class_, p_name: ?[*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize, p_n_parameters: c_uint, p_parameter_types: ?[*]usize) *javascriptcore.Value;
    pub const addConstructorv = jsc_class_add_constructorv;

    /// Add method with `name` to `jsc_class`. When the method is called by JavaScript or `javascriptcore.Value.objectInvokeMethod`,
    /// `callback` is called receiving the class instance as first parameter, followed by the method parameters and then
    /// `user_data` as last parameter. When the method is cleared in the `javascriptcore.Class` context, `destroy_notify` is called with
    /// `user_data` as parameter.
    ///
    /// Note that the value returned by `callback` must be transfer full. In case of non-refcounted boxed types, you should use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as the instance parameter.
    extern fn jsc_class_add_method(p_jsc_class: *Class_, p_name: [*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize, p_n_params: c_uint, ...) void;
    pub const addMethod = jsc_class_add_method;

    /// Add method with `name` to `jsc_class`. When the method is called by JavaScript or `javascriptcore.Value.objectInvokeMethod`,
    /// `callback` is called receiving the class instance as first parameter, followed by a `glib.PtrArray` of `javascriptcore.Value`<!-- -->s
    /// with the method arguments and then `user_data` as last parameter. When the method is cleared in the `javascriptcore.Class` context,
    /// `destroy_notify` is called with `user_data` as parameter.
    ///
    /// Note that the value returned by `callback` must be transfer full. In case of non-refcounted boxed types, you should use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as the instance parameter.
    extern fn jsc_class_add_method_variadic(p_jsc_class: *Class_, p_name: [*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize) void;
    pub const addMethodVariadic = jsc_class_add_method_variadic;

    /// Add method with `name` to `jsc_class`. When the method is called by JavaScript or `javascriptcore.Value.objectInvokeMethod`,
    /// `callback` is called receiving the class instance as first parameter, followed by the method parameters and then
    /// `user_data` as last parameter. When the method is cleared in the `javascriptcore.Class` context, `destroy_notify` is called with
    /// `user_data` as parameter.
    ///
    /// Note that the value returned by `callback` must be transfer full. In case of non-refcounted boxed types, you should use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as the instance parameter.
    extern fn jsc_class_add_methodv(p_jsc_class: *Class_, p_name: [*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize, p_n_parameters: c_uint, p_parameter_types: ?[*]usize) void;
    pub const addMethodv = jsc_class_add_methodv;

    /// Add a property with `name` to `jsc_class`. When the property value is read, `getter` is called
    /// receiving the the class instance as first parameter and `user_data` as last parameter. When the property
    /// value needs to be set, `setter` is called receiving the the class instance as first parameter, followed
    /// by the value to be set and then `user_data` as the last parameter. When the property is cleared in the
    /// `javascriptcore.Class` context, `destroy_notify` is called with `user_data` as parameter.
    ///
    /// Note that the value returned by `getter` must be transfer full. In case of non-refcounted boxed types, you should use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as the instance parameter.
    extern fn jsc_class_add_property(p_jsc_class: *Class_, p_name: [*:0]const u8, p_property_type: usize, p_getter: ?gobject.Callback, p_setter: ?gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const addProperty = jsc_class_add_property;

    /// Get the class name of `jsc_class`
    extern fn jsc_class_get_name(p_jsc_class: *Class_) [*:0]const u8;
    pub const getName = jsc_class_get_name;

    /// Get the parent class of `jsc_class`
    extern fn jsc_class_get_parent(p_jsc_class: *Class_) *javascriptcore.Class_;
    pub const getParent = jsc_class_get_parent;

    extern fn jsc_class_get_type() usize;
    pub const getGObjectType = jsc_class_get_type;

    extern fn g_object_ref(p_self: *javascriptcore.Class_) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *javascriptcore.Class_) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Class_, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// JSCContext represents a JavaScript execution context, where all operations
/// take place and where the values will be associated.
///
/// When a new context is created, a global object is allocated and the built-in JavaScript
/// objects (Object, Function, String, Array) are populated. You can execute JavaScript in
/// the context by using `javascriptcore.Context.evaluate` or `javascriptcore.Context.evaluateWithSourceUri`.
/// It's also possible to register custom objects in the context with `javascriptcore.Context.registerClass`.
pub const Context = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = javascriptcore.ContextClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The `javascriptcore.VirtualMachine` in which the context was created.
        pub const virtual_machine = struct {
            pub const name = "virtual-machine";

            pub const Type = ?*javascriptcore.VirtualMachine;
        };
    };

    pub const signals = struct {};

    /// Get the `javascriptcore.Context` that is currently executing a function. This should only be
    /// called within a function or method callback, otherwise `NULL` will be returned.
    extern fn jsc_context_get_current() ?*javascriptcore.Context;
    pub const getCurrent = jsc_context_get_current;

    /// Create a new `javascriptcore.Context`. The context is created in a new `javascriptcore.VirtualMachine`.
    /// Use `javascriptcore.Context.newWithVirtualMachine` to create a new `javascriptcore.Context` in an
    /// existing `javascriptcore.VirtualMachine`.
    extern fn jsc_context_new() *javascriptcore.Context;
    pub const new = jsc_context_new;

    /// Create a new `javascriptcore.Context` in `virtual_machine`.
    extern fn jsc_context_new_with_virtual_machine(p_vm: *javascriptcore.VirtualMachine) *javascriptcore.Context;
    pub const newWithVirtualMachine = jsc_context_new_with_virtual_machine;

    /// Check the given `code` in `context` for syntax errors. The `line_number` is the starting line number in `uri`;
    /// the value is one-based so the first line is 1. `uri` and `line_number` are only used to fill the `exception`.
    /// In case of errors `exception` will be set to a new `javascriptcore.Exception` with the details. You can pass `NULL` to
    /// `exception` to ignore the error details.
    extern fn jsc_context_check_syntax(p_context: *Context, p_code: [*:0]const u8, p_length: isize, p_mode: javascriptcore.CheckSyntaxMode, p_uri: [*:0]const u8, p_line_number: c_uint, p_exception: ?**javascriptcore.Exception) javascriptcore.CheckSyntaxResult;
    pub const checkSyntax = jsc_context_check_syntax;

    /// Clear the uncaught exception in `context` if any.
    extern fn jsc_context_clear_exception(p_context: *Context) void;
    pub const clearException = jsc_context_clear_exception;

    /// Evaluate `code` in `context`.
    extern fn jsc_context_evaluate(p_context: *Context, p_code: [*:0]const u8, p_length: isize) *javascriptcore.Value;
    pub const evaluate = jsc_context_evaluate;

    /// Evaluate `code` and create an new object where symbols defined in `code` will be added as properties,
    /// instead of being added to `context` global object. The new object is returned as `object` parameter.
    /// Similar to how `javascriptcore.Value.newObject` works, if `object_instance` is not `NULL` `object_class` must be provided too.
    /// The `line_number` is the starting line number in `uri`; the value is one-based so the first line is 1.
    /// `uri` and `line_number` will be shown in exceptions and they don't affect the behavior of the script.
    extern fn jsc_context_evaluate_in_object(p_context: *Context, p_code: [*:0]const u8, p_length: isize, p_object_instance: ?*anyopaque, p_object_class: ?*javascriptcore.Class_, p_uri: [*:0]const u8, p_line_number: c_uint, p_object: **javascriptcore.Value) *javascriptcore.Value;
    pub const evaluateInObject = jsc_context_evaluate_in_object;

    /// Evaluate `code` in `context` using `uri` as the source URI. The `line_number` is the starting line number
    /// in `uri`; the value is one-based so the first line is 1. `uri` and `line_number` will be shown in exceptions and
    /// they don't affect the behavior of the script.
    extern fn jsc_context_evaluate_with_source_uri(p_context: *Context, p_code: [*:0]const u8, p_length: isize, p_uri: [*:0]const u8, p_line_number: c_uint) *javascriptcore.Value;
    pub const evaluateWithSourceUri = jsc_context_evaluate_with_source_uri;

    /// Get the last unhandled exception thrown in `context` by API functions calls.
    extern fn jsc_context_get_exception(p_context: *Context) ?*javascriptcore.Exception;
    pub const getException = jsc_context_get_exception;

    /// Get a `javascriptcore.Value` referencing the `context` global object
    extern fn jsc_context_get_global_object(p_context: *Context) *javascriptcore.Value;
    pub const getGlobalObject = jsc_context_get_global_object;

    /// Get a property of `context` global object with `name`.
    extern fn jsc_context_get_value(p_context: *Context, p_name: [*:0]const u8) *javascriptcore.Value;
    pub const getValue = jsc_context_get_value;

    /// Get the `javascriptcore.VirtualMachine` where `context` was created.
    extern fn jsc_context_get_virtual_machine(p_context: *Context) *javascriptcore.VirtualMachine;
    pub const getVirtualMachine = jsc_context_get_virtual_machine;

    /// Remove the last `javascriptcore.ExceptionHandler` previously pushed to `context` with
    /// `javascriptcore.Context.pushExceptionHandler`.
    extern fn jsc_context_pop_exception_handler(p_context: *Context) void;
    pub const popExceptionHandler = jsc_context_pop_exception_handler;

    /// Push an exception handler in `context`. Whenever a JavaScript exception happens in
    /// the `javascriptcore.Context`, the given `handler` will be called. The default `javascriptcore.ExceptionHandler`
    /// simply calls `javascriptcore.Context.throwException` to throw the exception to the `javascriptcore.Context`.
    /// If you don't want to catch the exception, but only get notified about it, call
    /// `javascriptcore.Context.throwException` in `handler` like the default one does.
    /// The last exception handler pushed is the only one used by the `javascriptcore.Context`, use
    /// `javascriptcore.Context.popExceptionHandler` to remove it and set the previous one. When `handler`
    /// is removed from the context, `destroy_notify` is called with `user_data` as parameter.
    extern fn jsc_context_push_exception_handler(p_context: *Context, p_handler: javascriptcore.ExceptionHandler, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const pushExceptionHandler = jsc_context_push_exception_handler;

    /// Register a custom class in `context` using the given `name`. If the new class inherits from
    /// another `javascriptcore.Class`, the parent should be passed as `parent_class`, otherwise `NULL` should be
    /// used. The optional `vtable` parameter allows to provide a custom implementation for handling
    /// the class, for example, to handle external properties not added to the prototype.
    /// When an instance of the `javascriptcore.Class` is cleared in the context, `destroy_notify` is called with
    /// the instance as parameter.
    extern fn jsc_context_register_class(p_context: *Context, p_name: [*:0]const u8, p_parent_class: ?*javascriptcore.Class_, p_vtable: ?*javascriptcore.ClassVTable, p_destroy_notify: ?glib.DestroyNotify) *javascriptcore.Class_;
    pub const registerClass = jsc_context_register_class;

    /// Set a property of `context` global object with `name` and `value`.
    extern fn jsc_context_set_value(p_context: *Context, p_name: [*:0]const u8, p_value: *javascriptcore.Value) void;
    pub const setValue = jsc_context_set_value;

    /// Throw an exception to `context` using the given error message. The created `javascriptcore.Exception`
    /// can be retrieved with `javascriptcore.Context.getException`.
    extern fn jsc_context_throw(p_context: *Context, p_error_message: [*:0]const u8) void;
    pub const throw = jsc_context_throw;

    /// Throw `exception` to `context`.
    extern fn jsc_context_throw_exception(p_context: *Context, p_exception: *javascriptcore.Exception) void;
    pub const throwException = jsc_context_throw_exception;

    /// Throw an exception to `context` using the given formatted string as error message.
    /// The created `javascriptcore.Exception` can be retrieved with `javascriptcore.Context.getException`.
    extern fn jsc_context_throw_printf(p_context: *Context, p_format: [*:0]const u8, ...) void;
    pub const throwPrintf = jsc_context_throw_printf;

    /// Throw an exception to `context` using the given error name and message. The created `javascriptcore.Exception`
    /// can be retrieved with `javascriptcore.Context.getException`.
    extern fn jsc_context_throw_with_name(p_context: *Context, p_error_name: [*:0]const u8, p_error_message: [*:0]const u8) void;
    pub const throwWithName = jsc_context_throw_with_name;

    /// Throw an exception to `context` using the given error name and the formatted string as error message.
    /// The created `javascriptcore.Exception` can be retrieved with `javascriptcore.Context.getException`.
    extern fn jsc_context_throw_with_name_printf(p_context: *Context, p_error_name: [*:0]const u8, p_format: [*:0]const u8, ...) void;
    pub const throwWithNamePrintf = jsc_context_throw_with_name_printf;

    extern fn jsc_context_get_type() usize;
    pub const getGObjectType = jsc_context_get_type;

    extern fn g_object_ref(p_self: *javascriptcore.Context) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *javascriptcore.Context) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Context, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// JSCException represents a JavaScript exception.
pub const Exception = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = javascriptcore.ExceptionClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Create a new `javascriptcore.Exception` in `context` with `message`.
    extern fn jsc_exception_new(p_context: *javascriptcore.Context, p_message: [*:0]const u8) *javascriptcore.Exception;
    pub const new = jsc_exception_new;

    /// Create a new `javascriptcore.Exception` in `context` using a formatted string
    /// for the message.
    extern fn jsc_exception_new_printf(p_context: *javascriptcore.Context, p_format: [*:0]const u8, ...) *javascriptcore.Exception;
    pub const newPrintf = jsc_exception_new_printf;

    /// Create a new `javascriptcore.Exception` in `context` using a formatted string
    /// for the message. This is similar to `javascriptcore.Exception.newPrintf`
    /// except that the arguments to the format string are passed as a va_list.
    extern fn jsc_exception_new_vprintf(p_context: *javascriptcore.Context, p_format: [*:0]const u8, p_args: std.builtin.VaList) *javascriptcore.Exception;
    pub const newVprintf = jsc_exception_new_vprintf;

    /// Create a new `javascriptcore.Exception` in `context` with `name` and `message`.
    extern fn jsc_exception_new_with_name(p_context: *javascriptcore.Context, p_name: [*:0]const u8, p_message: [*:0]const u8) *javascriptcore.Exception;
    pub const newWithName = jsc_exception_new_with_name;

    /// Create a new `javascriptcore.Exception` in `context` with `name` and using a formatted string
    /// for the message.
    extern fn jsc_exception_new_with_name_printf(p_context: *javascriptcore.Context, p_name: [*:0]const u8, p_format: [*:0]const u8, ...) *javascriptcore.Exception;
    pub const newWithNamePrintf = jsc_exception_new_with_name_printf;

    /// Create a new `javascriptcore.Exception` in `context` with `name` and using a formatted string
    /// for the message. This is similar to `javascriptcore.Exception.newWithNamePrintf`
    /// except that the arguments to the format string are passed as a va_list.
    extern fn jsc_exception_new_with_name_vprintf(p_context: *javascriptcore.Context, p_name: [*:0]const u8, p_format: [*:0]const u8, p_args: std.builtin.VaList) *javascriptcore.Exception;
    pub const newWithNameVprintf = jsc_exception_new_with_name_vprintf;

    /// Get a string with the exception backtrace.
    extern fn jsc_exception_get_backtrace_string(p_exception: *Exception) ?[*:0]const u8;
    pub const getBacktraceString = jsc_exception_get_backtrace_string;

    /// Get the column number at which `exception` happened.
    extern fn jsc_exception_get_column_number(p_exception: *Exception) c_uint;
    pub const getColumnNumber = jsc_exception_get_column_number;

    /// Get the line number at which `exception` happened.
    extern fn jsc_exception_get_line_number(p_exception: *Exception) c_uint;
    pub const getLineNumber = jsc_exception_get_line_number;

    /// Get the error message of `exception`.
    extern fn jsc_exception_get_message(p_exception: *Exception) [*:0]const u8;
    pub const getMessage = jsc_exception_get_message;

    /// Get the error name of `exception`
    extern fn jsc_exception_get_name(p_exception: *Exception) [*:0]const u8;
    pub const getName = jsc_exception_get_name;

    /// Get the source URI of `exception`.
    extern fn jsc_exception_get_source_uri(p_exception: *Exception) ?[*:0]const u8;
    pub const getSourceUri = jsc_exception_get_source_uri;

    /// Return a report message of `exception`, containing all the possible details such us
    /// source URI, line, column and backtrace, and formatted to be printed.
    extern fn jsc_exception_report(p_exception: *Exception) [*:0]u8;
    pub const report = jsc_exception_report;

    /// Get the string representation of `exception` error.
    extern fn jsc_exception_to_string(p_exception: *Exception) [*:0]u8;
    pub const toString = jsc_exception_to_string;

    extern fn jsc_exception_get_type() usize;
    pub const getGObjectType = jsc_exception_get_type;

    extern fn g_object_ref(p_self: *javascriptcore.Exception) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *javascriptcore.Exception) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Exception, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// JSCValue represents a reference to a value in a `javascriptcore.Context`. The JSCValue
/// protects the referenced value from being garbage collected.
pub const Value = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = javascriptcore.ValueClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The `javascriptcore.Context` in which the value was created.
        pub const context = struct {
            pub const name = "context";

            pub const Type = ?*javascriptcore.Context;
        };
    };

    pub const signals = struct {};

    /// Create a new `javascriptcore.Value` referencing an array with the given items. If `first_item_type`
    /// is `G_TYPE_NONE` an empty array is created.
    extern fn jsc_value_new_array(p_context: *javascriptcore.Context, p_first_item_type: usize, ...) *javascriptcore.Value;
    pub const newArray = jsc_value_new_array;

    /// Creates a new `ArrayBuffer` from existing `data` in memory.
    ///
    /// The `data` is not copied: while this allows sharing data with JavaScript
    /// efficiently, the caller must ensure that the memory region remains valid
    /// until the newly created object is released by JSC.
    ///
    /// Optionally, a `destroy_notify` callback can be provided, which will be
    /// invoked with `user_data` as parameter when the `ArrayBuffer` object is
    /// released. This is intended to be used for freeing resources related to
    /// the memory region which contains the data:
    ///
    /// ```
    /// GMappedFile *f = g_mapped_file_new (file_path, TRUE, NULL);
    /// JSCValue *value = jsc_value_new_array_buffer (context,
    ///     g_mapped_file_get_contents (f), g_mapped_file_get_length (f),
    ///     (GDestroyNotify) g_mapped_file_unref, f);
    /// ```
    ///
    /// Note that the `user_data` can be the same value as `data`:
    ///
    /// ```
    /// void *bytes = g_malloc0 (100);
    /// JSCValue *value = jsc_value_new_array_buffer (context, bytes, 100, g_free, bytes);
    /// ```
    extern fn jsc_value_new_array_buffer(p_context: *javascriptcore.Context, p_data: ?*anyopaque, p_size: usize, p_destroy_notify: ?glib.DestroyNotify, p_user_data: ?*anyopaque) ?*javascriptcore.Value;
    pub const newArrayBuffer = jsc_value_new_array_buffer;

    /// Create a new `javascriptcore.Value` referencing an array with the items from `array`. If `array`
    /// is `NULL` or empty a new empty array will be created. Elements of `array` should be
    /// pointers to a `javascriptcore.Value`.
    extern fn jsc_value_new_array_from_garray(p_context: *javascriptcore.Context, p_array: ?*glib.PtrArray) *javascriptcore.Value;
    pub const newArrayFromGarray = jsc_value_new_array_from_garray;

    /// Create a new `javascriptcore.Value` referencing an array of strings with the items from `strv`. If `array`
    /// is `NULL` or empty a new empty array will be created.
    extern fn jsc_value_new_array_from_strv(p_context: *javascriptcore.Context, p_strv: [*]const [*:0]const u8) *javascriptcore.Value;
    pub const newArrayFromStrv = jsc_value_new_array_from_strv;

    /// Create a new `javascriptcore.Value` from `value`
    extern fn jsc_value_new_boolean(p_context: *javascriptcore.Context, p_value: c_int) *javascriptcore.Value;
    pub const newBoolean = jsc_value_new_boolean;

    /// Create a new `javascriptcore.Value` referencing a new value created by parsing `json`.
    extern fn jsc_value_new_from_json(p_context: *javascriptcore.Context, p_json: [*:0]const u8) *javascriptcore.Value;
    pub const newFromJson = jsc_value_new_from_json;

    /// Create a function in `context`. If `name` is `NULL` an anonymous function will be created.
    /// When the function is called by JavaScript or `javascriptcore.Value.functionCall`, `callback` is called
    /// receiving the function parameters and then `user_data` as last parameter. When the function is
    /// cleared in `context`, `destroy_notify` is called with `user_data` as parameter.
    ///
    /// Note that the value returned by `callback` must be fully transferred. In case of boxed types, you could use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as instance parameter.
    extern fn jsc_value_new_function(p_context: *javascriptcore.Context, p_name: ?[*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize, p_n_params: c_uint, ...) *javascriptcore.Value;
    pub const newFunction = jsc_value_new_function;

    /// Create a function in `context`. If `name` is `NULL` an anonymous function will be created.
    /// When the function is called by JavaScript or `javascriptcore.Value.functionCall`, `callback` is called
    /// receiving an `glib.PtrArray` of `javascriptcore.Value`<!-- -->s with the arguments and then `user_data` as last parameter.
    /// When the function is cleared in `context`, `destroy_notify` is called with `user_data` as parameter.
    ///
    /// Note that the value returned by `callback` must be fully transferred. In case of boxed types, you could use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as instance parameter.
    extern fn jsc_value_new_function_variadic(p_context: *javascriptcore.Context, p_name: ?[*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize) *javascriptcore.Value;
    pub const newFunctionVariadic = jsc_value_new_function_variadic;

    /// Create a function in `context`. If `name` is `NULL` an anonymous function will be created.
    /// When the function is called by JavaScript or `javascriptcore.Value.functionCall`, `callback` is called
    /// receiving the function parameters and then `user_data` as last parameter. When the function is
    /// cleared in `context`, `destroy_notify` is called with `user_data` as parameter.
    ///
    /// Note that the value returned by `callback` must be fully transferred. In case of boxed types, you could use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as instance parameter.
    extern fn jsc_value_new_functionv(p_context: *javascriptcore.Context, p_name: ?[*:0]const u8, p_callback: gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify, p_return_type: usize, p_n_parameters: c_uint, p_parameter_types: ?[*]usize) *javascriptcore.Value;
    pub const newFunctionv = jsc_value_new_functionv;

    /// Create a new `javascriptcore.Value` referencing <function>null</function> in `context`.
    extern fn jsc_value_new_null(p_context: *javascriptcore.Context) *javascriptcore.Value;
    pub const newNull = jsc_value_new_null;

    /// Create a new `javascriptcore.Value` from `number`.
    extern fn jsc_value_new_number(p_context: *javascriptcore.Context, p_number: f64) *javascriptcore.Value;
    pub const newNumber = jsc_value_new_number;

    /// Create a new `javascriptcore.Value` from `instance`. If `instance` is `NULL` a new empty object is created.
    /// When `instance` is provided, `jsc_class` must be provided too. `jsc_class` takes ownership of
    /// `instance` that will be freed by the `glib.DestroyNotify` passed to `javascriptcore.Context.registerClass`.
    extern fn jsc_value_new_object(p_context: *javascriptcore.Context, p_instance: ?*anyopaque, p_jsc_class: ?*javascriptcore.Class_) *javascriptcore.Value;
    pub const newObject = jsc_value_new_object;

    /// Creates a new Promise. `executor` will be invoked during promise initialization
    /// and it receives the `resolve` and `reject` objects than can be called to resolve
    /// or reject the promise. It is called like a JavaScript function, so exceptions raised
    /// during the executor invocation will not be propagated to the context, but
    /// handled by the promise causing a rejection.
    extern fn jsc_value_new_promise(p_context: *javascriptcore.Context, p_executor: javascriptcore.Executor, p_user_data: ?*anyopaque) *javascriptcore.Value;
    pub const newPromise = jsc_value_new_promise;

    /// Create a new `javascriptcore.Value` from `string`. If you need to create a `javascriptcore.Value` from a
    /// string containing null characters, use `javascriptcore.Value.newStringFromBytes` instead.
    extern fn jsc_value_new_string(p_context: *javascriptcore.Context, p_string: ?[*:0]const u8) *javascriptcore.Value;
    pub const newString = jsc_value_new_string;

    /// Create a new `javascriptcore.Value` from `bytes`.
    extern fn jsc_value_new_string_from_bytes(p_context: *javascriptcore.Context, p_bytes: ?*glib.Bytes) *javascriptcore.Value;
    pub const newStringFromBytes = jsc_value_new_string_from_bytes;

    /// Create a new typed array containing a given amount of elements.
    ///
    /// Create a `javascriptcore.Value` referencing a new typed array with space for `length`
    /// elements of a given `type`. As all typed arrays must have an associated
    /// `ArrayBuffer`, a new one of suitable size will be allocated to store
    /// the elements, which will be initialized to zero.
    ///
    /// The `type` must *not* be `JSC_TYPED_ARRAY_NONE`.
    extern fn jsc_value_new_typed_array(p_context: *javascriptcore.Context, p_type: javascriptcore.TypedArrayType, p_length: usize) *javascriptcore.Value;
    pub const newTypedArray = jsc_value_new_typed_array;

    /// Create a new `javascriptcore.Value` referencing <function>undefined</function> in `context`.
    extern fn jsc_value_new_undefined(p_context: *javascriptcore.Context) *javascriptcore.Value;
    pub const newUndefined = jsc_value_new_undefined;

    /// Gets a pointer to memory that contains the array buffer data.
    ///
    /// Obtains a pointer to the memory region that holds the contents of the
    /// `ArrayBuffer`; modifications done to the data will be visible to JavaScript
    /// code. If `size` is not `NULL`, the size in bytes of the memory region
    /// will also be stored in the pointed location.
    ///
    /// Note that the pointer returned by this function is not guaranteed to remain
    /// the same after calls to other JSC API functions. If you plan to access the
    /// data of the `ArrayBuffer` later, you can keep a reference to the `value` and
    /// obtain the data pointer at a later point. Keep in mind that if JavaScript
    /// code has a chance to run, for example due to main loop events that result
    /// in JSC being called, the contents of the memory region might be modified in
    /// the meantime. Consider taking a copy of the data and using the copy instead
    /// in asynchronous code.
    extern fn jsc_value_array_buffer_get_data(p_value: *Value, p_size: ?*usize) [*]u8;
    pub const arrayBufferGetData = jsc_value_array_buffer_get_data;

    /// Gets the size in bytes of the array buffer.
    ///
    /// Obtains the size in bytes of the memory region that holds the contents of
    /// an `ArrayBuffer`.
    extern fn jsc_value_array_buffer_get_size(p_value: *Value) usize;
    pub const arrayBufferGetSize = jsc_value_array_buffer_get_size;

    /// Invoke <function>new</function> with constructor referenced by `value`. If `first_parameter_type`
    /// is `G_TYPE_NONE` no parameters will be passed to the constructor.
    extern fn jsc_value_constructor_call(p_value: *Value, p_first_parameter_type: usize, ...) *javascriptcore.Value;
    pub const constructorCall = jsc_value_constructor_call;

    /// Invoke <function>new</function> with constructor referenced by `value`. If `n_parameters`
    /// is 0 no parameters will be passed to the constructor.
    extern fn jsc_value_constructor_callv(p_value: *Value, p_n_parameters: c_uint, p_parameters: ?[*]*javascriptcore.Value) *javascriptcore.Value;
    pub const constructorCallv = jsc_value_constructor_callv;

    /// Call function referenced by `value`, passing the given parameters. If `first_parameter_type`
    /// is `G_TYPE_NONE` no parameters will be passed to the function.
    ///
    /// This function always returns a `javascriptcore.Value`, in case of void functions a `javascriptcore.Value` referencing
    /// <function>undefined</function> is returned
    extern fn jsc_value_function_call(p_value: *Value, p_first_parameter_type: usize, ...) *javascriptcore.Value;
    pub const functionCall = jsc_value_function_call;

    /// Call function referenced by `value`, passing the given `parameters`. If `n_parameters`
    /// is 0 no parameters will be passed to the function.
    ///
    /// This function always returns a `javascriptcore.Value`, in case of void functions a `javascriptcore.Value` referencing
    /// <function>undefined</function> is returned
    extern fn jsc_value_function_callv(p_value: *Value, p_n_parameters: c_uint, p_parameters: ?[*]*javascriptcore.Value) *javascriptcore.Value;
    pub const functionCallv = jsc_value_function_callv;

    /// Get the `javascriptcore.Context` in which `value` was created.
    extern fn jsc_value_get_context(p_value: *Value) *javascriptcore.Context;
    pub const getContext = jsc_value_get_context;

    /// Get whether the value referenced by `value` is an array.
    extern fn jsc_value_is_array(p_value: *Value) c_int;
    pub const isArray = jsc_value_is_array;

    /// Check whether the `value` is an `ArrayBuffer`.
    extern fn jsc_value_is_array_buffer(p_value: *Value) c_int;
    pub const isArrayBuffer = jsc_value_is_array_buffer;

    /// Get whether the value referenced by `value` is a boolean.
    extern fn jsc_value_is_boolean(p_value: *Value) c_int;
    pub const isBoolean = jsc_value_is_boolean;

    /// Get whether the value referenced by `value` is a constructor.
    extern fn jsc_value_is_constructor(p_value: *Value) c_int;
    pub const isConstructor = jsc_value_is_constructor;

    /// Get whether the value referenced by `value` is a function
    extern fn jsc_value_is_function(p_value: *Value) c_int;
    pub const isFunction = jsc_value_is_function;

    /// Get whether the value referenced by `value` is <function>null</function>.
    extern fn jsc_value_is_null(p_value: *Value) c_int;
    pub const isNull = jsc_value_is_null;

    /// Get whether the value referenced by `value` is a number.
    extern fn jsc_value_is_number(p_value: *Value) c_int;
    pub const isNumber = jsc_value_is_number;

    /// Get whether the value referenced by `value` is an object.
    extern fn jsc_value_is_object(p_value: *Value) c_int;
    pub const isObject = jsc_value_is_object;

    /// Get whether the value referenced by `value` is a string
    extern fn jsc_value_is_string(p_value: *Value) c_int;
    pub const isString = jsc_value_is_string;

    /// Determines whether a value is a typed array.
    extern fn jsc_value_is_typed_array(p_value: *Value) c_int;
    pub const isTypedArray = jsc_value_is_typed_array;

    /// Get whether the value referenced by `value` is <function>undefined</function>.
    extern fn jsc_value_is_undefined(p_value: *Value) c_int;
    pub const isUndefined = jsc_value_is_undefined;

    /// Create a new typed array value with elements from an array buffer.
    ///
    /// Create a `javascriptcore.Value` referencing a new typed array value containing
    /// elements of the given `type`, where the elements are stored at the memory
    /// region represented by the `array_buffer`.
    ///
    /// The `type` must *not* be `JSC_TYPED_ARRAY_NONE`.
    ///
    /// The `offset` and `length` parameters can be used to indicate which part of
    /// the array buffer can be accessed through the typed array. If both are
    /// omitted (passing zero as `offset`, and `-1` as `length`), the whole
    /// `array_buffer` is exposed through the typed array. Omitting the `length`
    /// with a non-zero `offset` will expose the remainder of the `array_buffer`
    /// starting at the indicated offset.
    extern fn jsc_value_new_typed_array_with_buffer(p_array_buffer: *Value, p_type: javascriptcore.TypedArrayType, p_offset: usize, p_length: isize) *javascriptcore.Value;
    pub const newTypedArrayWithBuffer = jsc_value_new_typed_array_with_buffer;

    /// Define or modify a property with `property_name` in object referenced by `value`. When the
    /// property value is read or set, `getter` and `setter` callbacks will be called.
    /// When the property is cleared in the `javascriptcore.Class` context, `destroy_notify` is called with
    /// `user_data` as parameter. This is equivalent to JavaScript <function>Object.`defineProperty`</function>
    /// when used with an accessor descriptor.
    ///
    /// Note that the value returned by `getter` must be fully transferred. In case of boxed types, you could use
    /// `G_TYPE_POINTER` instead of the actual boxed `gobject.Type` to ensure that the instance owned by `javascriptcore.Class` is used.
    /// If you really want to return a new copy of the boxed type, use `JSC_TYPE_VALUE` and return a `javascriptcore.Value` created
    /// with `javascriptcore.Value.newObject` that receives the copy as instance parameter.
    ///
    /// Note that `getter` and `setter` are called as functions and not methods, so they don't receive an instance as
    /// first parameter. Use `javascriptcore.Class.addProperty` if you want to add property accessor invoked as a method.
    extern fn jsc_value_object_define_property_accessor(p_value: *Value, p_property_name: [*:0]const u8, p_flags: javascriptcore.ValuePropertyFlags, p_property_type: usize, p_getter: ?gobject.Callback, p_setter: ?gobject.Callback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const objectDefinePropertyAccessor = jsc_value_object_define_property_accessor;

    /// Define or modify a property with `property_name` in object referenced by `value`. This is equivalent to
    /// JavaScript <function>Object.`defineProperty`</function> when used with a data descriptor.
    extern fn jsc_value_object_define_property_data(p_value: *Value, p_property_name: [*:0]const u8, p_flags: javascriptcore.ValuePropertyFlags, p_property_value: ?*javascriptcore.Value) void;
    pub const objectDefinePropertyData = jsc_value_object_define_property_data;

    /// Try to delete property with `name` from `value`. This function will return `FALSE` if
    /// the property was defined without `JSC_VALUE_PROPERTY_CONFIGURABLE` flag.
    extern fn jsc_value_object_delete_property(p_value: *Value, p_name: [*:0]const u8) c_int;
    pub const objectDeleteProperty = jsc_value_object_delete_property;

    /// Get the list of property names of `value`. Only properties defined with `JSC_VALUE_PROPERTY_ENUMERABLE`
    /// flag will be collected.
    extern fn jsc_value_object_enumerate_properties(p_value: *Value) ?[*][*:0]u8;
    pub const objectEnumerateProperties = jsc_value_object_enumerate_properties;

    /// Get property with `name` from `value`.
    extern fn jsc_value_object_get_property(p_value: *Value, p_name: [*:0]const u8) *javascriptcore.Value;
    pub const objectGetProperty = jsc_value_object_get_property;

    /// Get property at `index` from `value`.
    extern fn jsc_value_object_get_property_at_index(p_value: *Value, p_index: c_uint) *javascriptcore.Value;
    pub const objectGetPropertyAtIndex = jsc_value_object_get_property_at_index;

    /// Get whether `value` has property with `name`.
    extern fn jsc_value_object_has_property(p_value: *Value, p_name: [*:0]const u8) c_int;
    pub const objectHasProperty = jsc_value_object_has_property;

    /// Invoke method with `name` on object referenced by `value`, passing the given parameters. If
    /// `first_parameter_type` is `G_TYPE_NONE` no parameters will be passed to the method.
    /// The object instance will be handled automatically even when the method is a custom one
    /// registered with `javascriptcore.Class.addMethod`, so it should never be passed explicitly as parameter
    /// of this function.
    ///
    /// This function always returns a `javascriptcore.Value`, in case of void methods a `javascriptcore.Value` referencing
    /// <function>undefined</function> is returned.
    extern fn jsc_value_object_invoke_method(p_value: *Value, p_name: [*:0]const u8, p_first_parameter_type: usize, ...) *javascriptcore.Value;
    pub const objectInvokeMethod = jsc_value_object_invoke_method;

    /// Invoke method with `name` on object referenced by `value`, passing the given `parameters`. If
    /// `n_parameters` is 0 no parameters will be passed to the method.
    /// The object instance will be handled automatically even when the method is a custom one
    /// registered with `javascriptcore.Class.addMethod`, so it should never be passed explicitly as parameter
    /// of this function.
    ///
    /// This function always returns a `javascriptcore.Value`, in case of void methods a `javascriptcore.Value` referencing
    /// <function>undefined</function> is returned.
    extern fn jsc_value_object_invoke_methodv(p_value: *Value, p_name: [*:0]const u8, p_n_parameters: c_uint, p_parameters: ?[*]*javascriptcore.Value) *javascriptcore.Value;
    pub const objectInvokeMethodv = jsc_value_object_invoke_methodv;

    /// Get whether the value referenced by `value` is an instance of class `name`.
    extern fn jsc_value_object_is_instance_of(p_value: *Value, p_name: [*:0]const u8) c_int;
    pub const objectIsInstanceOf = jsc_value_object_is_instance_of;

    /// Set `property` with `name` on `value`.
    extern fn jsc_value_object_set_property(p_value: *Value, p_name: [*:0]const u8, p_property: *javascriptcore.Value) void;
    pub const objectSetProperty = jsc_value_object_set_property;

    /// Set `property` at `index` on `value`.
    extern fn jsc_value_object_set_property_at_index(p_value: *Value, p_index: c_uint, p_property: *javascriptcore.Value) void;
    pub const objectSetPropertyAtIndex = jsc_value_object_set_property_at_index;

    /// Convert `value` to a boolean.
    extern fn jsc_value_to_boolean(p_value: *Value) c_int;
    pub const toBoolean = jsc_value_to_boolean;

    /// Convert `value` to a double.
    extern fn jsc_value_to_double(p_value: *Value) f64;
    pub const toDouble = jsc_value_to_double;

    /// Convert `value` to a `gint32`.
    extern fn jsc_value_to_int32(p_value: *Value) i32;
    pub const toInt32 = jsc_value_to_int32;

    /// Create a JSON string of `value` serialization. If `indent` is 0, the resulting JSON will
    /// not contain newlines. The size of the indent is clamped to 10 spaces.
    extern fn jsc_value_to_json(p_value: *Value, p_indent: c_uint) [*:0]u8;
    pub const toJson = jsc_value_to_json;

    /// Convert `value` to a string. Use `javascriptcore.Value.toStringAsBytes` instead, if you need to
    /// handle strings containing null characters.
    extern fn jsc_value_to_string(p_value: *Value) [*:0]u8;
    pub const toString = jsc_value_to_string;

    /// Convert `value` to a string and return the results as `glib.Bytes`. This is needed
    /// to handle strings with null characters.
    extern fn jsc_value_to_string_as_bytes(p_value: *Value) *glib.Bytes;
    pub const toStringAsBytes = jsc_value_to_string_as_bytes;

    /// Obtain the `ArrayBuffer` for the memory region of the typed array elements.
    extern fn jsc_value_typed_array_get_buffer(p_value: *Value) *javascriptcore.Value;
    pub const typedArrayGetBuffer = jsc_value_typed_array_get_buffer;

    /// Obtains a pointer to the memory region that holds the elements of the typed
    /// array; modifications done to them will be visible to JavaScript code. If
    /// `length` is not `NULL`, the number of elements contained in the typed array
    /// are also stored in the pointed location.
    ///
    /// The returned pointer needs to be casted to the appropriate type (see
    /// `javascriptcore.TypedArrayType`), and has the `offset` over the underlying array
    /// buffer data applied—that is, points to the first element of the typed
    /// array:
    ///
    /// ```
    /// if (jsc_value_typed_array_get_type(value) != JSC_TYPED_ARRAY_UINT32)
    ///     g_error ("Only arrays of uint32_t are supported");
    ///
    /// gsize count = 0;
    /// uint32_t *elements = jsc_value_typed_array_get_contents (value, &count);
    /// for (gsize i = 0; i < count; i++)
    ///      g_print ("index `zu`, value %" PRIu32 "\n", i, elements[i]);
    /// ```
    ///
    /// Note that the pointer returned by this function is not guaranteed to remain
    /// the same after calls to other JSC API functions. See
    /// `javascriptcore.Value.arrayBufferGetData` for details.
    extern fn jsc_value_typed_array_get_data(p_value: *Value, p_length: ?*usize) ?*anyopaque;
    pub const typedArrayGetData = jsc_value_typed_array_get_data;

    /// Gets the number of elements in a typed array.
    extern fn jsc_value_typed_array_get_length(p_value: *Value) usize;
    pub const typedArrayGetLength = jsc_value_typed_array_get_length;

    /// Gets the offset over the underlying array buffer data.
    extern fn jsc_value_typed_array_get_offset(p_value: *Value) usize;
    pub const typedArrayGetOffset = jsc_value_typed_array_get_offset;

    /// Gets the size of a typed array.
    extern fn jsc_value_typed_array_get_size(p_value: *Value) usize;
    pub const typedArrayGetSize = jsc_value_typed_array_get_size;

    /// Gets the type of elements contained in a typed array.
    extern fn jsc_value_typed_array_get_type(p_value: *Value) javascriptcore.TypedArrayType;
    pub const typedArrayGetType = jsc_value_typed_array_get_type;

    extern fn jsc_value_get_type() usize;
    pub const getGObjectType = jsc_value_get_type;

    extern fn g_object_ref(p_self: *javascriptcore.Value) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *javascriptcore.Value) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Value, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// JSCVirtualMachine represents a group of JSCContext<!-- -->s. It allows
/// concurrent JavaScript execution by creating a different instance of
/// JSCVirtualMachine in each thread.
///
/// To create a group of JSCContext<!-- -->s pass the same JSCVirtualMachine
/// instance to every JSCContext constructor.
pub const VirtualMachine = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = javascriptcore.VirtualMachineClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Create a new `javascriptcore.VirtualMachine`.
    extern fn jsc_virtual_machine_new() *javascriptcore.VirtualMachine;
    pub const new = jsc_virtual_machine_new;

    extern fn jsc_virtual_machine_get_type() usize;
    pub const getGObjectType = jsc_virtual_machine_get_type;

    extern fn g_object_ref(p_self: *javascriptcore.VirtualMachine) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *javascriptcore.VirtualMachine) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *VirtualMachine, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// JSCWeakValue represents a weak reference to a value in a `javascriptcore.Context`. It can be used
/// to keep a reference to a JavaScript value without protecting it from being garbage
/// collected and without referencing the `javascriptcore.Context` either.
pub const WeakValue = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = javascriptcore.WeakValueClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The `javascriptcore.Value` referencing the JavaScript value.
        pub const value = struct {
            pub const name = "value";

            pub const Type = ?*javascriptcore.Value;
        };
    };

    pub const signals = struct {
        /// This signal is emitted when the JavaScript value is destroyed.
        pub const cleared = struct {
            pub const name = "cleared";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(WeakValue, p_instance))),
                    gobject.signalLookup("cleared", WeakValue.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Create a new `javascriptcore.WeakValue` for the JavaScript value referenced by `value`.
    extern fn jsc_weak_value_new(p_value: *javascriptcore.Value) *javascriptcore.WeakValue;
    pub const new = jsc_weak_value_new;

    /// Get a `javascriptcore.Value` referencing the JavaScript value of `weak_value`.
    extern fn jsc_weak_value_get_value(p_weak_value: *WeakValue) *javascriptcore.Value;
    pub const getValue = jsc_weak_value_get_value;

    extern fn jsc_weak_value_get_type() usize;
    pub const getGObjectType = jsc_weak_value_get_type;

    extern fn g_object_ref(p_self: *javascriptcore.WeakValue) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *javascriptcore.WeakValue) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *WeakValue, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ClassClass = extern struct {
    pub const Instance = javascriptcore.Class_;

    f_parent_class: gobject.ObjectClass,

    pub fn as(p_instance: *ClassClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Virtual table for a JSCClass. This can be optionally used when registering a `javascriptcore.Class` in a `javascriptcore.Context`
/// to provide a custom implementation for the class. All virtual functions are optional and can be set to
/// `NULL` to fallback to the default implementation.
pub const ClassVTable = extern struct {
    /// a `javascriptcore.ClassGetPropertyFunction` for getting a property.
    f_get_property: ?javascriptcore.ClassGetPropertyFunction,
    /// a `javascriptcore.ClassSetPropertyFunction` for setting a property.
    f_set_property: ?javascriptcore.ClassSetPropertyFunction,
    /// a `javascriptcore.ClassHasPropertyFunction` for querying a property.
    f_has_property: ?javascriptcore.ClassHasPropertyFunction,
    /// a `javascriptcore.ClassDeletePropertyFunction` for deleting a property.
    f_delete_property: ?javascriptcore.ClassDeletePropertyFunction,
    /// a `javascriptcore.ClassEnumeratePropertiesFunction` for enumerating properties.
    f_enumerate_properties: ?javascriptcore.ClassEnumeratePropertiesFunction,
    f__jsc_reserved0: ?*const fn () callconv(.c) void,
    f__jsc_reserved1: ?*const fn () callconv(.c) void,
    f__jsc_reserved2: ?*const fn () callconv(.c) void,
    f__jsc_reserved3: ?*const fn () callconv(.c) void,
    f__jsc_reserved4: ?*const fn () callconv(.c) void,
    f__jsc_reserved5: ?*const fn () callconv(.c) void,
    f__jsc_reserved6: ?*const fn () callconv(.c) void,
    f__jsc_reserved7: ?*const fn () callconv(.c) void,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ContextClass = extern struct {
    pub const Instance = javascriptcore.Context;

    f_parent_class: gobject.ObjectClass,

    pub fn as(p_instance: *ContextClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ExceptionClass = extern struct {
    pub const Instance = javascriptcore.Exception;

    f_parent_class: gobject.ObjectClass,

    pub fn as(p_instance: *ExceptionClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ValueClass = extern struct {
    pub const Instance = javascriptcore.Value;

    f_parent_class: gobject.ObjectClass,

    pub fn as(p_instance: *ValueClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const VirtualMachineClass = extern struct {
    pub const Instance = javascriptcore.VirtualMachine;

    f_parent_class: gobject.ObjectClass,

    pub fn as(p_instance: *VirtualMachineClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const WeakValueClass = extern struct {
    pub const Instance = javascriptcore.WeakValue;

    f_parent_class: gobject.ObjectClass,

    pub fn as(p_instance: *WeakValueClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Enum values to specify a mode to check for syntax errors in `javascriptcore.Context.checkSyntax`.
pub const CheckSyntaxMode = enum(c_int) {
    script = 0,
    module = 1,
    _,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Enum values to specify the result of `javascriptcore.Context.checkSyntax`.
pub const CheckSyntaxResult = enum(c_int) {
    success = 0,
    recoverable_error = 1,
    irrecoverable_error = 2,
    unterminated_literal_error = 3,
    out_of_memory_error = 4,
    stack_overflow_error = 5,
    _,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Enum values for options types.
pub const OptionType = enum(c_int) {
    boolean = 0,
    int = 1,
    uint = 2,
    size = 3,
    double = 4,
    string = 5,
    range_string = 6,
    _,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Possible types of the elements contained in a typed array.
pub const TypedArrayType = enum(c_int) {
    none = 0,
    int8 = 1,
    int16 = 2,
    int32 = 3,
    int64 = 4,
    uint8 = 5,
    uint8_clamped = 6,
    uint16 = 7,
    uint32 = 8,
    uint64 = 9,
    float32 = 10,
    float64 = 11,
    _,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags used when defining properties with `javascriptcore.Value.objectDefinePropertyData` and
/// `javascriptcore.Value.objectDefinePropertyAccessor`.
pub const ValuePropertyFlags = packed struct(c_uint) {
    configurable: bool = false,
    enumerable: bool = false,
    writable: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_configurable: ValuePropertyFlags = @bitCast(@as(c_uint, 1));
    pub const flags_enumerable: ValuePropertyFlags = @bitCast(@as(c_uint, 2));
    pub const flags_writable: ValuePropertyFlags = @bitCast(@as(c_uint, 4));

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Returns the major version number of the JavaScriptCore library.
/// (e.g. in JavaScriptCore version 1.8.3 this is 1.)
///
/// This function is in the library, so it represents the JavaScriptCore library
/// your code is running against. Contrast with the `JSC_MAJOR_VERSION`
/// macro, which represents the major version of the JavaScriptCore headers you
/// have included when compiling your code.
extern fn jsc_get_major_version() c_uint;
pub const getMajorVersion = jsc_get_major_version;

/// Returns the micro version number of the JavaScriptCore library.
/// (e.g. in JavaScriptCore version 1.8.3 this is 3.)
///
/// This function is in the library, so it represents the JavaScriptCore library
/// your code is running against. Contrast with the `JSC_MICRO_VERSION`
/// macro, which represents the micro version of the JavaScriptCore headers you
/// have included when compiling your code.
extern fn jsc_get_micro_version() c_uint;
pub const getMicroVersion = jsc_get_micro_version;

/// Returns the minor version number of the JavaScriptCore library.
/// (e.g. in JavaScriptCore version 1.8.3 this is 8.)
///
/// This function is in the library, so it represents the JavaScriptCore library
/// your code is running against. Contrast with the `JSC_MINOR_VERSION`
/// macro, which represents the minor version of the JavaScriptCore headers you
/// have included when compiling your code.
extern fn jsc_get_minor_version() c_uint;
pub const getMinorVersion = jsc_get_minor_version;

/// Iterates all available options calling `function` for each one. Iteration can
/// stop early if `function` returns `FALSE`.
extern fn jsc_options_foreach(p_function: javascriptcore.OptionsFunc, p_user_data: ?*anyopaque) void;
pub const optionsForeach = jsc_options_foreach;

/// Get `option` as a `gboolean` value.
extern fn jsc_options_get_boolean(p_option: [*:0]const u8, p_value: *c_int) c_int;
pub const optionsGetBoolean = jsc_options_get_boolean;

/// Get `option` as a `gdouble` value.
extern fn jsc_options_get_double(p_option: [*:0]const u8, p_value: *f64) c_int;
pub const optionsGetDouble = jsc_options_get_double;

/// Get `option` as a `gint` value.
extern fn jsc_options_get_int(p_option: [*:0]const u8, p_value: *c_int) c_int;
pub const optionsGetInt = jsc_options_get_int;

/// Create a `glib.OptionGroup` to handle JSCOptions as command line arguments.
/// The options will be exposed as command line arguments with the form
/// <emphasis>--jsc-&lt;option&gt;=&lt;value&gt;</emphasis>.
/// Each entry in the returned `glib.OptionGroup` is configured to apply the
/// corresponding option during command line parsing. Applications only need to
/// pass the returned group to `glib.OptionContext.addGroup`, and the rest will
/// be taken care for automatically.
extern fn jsc_options_get_option_group() *glib.OptionGroup;
pub const optionsGetOptionGroup = jsc_options_get_option_group;

/// Get `option` as a range string. The string must be in the
/// format <emphasis>[!]&lt;low&gt;[:&lt;high&gt;]</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.
extern fn jsc_options_get_range_string(p_option: [*:0]const u8, p_value: *[*:0]u8) c_int;
pub const optionsGetRangeString = jsc_options_get_range_string;

/// Get `option` as a `gsize` value.
extern fn jsc_options_get_size(p_option: [*:0]const u8, p_value: *usize) c_int;
pub const optionsGetSize = jsc_options_get_size;

/// Get `option` as a string.
extern fn jsc_options_get_string(p_option: [*:0]const u8, p_value: *[*:0]u8) c_int;
pub const optionsGetString = jsc_options_get_string;

/// Get `option` as a `guint` value.
extern fn jsc_options_get_uint(p_option: [*:0]const u8, p_value: *c_uint) c_int;
pub const optionsGetUint = jsc_options_get_uint;

/// Set `option` as a `gboolean` value.
extern fn jsc_options_set_boolean(p_option: [*:0]const u8, p_value: c_int) c_int;
pub const optionsSetBoolean = jsc_options_set_boolean;

/// Set `option` as a `gdouble` value.
extern fn jsc_options_set_double(p_option: [*:0]const u8, p_value: f64) c_int;
pub const optionsSetDouble = jsc_options_set_double;

/// Set `option` as a `gint` value.
extern fn jsc_options_set_int(p_option: [*:0]const u8, p_value: c_int) c_int;
pub const optionsSetInt = jsc_options_set_int;

/// Set `option` as a range string. The string must be in the
/// format <emphasis>[!]&lt;low&gt;[:&lt;high&gt;]</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.
extern fn jsc_options_set_range_string(p_option: [*:0]const u8, p_value: [*:0]const u8) c_int;
pub const optionsSetRangeString = jsc_options_set_range_string;

/// Set `option` as a `gsize` value.
extern fn jsc_options_set_size(p_option: [*:0]const u8, p_value: usize) c_int;
pub const optionsSetSize = jsc_options_set_size;

/// Set `option` as a string.
extern fn jsc_options_set_string(p_option: [*:0]const u8, p_value: [*:0]const u8) c_int;
pub const optionsSetString = jsc_options_set_string;

/// Set `option` as a `guint` value.
extern fn jsc_options_set_uint(p_option: [*:0]const u8, p_value: c_uint) c_int;
pub const optionsSetUint = jsc_options_set_uint;

/// The type of delete_property in `javascriptcore.ClassVTable`. This is only required when you need to handle
/// external properties not added to the prototype.
pub const ClassDeletePropertyFunction = *const fn (p_jsc_class: *javascriptcore.Class_, p_context: *javascriptcore.Context, p_instance: ?*anyopaque, p_name: [*:0]const u8) callconv(.c) c_int;

/// The type of enumerate_properties in `javascriptcore.ClassVTable`. This is only required when you need to handle
/// external properties not added to the prototype.
pub const ClassEnumeratePropertiesFunction = *const fn (p_jsc_class: *javascriptcore.Class_, p_context: *javascriptcore.Context, p_instance: ?*anyopaque) callconv(.c) ?[*][*:0]u8;

/// The type of get_property in `javascriptcore.ClassVTable`. This is only required when you need to handle
/// external properties not added to the prototype.
pub const ClassGetPropertyFunction = *const fn (p_jsc_class: *javascriptcore.Class_, p_context: *javascriptcore.Context, p_instance: ?*anyopaque, p_name: [*:0]const u8) callconv(.c) ?*javascriptcore.Value;

/// The type of has_property in `javascriptcore.ClassVTable`. This is only required when you need to handle
/// external properties not added to the prototype.
pub const ClassHasPropertyFunction = *const fn (p_jsc_class: *javascriptcore.Class_, p_context: *javascriptcore.Context, p_instance: ?*anyopaque, p_name: [*:0]const u8) callconv(.c) c_int;

/// The type of set_property in `javascriptcore.ClassVTable`. This is only required when you need to handle
/// external properties not added to the prototype.
pub const ClassSetPropertyFunction = *const fn (p_jsc_class: *javascriptcore.Class_, p_context: *javascriptcore.Context, p_instance: ?*anyopaque, p_name: [*:0]const u8, p_value: *javascriptcore.Value) callconv(.c) c_int;

/// Function used to handle JavaScript exceptions in a `javascriptcore.Context`.
pub const ExceptionHandler = *const fn (p_context: *javascriptcore.Context, p_exception: *javascriptcore.Exception, p_user_data: ?*anyopaque) callconv(.c) void;

/// A function passed to `jsc_value_new_promise` called during initialization
///
/// It is called like a JavaScript function, so exceptions raised will not be propagated
/// to the context, but handled by the promise causing a rejection.
/// `resolve` and `reject` can be reffed for later use to handle async task completion.
pub const Executor = *const fn (p_resolve: *javascriptcore.Value, p_reject: *javascriptcore.Value, p_user_data: ?*anyopaque) callconv(.c) void;

/// Function used to iterate options.
///
/// Not that `description` string is not localized.
pub const OptionsFunc = *const fn (p_option: [*:0]const u8, p_type: javascriptcore.OptionType, p_description: ?[*:0]const u8, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// Like `javascriptcore.getMajorVersion`, but from the headers used at
/// application compile time, rather than from the library linked
/// against at application run time.
pub const MAJOR_VERSION = 2;
/// Like `javascriptcore.getMicroVersion`, but from the headers used at
/// application compile time, rather than from the library linked
/// against at application run time.
pub const MICRO_VERSION = 5;
/// Like `javascriptcore.getMinorVersion`, but from the headers used at
/// application compile time, rather than from the library linked
/// against at application run time.
pub const MINOR_VERSION = 52;
/// Allows the DFG JIT to be used if `TRUE`.
/// Option type: `JSC_OPTION_BOOLEAN`
/// Default value: `TRUE`.
pub const OPTIONS_USE_DFG = "useDFGJIT";
/// Allows the FTL JIT to be used if `TRUE`.
/// Option type: `JSC_OPTION_BOOLEAN`
/// Default value: `TRUE`.
pub const OPTIONS_USE_FTL = "useFTLJIT";
/// Allows the executable pages to be allocated for JIT and thunks if `TRUE`.
/// Option type: `JSC_OPTION_BOOLEAN`
/// Default value: `TRUE`.
pub const OPTIONS_USE_JIT = "useJIT";
/// Allows the LLINT to be used if `TRUE`.
/// Option type: `JSC_OPTION_BOOLEAN`
/// Default value: `TRUE`.
pub const OPTIONS_USE_LLINT = "useLLInt";

test {
    @setEvalBranchQuota(100_000);
    std.testing.refAllDecls(@This());
    std.testing.refAllDecls(ext);
}
