/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qv4internalclass_p.h>
#include <qv4string_p.h>
#include <qv4engine_p.h>
#include <qv4identifier_p.h>
#include "qv4object_p.h"
#include "qv4identifiertable_p.h"
#include "qv4value_p.h"
#include "qv4mm_p.h"
#include <private/qprimefornumbits_p.h>

QT_BEGIN_NAMESPACE

namespace QV4 {

PropertyHashData::PropertyHashData(int numBits)
    : refCount(1)
    , size(0)
    , numBits(numBits)
{
    alloc = qPrimeForNumBits(numBits);
    entries = (PropertyHash::Entry *)malloc(alloc*sizeof(PropertyHash::Entry));
    memset(entries, 0, alloc*sizeof(PropertyHash::Entry));
}

void PropertyHash::addEntry(const PropertyHash::Entry &entry, int classSize)
{
    // fill up to max 50%
    bool grow = (d->alloc <= d->size*2);

    if (classSize < d->size || grow)
        detach(grow, classSize);

    uint idx = entry.identifier.id() % d->alloc;
    while (d->entries[idx].identifier.isValid()) {
        ++idx;
        idx %= d->alloc;
    }
    d->entries[idx] = entry;
    ++d->size;
}

int PropertyHash::removeIdentifier(PropertyKey identifier, int classSize)
{
    int val = -1;
    PropertyHashData *dd = new PropertyHashData(d->numBits);
    for (int i = 0; i < d->alloc; ++i) {
        const Entry &e = d->entries[i];
        if (!e.identifier.isValid() || e.index >= static_cast<unsigned>(classSize))
            continue;
        if (e.identifier == identifier) {
            val = e.index;
            continue;
        }
        uint idx = e.identifier.id() % dd->alloc;
        while (dd->entries[idx].identifier.isValid()) {
            ++idx;
            idx %= dd->alloc;
        }
        dd->entries[idx] = e;
    }
    dd->size = classSize;
    if (!--d->refCount)
        delete d;
    d = dd;

    Q_ASSERT(val != -1);
    return val;
}

void PropertyHash::detach(bool grow, int classSize)
{
    if (d->refCount == 1 && !grow)
        return;

    PropertyHashData *dd = new PropertyHashData(grow ? d->numBits + 1 : d->numBits);
    for (int i = 0; i < d->alloc; ++i) {
        const Entry &e = d->entries[i];
        if (!e.identifier.isValid() || e.index >= static_cast<unsigned>(classSize))
            continue;
        uint idx = e.identifier.id() % dd->alloc;
        while (dd->entries[idx].identifier.isValid()) {
            ++idx;
            idx %= dd->alloc;
        }
        dd->entries[idx] = e;
    }
    dd->size = classSize;
    if (!--d->refCount)
        delete d;
    d = dd;
}


SharedInternalClassDataPrivate<PropertyKey>::SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate<PropertyKey> &other)
    : refcount(1),
      engine(other.engine),
      data(nullptr)
{
    if (other.alloc()) {
        const uint s = other.size();
        data = MemberData::allocate(engine, other.alloc(), other.data);
        setSize(s);
    }
}

SharedInternalClassDataPrivate<PropertyKey>::SharedInternalClassDataPrivate(const SharedInternalClassDataPrivate<PropertyKey> &other,
                                                                            uint pos, PropertyKey value)
    : refcount(1),
      engine(other.engine)
{
    data = MemberData::allocate(engine, other.alloc(), nullptr);
    memcpy(data, other.data, sizeof(Heap::MemberData) - sizeof(Value) + pos*sizeof(Value));
    data->values.size = pos + 1;
    data->values.set(engine, pos, Value::fromReturnedValue(value.id()));
}

void SharedInternalClassDataPrivate<PropertyKey>::grow()
{
    const uint a = alloc() * 2;
    const uint s = size();
    data = MemberData::allocate(engine, a, data);
    setSize(s);
    Q_ASSERT(alloc() >= a);
}

uint SharedInternalClassDataPrivate<PropertyKey>::alloc() const
{
    return data ? data->values.alloc : 0;
}

uint SharedInternalClassDataPrivate<PropertyKey>::size() const
{
    return data ? data->values.size : 0;
}

