/*
 * Copyright (C) 2018 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "JSCContext.h"

#include "APICast.h"
#include "IntegrityInlines.h"
#include "JSCClassPrivate.h"
#include "JSCContextInternal.h"
#include "JSCContextPrivate.h"
#include "JSCExceptionPrivate.h"
#include "JSCInlines.h"
#include "JSCValuePrivate.h"
#include "JSCVirtualMachinePrivate.h"
#include "JSCWrapperMap.h"
#include "JSRetainPtr.h"
#include "JSWithScope.h"
#include "OpaqueJSString.h"
#include "Parser.h"
#include <wtf/glib/GUniquePtr.h>
#include <wtf/glib/WTFGType.h>

/**
 * JSCContext:
 * @short_description: JavaScript execution context
 * @title: JSCContext
 *
 * 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 jsc_context_evaluate() or jsc_context_evaluate_with_source_uri().
 * It's also possible to register custom objects in the context with jsc_context_register_class().
 */

enum {
    PROP_0,

    PROP_VIRTUAL_MACHINE,
};

struct JSCContextExceptionHandler {
    JSCContextExceptionHandler(JSCExceptionHandler handler, void* userData = nullptr, GDestroyNotify destroyNotifyFunction = nullptr)
        : handler(handler)
        , userData(userData)
        , destroyNotifyFunction(destroyNotifyFunction)
    {
    }

    ~JSCContextExceptionHandler()
    {
        if (destroyNotifyFunction)
            destroyNotifyFunction(userData);
    }

    JSCContextExceptionHandler(JSCContextExceptionHandler&& other)
    {
        std::swap(handler, other.handler);
        std::swap(userData, other.userData);
        std::swap(destroyNotifyFunction, other.destroyNotifyFunction);
    }

    JSCContextExceptionHandler(const JSCContextExceptionHandler&) = delete;
    JSCContextExceptionHandler& operator=(const JSCContextExceptionHandler&) = delete;

    JSCExceptionHandler handler { nullptr };
    void* userData { nullptr };
    GDestroyNotify destroyNotifyFunction { nullptr };
};

struct _JSCContextPrivate {
    GRefPtr<JSCVirtualMachine> vm;
    JSRetainPtr<JSGlobalContextRef> jsContext;
    GRefPtr<JSCException> exception;
    Vector<JSCContextExceptionHandler> exceptionHandlers;
};

WEBKIT_DEFINE_TYPE(JSCContext, jsc_context, G_TYPE_OBJECT)

static void jscContextSetVirtualMachine(JSCContext* context, GRefPtr<JSCVirtualMachine>&& vm)
{
    JSCContextPrivate* priv = context->priv;
    if (vm) {
        ASSERT(!priv->vm);
        priv->vm = WTFMove(vm);
        ASSERT(!priv->jsContext);
        GUniquePtr<char> name(g_strdup_printf("%p-jsContext", &Thread::current()));
        if (auto* data = g_object_get_data(G_OBJECT(priv->vm.get()), name.get())) {
            priv->jsContext = static_cast<JSGlobalContextRef>(data);
            g_object_set_data(G_OBJECT(priv->vm.get()), name.get(), nullptr);
        } else
            priv->jsContext = JSRetainPtr<JSGlobalContextRef>(Adopt, JSGlobalContextCreateInGroup(jscVirtualMachineGetContextGroup(priv->vm.get()), nullptr));
        auto* globalObject = toJSGlobalObject(priv->jsContext.get());
        if (!globalObject->wrapperMap())
            globalObject->setWrapperMap(makeUnique<JSC::WrapperMap>(priv->jsContext.get()));
        jscVirtualMachineAddContext(priv->vm.get(), context);
    } else if (priv->vm) {
        ASSERT(priv->jsContext);
        jscVirtualMachineRemoveContext(priv->vm.get(), context);
        priv->jsContext = nullptr;
        priv->vm = nullptr;
    }
}

static void jscContextGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec)
{
    JSCContextPrivate* priv = JSC_CONTEXT(object)->priv;

    switch (propID) {
    case PROP_VIRTUAL_MACHINE:
        g_value_set_object(value, priv->vm.get());
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
    }
}

static void jscContextSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec)
{
    JSCContext* context = JSC_CONTEXT(object);

    switch (propID) {
    case PROP_VIRTUAL_MACHINE:
        if (gpointer vm = g_value_get_object(value))
            jscContextSetVirtualMachine(context, GRefPtr<JSCVirtualMachine>(JSC_VIRTUAL_MACHINE(vm)));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
    }
}

static void jscContextConstructed(GObject* object)
{
    G_OBJECT_CLASS(jsc_context_parent_class)->constructed(object);

    JSCContext* context = JSC_CONTEXT(object);
    if (!context->priv->vm)
        jscContextSetVirtualMachine(context, adoptGRef(jsc_virtual_machine_new()));

    context->priv->exceptionHandlers.append(JSCContextExceptionHandler([](JSCContext* context, JSCException* exception, gpointer) {
        jsc_context_throw_exception(context, exception);
    }));
}

