/****************************************************************************
**
** 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 "qv4regexpobject_p.h"
#include "qv4objectproto_p.h"
#include "qv4regexp_p.h"
#include "qv4stringobject_p.h"
#include <private/qv4mm_p.h>
#include "qv4scopedvalue_p.h"
#include "qv4jscall_p.h"
#include "qv4symbol_p.h"

#include "private/qlocale_tools_p.h"

#include <QtCore/QDebug>
#include <QtCore/qregexp.h>
#if QT_CONFIG(regularexpression)
#include <QtCore/qregularexpression.h>
#endif
#include <cassert>
#include <typeinfo>
#include <iostream>
#include <private/qv4alloca_p.h>

QT_BEGIN_NAMESPACE

Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);

using namespace QV4;

DEFINE_OBJECT_VTABLE(RegExpObject);

void Heap::RegExpObject::init()
{
    Object::init();
    Scope scope(internalClass->engine);
    Scoped<QV4::RegExpObject> o(scope, this);
    value.set(scope.engine, QV4::RegExp::create(scope.engine, QString(), CompiledData::RegExp::RegExp_NoFlags));
    o->initProperties();
}

void Heap::RegExpObject::init(QV4::RegExp *value)
{
    Object::init();
    Scope scope(internalClass->engine);
    this->value.set(scope.engine, value->d());
    Scoped<QV4::RegExpObject> o(scope, this);
    o->initProperties();
}

// Converts a QRegExp to a JS RegExp.
// The conversion is not 100% exact since ECMA regexp and QRegExp
// have different semantics/flags, but we try to do our best.
void Heap::RegExpObject::init(const QRegExp &re)
{
    Object::init();

    // Convert the pattern to a ECMAScript pattern.
    QString pattern = QT_PREPEND_NAMESPACE(qt_regexp_toCanonical)(re.pattern(), re.patternSyntax());
    if (re.isMinimal()) {
        QString ecmaPattern;
        int len = pattern.length();
        ecmaPattern.reserve(len);
        int i = 0;
        const QChar *wc = pattern.unicode();
        bool inBracket = false;
        while (i < len) {
            QChar c = wc[i++];
            ecmaPattern += c;
            switch (c.unicode()) {
            case '?':
            case '+':
            case '*':
            case '}':
                if (!inBracket)
                    ecmaPattern += QLatin1Char('?');
                break;
            case '\\':
                if (i < len)
                    ecmaPattern += wc[i++];
                break;
            case '[':
                inBracket = true;
                break;
            case ']':
                inBracket = false;
                break;
            default:
                break;
            }
        }
        pattern = ecmaPattern;
    }

    Scope scope(internalClass->engine);
    Scoped<QV4::RegExpObject> o(scope, this);

    uint flags = (re.caseSensitivity() == Qt::CaseInsensitive ? CompiledData::RegExp::RegExp_IgnoreCase : CompiledData::RegExp::RegExp_NoFlags);
    o->d()->value.set(scope.engine, QV4::RegExp::create(scope.engine, pattern, flags));

    o->initProperties();
}

#if QT_CONFIG(regularexpression)
// Converts a QRegularExpression to a JS RegExp.
// The conversion is not 100% exact since ECMA regexp and QRegularExpression
// have different semantics/flags, but we try to do our best.
void Heap::RegExpObject::init(const QRegularExpression &re)
{
    Object::init();

    Scope scope(internalClass->engine);
    Scoped<QV4::RegExpObject> o(scope, this);

    const uint flags = (re.patternOptions() & QRegularExpression::CaseInsensitiveOption)
            ? CompiledData::RegExp::RegExp_IgnoreCase
            : CompiledData::RegExp::RegExp_NoFlags;
    o->d()->value.set(scope.engine, QV4::RegExp::create(scope.engine, re.pattern(), flags));
    o->initProperties();
}
#endif

void RegExpObject::initProperties()
{
    setProperty(Index_LastIndex, Value::fromInt32(0));

    Q_ASSERT(value());
}

// Converts a JS RegExp to a QRegExp.
// The conversion is not 100% exact since ECMA regexp and QRegExp
// have different semantics/flags, but we try to do our best.
QRegExp RegExpObject::toQRegExp() const
{
    Qt::CaseSensitivity caseSensitivity = (value()->flags & CompiledData::RegExp::RegExp_IgnoreCase) ? Qt::CaseInsensitive : Qt::CaseSensitive;
    return QRegExp(*value()->pattern, caseSensitivity, QRegExp::RegExp2);
}

#if QT_CONFIG(regularexpression)
// Converts a JS RegExp to a QRegularExpression.
// The conversion is not 100% exact since ECMA regexp and QRegularExpression
// have different semantics/flags, but we try to do our best.
QRegularExpression RegExpObject::toQRegularExpression() const
{
    QRegularExpression::PatternOptions caseSensitivity
            = (value()->flags & CompiledData::RegExp::RegExp_IgnoreCase)
            ? QRegularExpression::CaseInsensitiveOption
            : QRegularExpression::NoPatternOption;
    return QRegularExpression(*value()->pattern, caseSensitivity);
}
#endif

QString RegExpObject::toString() const
{
    QString p = *value()->pattern;
    if (p.isEmpty()) {
        p = QStringLiteral("(?:)");
    } else {
        // escape certain parts, see ch. 15.10.4
        p.replace('/', QLatin1String("\\/"));
    }
    return p;
}

ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *str)
{
    QString s = str->toQString();

    Scope scope(engine);
    int offset = (global() || sticky()) ? lastIndex() : 0;
    if (offset < 0 || offset > s.length()) {
        setLastIndex(0);
        RETURN_RESULT(Encode::null());
    }

    Q_ALLOCA_VAR(uint, matchOffsets, value()->captureCount() * 2 * sizeof(uint));
    const uint result = Scoped<RegExp>(scope, value())->match(s, offset, matchOffsets);

    RegExpCtor *regExpCtor = static_cast<RegExpCtor *>(scope.engine->regExpCtor());
    regExpCtor->d()->clearLastMatch();

    if (result == JSC::Yarr::offsetNoMatch) {
        if (global() || sticky())
            setLastIndex(0);
        RETURN_RESULT(Encode::null());
    }

    Q_ASSERT(result <= uint(std::numeric_limits<int>::max()));

    // fill in result data
    ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->internalClasses(EngineBase::Class_RegExpExecArray)));
    int len = value()->captureCount();
    array->arrayReserve(len);
    ScopedValue v(scope);
    int strlen = s.length();
    for (int i = 0; i < len; ++i) {
        int start = matchOffsets[i * 2];
        int end = matchOffsets[i * 2 + 1];
        if (end > strlen)
            end = strlen;
        v = (start != -1) ? scope.engine->memoryManager->alloc<ComplexString>(str->d(), start, end - start)->asReturnedValue() : Encode::undefined();
        array->arrayPut(i, v);
    }
    array->setArrayLengthUnchecked(len);
    array->setProperty(Index_ArrayIndex, Value::fromInt32(int(result)));
    array->setProperty(Index_ArrayInput, *str);

    RegExpCtor::Data *dd = regExpCtor->d();
    dd->lastMatch.set(scope.engine, array);
    dd->lastInput.set(scope.engine, str->d());
    dd->lastMatchStart = matchOffsets[0];
    dd->lastMatchEnd = matchOffsets[1];

    if (global() || sticky())
        setLastIndex(matchOffsets[1]);

    return array.asReturnedValue();
}

DEFINE_OBJECT_VTABLE(RegExpCtor);

void Heap::RegExpCtor::init(QV4::ExecutionContext *scope)
{
    Heap::FunctionObject::init(scope, QStringLiteral("RegExp"));
    clearLastMatch();
}

void Heap::RegExpCtor::clearLastMatch()
{
    lastMatch.set(internalClass->engine, Value::nullValue());
    lastInput.set(internalClass->engine, internalClass->engine->id_empty()->d());
    lastMatchStart = 0;
    lastMatchEnd = 0;
}

static bool isRegExp(ExecutionEngine *e, const QV4::Value *arg)
{
    const QV4::Object *o = arg->objectValue();
    if (!o)
        return false;

    QV4::Value isRegExp = QV4::Value::fromReturnedValue(o->get(e->symbol_match()));
    if (!isRegExp.isUndefined())
        return isRegExp.toBoolean();
    const RegExpObject *re = o->as<RegExpObject>();
    return re ? true : false;
}

uint parseFlags(Scope &scope, const QV4::Value *f)
{
    uint flags = CompiledData::RegExp::RegExp_NoFlags;
    if (!f->isUndefined()) {
        ScopedString s(scope, f->toString(scope.engine));
        if (scope.hasException())
            return flags;
        QString str = s->toQString();
        for (int i = 0; i < str.length(); ++i) {
            if (str.at(i) == QLatin1Char('g') && !(flags & CompiledData::RegExp::RegExp_Global)) {
                flags |= CompiledData::RegExp::RegExp_Global;
            } else if (str.at(i) == QLatin1Char('i') && !(flags & CompiledData::RegExp::RegExp_IgnoreCase)) {
                flags |= CompiledData::RegExp::RegExp_IgnoreCase;
            } else if (str.at(i) == QLatin1Char('m') && !(flags & CompiledData::RegExp::RegExp_Multiline)) {
                flags |= CompiledData::RegExp::RegExp_Multiline;
            } else if (str.at(i) == QLatin1Char('u') && !(flags & CompiledData::RegExp::RegExp_Unicode)) {
                flags |= CompiledData::RegExp::RegExp_Unicode;
            } else if (str.at(i) == QLatin1Char('y') && !(flags & CompiledData::RegExp::RegExp_Sticky)) {
                flags |= CompiledData::RegExp::RegExp_Sticky;
            } else {
                scope.engine->throwSyntaxError(QStringLiteral("Invalid flags supplied to RegExp constructor"));
                return flags;
            }
        }
    }
    return flags;
}

ReturnedValue RegExpCtor::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *newTarget)
{
    Scope scope(fo);

    bool patternIsRegExp = argc ? ::isRegExp(scope.engine, argv) : false;

    if (newTarget == fo) {
        if (patternIsRegExp && (argc < 2 || argv[1].isUndefined())) {
            const Object *pattern = static_cast<const Object *>(argv);
            ScopedValue patternConstructor(scope, pattern->get(scope.engine->id_constructor()));
            if (patternConstructor->sameValue(*newTarget))
                return pattern->asReturnedValue();
        }
    }

    ScopedValue p(scope, argc ? argv[0] : Value::undefinedValue());
    ScopedValue f(scope, argc > 1 ? argv[1] : Value::undefinedValue());
    Scoped<RegExpObject> re(scope, p);
    QString pattern;
    uint flags = CompiledData::RegExp::RegExp_NoFlags;

    if (re) {
        if (f->isUndefined()) {
            Scoped<RegExp> regexp(scope, re->value());
            return Encode(scope.engine->newRegExpObject(regexp));
        }
        pattern = *re->value()->pattern;
        flags = parseFlags(scope, f);
    } else if (patternIsRegExp) {
        const Object *po = static_cast<const Object *>(argv);
        p = po->get(scope.engine->id_source());
        if (!p->isUndefined())
            pattern = p->toQString();
        if (scope.hasException())
            return Encode::undefined();
        if (f->isUndefined())
            f = po->get(scope.engine->id_flags());
        flags = parseFlags(scope, f);
    } else {
        if (!p->isUndefined())
            pattern = p->toQString();
        if (scope.hasException())
            return Encode::undefined();
        flags = parseFlags(scope, f);
    }
    if (scope.hasException())
        return Encode::undefined();

    Scoped<RegExp> regexp(scope, RegExp::create(scope.engine, pattern, flags));
    if (!regexp->isValid()) {
        return scope.engine->throwSyntaxError(QStringLiteral("Invalid regular expression"));
    }

    ReturnedValue o = Encode(scope.engine->newRegExpObject(regexp));

    if (!newTarget)
        return o;
    ScopedObject obj(scope, o);
    obj->setProtoFromNewTarget(newTarget);
    return obj->asReturnedValue();
}

ReturnedValue RegExpCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
    return virtualCallAsConstructor(f, argv, argc, f);
}

void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
{
    Scope scope(engine);
    ScopedObject o(scope);
    ScopedObject ctor(scope, constructor);

    ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
    ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(2));
    ctor->addSymbolSpecies();

    // Properties deprecated in the spec but required by "the web" :(
    ctor->defineAccessorProperty(QStringLiteral("lastMatch"), method_get_lastMatch_n<0>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$&"), method_get_lastMatch_n<0>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$1"), method_get_lastMatch_n<1>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$2"), method_get_lastMatch_n<2>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$3"), method_get_lastMatch_n<3>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$4"), method_get_lastMatch_n<4>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$5"), method_get_lastMatch_n<5>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$6"), method_get_lastMatch_n<6>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$7"), method_get_lastMatch_n<7>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$8"), method_get_lastMatch_n<8>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$9"), method_get_lastMatch_n<9>, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("lastParen"), method_get_lastParen, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$+"), method_get_lastParen, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("input"), method_get_input, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$_"), method_get_input, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("leftContext"), method_get_leftContext, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$`"), method_get_leftContext, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("rightContext"), method_get_rightContext, nullptr);
    ctor->defineAccessorProperty(QStringLiteral("$'"), method_get_rightContext, nullptr);

    defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
    defineAccessorProperty(scope.engine->id_flags(), method_get_flags, nullptr);
    defineAccessorProperty(scope.engine->id_global(), method_get_global, nullptr);
    defineAccessorProperty(scope.engine->id_ignoreCase(), method_get_ignoreCase, nullptr);
    defineDefaultProperty(QStringLiteral("exec"), method_exec, 1);
    defineDefaultProperty(engine->symbol_match(), method_match, 1);
    defineAccessorProperty(scope.engine->id_multiline(), method_get_multiline, nullptr);
    defineDefaultProperty(engine->symbol_replace(), method_replace, 2);
    defineDefaultProperty(engine->symbol_search(), method_search, 1);
    defineAccessorProperty(scope.engine->id_source(), method_get_source, nullptr);
    defineDefaultProperty(engine->symbol_split(), method_split, 2);
    defineAccessorProperty(scope.engine->id_sticky(), method_get_sticky, nullptr);
    defineDefaultProperty(QStringLiteral("test"), method_test, 1);
    defineDefaultProperty(engine->id_toString(), method_toString, 0);
    defineAccessorProperty(scope.engine->id_unicode(), method_get_unicode, nullptr);

    // another web extension
    defineDefaultProperty(QStringLiteral("compile"), method_compile, 2);
}

/* used by String.match */
ReturnedValue RegExpPrototype::execFirstMatch(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
    Scope scope(b);
    Scoped<RegExpObject> r(scope, thisObject->as<RegExpObject>());
    Q_ASSERT(r && r->global());

    ScopedString str(scope, argc ? argv[0] : Value::undefinedValue());
    Q_ASSERT(str);
    QString s = str->toQString();

    int offset = r->lastIndex();
    if (offset < 0 || offset > s.length()) {
        r->setLastIndex(0);
        RETURN_RESULT(Encode::null());
    }

    Q_ALLOCA_VAR(uint, matchOffsets, r->value()->captureCount() * 2 * sizeof(uint));
    const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);

    RegExpCtor *regExpCtor = static_cast<RegExpCtor *>(scope.engine->regExpCtor());
    regExpCtor->d()->clearLastMatch();

    if (result == -1) {
        r->setLastIndex(0);
        RETURN_RESULT(Encode::null());
    }

    ReturnedValue retVal = Encode::undefined();
    // return first match
    if (r->value()->captureCount()) {
        int start = matchOffsets[0];
        int end = matchOffsets[1];
        retVal = (start != -1) ? scope.engine->memoryManager->alloc<ComplexString>(str->d(), start, end - start)->asReturnedValue() : Encode::undefined();
    }

    RegExpCtor::Data *dd = regExpCtor->d();
    dd->lastInput.set(scope.engine, str->d());
    dd->lastMatchStart = matchOffsets[0];
    dd->lastMatchEnd = matchOffsets[1];

    r->setLastIndex(matchOffsets[1]);

    return retVal;
}

