/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** 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
** us via http://www.qt.io/contact-us/.
**
** $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/qshareddata.h>
#include <QtCore/qmetaobject.h>

#include <math.h>
#include <algorithm>

#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

#include <stdlib.h>

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
  \inmodule QtScript

  \brief The QScriptEngine class provides an environment for evaluating Qt Script code.

  \ingroup script

  See the \l{Qt Script} 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 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 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 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 \b {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 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 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 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 \l{Making Applications Scriptable} 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 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 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 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 QSharedData
{
public:
    QScriptSyntaxCheckResultPrivate() {}
    ~QScriptSyntaxCheckResultPrivate() {}

    QScriptSyntaxCheckResult::State state;
    int errorColumnNumber;
    int errorLineNumber;
    QString errorMessage;
};

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);
}

void GlobalClientData::uncaughtException(JSC::ExecState* exec, unsigned bytecodeOffset,
                                         JSC::JSValue value)
{
    engine->uncaughtException(exec, bytecodeOffset, value);
}

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.methodSignature().constData()));
        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.methodSignature().constData()));
        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.methodSignature().constData()));
        return JSC::throwError(exec, JSC::TypeError, message);
    }

    {
        QList<int> overloads = qtSignal->overloadedIndexes();
        if (!overloads.isEmpty()) {
            overloads.append(qtSignal->initialIndex());
            QByteArray signature = sig.methodSignature();
            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.methodSignature().constData())));
            }
            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.methodSignature().constData()));
        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);
}

#ifndef QT_NO_TRANSLATION

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");

    int n = -1;
    if ((args.size() > 3)) {
        if (args.at(3).isString()) {
            qWarning("qsTranslate(): specifying the encoding as fourth argument is deprecated");
            if (args.size() > 4) {
                if (args.at(4).isNumber())
                    n = args.at(4).toInt32(exec);
                else
                    return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fifth argument (n) must be a number");
            }
        } else if (args.at(3).isNumber()) {
            n = args.at(3).toInt32(exec);
        } else {
            return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fourth 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);
#endif
    JSC::UString result;
#ifndef QT_NO_QOBJECT
    result = QCoreApplication::translate(context.UTF8String().c_str(),
                                         text.UTF8String().c_str(),
                                         comment.UTF8String().c_str(),
                                         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(context.UTF8String().c_str(),
                                         text.UTF8String().c_str(),
                                         comment.UTF8String().c_str(),
                                         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(id.UTF8String().c_str(), 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);
}
#endif // QT_NO_TRANSLATION

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),
      uncaughtExceptionLineNumber(-1)
{
    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;
        free(p);
    }
}

QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType)
{
    if (targetType == QMetaType::QVariant || uint(targetType) == QVariant::LastType)
        return toVariant(exec, value);
    QVariant v(targetType, (void *)0);
    if (convertValue(exec, value, targetType, v.data()))
        return v;
    if (isVariant(value)) {
        v = variantValue(value);
        if (v.canConvert(targetType)) {
            v.convert(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);
}


// This function is called by JSC after all objects reachable by JSC itself
// have been processed (see JSC::Heap::markRoots()).
// Here we should mark additional objects managed by Qt Script.
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
    markQObjectData(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 && !executable->isCompiled()) {
        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;
}

// See ExceptionHelpers.cpp createStackOverflowError()
bool QScriptEnginePrivate::isLikelyStackOverflowError(JSC::ExecState *exec, JSC::JSValue value)
{
    if (!isError(value))
        return false;

    JSC::JSValue name = property(exec, value, exec->propertyNames().name);
    if (!name || !name.isString() || name.toString(exec) != "RangeError")
        return false;

    JSC::JSValue message = property(exec, value, exec->propertyNames().message);
    if (!message || !message.isString() || message.toString(exec) != "Maximum call stack size exceeded.")
        return false;

    return true;
}

/*!
  \internal
  Called by the VM when an uncaught exception is being processed.
  If the VM call stack contains a native call inbetween two JS calls at the
  time the exception is thrown, this function will get called multiple times
  for a single exception (once per "interval" of JS call frames). In other
  words, at the time of this call, the VM stack can be in a partially unwound
  state.
*/
void QScriptEnginePrivate::uncaughtException(JSC::ExecState *exec, unsigned bytecodeOffset,
                                             JSC::JSValue value)
{
    // Don't capture exception information if we already have.
    if (uncaughtExceptionLineNumber != -1)
        return;

    QScript::SaveFrameHelper saveFrame(this, exec);

    uncaughtExceptionLineNumber = exec->codeBlock()->lineNumberForBytecodeOffset(exec, bytecodeOffset);

    if (isLikelyStackOverflowError(exec, value)) {
        // Don't save the backtrace, it's likely to take forever to create.
        uncaughtExceptionBacktrace.clear();
    } else {
        uncaughtExceptionBacktrace = contextForFrame(exec)->backtrace();
    }
}

#ifndef QT_NO_QOBJECT

void QScriptEnginePrivate::markQObjectData(JSC::MarkStack& markStack)
{
    QHash<QObject*, QScript::QObjectData*>::const_iterator it;
    // 1. Clear connection mark bits for all objects
    for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) {
        QScript::QObjectData *qdata = it.value();
        qdata->clearConnectionMarkBits();
    }

    // 2. Iterate until no more connections are marked
    int markedCount;
    do {
        // Drain the stack to ensure mark bits are set; this is used to determine
        // whether a connection's sender object is weakly referenced
        markStack.drain();

        markedCount = 0;
        for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) {
            QScript::QObjectData *qdata = it.value();
            markedCount += qdata->markConnections(markStack);
        }
    } while (markedCount > 0);
    markStack.drain(); // One last time before marking wrappers

    // 3. Mark all wrappers
    for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) {
        QScript::QObjectData *qdata = it.value();
        qdata->markWrappers(markStack);
    }
}

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 QVariant::fromValue(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.isInt32()) {
        return QVariant(toInt32(exec, value));
    } else if (value.isDouble()) {
        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 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 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 | QScriptValue::SkipInEnumeration);
    const_cast<QScriptValue&>(prototype)
        .setProperty(QLatin1String("constructor"), result, QScriptValue::SkipInEnumeration);
    return result;
}