static void jscContextDispose(GObject* object)
{
    JSCContext* context = JSC_CONTEXT(object);
    jscContextSetVirtualMachine(context, nullptr);

    G_OBJECT_CLASS(jsc_context_parent_class)->dispose(object);
}

static void jsc_context_class_init(JSCContextClass* klass)
{
    GObjectClass* objClass = G_OBJECT_CLASS(klass);
    objClass->get_property = jscContextGetProperty;
    objClass->set_property = jscContextSetProperty;
    objClass->constructed = jscContextConstructed;
    objClass->dispose = jscContextDispose;

    /**
     * JSCContext:virtual-machine:
     *
     * The #JSCVirtualMachine in which the context was created.
     */
    g_object_class_install_property(objClass,
        PROP_VIRTUAL_MACHINE,
        g_param_spec_object(
            "virtual-machine",
            "JSCVirtualMachine",
            "JSC Virtual Machine",
            JSC_TYPE_VIRTUAL_MACHINE,
            static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
}

GRefPtr<JSCContext> jscContextGetOrCreate(JSGlobalContextRef jsContext)
{
    auto vm = jscVirtualMachineGetOrCreate(toRef(&toJS(jsContext)->vm()));
    if (GRefPtr<JSCContext> context = jscVirtualMachineGetContext(vm.get(), jsContext))
        return context;

    GUniquePtr<char> name(g_strdup_printf("%p-jsContext", &Thread::current()));
    g_object_set_data(G_OBJECT(vm.get()), name.get(), jsContext);
    return adoptGRef(jsc_context_new_with_virtual_machine(vm.get()));
}

JSGlobalContextRef jscContextGetJSContext(JSCContext* context)
{
    ASSERT(JSC_IS_CONTEXT(context));

    JSCContextPrivate* priv = context->priv;
    return priv->jsContext.get();
}

static JSC::WrapperMap& wrapperMap(JSCContext* context)
{
    auto* map = toJSGlobalObject(context->priv->jsContext.get())->wrapperMap();
    ASSERT(map);
    return *map;
}

GRefPtr<JSCValue> jscContextGetOrCreateValue(JSCContext* context, JSValueRef jsValue)
{
    return wrapperMap(context).gobjectWrapper(context, jsValue);
}

void jscContextValueDestroyed(JSCContext* context, JSValueRef jsValue)
{
    wrapperMap(context).unwrap(jsValue);
}

JSC::JSObject* jscContextGetJSWrapper(JSCContext* context, gpointer wrappedObject)
{
    return wrapperMap(context).jsWrapper(wrappedObject);
}

JSC::JSObject* jscContextGetOrCreateJSWrapper(JSCContext* context, JSClassRef jsClass, JSValueRef prototype, gpointer wrappedObject, GDestroyNotify destroyFunction)
{
    if (auto* jsWrapper = jscContextGetJSWrapper(context, wrappedObject))
        return jsWrapper;

    return wrapperMap(context).createJSWrapper(context->priv->jsContext.get(), jsClass, prototype, wrappedObject, destroyFunction);
}

JSGlobalContextRef jscContextCreateContextWithJSWrapper(JSCContext* context, JSClassRef jsClass, JSValueRef prototype, gpointer wrappedObject, GDestroyNotify destroyFunction)
{
    return wrapperMap(context).createContextWithJSWrapper(jscVirtualMachineGetContextGroup(context->priv->vm.get()), jsClass, prototype, wrappedObject, destroyFunction);
}

gpointer jscContextWrappedObject(JSCContext* context, JSObjectRef jsObject)
{
    return wrapperMap(context).wrappedObject(context->priv->jsContext.get(), jsObject);
}

JSCClass* jscContextGetRegisteredClass(JSCContext* context, JSClassRef jsClass)
{
    return wrapperMap(context).registeredClass(jsClass);
}

CallbackData jscContextPushCallback(JSCContext* context, JSValueRef calleeValue, JSValueRef thisValue, size_t argumentCount, const JSValueRef* arguments)
{
    Thread& thread = Thread::current();
    auto* previousStack = static_cast<CallbackData*>(thread.m_apiData);
    CallbackData data = { context, WTFMove(context->priv->exception), calleeValue, thisValue, argumentCount, arguments, previousStack };
    thread.m_apiData = &data;
    return data;
}

void jscContextPopCallback(JSCContext* context, CallbackData&& data)
{
    Thread& thread = Thread::current();
    context->priv->exception = WTFMove(data.preservedException);
    thread.m_apiData = data.next;
}

JSValueRef jscContextGArrayToJSArray(JSCContext* context, GPtrArray* gArray, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    JSC::JSGlobalObject* globalObject = toJS(priv->jsContext.get());
    JSC::JSLockHolder locker(globalObject);

    auto* jsArray = JSObjectMakeArray(priv->jsContext.get(), 0, nullptr, exception);
    if (*exception)
        return JSValueMakeUndefined(priv->jsContext.get());

    if (!gArray)
        return jsArray;

    auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
    if (*exception)
        return JSValueMakeUndefined(priv->jsContext.get());

    for (unsigned i = 0; i < gArray->len; ++i) {
        gpointer item = g_ptr_array_index(gArray, i);
        if (!item)
            JSObjectSetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, JSValueMakeNull(priv->jsContext.get()), exception);
        else if (JSC_IS_VALUE(item))
            JSObjectSetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, jscValueGetJSValue(JSC_VALUE(item)), exception);
        else
            *exception = toRef(JSC::createTypeError(globalObject, makeString("invalid item type in GPtrArray")));

        if (*exception)
            return JSValueMakeUndefined(priv->jsContext.get());
    }

    return jsArray;
}