ReturnedValue RegExpPrototype::exec(ExecutionEngine *engine, const Object *o, const String *s)
{
    Scope scope(engine);
    ScopedString key(scope, scope.engine->newString(QStringLiteral("exec")));
    ScopedFunctionObject exec(scope, o->get(key));
    if (exec) {
        ScopedValue result(scope, exec->call(o, s, 1));
        if (!result->isNull() && !result->isObject())
            return scope.engine->throwTypeError();
        return result->asReturnedValue();
    }
    Scoped<RegExpObject> re(scope, o);
    if (!re)
        return scope.engine->throwTypeError();
    return re->builtinExec(engine, s);
}

ReturnedValue RegExpPrototype::method_exec(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
    Scope scope(b);
    Scoped<RegExpObject> r(scope, thisObject->as<RegExpObject>());
    if (!r)
        return scope.engine->throwTypeError();

    ScopedValue arg(scope, argc ? argv[0]: Value::undefinedValue());
    ScopedString str(scope, arg->toString(scope.engine));
    if (scope.hasException())
        RETURN_UNDEFINED();

    return  r->builtinExec(scope.engine, str);
}

ReturnedValue RegExpPrototype::method_get_flags(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
    Scope scope(f);
    ScopedObject o(scope, thisObject);
    if (!o)
        return scope.engine->throwTypeError();

    QString result;
    ScopedValue v(scope);
    v = o->get(scope.engine->id_global());
    if (scope.hasException())
        return Encode::undefined();
    if (v->toBoolean())
        result += QLatin1Char('g');
    v = o->get(scope.engine->id_ignoreCase());
    if (scope.hasException())
        return Encode::undefined();
    if (v->toBoolean())
        result += QLatin1Char('i');
    v = o->get(scope.engine->id_multiline());
    if (scope.hasException())
        return Encode::undefined();
    if (v->toBoolean())
        result += QLatin1Char('m');
    v = o->get(scope.engine->id_unicode());
    if (scope.hasException())
        return Encode::undefined();
    if (v->toBoolean())
        result += QLatin1Char('u');
    v = o->get(scope.engine->id_sticky());
    if (scope.hasException())
        return Encode::undefined();
    if (v->toBoolean())
        result += QLatin1Char('y');
    return scope.engine->newString(result)->asReturnedValue();
}