void SharedInternalClassDataPrivate<PropertyKey>::setSize(uint s)
{
    Q_ASSERT(data && s <= alloc());
    data->values.size = s;
}

PropertyKey SharedInternalClassDataPrivate<PropertyKey>::at(uint i)
{
    Q_ASSERT(data && i < size());
    return PropertyKey::fromId(data->values.values[i].rawValue());
}

void SharedInternalClassDataPrivate<PropertyKey>::set(uint i, PropertyKey t)
{
    Q_ASSERT(data && i < size());
    data->values.values[i].rawValueRef() = t.id();
}

void SharedInternalClassDataPrivate<PropertyKey>::mark(MarkStack *s)
{
    if (data)
        data->mark(s);
}

SharedInternalClassDataPrivate<PropertyAttributes>::SharedInternalClassDataPrivate(
        const SharedInternalClassDataPrivate<PropertyAttributes> &other, uint pos,
        PropertyAttributes value)
    : refcount(1),
      m_alloc(qMin(other.m_alloc, pos + 8)),
      m_size(pos + 1),
      m_engine(other.m_engine)
{
    Q_ASSERT(m_size <= m_alloc);
    m_engine->memoryManager->changeUnmanagedHeapSizeUsage(m_alloc * sizeof(PropertyAttributes));
    data = new PropertyAttributes[m_alloc];
    if (other.data)
        memcpy(data, other.data, (m_size - 1) * sizeof(PropertyAttributes));
    data[pos] = value;
}

SharedInternalClassDataPrivate<PropertyAttributes>::SharedInternalClassDataPrivate(
        const SharedInternalClassDataPrivate<PropertyAttributes> &other)
    : refcount(1),
      m_alloc(other.m_alloc),
      m_size(other.m_size),
      m_engine(other.m_engine)
{
    if (m_alloc) {
        m_engine->memoryManager->changeUnmanagedHeapSizeUsage(m_alloc * sizeof(PropertyAttributes));
        data = new PropertyAttributes[m_alloc];
        memcpy(data, other.data, m_size*sizeof(PropertyAttributes));
    } else {
        data = nullptr;
    }
}

SharedInternalClassDataPrivate<PropertyAttributes>::~SharedInternalClassDataPrivate()
{
    m_engine->memoryManager->changeUnmanagedHeapSizeUsage(
            -qptrdiff(m_alloc * sizeof(PropertyAttributes)));
    delete [] data;
}

void SharedInternalClassDataPrivate<PropertyAttributes>::grow() {
    uint alloc;
    if (!m_alloc) {
        alloc = 8;
        m_engine->memoryManager->changeUnmanagedHeapSizeUsage(alloc * sizeof(PropertyAttributes));
    } else {
        // yes, signed. We don't want to deal with stuff > 2G
        const uint currentSize = m_alloc * sizeof(PropertyAttributes);
        if (currentSize < uint(std::numeric_limits<int>::max() / 2))
            alloc = m_alloc * 2;
        else
            alloc = std::numeric_limits<int>::max() / sizeof(PropertyAttributes);

        m_engine->memoryManager->changeUnmanagedHeapSizeUsage(
                (alloc - m_alloc) * sizeof(PropertyAttributes));
    }

    auto *n = new PropertyAttributes[alloc];
    if (data) {
        memcpy(n, data, m_alloc*sizeof(PropertyAttributes));
        delete [] data;
    }
    data = n;
    m_alloc = alloc;
}

