/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtScript module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL-ONLY$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "config.h"
#include "qscriptengine.h"
#include "qscriptsyntaxchecker_p.h"

#include "qscriptengine_p.h"
#include "qscriptengineagent_p.h"
#include "qscriptcontext_p.h"
#include "qscriptstring_p.h"
#include "qscriptvalue_p.h"
#include "qscriptvalueiterator.h"
#include "qscriptclass.h"
#include "qscriptcontextinfo.h"
#include "qscriptprogram.h"
#include "qscriptprogram_p.h"
#include "qdebug.h"

#include <QtCore/qstringlist.h>
#include <QtCore/qmetaobject.h>

#include <math.h>

#include "CodeBlock.h"
#include "Error.h"
#include "Interpreter.h"

#include "ExceptionHelpers.h"
#include "PrototypeFunction.h"
#include "InitializeThreading.h"
#include "ObjectPrototype.h"
#include "SourceCode.h"
#include "FunctionPrototype.h"
#include "TimeoutChecker.h"
#include "JSFunction.h"
#include "Parser.h"
#include "PropertyNameArray.h"
#include "Operations.h"

#include "bridge/qscriptfunction_p.h"
#include "bridge/qscriptclassobject_p.h"
#include "bridge/qscriptvariant_p.h"
#include "bridge/qscriptqobject_p.h"
#include "bridge/qscriptglobalobject_p.h"
#include "bridge/qscriptactivationobject_p.h"
#include "bridge/qscriptstaticscopeobject_p.h"

#ifndef QT_NO_QOBJECT
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qpluginloader.h>
#include <QtCore/qset.h>
#include <QtCore/qtextstream.h>
#include "qscriptextensioninterface.h"
#endif

Q_DECLARE_METATYPE(QScriptValue)
#ifndef QT_NO_QOBJECT
Q_DECLARE_METATYPE(QObjectList)
#endif
Q_DECLARE_METATYPE(QList<int>)

QT_BEGIN_NAMESPACE

/*!
  \since 4.3
  \class QScriptEngine
  \reentrant

  \brief The QScriptEngine class provides an environment for evaluating Qt Script code.

  \ingroup script
  \mainclass

  See the \l{QtScript} documentation for information about the Qt Script language,
  and how to get started with scripting your C++ application.

  \section1 Evaluating Scripts

  Use evaluate() to evaluate script code; this is the C++ equivalent
  of the built-in script function \c{eval()}.

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 0

  evaluate() returns a QScriptValue that holds the result of the
  evaluation. The QScriptValue class provides functions for converting
  the result to various C++ types (e.g. QScriptValue::toString()
  and QScriptValue::toNumber()).

  The following code snippet shows how a script function can be
  defined and then invoked from C++ using QScriptValue::call():

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 1

  As can be seen from the above snippets, a script is provided to the
  engine in the form of a string. One common way of loading scripts is
  by reading the contents of a file and passing it to evaluate():

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 2

  Here we pass the name of the file as the second argument to
  evaluate().  This does not affect evaluation in any way; the second
  argument is a general-purpose string that is used to identify the
  script for debugging purposes (for example, our filename will now
  show up in any uncaughtExceptionBacktrace() involving the script).

  \section1 Engine Configuration

  The globalObject() function returns the \bold {Global Object}
  associated with the script engine. Properties of the Global Object
  are accessible from any script code (i.e. they are global
  variables). Typically, before evaluating "user" scripts, you will
  want to configure a script engine by adding one or more properties
  to the Global Object:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 3

  Adding custom properties to the scripting environment is one of the
  standard means of providing a scripting API that is specific to your
  application. Usually these custom properties are objects created by
  the newQObject() or newObject() functions, or constructor functions
  created by newFunction().

  \section1 Script Exceptions

  evaluate() can throw a script exception (e.g. due to a syntax
  error); in that case, the return value is the value that was thrown
  (typically an \c{Error} object). You can check whether the
  evaluation caused an exception by calling hasUncaughtException(). In
  that case, you can call toString() on the error object to obtain an
  error message. The current uncaught exception is also available
  through uncaughtException().
  Calling clearExceptions() will cause any uncaught exceptions to be
  cleared.

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 4

  The checkSyntax() function can be used to determine whether code can be
  usefully passed to evaluate().

  \section1 Script Object Creation

  Use newObject() to create a standard Qt Script object; this is the
  C++ equivalent of the script statement \c{new Object()}. You can use
  the object-specific functionality in QScriptValue to manipulate the
  script object (e.g. QScriptValue::setProperty()). Similarly, use
  newArray() to create a Qt Script array object. Use newDate() to
  create a \c{Date} object, and newRegExp() to create a \c{RegExp}
  object.

  \section1 QObject Integration

  Use newQObject() to wrap a QObject (or subclass)
  pointer. newQObject() returns a proxy script object; properties,
  children, and signals and slots of the QObject are available as
  properties of the proxy object. No binding code is needed because it
  is done dynamically using the Qt meta object system.

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 5

  Use qScriptConnect() to connect a C++ signal to a script function;
  this is the Qt Script equivalent of QObject::connect().  When a
  script function is invoked in response to a C++ signal, it can cause
  a script exception; you can connect to the signalHandlerException()
  signal to catch such an exception.

  Use newQMetaObject() to wrap a QMetaObject; this gives you a "script
  representation" of a QObject-based class. newQMetaObject() returns a
  proxy script object; enum values of the class are available as
  properties of the proxy object. You can also specify a function that
  will be used to construct objects of the class (e.g.  when the
  constructor is invoked from a script). For classes that have a
  "standard" Qt constructor, Qt Script can provide a default script
  constructor for you; see scriptValueFromQMetaObject().

  See the \l{QtScript} documentation for more information on
  the QObject integration.

  \section1 Support for Custom C++ Types

  Use newVariant() to wrap a QVariant. This can be used to store
  values of custom (non-QObject) C++ types that have been registered
  with the Qt meta-type system. To make such types scriptable, you
  typically associate a prototype (delegate) object with the C++ type
  by calling setDefaultPrototype(); the prototype object defines the
  scripting API for the C++ type. Unlike the QObject integration,
  there is no automatic binding possible here; i.e. you have to create
  the scripting API yourself, for example by using the QScriptable
  class.

  Use fromScriptValue() to cast from a QScriptValue to another type,
  and toScriptValue() to create a QScriptValue from another value.
  You can specify how the conversion of C++ types is to be performed
  with qScriptRegisterMetaType() and qScriptRegisterSequenceMetaType().
  By default, Qt Script will use QVariant to store values of custom
  types.

  \section1 Importing Extensions

  Use importExtension() to import plugin-based extensions into the
  engine. Call availableExtensions() to obtain a list naming all the
  available extensions, and importedExtensions() to obtain a list
  naming only those extensions that have been imported.

  Call pushContext() to open up a new variable scope, and popContext()
  to close the current scope. This is useful if you are implementing
  an extension that evaluates script code containing temporary
  variable definitions (e.g. \c{var foo = 123;}) that are safe to
  discard when evaluation has completed.

  \section1 Native Functions

  Use newFunction() to wrap native (C++) functions, including
  constructors for your own custom types, so that these can be invoked
  from script code. Such functions must have the signature
  QScriptEngine::FunctionSignature. You may then pass the function as
  argument to newFunction(). Here is an example of a function that
  returns the sum of its first two arguments:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 6

  To expose this function to script code, you can set it as a property
  of the Global Object:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 7

  Once this is done, script code can call your function in the exact
  same manner as a "normal" script function:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 8

  \section1 Long-running Scripts

  If you need to evaluate possibly long-running scripts from the main
  (GUI) thread, you should first call setProcessEventsInterval() to
  make sure that the GUI stays responsive. You can abort a currently
  running script by calling abortEvaluation(). You can determine
  whether an engine is currently running a script by calling
  isEvaluating().

  \section1 Garbage Collection

  Qt Script objects may be garbage collected when they are no longer
  referenced. There is no guarantee as to when automatic garbage
  collection will take place.

  The collectGarbage() function can be called to explicitly request
  garbage collection.

  The reportAdditionalMemoryCost() function can be called to indicate
  that a Qt Script object occupies memory that isn't managed by the
  scripting environment. Reporting the additional cost makes it more
  likely that the garbage collector will be triggered. This can be
  useful, for example, when many custom, native Qt Script objects are
  allocated.

  \section1 Core Debugging/Tracing Facilities

  Since Qt 4.4, you can be notified of events pertaining to script
  execution (e.g. script function calls and statement execution)
  through the QScriptEngineAgent interface; see the setAgent()
  function. This can be used to implement debugging and profiling of a
  QScriptEngine.

  \sa QScriptValue, QScriptContext, QScriptEngineAgent

*/

/*!
    \enum QScriptEngine::ValueOwnership

    This enum specifies the ownership when wrapping a C++ value, e.g. by using newQObject().

    \value QtOwnership The standard Qt ownership rules apply, i.e. the
    associated object will never be explicitly deleted by the script
    engine. This is the default. (QObject ownership is explained in
    \l{Object Trees & Ownership}.)

    \value ScriptOwnership The value is owned by the script
    environment. The associated data will be deleted when appropriate
    (i.e. after the garbage collector has discovered that there are no
    more live references to the value).

    \value AutoOwnership If the associated object has a parent, the Qt
    ownership rules apply (QtOwnership); otherwise, the object is
    owned by the script environment (ScriptOwnership).

*/

/*!
    \enum  QScriptEngine::QObjectWrapOption

    These flags specify options when wrapping a QObject pointer with newQObject().

    \value ExcludeChildObjects The script object will not expose child objects as properties.
    \value ExcludeSuperClassMethods The script object will not expose signals and slots inherited from the superclass.
    \value ExcludeSuperClassProperties The script object will not expose properties inherited from the superclass.
    \value ExcludeSuperClassContents Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties
    \value ExcludeDeleteLater The script object will not expose the QObject::deleteLater() slot.
    \value ExcludeSlots The script object will not expose the QObject's slots.
    \value AutoCreateDynamicProperties Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object.
    \value PreferExistingWrapperObject If a wrapper object with the requested configuration already exists, return that object.
    \value SkipMethodsInEnumeration Don't include methods (signals and slots) when enumerating the object's properties.
*/

class QScriptSyntaxCheckResultPrivate
{
public:
    QScriptSyntaxCheckResultPrivate() { ref = 0; }
    ~QScriptSyntaxCheckResultPrivate() {}

    QScriptSyntaxCheckResult::State state;
    int errorColumnNumber;
    int errorLineNumber;
    QString errorMessage;
    QBasicAtomicInt ref;
};

class QScriptTypeInfo
{
public:
    QScriptTypeInfo() : signature(0, '\0'), marshal(0), demarshal(0)
    { }

    QByteArray signature;
    QScriptEngine::MarshalFunction marshal;
    QScriptEngine::DemarshalFunction demarshal;
    JSC::JSValue prototype;
};

namespace QScript
{

static const qsreal D32 = 4294967296.0;

qint32 ToInt32(qsreal n)
{
    if (qIsNaN(n) || qIsInf(n) || (n == 0))
        return 0;

    qsreal sign = (n < 0) ? -1.0 : 1.0;
    qsreal abs_n = fabs(n);

    n = ::fmod(sign * ::floor(abs_n), D32);
    const double D31 = D32 / 2.0;

    if (sign == -1 && n < -D31)
        n += D32;

    else if (sign != -1 && n >= D31)
        n -= D32;

    return qint32 (n);
}

quint32 ToUInt32(qsreal n)
{
    if (qIsNaN(n) || qIsInf(n) || (n == 0))
        return 0;

    qsreal sign = (n < 0) ? -1.0 : 1.0;
    qsreal abs_n = fabs(n);

    n = ::fmod(sign * ::floor(abs_n), D32);

    if (n < 0)
        n += D32;

    return quint32 (n);
}

quint16 ToUInt16(qsreal n)
{
    static const qsreal D16 = 65536.0;

    if (qIsNaN(n) || qIsInf(n) || (n == 0))
        return 0;

    qsreal sign = (n < 0) ? -1.0 : 1.0;
    qsreal abs_n = fabs(n);

    n = ::fmod(sign * ::floor(abs_n), D16);

    if (n < 0)
        n += D16;

    return quint16 (n);
}

qsreal ToInteger(qsreal n)
{
    if (qIsNaN(n))
        return 0;

    if (n == 0 || qIsInf(n))
        return n;

    int sign = n < 0 ? -1 : 1;
    return sign * ::floor(::fabs(n));
}

#ifdef Q_CC_MSVC
// MSVC2008 crashes if these are inlined.

QString ToString(qsreal value)
{
    return JSC::UString::from(value);
}

qsreal ToNumber(const QString &value)
{
    return ((JSC::UString)value).toDouble();
}

#endif

static const qsreal MsPerSecond = 1000.0;

static inline int MsFromTime(qsreal t)
{
    int r = int(::fmod(t, MsPerSecond));
    return (r >= 0) ? r : r + int(MsPerSecond);
}

/*!
  \internal
  Converts a JS date value (milliseconds) to a QDateTime (local time).
*/
QDateTime MsToDateTime(JSC::ExecState *exec, qsreal t)
{
    if (qIsNaN(t))
        return QDateTime();
    JSC::GregorianDateTime tm;
    JSC::msToGregorianDateTime(exec, t, /*output UTC=*/true, tm);
    int ms = MsFromTime(t);
    QDateTime convertedUTC = QDateTime(QDate(tm.year + 1900, tm.month + 1, tm.monthDay),
                                       QTime(tm.hour, tm.minute, tm.second, ms), Qt::UTC);
    return convertedUTC.toLocalTime();
}

/*!
  \internal
  Converts a QDateTime to a JS date value (milliseconds).
*/
qsreal DateTimeToMs(JSC::ExecState *exec, const QDateTime &dt)
{
    if (!dt.isValid())
        return qSNaN();
    QDateTime utc = dt.toUTC();
    QDate date = utc.date();
    QTime time = utc.time();
    JSC::GregorianDateTime tm;
    tm.year = date.year() - 1900;
    tm.month = date.month() - 1;
    tm.monthDay = date.day();
    tm.weekDay = date.dayOfWeek();
    tm.yearDay = date.dayOfYear();
    tm.hour = time.hour();
    tm.minute = time.minute();
    tm.second = time.second();
    return JSC::gregorianDateTimeToMS(exec, tm, time.msec(), /*inputIsUTC=*/true);
}

void GlobalClientData::mark(JSC::MarkStack& markStack)
{
    engine->mark(markStack);
}

class TimeoutCheckerProxy : public JSC::TimeoutChecker
{
public:
    TimeoutCheckerProxy(const JSC::TimeoutChecker& originalChecker)
        : JSC::TimeoutChecker(originalChecker)
        , m_shouldProcessEvents(false)
        , m_shouldAbortEvaluation(false)
    {}

    void setShouldProcessEvents(bool shouldProcess) { m_shouldProcessEvents = shouldProcess; }
    void setShouldAbort(bool shouldAbort) { m_shouldAbortEvaluation = shouldAbort; }
    bool shouldAbort() { return m_shouldAbortEvaluation; }

    virtual bool didTimeOut(JSC::ExecState* exec)
    {
        if (JSC::TimeoutChecker::didTimeOut(exec))
            return true;

        if (m_shouldProcessEvents)
            QCoreApplication::processEvents();

        return m_shouldAbortEvaluation;
    }

private:
    bool m_shouldProcessEvents;
    bool m_shouldAbortEvaluation;
};

static int toDigit(char c)
{
    if ((c >= '0') && (c <= '9'))
        return c - '0';
    else if ((c >= 'a') && (c <= 'z'))
        return 10 + c - 'a';
    else if ((c >= 'A') && (c <= 'Z'))
        return 10 + c - 'A';
    return -1;
}

qsreal integerFromString(const char *buf, int size, int radix)
{
    if (size == 0)
        return qSNaN();

    qsreal sign = 1.0;
    int i = 0;
    if (buf[0] == '+') {
        ++i;
    } else if (buf[0] == '-') {
        sign = -1.0;
        ++i;
    }

    if (((size-i) >= 2) && (buf[i] == '0')) {
        if (((buf[i+1] == 'x') || (buf[i+1] == 'X'))
            && (radix < 34)) {
            if ((radix != 0) && (radix != 16))
                return 0;
            radix = 16;
            i += 2;
        } else {
            if (radix == 0) {
                radix = 8;
                ++i;
            }
        }
    } else if (radix == 0) {
        radix = 10;
    }

    int j = i;
    for ( ; i < size; ++i) {
        int d = toDigit(buf[i]);
        if ((d == -1) || (d >= radix))
            break;
    }
    qsreal result;
    if (j == i) {
        if (!qstrcmp(buf, "Infinity"))
            result = qInf();
        else
            result = qSNaN();
    } else {
        result = 0;
        qsreal multiplier = 1;
        for (--i ; i >= j; --i, multiplier *= radix)
            result += toDigit(buf[i]) * multiplier;
    }
    result *= sign;
    return result;
}

qsreal integerFromString(const QString &str, int radix)
{
    QByteArray ba = str.trimmed().toUtf8();
    return integerFromString(ba.constData(), ba.size(), radix);
}

bool isFunction(JSC::JSValue value)
{
    if (!value || !value.isObject())
        return false;
    JSC::CallData callData;
    return (JSC::asObject(value)->getCallData(callData) != JSC::CallTypeNone);
}

static JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);

JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState *exec, JSC::JSObject * /*callee*/, JSC::JSValue thisObject, const JSC::ArgList &args)
{
#ifndef QT_NO_QOBJECT
    if (args.size() == 0) {
        return JSC::throwError(exec, JSC::GeneralError, "Function.prototype.disconnect: no arguments given");
    }

    if (!JSC::asObject(thisObject)->inherits(&QScript::QtFunction::info)) {
        return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: this object is not a signal");
    }

    QScript::QtFunction *qtSignal = static_cast<QScript::QtFunction*>(JSC::asObject(thisObject));

    const QMetaObject *meta = qtSignal->metaObject();
    if (!meta) {
        return JSC::throwError(exec, JSC::TypeError, "Function.prototype.discconnect: cannot disconnect from deleted QObject");
    }

    QMetaMethod sig = meta->method(qtSignal->initialIndex());
    if (sig.methodType() != QMetaMethod::Signal) {
        QString message = QString::fromLatin1("Function.prototype.disconnect: %0::%1 is not a signal")
                          .arg(QLatin1String(qtSignal->metaObject()->className()))
                          .arg(QLatin1String(sig.signature()));
        return JSC::throwError(exec, JSC::TypeError, message);
    }

    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);

    JSC::JSValue receiver;
    JSC::JSValue slot;
    JSC::JSValue arg0 = args.at(0);
    if (args.size() < 2) {
        slot = arg0;
    } else {
        receiver = arg0;
        JSC::JSValue arg1 = args.at(1);
        if (isFunction(arg1))
            slot = arg1;
        else {
            QScript::SaveFrameHelper saveFrame(engine, exec);
            JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1);
            slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
        }
    }

    if (!isFunction(slot)) {
        return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: target is not a function");
    }

    bool ok = engine->scriptDisconnect(thisObject, receiver, slot);
    if (!ok) {
        QString message = QString::fromLatin1("Function.prototype.disconnect: failed to disconnect from %0::%1")
                          .arg(QLatin1String(qtSignal->metaObject()->className()))
                          .arg(QLatin1String(sig.signature()));
        return JSC::throwError(exec, JSC::GeneralError, message);
    }
    return JSC::jsUndefined();
#else
    Q_UNUSED(eng);
    return context->throwError(QScriptContext::TypeError,
                               QLatin1String("Function.prototype.disconnect"));
#endif // QT_NO_QOBJECT
}

JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState *exec, JSC::JSObject * /*callee*/, JSC::JSValue thisObject, const JSC::ArgList &args)
{
#ifndef QT_NO_QOBJECT
    if (args.size() == 0) {
        return JSC::throwError(exec, JSC::GeneralError,"Function.prototype.connect: no arguments given");
    }

    if (!JSC::asObject(thisObject)->inherits(&QScript::QtFunction::info)) {
        return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: this object is not a signal");
    }

    QScript::QtFunction *qtSignal = static_cast<QScript::QtFunction*>(JSC::asObject(thisObject));

    const QMetaObject *meta = qtSignal->metaObject();
    if (!meta) {
        return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: cannot connect to deleted QObject");
    }

    QMetaMethod sig = meta->method(qtSignal->initialIndex());
    if (sig.methodType() != QMetaMethod::Signal) {
        QString message = QString::fromLatin1("Function.prototype.connect: %0::%1 is not a signal")
                          .arg(QLatin1String(qtSignal->metaObject()->className()))
                          .arg(QLatin1String(sig.signature()));
        return JSC::throwError(exec, JSC::TypeError, message);
    }

    {
        QList<int> overloads = qtSignal->overloadedIndexes();
        if (!overloads.isEmpty()) {
            overloads.append(qtSignal->initialIndex());
            QByteArray signature = sig.signature();
            QString message = QString::fromLatin1("Function.prototype.connect: ambiguous connect to %0::%1(); candidates are\n")
                              .arg(QLatin1String(qtSignal->metaObject()->className()))
                              .arg(QLatin1String(signature.left(signature.indexOf('('))));
            for (int i = 0; i < overloads.size(); ++i) {
                QMetaMethod mtd = meta->method(overloads.at(i));
                message.append(QString::fromLatin1("    %0\n").arg(QString::fromLatin1(mtd.signature())));
            }
            message.append(QString::fromLatin1("Use e.g. object['%0'].connect() to connect to a particular overload")
                           .arg(QLatin1String(signature)));
            return JSC::throwError(exec, JSC::GeneralError, message);
        }
    }

    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);

    JSC::JSValue receiver;
    JSC::JSValue slot;
    JSC::JSValue arg0 = args.at(0);
    if (args.size() < 2) {
        slot = arg0;
    } else {
        receiver = arg0;
        JSC::JSValue arg1 = args.at(1);
        if (isFunction(arg1))
            slot = arg1;
        else {
            QScript::SaveFrameHelper saveFrame(engine, exec);
            JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1);
            slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
        }
    }

    if (!isFunction(slot)) {
        return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: target is not a function");
    }

    bool ok = engine->scriptConnect(thisObject, receiver, slot, Qt::AutoConnection);
    if (!ok) {
        QString message = QString::fromLatin1("Function.prototype.connect: failed to connect to %0::%1")
                          .arg(QLatin1String(qtSignal->metaObject()->className()))
                          .arg(QLatin1String(sig.signature()));
        return JSC::throwError(exec, JSC::GeneralError, message);
    }
    return JSC::jsUndefined();
#else
    Q_UNUSED(eng);
    Q_UNUSED(classInfo);
    return context->throwError(QScriptContext::TypeError,
                               QLatin1String("Function.prototype.connect"));
#endif // QT_NO_QOBJECT
}

static JSC::JSValue JSC_HOST_CALL functionPrint(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionGC(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionVersion(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);

JSC::JSValue JSC_HOST_CALL functionPrint(JSC::ExecState* exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList& args)
{
    QString result;
    for (unsigned i = 0; i < args.size(); ++i) {
        if (i != 0)
            result.append(QLatin1Char(' '));
        QString s(args.at(i).toString(exec));
        if (exec->hadException())
            break;
        result.append(s);
    }
    if (exec->hadException())
        return exec->exception();
    qDebug("%s", qPrintable(result));
    return JSC::jsUndefined();
}

JSC::JSValue JSC_HOST_CALL functionGC(JSC::ExecState* exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    engine->collectGarbage();
    return JSC::jsUndefined();
}

JSC::JSValue JSC_HOST_CALL functionVersion(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&)
{
    return JSC::JSValue(exec, 1);
}

static JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionQsTranslateNoOp(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionQsTrNoOp(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionQsTrId(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
static JSC::JSValue JSC_HOST_CALL functionQsTrIdNoOp(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);

JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
{
    if (args.size() < 2)
        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate() requires at least two arguments");
    if (!args.at(0).isString())
        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): first argument (context) must be a string");
    if (!args.at(1).isString())
        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): second argument (text) must be a string");
    if ((args.size() > 2) && !args.at(2).isString())
        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (comment) must be a string");
    if ((args.size() > 3) && !args.at(3).isString())
        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fourth argument (encoding) must be a string");
    if ((args.size() > 4) && !args.at(4).isNumber())
        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fifth argument (n) must be a number");
#ifndef QT_NO_QOBJECT
    JSC::UString context = args.at(0).toString(exec);
#endif
    JSC::UString text = args.at(1).toString(exec);
#ifndef QT_NO_QOBJECT
    JSC::UString comment;
    if (args.size() > 2)
        comment = args.at(2).toString(exec);
    QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr;
    if (args.size() > 3) {
        JSC::UString encStr = args.at(3).toString(exec);
        if (encStr == "CodecForTr")
            encoding = QCoreApplication::CodecForTr;
        else if (encStr == "UnicodeUTF8")
            encoding = QCoreApplication::UnicodeUTF8;
        else
            return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr));
    }
    int n = -1;
    if (args.size() > 4)
        n = args.at(4).toInt32(exec);
#endif
    JSC::UString result;
#ifndef QT_NO_QOBJECT
    result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
                                         QScript::convertToLatin1(text).constData(),
                                         QScript::convertToLatin1(comment).constData(),
                                         encoding, n);
#else
    result = text;
#endif
    return JSC::jsString(exec, result);
}

JSC::JSValue JSC_HOST_CALL functionQsTranslateNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
{
    if (args.size() < 2)
        return JSC::jsUndefined();
    return args.at(1);
}

JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
{
    if (args.size() < 1)
        return JSC::throwError(exec, JSC::GeneralError, "qsTr() requires at least one argument");
    if (!args.at(0).isString())
        return JSC::throwError(exec, JSC::GeneralError, "qsTr(): first argument (text) must be a string");
    if ((args.size() > 1) && !args.at(1).isString())
        return JSC::throwError(exec, JSC::GeneralError, "qsTr(): second argument (comment) must be a string");
    if ((args.size() > 2) && !args.at(2).isNumber())
        return JSC::throwError(exec, JSC::GeneralError, "qsTr(): third argument (n) must be a number");
#ifndef QT_NO_QOBJECT
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    JSC::UString context;
    // The first non-empty source URL in the call stack determines the translation context.
    {
        JSC::ExecState *frame = exec->callerFrame()->removeHostCallFrameFlag();
        while (frame) {
            if (frame->codeBlock() && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)
                && frame->codeBlock()->source()
                && !frame->codeBlock()->source()->url().isEmpty()) {
                context = engine->translationContextFromUrl(frame->codeBlock()->source()->url());
                break;
            }
            frame = frame->callerFrame()->removeHostCallFrameFlag();
        }
    }
#endif
    JSC::UString text = args.at(0).toString(exec);
#ifndef QT_NO_QOBJECT
    JSC::UString comment;
    if (args.size() > 1)
        comment = args.at(1).toString(exec);
    int n = -1;
    if (args.size() > 2)
        n = args.at(2).toInt32(exec);
#endif
    JSC::UString result;
#ifndef QT_NO_QOBJECT
    result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
                                         QScript::convertToLatin1(text).constData(),
                                         QScript::convertToLatin1(comment).constData(),
                                         QCoreApplication::CodecForTr, n);
#else
    result = text;
#endif
    return JSC::jsString(exec, result);
}

JSC::JSValue JSC_HOST_CALL functionQsTrNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
{
    if (args.size() < 1)
        return JSC::jsUndefined();
    return args.at(0);
}

JSC::JSValue JSC_HOST_CALL functionQsTrId(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
{
    if (args.size() < 1)
        return JSC::throwError(exec, JSC::GeneralError, "qsTrId() requires at least one argument");
    if (!args.at(0).isString())
        return JSC::throwError(exec, JSC::TypeError, "qsTrId(): first argument (id) must be a string");
    if ((args.size() > 1) && !args.at(1).isNumber())
        return JSC::throwError(exec, JSC::TypeError, "qsTrId(): second argument (n) must be a number");
    JSC::UString id = args.at(0).toString(exec);
    int n = -1;
    if (args.size() > 1)
        n = args.at(1).toInt32(exec);
    return JSC::jsString(exec, qtTrId(QScript::convertToLatin1(id).constData(), n));
}

JSC::JSValue JSC_HOST_CALL functionQsTrIdNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
{
    if (args.size() < 1)
        return JSC::jsUndefined();
    return args.at(0);
}

static JSC::JSValue JSC_HOST_CALL stringProtoFuncArg(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);

JSC::JSValue JSC_HOST_CALL stringProtoFuncArg(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue thisObject, const JSC::ArgList &args)
{
    QString value(thisObject.toString(exec));
    JSC::JSValue arg = (args.size() != 0) ? args.at(0) : JSC::jsUndefined();
    QString result;
    if (arg.isString())
        result = value.arg(arg.toString(exec));
    else if (arg.isNumber())
        result = value.arg(arg.toNumber(exec));
    return JSC::jsString(exec, result);
}


#if !defined(QT_NO_QOBJECT) && !defined(QT_NO_LIBRARY)
static QScriptValue __setupPackage__(QScriptContext *ctx, QScriptEngine *eng)
{
    QString path = ctx->argument(0).toString();
    QStringList components = path.split(QLatin1Char('.'));
    QScriptValue o = eng->globalObject();
    for (int i = 0; i < components.count(); ++i) {
        QString name = components.at(i);
        QScriptValue oo = o.property(name);
        if (!oo.isValid()) {
            oo = eng->newObject();
            o.setProperty(name, oo);
        }
        o = oo;
    }
    return o;
}
#endif

} // namespace QScript

QScriptEnginePrivate::QScriptEnginePrivate()
    : originalGlobalObjectProxy(0), currentFrame(0),
      qobjectPrototype(0), qmetaobjectPrototype(0), variantPrototype(0),
      activeAgent(0), agentLineNumber(-1),
      registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0),
      registeredScriptStrings(0), processEventsInterval(-1), inEval(false)
{
    qMetaTypeId<QScriptValue>();
    qMetaTypeId<QList<int> >();
#ifndef QT_NO_QOBJECT
    qMetaTypeId<QObjectList>();
#endif

    if (!QCoreApplication::instance()) {
        qFatal("QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine");
        return;
    }
    JSC::initializeThreading();
    JSC::IdentifierTable *oldTable = JSC::currentIdentifierTable();
    globalData = JSC::JSGlobalData::create().releaseRef();
    globalData->clientData = new QScript::GlobalClientData(this);
    JSC::JSGlobalObject *globalObject = new (globalData)QScript::GlobalObject();

    JSC::ExecState* exec = globalObject->globalExec();

    scriptObjectStructure = QScriptObject::createStructure(globalObject->objectPrototype());
    staticScopeObjectStructure = QScriptStaticScopeObject::createStructure(JSC::jsNull());

    qobjectPrototype = new (exec) QScript::QObjectPrototype(exec, QScript::QObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure());
    qobjectWrapperObjectStructure = QScriptObject::createStructure(qobjectPrototype);

    qmetaobjectPrototype = new (exec) QScript::QMetaObjectPrototype(exec, QScript::QMetaObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure());
    qmetaobjectWrapperObjectStructure = QScript::QMetaObjectWrapperObject::createStructure(qmetaobjectPrototype);

    variantPrototype = new (exec) QScript::QVariantPrototype(exec, QScript::QVariantPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure());
    variantWrapperObjectStructure = QScriptObject::createStructure(variantPrototype);

    globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "print"), QScript::functionPrint));
    globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 0, JSC::Identifier(exec, "gc"), QScript::functionGC));
    globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 0, JSC::Identifier(exec, "version"), QScript::functionVersion));

    // ### rather than extending Function.prototype, consider creating a QtSignal.prototype
    globalObject->functionPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "disconnect"), QScript::functionDisconnect));
    globalObject->functionPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "connect"), QScript::functionConnect));

    JSC::TimeoutChecker* originalChecker = globalData->timeoutChecker;
    globalData->timeoutChecker = new QScript::TimeoutCheckerProxy(*originalChecker);
    delete originalChecker;

    currentFrame = exec;

    cachedTranslationUrl = JSC::UString();
    cachedTranslationContext = JSC::UString();
    JSC::setCurrentIdentifierTable(oldTable);
}

QScriptEnginePrivate::~QScriptEnginePrivate()
{
    QScript::APIShim shim(this);

    //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events
    QHash<intptr_t,QScript::UStringSourceProviderWithFeedback*>::const_iterator it;
    for (it = loadedScripts.constBegin(); it != loadedScripts.constEnd(); ++it)
        it.value()->disconnectFromEngine();

    while (!ownedAgents.isEmpty())
        delete ownedAgents.takeFirst();

    detachAllRegisteredScriptPrograms();
    detachAllRegisteredScriptValues();
    detachAllRegisteredScriptStrings();
    qDeleteAll(m_qobjectData);
    qDeleteAll(m_typeInfos);
    globalData->heap.destroy();
    globalData->deref();
    while (freeScriptValues) {
        QScriptValuePrivate *p = freeScriptValues;
        freeScriptValues = p->next;
        qFree(p);
    }
}

QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType)
{
    QVariant v(targetType, (void *)0);
    if (convertValue(exec, value, targetType, v.data()))
        return v;
    if (uint(targetType) == QVariant::LastType)
        return toVariant(exec, value);
    if (isVariant(value)) {
        v = variantValue(value);
        if (v.canConvert(QVariant::Type(targetType))) {
            v.convert(QVariant::Type(targetType));
            return v;
        }
        QByteArray typeName = v.typeName();
        if (typeName.endsWith('*')
            && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) {
            return QVariant(targetType, *reinterpret_cast<void* *>(v.data()));
        }
    }
    return QVariant();
}

JSC::JSValue QScriptEnginePrivate::arrayFromStringList(JSC::ExecState *exec, const QStringList &lst)
{
    JSC::JSValue arr =  newArray(exec, lst.size());
    for (int i = 0; i < lst.size(); ++i)
        setProperty(exec, arr, i, JSC::jsString(exec, lst.at(i)));
    return arr;
}

QStringList QScriptEnginePrivate::stringListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
{
    QStringList lst;
    uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
    for (uint i = 0; i < len; ++i)
        lst.append(toString(exec, property(exec, arr, i)));
    return lst;
}

JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, const QVariantList &lst)
{
    JSC::JSValue arr = newArray(exec, lst.size());
    for (int i = 0; i < lst.size(); ++i)
        setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i)));
    return arr;
}

QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSArray *arr)
{
    QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
    if (eng->visitedConversionObjects.contains(arr))
        return QVariantList(); // Avoid recursion.
    eng->visitedConversionObjects.insert(arr);
    QVariantList lst;
    uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
    for (uint i = 0; i < len; ++i)
        lst.append(toVariant(exec, property(exec, arr, i)));
    eng->visitedConversionObjects.remove(arr);
    return lst;
}

JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap)
{
    JSC::JSValue obj = JSC::constructEmptyObject(exec);
    QVariantMap::const_iterator it;
    for (it = vmap.constBegin(); it != vmap.constEnd(); ++it)
        setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value()));
    return obj;
}

QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSObject *obj)
{
    QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
    if (eng->visitedConversionObjects.contains(obj))
        return QVariantMap(); // Avoid recursion.
    eng->visitedConversionObjects.insert(obj);
    JSC::PropertyNameArray propertyNames(exec);
    obj->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
    QVariantMap vmap;
    JSC::PropertyNameArray::const_iterator it = propertyNames.begin();
    for( ; it != propertyNames.end(); ++it)
        vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it)));
    eng->visitedConversionObjects.remove(obj);
    return vmap;
}

JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const
{
    QScriptTypeInfo *info = m_typeInfos.value(metaTypeId);
    if (!info)
        return JSC::JSValue();
    return info->prototype;
}

void QScriptEnginePrivate::setDefaultPrototype(int metaTypeId, JSC::JSValue prototype)
{
    QScriptTypeInfo *info = m_typeInfos.value(metaTypeId);
    if (!info) {
        info = new QScriptTypeInfo();
        m_typeInfos.insert(metaTypeId, info);
    }
    info->prototype = prototype;
}

JSC::JSGlobalObject *QScriptEnginePrivate::originalGlobalObject() const
{
    return globalData->head;
}

JSC::JSObject *QScriptEnginePrivate::customGlobalObject() const
{
    QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject());
    return glob->customGlobalObject;
}

JSC::JSObject *QScriptEnginePrivate::getOriginalGlobalObjectProxy()
{
    if (!originalGlobalObjectProxy) {
        JSC::ExecState* exec = currentFrame;
        originalGlobalObjectProxy = new (exec)QScript::OriginalGlobalObjectProxy(scriptObjectStructure, originalGlobalObject());
    }
    return originalGlobalObjectProxy;
}

JSC::JSObject *QScriptEnginePrivate::globalObject() const
{
    QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject());
    if (glob->customGlobalObject)
        return glob->customGlobalObject;
    return glob;
}

void QScriptEnginePrivate::setGlobalObject(JSC::JSObject *object)
{
    if (object == globalObject())
        return;
    QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject());
    if (object == originalGlobalObjectProxy) {
        glob->customGlobalObject = 0;
        // Sync the internal prototype, since JSObject::prototype() is not virtual.
        glob->setPrototype(originalGlobalObjectProxy->prototype());
    } else {
        Q_ASSERT(object != originalGlobalObject());
        glob->customGlobalObject = object;
        // Sync the internal prototype, since JSObject::prototype() is not virtual.
        glob->setPrototype(object->prototype());
    }
}

/*!
  \internal

  If the given \a value is the original global object, returns the custom
  global object or a proxy to the original global object; otherwise returns \a
  value.
*/
JSC::JSValue QScriptEnginePrivate::toUsableValue(JSC::JSValue value)
{
    if (!value || !value.isObject() || !JSC::asObject(value)->isGlobalObject())
        return value;
    Q_ASSERT(JSC::asObject(value) == originalGlobalObject());
    if (customGlobalObject())
        return customGlobalObject();
    if (!originalGlobalObjectProxy)
        originalGlobalObjectProxy = new (currentFrame)QScript::OriginalGlobalObjectProxy(scriptObjectStructure, originalGlobalObject());
    return originalGlobalObjectProxy;
}
/*!
    \internal
    Return the 'this' value for a given context
*/
JSC::JSValue QScriptEnginePrivate::thisForContext(JSC::ExecState *frame)
{
    if (frame->codeBlock() != 0) {
        return frame->thisValue();
    } else if(frame == frame->lexicalGlobalObject()->globalExec()) {
        return frame->globalThisValue();
    } else {
        JSC::Register *thisRegister = thisRegisterForFrame(frame);
        return thisRegister->jsValue();
    }
}

JSC::Register* QScriptEnginePrivate::thisRegisterForFrame(JSC::ExecState *frame)
{
    Q_ASSERT(frame->codeBlock() == 0); // only for native calls
    return frame->registers() - JSC::RegisterFile::CallFrameHeaderSize - frame->argumentCount();
}

/*! \internal
     For native context, we use the ReturnValueRegister entry in the stackframe header to store flags.
     We can do that because this header is not used as the native function return their value thought C++

     when setting flags, NativeContext should always be set

     contextFlags returns 0 for non native context
 */
uint QScriptEnginePrivate::contextFlags(JSC::ExecState *exec)
{
    if (exec->codeBlock())
        return 0; //js function doesn't have flags

    return exec->returnValueRegister();
}

void QScriptEnginePrivate::setContextFlags(JSC::ExecState *exec, uint flags)
{
    Q_ASSERT(!exec->codeBlock());
    exec->registers()[JSC::RegisterFile::ReturnValueRegister] = JSC::Register::withInt(flags);
}


void QScriptEnginePrivate::mark(JSC::MarkStack& markStack)
{
    Q_Q(QScriptEngine);

    if (originalGlobalObject()) {
        markStack.append(originalGlobalObject());
        markStack.append(globalObject());
        if (originalGlobalObjectProxy)
            markStack.append(originalGlobalObjectProxy);
    }

    if (qobjectPrototype)
        markStack.append(qobjectPrototype);
    if (qmetaobjectPrototype)
        markStack.append(qmetaobjectPrototype);
    if (variantPrototype)
        markStack.append(variantPrototype);

    {
        QScriptValuePrivate *it;
        for (it = registeredScriptValues; it != 0; it = it->next) {
            if (it->isJSC())
                markStack.append(it->jscValue);
        }
    }

    {
        QHash<int, QScriptTypeInfo*>::const_iterator it;
        for (it = m_typeInfos.constBegin(); it != m_typeInfos.constEnd(); ++it) {
            if ((*it)->prototype)
                markStack.append((*it)->prototype);
        }
    }

    if (q) {
        QScriptContext *context = q->currentContext();

        while (context) {
            JSC::ScopeChainNode *node = frameForContext(context)->scopeChain();
            JSC::ScopeChainIterator it(node);
            for (it = node->begin(); it != node->end(); ++it) {
                JSC::JSObject *object = *it;
                if (object)
                    markStack.append(object);
            }

            context = context->parentContext();
        }
    }

#ifndef QT_NO_QOBJECT
    markStack.drain(); // make sure everything is marked before marking qobject data
    {
        QHash<QObject*, QScript::QObjectData*>::const_iterator it;
        for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) {
            QScript::QObjectData *qdata = it.value();
            qdata->mark(markStack);
        }
    }
#endif
}

bool QScriptEnginePrivate::isCollecting() const
{
    return globalData->heap.isBusy();
}

void QScriptEnginePrivate::collectGarbage()
{
    QScript::APIShim shim(this);
    globalData->heap.collectAllGarbage();
}

void QScriptEnginePrivate::reportAdditionalMemoryCost(int size)
{
    if (size > 0)
        globalData->heap.reportExtraMemoryCost(size);
}

QScript::TimeoutCheckerProxy *QScriptEnginePrivate::timeoutChecker() const
{
    return static_cast<QScript::TimeoutCheckerProxy*>(globalData->timeoutChecker);
}

void QScriptEnginePrivate::agentDeleted(QScriptEngineAgent *agent)
{
    ownedAgents.removeOne(agent);
    if (activeAgent == agent) {
        QScriptEngineAgentPrivate::get(agent)->detach();
        activeAgent = 0;
    }
}

JSC::JSValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, intptr_t sourceId,
                                                  JSC::EvalExecutable *executable,
                                                  bool &compile)
{
    Q_Q(QScriptEngine);
    QBoolBlocker inEvalBlocker(inEval, true);
    q->currentContext()->activationObject(); //force the creation of a context for native function;

    JSC::Debugger* debugger = originalGlobalObject()->debugger();
    if (debugger)
        debugger->evaluateStart(sourceId);

    q->clearExceptions();
    JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject);

    if (compile) {
        JSC::JSObject* error = executable->compile(exec, exec->scopeChain());
        if (error) {
            compile = false;
            exec->setException(error);

            if (debugger) {
                debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, error), sourceId, false);
                debugger->evaluateStop(error, sourceId);
            }

            return error;
        }
    }

    JSC::JSValue thisValue = thisForContext(exec);
    JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull())
                                ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
    JSC::JSValue exceptionValue;
    timeoutChecker()->setShouldAbort(false);
    if (processEventsInterval > 0)
        timeoutChecker()->reset();

    JSC::JSValue result = exec->interpreter()->execute(executable, exec, thisObject, exec->scopeChain(), &exceptionValue);

    if (timeoutChecker()->shouldAbort()) {
        if (abortResult.isError())
            exec->setException(scriptValueToJSCValue(abortResult));

        if (debugger)
            debugger->evaluateStop(scriptValueToJSCValue(abortResult), sourceId);

        return scriptValueToJSCValue(abortResult);
    }

    if (exceptionValue) {
        exec->setException(exceptionValue);

        if (debugger)
            debugger->evaluateStop(exceptionValue, sourceId);

        return exceptionValue;
    }

    if (debugger)
        debugger->evaluateStop(result, sourceId);

    Q_ASSERT(!exec->hadException());
    return result;
}

#ifndef QT_NO_QOBJECT

JSC::JSValue QScriptEnginePrivate::newQObject(
    QObject *object, QScriptEngine::ValueOwnership ownership,
    const QScriptEngine::QObjectWrapOptions &options)
{
    if (!object)
        return JSC::jsNull();
    JSC::ExecState* exec = currentFrame;
    QScript::QObjectData *data = qobjectData(object);
    bool preferExisting = (options & QScriptEngine::PreferExistingWrapperObject) != 0;
    QScriptEngine::QObjectWrapOptions opt = options & ~QScriptEngine::PreferExistingWrapperObject;
    QScriptObject *result = 0;
    if (preferExisting) {
        result = data->findWrapper(ownership, opt);
        if (result)
            return result;
    }
    result = new (exec) QScriptObject(qobjectWrapperObjectStructure);
    if (preferExisting)
        data->registerWrapper(result, ownership, opt);
    result->setDelegate(new QScript::QObjectDelegate(object, ownership, options));
    /*if (setDefaultPrototype)*/ {
        const QMetaObject *meta = object->metaObject();
        while (meta) {
            QByteArray typeString = meta->className();
            typeString.append('*');
            int typeId = QMetaType::type(typeString);
            if (typeId != 0) {
                JSC::JSValue proto = defaultPrototype(typeId);
                if (proto) {
                    result->setPrototype(proto);
                    break;
                }
            }
            meta = meta->superClass();
        }
    }
    return result;
}

JSC::JSValue QScriptEnginePrivate::newQMetaObject(
    const QMetaObject *metaObject, JSC::JSValue ctor)
{
    if (!metaObject)
        return JSC::jsNull();
    JSC::ExecState* exec = currentFrame;
    QScript::QMetaObjectWrapperObject *result = new (exec) QScript::QMetaObjectWrapperObject(exec, metaObject, ctor, qmetaobjectWrapperObjectStructure);
    return result;
}

bool QScriptEnginePrivate::convertToNativeQObject(JSC::ExecState *exec, JSC::JSValue value,
                                                  const QByteArray &targetType,
                                                  void **result)
{
    if (!targetType.endsWith('*'))
        return false;
    if (QObject *qobject = toQObject(exec, value)) {
        int start = targetType.startsWith("const ") ? 6 : 0;
        QByteArray className = targetType.mid(start, targetType.size()-start-1);
        if (void *instance = qobject->qt_metacast(className)) {
            *result = instance;
            return true;
        }
    }
    return false;
}

QScript::QObjectData *QScriptEnginePrivate::qobjectData(QObject *object)
{
    QHash<QObject*, QScript::QObjectData*>::const_iterator it;
    it = m_qobjectData.constFind(object);
    if (it != m_qobjectData.constEnd())
        return it.value();

    QScript::QObjectData *data = new QScript::QObjectData(this);
    m_qobjectData.insert(object, data);
    QObject::connect(object, SIGNAL(destroyed(QObject*)),
                     q_func(), SLOT(_q_objectDestroyed(QObject*)));
    return data;
}

void QScriptEnginePrivate::_q_objectDestroyed(QObject *object)
{
    QHash<QObject*, QScript::QObjectData*>::iterator it;
    it = m_qobjectData.find(object);
    Q_ASSERT(it != m_qobjectData.end());
    QScript::QObjectData *data = it.value();
    m_qobjectData.erase(it);
    delete data;
}

void QScriptEnginePrivate::disposeQObject(QObject *object)
{
    // TODO
/*    if (isCollecting()) {
        // wait until we're done with GC before deleting it
        int index = m_qobjectsToBeDeleted.indexOf(object);
        if (index == -1)
            m_qobjectsToBeDeleted.append(object);
            } else*/ {
        delete object;
    }
}

void QScriptEnginePrivate::emitSignalHandlerException()
{
    Q_Q(QScriptEngine);
    emit q->signalHandlerException(q->uncaughtException());
}

bool QScriptEnginePrivate::scriptConnect(QObject *sender, const char *signal,
                                         JSC::JSValue receiver, JSC::JSValue function,
                                         Qt::ConnectionType type)
{
    Q_ASSERT(sender);
    Q_ASSERT(signal);
    const QMetaObject *meta = sender->metaObject();
    int index = meta->indexOfSignal(QMetaObject::normalizedSignature(signal+1));
    if (index == -1)
        return false;
    return scriptConnect(sender, index, receiver, function, /*wrapper=*/JSC::JSValue(), type);
}

bool QScriptEnginePrivate::scriptDisconnect(QObject *sender, const char *signal,
                                            JSC::JSValue receiver, JSC::JSValue function)
{
    Q_ASSERT(sender);
    Q_ASSERT(signal);
    const QMetaObject *meta = sender->metaObject();
    int index = meta->indexOfSignal(QMetaObject::normalizedSignature(signal+1));
    if (index == -1)
        return false;
    return scriptDisconnect(sender, index, receiver, function);
}

bool QScriptEnginePrivate::scriptConnect(QObject *sender, int signalIndex,
                                         JSC::JSValue receiver, JSC::JSValue function,
                                         JSC::JSValue senderWrapper,
                                         Qt::ConnectionType type)
{
    QScript::QObjectData *data = qobjectData(sender);
    return data->addSignalHandler(sender, signalIndex, receiver, function, senderWrapper, type);
}

bool QScriptEnginePrivate::scriptDisconnect(QObject *sender, int signalIndex,
                                            JSC::JSValue receiver, JSC::JSValue function)
{
    QScript::QObjectData *data = qobjectData(sender);
    if (!data)
        return false;
    return data->removeSignalHandler(sender, signalIndex, receiver, function);
}

bool QScriptEnginePrivate::scriptConnect(JSC::JSValue signal, JSC::JSValue receiver,
                                         JSC::JSValue function, Qt::ConnectionType type)
{
    QScript::QtFunction *fun = static_cast<QScript::QtFunction*>(JSC::asObject(signal));
    int index = fun->mostGeneralMethod();
    return scriptConnect(fun->qobject(), index, receiver, function, fun->wrapperObject(), type);
}