ReturnedValue RegExpPrototype::method_get_global(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
    Scope scope(f);
    Scoped<RegExpObject> re(scope, thisObject);
    if (!re) {
        if (thisObject->sameValue(*scope.engine->regExpPrototype()))
            return Encode::undefined();
        return scope.engine->throwTypeError();
    }

    bool b = re->value()->flags & CompiledData::RegExp::RegExp_Global;
    return Encode(b);
}

ReturnedValue RegExpPrototype::method_get_ignoreCase(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
    Scope scope(f);
    Scoped<RegExpObject> re(scope, thisObject);
    if (!re) {
        if (thisObject->sameValue(*scope.engine->regExpPrototype()))
            return Encode::undefined();
        return scope.engine->throwTypeError();
    }

    bool b = re->value()->flags & CompiledData::RegExp::RegExp_IgnoreCase;
    return Encode(b);
}

static int advanceStringIndex(int index, const QString &str, bool unicode)
{
    if (unicode) {
        if (index < str.length() - 1 &&
            str.at(index).isHighSurrogate() &&
            str.at(index + 1).isLowSurrogate())
            ++index;
    }
    ++index;
    return index;
}

static void advanceLastIndexOnEmptyMatch(ExecutionEngine *e, bool unicode, QV4::Object *rx, const String *matchString, const QString &str)
{
    Scope scope(e);
    if (matchString->d()->length() == 0) {
        QV4::ScopedValue v(scope, rx->get(scope.engine->id_lastIndex()));
        int lastIndex = advanceStringIndex(v->toLength(), str, unicode);
        if (!rx->put(scope.engine->id_lastIndex(), QV4::Value::fromInt32(lastIndex)))
            scope.engine->throwTypeError();
    }
}