static GRefPtr<GPtrArray> jscContextJSArrayToGArray(JSCContext* context, JSValueRef jsArray, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    JSC::JSGlobalObject* globalObject = toJS(priv->jsContext.get());
    JSC::JSLockHolder locker(globalObject);

    if (JSValueIsNull(priv->jsContext.get(), jsArray))
        return nullptr;

    if (!JSValueIsArray(priv->jsContext.get(), jsArray)) {
        *exception = toRef(JSC::createTypeError(globalObject, makeString("invalid js type for GPtrArray")));
        return nullptr;
    }

    auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
    if (*exception)
        return nullptr;

    JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
    auto* jsLength = JSObjectGetProperty(priv->jsContext.get(), jsArrayObject, lengthString.get(), exception);
    if (*exception)
        return nullptr;

    auto length = JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsLength, exception));
    if (*exception)
        return nullptr;

    GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_with_free_func(g_object_unref));
    for (unsigned i = 0; i < length; ++i) {
        auto* jsItem = JSObjectGetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, exception);
        if (*exception)
            return nullptr;

        g_ptr_array_add(gArray.get(), jsItem ? jscContextGetOrCreateValue(context, jsItem).leakRef() : nullptr);
    }

    return gArray;
}

GUniquePtr<char*> jscContextJSArrayToGStrv(JSCContext* context, JSValueRef jsArray, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    JSC::JSGlobalObject* globalObject = toJS(priv->jsContext.get());
    JSC::JSLockHolder locker(globalObject);

    if (JSValueIsNull(priv->jsContext.get(), jsArray))
        return nullptr;

    if (!JSValueIsArray(priv->jsContext.get(), jsArray)) {
        *exception = toRef(JSC::createTypeError(globalObject, makeString("invalid js type for GStrv")));
        return nullptr;
    }

    auto* jsArrayObject = JSValueToObject(priv->jsContext.get(), jsArray, exception);
    if (*exception)
        return nullptr;

    JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
    auto* jsLength = JSObjectGetProperty(priv->jsContext.get(), jsArrayObject, lengthString.get(), exception);
    if (*exception)
        return nullptr;

    auto length = JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsLength, exception));
    if (*exception)
        return nullptr;

    GUniquePtr<char*> strv(static_cast<char**>(g_new0(char*, length + 1)));
    for (unsigned i = 0; i < length; ++i) {
        auto* jsItem = JSObjectGetPropertyAtIndex(priv->jsContext.get(), jsArrayObject, i, exception);
        if (*exception)
            return nullptr;

        auto jsValueItem = jscContextGetOrCreateValue(context, jsItem);
        if (!jsc_value_is_string(jsValueItem.get())) {
            *exception = toRef(JSC::createTypeError(globalObject, makeString("invalid js type for GStrv: item ", String::number(i), " is not a string")));
            return nullptr;
        }

        strv.get()[i] = jsc_value_to_string(jsValueItem.get());
    }

    return strv;
}

JSValueRef jscContextGValueToJSValue(JSCContext* context, const GValue* value, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    JSC::JSGlobalObject* globalObject = toJS(priv->jsContext.get());
    JSC::JSLockHolder locker(globalObject);

    switch (g_type_fundamental(G_VALUE_TYPE(value))) {
    case G_TYPE_BOOLEAN:
        return JSValueMakeBoolean(priv->jsContext.get(), g_value_get_boolean(value));
    case G_TYPE_CHAR:
    case G_TYPE_INT:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_int);
    case G_TYPE_ENUM:
        return JSValueMakeNumber(priv->jsContext.get(), g_value_get_enum(value));
    case G_TYPE_FLAGS:
        return JSValueMakeNumber(priv->jsContext.get(), g_value_get_flags(value));
    case G_TYPE_UCHAR:
    case G_TYPE_UINT:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_uint);
    case G_TYPE_FLOAT:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_float);
    case G_TYPE_DOUBLE:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_double);
    case G_TYPE_LONG:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_long);
    case G_TYPE_ULONG:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_ulong);
    case G_TYPE_INT64:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_int64);
    case G_TYPE_UINT64:
        return JSValueMakeNumber(priv->jsContext.get(), value->data[0].v_uint64);
    case G_TYPE_STRING:
        if (const char* stringValue = g_value_get_string(value)) {
            JSRetainPtr<JSStringRef> jsString(Adopt, JSStringCreateWithUTF8CString(stringValue));
            return JSValueMakeString(priv->jsContext.get(), jsString.get());
        }
        return JSValueMakeNull(priv->jsContext.get());
    case G_TYPE_POINTER:
    case G_TYPE_OBJECT:
    case G_TYPE_BOXED:
        if (auto* ptr = value->data[0].v_pointer) {
            if (auto* jsWrapper = jscContextGetJSWrapper(context, ptr))
                return toRef(jsWrapper);

            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_VALUE))
                return jscValueGetJSValue(JSC_VALUE(ptr));

            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_EXCEPTION))
                return jscExceptionGetJSValue(JSC_EXCEPTION(ptr));

            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY))
                return jscContextGArrayToJSArray(context, static_cast<GPtrArray*>(ptr), exception);

            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
                auto** strv = static_cast<char**>(ptr);
                auto strvLength = g_strv_length(strv);
                GRefPtr<GPtrArray> gArray = adoptGRef(g_ptr_array_new_full(strvLength, g_object_unref));
                for (unsigned i = 0; i < strvLength; i++)
                    g_ptr_array_add(gArray.get(), jsc_value_new_string(context, strv[i]));
                return jscContextGArrayToJSArray(context, gArray.get(), exception);
            }
        } else
            return JSValueMakeNull(priv->jsContext.get());

        break;
    case G_TYPE_PARAM:
    case G_TYPE_INTERFACE:
    case G_TYPE_VARIANT:
    default:
        break;
    }

    *exception = toRef(JSC::createTypeError(globalObject, makeString("unsupported type ", g_type_name(G_VALUE_TYPE(value)))));
    return JSValueMakeUndefined(priv->jsContext.get());
}