bool QScriptEnginePrivate::scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver,
                                            JSC::JSValue function)
{
    QScript::QtFunction *fun = static_cast<QScript::QtFunction*>(JSC::asObject(signal));
    int index = fun->mostGeneralMethod();
    return scriptDisconnect(fun->qobject(), index, receiver, function);
}

#endif

void QScriptEnginePrivate::detachAllRegisteredScriptPrograms()
{
    QSet<QScriptProgramPrivate*>::const_iterator it;
    for (it = registeredScriptPrograms.constBegin(); it != registeredScriptPrograms.constEnd(); ++it)
        (*it)->detachFromEngine();
    registeredScriptPrograms.clear();
}

void QScriptEnginePrivate::detachAllRegisteredScriptValues()
{
    QScriptValuePrivate *it;
    QScriptValuePrivate *next;
    for (it = registeredScriptValues; it != 0; it = next) {
        it->detachFromEngine();
        next = it->next;
        it->prev = 0;
        it->next = 0;
    }
    registeredScriptValues = 0;
}

void QScriptEnginePrivate::detachAllRegisteredScriptStrings()
{
    QScriptStringPrivate *it;
    QScriptStringPrivate *next;
    for (it = registeredScriptStrings; it != 0; it = next) {
        it->detachFromEngine();
        next = it->next;
        it->prev = 0;
        it->next = 0;
    }
    registeredScriptStrings = 0;
}

#ifndef QT_NO_REGEXP

Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);

JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp &regexp)
{
    JSC::JSValue buf[2];
    JSC::ArgList args(buf, sizeof(buf));

    //convert the pattern to a ECMAScript pattern
    QString pattern = qt_regexp_toCanonical(regexp.pattern(), regexp.patternSyntax());
    if (regexp.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;
    }

    JSC::UString jscPattern = pattern;
    QString flags;
    if (regexp.caseSensitivity() == Qt::CaseInsensitive)
        flags.append(QLatin1Char('i'));
    JSC::UString jscFlags = flags;
    buf[0] = JSC::jsString(exec, jscPattern);
    buf[1] = JSC::jsString(exec, jscFlags);
    return JSC::constructRegExp(exec, args);
}

#endif

JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QString &pattern, const QString &flags)
{
    JSC::JSValue buf[2];
    JSC::ArgList args(buf, sizeof(buf));
    JSC::UString jscPattern = pattern;
    QString strippedFlags;
    if (flags.contains(QLatin1Char('i')))
        strippedFlags += QLatin1Char('i');
    if (flags.contains(QLatin1Char('m')))
        strippedFlags += QLatin1Char('m');
    if (flags.contains(QLatin1Char('g')))
        strippedFlags += QLatin1Char('g');
    JSC::UString jscFlags = strippedFlags;
    buf[0] = JSC::jsString(exec, jscPattern);
    buf[1] = JSC::jsString(exec, jscFlags);
    return JSC::constructRegExp(exec, args);
}

JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value)
{
    QScriptObject *obj = new (currentFrame) QScriptObject(variantWrapperObjectStructure);
    obj->setDelegate(new QScript::QVariantDelegate(value));
    JSC::JSValue proto = defaultPrototype(value.userType());
    if (proto)
        obj->setPrototype(proto);
    return obj;
}

JSC::JSValue QScriptEnginePrivate::newVariant(JSC::JSValue objectValue,
                                              const QVariant &value)
{
    if (!isObject(objectValue))
        return newVariant(value);
    JSC::JSObject *jscObject = JSC::asObject(objectValue);
    if (!jscObject->inherits(&QScriptObject::info)) {
        qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
        return JSC::JSValue();
    }
    QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
    if (!isVariant(objectValue)) {
        jscScriptObject->setDelegate(new QScript::QVariantDelegate(value));
    } else {
        setVariantValue(objectValue, value);
    }
    return objectValue;
}

#ifndef QT_NO_REGEXP

QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value)
{
    if (!isRegExp(value))
        return QRegExp();
    QString pattern = toString(exec, property(exec, value, "source", QScriptValue::ResolvePrototype));
    Qt::CaseSensitivity kase = Qt::CaseSensitive;
    if (toBool(exec, property(exec, value, "ignoreCase", QScriptValue::ResolvePrototype)))
        kase = Qt::CaseInsensitive;
    return QRegExp(pattern, kase, QRegExp::RegExp2);
}

#endif

QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue value)
{
    if (!value) {
        return QVariant();
    } else if (isObject(value)) {
        if (isVariant(value))
            return variantValue(value);
#ifndef QT_NO_QOBJECT
        else if (isQObject(value))
            return qVariantFromValue(toQObject(exec, value));
#endif
        else if (isDate(value))
            return QVariant(toDateTime(exec, value));
#ifndef QT_NO_REGEXP
        else if (isRegExp(value))
            return QVariant(toRegExp(exec, value));
#endif
        else if (isArray(value))
            return variantListFromArray(exec, JSC::asArray(value));
        else if (QScriptDeclarativeClass *dc = declarativeClass(value))
            return dc->toVariant(declarativeObject(value));
        return variantMapFromObject(exec, JSC::asObject(value));
    } else if (value.isNumber()) {
        return QVariant(toNumber(exec, value));
    } else if (value.isString()) {
        return QVariant(toString(exec, value));
    } else if (value.isBoolean()) {
        return QVariant(toBool(exec, value));
    }
    return QVariant();
}

JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode)
{
    JSC::JSValue result;
    if (!(resolveMode & QScriptValue::ResolvePrototype)) {
        // Look in the object's own properties
        JSC::JSObject *object = JSC::asObject(value);
        JSC::PropertySlot slot(object);
        if (object->getOwnPropertySlot(exec, id, slot))
            result = slot.getValue(exec, id);
    }
    if (!result && (resolveMode & QScriptValue::ResolveScope)) {
        // ### check if it's a function object and look in the scope chain
        JSC::JSValue scope = property(exec, value, "__qt_scope__", QScriptValue::ResolveLocal);
        if (isObject(scope))
            result = property(exec, scope, id, resolveMode);
    }
    return result;
}

JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode)
{
    JSC::JSValue result;
    if (!(resolveMode & QScriptValue::ResolvePrototype)) {
        // Look in the object's own properties
        JSC::JSObject *object = JSC::asObject(value);
        JSC::PropertySlot slot(object);
        if (object->getOwnPropertySlot(exec, index, slot))
            result = slot.getValue(exec, index);
    }
    return result;
}

void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::Identifier &id,
                                       JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
{
    JSC::JSObject *thisObject = JSC::asObject(objectValue);
    JSC::JSValue setter = thisObject->lookupSetter(exec, id);
    JSC::JSValue getter = thisObject->lookupGetter(exec, id);
    if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
        if (!value) {
            // deleting getter/setter
            if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) {
                // deleting both: just delete the property
                thisObject->deleteProperty(exec, id);
            } else if (flags & QScriptValue::PropertyGetter) {
                // preserve setter, if there is one
                thisObject->deleteProperty(exec, id);
                if (setter && setter.isObject())
                    thisObject->defineSetter(exec, id, JSC::asObject(setter));
            } else { // flags & QScriptValue::PropertySetter
                // preserve getter, if there is one
                thisObject->deleteProperty(exec, id);
                if (getter && getter.isObject())
                    thisObject->defineGetter(exec, id, JSC::asObject(getter));
            }
        } else {
            if (value.isObject()) { // ### should check if it has callData()
                // defining getter/setter
                if (id == exec->propertyNames().underscoreProto) {
                    qWarning("QScriptValue::setProperty() failed: "
                             "cannot set getter or setter of native property `__proto__'");
                } else {
                    if (flags & QScriptValue::PropertyGetter)
                        thisObject->defineGetter(exec, id, JSC::asObject(value));
                    if (flags & QScriptValue::PropertySetter)
                        thisObject->defineSetter(exec, id, JSC::asObject(value));
                }
            } else {
                qWarning("QScriptValue::setProperty(): getter/setter must be a function");
            }
        }
    } else {
        // setting the value
        if (getter && getter.isObject() && !(setter && setter.isObject())) {
            qWarning("QScriptValue::setProperty() failed: "
                     "property '%s' has a getter but no setter",
                     qPrintable(QString(id.ustring())));
            return;
        }
        if (!value) {
            // ### check if it's a getter/setter property
            thisObject->deleteProperty(exec, id);
        } else if (flags != QScriptValue::KeepExistingFlags) {
            if (thisObject->hasOwnProperty(exec, id))
                thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes?
            thisObject->putWithAttributes(exec, id, value, propertyFlagsToJSCAttributes(flags));
        } else {
            JSC::PutPropertySlot slot;
            thisObject->put(exec, id, value, slot);
        }
    }
}

void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, quint32 index,
                                       JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
{
    if (!value) {
        JSC::asObject(objectValue)->deleteProperty(exec, index);
    } else {
        if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
            // fall back to string-based setProperty(), since there is no
            // JSC::JSObject::defineGetter(unsigned)
            setProperty(exec, objectValue, JSC::Identifier::from(exec, index), value, flags);
        } else {
            if (flags != QScriptValue::KeepExistingFlags) {
                //                if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex))
                //                    JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex);
                unsigned attribs = 0;
                if (flags & QScriptValue::ReadOnly)
                    attribs |= JSC::ReadOnly;
                if (flags & QScriptValue::SkipInEnumeration)
                    attribs |= JSC::DontEnum;
                if (flags & QScriptValue::Undeletable)
                    attribs |= JSC::DontDelete;
                attribs |= flags & QScriptValue::UserRange;
                JSC::asObject(objectValue)->putWithAttributes(exec, index, value, attribs);
            } else {
                JSC::asObject(objectValue)->put(exec, index, value);
            }
        }
    }
}

QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id,
                                                                const QScriptValue::ResolveFlags &mode)
{
    JSC::JSObject *object = JSC::asObject(value);
    unsigned attribs = 0;
    JSC::PropertyDescriptor descriptor;
    if (object->getOwnPropertyDescriptor(exec, id, descriptor))
        attribs = descriptor.attributes();
    else {
        if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
            JSC::JSValue proto = object->prototype();
            return propertyFlags(exec, proto, id, mode);
        }
        return 0;
    }
    QScriptValue::PropertyFlags result = 0;
    if (attribs & JSC::ReadOnly)
        result |= QScriptValue::ReadOnly;
    if (attribs & JSC::DontEnum)
        result |= QScriptValue::SkipInEnumeration;
    if (attribs & JSC::DontDelete)
        result |= QScriptValue::Undeletable;
    //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?)
    if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull())
        result |= QScriptValue::PropertyGetter;
    if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull())
        result |= QScriptValue::PropertySetter;
#ifndef QT_NO_QOBJECT
    if (attribs & QScript::QObjectMemberAttribute)
        result |= QScriptValue::QObjectMember;
#endif
    result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange);
    return result;
}

QScriptString QScriptEnginePrivate::toStringHandle(const JSC::Identifier &name)
{
    QScriptString result;
    QScriptStringPrivate *p = new QScriptStringPrivate(this, name, QScriptStringPrivate::HeapAllocated);
    QScriptStringPrivate::init(result, p);
    registerScriptString(p);
    return result;
}

#ifdef QT_NO_QOBJECT

QScriptEngine::QScriptEngine()
    : d_ptr(new QScriptEnginePrivate)
{
    d_ptr->q_ptr = this;
}

/*! \internal
*/
QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd)
    : d_ptr(&dd)
{
    d_ptr->q_ptr = this;
}
#else

/*!
    Constructs a QScriptEngine object.

    The globalObject() is initialized to have properties as described in
    \l{ECMA-262}, Section 15.1.
*/
QScriptEngine::QScriptEngine()
    : QObject(*new QScriptEnginePrivate, 0)
{
}

/*!
    Constructs a QScriptEngine object with the given \a parent.

    The globalObject() is initialized to have properties as described in
    \l{ECMA-262}, Section 15.1.
*/

QScriptEngine::QScriptEngine(QObject *parent)
    : QObject(*new QScriptEnginePrivate, parent)
{
}

/*! \internal
*/
QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent)
    : QObject(dd, parent)
{
}
#endif

/*!
  Destroys this QScriptEngine.
*/
QScriptEngine::~QScriptEngine()
{
#ifdef QT_NO_QOBJECT
    delete d_ptr;
    d_ptr = 0;
#endif
}

/*!
  Returns this engine's Global Object.

  By default, the Global Object contains the built-in objects that are
  part of \l{ECMA-262}, such as Math, Date and String. Additionally,
  you can set properties of the Global Object to make your own
  extensions available to all script code. Non-local variables in
  script code will be created as properties of the Global Object, as
  well as local variables in global code.
*/
QScriptValue QScriptEngine::globalObject() const
{
    Q_D(const QScriptEngine);
    QScript::APIShim shim(const_cast<QScriptEnginePrivate*>(d));
    JSC::JSObject *result = d->globalObject();
    return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result);
}

/*!
  \since 4.5

  Sets this engine's Global Object to be the given \a object.
  If \a object is not a valid script object, this function does
  nothing.

  When setting a custom global object, you may want to use
  QScriptValueIterator to copy the properties of the standard Global
  Object; alternatively, you can set the internal prototype of your
  custom object to be the original Global Object.
*/
void QScriptEngine::setGlobalObject(const QScriptValue &object)
{
    Q_D(QScriptEngine);
    if (!object.isObject())
        return;
    QScript::APIShim shim(d);
    JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object));
    d->setGlobalObject(jscObject);
}

/*!
  Returns a QScriptValue of the primitive type Null.

  \sa undefinedValue()
*/
QScriptValue QScriptEngine::nullValue()
{
    Q_D(QScriptEngine);
    return d->scriptValueFromJSCValue(JSC::jsNull());
}

/*!
  Returns a QScriptValue of the primitive type Undefined.

  \sa nullValue()
*/
QScriptValue QScriptEngine::undefinedValue()
{
    Q_D(QScriptEngine);
    return d->scriptValueFromJSCValue(JSC::jsUndefined());
}

/*!
  Creates a constructor function from \a fun, with the given \a length.
  The \c{prototype} property of the resulting function is set to be the
  given \a prototype. The \c{constructor} property of \a prototype is
  set to be the resulting function.

  When a function is called as a constructor (e.g. \c{new Foo()}), the
  `this' object associated with the function call is the new object
  that the function is expected to initialize; the prototype of this
  default constructed object will be the function's public
  \c{prototype} property. If you always want the function to behave as
  a constructor (e.g. \c{Foo()} should also create a new object), or
  if you need to create your own object rather than using the default
  `this' object, you should make sure that the prototype of your
  object is set correctly; either by setting it manually, or, when
  wrapping a custom type, by having registered the defaultPrototype()
  of that type. Example:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9

  To wrap a custom type and provide a constructor for it, you'd typically
  do something like this:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
*/
QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun,
                                        const QScriptValue &prototype,
                                        int length)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::ExecState* exec = d->currentFrame;
    JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
    QScriptValue result = d->scriptValueFromJSCValue(function);
    result.setProperty(QLatin1String("prototype"), prototype, QScriptValue::Undeletable);
    const_cast<QScriptValue&>(prototype)
        .setProperty(QLatin1String("constructor"), result,
                     QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    return result;
}

#ifndef QT_NO_REGEXP

/*!
  Creates a QtScript object of class RegExp with the given
  \a regexp.

  \sa QScriptValue::toRegExp()
*/
QScriptValue QScriptEngine::newRegExp(const QRegExp &regexp)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, regexp));
}

#endif // QT_NO_REGEXP

/*!
  Creates a QtScript object holding the given variant \a value.

  If a default prototype has been registered with the meta type id of
  \a value, then the prototype of the created object will be that
  prototype; otherwise, the prototype will be the Object prototype
  object.

  \sa setDefaultPrototype(), QScriptValue::toVariant(), reportAdditionalMemoryCost()
*/
QScriptValue QScriptEngine::newVariant(const QVariant &value)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->newVariant(value));
}

/*!
  \since 4.4
  \overload

  Initializes the given Qt Script \a object to hold the given variant
  \a value, and returns the \a object.

  This function enables you to "promote" a plain Qt Script object
  (created by the newObject() function) to a variant, or to replace
  the variant contained inside an object previously created by the
  newVariant() function.

  The prototype() of the \a object will remain unchanged.

  If \a object is not an object, this function behaves like the normal
  newVariant(), i.e. it creates a new script object and returns it.

  This function is useful when you want to provide a script
  constructor for a C++ type. If your constructor is invoked in a
  \c{new} expression (QScriptContext::isCalledAsConstructor() returns
  true), you can pass QScriptContext::thisObject() (the default
  constructed script object) to this function to initialize the new
  object.

  \sa reportAdditionalMemoryCost()
*/
QScriptValue QScriptEngine::newVariant(const QScriptValue &object,
                                       const QVariant &value)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::JSValue jsObject = d->scriptValueToJSCValue(object);
    return d->scriptValueFromJSCValue(d->newVariant(jsObject, value));
}