ReturnedValue RegExpPrototype::method_match(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
    Scope scope(f);
    ScopedObject rx(scope, thisObject);
    if (!rx)
        return scope.engine->throwTypeError();
    ScopedString s(scope, (argc ? argv[0] : Value::undefinedValue()).toString(scope.engine));
    if (scope.hasException())
        return Encode::undefined();
    bool global = ScopedValue(scope, rx->get(scope.engine->id_global()))->toBoolean();

    if (!global)
        return exec(scope.engine, rx, s);

    bool unicode = ScopedValue(scope, rx->get(scope.engine->id_unicode()))->toBoolean();

    rx->put(scope.engine->id_lastIndex(), Value::fromInt32(0));
    ScopedArrayObject a(scope, scope.engine->newArrayObject());
    uint n = 0;

    ScopedValue result(scope);
    ScopedValue match(scope);
    ScopedString matchString(scope);
    ScopedValue v(scope);
    while (1) {
        result = exec(scope.engine, rx, s);
        if (scope.hasException())
            return Encode::undefined();
        if (result->isNull()) {
            if (!n)
                return Encode::null();
            return a->asReturnedValue();
        }
        Q_ASSERT(result->isObject());
        match = static_cast<Object &>(*result).get(PropertyKey::fromArrayIndex(0));
        matchString = match->toString(scope.engine);
        if (scope.hasException())
            return Encode::undefined();
        a->push_back(matchString);
        advanceLastIndexOnEmptyMatch(scope.engine, unicode, rx, matchString, s->toQString());
        ++n;
    }
}

