/*
    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"

#if ENABLE(SUBTLE_CRYPTO)

#include "JSWebKitSubtleCrypto.h"

#include "JSDOMBinding.h"
#include "JSDOMPromise.h"
#include <runtime/Error.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionEncrypt(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionDecrypt(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionSign(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionVerify(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionDigest(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionGenerateKey(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionImportKey(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionExportKey(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionWrapKey(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionUnwrapKey(JSC::ExecState*);

class JSWebKitSubtleCryptoPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSWebKitSubtleCryptoPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSWebKitSubtleCryptoPrototype* ptr = new (NotNull, JSC::allocateCell<JSWebKitSubtleCryptoPrototype>(vm.heap)) JSWebKitSubtleCryptoPrototype(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:
    JSWebKitSubtleCryptoPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

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

/* Hash table for prototype */

static const HashTableValue JSWebKitSubtleCryptoPrototypeTableValues[] =
{
    { "encrypt", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionEncrypt), (intptr_t) (3) } },
    { "decrypt", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionDecrypt), (intptr_t) (3) } },
    { "sign", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionSign), (intptr_t) (3) } },
    { "verify", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionVerify), (intptr_t) (4) } },
    { "digest", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionDigest), (intptr_t) (2) } },
    { "generateKey", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionGenerateKey), (intptr_t) (1) } },
    { "importKey", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionImportKey), (intptr_t) (3) } },
    { "exportKey", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionExportKey), (intptr_t) (2) } },
    { "wrapKey", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionWrapKey), (intptr_t) (4) } },
    { "unwrapKey", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsWebKitSubtleCryptoPrototypeFunctionUnwrapKey), (intptr_t) (5) } },
};

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

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

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

JSWebKitSubtleCrypto::JSWebKitSubtleCrypto(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WebKitSubtleCrypto>&& impl)
    : JSDOMWrapper<WebKitSubtleCrypto>(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSWebKitSubtleCrypto::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSWebKitSubtleCryptoPrototype::create(vm, globalObject, JSWebKitSubtleCryptoPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
}

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

void JSWebKitSubtleCrypto::destroy(JSC::JSCell* cell)
{
    JSWebKitSubtleCrypto* thisObject = static_cast<JSWebKitSubtleCrypto*>(cell);
    thisObject->JSWebKitSubtleCrypto::~JSWebKitSubtleCrypto();
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionEncrypt(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "encrypt"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->encrypt(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionDecrypt(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "decrypt"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->decrypt(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionSign(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "sign"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->sign(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionVerify(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "verify"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->verify(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionDigest(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "digest"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->digest(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionGenerateKey(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "generateKey"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->generateKey(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionImportKey(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "importKey"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->importKey(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionExportKey(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "exportKey"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->exportKey(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionWrapKey(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "wrapKey"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->wrapKey(*state));
}

EncodedJSValue JSC_HOST_CALL jsWebKitSubtleCryptoPrototypeFunctionUnwrapKey(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSWebKitSubtleCrypto*>(thisValue);
    if (UNLIKELY(!castedThis))
        return createRejectedPromiseWithTypeError(*state, makeThisTypeErrorMessage("WebKitSubtleCrypto", "unwrapKey"));
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSWebKitSubtleCrypto::info());
    return JSValue::encode(castedThis->unwrapKey(*state));
}

bool JSWebKitSubtleCryptoOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    auto* jsWebKitSubtleCrypto = jsCast<JSWebKitSubtleCrypto*>(handle.slot()->asCell());
    Document* root = WTF::getPtr(jsWebKitSubtleCrypto->wrapped().document());
    if (!root)
        return false;
    return visitor.containsOpaqueRoot(root);
}

void JSWebKitSubtleCryptoOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
    auto* jsWebKitSubtleCrypto = jsCast<JSWebKitSubtleCrypto*>(handle.slot()->asCell());
    auto& world = *static_cast<DOMWrapperWorld*>(context);
    uncacheWrapper(world, &jsWebKitSubtleCrypto->wrapped(), jsWebKitSubtleCrypto);
}

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

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

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

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

WebKitSubtleCrypto* JSWebKitSubtleCrypto::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSWebKitSubtleCrypto*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}

#endif // ENABLE(SUBTLE_CRYPTO)