#ifndef QT_NO_QOBJECT
/*!
  Creates a QtScript object that wraps the given QObject \a
  object, using the given \a ownership. The given \a options control
  various aspects of the interaction with the resulting script object.

  Signals and slots, properties and children of \a object are
  available as properties of the created QScriptValue. For more
  information, see the \l{QtScript} documentation.

  If \a object is a null pointer, this function returns nullValue().

  If a default prototype has been registered for the \a object's class
  (or its superclass, recursively), the prototype of the new script
  object will be set to be that default prototype.

  If the given \a object is deleted outside of QtScript's control, any
  attempt to access the deleted QObject's members through the QtScript
  wrapper object (either by script code or C++) will result in a
  script exception.

  \sa QScriptValue::toQObject(), reportAdditionalMemoryCost()
*/
QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership,
                                       const QObjectWrapOptions &options)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::JSValue jscQObject = d->newQObject(object, ownership, options);
    return d->scriptValueFromJSCValue(jscQObject);
}

/*!
  \since 4.4
  \overload

  Initializes the given \a scriptObject to hold the given \a qtObject,
  and returns the \a scriptObject.

  This function enables you to "promote" a plain Qt Script object
  (created by the newObject() function) to a QObject proxy, or to
  replace the QObject contained inside an object previously created by
  the newQObject() function.

  The prototype() of the \a scriptObject will remain unchanged.

  If \a scriptObject is not an object, this function behaves like the
  normal newQObject(), i.e. it creates a new script object and returns
  it.

  This function is useful when you want to provide a script
  constructor for a QObject-based class. If your constructor is
  invoked in a \c{new} expression
  (QScriptContext::isCalledAsConstructor() returns true), you can pass
  QScriptContext::thisObject() (the default constructed script object)
  to this function to initialize the new object.

  \sa reportAdditionalMemoryCost()
*/
QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject,
                                       QObject *qtObject,
                                       ValueOwnership ownership,
                                       const QObjectWrapOptions &options)
{
    Q_D(QScriptEngine);
    if (!scriptObject.isObject())
        return newQObject(qtObject, ownership, options);
    QScript::APIShim shim(d);
    JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue);
    if (!jscObject->inherits(&QScriptObject::info)) {
        qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported");
        return QScriptValue();
    }
    QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
    if (!scriptObject.isQObject()) {
        jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options));
    } else {
        QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate());
        delegate->setValue(qtObject);
        delegate->setOwnership(ownership);
        delegate->setOptions(options);
    }
    return scriptObject;
}

#endif // QT_NO_QOBJECT

/*!
  Creates a QtScript object of class Object.

  The prototype of the created object will be the Object
  prototype object.

  \sa newArray(), QScriptValue::setProperty()
*/
QScriptValue QScriptEngine::newObject()
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->newObject());
}

/*!
  \since 4.4
  \overload

  Creates a QtScript Object of the given class, \a scriptClass.

  The prototype of the created object will be the Object
  prototype object.

  \a data, if specified, is set as the internal data of the
  new object (using QScriptValue::setData()).

  \sa QScriptValue::scriptClass(), reportAdditionalMemoryCost()
*/
QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass,
                                      const QScriptValue &data)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::ExecState* exec = d->currentFrame;
    QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure);
    result->setDelegate(new QScript::ClassObjectDelegate(scriptClass));
    QScriptValue scriptObject = d->scriptValueFromJSCValue(result);
    scriptObject.setData(data);
    QScriptValue proto = scriptClass->prototype();
    if (proto.isValid())
        scriptObject.setPrototype(proto);
    return scriptObject;
}

/*!
  \internal
*/
QScriptValue QScriptEngine::newActivationObject()
{
    qWarning("QScriptEngine::newActivationObject() not implemented");
    // ### JSActivation or JSVariableObject?
    return QScriptValue();
}

/*!
  Creates a QScriptValue that wraps a native (C++) function. \a fun
  must be a C++ function with signature QScriptEngine::FunctionSignature.  \a
  length is the number of arguments that \a fun expects; this becomes
  the \c{length} property of the created QScriptValue.

  Note that \a length only gives an indication of the number of
  arguments that the function expects; an actual invocation of a
  function can include any number of arguments. You can check the
  \l{QScriptContext::argumentCount()}{argumentCount()} of the
  QScriptContext associated with the invocation to determine the
  actual number of arguments passed.

  A \c{prototype} property is automatically created for the resulting
  function object, to provide for the possibility that the function
  will be used as a constructor.

  By combining newFunction() and the property flags
  QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
  can create script object properties that behave like normal
  properties in script code, but are in fact accessed through
  functions (analogous to how properties work in \l{Qt's Property
  System}). Example:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11

  When the property \c{foo} of the script object is subsequently
  accessed in script code, \c{getSetFoo()} will be invoked to handle
  the access.  In this particular case, we chose to store the "real"
  value of \c{foo} as a property of the accessor function itself; you
  are of course free to do whatever you like in this function.

  In the above example, a single native function was used to handle
  both reads and writes to the property; the argument count is used to
  determine if we are handling a read or write. You can also use two
  separate functions; just specify the relevant flag
  (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
  setting the property, e.g.:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12

  \sa QScriptValue::call()
*/
QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::ExecState* exec = d->currentFrame;
    JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
    QScriptValue result = d->scriptValueFromJSCValue(function);
    QScriptValue proto = newObject();
    result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
    proto.setProperty(QLatin1String("constructor"), result,
                      QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    return result;
}

/*!
  \internal
  \since 4.4
*/
QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::ExecState* exec = d->currentFrame;
    JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg);
    QScriptValue result = d->scriptValueFromJSCValue(function);
    QScriptValue proto = newObject();
    result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
    proto.setProperty(QLatin1String("constructor"), result,
                      QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    return result;
}

/*!
  Creates a QtScript object of class Array with the given \a length.

  \sa newObject()
*/
QScriptValue QScriptEngine::newArray(uint length)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->newArray(d->currentFrame, length));
}

/*!
  Creates a QtScript object of class RegExp with the given
  \a pattern and \a flags.

  The legal flags are 'g' (global), 'i' (ignore case), and 'm'
  (multiline).
*/
QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, pattern, flags));
}

/*!
  Creates a QtScript object of class Date with the given
  \a value (the number of milliseconds since 01 January 1970,
  UTC).
*/
QScriptValue QScriptEngine::newDate(qsreal value)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value));
}

/*!
  Creates a QtScript object of class Date from the given \a value.

  \sa QScriptValue::toDateTime()
*/
QScriptValue QScriptEngine::newDate(const QDateTime &value)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value));
}

#ifndef QT_NO_QOBJECT
/*!
  Creates a QtScript object that represents a QObject class, using the
  the given \a metaObject and constructor \a ctor.

  Enums of \a metaObject (declared with Q_ENUMS) are available as
  properties of the created QScriptValue. When the class is called as
  a function, \a ctor will be called to create a new instance of the
  class.

  Example:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 27

  \sa newQObject(), scriptValueFromQMetaObject()
*/
QScriptValue QScriptEngine::newQMetaObject(
    const QMetaObject *metaObject, const QScriptValue &ctor)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::JSValue jscCtor = d->scriptValueToJSCValue(ctor);
    JSC::JSValue jscQMetaObject = d->newQMetaObject(metaObject, jscCtor);
    return d->scriptValueFromJSCValue(jscQMetaObject);
}

/*!
  \fn QScriptValue QScriptEngine::scriptValueFromQMetaObject()

  Creates a QScriptValue that represents the Qt class \c{T}.

  This function is used in combination with one of the
  Q_SCRIPT_DECLARE_QMETAOBJECT() macro. Example:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 13

  \warning This function is not available with MSVC 6. Use
  qScriptValueFromQMetaObject() instead if you need to support that version
  of the compiler.

  \sa QScriptEngine::newQMetaObject()
*/

/*!
  \fn QScriptValue qScriptValueFromQMetaObject(QScriptEngine *engine)
  \since 4.3
  \relates QScriptEngine

  Uses \a engine to create a QScriptValue that represents the Qt class
  \c{T}.

  This function is equivalent to
  QScriptEngine::scriptValueFromQMetaObject(). It is provided as a
  work-around for MSVC 6, which doesn't support member template
  functions.

  \sa QScriptEngine::newQMetaObject()
*/
#endif // QT_NO_QOBJECT

/*!
  \obsolete

  Returns true if \a program can be evaluated; i.e. the code is
  sufficient to determine whether it appears to be a syntactically
  correct program, or contains a syntax error.

  This function returns false if \a program is incomplete; i.e. the
  input is syntactically correct up to the point where the input is
  terminated.

  Note that this function only does a static check of \a program;
  e.g. it does not check whether references to variables are
  valid, and so on.

  A typical usage of canEvaluate() is to implement an interactive
  interpreter for QtScript. The user is repeatedly queried for
  individual lines of code; the lines are concatened internally, and
  only when canEvaluate() returns true for the resulting program is it
  passed to evaluate().

  The following are some examples to illustrate the behavior of
  canEvaluate(). (Note that all example inputs are assumed to have an
  explicit newline as their last character, since otherwise the
  QtScript parser would automatically insert a semi-colon character at
  the end of the input, and this could cause canEvaluate() to produce
  different results.)

  Given the input
  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 14
  canEvaluate() will return true, since the program appears to be complete.

  Given the input
  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 15
  canEvaluate() will return false, since the if-statement is not complete,
  but is syntactically correct so far.

  Given the input
  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 16
  canEvaluate() will return true, but evaluate() will throw a
  SyntaxError given the same input.

  Given the input
  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 17
  canEvaluate() will return true, even though the code is clearly not
  syntactically valid QtScript code. evaluate() will throw a
  SyntaxError when this code is evaluated.

  Given the input
  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 18
  canEvaluate() will return true, but evaluate() will throw a
  ReferenceError if \c{foo} is not defined in the script
  environment.

  \sa evaluate(), checkSyntax()
*/
bool QScriptEngine::canEvaluate(const QString &program) const
{
    return QScriptEnginePrivate::canEvaluate(program);
}


bool QScriptEnginePrivate::canEvaluate(const QString &program)
{
    QScript::SyntaxChecker checker;
    QScript::SyntaxChecker::Result result = checker.checkSyntax(program);
    return (result.state != QScript::SyntaxChecker::Intermediate);
}

/*!
  \since 4.5

  Checks the syntax of the given \a program. Returns a
  QScriptSyntaxCheckResult object that contains the result of the check.
*/
QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program)
{
    return QScriptEnginePrivate::checkSyntax(program);
}

QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &program)
{
    QScript::SyntaxChecker checker;
    QScript::SyntaxChecker::Result result = checker.checkSyntax(program);
    QScriptSyntaxCheckResultPrivate *p = new QScriptSyntaxCheckResultPrivate();
    switch (result.state) {
    case QScript::SyntaxChecker::Error:
        p->state = QScriptSyntaxCheckResult::Error;
        break;
    case QScript::SyntaxChecker::Intermediate:
        p->state = QScriptSyntaxCheckResult::Intermediate;
        break;
    case QScript::SyntaxChecker::Valid:
        p->state = QScriptSyntaxCheckResult::Valid;
        break;
    }
    p->errorLineNumber = result.errorLineNumber;
    p->errorColumnNumber = result.errorColumnNumber;
    p->errorMessage = result.errorMessage;
    return QScriptSyntaxCheckResult(p);
}



/*!
  Evaluates \a program, using \a lineNumber as the base line number,
  and returns the result of the evaluation.

  The script code will be evaluated in the current context.

  The evaluation of \a program can cause an exception in the
  engine; in this case the return value will be the exception
  that was thrown (typically an \c{Error} object). You can call
  hasUncaughtException() to determine if an exception occurred in
  the last call to evaluate().

  \a lineNumber is used to specify a starting line number for \a
  program; line number information reported by the engine that pertain
  to this evaluation (e.g. uncaughtExceptionLineNumber()) will be
  based on this argument. For example, if \a program consists of two
  lines of code, and the statement on the second line causes a script
  exception, uncaughtExceptionLineNumber() would return the given \a
  lineNumber plus one. When no starting line number is specified, line
  numbers will be 1-based.

  \a fileName is used for error reporting. For example in error objects
  the file name is accessible through the "fileName" property if it's
  provided with this function.

  \sa canEvaluate(), hasUncaughtException(), isEvaluating(), abortEvaluation()
*/

QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
            = QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d);
    intptr_t sourceId = provider->asID();
    JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null.

    JSC::ExecState* exec = d->currentFrame;
    WTF::RefPtr<JSC::EvalExecutable> executable = JSC::EvalExecutable::create(exec, source);
    bool compile = true;
    return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, executable.get(), compile));
}

/*!
  \since 4.7

  Evaluates the given \a program and returns the result of the
  evaluation.
*/
QScriptValue QScriptEngine::evaluate(const QScriptProgram &program)
{
    Q_D(QScriptEngine);
    QScriptProgramPrivate *program_d = QScriptProgramPrivate::get(program);
    if (!program_d)
        return QScriptValue();

    QScript::APIShim shim(d);
    JSC::ExecState* exec = d->currentFrame;
    JSC::EvalExecutable *executable = program_d->executable(exec, d);
    bool compile = !program_d->isCompiled;
    JSC::JSValue result = d->evaluateHelper(exec, program_d->sourceId,
                                            executable, compile);
    if (compile)
        program_d->isCompiled = true;
    return d->scriptValueFromJSCValue(result);
}

/*!
  Returns the current context.

  The current context is typically accessed to retrieve the arguments
  and `this' object in native functions; for convenience, it is
  available as the first argument in QScriptEngine::FunctionSignature.
*/
QScriptContext *QScriptEngine::currentContext() const
{
    Q_D(const QScriptEngine);
    return const_cast<QScriptEnginePrivate*>(d)->contextForFrame(d->currentFrame);
}

/*!
  Enters a new execution context and returns the associated
  QScriptContext object.

  Once you are done with the context, you should call popContext() to
  restore the old context.

  By default, the `this' object of the new context is the Global Object.
  The context's \l{QScriptContext::callee()}{callee}() will be invalid.

  This function is useful when you want to evaluate script code
  as if it were the body of a function. You can use the context's
  \l{QScriptContext::activationObject()}{activationObject}() to initialize
  local variables that will be available to scripts. Example:

  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 19

  In the above example, the new variable "tmp" defined in the script
  will be local to the context; in other words, the script doesn't
  have any effect on the global environment.

  Returns 0 in case of stack overflow

  \sa popContext()
*/
QScriptContext *QScriptEngine::pushContext()
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);

    JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, d->currentFrame->globalData().dynamicGlobalObject,
                                              JSC::ArgList(), /*callee = */0);

    if (agent())
        agent()->contextPush();

    return d->contextForFrame(newFrame);
}

/*! \internal
   push a context for a native function.
   JSC native function doesn't have different stackframe or context. so we need to create one.

   use popContext right after to go back to the previous context the context if no stack overflow has hapenned

   exec is the current top frame.

   return the new top frame. (might be the same as exec if a new stackframe was not needed) or 0 if stack overflow
*/
JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSValue _thisObject,
                                                  const JSC::ArgList& args, JSC::JSObject *callee, bool calledAsConstructor,
                                                  bool clearScopeChain)
{
    JSC::JSValue thisObject = _thisObject;
    if (!callee) {
        // callee can't be zero, as this can cause JSC to crash during GC
        // marking phase if the context's Arguments object has been created.
        // Fake it by using the global object. Note that this is also handled
        // in QScriptContext::callee(), as that function should still return
        // an invalid value.
        callee = originalGlobalObject();
    }
    if (calledAsConstructor) {
        //JSC doesn't create default created object for native functions. so we do it
        JSC::JSValue prototype = callee->get(exec, exec->propertyNames().prototype);
        JSC::Structure *structure = prototype.isObject() ? JSC::asObject(prototype)->inheritorID()
                                                         : originalGlobalObject()->emptyObjectStructure();
        thisObject = new (exec) QScriptObject(structure);
    }

    int flags = NativeContext;
    if (calledAsConstructor)
        flags |= CalledAsConstructorContext;

    //build a frame
    JSC::CallFrame *newCallFrame = exec;
    if (callee == 0 //called from  public QScriptEngine::pushContext
        || exec->returnPC() == 0 || (contextFlags(exec) & NativeContext) //called from native-native call
        || (exec->codeBlock() && exec->callee() != callee)) { //the interpreter did not build a frame for us.
        //We need to check if the Interpreter might have already created a frame for function called from JS.
        JSC::Interpreter *interp = exec->interpreter();
        JSC::Register *oldEnd = interp->registerFile().end();
        int argc = args.size() + 1; //add "this"
        JSC::Register *newEnd = oldEnd + argc + JSC::RegisterFile::CallFrameHeaderSize;
        if (!interp->registerFile().grow(newEnd))
            return 0; //### Stack overflow
        newCallFrame = JSC::CallFrame::create(oldEnd);
        newCallFrame[0] = thisObject;
        int dst = 0;
        JSC::ArgList::const_iterator it;
        for (it = args.begin(); it != args.end(); ++it)
            newCallFrame[++dst] = *it;
        newCallFrame += argc + JSC::RegisterFile::CallFrameHeaderSize;

        if (!clearScopeChain) {
            newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee);
        } else {
            newCallFrame->init(0, /*vPC=*/0, globalExec()->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee);
        }
    } else {
        setContextFlags(newCallFrame, flags);
#if ENABLE(JIT)
        exec->registers()[JSC::RegisterFile::Callee] = JSC::JSValue(callee); //JIT let the callee set the 'callee'
#endif
        if (calledAsConstructor) {
            //update the new created this
            JSC::Register* thisRegister = thisRegisterForFrame(newCallFrame);
            *thisRegister = thisObject;
        }
    }
    currentFrame = newCallFrame;
    return newCallFrame;
}