ReturnedValue RegExpPrototype::method_get_multiline(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
    Scope scope(f);
    Scoped<RegExpObject> re(scope, thisObject);
    if (!re) {
        if (thisObject->sameValue(*scope.engine->regExpPrototype()))
            return Encode::undefined();
        return scope.engine->throwTypeError();
    }

    bool b = re->value()->flags & CompiledData::RegExp::RegExp_Multiline;
    return Encode(b);
}

ReturnedValue RegExpPrototype::method_replace(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
    Scope scope(f);
    ScopedObject rx(scope, thisObject);
    if (!rx)
        return scope.engine->throwTypeError();

    ScopedString s(scope, (argc ? argv[0] : Value::undefinedValue()).toString(scope.engine));
    if (scope.hasException())
        return Encode::undefined();

    int lengthS = s->toQString().length();

    ScopedString replaceValue(scope);
    ScopedFunctionObject replaceFunction(scope, (argc > 1 ? argv[1] : Value::undefinedValue()));
    bool functionalReplace = !!replaceFunction;
    if (!functionalReplace)
        replaceValue = (argc > 1 ? argv[1] : Value::undefinedValue()).toString(scope.engine);

    ScopedValue v(scope);
    bool global = (v = rx->get(scope.engine->id_global()))->toBoolean();
    bool unicode = false;
    if (global) {
        unicode = (v = rx->get(scope.engine->id_unicode()))->toBoolean();
        if (!rx->put(scope.engine->id_lastIndex(), Value::fromInt32(0)))
            return scope.engine->throwTypeError();
    }

    ScopedArrayObject results(scope, scope.engine->newArrayObject());
    ScopedValue result(scope);
    ScopedValue match(scope);
    ScopedString matchString(scope);
    while (1) {
        result = exec(scope.engine, rx, s);
        if (scope.hasException())
            return Encode::undefined();
        if (result->isNull())
            break;
        results->push_back(result);
        if (!global)
            break;
        match = static_cast<Object &>(*result).get(PropertyKey::fromArrayIndex(0));
        matchString = match->toString(scope.engine);
        if (scope.hasException())
            return Encode::undefined();
        advanceLastIndexOnEmptyMatch(scope.engine, unicode, rx, matchString, s->toQString());
    }
    QString accumulatedResult;
    int nextSourcePosition = 0;
    int resultsLength = results->getLength();
    ScopedObject resultObject(scope);
    for (int i = 0; i < resultsLength; ++i) {
        resultObject = results->get(PropertyKey::fromArrayIndex(i));
        if (scope.hasException())
            return Encode::undefined();

        int nCaptures = resultObject->getLength();
        nCaptures = qMax(nCaptures - 1, 0);
        match = resultObject->get(PropertyKey::fromArrayIndex(0));
        matchString = match->toString(scope.engine);
        if (scope.hasException())
            return Encode::undefined();
        QString m = matchString->toQString();
        int matchLength = m.length();
        v = resultObject->get(scope.engine->id_index());
        int position = v->toInt32();
        position = qMax(qMin(position, lengthS), 0);
        if (scope.hasException())
            return Encode::undefined();

        int n = 1;
        Scope innerScope(scope.engine);
        JSCallData cData(scope, nCaptures + 3);
        while (n <= nCaptures) {
            v = resultObject->get(PropertyKey::fromArrayIndex(n));
            if (!v->isUndefined())
                cData->args[n] = v->toString(scope.engine);
            ++n;
        }
        QString replacement;
        if (functionalReplace) {
            cData->args[0] = matchString;
            cData->args[nCaptures + 1] = Encode(position);
            cData->args[nCaptures + 2] = s;
            ScopedValue replValue(scope, replaceFunction->call(cData));
            replacement = replValue->toQString();
        } else {
            replacement = RegExp::getSubstitution(matchString->toQString(), s->toQString(), position, cData.args, nCaptures, replaceValue->toQString());
        }
        if (scope.hasException())
            return Encode::undefined();
        if (position >= nextSourcePosition) {
            accumulatedResult += s->toQString().midRef(nextSourcePosition, position - nextSourcePosition) + replacement;
            nextSourcePosition = position + matchLength;
        }
    }
    if (nextSourcePosition < lengthS) {
        accumulatedResult += s->toQString().midRef(nextSourcePosition);
    }
    return scope.engine->newString(accumulatedResult)->asReturnedValue();
}