static inline gpointer jscContextJSValueToWrappedObject(JSCContext* context, JSValueRef jsValue)
{
    auto jsObject = JSValueToObject(context->priv->jsContext.get(), jsValue, nullptr);
    return jsObject ? jscContextWrappedObject(context, jsObject) : nullptr;
}

void jscContextJSValueToGValue(JSCContext* context, JSValueRef jsValue, GType type, GValue* value, JSValueRef* exception)
{
    JSCContextPrivate* priv = context->priv;
    JSC::JSGlobalObject* globalObject = toJS(priv->jsContext.get());
    JSC::JSLockHolder locker(globalObject);

    g_value_init(value, type);
    auto fundamentalType = g_type_fundamental(G_VALUE_TYPE(value));
    switch (fundamentalType) {
    case G_TYPE_INT:
        g_value_set_int(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
        break;
    case G_TYPE_FLOAT:
        g_value_set_float(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_DOUBLE:
        g_value_set_double(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_BOOLEAN:
        g_value_set_boolean(value, JSValueToBoolean(priv->jsContext.get(), jsValue));
        break;
    case G_TYPE_STRING:
        if (!JSValueIsNull(priv->jsContext.get(), jsValue)) {
            JSRetainPtr<JSStringRef> jsString(Adopt, JSValueToStringCopy(priv->jsContext.get(), jsValue, exception));
            if (*exception)
                return;
            size_t maxSize = JSStringGetMaximumUTF8CStringSize(jsString.get());
            auto* string = static_cast<char*>(g_malloc(maxSize));
            JSStringGetUTF8CString(jsString.get(), string, maxSize);
            g_value_take_string(value, string);
        } else
            g_value_set_string(value, nullptr);
        break;
    case G_TYPE_CHAR:
        g_value_set_schar(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
        break;
    case G_TYPE_UCHAR:
        g_value_set_uchar(value, JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
        break;
    case G_TYPE_UINT:
        g_value_set_uint(value, JSC::toUInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
        break;
    case G_TYPE_POINTER:
    case G_TYPE_OBJECT:
    case G_TYPE_BOXED: {
        gpointer wrappedObject = jscContextJSValueToWrappedObject(context, jsValue);

        if (!wrappedObject) {
            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_VALUE)) {
                auto jscValue = jscContextGetOrCreateValue(context, jsValue);
                g_value_set_object(value, jscValue.get());
                return;
            }

            if (g_type_is_a(G_VALUE_TYPE(value), JSC_TYPE_EXCEPTION)) {
                auto exception = jscExceptionCreate(context, jsValue);
                g_value_set_object(value, exception.get());
                return;
            }

            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_PTR_ARRAY)) {
                auto gArray = jscContextJSArrayToGArray(context, jsValue, exception);
                if (!*exception)
                    g_value_take_boxed(value, gArray.leakRef());
                return;
            }

            if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_STRV)) {
                auto strv = jscContextJSArrayToGStrv(context, jsValue, exception);
                if (!*exception)
                    g_value_take_boxed(value, strv.release());
                return;
            }

            *exception = toRef(JSC::createTypeError(globalObject, "invalid pointer type"_s));
            return;
        }

        if (fundamentalType == G_TYPE_POINTER)
            g_value_set_pointer(value, wrappedObject);
        else if (fundamentalType == G_TYPE_BOXED)
            g_value_set_boxed(value, wrappedObject);
        else if (G_IS_OBJECT(wrappedObject))
            g_value_set_object(value, wrappedObject);
        else
            *exception = toRef(JSC::createTypeError(globalObject, "wrapped object is not a GObject"_s));
        break;
    }
    case G_TYPE_LONG:
        g_value_set_long(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_ULONG:
        g_value_set_ulong(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_INT64:
        g_value_set_int64(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_UINT64:
        g_value_set_uint64(value, JSValueToNumber(priv->jsContext.get(), jsValue, exception));
        break;
    case G_TYPE_ENUM:
        g_value_set_enum(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
        break;
    case G_TYPE_FLAGS:
        g_value_set_flags(value, JSC::toInt32(JSValueToNumber(priv->jsContext.get(), jsValue, exception)));
        break;
    case G_TYPE_PARAM:
    case G_TYPE_INTERFACE:
    case G_TYPE_VARIANT:
    default:
        *exception = toRef(JSC::createTypeError(globalObject, makeString("unsupported type ", g_type_name(G_VALUE_TYPE(value)))));
        break;
    }
}

void jscContextGarbageCollect(JSCContext* context, bool sanitizeStack)
{
    auto* jsContext = context->priv->jsContext.get();
    JSC::JSGlobalObject* globalObject = toJS(jsContext);
    JSC::VM& vm = globalObject->vm();
    JSC::JSLockHolder locker(vm);

    if (sanitizeStack)
        sanitizeStackForVM(vm);

    vm.heap.collectNow(JSC::Sync, JSC::CollectionScope::Full);
}

/**
 * jsc_context_new:
 *
 * Create a new #JSCContext. The context is created in a new #JSCVirtualMachine.
 * Use jsc_context_new_with_virtual_machine() to create a new #JSCContext in an
 * existing #JSCVirtualMachine.
 *
 * Returns: (transfer full): the newly created #JSCContext.
 */
JSCContext* jsc_context_new()
{
    return JSC_CONTEXT(g_object_new(JSC_TYPE_CONTEXT, nullptr));
}

/**
 * jsc_context_new_with_virtual_machine:
 * @vm: a #JSCVirtualMachine
 *
 * Create a new #JSCContext in @virtual_machine.
 *
 * Returns: (transfer full): the newly created #JSCContext.
 */
JSCContext* jsc_context_new_with_virtual_machine(JSCVirtualMachine* vm)
{
    g_return_val_if_fail(JSC_IS_VIRTUAL_MACHINE(vm), nullptr);
    return JSC_CONTEXT(g_object_new(JSC_TYPE_CONTEXT, "virtual-machine", vm, nullptr));
}

/**
 * jsc_context_get_virtual_machine:
 * @context: a #JSCContext
 *
 * Get the #JSCVirtualMachine where @context was created.
 *
 * Returns: (transfer none): the #JSCVirtualMachine where the #JSCContext was created.
 */
JSCVirtualMachine* jsc_context_get_virtual_machine(JSCContext* context)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);

    return context->priv->vm.get();
}

/**
 * jsc_context_get_exception:
 * @context: a #JSCContext
 *
 * Get the last unhandled exception thrown in @context by API functions calls.
 *
 * Returns: (transfer none) (nullable): a #JSCException or %NULL if there isn't any
 *    unhandled exception in the #JSCContext.
 */
JSCException* jsc_context_get_exception(JSCContext *context)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);

    return context->priv->exception.get();
}

