/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    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 "JSInternalSettings.h"

#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConvert.h"
#include "URL.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTouchEventEmulationEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetStandardFontFamily(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetSerifFontFamily(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetSansSerifFontFamily(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetFixedFontFamily(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetCursiveFontFamily(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetFantasyFontFamily(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetPictographFontFamily(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetFontFallbackPrefersPictographs(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetWebFontsAlwaysFallBack(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTextAutosizingEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTextAutosizingWindowSizeOverride(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetCanStartMedia(JSC::ExecState*);
#if ENABLE(VIDEO_TRACK)
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetShouldDisplayTrackKind(JSC::ExecState*);
#endif
#if ENABLE(VIDEO_TRACK)
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionShouldDisplayTrackKind(JSC::ExecState*);
#endif
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetDefaultVideoPosterURL(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTimeWithoutMouseMovementBeforeHidingControls(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetMediaTypeOverride(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAllowsAirPlayForMediaPlayback(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetForcePendingWebGLPolicy(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetQuickTimePluginReplacementEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetYouTubeFlashPluginReplacementEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetEditingBehavior(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetShouldConvertPositionStyleOnCopy(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetLangAttributeAwareFormControlUIEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetPreferMIMETypeForImages(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetStorageBlockingPolicy(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetImagesEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetPDFImageCachingPolicy(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetUseLegacyBackgroundSizeShorthandBehavior(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAutoscrollForDragAndDropEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetBackgroundShouldExtendBeyondPage(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetScrollingTreeIncludesFrames(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetMinimumTimerInterval(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAllowsInlineMediaPlayback(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAllowsInlineMediaPlaybackAfterFullscreen(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetInlineMediaPlaybackRequiresPlaysInlineAttribute(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetIndexedDBWorkersEnabled(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionUserInterfaceDirectionPolicy(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetUserInterfaceDirectionPolicy(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSystemLayoutDirection(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetSystemLayoutDirection(JSC::ExecState*);

class JSInternalSettingsPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSInternalSettingsPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSInternalSettingsPrototype* ptr = new (NotNull, JSC::allocateCell<JSInternalSettingsPrototype>(vm.heap)) JSInternalSettingsPrototype(vm, globalObject, structure);
        ptr->finishCreation(vm);
        return ptr;
    }

    DECLARE_INFO;
    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

private:
    JSInternalSettingsPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

    void finishCreation(JSC::VM&);
};

/* Hash table for prototype */

static const HashTableValue JSInternalSettingsPrototypeTableValues[] =
{
    { "setTouchEventEmulationEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetTouchEventEmulationEnabled), (intptr_t) (1) } },
    { "setStandardFontFamily", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetStandardFontFamily), (intptr_t) (2) } },
    { "setSerifFontFamily", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetSerifFontFamily), (intptr_t) (2) } },
    { "setSansSerifFontFamily", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetSansSerifFontFamily), (intptr_t) (2) } },
    { "setFixedFontFamily", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetFixedFontFamily), (intptr_t) (2) } },
    { "setCursiveFontFamily", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetCursiveFontFamily), (intptr_t) (2) } },
    { "setFantasyFontFamily", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetFantasyFontFamily), (intptr_t) (2) } },
    { "setPictographFontFamily", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetPictographFontFamily), (intptr_t) (2) } },
    { "setFontFallbackPrefersPictographs", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetFontFallbackPrefersPictographs), (intptr_t) (1) } },
    { "setWebFontsAlwaysFallBack", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetWebFontsAlwaysFallBack), (intptr_t) (1) } },
    { "setTextAutosizingEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetTextAutosizingEnabled), (intptr_t) (1) } },
    { "setTextAutosizingWindowSizeOverride", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetTextAutosizingWindowSizeOverride), (intptr_t) (2) } },
    { "setCanStartMedia", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetCanStartMedia), (intptr_t) (1) } },
#if ENABLE(VIDEO_TRACK)
    { "setShouldDisplayTrackKind", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetShouldDisplayTrackKind), (intptr_t) (2) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
#if ENABLE(VIDEO_TRACK)
    { "shouldDisplayTrackKind", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionShouldDisplayTrackKind), (intptr_t) (1) } },
#else
    { 0, 0, NoIntrinsic, { 0, 0 } },