ReturnedValue RegExpPrototype::method_search(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
    Scope scope(f);
    ScopedObject rx(scope, thisObject);
    if (!rx)
        return scope.engine->throwTypeError();

    ScopedString s(scope, (argc ? argv[0] : Value::undefinedValue()).toString(scope.engine));
    if (scope.hasException())
        return Encode::undefined();

    ScopedValue previousLastIndex(scope, rx->get(scope.engine->id_lastIndex()));
    if (previousLastIndex->toNumber() != 0) {
        if (!rx->put(scope.engine->id_lastIndex(), Value::fromInt32(0)))
            return scope.engine->throwTypeError();
    }

    ScopedValue result(scope, exec(scope.engine, rx, s));
    if (scope.hasException())
        return Encode::undefined();

    ScopedValue currentLastIndex(scope, rx->get(scope.engine->id_lastIndex()));
    if (!currentLastIndex->sameValue(previousLastIndex)) {
        if (!rx->put(scope.engine->id_lastIndex(), previousLastIndex))
            return scope.engine->throwTypeError();
    }

    if (result->isNull())
        return Encode(-1);
    ScopedObject o(scope, result);
    Q_ASSERT(o);
    return o->get(scope.engine->id_index());
}


ReturnedValue RegExpPrototype::method_get_source(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
    Scope scope(f);
    Scoped<RegExpObject> re(scope, thisObject);
    if (!re) {
        if (thisObject->sameValue(*scope.engine->regExpPrototype()))
            return scope.engine->newString(QStringLiteral("(?:)"))->asReturnedValue();
        return scope.engine->throwTypeError();
    }

    return scope.engine->newString(re->toString())->asReturnedValue();
}