/**
 * jsc_context_throw:
 * @context: a #JSCContext
 * @error_message: an error message
 *
 * Throw an exception to @context using the given error message. The created #JSCException
 * can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw(JSCContext* context, const char* errorMessage)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    context->priv->exception = adoptGRef(jsc_exception_new(context, errorMessage));
}

/**
 * jsc_context_throw_printf:
 * @context: a #JSCContext
 * @format: the string format
 * @...: the parameters to insert into the format string
 *
 * Throw an exception to @context using the given formatted string as error message.
 * The created #JSCException can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw_printf(JSCContext* context, const char* format, ...)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    va_list args;
    va_start(args, format);
    context->priv->exception = adoptGRef(jsc_exception_new_vprintf(context, format, args));
    va_end(args);
}

/**
 * jsc_context_throw_with_name:
 * @context: a #JSCContext
 * @error_name: the error name
 * @error_message: an error message
 *
 * Throw an exception to @context using the given error name and message. The created #JSCException
 * can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw_with_name(JSCContext* context, const char* errorName, const char* errorMessage)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(errorName);

    context->priv->exception = adoptGRef(jsc_exception_new_with_name(context, errorName, errorMessage));
}

/**
 * jsc_context_throw_with_name_printf:
 * @context: a #JSCContext
 * @error_name: the error name
 * @format: the string format
 * @...: the parameters to insert into the format string
 *
 * Throw an exception to @context using the given error name and the formatted string as error message.
 * The created #JSCException can be retrieved with jsc_context_get_exception().
 */
void jsc_context_throw_with_name_printf(JSCContext* context, const char* errorName, const char* format, ...)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    va_list args;
    va_start(args, format);
    context->priv->exception = adoptGRef(jsc_exception_new_with_name_vprintf(context, errorName, format, args));
    va_end(args);
}