/*!
  Pops the current execution context and restores the previous one.
  This function must be used in conjunction with pushContext().

  \sa pushContext()
*/
void QScriptEngine::popContext()
{
    if (agent())
        agent()->contextPop();
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    if (d->currentFrame->returnPC() != 0 || d->currentFrame->codeBlock() != 0
        || !currentContext()->parentContext()) {
        qWarning("QScriptEngine::popContext() doesn't match with pushContext()");
        return;
    }

    d->popContext();
}

/*! \internal
    counter part of QScriptEnginePrivate::pushContext
 */
void QScriptEnginePrivate::popContext()
{
    uint flags = contextFlags(currentFrame);
    bool hasScope = flags & HasScopeContext;
    if (flags & ShouldRestoreCallFrame) { //normal case
        JSC::RegisterFile &registerFile = currentFrame->interpreter()->registerFile();
        JSC::Register *const newEnd = currentFrame->registers() - JSC::RegisterFile::CallFrameHeaderSize - currentFrame->argumentCount();
        if (hasScope)
            currentFrame->scopeChain()->pop()->deref();
        registerFile.shrink(newEnd);
    } else if(hasScope) { //the stack frame was created by the Interpreter, we don't need to rewind it.
        currentFrame->setScopeChain(currentFrame->scopeChain()->pop());
        currentFrame->scopeChain()->deref();
    }
    currentFrame = currentFrame->callerFrame();
}

/*!
  Returns true if the last script evaluation resulted in an uncaught
  exception; otherwise returns false.

  The exception state is cleared when evaluate() is called.

  \sa uncaughtException(), uncaughtExceptionLineNumber()
*/
bool QScriptEngine::hasUncaughtException() const
{
    Q_D(const QScriptEngine);
    JSC::ExecState* exec = d->globalExec();
    return exec->hadException() || d->currentException().isValid();
}

/*!
  Returns the current uncaught exception, or an invalid QScriptValue
  if there is no uncaught exception.

  The exception value is typically an \c{Error} object; in that case,
  you can call toString() on the return value to obtain an error
  message.

  \sa hasUncaughtException(), uncaughtExceptionLineNumber(),
*/
QScriptValue QScriptEngine::uncaughtException() const
{
    Q_D(const QScriptEngine);
    QScriptValue result;
    JSC::ExecState* exec = d->globalExec();
    if (exec->hadException())
        result = const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(exec->exception());
    else
        result = d->currentException();
    return result;
}

/*!
  Returns the line number where the last uncaught exception occurred.

  Line numbers are 1-based, unless a different base was specified as
  the second argument to evaluate().

  \sa hasUncaughtException()
*/
int QScriptEngine::uncaughtExceptionLineNumber() const
{
    if (!hasUncaughtException())
        return -1;
    return uncaughtException().property(QLatin1String("lineNumber")).toInt32();
}

/*!
  Returns a human-readable backtrace of the last uncaught exception.

  It is in the form \c{<function-name>()@<file-name>:<line-number>}.

  \sa uncaughtException()
*/
QStringList QScriptEngine::uncaughtExceptionBacktrace() const
{
    if (!hasUncaughtException())
        return QStringList();
// ### currently no way to get a full backtrace from JSC without installing a
// debugger that reimplements exception() and store the backtrace there.
    QScriptValue value = uncaughtException();
    if (!value.isError())
        return QStringList();
    QStringList result;
    result.append(QString::fromLatin1("<anonymous>()@%0:%1")
                  .arg(value.property(QLatin1String("fileName")).toString())
                  .arg(value.property(QLatin1String("lineNumber")).toInt32()));
    return result;
}

/*!
  \since 4.4

  Clears any uncaught exceptions in this engine.

  \sa hasUncaughtException()
*/
void QScriptEngine::clearExceptions()
{
    Q_D(QScriptEngine);
    JSC::ExecState* exec = d->currentFrame;
    exec->clearException();
    d->clearCurrentException();
}

/*!
  Returns the default prototype associated with the given \a metaTypeId,
  or an invalid QScriptValue if no default prototype has been set.

  \sa setDefaultPrototype()
*/
QScriptValue QScriptEngine::defaultPrototype(int metaTypeId) const
{
    Q_D(const QScriptEngine);
    return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(d->defaultPrototype(metaTypeId));
}

/*!
  Sets the default prototype of the C++ type identified by the given
  \a metaTypeId to \a prototype.

  The default prototype provides a script interface for values of
  type \a metaTypeId when a value of that type is accessed from script
  code.  Whenever the script engine (implicitly or explicitly) creates
  a QScriptValue from a value of type \a metaTypeId, the default
  prototype will be set as the QScriptValue's prototype.

  The \a prototype object itself may be constructed using one of two
  principal techniques; the simplest is to subclass QScriptable, which
  enables you to define the scripting API of the type through QObject
  properties and slots.  Another possibility is to create a script
  object by calling newObject(), and populate the object with the
  desired properties (e.g. native functions wrapped with
  newFunction()).

  \sa defaultPrototype(), qScriptRegisterMetaType(), QScriptable, {Default Prototypes Example}
*/
void QScriptEngine::setDefaultPrototype(int metaTypeId, const QScriptValue &prototype)
{
    Q_D(QScriptEngine);
    d->setDefaultPrototype(metaTypeId, d->scriptValueToJSCValue(prototype));
}

/*!
  \typedef QScriptEngine::FunctionSignature
  \relates QScriptEngine

  The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}.

  A function with such a signature can be passed to
  QScriptEngine::newFunction() to wrap the function.
*/

/*!
  \typedef QScriptEngine::FunctionWithArgSignature
  \relates QScriptEngine

  The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}.

  A function with such a signature can be passed to
  QScriptEngine::newFunction() to wrap the function.
*/

/*!
    \typedef QScriptEngine::MarshalFunction
    \internal
*/

/*!
    \typedef QScriptEngine::DemarshalFunction
    \internal
*/

/*!
    \internal
*/
QScriptValue QScriptEngine::create(int type, const void *ptr)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr));
}

JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const void *ptr)
{
    Q_ASSERT(ptr != 0);
    JSC::JSValue result;
    QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
    QScriptTypeInfo *info = eng ? eng->m_typeInfos.value(type) : 0;
    if (info && info->marshal) {
        result = eng->scriptValueToJSCValue(info->marshal(eng->q_func(), ptr));
    } else {
        // check if it's one of the types we know
        switch (QMetaType::Type(type)) {
        case QMetaType::Void:
            return JSC::jsUndefined();
        case QMetaType::Bool:
            return JSC::jsBoolean(*reinterpret_cast<const bool*>(ptr));
        case QMetaType::Int:
            return JSC::jsNumber(exec, *reinterpret_cast<const int*>(ptr));
        case QMetaType::UInt:
            return JSC::jsNumber(exec, *reinterpret_cast<const uint*>(ptr));
        case QMetaType::LongLong:
            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
        case QMetaType::ULongLong:
#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
            return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
            return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
#else
            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
#endif
        case QMetaType::Double:
            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const double*>(ptr)));
        case QMetaType::QString:
            return JSC::jsString(exec, *reinterpret_cast<const QString*>(ptr));
        case QMetaType::Float:
            return JSC::jsNumber(exec, *reinterpret_cast<const float*>(ptr));
        case QMetaType::Short:
            return JSC::jsNumber(exec, *reinterpret_cast<const short*>(ptr));
        case QMetaType::UShort:
            return JSC::jsNumber(exec, *reinterpret_cast<const unsigned short*>(ptr));
        case QMetaType::Char:
            return JSC::jsNumber(exec, *reinterpret_cast<const char*>(ptr));
        case QMetaType::UChar:
            return JSC::jsNumber(exec, *reinterpret_cast<const unsigned char*>(ptr));
        case QMetaType::QChar:
            return JSC::jsNumber(exec, (*reinterpret_cast<const QChar*>(ptr)).unicode());
        case QMetaType::QStringList:
            result = arrayFromStringList(exec, *reinterpret_cast<const QStringList *>(ptr));
            break;
        case QMetaType::QVariantList:
            result = arrayFromVariantList(exec, *reinterpret_cast<const QVariantList *>(ptr));
            break;
        case QMetaType::QVariantMap:
            result = objectFromVariantMap(exec, *reinterpret_cast<const QVariantMap *>(ptr));
            break;
        case QMetaType::QDateTime:
            result = newDate(exec, *reinterpret_cast<const QDateTime *>(ptr));
            break;
        case QMetaType::QDate:
            result = newDate(exec, QDateTime(*reinterpret_cast<const QDate *>(ptr)));
            break;
#ifndef QT_NO_REGEXP
        case QMetaType::QRegExp:
            result = newRegExp(exec, *reinterpret_cast<const QRegExp *>(ptr));
            break;
#endif
#ifndef QT_NO_QOBJECT
        case QMetaType::QObjectStar:
        case QMetaType::QWidgetStar:
            result = eng->newQObject(*reinterpret_cast<QObject* const *>(ptr));
            break;
#endif
        case QMetaType::QVariant:
            result = jscValueFromVariant(exec, *reinterpret_cast<const QVariant*>(ptr));
            break;
        default:
            if (type == qMetaTypeId<QScriptValue>()) {
                result = eng->scriptValueToJSCValue(*reinterpret_cast<const QScriptValue*>(ptr));
                if (!result)
                    return JSC::jsUndefined();
            }

#ifndef QT_NO_QOBJECT
            // lazy registration of some common list types
            else if (type == qMetaTypeId<QObjectList>()) {
                qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
                return create(exec, type, ptr);
            }
#endif
            else if (type == qMetaTypeId<QList<int> >()) {
                qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
                return create(exec, type, ptr);
            }

            else {
                QByteArray typeName = QMetaType::typeName(type);
                if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr))
                    return JSC::jsNull();
                else
                    result = eng->newVariant(QVariant(type, ptr));
            }
        }
    }
    if (result && result.isObject() && info && info->prototype
        && JSC::JSValue::strictEqual(exec, JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) {
        JSC::asObject(result)->setPrototype(info->prototype);
    }
    return result;
}

bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value,
                                        int type, void *ptr)
{
    QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
    if (eng) {
        QScriptTypeInfo *info = eng->m_typeInfos.value(type);
        if (info && info->demarshal) {
            info->demarshal(eng->scriptValueFromJSCValue(value), ptr);
            return true;
        }
    }

    // check if it's one of the types we know
    switch (QMetaType::Type(type)) {
    case QMetaType::Bool:
        *reinterpret_cast<bool*>(ptr) = toBool(exec, value);
        return true;
    case QMetaType::Int:
        *reinterpret_cast<int*>(ptr) = toInt32(exec, value);
        return true;
    case QMetaType::UInt:
        *reinterpret_cast<uint*>(ptr) = toUInt32(exec, value);
        return true;
    case QMetaType::LongLong:
        *reinterpret_cast<qlonglong*>(ptr) = qlonglong(toInteger(exec, value));
        return true;
    case QMetaType::ULongLong:
        *reinterpret_cast<qulonglong*>(ptr) = qulonglong(toInteger(exec, value));
        return true;
    case QMetaType::Double:
        *reinterpret_cast<double*>(ptr) = toNumber(exec, value);
        return true;
    case QMetaType::QString:
        if (value.isUndefined() || value.isNull())
            *reinterpret_cast<QString*>(ptr) = QString();
        else
            *reinterpret_cast<QString*>(ptr) = toString(exec, value);
        return true;
    case QMetaType::Float:
        *reinterpret_cast<float*>(ptr) = toNumber(exec, value);
        return true;
    case QMetaType::Short:
        *reinterpret_cast<short*>(ptr) = short(toInt32(exec, value));
        return true;
    case QMetaType::UShort:
        *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(toNumber(exec, value));
        return true;
    case QMetaType::Char:
        *reinterpret_cast<char*>(ptr) = char(toInt32(exec, value));
        return true;
    case QMetaType::UChar:
        *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(toInt32(exec, value));
        return true;
    case QMetaType::QChar:
        if (value.isString()) {
            QString str = toString(exec, value);
            *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0);
        } else {
            *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(toNumber(exec, value)));
        }
        return true;
    case QMetaType::QDateTime:
        if (isDate(value)) {
            *reinterpret_cast<QDateTime *>(ptr) = toDateTime(exec, value);
            return true;
        } break;
    case QMetaType::QDate:
        if (isDate(value)) {
            *reinterpret_cast<QDate *>(ptr) = toDateTime(exec, value).date();
            return true;
        } break;
#ifndef QT_NO_REGEXP
    case QMetaType::QRegExp:
        if (isRegExp(value)) {
            *reinterpret_cast<QRegExp *>(ptr) = toRegExp(exec, value);
            return true;
        } break;
#endif
#ifndef QT_NO_QOBJECT
    case QMetaType::QObjectStar:
        if (isQObject(value) || value.isNull()) {
            *reinterpret_cast<QObject* *>(ptr) = toQObject(exec, value);
            return true;
        } break;
    case QMetaType::QWidgetStar:
        if (isQObject(value) || value.isNull()) {
            QObject *qo = toQObject(exec, value);
            if (!qo || qo->isWidgetType()) {
                *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo);
                return true;
            }
        } break;
#endif
    case QMetaType::QStringList:
        if (isArray(value)) {
            *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(exec, value);
            return true;
        } break;
    case QMetaType::QVariantList:
        if (isArray(value)) {
            *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, JSC::asArray(value));
            return true;
        } break;
    case QMetaType::QVariantMap:
        if (isObject(value)) {
            *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, JSC::asObject(value));
            return true;
        } break;
    case QMetaType::QVariant:
        *reinterpret_cast<QVariant*>(ptr) = toVariant(exec, value);
        return true;
    default:
    ;
    }

    QByteArray name = QMetaType::typeName(type);
#ifndef QT_NO_QOBJECT
    if (convertToNativeQObject(exec, value, name, reinterpret_cast<void* *>(ptr)))
        return true;
#endif
    if (isVariant(value) && name.endsWith('*')) {
        int valueType = QMetaType::type(name.left(name.size()-1));
        QVariant &var = variantValue(value);
        if (valueType == var.userType()) {
            *reinterpret_cast<void* *>(ptr) = var.data();
            return true;
        } else {
            // look in the prototype chain
            JSC::JSValue proto = JSC::asObject(value)->prototype();
            while (proto.isObject()) {
                bool canCast = false;
                if (isVariant(proto)) {
                    canCast = (type == variantValue(proto).userType())
                              || (valueType && (valueType == variantValue(proto).userType()));
                }
#ifndef QT_NO_QOBJECT
                else if (isQObject(proto)) {
                    QByteArray className = name.left(name.size()-1);
                    if (QObject *qobject = toQObject(exec, proto))
                        canCast = qobject->qt_metacast(className) != 0;
                }
#endif
                if (canCast) {
                    QByteArray varTypeName = QMetaType::typeName(var.userType());
                    if (varTypeName.endsWith('*'))
                        *reinterpret_cast<void* *>(ptr) = *reinterpret_cast<void* *>(var.data());
                    else
                        *reinterpret_cast<void* *>(ptr) = var.data();
                    return true;
                }
                proto = JSC::asObject(proto)->prototype();
            }
        }
    } else if (value.isNull() && name.endsWith('*')) {
        *reinterpret_cast<void* *>(ptr) = 0;
        return true;
    } else if (type == qMetaTypeId<QScriptValue>()) {
        if (!eng)
            return false;
        *reinterpret_cast<QScriptValue*>(ptr) = eng->scriptValueFromJSCValue(value);
        return true;
    }

    // lazy registration of some common list types
#ifndef QT_NO_QOBJECT
    else if (type == qMetaTypeId<QObjectList>()) {
        if (!eng)
            return false;
        qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
        return convertValue(exec, value, type, ptr);
    }