ReturnedValue RegExpPrototype::method_split(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
    Scope scope(f);
    ScopedObject rx(scope, thisObject);
    if (!rx)
        return scope.engine->throwTypeError();

    ScopedString s(scope, (argc ? argv[0] : Value::undefinedValue()).toString(scope.engine));
    if (scope.hasException())
        return Encode::undefined();

    ScopedValue flagsValue(scope, rx->get(scope.engine->id_flags()));
    ScopedString flags(scope, flagsValue->toString(scope.engine));
    if (scope.hasException())
        return Encode::undefined();
    QString flagsString = flags->toQString();
    if (!flagsString.contains(QLatin1Char('y')))
        flags = scope.engine->newString(flagsString + QLatin1Char('y'));
    bool unicodeMatching = flagsString.contains(QLatin1Char('u'));

    const FunctionObject *C = rx->speciesConstructor(scope, scope.engine->regExpCtor());
    if (!C)
        return Encode::undefined();

    Value *args = scope.alloc(2);
    args[0] = rx;
    args[1] = flags;
    ScopedObject splitter(scope, C->callAsConstructor(args, 2, f));
    if (scope.hasException())
        return Encode::undefined();

    ScopedArrayObject A(scope, scope.engine->newArrayObject());
    uint lengthA = 0;
    uint limit = argc < 2 ? UINT_MAX : argv[1].toUInt32();
    if (limit == 0)
        return A->asReturnedValue();

    QString S = s->toQString();
    int size = S.length();
    if (size == 0) {
        ScopedValue z(scope, exec(scope.engine, splitter, s));
        if (z->isNull())
            A->push_back(s);
        return A->asReturnedValue();
    }

    int p = 0;
    int q = 0;
    ScopedValue v(scope);
    ScopedValue z(scope);
    ScopedObject zz(scope);
    ScopedString t(scope);
    while (q < size) {
        Value qq = Value::fromInt32(q);
        if (!splitter->put(scope.engine->id_lastIndex(), qq))
            return scope.engine->throwTypeError();
        z = exec(scope.engine, splitter, s);
        if (scope.hasException())
            return Encode::undefined();

        if (z->isNull()) {
            q = advanceStringIndex(q, S, unicodeMatching);
            continue;
        }

        v = splitter->get(scope.engine->id_lastIndex());
        int e = qMin(v->toInt32(), size);
        if (e == p) {
            q = advanceStringIndex(q, S, unicodeMatching);
            continue;
        }
        QString T = S.mid(p, q - p);
        t = scope.engine->newString(T);
        A->push_back(t);
        ++lengthA;
        if (lengthA == limit)
            return A->asReturnedValue();
        p = e;
        zz = *z;
        uint numberOfCaptures = qMax(zz->getLength() - 1, 0ll);
        for (uint i = 1; i <= numberOfCaptures; ++i) {
            v = zz->get(PropertyKey::fromArrayIndex(i));
            A->push_back(v);
            ++lengthA;
            if (lengthA == limit)
                return A->asReturnedValue();
        }
        q = p;
    }

    QString T = S.mid(p);
    t = scope.engine->newString(T);
    A->push_back(t);
    return A->asReturnedValue();
}