#endif
    { "setDefaultVideoPosterURL", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetDefaultVideoPosterURL), (intptr_t) (1) } },
    { "setTimeWithoutMouseMovementBeforeHidingControls", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetTimeWithoutMouseMovementBeforeHidingControls), (intptr_t) (1) } },
    { "setMediaTypeOverride", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetMediaTypeOverride), (intptr_t) (1) } },
    { "setAllowsAirPlayForMediaPlayback", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetAllowsAirPlayForMediaPlayback), (intptr_t) (1) } },
    { "setForcePendingWebGLPolicy", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetForcePendingWebGLPolicy), (intptr_t) (1) } },
    { "setQuickTimePluginReplacementEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetQuickTimePluginReplacementEnabled), (intptr_t) (1) } },
    { "setYouTubeFlashPluginReplacementEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetYouTubeFlashPluginReplacementEnabled), (intptr_t) (1) } },
    { "setEditingBehavior", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetEditingBehavior), (intptr_t) (1) } },
    { "setShouldConvertPositionStyleOnCopy", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetShouldConvertPositionStyleOnCopy), (intptr_t) (1) } },
    { "setLangAttributeAwareFormControlUIEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetLangAttributeAwareFormControlUIEnabled), (intptr_t) (1) } },
    { "setPreferMIMETypeForImages", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetPreferMIMETypeForImages), (intptr_t) (1) } },
    { "setStorageBlockingPolicy", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetStorageBlockingPolicy), (intptr_t) (1) } },
    { "setImagesEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetImagesEnabled), (intptr_t) (1) } },
    { "setPDFImageCachingPolicy", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetPDFImageCachingPolicy), (intptr_t) (1) } },
    { "setUseLegacyBackgroundSizeShorthandBehavior", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetUseLegacyBackgroundSizeShorthandBehavior), (intptr_t) (1) } },
    { "setAutoscrollForDragAndDropEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetAutoscrollForDragAndDropEnabled), (intptr_t) (1) } },
    { "setBackgroundShouldExtendBeyondPage", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetBackgroundShouldExtendBeyondPage), (intptr_t) (1) } },
    { "setScrollingTreeIncludesFrames", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetScrollingTreeIncludesFrames), (intptr_t) (1) } },
    { "setMinimumTimerInterval", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetMinimumTimerInterval), (intptr_t) (1) } },
    { "setAllowsInlineMediaPlayback", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetAllowsInlineMediaPlayback), (intptr_t) (1) } },
    { "setAllowsInlineMediaPlaybackAfterFullscreen", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetAllowsInlineMediaPlaybackAfterFullscreen), (intptr_t) (1) } },
    { "setInlineMediaPlaybackRequiresPlaysInlineAttribute", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetInlineMediaPlaybackRequiresPlaysInlineAttribute), (intptr_t) (1) } },
    { "setIndexedDBWorkersEnabled", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetIndexedDBWorkersEnabled), (intptr_t) (1) } },
    { "userInterfaceDirectionPolicy", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionUserInterfaceDirectionPolicy), (intptr_t) (0) } },
    { "setUserInterfaceDirectionPolicy", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetUserInterfaceDirectionPolicy), (intptr_t) (1) } },
    { "systemLayoutDirection", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSystemLayoutDirection), (intptr_t) (0) } },
    { "setSystemLayoutDirection", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsInternalSettingsPrototypeFunctionSetSystemLayoutDirection), (intptr_t) (1) } },
};

const ClassInfo JSInternalSettingsPrototype::s_info = { "InternalSettingsPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSInternalSettingsPrototype) };

void JSInternalSettingsPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSInternalSettingsPrototypeTableValues, *this);
}

const ClassInfo JSInternalSettings::s_info = { "InternalSettings", &Base::s_info, 0, CREATE_METHOD_TABLE(JSInternalSettings) };

JSInternalSettings::JSInternalSettings(Structure* structure, JSDOMGlobalObject& globalObject, Ref<InternalSettings>&& impl)
    : JSInternalSettingsGenerated(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSInternalSettings::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSInternalSettingsPrototype::create(vm, globalObject, JSInternalSettingsPrototype::createStructure(vm, globalObject, JSInternalSettingsGenerated::prototype(vm, globalObject)));
}