/**
 * jsc_context_throw_exception:
 * @context: a #JSCContext
 * @exception: a #JSCException
 *
 * Throw @exception to @context.
 */
void jsc_context_throw_exception(JSCContext* context, JSCException* exception)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(JSC_IS_EXCEPTION(exception));

    context->priv->exception = exception;
}

/**
 * jsc_context_clear_exception:
 * @context: a #JSCContext
 *
 * Clear the uncaught exception in @context if any.
 */
void jsc_context_clear_exception(JSCContext* context)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));

    context->priv->exception = nullptr;
}

/**
 * JSCExceptionHandler:
 * @context: a #JSCContext
 * @exception: a #JSCException
 * @user_data: user data
 *
 * Function used to handle JavaScript exceptions in a #JSCContext.
 */

/**
 * jsc_context_push_exception_handler:
 * @context: a #JSCContext
 * @handler: a #JSCExceptionHandler
 * @user_data: (closure): user data to pass to @handler
 * @destroy_notify: (nullable): destroy notifier for @user_data
 *
 * Push an exception handler in @context. Whenever a JavaScript exception happens in
 * the #JSCContext, the given @handler will be called. The default #JSCExceptionHandler
 * simply calls jsc_context_throw_exception() to throw the exception to the #JSCContext.
 * If you don't want to catch the exception, but only get notified about it, call
 * jsc_context_throw_exception() in @handler like the default one does.
 * The last exception handler pushed is the only one used by the #JSCContext, use
 * jsc_context_pop_exception_handler() to remove it and set the previous one. When @handler
 * is removed from the context, @destroy_notify i called with @user_data as parameter.
 */
void jsc_context_push_exception_handler(JSCContext* context, JSCExceptionHandler handler, gpointer userData, GDestroyNotify destroyNotify)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(handler);

    context->priv->exceptionHandlers.append({ handler, userData, destroyNotify });
}

/**
 * jsc_context_pop_exception_handler:
 * @context: a #JSCContext
 *
 * Remove the last #JSCExceptionHandler previously pushed to @context with
 * jsc_context_push_exception_handler().
 */
void jsc_context_pop_exception_handler(JSCContext* context)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(context->priv->exceptionHandlers.size() > 1);

    context->priv->exceptionHandlers.removeLast();
}

bool jscContextHandleExceptionIfNeeded(JSCContext* context, JSValueRef jsException)
{
    if (!jsException)
        return false;

    auto exception = jscExceptionCreate(context, jsException);
    ASSERT(!context->priv->exceptionHandlers.isEmpty());
    const auto& exceptionHandler = context->priv->exceptionHandlers.last();
    exceptionHandler.handler(context, exception.get(), exceptionHandler.userData);

    return true;
}

/**
 * jsc_context_get_current:
 *
 * Get the #JSCContext that is currently executing a function. This should only be
 * called within a function or method callback, otherwise %NULL will be returned.
 *
 * Returns: (transfer none) (nullable): the #JSCContext that is currently executing.
 */
JSCContext* jsc_context_get_current()
{
    auto* data = static_cast<CallbackData*>(Thread::current().m_apiData);
    return data ? data->context.get() : nullptr;
}

/**
 * jsc_context_evaluate:
 * @context: a #JSCContext
 * @code: a JavaScript script to evaluate
 * @length: length of @code, or -1 if @code is a nul-terminated string
 *
 * Evaluate @code in @context.
 *
 * Returns: (transfer full): a #JSCValue representing the last value generated by the script.
 */
JSCValue* jsc_context_evaluate(JSCContext* context, const char* code, gssize length)
{
    return jsc_context_evaluate_with_source_uri(context, code, length, nullptr, 0);
}

static JSValueRef evaluateScriptInContext(JSGlobalContextRef jsContext, String&& script, const char* uri, unsigned lineNumber, JSValueRef* exception)
{
    JSRetainPtr<JSStringRef> scriptJS(Adopt, OpaqueJSString::tryCreate(WTFMove(script)).leakRef());
    JSRetainPtr<JSStringRef> sourceURI = uri ? adopt(JSStringCreateWithUTF8CString(uri)) : nullptr;
    return JSEvaluateScript(jsContext, scriptJS.get(), nullptr, sourceURI.get(), lineNumber, exception);
}

/**
 * jsc_context_evaluate_with_source_uri:
 * @context: a #JSCContext
 * @code: a JavaScript script to evaluate
 * @length: length of @code, or -1 if @code is a nul-terminated string
 * @uri: the source URI
 * @line_number: the starting line number
 *
 * 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.
 *
 * Returns: (transfer full): a #JSCValue representing the last value generated by the script.
 */
JSCValue* jsc_context_evaluate_with_source_uri(JSCContext* context, const char* code, gssize length, const char* uri, unsigned lineNumber)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(code, nullptr);

    JSValueRef exception = nullptr;
    JSValueRef result = evaluateScriptInContext(context->priv->jsContext.get(), String::fromUTF8(code, length < 0 ? strlen(code) : length), uri, lineNumber, &exception);
    if (jscContextHandleExceptionIfNeeded(context, exception))
        return jsc_value_new_undefined(context);

    return jscContextGetOrCreateValue(context, result).leakRef();
}