#endif
    else if (type == qMetaTypeId<QList<int> >()) {
        if (!eng)
            return false;
        qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
        return convertValue(exec, value, type, ptr);
    }

#if 0
    if (!name.isEmpty()) {
        qWarning("QScriptEngine::convert: unable to convert value to type `%s'",
                 name.constData());
    }
#endif
    return false;
}

bool QScriptEnginePrivate::convertNumber(qsreal value, int type, void *ptr)
{
    switch (QMetaType::Type(type)) {
    case QMetaType::Bool:
        *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
        return true;
    case QMetaType::Int:
        *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
        return true;
    case QMetaType::UInt:
        *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
        return true;
    case QMetaType::LongLong:
        *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
        return true;
    case QMetaType::ULongLong:
        *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
        return true;
    case QMetaType::Double:
        *reinterpret_cast<double*>(ptr) = value;
        return true;
    case QMetaType::QString:
        *reinterpret_cast<QString*>(ptr) = QScript::ToString(value);
        return true;
    case QMetaType::Float:
        *reinterpret_cast<float*>(ptr) = value;
        return true;
    case QMetaType::Short:
        *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
        return true;
    case QMetaType::UShort:
        *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
        return true;
    case QMetaType::Char:
        *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
        return true;
    case QMetaType::UChar:
        *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
        return true;
    case QMetaType::QChar:
        *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
        return true;
    default:
        break;
    }
    return false;
}

bool QScriptEnginePrivate::convertString(const QString &value, int type, void *ptr)
{
    switch (QMetaType::Type(type)) {
    case QMetaType::Bool:
        *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
        return true;
    case QMetaType::Int:
        *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
        return true;
    case QMetaType::UInt:
        *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
        return true;
    case QMetaType::LongLong:
        *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
        return true;
    case QMetaType::ULongLong:
        *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
        return true;
    case QMetaType::Double:
        *reinterpret_cast<double*>(ptr) = QScript::ToNumber(value);
        return true;
    case QMetaType::QString:
        *reinterpret_cast<QString*>(ptr) = value;
        return true;
    case QMetaType::Float:
        *reinterpret_cast<float*>(ptr) = QScript::ToNumber(value);
        return true;
    case QMetaType::Short:
        *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
        return true;
    case QMetaType::UShort:
        *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
        return true;
    case QMetaType::Char:
        *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
        return true;
    case QMetaType::UChar:
        *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
        return true;
    case QMetaType::QChar:
        *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
        return true;
    default:
        break;
    }
    return false;
}

bool QScriptEnginePrivate::hasDemarshalFunction(int type) const
{
    QScriptTypeInfo *info = m_typeInfos.value(type);
    return info && (info->demarshal != 0);
}

JSC::UString QScriptEnginePrivate::translationContextFromUrl(const JSC::UString &url)
{
    if (url != cachedTranslationUrl) {
        cachedTranslationContext = QFileInfo(url).baseName();
        cachedTranslationUrl = url;
    }
    return cachedTranslationContext;
}

/*!
    \internal
*/
bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr);
}

/*!
    \internal
*/
bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr)
{
    QScriptValuePrivate *vp = QScriptValuePrivate::get(value);
    if (vp) {
        switch (vp->type) {
        case QScriptValuePrivate::JavaScriptCore: {
            if (vp->engine) {
                QScript::APIShim shim(vp->engine);
                return QScriptEnginePrivate::convertValue(vp->engine->currentFrame, vp->jscValue, type, ptr);
            } else {
                return QScriptEnginePrivate::convertValue(0, vp->jscValue, type, ptr);
            }
        }
        case QScriptValuePrivate::Number:
            return QScriptEnginePrivate::convertNumber(vp->numberValue, type, ptr);
        case QScriptValuePrivate::String:
            return QScriptEnginePrivate::convertString(vp->stringValue, type, ptr);
        }
    }
    return false;
}

/*!
    \internal
*/
void QScriptEngine::registerCustomType(int type, MarshalFunction mf,
                                       DemarshalFunction df,
                                       const QScriptValue &prototype)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    QScriptTypeInfo *info = d->m_typeInfos.value(type);
    if (!info) {
        info = new QScriptTypeInfo();
        d->m_typeInfos.insert(type, info);
    }
    info->marshal = mf;
    info->demarshal = df;
    info->prototype = d->scriptValueToJSCValue(prototype);
}

/*!
  \since 4.5

  Installs translator functions on the given \a object, or on the Global
  Object if no object is specified.

  The relation between Qt Script translator functions and C++ translator
  functions is described in the following table:

    \table
    \header \o Script Function \o Corresponding C++ Function
    \row    \o qsTr()       \o QObject::tr()
    \row    \o QT_TR_NOOP() \o QT_TR_NOOP()
    \row    \o qsTranslate() \o QCoreApplication::translate()
    \row    \o QT_TRANSLATE_NOOP() \o QT_TRANSLATE_NOOP()
    \row    \o qsTrId() (since 4.7) \o qtTrId()
    \row    \o QT_TRID_NOOP() (since 4.7) \o QT_TRID_NOOP()
    \endtable

  \sa {Internationalization with Qt}
*/
void QScriptEngine::installTranslatorFunctions(const QScriptValue &object)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::ExecState* exec = d->currentFrame;
    JSC::JSValue jscObject = d->scriptValueToJSCValue(object);
    JSC::JSGlobalObject *glob = d->originalGlobalObject();
    if (!jscObject || !jscObject.isObject())
        jscObject = d->globalObject();
//    unsigned attribs = JSC::DontEnum;
    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate));
    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp));
    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr));
    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TR_NOOP"), QScript::functionQsTrNoOp));
    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "qsTrId"), QScript::functionQsTrId));
    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TRID_NOOP"), QScript::functionQsTrIdNoOp));

    glob->stringPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "arg"), QScript::stringProtoFuncArg));
}

/*!
    Imports the given \a extension into this QScriptEngine.  Returns
    undefinedValue() if the extension was successfully imported. You
    can call hasUncaughtException() to check if an error occurred; in
    that case, the return value is the value that was thrown by the
    exception (usually an \c{Error} object).

    QScriptEngine ensures that a particular extension is only imported
    once; subsequent calls to importExtension() with the same extension
    name will do nothing and return undefinedValue().

    \sa availableExtensions(), QScriptExtensionPlugin, {Creating QtScript Extensions}
*/
QScriptValue QScriptEngine::importExtension(const QString &extension)
{
#if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
    Q_UNUSED(extension);
#else
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    if (d->importedExtensions.contains(extension))
        return undefinedValue(); // already imported

    QScriptContext *context = currentContext();
    QCoreApplication *app = QCoreApplication::instance();
    if (!app)
        return context->throwError(QLatin1String("No application object"));

    QObjectList staticPlugins = QPluginLoader::staticInstances();
    QStringList libraryPaths = app->libraryPaths();
    QString dot = QLatin1String(".");
    QStringList pathComponents = extension.split(dot);
    QString initDotJs = QLatin1String("__init__.js");

    QString ext;
    for (int i = 0; i < pathComponents.count(); ++i) {
        if (!ext.isEmpty())
            ext.append(dot);
        ext.append(pathComponents.at(i));
        if (d->importedExtensions.contains(ext))
            continue; // already imported

        if (d->extensionsBeingImported.contains(ext)) {
            return context->throwError(QString::fromLatin1("recursive import of %0")
                                       .arg(extension));
        }
        d->extensionsBeingImported.insert(ext);

        QScriptExtensionInterface *iface = 0;
        QString initjsContents;
        QString initjsFileName;

        // look for the extension in static plugins
        for (int j = 0; j < staticPlugins.size(); ++j) {
            iface = qobject_cast<QScriptExtensionInterface*>(staticPlugins.at(j));
            if (!iface)
                continue;
            if (iface->keys().contains(ext))
                break; // use this one
            else
                iface = 0; // keep looking
        }

        {
            // look for __init__.js resource
            QString path = QString::fromLatin1(":/qtscriptextension");
            for (int j = 0; j <= i; ++j) {
                path.append(QLatin1Char('/'));
                path.append(pathComponents.at(j));
            }
            path.append(QLatin1Char('/'));
            path.append(initDotJs);
            QFile file(path);
            if (file.open(QIODevice::ReadOnly)) {
                QTextStream ts(&file);
                initjsContents = ts.readAll();
                initjsFileName = path;
                file.close();
            }
        }

        if (!iface && initjsContents.isEmpty()) {
            // look for the extension in library paths
            for (int j = 0; j < libraryPaths.count(); ++j) {
                QString libPath = libraryPaths.at(j) + QDir::separator() + QLatin1String("script");
                QDir dir(libPath);
                if (!dir.exists(dot))
                    continue;

                // look for C++ plugin
                QFileInfoList files = dir.entryInfoList(QDir::Files);
                for (int k = 0; k < files.count(); ++k) {
                    QFileInfo entry = files.at(k);
                    QString filePath = entry.canonicalFilePath();
                    QPluginLoader loader(filePath);
                    iface = qobject_cast<QScriptExtensionInterface*>(loader.instance());
                    if (iface) {
                        if (iface->keys().contains(ext))
                            break; // use this one
                        else
                            iface = 0; // keep looking
                    }
                }

                // look for __init__.js in the corresponding dir
                QDir dirdir(libPath);
                bool dirExists = dirdir.exists();
                for (int k = 0; dirExists && (k <= i); ++k)
                    dirExists = dirdir.cd(pathComponents.at(k));
                if (dirExists && dirdir.exists(initDotJs)) {
                    QFile file(dirdir.canonicalPath()
                               + QDir::separator() + initDotJs);
                    if (file.open(QIODevice::ReadOnly)) {
                        QTextStream ts(&file);
                        initjsContents = ts.readAll();
                        initjsFileName = file.fileName();
                        file.close();
                    }
                }

                if (iface || !initjsContents.isEmpty())
                    break;
            }
        }

        if (!iface && initjsContents.isEmpty()) {
            d->extensionsBeingImported.remove(ext);
            return context->throwError(
                QString::fromLatin1("Unable to import %0: no such extension")
                .arg(extension));
        }

        // initialize the extension in a new context
        QScriptContext *ctx = pushContext();
        ctx->setThisObject(globalObject());
        ctx->activationObject().setProperty(QLatin1String("__extension__"), ext,
                                            QScriptValue::ReadOnly | QScriptValue::Undeletable);
        ctx->activationObject().setProperty(QLatin1String("__setupPackage__"),
                                            newFunction(QScript::__setupPackage__));
        ctx->activationObject().setProperty(QLatin1String("__postInit__"), QScriptValue(QScriptValue::UndefinedValue));

        // the script is evaluated first
        if (!initjsContents.isEmpty()) {
            QScriptValue ret = evaluate(initjsContents, initjsFileName);
            if (hasUncaughtException()) {
                popContext();
                d->extensionsBeingImported.remove(ext);
                return ret;
            }
        }

        // next, the C++ plugin is called
        if (iface) {
            iface->initialize(ext, this);
            if (hasUncaughtException()) {
                QScriptValue ret = uncaughtException(); // ctx_p->returnValue();
                popContext();
                d->extensionsBeingImported.remove(ext);
                return ret;
            }
        }

        // if the __postInit__ function has been set, we call it
        QScriptValue postInit = ctx->activationObject().property(QLatin1String("__postInit__"));
        if (postInit.isFunction()) {
            postInit.call(globalObject());
            if (hasUncaughtException()) {
                QScriptValue ret = uncaughtException(); // ctx_p->returnValue();
                popContext();
                d->extensionsBeingImported.remove(ext);
                return ret;
            }
        }

        popContext();

        d->importedExtensions.insert(ext);
        d->extensionsBeingImported.remove(ext);
    } // for (i)
#endif // QT_NO_QOBJECT
    return undefinedValue();
}

/*!
    \since 4.4

    Returns a list naming the available extensions that can be
    imported using the importExtension() function. This list includes
    extensions that have been imported.

    \sa importExtension(), importedExtensions()
*/
QStringList QScriptEngine::availableExtensions() const
{
#if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
    return QStringList();
#else
    QCoreApplication *app = QCoreApplication::instance();
    if (!app)
        return QStringList();

    QSet<QString> result;

    QObjectList staticPlugins = QPluginLoader::staticInstances();
    for (int i = 0; i < staticPlugins.size(); ++i) {
        QScriptExtensionInterface *iface;
        iface = qobject_cast<QScriptExtensionInterface*>(staticPlugins.at(i));
        if (iface) {
            QStringList keys = iface->keys();
            for (int j = 0; j < keys.count(); ++j)
                result << keys.at(j);
        }
    }

    QStringList libraryPaths = app->libraryPaths();
    for (int i = 0; i < libraryPaths.count(); ++i) {
        QString libPath = libraryPaths.at(i) + QDir::separator() + QLatin1String("script");
        QDir dir(libPath);
        if (!dir.exists())
            continue;

        // look for C++ plugins
        QFileInfoList files = dir.entryInfoList(QDir::Files);
        for (int j = 0; j < files.count(); ++j) {
            QFileInfo entry = files.at(j);
            QString filePath = entry.canonicalFilePath();
            QPluginLoader loader(filePath);
            QScriptExtensionInterface *iface;
            iface = qobject_cast<QScriptExtensionInterface*>(loader.instance());
            if (iface) {
                QStringList keys = iface->keys();
                for (int k = 0; k < keys.count(); ++k)
                    result << keys.at(k);
            }
        }

        // look for scripts
        QString initDotJs = QLatin1String("__init__.js");
        QList<QFileInfo> stack;
        stack << dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
        while (!stack.isEmpty()) {
            QFileInfo entry = stack.takeLast();
            QDir dd(entry.canonicalFilePath());
            if (dd.exists(initDotJs)) {
                QString rpath = dir.relativeFilePath(dd.canonicalPath());
                QStringList components = rpath.split(QLatin1Char('/'));
                result << components.join(QLatin1String("."));
                stack << dd.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
            }
        }
    }

    QStringList lst = result.toList();
    qSort(lst);
    return lst;
#endif
}

/*!
    \since 4.4

    Returns a list naming the extensions that have been imported
    using the importExtension() function.

    \sa availableExtensions()
*/
QStringList QScriptEngine::importedExtensions() const
{
    Q_D(const QScriptEngine);
    QStringList lst = d->importedExtensions.toList();
    qSort(lst);
    return lst;
}

/*! \fn QScriptValue QScriptEngine::toScriptValue(const T &value)

    Creates a QScriptValue with the given \a value.

    Note that the template type \c{T} must be known to QMetaType.

    See \l{Conversion Between QtScript and C++ Types} for a
    description of the built-in type conversion provided by
    QtScript. By default, the types that are not specially handled by
    QtScript are represented as QVariants (e.g. the \a value is passed
    to newVariant()); you can change this behavior by installing your
    own type conversion functions with qScriptRegisterMetaType().

    \warning This function is not available with MSVC 6. Use
    qScriptValueFromValue() instead if you need to support that
    version of the compiler.

    \sa fromScriptValue(), qScriptRegisterMetaType()
*/

/*! \fn T QScriptEngine::fromScriptValue(const QScriptValue &value)

    Returns the given \a value converted to the template type \c{T}.

    Note that \c{T} must be known to QMetaType.

    See \l{Conversion Between QtScript and C++ Types} for a
    description of the built-in type conversion provided by
    QtScript.

    \warning This function is not available with MSVC 6. Use
    qScriptValueToValue() or qscriptvalue_cast() instead if you need
    to support that version of the compiler.

    \sa toScriptValue(), qScriptRegisterMetaType()
*/

/*!
    \fn QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &value)
    \since 4.3
    \relates QScriptEngine

    Creates a QScriptValue using the given \a engine with the given \a
    value of template type \c{T}.

    This function is equivalent to QScriptEngine::toScriptValue().
    It is provided as a work-around for MSVC 6, which doesn't support
    member template functions.

    \sa qScriptValueToValue()
*/

/*!
    \fn T qScriptValueToValue(const QScriptValue &value)
    \since 4.3
    \relates QScriptEngine

    Returns the given \a value converted to the template type \c{T}.

    This function is equivalent to QScriptEngine::fromScriptValue().
    It is provided as a work-around for MSVC 6, which doesn't
    support member template functions.

    \sa qScriptValueFromValue()
*/

/*!
    \fn QScriptValue qScriptValueFromSequence(QScriptEngine *engine, const Container &container)
    \since 4.3
    \relates QScriptEngine

    Creates an array in the form of a QScriptValue using the given \a engine
    with the given \a container of template type \c{Container}.

    The \c Container type must provide a \c const_iterator class to enable the
    contents of the container to be copied into the array.

    Additionally, the type of each element in the sequence should be
    suitable for conversion to a QScriptValue.  See
    \l{Conversion Between QtScript and C++ Types} for more information
    about the restrictions on types that can be used with QScriptValue.

    \sa qScriptValueFromValue()
*/