JSObject* JSInternalSettings::prototype(VM& vm, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSInternalSettings>(vm, globalObject);
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTouchEventEmulationEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setTouchEventEmulationEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setTouchEventEmulationEnabled(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetStandardFontFamily(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setStandardFontFamily");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto family = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto script = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setStandardFontFamily(WTFMove(family), WTFMove(script), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetSerifFontFamily(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setSerifFontFamily");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto family = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto script = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setSerifFontFamily(WTFMove(family), WTFMove(script), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetSansSerifFontFamily(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setSansSerifFontFamily");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto family = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto script = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setSansSerifFontFamily(WTFMove(family), WTFMove(script), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetFixedFontFamily(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setFixedFontFamily");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto family = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto script = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setFixedFontFamily(WTFMove(family), WTFMove(script), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetCursiveFontFamily(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setCursiveFontFamily");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto family = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto script = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setCursiveFontFamily(WTFMove(family), WTFMove(script), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetFantasyFontFamily(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setFantasyFontFamily");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto family = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto script = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setFantasyFontFamily(WTFMove(family), WTFMove(script), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetPictographFontFamily(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setPictographFontFamily");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto family = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto script = state->uncheckedArgument(1).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setPictographFontFamily(WTFMove(family), WTFMove(script), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetFontFallbackPrefersPictographs(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setFontFallbackPrefersPictographs");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto preferPictographs = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setFontFallbackPrefersPictographs(WTFMove(preferPictographs), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetWebFontsAlwaysFallBack(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setWebFontsAlwaysFallBack");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enable = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setWebFontsAlwaysFallBack(WTFMove(enable), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTextAutosizingEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setTextAutosizingEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setTextAutosizingEnabled(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTextAutosizingWindowSizeOverride(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setTextAutosizingWindowSizeOverride");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto width = convert<int32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto height = convert<int32_t>(*state, state->uncheckedArgument(1), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setTextAutosizingWindowSizeOverride(WTFMove(width), WTFMove(height), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetCanStartMedia(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setCanStartMedia");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setCanStartMedia(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

#if ENABLE(VIDEO_TRACK)
EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetShouldDisplayTrackKind(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setShouldDisplayTrackKind");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto kind = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto enabled = state->uncheckedArgument(1).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setShouldDisplayTrackKind(WTFMove(kind), WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

#endif

#if ENABLE(VIDEO_TRACK)
EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionShouldDisplayTrackKind(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "shouldDisplayTrackKind");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto trackKind = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = jsBoolean(impl.shouldDisplayTrackKind(WTFMove(trackKind), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

#endif

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetDefaultVideoPosterURL(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setDefaultVideoPosterURL");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto poster = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setDefaultVideoPosterURL(WTFMove(poster), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetTimeWithoutMouseMovementBeforeHidingControls(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setTimeWithoutMouseMovementBeforeHidingControls");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto time = convert<double>(*state, state->uncheckedArgument(0), ShouldAllowNonFinite::Yes);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setTimeWithoutMouseMovementBeforeHidingControls(WTFMove(time), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetMediaTypeOverride(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setMediaTypeOverride");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto mediaTypeOverride = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setMediaTypeOverride(WTFMove(mediaTypeOverride), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAllowsAirPlayForMediaPlayback(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setAllowsAirPlayForMediaPlayback");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto available = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setAllowsAirPlayForMediaPlayback(WTFMove(available));
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetForcePendingWebGLPolicy(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setForcePendingWebGLPolicy");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto forced = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setForcePendingWebGLPolicy(WTFMove(forced), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetQuickTimePluginReplacementEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setQuickTimePluginReplacementEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setQuickTimePluginReplacementEnabled(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetYouTubeFlashPluginReplacementEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setYouTubeFlashPluginReplacementEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setYouTubeFlashPluginReplacementEnabled(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetEditingBehavior(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setEditingBehavior");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto behavior = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setEditingBehavior(WTFMove(behavior), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetShouldConvertPositionStyleOnCopy(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setShouldConvertPositionStyleOnCopy");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto convert = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setShouldConvertPositionStyleOnCopy(WTFMove(convert), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetLangAttributeAwareFormControlUIEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setLangAttributeAwareFormControlUIEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setLangAttributeAwareFormControlUIEnabled(WTFMove(enabled));
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetPreferMIMETypeForImages(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setPreferMIMETypeForImages");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto preferMimeTypeForImage = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setPreferMIMETypeForImages(WTFMove(preferMimeTypeForImage), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetStorageBlockingPolicy(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setStorageBlockingPolicy");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto policy = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setStorageBlockingPolicy(WTFMove(policy), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetImagesEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setImagesEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setImagesEnabled(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetPDFImageCachingPolicy(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setPDFImageCachingPolicy");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto policy = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setPDFImageCachingPolicy(WTFMove(policy), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetUseLegacyBackgroundSizeShorthandBehavior(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setUseLegacyBackgroundSizeShorthandBehavior");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setUseLegacyBackgroundSizeShorthandBehavior(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAutoscrollForDragAndDropEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setAutoscrollForDragAndDropEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setAutoscrollForDragAndDropEnabled(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetBackgroundShouldExtendBeyondPage(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setBackgroundShouldExtendBeyondPage");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto hasExtendedBackground = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setBackgroundShouldExtendBeyondPage(WTFMove(hasExtendedBackground), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetScrollingTreeIncludesFrames(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setScrollingTreeIncludesFrames");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto enabled = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setScrollingTreeIncludesFrames(WTFMove(enabled), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetMinimumTimerInterval(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setMinimumTimerInterval");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto intervalInSeconds = convert<double>(*state, state->uncheckedArgument(0), ShouldAllowNonFinite::Yes);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setMinimumTimerInterval(WTFMove(intervalInSeconds), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAllowsInlineMediaPlayback(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setAllowsInlineMediaPlayback");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto allows = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setAllowsInlineMediaPlayback(WTFMove(allows), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetAllowsInlineMediaPlaybackAfterFullscreen(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setAllowsInlineMediaPlaybackAfterFullscreen");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto allows = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setAllowsInlineMediaPlaybackAfterFullscreen(WTFMove(allows), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetInlineMediaPlaybackRequiresPlaysInlineAttribute(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setInlineMediaPlaybackRequiresPlaysInlineAttribute");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto requires = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setInlineMediaPlaybackRequiresPlaysInlineAttribute(WTFMove(requires), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetIndexedDBWorkersEnabled(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setIndexedDBWorkersEnabled");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto requires = state->uncheckedArgument(0).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setIndexedDBWorkersEnabled(WTFMove(requires), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionUserInterfaceDirectionPolicy(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "userInterfaceDirectionPolicy");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    JSValue result = jsStringWithCache(state, impl.userInterfaceDirectionPolicy(ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetUserInterfaceDirectionPolicy(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setUserInterfaceDirectionPolicy");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto policy = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setUserInterfaceDirectionPolicy(WTFMove(policy), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSystemLayoutDirection(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "systemLayoutDirection");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    JSValue result = jsStringWithCache(state, impl.systemLayoutDirection(ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsInternalSettingsPrototypeFunctionSetSystemLayoutDirection(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSInternalSettings*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "InternalSettings", "setSystemLayoutDirection");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSInternalSettings::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    auto direction = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.setSystemLayoutDirection(WTFMove(direction), ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7InternalSettings@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore16InternalSettingsE[]; }
#endif
#endif

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<InternalSettings>&& impl)
{

#if ENABLE(BINDING_INTEGRITY)
    void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
#if PLATFORM(WIN)
    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7InternalSettings@WebCore@@6B@"));
#else
    void* expectedVTablePointer = &_ZTVN7WebCore16InternalSettingsE[2];
#if COMPILER(CLANG)
    // If this fails InternalSettings does not have a vtable, so you need to add the
    // ImplementationLacksVTable attribute to the interface definition
    static_assert(__is_polymorphic(InternalSettings), "InternalSettings is not polymorphic");
#endif
#endif
    // If you hit this assertion you either have a use after free bug, or
    // InternalSettings has subclasses. If InternalSettings has subclasses that get passed
    // to toJS() we currently require InternalSettings you to opt out of binding hardening
    // by adding the SkipVTableValidation attribute to the interface IDL definition
    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
    return createWrapper<InternalSettings>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, InternalSettings& impl)
{
    return wrap(state, globalObject, impl);
}


}