/**
 * jsc_context_evaluate_in_object:
 * @context: a #JSCContext
 * @code: a JavaScript script to evaluate
 * @length: length of @code, or -1 if @code is a nul-terminated string
 * @object_instance: (nullable): an object instance
 * @object_class: (nullable): a #JSCClass or %NULL to use the default
 * @uri: the source URI
 * @line_number: the starting line number
 * @object: (out) (transfer full): return location for a #JSCValue.
 *
 * 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 jsc_value_new_object() 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.
 *
 * Returns: (transfer full): a #JSCValue representing the last value generated by the script.
 */
JSCValue* jsc_context_evaluate_in_object(JSCContext* context, const char* code, gssize length, gpointer instance, JSCClass* objectClass, const char* uri, unsigned lineNumber, JSCValue** object)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(code, nullptr);
    g_return_val_if_fail(!instance || JSC_IS_CLASS(objectClass), nullptr);
    g_return_val_if_fail(object && !*object, nullptr);

    JSRetainPtr<JSGlobalContextRef> objectContext(Adopt,
        instance ? jscClassCreateContextWithJSWrapper(objectClass, context, instance) : JSGlobalContextCreateInGroup(jscVirtualMachineGetContextGroup(context->priv->vm.get()), nullptr));
    JSC::JSGlobalObject* globalObject = toJS(objectContext.get());
    JSC::VM& vm = globalObject->vm();
    JSC::JSLockHolder locker(globalObject);
    globalObject->setGlobalScopeExtension(JSC::JSWithScope::create(vm, globalObject, globalObject->globalScope(), toJS(JSContextGetGlobalObject(context->priv->jsContext.get()))));
    JSValueRef exception = nullptr;
    JSValueRef result = evaluateScriptInContext(objectContext.get(), String::fromUTF8(code, length < 0 ? strlen(code) : length), uri, lineNumber, &exception);
    if (jscContextHandleExceptionIfNeeded(context, exception))
        return jsc_value_new_undefined(context);

    *object = jscContextGetOrCreateValue(context, JSContextGetGlobalObject(objectContext.get())).leakRef();

    return jscContextGetOrCreateValue(context, result).leakRef();
}

/**
 * JSCCheckSyntaxMode:
 * @JSC_CHECK_SYNTAX_MODE_SCRIPT: mode to check syntax of a script
 * @JSC_CHECK_SYNTAX_MODE_MODULE: mode to check syntax of a module
 *
 * Enum values to specify a mode to check for syntax errors in jsc_context_check_syntax().
 */

/**
 * JSCCheckSyntaxResult:
 * @JSC_CHECK_SYNTAX_RESULT_SUCCESS: no errors
 * @JSC_CHECK_SYNTAX_RESULT_RECOVERABLE_ERROR: recoverable syntax error
 * @JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR: irrecoverable syntax error
 * @JSC_CHECK_SYNTAX_RESULT_UNTERMINATED_LITERAL_ERROR: unterminated literal error
 * @JSC_CHECK_SYNTAX_RESULT_OUT_OF_MEMORY_ERROR: out of memory error
 * @JSC_CHECK_SYNTAX_RESULT_STACK_OVERFLOW_ERROR: stack overflow error
 *
 * Enum values to specify the result of jsc_context_check_syntax().
 */

/**
 * jsc_context_check_syntax:
 * @context: a #JSCContext
 * @code: a JavaScript script to check
 * @length: length of @code, or -1 if @code is a nul-terminated string
 * @mode: a #JSCCheckSyntaxMode
 * @uri: the source URI
 * @line_number: the starting line number
 * @exception: (out) (optional) (transfer full): return location for a #JSCException, or %NULL to ignore
 *
 * 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 #JSCException with the details. You can pass %NULL to
 * @exception to ignore the error details.
 *
 * Returns: a #JSCCheckSyntaxResult
 */