/*!
    \fn void qScriptValueToSequence(const QScriptValue &value, Container &container)
    \since 4.3
    \relates QScriptEngine

    Copies the elements in the sequence specified by \a value to the given
    \a container of template type \c{Container}.

    The \a value used is typically an array, but any container can be copied
    as long as it provides a \c length property describing how many elements
    it contains.

    Additionally, the type of each element in the sequence must be
    suitable for conversion to a C++ type from a QScriptValue.  See
    \l{Conversion Between QtScript and C++ Types} for more information
    about the restrictions on types that can be used with
    QScriptValue.

    \sa qscriptvalue_cast()
*/

/*!
    \fn T qscriptvalue_cast(const QScriptValue &value)
    \since 4.3
    \relates QScriptValue

    Returns the given \a value converted to the template type \c{T}.

    \sa qScriptRegisterMetaType(), QScriptEngine::toScriptValue()
*/

/*! \fn int qScriptRegisterMetaType(
            QScriptEngine *engine,
            QScriptValue (*toScriptValue)(QScriptEngine *, const T &t),
            void (*fromScriptValue)(const QScriptValue &, T &t),
            const QScriptValue &prototype = QScriptValue())
    \relates QScriptEngine

    Registers the type \c{T} in the given \a engine. \a toScriptValue must
    be a function that will convert from a value of type \c{T} to a
    QScriptValue, and \a fromScriptValue a function that does the
    opposite. \a prototype, if valid, is the prototype that's set on
    QScriptValues returned by \a toScriptValue.

    Returns the internal ID used by QMetaType.

    You only need to call this function if you want to provide custom
    conversion of values of type \c{T}, i.e. if the default
    QVariant-based representation and conversion is not
    appropriate. (Note that custom QObject-derived types also fall in
    this category; e.g. for a QObject-derived class called MyObject,
    you probably want to define conversion functions for MyObject*
    that utilize QScriptEngine::newQObject() and
    QScriptValue::toQObject().)

    If you only want to define a common script interface for values of
    type \c{T}, and don't care how those values are represented
    (i.e. storing them in QVariants is fine), use
    \l{QScriptEngine::setDefaultPrototype()}{setDefaultPrototype}()
    instead; this will minimize conversion costs.

    You need to declare the custom type first with
    Q_DECLARE_METATYPE().

    After a type has been registered, you can convert from a
    QScriptValue to that type using
    \l{QScriptEngine::fromScriptValue()}{fromScriptValue}(), and
    create a QScriptValue from a value of that type using
    \l{QScriptEngine::toScriptValue()}{toScriptValue}(). The engine
    will take care of calling the proper conversion function when
    calling C++ slots, and when getting or setting a C++ property;
    i.e. the custom type may be used seamlessly on both the C++ side
    and the script side.

    The following is an example of how to use this function. We will
    specify custom conversion of our type \c{MyStruct}. Here's the C++
    type:

    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 20

    We must declare it so that the type will be known to QMetaType:

    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 21

    Next, the \c{MyStruct} conversion functions. We represent the
    \c{MyStruct} value as a script object and just copy the properties:

    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 22

    Now we can register \c{MyStruct} with the engine:
    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 23

    Working with \c{MyStruct} values is now easy:
    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 24

    If you want to be able to construct values of your custom type
    from script code, you have to register a constructor function for
    the type. For example:

    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 25

    \sa qScriptRegisterSequenceMetaType(), qRegisterMetaType()
*/

/*!
    \macro Q_SCRIPT_DECLARE_QMETAOBJECT(QMetaObject, ArgType)
    \since 4.3
    \relates QScriptEngine

    Declares the given \a QMetaObject. Used in combination with
    QScriptEngine::scriptValueFromQMetaObject() to make enums and
    instantiation of \a QMetaObject available to script code. The
    constructor generated by this macro takes a single argument of
    type \a ArgType; typically the argument is the parent type of the
    new instance, in which case \a ArgType is \c{QWidget*} or
    \c{QObject*}. Objects created by the constructor will have
    QScriptEngine::AutoOwnership ownership.
*/

/*! \fn int qScriptRegisterSequenceMetaType(
            QScriptEngine *engine,
            const QScriptValue &prototype = QScriptValue())
    \relates QScriptEngine

    Registers the sequence type \c{T} in the given \a engine. This
    function provides conversion functions that convert between \c{T}
    and Qt Script \c{Array} objects. \c{T} must provide a
    const_iterator class and begin(), end() and push_back()
    functions. If \a prototype is valid, it will be set as the
    prototype of \c{Array} objects due to conversion from \c{T};
    otherwise, the standard \c{Array} prototype will be used.

    Returns the internal ID used by QMetaType.

    You need to declare the container type first with
    Q_DECLARE_METATYPE(). If the element type isn't a standard Qt/C++
    type, it must be declared using Q_DECLARE_METATYPE() as well.
    Example:

    \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 26

    \sa qScriptRegisterMetaType()
*/

/*!
  Runs the garbage collector.

  The garbage collector will attempt to reclaim memory by locating and
  disposing of objects that are no longer reachable in the script
  environment.

  Normally you don't need to call this function; the garbage collector
  will automatically be invoked when the QScriptEngine decides that
  it's wise to do so (i.e. when a certain number of new objects have
  been created). However, you can call this function to explicitly
  request that garbage collection should be performed as soon as
  possible.

  \sa reportAdditionalMemoryCost()
*/
void QScriptEngine::collectGarbage()
{
    Q_D(QScriptEngine);
    d->collectGarbage();
}

/*!
  \since 4.7

  Reports an additional memory cost of the given \a size, measured in
  bytes, to the garbage collector.

  This function can be called to indicate that a Qt Script object has
  memory associated with it that isn't managed by Qt Script itself.
  Reporting the additional cost makes it more likely that the garbage
  collector will be triggered.

  Note that if the additional memory is shared with objects outside
  the scripting environment, the cost should not be reported, since
  collecting the Qt Script object would not cause the memory to be
  freed anyway.

  Negative \a size values are ignored, i.e. this function can't be
  used to report that the additional memory has been deallocated.

  \sa collectGarbage()
*/
void QScriptEngine::reportAdditionalMemoryCost(int size)
{
    Q_D(QScriptEngine);
    d->reportAdditionalMemoryCost(size);
}

/*!

  Sets the interval between calls to QCoreApplication::processEvents
  to \a interval milliseconds.

  While the interpreter is running, all event processing is by default
  blocked. This means for instance that the gui will not be updated
  and timers will not be fired. To allow event processing during
  interpreter execution one can specify the processing interval to be
  a positive value, indicating the number of milliseconds between each
  time QCoreApplication::processEvents() is called.

  The default value is -1, which disables event processing during
  interpreter execution.

  You can use QCoreApplication::postEvent() to post an event that
  performs custom processing at the next interval. For example, you
  could keep track of the total running time of the script and call
  abortEvaluation() when you detect that the script has been running
  for a long time without completing.

  \sa processEventsInterval()
*/
void QScriptEngine::setProcessEventsInterval(int interval)
{
    Q_D(QScriptEngine);
    d->processEventsInterval = interval;

    if (interval > 0)
        d->globalData->timeoutChecker->setCheckInterval(interval);

    d->timeoutChecker()->setShouldProcessEvents(interval > 0);
}

/*!

  Returns the interval in milliseconds between calls to
  QCoreApplication::processEvents() while the interpreter is running.

  \sa setProcessEventsInterval()
*/
int QScriptEngine::processEventsInterval() const
{
    Q_D(const QScriptEngine);
    return d->processEventsInterval;
}

/*!
  \since 4.4

  Returns true if this engine is currently evaluating a script,
  otherwise returns false.

  \sa evaluate(), abortEvaluation()
*/
bool QScriptEngine::isEvaluating() const
{
    Q_D(const QScriptEngine);
    return (d->currentFrame != d->globalExec()) || d->inEval;
}

/*!
  \since 4.4

  Aborts any script evaluation currently taking place in this engine.
  The given \a result is passed back as the result of the evaluation
  (i.e. it is returned from the call to evaluate() being aborted).

  If the engine isn't evaluating a script (i.e. isEvaluating() returns
  false), this function does nothing.

  Call this function if you need to abort a running script for some
  reason, e.g.  when you have detected that the script has been
  running for several seconds without completing.

  \sa evaluate(), isEvaluating(), setProcessEventsInterval()
*/
void QScriptEngine::abortEvaluation(const QScriptValue &result)
{
    Q_D(QScriptEngine);
    if (!isEvaluating())
        return;
    d->abortResult = result;
    d->timeoutChecker()->setShouldAbort(true);
    JSC::throwError(d->currentFrame, JSC::createInterruptedExecutionException(&d->currentFrame->globalData()).toObject(d->currentFrame));
}

#ifndef QT_NO_QOBJECT

/*!
  \since 4.4
  \relates QScriptEngine

  Creates a connection from the \a signal in the \a sender to the
  given \a function. If \a receiver is an object, it will act as the
  `this' object when the signal handler function is invoked. Returns
  true if the connection succeeds; otherwise returns false.

  \sa qScriptDisconnect(), QScriptEngine::signalHandlerException()
*/
bool qScriptConnect(QObject *sender, const char *signal,
                    const QScriptValue &receiver, const QScriptValue &function)
{
    if (!sender || !signal)
        return false;
    if (!function.isFunction())
        return false;
    if (receiver.isObject() && (receiver.engine() != function.engine()))
        return false;
    QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
    QScript::APIShim shim(engine);
    JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
    JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
    return engine->scriptConnect(sender, signal, jscReceiver, jscFunction,
                                 Qt::AutoConnection);
}

/*!
  \since 4.4
  \relates QScriptEngine

  Disconnects the \a signal in the \a sender from the given (\a
  receiver, \a function) pair. Returns true if the connection is
  successfully broken; otherwise returns false.

  \sa qScriptConnect()
*/
bool qScriptDisconnect(QObject *sender, const char *signal,
                       const QScriptValue &receiver, const QScriptValue &function)
{
    if (!sender || !signal)
        return false;
    if (!function.isFunction())
        return false;
    if (receiver.isObject() && (receiver.engine() != function.engine()))
        return false;
    QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
    QScript::APIShim shim(engine);
    JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
    JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
    return engine->scriptDisconnect(sender, signal, jscReceiver, jscFunction);
}

/*!
    \since 4.4
    \fn void QScriptEngine::signalHandlerException(const QScriptValue &exception)

    This signal is emitted when a script function connected to a signal causes
    an \a exception.

    \sa qScriptConnect()
*/

QT_BEGIN_INCLUDE_NAMESPACE
#include "moc_qscriptengine.cpp"
QT_END_INCLUDE_NAMESPACE

#endif // QT_NO_QOBJECT

/*!
  \since 4.4

  Installs the given \a agent on this engine. The agent will be
  notified of various events pertaining to script execution. This is
  useful when you want to find out exactly what the engine is doing,
  e.g. when evaluate() is called. The agent interface is the basis of
  tools like debuggers and profilers.

  The engine maintains ownership of the \a agent.

  Calling this function will replace the existing agent, if any.

  \sa agent()
*/
void QScriptEngine::setAgent(QScriptEngineAgent *agent)
{
    Q_D(QScriptEngine);
    if (agent && (agent->engine() != this)) {
        qWarning("QScriptEngine::setAgent(): "
                 "cannot set agent belonging to different engine");
        return;
    }
    QScript::APIShim shim(d);
    if (d->activeAgent)
        QScriptEngineAgentPrivate::get(d->activeAgent)->detach();
    d->activeAgent = agent;
    if (agent) {
        QScriptEngineAgentPrivate::get(agent)->attach();
    }
}

/*!
  \since 4.4

  Returns the agent currently installed on this engine, or 0 if no
  agent is installed.

  \sa setAgent()
*/
QScriptEngineAgent *QScriptEngine::agent() const
{
    Q_D(const QScriptEngine);
    return d->activeAgent;
}

/*!
  \since 4.4

  Returns a handle that represents the given string, \a str.

  QScriptString can be used to quickly look up properties, and
  compare property names, of script objects.

  \sa QScriptValue::property()
*/
QScriptString QScriptEngine::toStringHandle(const QString &str)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    return d->toStringHandle(JSC::Identifier(d->currentFrame, str));
}

/*!
  \since 4.5

  Converts the given \a value to an object, if such a conversion is
  possible; otherwise returns an invalid QScriptValue. The conversion
  is performed according to the following table:

    \table
    \header \o Input Type \o Result
    \row    \o Undefined  \o An invalid QScriptValue.
    \row    \o Null       \o An invalid QScriptValue.
    \row    \o Boolean    \o A new Boolean object whose internal value is set to the value of the boolean.
    \row    \o Number     \o A new Number object whose internal value is set to the value of the number.
    \row    \o String     \o A new String object whose internal value is set to the value of the string.
    \row    \o Object     \o The result is the object itself (no conversion).
    \endtable

    \sa newObject()
*/
QScriptValue QScriptEngine::toObject(const QScriptValue &value)
{
    Q_D(QScriptEngine);
    QScript::APIShim shim(d);
    JSC::JSValue jscValue = d->scriptValueToJSCValue(value);
    if (!jscValue || jscValue.isUndefined() || jscValue.isNull())
        return QScriptValue();
    JSC::ExecState* exec = d->currentFrame;
    JSC::JSValue result = jscValue.toObject(exec);
    return d->scriptValueFromJSCValue(result);
}

/*!
  \internal

  Returns the object with the given \a id, or an invalid
  QScriptValue if there is no object with that id.

  \sa QScriptValue::objectId()
*/
QScriptValue QScriptEngine::objectById(qint64 id) const
{
    Q_D(const QScriptEngine);
    // Assumes that the cell was not been garbage collected
    return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue((JSC::JSCell*)id);
}

/*!
  \since 4.5
  \class QScriptSyntaxCheckResult

  \brief The QScriptSyntaxCheckResult class provides the result of a script syntax check.

  \ingroup script
  \mainclass

  QScriptSyntaxCheckResult is returned by QScriptEngine::checkSyntax() to
  provide information about the syntactical (in)correctness of a script.
*/

/*!
    \enum QScriptSyntaxCheckResult::State

    This enum specifies the state of a syntax check.

    \value Error The program contains a syntax error.
    \value Intermediate The program is incomplete.
    \value Valid The program is a syntactically correct Qt Script program.
*/

/*!
  Constructs a new QScriptSyntaxCheckResult from the \a other result.
*/
QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult &other)
    : d_ptr(other.d_ptr)
{
}

/*!
  \internal
*/
QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate *d)
    : d_ptr(d)
{
}

/*!
  \internal
*/
QScriptSyntaxCheckResult::QScriptSyntaxCheckResult()
    : d_ptr(0)
{
}

/*!
  Destroys this QScriptSyntaxCheckResult.
*/
QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult()
{
}

/*!
  Returns the state of this QScriptSyntaxCheckResult.
*/
QScriptSyntaxCheckResult::State QScriptSyntaxCheckResult::state() const
{
    Q_D(const QScriptSyntaxCheckResult);
    if (!d)
        return Valid;
    return d->state;
}

/*!
  Returns the error line number of this QScriptSyntaxCheckResult, or -1 if
  there is no error.

  \sa state(), errorMessage()
*/
int QScriptSyntaxCheckResult::errorLineNumber() const
{
    Q_D(const QScriptSyntaxCheckResult);
    if (!d)
        return -1;
    return d->errorLineNumber;
}

/*!
  Returns the error column number of this QScriptSyntaxCheckResult, or -1 if
  there is no error.

  \sa state(), errorLineNumber()
*/
int QScriptSyntaxCheckResult::errorColumnNumber() const
{
    Q_D(const QScriptSyntaxCheckResult);
    if (!d)
        return -1;
    return d->errorColumnNumber;
}

/*!
  Returns the error message of this QScriptSyntaxCheckResult, or an empty
  string if there is no error.

  \sa state(), errorLineNumber()
*/
QString QScriptSyntaxCheckResult::errorMessage() const
{
    Q_D(const QScriptSyntaxCheckResult);
    if (!d)
        return QString();
    return d->errorMessage;
}

/*!
  Assigns the \a other result to this QScriptSyntaxCheckResult, and returns a
  reference to this QScriptSyntaxCheckResult.
*/
QScriptSyntaxCheckResult &QScriptSyntaxCheckResult::operator=(const QScriptSyntaxCheckResult &other)
{
    d_ptr = other.d_ptr;
    return *this;
}

#ifdef QT_BUILD_INTERNAL
Q_AUTOTEST_EXPORT bool qt_script_isJITEnabled()
{
#if ENABLE(JIT)
    return true;
#else
    return false;
#endif
}
#endif

#ifdef Q_CC_MSVC
// Try to prevent compiler from crashing.
#pragma optimize("", off)
#endif

QT_END_NAMESPACE