namespace Heap {

void InternalClass::init(ExecutionEngine *engine)
{
    Base::init();
    new (&propertyTable) PropertyHash();
    new (&nameMap) SharedInternalClassData<PropertyKey>(engine);
    new (&propertyData) SharedInternalClassData<PropertyAttributes>(engine);
    new (&transitions) std::vector<Transition>();

    this->engine = engine;
    vtable = QV4::InternalClass::staticVTable();
//    prototype = nullptr;
//    parent = nullptr;
//    size = 0;
    extensible = true;
    isFrozen = false;
    isSealed = false;
    isUsedAsProto = false;
    protoId = engine->newProtoId();

    // Also internal classes need an internal class pointer. Simply make it point to itself
    internalClass.set(engine, this);
}


void InternalClass::init(Heap::InternalClass *other)
{
    Base::init();
    new (&propertyTable) PropertyHash(other->propertyTable);
    new (&nameMap) SharedInternalClassData<PropertyKey>(other->nameMap);
    new (&propertyData) SharedInternalClassData<PropertyAttributes>(other->propertyData);
    new (&transitions) std::vector<Transition>();

    engine = other->engine;
    vtable = other->vtable;
    prototype = other->prototype;
    parent = other;
    size = other->size;
    extensible = other->extensible;
    isSealed = other->isSealed;
    isFrozen = other->isFrozen;
    isUsedAsProto = other->isUsedAsProto;
    protoId = engine->newProtoId();

    internalClass.set(engine, other->internalClass);
}

void InternalClass::destroy()
{
    for (const auto &t : transitions) {
        if (t.lookup) {
#ifndef QT_NO_DEBUG
            Q_ASSERT(t.lookup->parent == this);
#endif
            t.lookup->parent = nullptr;
        }
    }

    if (parent && parent->engine && parent->isMarked())
        parent->removeChildEntry(this);

    propertyTable.~PropertyHash();
    nameMap.~SharedInternalClassData<PropertyKey>();
    propertyData.~SharedInternalClassData<PropertyAttributes>();
    transitions.~vector<Transition>();
    engine = nullptr;
    Base::destroy();
}

QString InternalClass::keyAt(uint index) const
{
    return nameMap.at(index).toQString();
}

void InternalClass::changeMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry)
{
    Q_ASSERT(id.isStringOrSymbol());

    Heap::InternalClass *oldClass = object->internalClass();
    Heap::InternalClass *newClass = oldClass->changeMember(id, data, entry);
    object->setInternalClass(newClass);
}

InternalClassTransition &InternalClass::lookupOrInsertTransition(const InternalClassTransition &t)
{
    std::vector<Transition>::iterator it = std::lower_bound(transitions.begin(), transitions.end(), t);
    if (it != transitions.end() && *it == t) {
        return *it;
    } else {
        it = transitions.insert(it, t);
        return *it;
    }
}

static void addDummyEntry(InternalClass *newClass, PropertyHash::Entry e)
{
    // add a dummy entry, since we need two entries for accessors
    newClass->propertyTable.addEntry(e, newClass->size);
    newClass->nameMap.add(newClass->size, PropertyKey::invalid());
    newClass->propertyData.add(newClass->size, PropertyAttributes());
    ++newClass->size;
}

Heap::InternalClass *InternalClass::changeMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry)
{
    if (!data.isEmpty())
        data.resolve();
    PropertyHash::Entry *e = findEntry(identifier);
    Q_ASSERT(e && e->index != UINT_MAX);
    uint idx = e->index;
    Q_ASSERT(idx != UINT_MAX);

    if (entry) {
        entry->index = idx;
        entry->setterIndex = e->setterIndex;
        entry->attributes = data;
    }

    if (data == propertyData.at(idx))
        return static_cast<Heap::InternalClass *>(this);

    Transition temp = { { identifier }, nullptr, int(data.all()) };
    Transition &t = lookupOrInsertTransition(temp);
    if (t.lookup)
        return t.lookup;

    // create a new class and add it to the tree
    Heap::InternalClass *newClass = engine->newClass(this);
    if (data.isAccessor() && e->setterIndex == UINT_MAX) {
        Q_ASSERT(!propertyData.at(idx).isAccessor());

        // add a dummy entry for the accessor
        entry->setterIndex = newClass->size;
        e->setterIndex = newClass->size;
        addDummyEntry(newClass, *e);
    }

    newClass->propertyData.set(idx, data);

    t.lookup = newClass;
    Q_ASSERT(t.lookup);
    return newClass;
}

Heap::InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto)
{
    Scope scope(engine);
    ScopedValue protectThis(scope, this);
    if (proto)
        proto->setUsedAsProto();
    Q_ASSERT(prototype != proto);
    Q_ASSERT(!proto || proto->internalClass->isUsedAsProto);

    Transition temp = { { PropertyKey::invalid() }, nullptr, Transition::PrototypeChange };
    temp.prototype = proto;

    Transition &t = lookupOrInsertTransition(temp);
    if (t.lookup)
        return t.lookup;

    // create a new class and add it to the tree
    Heap::InternalClass *newClass = engine->newClass(this);
    newClass->prototype = proto;

    t.lookup = newClass;

    return newClass;
}