ReturnedValue RegExpPrototype::method_get_sticky(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
    Scope scope(f);
    Scoped<RegExpObject> re(scope, thisObject);
    if (!re) {
        if (thisObject->sameValue(*scope.engine->regExpPrototype()))
            return Encode::undefined();
        return scope.engine->throwTypeError();
    }

    bool b = re->value()->flags & CompiledData::RegExp::RegExp_Sticky;
    return Encode(b);
}

ReturnedValue RegExpPrototype::method_test(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
    Value res = Value::fromReturnedValue(method_exec(b, thisObject, argv, argc));
    return Encode(!res.isNull());
}

ReturnedValue RegExpPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
    Scope scope(b);
    const Object *r = thisObject->as<Object>();
    if (!r)
        return scope.engine->throwTypeError();

    ScopedValue v(scope);
    v = r->get(scope.engine->id_source());
    ScopedString source(scope, v->toString(scope.engine));
    if (scope.hasException())
        return Encode::undefined();
    v = r->get(scope.engine->id_flags());
    ScopedString flags(scope, v->toString(scope.engine));
    if (scope.hasException())
        return Encode::undefined();

    QString result = QLatin1Char('/') + source->toQString() + QLatin1Char('/') + flags->toQString();
    return Encode(scope.engine->newString(result));
}

ReturnedValue RegExpPrototype::method_get_unicode(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
    Scope scope(f);
    Scoped<RegExpObject> re(scope, thisObject);
    if (!re) {
        if (thisObject->sameValue(*scope.engine->regExpPrototype()))
            return Encode::undefined();
        return scope.engine->throwTypeError();
    }

    bool b = re->value()->flags & CompiledData::RegExp::RegExp_Unicode;
    return Encode(b);
}

ReturnedValue RegExpPrototype::method_compile(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
    Scope scope(b);
    Scoped<RegExpObject> r(scope, thisObject->as<RegExpObject>());
    if (!r)
        return scope.engine->throwTypeError();

    Scoped<RegExpObject> re(scope, scope.engine->regExpCtor()->callAsConstructor(argv, argc));
    if (re) // Otherwise the regexp constructor should have thrown an exception
        r->d()->value.set(scope.engine, re->value());
    return Encode::undefined();
}

template <uint index>
ReturnedValue RegExpPrototype::method_get_lastMatch_n(const FunctionObject *b, const Value *, const Value *, int)
{
    Scope scope(b);
    ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
    ScopedValue res(scope, lastMatch ? lastMatch->get(index) : Encode::undefined());
    if (res->isUndefined())
        res = scope.engine->newString();
    return res->asReturnedValue();
}

ReturnedValue RegExpPrototype::method_get_lastParen(const FunctionObject *b, const Value *, const Value *, int)
{
    Scope scope(b);
    ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
    ScopedValue res(scope, lastMatch ? lastMatch->get(lastMatch->getLength() - 1) : Encode::undefined());
    if (res->isUndefined())
        res = scope.engine->newString();
    return res->asReturnedValue();
}

ReturnedValue RegExpPrototype::method_get_input(const FunctionObject *b, const Value *, const Value *, int)
{
    return static_cast<RegExpCtor*>(b->engine()->regExpCtor())->lastInput()->asReturnedValue();
}

ReturnedValue  RegExpPrototype::method_get_leftContext(const FunctionObject *b, const Value *, const Value *, int)
{
    Scope scope(b);
    Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
    QString lastInput = regExpCtor->lastInput()->toQString();
    return Encode(scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart())));
}

ReturnedValue  RegExpPrototype::method_get_rightContext(const FunctionObject *b, const Value *, const Value *, int)
{
    Scope scope(b);
    Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
    QString lastInput = regExpCtor->lastInput()->toQString();
    return Encode(scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd())));
}

QT_END_NAMESPACE