#ifndef QT_NO_REGEXP

/*!
  Creates a Qt Script 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 Qt Script 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 Qt Script 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{Qt Script} 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 Qt Script's control, any
  attempt to access the deleted QObject's members through the Qt Script
  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 Qt Script 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 Qt Script 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 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 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 | QScriptValue::SkipInEnumeration);
    proto.setProperty(QLatin1String("constructor"), result, 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 | QScriptValue::SkipInEnumeration);
    proto.setProperty(QLatin1String("constructor"), result, QScriptValue::SkipInEnumeration);
    return result;
}

/*!
  Creates a Qt Script 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 Qt Script 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 Qt Script 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 Qt Script 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 Qt Script 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 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 code/src_script_qscriptengine.cpp 13

  \sa QScriptEngine::newQMetaObject()
*/

/*!
  \fn QScriptValue qScriptValueFromQMetaObject(QScriptEngine *engine)
  \since 4.3
  \relates QScriptEngine
  \obsolete

  Uses \a engine to create a QScriptValue that represents the Qt class
  \c{T}.

  This function is equivalent to
  QScriptEngine::scriptValueFromQMetaObject().

  \note This function was provided as a workaround for MSVC 6
  which did not support member template functions. It is advised
  to use the other form in new code.

  \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 Qt Script. 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
  Qt Script 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 code/src_script_qscriptengine.cpp 14
  canEvaluate() will return true, since the program appears to be complete.

  Given the input
  \snippet 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 code/src_script_qscriptengine.cpp 16
  canEvaluate() will return true, but evaluate() will throw a
  SyntaxError given the same input.

  Given the input
  \snippet code/src_script_qscriptengine.cpp 17
  canEvaluate() will return true, even though the code is clearly not
  syntactically valid Qt Script code. evaluate() will throw a
  SyntaxError when this code is evaluated.

  Given the input
  \snippet 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 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)
{
    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->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;

        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
{
    Q_D(const QScriptEngine);
    if (!hasUncaughtException())
        return -1;
    if (d->uncaughtExceptionLineNumber != -1)
        return d->uncaughtExceptionLineNumber;

    return uncaughtException().property(QLatin1String("lineNumber")).toInt32();
}

/*!
  Returns a human-readable backtrace of the last uncaught exception.

  It is in the form \c{<function-name>() at <file-name>:<line-number>}.

  \sa uncaughtException()
*/
QStringList QScriptEngine::uncaughtExceptionBacktrace() const
{
    Q_D(const QScriptEngine);
    return d->uncaughtExceptionBacktrace;
}