Heap::InternalClass *InternalClass::changeVTableImpl(const VTable *vt)
{
    Q_ASSERT(vtable != vt);

    Transition temp = { { PropertyKey::invalid() }, nullptr, Transition::VTableChange };
    temp.vtable = vt;

    Transition &t = lookupOrInsertTransition(temp);
    if (t.lookup)
        return t.lookup;

    // create a new class and add it to the tree
    Heap::InternalClass *newClass = engine->newClass(this);
    newClass->vtable = vt;

    t.lookup = newClass;
    Q_ASSERT(t.lookup);
    Q_ASSERT(newClass->vtable);
    return newClass;
}

Heap::InternalClass *InternalClass::nonExtensible()
{
    if (!extensible)
        return this;

    Transition temp = { { PropertyKey::invalid() }, nullptr, Transition::NotExtensible};
    Transition &t = lookupOrInsertTransition(temp);
    if (t.lookup)
        return t.lookup;

    Heap::InternalClass *newClass = engine->newClass(this);
    newClass->extensible = false;

    t.lookup = newClass;
    Q_ASSERT(t.lookup);
    return newClass;
}

void InternalClass::addMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry)
{
    Q_ASSERT(id.isStringOrSymbol());
    if (!data.isEmpty())
        data.resolve();
    PropertyHash::Entry *e = object->internalClass()->findEntry(id);
    if (e) {
        changeMember(object, id, data, entry);
        return;
    }

    Heap::InternalClass *newClass = object->internalClass()->addMemberImpl(id, data, entry);
    object->setInternalClass(newClass);
}

Heap::InternalClass *InternalClass::addMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry)
{
    Q_ASSERT(identifier.isStringOrSymbol());
    if (!data.isEmpty())
        data.resolve();

    PropertyHash::Entry *e = findEntry(identifier);
    if (e)
        return changeMember(identifier, data, entry);

    return addMemberImpl(identifier, data, entry);
}

Heap::InternalClass *InternalClass::addMemberImpl(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry)
{
    Transition temp = { { identifier }, nullptr, (int)data.flags() };
    Transition &t = lookupOrInsertTransition(temp);

    if (entry) {
        entry->index = size;
        entry->setterIndex = data.isAccessor() ? size + 1 : UINT_MAX;
        entry->attributes = data;
    }

    if (t.lookup)
        return t.lookup;

    // create a new class and add it to the tree
    Scope scope(engine);
    Scoped<QV4::InternalClass> ic(scope, engine->newClass(this));
    InternalClass *newClass = ic->d();
    PropertyHash::Entry e = { identifier, newClass->size, data.isAccessor() ? newClass->size + 1 : UINT_MAX };
    newClass->propertyTable.addEntry(e, newClass->size);

    newClass->nameMap.add(newClass->size, identifier);
    newClass->propertyData.add(newClass->size, data);
    ++newClass->size;
    if (data.isAccessor())
        addDummyEntry(newClass, e);

    t.lookup = newClass;
    Q_ASSERT(t.lookup);
    return newClass;
}

void InternalClass::removeChildEntry(InternalClass *child)
{
    Q_ASSERT(engine);
    for (auto &t : transitions) {
        if (t.lookup == child) {
            t.lookup = nullptr;
            return;
        }
    }
    Q_UNREACHABLE();

}

void InternalClass::removeMember(QV4::Object *object, PropertyKey identifier)
{
#ifndef QT_NO_DEBUG
    Heap::InternalClass *oldClass = object->internalClass();
    Q_ASSERT(oldClass->findEntry(identifier) != nullptr);
#endif

    changeMember(object, identifier, Attr_Invalid);

#ifndef QT_NO_DEBUG
    // we didn't remove the data slot, just made it inaccessible
    Q_ASSERT(object->internalClass()->size == oldClass->size);
#endif
}