JSCCheckSyntaxResult jsc_context_check_syntax(JSCContext* context, const char* code, gssize length, JSCCheckSyntaxMode mode, const char* uri, unsigned lineNumber, JSCException **exception)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR);
    g_return_val_if_fail(code, JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR);
    g_return_val_if_fail(!exception || !*exception, JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR);

    lineNumber = std::max<unsigned>(1, lineNumber);

    auto* jsContext = context->priv->jsContext.get();
    JSC::JSGlobalObject* globalObject = toJS(jsContext);
    JSC::VM& vm = globalObject->vm();
    JSC::JSLockHolder locker(vm);

    URL sourceURL = uri ? URL(String::fromLatin1(uri)) : URL();
    JSC::SourceCode source = JSC::makeSource(String::fromUTF8(code, length < 0 ? strlen(code) : length), JSC::SourceOrigin { sourceURL },
        sourceURL.string() , TextPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber()));
    bool success = false;
    JSC::ParserError error;
    switch (mode) {
    case JSC_CHECK_SYNTAX_MODE_SCRIPT:
        success = !!JSC::parse<JSC::ProgramNode>(vm, source, JSC::Identifier(), JSC::JSParserBuiltinMode::NotBuiltin,
            JSC::JSParserStrictMode::NotStrict, JSC::JSParserScriptMode::Classic, JSC::SourceParseMode::ProgramMode, JSC::SuperBinding::NotNeeded, error);
        break;
    case JSC_CHECK_SYNTAX_MODE_MODULE:
        success = !!JSC::parse<JSC::ModuleProgramNode>(vm, source, JSC::Identifier(), JSC::JSParserBuiltinMode::NotBuiltin,
            JSC::JSParserStrictMode::Strict, JSC::JSParserScriptMode::Module, JSC::SourceParseMode::ModuleAnalyzeMode, JSC::SuperBinding::NotNeeded, error);
        break;
    }

    JSCCheckSyntaxResult result = JSC_CHECK_SYNTAX_RESULT_SUCCESS;
    if (success)
        return result;

    switch (error.type()) {
    case JSC::ParserError::ErrorType::SyntaxError: {
        switch (error.syntaxErrorType()) {
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorIrrecoverable:
            result = JSC_CHECK_SYNTAX_RESULT_IRRECOVERABLE_ERROR;
            break;
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorUnterminatedLiteral:
            result = JSC_CHECK_SYNTAX_RESULT_UNTERMINATED_LITERAL_ERROR;
            break;
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorRecoverable:
            result = JSC_CHECK_SYNTAX_RESULT_RECOVERABLE_ERROR;
            break;
        case JSC::ParserError::SyntaxErrorType::SyntaxErrorNone:
            ASSERT_NOT_REACHED();
            break;
        }
        break;
    }
    case JSC::ParserError::ErrorType::StackOverflow:
        result = JSC_CHECK_SYNTAX_RESULT_STACK_OVERFLOW_ERROR;
        break;
    case JSC::ParserError::ErrorType::OutOfMemory:
        result = JSC_CHECK_SYNTAX_RESULT_OUT_OF_MEMORY_ERROR;
        break;
    case JSC::ParserError::ErrorType::EvalError:
    case JSC::ParserError::ErrorType::ErrorNone:
        ASSERT_NOT_REACHED();
        break;
    }

    if (exception) {
        auto* jsError = error.toErrorObject(globalObject, source);
        *exception = jscExceptionCreate(context, toRef(globalObject, jsError)).leakRef();
    }

    return result;
}

/**
 * jsc_context_get_global_object:
 * @context: a #JSCContext
 *
 * Get a #JSCValue referencing the @context global object
 *
 * Returns: (transfer full): a #JSCValue
 */
JSCValue* jsc_context_get_global_object(JSCContext* context)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);

    return jscContextGetOrCreateValue(context, JSContextGetGlobalObject(context->priv->jsContext.get())).leakRef();
}

/**
 * jsc_context_set_value:
 * @context: a #JSCContext
 * @name: the value name
 * @value: a #JSCValue
 *
 * Set a property of @context global object with @name and @value.
 */
void jsc_context_set_value(JSCContext* context, const char* name, JSCValue* value)
{
    g_return_if_fail(JSC_IS_CONTEXT(context));
    g_return_if_fail(name);
    g_return_if_fail(JSC_IS_VALUE(value));

    auto contextObject = jscContextGetOrCreateValue(context, JSContextGetGlobalObject(context->priv->jsContext.get()));
    jsc_value_object_set_property(contextObject.get(), name, value);
}

/**
 * jsc_context_get_value:
 * @context: a #JSCContext
 * @name: the value name
 *
 * Get a property of @context global object with @name.
 *
 * Returns: (transfer full): a #JSCValue
 */
JSCValue* jsc_context_get_value(JSCContext* context, const char* name)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(name, nullptr);

    auto contextObject = jscContextGetOrCreateValue(context, JSContextGetGlobalObject(context->priv->jsContext.get()));
    return jsc_value_object_get_property(contextObject.get(), name);
}

/**
 * jsc_context_register_class:
 * @context: a #JSCContext
 * @name: the class name
 * @parent_class: (nullable): a #JSCClass or %NULL
 * @vtable: (nullable): an optional #JSCClassVTable or %NULL
 * @destroy_notify: (nullable): a destroy notifier for class instances
 *
 * Register a custom class in @context using the given @name. If the new class inherits from
 * another #JSCClass, 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 #JSCClass is cleared in the context, @destroy_notify is called with
 * the instance as parameter.
 *
 * Returns: (transfer none): a #JSCClass
 */
JSCClass* jsc_context_register_class(JSCContext* context, const char* name, JSCClass* parentClass, JSCClassVTable* vtable, GDestroyNotify destroyFunction)
{
    g_return_val_if_fail(JSC_IS_CONTEXT(context), nullptr);
    g_return_val_if_fail(name, nullptr);
    g_return_val_if_fail(!parentClass || JSC_IS_CLASS(parentClass), nullptr);

    auto jscClass = jscClassCreate(context, name, parentClass, vtable, destroyFunction);
    wrapperMap(context).registerClass(jscClass.get());
    return jscClass.get();
}