/*!
  \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

  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

  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::UnknownType:
        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::Long:
            return JSC::jsNumber(exec, *reinterpret_cast<const long*>(ptr));
        case QMetaType::ULong:
            return JSC::jsNumber(exec, *reinterpret_cast<const ulong*>(ptr));
        case QMetaType::LongLong:
            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
        case QMetaType::ULongLong:
            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
        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:
            result = eng->newQObject(*reinterpret_cast<QObject* const *>(ptr));
            break;
#endif
        case QMetaType::QVariant:
            result = eng->newVariant(*reinterpret_cast<const QVariant*>(ptr));
            break;
        default:
            if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
                result = eng->newQObject(*reinterpret_cast<QObject* const *>(ptr));
                break;
            }

            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::Long:
        *reinterpret_cast<long*>(ptr) = long(toInteger(exec, value));
        return true;
    case QMetaType::ULong:
        *reinterpret_cast<ulong*>(ptr) = ulong(toInteger(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;
#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::Long:
        *reinterpret_cast<long*>(ptr) = long(QScript::ToInteger(value));
        return true;
    case QMetaType::ULong:
        *reinterpret_cast<ulong*>(ptr) = ulong(QScript::ToInteger(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::Long:
        *reinterpret_cast<long*>(ptr) = long(QScript::ToInteger(value));
        return true;
    case QMetaType::ULong:
        *reinterpret_cast<ulong*>(ptr) = ulong(QScript::ToInteger(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) {
        const QString &baseName = QFileInfo(url).baseName();
        if (baseName.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive))
            cachedTranslationContext = baseName.mid(4);
        else
            cachedTranslationContext = 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 \li Script Function \li Corresponding C++ Function
    \row    \li qsTr()       \li QObject::tr()
    \row    \li QT_TR_NOOP() \li QT_TR_NOOP()
    \row    \li qsTranslate() \li QCoreApplication::translate()
    \row    \li QT_TRANSLATE_NOOP() \li QT_TRANSLATE_NOOP()
    \row    \li qsTrId() (since 4.7) \li qtTrId()
    \row    \li QT_TRID_NOOP() (since 4.7) \li 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;

#ifndef QT_NO_TRANSLATION
    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));
#endif

    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 Qt Script 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();
    std::sort(lst.begin(), lst.end());
    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();
    std::sort(lst.begin(), lst.end());
    return lst;
}

/*! \fn template <typename T> 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 Qt Script and C++ Types} for a
    description of the built-in type conversion provided by
    Qt Script. By default, the types that are not specially handled by
    Qt Script 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().

    \sa fromScriptValue(), qScriptRegisterMetaType()
*/

/*! \fn template <typename T> 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 Qt Script and C++ Types} for a
    description of the built-in type conversion provided by
    Qt Script.

    \sa toScriptValue(), qScriptRegisterMetaType()
*/

/*!
    \fn template <typename T> QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &value)
    \since 4.3
    \relates QScriptEngine
    \obsolete

    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().

    \note This function was provided as a workaround for MSVC 6
    which did not support member template functions. It is advised
    to use the other form in new code.

    \sa QScriptEngine::toScriptValue(), qscriptvalue_cast()
*/

/*!
    \fn template <typename T> T qScriptValueToValue(const QScriptValue &value)
    \since 4.3
    \relates QScriptEngine
    \obsolete

    Returns the given \a value converted to the template type \c{T}.

    This function is equivalent to QScriptEngine::fromScriptValue().

    \note This function was provided as a workaround for MSVC 6
    which did not support member template functions. It is advised
    to use the other form in new code.

    \sa QScriptEngine::fromScriptValue()
*/

/*!
    \fn template <class Container> 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 Qt Script and C++ Types} for more information
    about the restrictions on types that can be used with QScriptValue.

    \sa QScriptEngine::fromScriptValue()
*/

/*!
    \fn template <class Container> 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 Qt Script and C++ Types} for more information
    about the restrictions on types that can be used with
    QScriptValue.

    \sa qscriptvalue_cast()
*/

/*!
    \fn template <typename T> 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 template<typename T> int qScriptRegisterMetaType(
            QScriptEngine *eng,
            QScriptValue (*toScriptValue)(QScriptEngine *, const T &t),
            void (*fromScriptValue)(const QScriptValue &, T &t),
            const QScriptValue &prototype, T *)

    \relates QScriptEngine

    Registers the type \c{T} in the given \a eng. \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 code/src_script_qscriptengine.cpp 20

    We must declare it so that the type will be known to QMetaType:

    \snippet 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 code/src_script_qscriptengine.cpp 22

    Now we can register \c{MyStruct} with the engine:
    \snippet code/src_script_qscriptengine.cpp 23

    Working with \c{MyStruct} values is now easy:
    \snippet 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 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 template<typename T> int qScriptRegisterSequenceMetaType(
            QScriptEngine *engine,
            const QScriptValue &prototype, T *)

    \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 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 \li Input Type \li Result
    \row    \li Undefined  \li An invalid QScriptValue.
    \row    \li Null       \li An invalid QScriptValue.
    \row    \li Boolean    \li A new Boolean object whose internal value is set to the value of the boolean.
    \row    \li Number     \li A new Number object whose internal value is set to the value of the number.
    \row    \li String     \li A new String object whose internal value is set to the value of the string.
    \row    \li Object     \li 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
  \inmodule QtScript

  \brief The QScriptSyntaxCheckResult class provides the result of a script syntax check.

  \ingroup script

  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