Heap::InternalClass *InternalClass::sealed()
{
    if (isSealed)
        return this;

    Transition temp = { { PropertyKey::invalid() }, nullptr, InternalClassTransition::Sealed };
    Transition &t = lookupOrInsertTransition(temp);

    if (t.lookup) {
        Q_ASSERT(t.lookup && t.lookup->isSealed);
        return t.lookup;
    }

    Scope scope(engine);
    Scoped<QV4::InternalClass> ic(scope, engine->newClass(this));
    Heap::InternalClass *s = ic->d();

    if (!isFrozen) { // freezing also makes all properties non-configurable
        for (uint i = 0; i < size; ++i) {
            PropertyAttributes attrs = propertyData.at(i);
            if (attrs.isEmpty())
                continue;
            attrs.setConfigurable(false);
            s->propertyData.set(i, attrs);
        }
    }
    s->isSealed = true;

    t.lookup = s;
    return s;
}

Heap::InternalClass *InternalClass::frozen()
{
    if (isFrozen)
        return this;

    Transition temp = { { PropertyKey::invalid() }, nullptr, InternalClassTransition::Frozen };
    Transition &t = lookupOrInsertTransition(temp);

    if (t.lookup) {
        Q_ASSERT(t.lookup && t.lookup->isFrozen);
        return t.lookup;
    }

    Scope scope(engine);
    Scoped<QV4::InternalClass> ic(scope, engine->newClass(this));
    Heap::InternalClass *f = ic->d();

    for (uint i = 0; i < size; ++i) {
        PropertyAttributes attrs = propertyData.at(i);
        if (attrs.isEmpty())
            continue;
        if (attrs.isData())
            attrs.setWritable(false);
        attrs.setConfigurable(false);
        f->propertyData.set(i, attrs);
    }
    f->isFrozen = true;

    t.lookup = f;
    return f;
}

InternalClass *InternalClass::canned()
{
    // scope the intermediate result to prevent it from getting garbage collected
    Scope scope(engine);
    Scoped<QV4::InternalClass> ic(scope, sealed());
    return ic->d()->nonExtensible();
}

InternalClass *InternalClass::cryopreserved()
{
    // scope the intermediate result to prevent it from getting garbage collected
    Scope scope(engine);
    Scoped<QV4::InternalClass> ic(scope, frozen());
    return ic->d()->canned();
}

bool InternalClass::isImplicitlyFrozen() const
{
    if (isFrozen)
        return true;

    for (uint i = 0; i < size; ++i) {
        const PropertyAttributes attrs = propertyData.at(i);
        if (attrs.isEmpty())
            continue;
        if ((attrs.isData() && attrs.isWritable()) || attrs.isConfigurable())
            return false;
    }

    return true;
}

Heap::InternalClass *InternalClass::asProtoClass()
{
    if (isUsedAsProto)
        return this;

    Transition temp = { { PropertyKey::invalid() }, nullptr, Transition::ProtoClass };
    Transition &t = lookupOrInsertTransition(temp);
    if (t.lookup)
        return t.lookup;

    Heap::InternalClass *newClass = engine->newClass(this);
    newClass->isUsedAsProto = true;

    t.lookup = newClass;
    Q_ASSERT(t.lookup);
    return newClass;
}

static void updateProtoUsage(Heap::Object *o, Heap::InternalClass *ic)
{
    if (ic->prototype == o)
        ic->protoId = ic->engine->newProtoId();
    for (auto &t : ic->transitions) {
        if (t.lookup)
            updateProtoUsage(o, t.lookup);
    }
}


void InternalClass::updateProtoUsage(Heap::Object *o)
{
    Q_ASSERT(isUsedAsProto);
    Heap::InternalClass *ic = engine->internalClasses(EngineBase::Class_Empty);
    Q_ASSERT(!ic->prototype);

    Heap::updateProtoUsage(o, ic);
}

void InternalClass::markObjects(Heap::Base *b, MarkStack *stack)
{
    Heap::InternalClass *ic = static_cast<Heap::InternalClass *>(b);
    if (ic->prototype)
        ic->prototype->mark(stack);

    ic->nameMap.mark(stack);
}

}

}

QT_END_NAMESPACE
