Changeset 846 for trunk/src/script/api


Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
33 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/script/api/qscriptable.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptable.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptable_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptclass.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptclass.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptclasspropertyiterator.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptclasspropertyiterator.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptcontext.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    162162{
    163163    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
     164    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    164165    JSC::JSValue jscValue = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(value);
    165166    frame->setException(jscValue);
     
    184185{
    185186    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
     187    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    186188    JSC::ErrorType jscError = JSC::GeneralError;
    187189    switch (error) {
     
    219221{
    220222    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
     223    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    221224    JSC::JSObject *result = JSC::throwError(frame, JSC::GeneralError, text);
    222225    return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result);
     
    266269{
    267270    const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
     271    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    268272    return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->callee());
    269273}
     
    287291{
    288292    JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this));
     293    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    289294
    290295    if (frame == frame->lexicalGlobalObject()->globalExec()) {
     
    295300    //for a js function
    296301    if (frame->codeBlock() && frame->callee()) {
     302        if (!QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) {
     303            // We have a built-in JS host call.
     304            // codeBlock is needed by retrieveArguments(), but since it
     305            // contains junk, we would crash. Return an invalid value for now.
     306            return QScriptValue();
     307        }
    297308        JSC::JSValue result = frame->interpreter()->retrieveArguments(frame, JSC::asFunction(frame->callee()));
    298309        return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result);
     
    305316
    306317    //for a native function
    307     if (!frame->optionalCalleeArguments()) {
     318    if (!frame->optionalCalleeArguments()
     319        && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) { // Make sure we don't go here for host JSFunctions
    308320        Q_ASSERT(frame->argumentCount() > 0); //we need at least 'this' otherwise we'll crash later
    309321        JSC::Arguments* arguments = new (&frame->globalData())JSC::Arguments(frame, JSC::Arguments::NoParameters);
     
    319331  When a function is called as constructor, the thisObject()
    320332  contains the newly constructed object to be initialized.
     333
     334  \note This function is only guaranteed to work for a context
     335  corresponding to native functions.
    321336*/
    322337bool QScriptContext::isCalledAsConstructor() const
    323338{
    324339    JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this));
     340    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    325341
    326342    //For native functions, look up flags.
     
    356372{
    357373    const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
     374    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    358375    JSC::CallFrame *callerFrame = frame->callerFrame()->removeHostCallFrameFlag();
    359376    return QScriptEnginePrivate::contextForFrame(callerFrame);
     
    407424  context.
    408425
     426  \note The activation object might not be available if there is no
     427  active QScriptEngineAgent, as it might be optimized.
     428
    409429  \sa argument(), argumentsObject()
    410430*/
     
    413433{
    414434    JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this));
     435    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    415436    JSC::JSObject *result = 0;
    416437
     
    465486
    466487  If \a activation is not an object, this function does nothing.
     488
     489  \note For a context corresponding to a JavaScript function, this is only
     490  guaranteed to work if there was an QScriptEngineAgent active on the
     491  engine while the function was evaluated.
    467492*/
    468493void QScriptContext::setActivationObject(const QScriptValue &activation)
     
    478503    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    479504    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
     505    QScript::APIShim shim(engine);
    480506    JSC::JSObject *object = JSC::asObject(engine->scriptValueToJSCValue(activation));
    481507    if (object == engine->originalGlobalObjectProxy)
     
    522548    JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this));
    523549    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
     550    QScript::APIShim shim(engine);
    524551    JSC::JSValue result = engine->thisForContext(frame);
    525552    if (!result || result.isNull())
     
    537564{
    538565    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
     566    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    539567    if (!thisObject.isObject())
    540568        return;
     
    663691    const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    664692    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
     693    QScript::APIShim shim(engine);
    665694    QScriptValueList result;
    666695    JSC::ScopeChainNode *node = frame->scopeChain();
     
    701730    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    702731    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
     732    QScript::APIShim shim(engine);
    703733    JSC::JSObject *jscObject = JSC::asObject(engine->scriptValueToJSCValue(object));
    704734    if (jscObject == engine->originalGlobalObjectProxy)
     
    730760QScriptValue QScriptContext::popScope()
    731761{
     762    activationObject(); //ensure the creation of the normal scope for native context
    732763    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    733764    JSC::ScopeChainNode *scope = frame->scopeChain();
    734765    Q_ASSERT(scope != 0);
    735766    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
     767    QScript::APIShim shim(engine);
    736768    QScriptValue result = engine->scriptValueFromJSCValue(scope->object);
    737769    if (!scope->next) {
  • trunk/src/script/api/qscriptcontext.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptcontext_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptcontextinfo.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5454
    5555  If the called function is executing Qt Script code, you can obtain
    56   the script location with the functions fileName(), lineNumber() and
    57   columnNumber().
     56  the script location with the functions fileName() and lineNumber().
    5857
    5958  You can obtain the starting line number and ending line number of a
     
    159158            JSC::Instruction *returnPC = rewindContext->returnPC();
    160159            JSC::CodeBlock *codeBlock = frame->codeBlock();
    161             if (returnPC && codeBlock) {
     160            if (returnPC && codeBlock && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) {
    162161#if ENABLE(JIT)
    163162                unsigned bytecodeOffset = codeBlock->getBytecodeIndex(frame, JSC::ReturnAddressPtr(returnPC));
     
    173172    // Get the filename and the scriptId:
    174173    JSC::CodeBlock *codeBlock = frame->codeBlock();
    175     if (codeBlock) {
     174    if (codeBlock && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) {
    176175           JSC::SourceProvider *source = codeBlock->source();
    177176           scriptId = source->asID();
     
    179178    }
    180179
    181     // Get the others informations:
     180    // Get the others information:
    182181    JSC::JSObject *callee = frame->callee();
    183182    if (callee && callee->inherits(&JSC::InternalFunction::info))
    184         functionName = JSC::asInternalFunction(callee)->name(&frame->globalData());
    185     if (callee && callee->inherits(&JSC::JSFunction::info)) {
     183        functionName = JSC::asInternalFunction(callee)->name(frame);
     184    if (callee && callee->inherits(&JSC::JSFunction::info)
     185        && !JSC::asFunction(callee)->isHostFunction()) {
    186186        functionType = QScriptContextInfo::ScriptFunction;
    187187        JSC::FunctionExecutable *body = JSC::asFunction(callee)->jsExecutable();
     
    318318
    319319/*!
    320   Returns the column number corresponding to the statement being
    321   executed, or -1 if the column number is not available.
    322 
    323   The column number is only available if Qt Script code is being
    324   executed.
    325 
    326   \sa lineNumber(), fileName()
     320  \obsolete
    327321*/
    328322int QScriptContextInfo::columnNumber() const
  • trunk/src/script/api/qscriptcontextinfo.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    7070    QString fileName() const;
    7171    int lineNumber() const;
    72     int columnNumber() const;
     72#ifdef QT_DEPRECATED
     73    QT_DEPRECATED int columnNumber() const;
     74#endif
    7375
    7476    QString functionName() const;
  • trunk/src/script/api/qscriptengine.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    2525#include "qscriptengine.h"
    2626#include "qscriptsyntaxchecker_p.h"
    27 #include "qnumeric.h"
    2827
    2928#include "qscriptengine_p.h"
     
    4241#include <QtCore/qmetaobject.h>
    4342
     43#include <math.h>
     44
    4445#include "CodeBlock.h"
    4546#include "Error.h"
    46 #include "JSArray.h"
    47 #include "JSLock.h"
    4847#include "Interpreter.h"
    49 #include "DateConstructor.h"
    50 #include "RegExpConstructor.h"
    51 
     48
     49#include "ExceptionHelpers.h"
    5250#include "PrototypeFunction.h"
    5351#include "InitializeThreading.h"
     
    5856#include "JSFunction.h"
    5957#include "Parser.h"
     58#include "PropertyNameArray.h"
    6059#include "Operations.h"
    6160
    62 #include "utils/qscriptdate_p.h"
    6361#include "bridge/qscriptfunction_p.h"
    64 #include "bridge/qscriptobject_p.h"
    6562#include "bridge/qscriptclassobject_p.h"
    6663#include "bridge/qscriptvariant_p.h"
     
    6865#include "bridge/qscriptglobalobject_p.h"
    6966#include "bridge/qscriptactivationobject_p.h"
     67#include "bridge/qscriptstaticscopeobject_p.h"
    7068
    7169#ifndef QT_NO_QOBJECT
     
    155153  that case, you can call toString() on the error object to obtain an
    156154  error message. The current uncaught exception is also available
    157   through uncaughtException(). You can obtain a human-readable
    158   backtrace of the exception with uncaughtExceptionBacktrace().
     155  through uncaughtException().
    159156  Calling clearExceptions() will cause any uncaught exceptions to be
    160157  cleared.
     
    265262  isEvaluating().
    266263
     264  \section1 Garbage Collection
     265
     266  Qt Script objects may be garbage collected when they are no longer
     267  referenced. There is no guarantee as to when automatic garbage
     268  collection will take place.
     269
     270  The collectGarbage() function can be called to explicitly request
     271  garbage collection.
     272
     273  The reportAdditionalMemoryCost() function can be called to indicate
     274  that a Qt Script object occupies memory that isn't managed by the
     275  scripting environment. Reporting the additional cost makes it more
     276  likely that the garbage collector will be triggered. This can be
     277  useful, for example, when many custom, native Qt Script objects are
     278  allocated.
     279
    267280  \section1 Core Debugging/Tracing Facilities
    268281
     
    282295    This enum specifies the ownership when wrapping a C++ value, e.g. by using newQObject().
    283296
    284     \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 and Object Ownership}.)
    285     \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).
    286     \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).
     297    \value QtOwnership The standard Qt ownership rules apply, i.e. the
     298    associated object will never be explicitly deleted by the script
     299    engine. This is the default. (QObject ownership is explained in
     300    \l{Object Trees & Ownership}.)
     301
     302    \value ScriptOwnership The value is owned by the script
     303    environment. The associated data will be deleted when appropriate
     304    (i.e. after the garbage collector has discovered that there are no
     305    more live references to the value).
     306
     307    \value AutoOwnership If the associated object has a parent, the Qt
     308    ownership rules apply (QtOwnership); otherwise, the object is
     309    owned by the script environment (ScriptOwnership).
     310
    287311*/
    288312
     
    297321    \value ExcludeSuperClassContents Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties
    298322    \value ExcludeDeleteLater The script object will not expose the QObject::deleteLater() slot.
     323    \value ExcludeSlots The script object will not expose the QObject's slots.
    299324    \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.
    300325    \value PreferExistingWrapperObject If a wrapper object with the requested configuration already exists, return that object.
     
    329354namespace QScript
    330355{
     356
     357static const qsreal D32 = 4294967296.0;
     358
     359qint32 ToInt32(qsreal n)
     360{
     361    if (qIsNaN(n) || qIsInf(n) || (n == 0))
     362        return 0;
     363
     364    qsreal sign = (n < 0) ? -1.0 : 1.0;
     365    qsreal abs_n = fabs(n);
     366
     367    n = ::fmod(sign * ::floor(abs_n), D32);
     368    const double D31 = D32 / 2.0;
     369
     370    if (sign == -1 && n < -D31)
     371        n += D32;
     372
     373    else if (sign != -1 && n >= D31)
     374        n -= D32;
     375
     376    return qint32 (n);
     377}
     378
     379quint32 ToUInt32(qsreal n)
     380{
     381    if (qIsNaN(n) || qIsInf(n) || (n == 0))
     382        return 0;
     383
     384    qsreal sign = (n < 0) ? -1.0 : 1.0;
     385    qsreal abs_n = fabs(n);
     386
     387    n = ::fmod(sign * ::floor(abs_n), D32);
     388
     389    if (n < 0)
     390        n += D32;
     391
     392    return quint32 (n);
     393}
     394
     395quint16 ToUInt16(qsreal n)
     396{
     397    static const qsreal D16 = 65536.0;
     398
     399    if (qIsNaN(n) || qIsInf(n) || (n == 0))
     400        return 0;
     401
     402    qsreal sign = (n < 0) ? -1.0 : 1.0;
     403    qsreal abs_n = fabs(n);
     404
     405    n = ::fmod(sign * ::floor(abs_n), D16);
     406
     407    if (n < 0)
     408        n += D16;
     409
     410    return quint16 (n);
     411}
     412
     413qsreal ToInteger(qsreal n)
     414{
     415    if (qIsNaN(n))
     416        return 0;
     417
     418    if (n == 0 || qIsInf(n))
     419        return n;
     420
     421    int sign = n < 0 ? -1 : 1;
     422    return sign * ::floor(::fabs(n));
     423}
     424
     425#ifdef Q_CC_MSVC
     426// MSVC2008 crashes if these are inlined.
     427
     428QString ToString(qsreal value)
     429{
     430    return JSC::UString::from(value);
     431}
     432
     433qsreal ToNumber(const QString &value)
     434{
     435    return ((JSC::UString)value).toDouble();
     436}
     437
     438#endif
     439
     440static const qsreal MsPerSecond = 1000.0;
     441
     442static inline int MsFromTime(qsreal t)
     443{
     444    int r = int(::fmod(t, MsPerSecond));
     445    return (r >= 0) ? r : r + int(MsPerSecond);
     446}
     447
     448/*!
     449  \internal
     450  Converts a JS date value (milliseconds) to a QDateTime (local time).
     451*/
     452QDateTime MsToDateTime(JSC::ExecState *exec, qsreal t)
     453{
     454    if (qIsNaN(t))
     455        return QDateTime();
     456    JSC::GregorianDateTime tm;
     457    JSC::msToGregorianDateTime(exec, t, /*output UTC=*/true, tm);
     458    int ms = MsFromTime(t);
     459    QDateTime convertedUTC = QDateTime(QDate(tm.year + 1900, tm.month + 1, tm.monthDay),
     460                                       QTime(tm.hour, tm.minute, tm.second, ms), Qt::UTC);
     461    return convertedUTC.toLocalTime();
     462}
     463
     464/*!
     465  \internal
     466  Converts a QDateTime to a JS date value (milliseconds).
     467*/
     468qsreal DateTimeToMs(JSC::ExecState *exec, const QDateTime &dt)
     469{
     470    if (!dt.isValid())
     471        return qSNaN();
     472    QDateTime utc = dt.toUTC();
     473    QDate date = utc.date();
     474    QTime time = utc.time();
     475    JSC::GregorianDateTime tm;
     476    tm.year = date.year() - 1900;
     477    tm.month = date.month() - 1;
     478    tm.monthDay = date.day();
     479    tm.weekDay = date.dayOfWeek();
     480    tm.yearDay = date.dayOfYear();
     481    tm.hour = time.hour();
     482    tm.minute = time.minute();
     483    tm.second = time.second();
     484    return JSC::gregorianDateTimeToMS(exec, tm, time.msec(), /*inputIsUTC=*/true);
     485}
    331486
    332487void GlobalClientData::mark(JSC::MarkStack& markStack)
     
    484639            slot = arg1;
    485640        else {
    486             // ### don't go via QScriptValue
    487641            QScript::SaveFrameHelper saveFrame(engine, exec);
    488             QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
    489             QString propertyName(arg1.toString(exec));
    490             slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
     642            JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1);
     643            slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
    491644        }
    492645    }
     
    568721            slot = arg1;
    569722        else {
    570             // ### don't go via QScriptValue
    571723            QScript::SaveFrameHelper saveFrame(engine, exec);
    572             QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
    573             QString propertyName = arg1.toString(exec);
    574             slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
     724            JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1);
     725            slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
    575726        }
    576727    }
     
    633784static JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
    634785static JSC::JSValue JSC_HOST_CALL functionQsTrNoOp(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
     786static JSC::JSValue JSC_HOST_CALL functionQsTrId(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
     787static JSC::JSValue JSC_HOST_CALL functionQsTrIdNoOp(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&);
    635788
    636789JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
     
    649802        return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fifth argument (n) must be a number");
    650803#ifndef QT_NO_QOBJECT
    651     QString context(args.at(0).toString(exec));
     804    JSC::UString context = args.at(0).toString(exec);
    652805#endif
    653     QString text(args.at(1).toString(exec));
     806    JSC::UString text = args.at(1).toString(exec);
    654807#ifndef QT_NO_QOBJECT
    655     QString comment;
     808    JSC::UString comment;
    656809    if (args.size() > 2)
    657810        comment = args.at(2).toString(exec);
    658811    QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr;
    659812    if (args.size() > 3) {
    660         QString encStr(args.at(3).toString(exec));
    661         if (encStr == QLatin1String("CodecForTr"))
     813        JSC::UString encStr = args.at(3).toString(exec);
     814        if (encStr == "CodecForTr")
    662815            encoding = QCoreApplication::CodecForTr;
    663         else if (encStr == QLatin1String("UnicodeUTF8"))
     816        else if (encStr == "UnicodeUTF8")
    664817            encoding = QCoreApplication::UnicodeUTF8;
    665818        else
     
    670823        n = args.at(4).toInt32(exec);
    671824#endif
    672     QString result;
     825    JSC::UString result;
    673826#ifndef QT_NO_QOBJECT
    674     result = QCoreApplication::translate(context.toLatin1().constData(),
    675                                          text.toLatin1().constData(),
    676                                          comment.toLatin1().constData(),
     827    result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
     828                                         QScript::convertToLatin1(text).constData(),
     829                                         QScript::convertToLatin1(comment).constData(),
    677830                                         encoding, n);
    678831#else
     
    700853        return JSC::throwError(exec, JSC::GeneralError, "qsTr(): third argument (n) must be a number");
    701854#ifndef QT_NO_QOBJECT
    702     QString context;
     855    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
     856    JSC::UString context;
    703857    // The first non-empty source URL in the call stack determines the translation context.
    704858    {
    705         JSC::ExecState *frame = exec->removeHostCallFrameFlag();
     859        JSC::ExecState *frame = exec->callerFrame()->removeHostCallFrameFlag();
    706860        while (frame) {
    707             if (frame->codeBlock() && frame->codeBlock()->source()
     861            if (frame->codeBlock() && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)
     862                && frame->codeBlock()->source()
    708863                && !frame->codeBlock()->source()->url().isEmpty()) {
    709                 context = QFileInfo(frame->codeBlock()->source()->url()).baseName();
     864                context = engine->translationContextFromUrl(frame->codeBlock()->source()->url());
    710865                break;
    711866            }
     
    714869    }
    715870#endif
    716     QString text(args.at(0).toString(exec));
     871    JSC::UString text = args.at(0).toString(exec);
    717872#ifndef QT_NO_QOBJECT
    718     QString comment;
     873    JSC::UString comment;
    719874    if (args.size() > 1)
    720875        comment = args.at(1).toString(exec);
     
    723878        n = args.at(2).toInt32(exec);
    724879#endif
    725     QString result;
     880    JSC::UString result;
    726881#ifndef QT_NO_QOBJECT
    727     result = QCoreApplication::translate(context.toLatin1().constData(),
    728                                          text.toLatin1().constData(),
    729                                          comment.toLatin1().constData(),
     882    result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
     883                                         QScript::convertToLatin1(text).constData(),
     884                                         QScript::convertToLatin1(comment).constData(),
    730885                                         QCoreApplication::CodecForTr, n);
    731886#else
     
    736891
    737892JSC::JSValue JSC_HOST_CALL functionQsTrNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
     893{
     894    if (args.size() < 1)
     895        return JSC::jsUndefined();
     896    return args.at(0);
     897}
     898
     899JSC::JSValue JSC_HOST_CALL functionQsTrId(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
     900{
     901    if (args.size() < 1)
     902        return JSC::throwError(exec, JSC::GeneralError, "qsTrId() requires at least one argument");
     903    if (!args.at(0).isString())
     904        return JSC::throwError(exec, JSC::TypeError, "qsTrId(): first argument (id) must be a string");
     905    if ((args.size() > 1) && !args.at(1).isNumber())
     906        return JSC::throwError(exec, JSC::TypeError, "qsTrId(): second argument (n) must be a number");
     907    JSC::UString id = args.at(0).toString(exec);
     908    int n = -1;
     909    if (args.size() > 1)
     910        n = args.at(1).toInt32(exec);
     911    return JSC::jsString(exec, qtTrId(QScript::convertToLatin1(id).constData(), n));
     912}
     913
     914JSC::JSValue JSC_HOST_CALL functionQsTrIdNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
    738915{
    739916    if (args.size() < 1)
     
    793970    }
    794971    JSC::initializeThreading();
    795 
     972    JSC::IdentifierTable *oldTable = JSC::currentIdentifierTable();
    796973    globalData = JSC::JSGlobalData::create().releaseRef();
    797974    globalData->clientData = new QScript::GlobalClientData(this);
     
    801978
    802979    scriptObjectStructure = QScriptObject::createStructure(globalObject->objectPrototype());
     980    staticScopeObjectStructure = QScriptStaticScopeObject::createStructure(JSC::jsNull());
    803981
    804982    qobjectPrototype = new (exec) QScript::QObjectPrototype(exec, QScript::QObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure());
     
    8291007    agentLineNumber = -1;
    8301008    processEventsInterval = -1;
     1009    cachedTranslationUrl = JSC::UString();
     1010    cachedTranslationContext = JSC::UString();
     1011    JSC::setCurrentIdentifierTable(oldTable);
    8311012}
    8321013
    8331014QScriptEnginePrivate::~QScriptEnginePrivate()
    8341015{
     1016    QScript::APIShim shim(this);
     1017
    8351018    //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events
    8361019    QHash<intptr_t,QScript::UStringSourceProviderWithFeedback*>::const_iterator it;
     
    8411024        delete ownedAgents.takeFirst();
    8421025
     1026    detachAllRegisteredScriptPrograms();
    8431027    detachAllRegisteredScriptValues();
    8441028    detachAllRegisteredScriptStrings();
    8451029    qDeleteAll(m_qobjectData);
    8461030    qDeleteAll(m_typeInfos);
    847     JSC::JSLock lock(false);
    8481031    globalData->heap.destroy();
    8491032    globalData->deref();
     
    8551038}
    8561039
    857 QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v)
    858 {
    859     Q_Q(QScriptEngine);
    860     QScriptValue result = q->create(v.userType(), v.data());
    861     Q_ASSERT(result.isValid());
    862     return result;
    863 }
    864 
    865 QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, int targetType)
     1040QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType)
    8661041{
    8671042    QVariant v(targetType, (void *)0);
    868     if (QScriptEnginePrivate::convert(value, targetType, v.data(), this))
     1043    if (convertValue(exec, value, targetType, v.data()))
    8691044        return v;
    8701045    if (uint(targetType) == QVariant::LastType)
    871         return value.toVariant();
    872     if (value.isVariant()) {
    873         v = value.toVariant();
     1046        return toVariant(exec, value);
     1047    if (isVariant(value)) {
     1048        v = variantValue(value);
    8741049        if (v.canConvert(QVariant::Type(targetType))) {
    8751050            v.convert(QVariant::Type(targetType));
     
    8821057        }
    8831058    }
    884 
    8851059    return QVariant();
    8861060}
    8871061
    888 JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(const QVariant &v)
    889 {
    890     // ### it's inefficient to convert to QScriptValue and then to JSValue
    891     QScriptValue vv = scriptValueFromVariant(v);
    892     QScriptValuePrivate *p = QScriptValuePrivate::get(vv);
    893     switch (p->type) {
    894     case QScriptValuePrivate::JavaScriptCore:
    895         return p->jscValue;
    896     case QScriptValuePrivate::Number:
    897         return JSC::jsNumber(currentFrame, p->numberValue);
    898     case QScriptValuePrivate::String: {
    899         JSC::UString str = p->stringValue;
    900         return JSC::jsString(currentFrame, str);
    901       }
    902     }
    903     return JSC::JSValue();
    904 }
    905 
    906 QVariant QScriptEnginePrivate::jscValueToVariant(JSC::JSValue value, int targetType)
    907 {
    908     // ### it's inefficient to convert to QScriptValue and then to QVariant
    909     return scriptValueToVariant(scriptValueFromJSCValue(value), targetType);
    910 }
    911 
    912 QScriptValue QScriptEnginePrivate::arrayFromStringList(const QStringList &lst)
    913 {
    914     Q_Q(QScriptEngine);
    915     QScriptValue arr = q->newArray(lst.size());
     1062JSC::JSValue QScriptEnginePrivate::arrayFromStringList(JSC::ExecState *exec, const QStringList &lst)
     1063{
     1064    JSC::JSValue arr =  newArray(exec, lst.size());
    9161065    for (int i = 0; i < lst.size(); ++i)
    917         arr.setProperty(i, QScriptValue(q, lst.at(i)));
     1066        setProperty(exec, arr, i, JSC::jsString(exec, lst.at(i)));
    9181067    return arr;
    9191068}
    9201069
    921 QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValue &arr)
     1070QStringList QScriptEnginePrivate::stringListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
    9221071{
    9231072    QStringList lst;
    924     uint len = arr.property(QLatin1String("length")).toUInt32();
     1073    uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
    9251074    for (uint i = 0; i < len; ++i)
    926         lst.append(arr.property(i).toString());
     1075        lst.append(toString(exec, property(exec, arr, i)));
    9271076    return lst;
    9281077}
    9291078
    930 QScriptValue QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst)
    931 {
    932     Q_Q(QScriptEngine);
    933     QScriptValue arr = q->newArray(lst.size());
     1079JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, const QVariantList &lst)
     1080{
     1081    JSC::JSValue arr = newArray(exec, lst.size());
    9341082    for (int i = 0; i < lst.size(); ++i)
    935         arr.setProperty(i, scriptValueFromVariant(lst.at(i)));
     1083        setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i)));
    9361084    return arr;
    9371085}
    9381086
    939 QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValue &arr)
    940 {
     1087QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSArray *arr)
     1088{
     1089    QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
     1090    if (eng->visitedConversionObjects.contains(arr))
     1091        return QVariantList(); // Avoid recursion.
     1092    eng->visitedConversionObjects.insert(arr);
    9411093    QVariantList lst;
    942     uint len = arr.property(QLatin1String("length")).toUInt32();
     1094    uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
    9431095    for (uint i = 0; i < len; ++i)
    944         lst.append(arr.property(i).toVariant());
     1096        lst.append(toVariant(exec, property(exec, arr, i)));
     1097    eng->visitedConversionObjects.remove(arr);
    9451098    return lst;
    9461099}
    9471100
    948 QScriptValue QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap)
    949 {
    950     Q_Q(QScriptEngine);
    951     QScriptValue obj = q->newObject();
     1101JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap)
     1102{
     1103    JSC::JSValue obj = JSC::constructEmptyObject(exec);
    9521104    QVariantMap::const_iterator it;
    9531105    for (it = vmap.constBegin(); it != vmap.constEnd(); ++it)
    954         obj.setProperty(it.key(), scriptValueFromVariant(it.value()));
     1106        setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value()));
    9551107    return obj;
    9561108}
    9571109
    958 QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValue &obj)
    959 {
     1110QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSObject *obj)
     1111{
     1112    QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
     1113    if (eng->visitedConversionObjects.contains(obj))
     1114        return QVariantMap(); // Avoid recursion.
     1115    eng->visitedConversionObjects.insert(obj);
     1116    JSC::PropertyNameArray propertyNames(exec);
     1117    obj->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
    9601118    QVariantMap vmap;
    961     QScriptValueIterator it(obj);
    962     while (it.hasNext()) {
    963         it.next();
    964         vmap.insert(it.name(), it.value().toVariant());
    965     }
     1119    JSC::PropertyNameArray::const_iterator it = propertyNames.begin();
     1120    for( ; it != propertyNames.end(); ++it)
     1121        vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it)));
     1122    eng->visitedConversionObjects.remove(obj);
    9661123    return vmap;
    9671124}
     
    11601317void QScriptEnginePrivate::collectGarbage()
    11611318{
    1162     JSC::JSLock lock(false);
    1163     globalData->heap.collect();
     1319    QScript::APIShim shim(this);
     1320    globalData->heap.collectAllGarbage();
     1321}
     1322
     1323void QScriptEnginePrivate::reportAdditionalMemoryCost(int size)
     1324{
     1325    if (size > 0)
     1326        globalData->heap.reportExtraMemoryCost(size);
    11641327}
    11651328
     
    11831346{
    11841347    Q_Q(QScriptEngine);
    1185     JSC::JSLock lock(false); // ### hmmm
    11861348    QBoolBlocker inEvalBlocker(inEval, true);
    11871349    q->currentContext()->activationObject(); //force the creation of a context for native function;
     
    11921354
    11931355    q->clearExceptions();
    1194     JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject());
     1356    JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject);
    11951357
    11961358    if (compile) {
     
    12961458}
    12971459
    1298 bool QScriptEnginePrivate::convertToNativeQObject(const QScriptValue &value,
     1460bool QScriptEnginePrivate::convertToNativeQObject(JSC::ExecState *exec, JSC::JSValue value,
    12991461                                                  const QByteArray &targetType,
    13001462                                                  void **result)
     
    13021464    if (!targetType.endsWith('*'))
    13031465        return false;
    1304     if (QObject *qobject = value.toQObject()) {
     1466    if (QObject *qobject = toQObject(exec, value)) {
    13051467        int start = targetType.startsWith("const ") ? 6 : 0;
    13061468        QByteArray className = targetType.mid(start, targetType.size()-start-1);
     
    14171579#endif
    14181580
     1581void QScriptEnginePrivate::detachAllRegisteredScriptPrograms()
     1582{
     1583    QSet<QScriptProgramPrivate*>::const_iterator it;
     1584    for (it = registeredScriptPrograms.constBegin(); it != registeredScriptPrograms.constEnd(); ++it)
     1585        (*it)->detachFromEngine();
     1586    registeredScriptPrograms.clear();
     1587}
     1588
    14191589void QScriptEnginePrivate::detachAllRegisteredScriptValues()
    14201590{
     
    14431613}
    14441614
    1445 #ifdef QT_NO_QOBJECT
    1446 
    1447 QScriptEngine::QScriptEngine()
    1448     : d_ptr(new QScriptEnginePrivate)
    1449 {
    1450     d_ptr->q_ptr = this;
    1451 }
    1452 
    1453 /*! \internal
    1454 */
    1455 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd)
    1456     : d_ptr(&dd)
    1457 {
    1458     d_ptr->q_ptr = this;
    1459 }
    1460 #else
    1461 
    1462 /*!
    1463     Constructs a QScriptEngine object.
    1464 
    1465     The globalObject() is initialized to have properties as described in
    1466     \l{ECMA-262}, Section 15.1.
    1467 */
    1468 QScriptEngine::QScriptEngine()
    1469     : QObject(*new QScriptEnginePrivate, 0)
    1470 {
    1471 }
    1472 
    1473 /*!
    1474     Constructs a QScriptEngine object with the given \a parent.
    1475 
    1476     The globalObject() is initialized to have properties as described in
    1477     \l{ECMA-262}, Section 15.1.
    1478 */
    1479 
    1480 QScriptEngine::QScriptEngine(QObject *parent)
    1481     : QObject(*new QScriptEnginePrivate, parent)
    1482 {
    1483 }
    1484 
    1485 /*! \internal
    1486 */
    1487 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent)
    1488     : QObject(dd, parent)
    1489 {
    1490 }
    1491 #endif
    1492 
    1493 /*!
    1494   Destroys this QScriptEngine.
    1495 */
    1496 QScriptEngine::~QScriptEngine()
    1497 {
    1498 #ifdef QT_NO_QOBJECT
    1499     delete d_ptr;
    1500     d_ptr = 0;
    1501 #endif
    1502 }
    1503 
    1504 /*!
    1505   Returns this engine's Global Object.
    1506 
    1507   By default, the Global Object contains the built-in objects that are
    1508   part of \l{ECMA-262}, such as Math, Date and String. Additionally,
    1509   you can set properties of the Global Object to make your own
    1510   extensions available to all script code. Non-local variables in
    1511   script code will be created as properties of the Global Object, as
    1512   well as local variables in global code.
    1513 */
    1514 QScriptValue QScriptEngine::globalObject() const
    1515 {
    1516     Q_D(const QScriptEngine);
    1517     JSC::JSObject *result = d->globalObject();
    1518     return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result);
    1519 }
    1520 
    1521 /*!
    1522   \since 4.5
    1523 
    1524   Sets this engine's Global Object to be the given \a object.
    1525   If \a object is not a valid script object, this function does
    1526   nothing.
    1527 
    1528   When setting a custom global object, you may want to use
    1529   QScriptValueIterator to copy the properties of the standard Global
    1530   Object; alternatively, you can set the internal prototype of your
    1531   custom object to be the original Global Object.
    1532 */
    1533 void QScriptEngine::setGlobalObject(const QScriptValue &object)
    1534 {
    1535     Q_D(QScriptEngine);
    1536     if (!object.isObject())
    1537         return;
    1538     JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object));
    1539     d->setGlobalObject(jscObject);
    1540 }
    1541 
    1542 /*!
    1543   Returns a QScriptValue of the primitive type Null.
    1544 
    1545   \sa undefinedValue()
    1546 */
    1547 QScriptValue QScriptEngine::nullValue()
    1548 {
    1549     Q_D(QScriptEngine);
    1550     return d->scriptValueFromJSCValue(JSC::jsNull());
    1551 }
    1552 
    1553 /*!
    1554   Returns a QScriptValue of the primitive type Undefined.
    1555 
    1556   \sa nullValue()
    1557 */
    1558 QScriptValue QScriptEngine::undefinedValue()
    1559 {
    1560     Q_D(QScriptEngine);
    1561     return d->scriptValueFromJSCValue(JSC::jsUndefined());
    1562 }
    1563 
    1564 /*!
    1565   Creates a constructor function from \a fun, with the given \a length.
    1566   The \c{prototype} property of the resulting function is set to be the
    1567   given \a prototype. The \c{constructor} property of \a prototype is
    1568   set to be the resulting function.
    1569 
    1570   When a function is called as a constructor (e.g. \c{new Foo()}), the
    1571   `this' object associated with the function call is the new object
    1572   that the function is expected to initialize; the prototype of this
    1573   default constructed object will be the function's public
    1574   \c{prototype} property. If you always want the function to behave as
    1575   a constructor (e.g. \c{Foo()} should also create a new object), or
    1576   if you need to create your own object rather than using the default
    1577   `this' object, you should make sure that the prototype of your
    1578   object is set correctly; either by setting it manually, or, when
    1579   wrapping a custom type, by having registered the defaultPrototype()
    1580   of that type. Example:
    1581 
    1582   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
    1583 
    1584   To wrap a custom type and provide a constructor for it, you'd typically
    1585   do something like this:
    1586 
    1587   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
    1588 */
    1589 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun,
    1590                                         const QScriptValue &prototype,
    1591                                         int length)
    1592 {
    1593     Q_D(QScriptEngine);
    1594     JSC::ExecState* exec = d->currentFrame;
    1595     JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
    1596     QScriptValue result = d->scriptValueFromJSCValue(function);
    1597     result.setProperty(QLatin1String("prototype"), prototype, QScriptValue::Undeletable);
    1598     const_cast<QScriptValue&>(prototype)
    1599         .setProperty(QLatin1String("constructor"), result,
    1600                      QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    1601     return result;
    1602 }
    1603 
    16041615#ifndef QT_NO_REGEXP
    16051616
    1606 Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
    1607 
    1608 /*!
    1609   Creates a QtScript object of class RegExp with the given
    1610   \a regexp.
    1611 
    1612   \sa QScriptValue::toRegExp()
    1613 */
    1614 QScriptValue QScriptEngine::newRegExp(const QRegExp &regexp)
    1615 {
    1616     Q_D(QScriptEngine);
    1617     JSC::ExecState* exec = d->currentFrame;
     1617Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
     1618
     1619JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp &regexp)
     1620{
    16181621    JSC::JSValue buf[2];
    16191622    JSC::ArgList args(buf, sizeof(buf));
     
    16481651            case ']':
    16491652                inBracket = false;
    1650                 break;
     1653               break;
    16511654            default:
    16521655                break;
     
    16631666    buf[0] = JSC::jsString(exec, jscPattern);
    16641667    buf[1] = JSC::jsString(exec, jscFlags);
    1665     JSC::JSObject* result = JSC::constructRegExp(exec, args);
    1666     return d->scriptValueFromJSCValue(result);
    1667 }
    1668 
    1669 #endif // QT_NO_REGEXP
    1670 
    1671 /*!
    1672   Creates a QtScript object holding the given variant \a value.
    1673 
    1674   If a default prototype has been registered with the meta type id of
    1675   \a value, then the prototype of the created object will be that
    1676   prototype; otherwise, the prototype will be the Object prototype
    1677   object.
    1678 
    1679   \sa setDefaultPrototype(), QScriptValue::toVariant()
    1680 */
    1681 QScriptValue QScriptEngine::newVariant(const QVariant &value)
    1682 {
    1683     Q_D(QScriptEngine);
    1684     JSC::ExecState* exec = d->currentFrame;
    1685     QScriptObject *obj = new (exec) QScriptObject(d->variantWrapperObjectStructure);
    1686     obj->setDelegate(new QScript::QVariantDelegate(value));
    1687     QScriptValue result = d->scriptValueFromJSCValue(obj);
    1688     QScriptValue proto = defaultPrototype(value.userType());
    1689     if (proto.isValid())
    1690         result.setPrototype(proto);
    1691     return result;
    1692 }
    1693 
    1694 /*!
    1695   \since 4.4
    1696   \overload
    1697 
    1698   Initializes the given Qt Script \a object to hold the given variant
    1699   \a value, and returns the \a object.
    1700 
    1701   This function enables you to "promote" a plain Qt Script object
    1702   (created by the newObject() function) to a variant, or to replace
    1703   the variant contained inside an object previously created by the
    1704   newVariant() function.
    1705 
    1706   The prototype() of the \a object will remain unchanged.
    1707 
    1708   If \a object is not an object, this function behaves like the normal
    1709   newVariant(), i.e. it creates a new script object and returns it.
    1710 
    1711   This function is useful when you want to provide a script
    1712   constructor for a C++ type. If your constructor is invoked in a
    1713   \c{new} expression (QScriptContext::isCalledAsConstructor() returns
    1714   true), you can pass QScriptContext::thisObject() (the default
    1715   constructed script object) to this function to initialize the new
    1716   object.
    1717 */
    1718 QScriptValue QScriptEngine::newVariant(const QScriptValue &object,
    1719                                        const QVariant &value)
    1720 {
    1721     if (!object.isObject())
    1722         return newVariant(value);
    1723     JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(object)->jscValue);
    1724     if (!jscObject->inherits(&QScriptObject::info)) {
    1725         qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
    1726         return QScriptValue();
    1727     }
    1728     QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
    1729     if (!object.isVariant()) {
    1730         jscScriptObject->setDelegate(new QScript::QVariantDelegate(value));
    1731     } else {
    1732         QScriptValuePrivate::get(object)->setVariantValue(value);
    1733     }
    1734     return object;
    1735 }
    1736 
    1737 #ifndef QT_NO_QOBJECT
    1738 /*!
    1739   Creates a QtScript object that wraps the given QObject \a
    1740   object, using the given \a ownership. The given \a options control
    1741   various aspects of the interaction with the resulting script object.
    1742 
    1743   Signals and slots, properties and children of \a object are
    1744   available as properties of the created QScriptValue. For more
    1745   information, see the \l{QtScript} documentation.
    1746 
    1747   If \a object is a null pointer, this function returns nullValue().
    1748 
    1749   If a default prototype has been registered for the \a object's class
    1750   (or its superclass, recursively), the prototype of the new script
    1751   object will be set to be that default prototype.
    1752 
    1753   If the given \a object is deleted outside of QtScript's control, any
    1754   attempt to access the deleted QObject's members through the QtScript
    1755   wrapper object (either by script code or C++) will result in a
    1756   script exception.
    1757 
    1758   \sa QScriptValue::toQObject()
    1759 */
    1760 QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership,
    1761                                        const QObjectWrapOptions &options)
    1762 {
    1763     Q_D(QScriptEngine);
    1764     JSC::JSValue jscQObject = d->newQObject(object, ownership, options);
    1765     return d->scriptValueFromJSCValue(jscQObject);
    1766 }
    1767 
    1768 /*!
    1769   \since 4.4
    1770   \overload
    1771 
    1772   Initializes the given \a scriptObject to hold the given \a qtObject,
    1773   and returns the \a scriptObject.
    1774 
    1775   This function enables you to "promote" a plain Qt Script object
    1776   (created by the newObject() function) to a QObject proxy, or to
    1777   replace the QObject contained inside an object previously created by
    1778   the newQObject() function.
    1779 
    1780   The prototype() of the \a scriptObject will remain unchanged.
    1781 
    1782   If \a scriptObject is not an object, this function behaves like the
    1783   normal newQObject(), i.e. it creates a new script object and returns
    1784   it.
    1785 
    1786   This function is useful when you want to provide a script
    1787   constructor for a QObject-based class. If your constructor is
    1788   invoked in a \c{new} expression
    1789   (QScriptContext::isCalledAsConstructor() returns true), you can pass
    1790   QScriptContext::thisObject() (the default constructed script object)
    1791   to this function to initialize the new object.
    1792 */
    1793 QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject,
    1794                                        QObject *qtObject,
    1795                                        ValueOwnership ownership,
    1796                                        const QObjectWrapOptions &options)
    1797 {
    1798     if (!scriptObject.isObject())
    1799         return newQObject(qtObject, ownership, options);
    1800     JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue);
    1801     if (!jscObject->inherits(&QScriptObject::info)) {
    1802         qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported");
    1803         return QScriptValue();
    1804     }
    1805     QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
    1806     if (!scriptObject.isQObject()) {
    1807         jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options));
    1808     } else {
    1809         QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate());
    1810         delegate->setValue(qtObject);
    1811         delegate->setOwnership(ownership);
    1812         delegate->setOptions(options);
    1813     }
    1814     return scriptObject;
    1815 }
    1816 
    1817 #endif // QT_NO_QOBJECT
    1818 
    1819 /*!
    1820   Creates a QtScript object of class Object.
    1821 
    1822   The prototype of the created object will be the Object
    1823   prototype object.
    1824 
    1825   \sa newArray(), QScriptValue::setProperty()
    1826 */
    1827 QScriptValue QScriptEngine::newObject()
    1828 {
    1829     Q_D(QScriptEngine);
    1830     JSC::ExecState* exec = d->currentFrame;
    1831     JSC::JSObject *result = new (exec)QScriptObject(d->scriptObjectStructure);
    1832     return d->scriptValueFromJSCValue(result);
    1833 }
    1834 
    1835 /*!
    1836   \since 4.4
    1837   \overload
    1838 
    1839   Creates a QtScript Object of the given class, \a scriptClass.
    1840 
    1841   The prototype of the created object will be the Object
    1842   prototype object.
    1843 
    1844   \a data, if specified, is set as the internal data of the
    1845   new object (using QScriptValue::setData()).
    1846 
    1847   \sa QScriptValue::scriptClass()
    1848 */
    1849 QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass,
    1850                                       const QScriptValue &data)
    1851 {
    1852     Q_D(QScriptEngine);
    1853     JSC::ExecState* exec = d->currentFrame;
    1854     QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure);
    1855     result->setDelegate(new QScript::ClassObjectDelegate(scriptClass));
    1856     QScriptValue scriptObject = d->scriptValueFromJSCValue(result);
    1857     scriptObject.setData(data);
    1858     QScriptValue proto = scriptClass->prototype();
    1859     if (proto.isValid())
    1860         scriptObject.setPrototype(proto);
    1861     return scriptObject;
    1862 }
    1863 
    1864 /*!
    1865   \internal
    1866 */
    1867 QScriptValue QScriptEngine::newActivationObject()
    1868 {
    1869     qWarning("QScriptEngine::newActivationObject() not implemented");
    1870     // ### JSActivation or JSVariableObject?
    1871     return QScriptValue();
    1872 }
    1873 
    1874 /*!
    1875   Creates a QScriptValue that wraps a native (C++) function. \a fun
    1876   must be a C++ function with signature QScriptEngine::FunctionSignature.  \a
    1877   length is the number of arguments that \a fun expects; this becomes
    1878   the \c{length} property of the created QScriptValue.
    1879 
    1880   Note that \a length only gives an indication of the number of
    1881   arguments that the function expects; an actual invocation of a
    1882   function can include any number of arguments. You can check the
    1883   \l{QScriptContext::argumentCount()}{argumentCount()} of the
    1884   QScriptContext associated with the invocation to determine the
    1885   actual number of arguments passed.
    1886 
    1887   A \c{prototype} property is automatically created for the resulting
    1888   function object, to provide for the possibility that the function
    1889   will be used as a constructor.
    1890 
    1891   By combining newFunction() and the property flags
    1892   QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
    1893   can create script object properties that behave like normal
    1894   properties in script code, but are in fact accessed through
    1895   functions (analogous to how properties work in \l{Qt's Property
    1896   System}). Example:
    1897 
    1898   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
    1899 
    1900   When the property \c{foo} of the script object is subsequently
    1901   accessed in script code, \c{getSetFoo()} will be invoked to handle
    1902   the access.  In this particular case, we chose to store the "real"
    1903   value of \c{foo} as a property of the accessor function itself; you
    1904   are of course free to do whatever you like in this function.
    1905 
    1906   In the above example, a single native function was used to handle
    1907   both reads and writes to the property; the argument count is used to
    1908   determine if we are handling a read or write. You can also use two
    1909   separate functions; just specify the relevant flag
    1910   (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
    1911   setting the property, e.g.:
    1912 
    1913   \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
    1914 
    1915   \sa QScriptValue::call()
    1916 */
    1917 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
    1918 {
    1919     Q_D(QScriptEngine);
    1920     JSC::ExecState* exec = d->currentFrame;
    1921     JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
    1922     QScriptValue result = d->scriptValueFromJSCValue(function);
    1923     QScriptValue proto = newObject();
    1924     result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
    1925     proto.setProperty(QLatin1String("constructor"), result,
    1926                       QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    1927     return result;
    1928 }
    1929 
    1930 /*!
    1931   \internal
    1932   \since 4.4
    1933 */
    1934 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg)
    1935 {
    1936     Q_D(QScriptEngine);
    1937     JSC::ExecState* exec = d->currentFrame;
    1938     JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg);
    1939     QScriptValue result = d->scriptValueFromJSCValue(function);
    1940     QScriptValue proto = newObject();
    1941     result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
    1942     proto.setProperty(QLatin1String("constructor"), result,
    1943                       QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    1944     return result;
    1945 }
    1946 
    1947 /*!
    1948   Creates a QtScript object of class Array with the given \a length.
    1949 
    1950   \sa newObject()
    1951 */
    1952 QScriptValue QScriptEngine::newArray(uint length)
    1953 {
    1954     Q_D(QScriptEngine);
    1955     JSC::ExecState* exec = d->currentFrame;
    1956     JSC::JSArray* result = JSC::constructEmptyArray(exec, length);
    1957     return d->scriptValueFromJSCValue(result);
    1958 }
    1959 
    1960 /*!
    1961   Creates a QtScript object of class RegExp with the given
    1962   \a pattern and \a flags.
    1963 
    1964   The legal flags are 'g' (global), 'i' (ignore case), and 'm'
    1965   (multiline).
    1966 */
    1967 QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags)
    1968 {
    1969     Q_D(QScriptEngine);
    1970     JSC::ExecState* exec = d->currentFrame;
     1668    return JSC::constructRegExp(exec, args);
     1669}
     1670
     1671#endif
     1672
     1673JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QString &pattern, const QString &flags)
     1674{
    19711675    JSC::JSValue buf[2];
    19721676    JSC::ArgList args(buf, sizeof(buf));
     
    19821686    buf[0] = JSC::jsString(exec, jscPattern);
    19831687    buf[1] = JSC::jsString(exec, jscFlags);
    1984     JSC::JSObject* result = JSC::constructRegExp(exec, args);
    1985     return d->scriptValueFromJSCValue(result);
     1688    return JSC::constructRegExp(exec, args);
     1689}
     1690
     1691JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value)
     1692{
     1693    QScriptObject *obj = new (currentFrame) QScriptObject(variantWrapperObjectStructure);
     1694    obj->setDelegate(new QScript::QVariantDelegate(value));
     1695    JSC::JSValue proto = defaultPrototype(value.userType());
     1696    if (proto)
     1697        obj->setPrototype(proto);
     1698    return obj;
     1699}
     1700
     1701JSC::JSValue QScriptEnginePrivate::newVariant(JSC::JSValue objectValue,
     1702                                              const QVariant &value)
     1703{
     1704    if (!isObject(objectValue))
     1705        return newVariant(value);
     1706    JSC::JSObject *jscObject = JSC::asObject(objectValue);
     1707    if (!jscObject->inherits(&QScriptObject::info)) {
     1708        qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
     1709        return JSC::JSValue();
     1710    }
     1711    QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
     1712    if (!isVariant(objectValue)) {
     1713        jscScriptObject->setDelegate(new QScript::QVariantDelegate(value));
     1714    } else {
     1715        setVariantValue(objectValue, value);
     1716    }
     1717    return objectValue;
     1718}
     1719
     1720#ifndef QT_NO_REGEXP
     1721
     1722QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value)
     1723{
     1724    if (!isRegExp(value))
     1725        return QRegExp();
     1726    QString pattern = toString(exec, property(exec, value, "source", QScriptValue::ResolvePrototype));
     1727    Qt::CaseSensitivity kase = Qt::CaseSensitive;
     1728    if (toBool(exec, property(exec, value, "ignoreCase", QScriptValue::ResolvePrototype)))
     1729        kase = Qt::CaseInsensitive;
     1730    return QRegExp(pattern, kase, QRegExp::RegExp2);
     1731}
     1732
     1733#endif
     1734
     1735QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue value)
     1736{
     1737    if (!value) {
     1738        return QVariant();
     1739    } else if (isObject(value)) {
     1740        if (isVariant(value))
     1741            return variantValue(value);
     1742#ifndef QT_NO_QOBJECT
     1743        else if (isQObject(value))
     1744            return qVariantFromValue(toQObject(exec, value));
     1745#endif
     1746        else if (isDate(value))
     1747            return QVariant(toDateTime(exec, value));
     1748#ifndef QT_NO_REGEXP
     1749        else if (isRegExp(value))
     1750            return QVariant(toRegExp(exec, value));
     1751#endif
     1752        else if (isArray(value))
     1753            return variantListFromArray(exec, JSC::asArray(value));
     1754        else if (QScriptDeclarativeClass *dc = declarativeClass(value))
     1755            return dc->toVariant(declarativeObject(value));
     1756        return variantMapFromObject(exec, JSC::asObject(value));
     1757    } else if (value.isNumber()) {
     1758        return QVariant(toNumber(exec, value));
     1759    } else if (value.isString()) {
     1760        return QVariant(toString(exec, value));
     1761    } else if (value.isBoolean()) {
     1762        return QVariant(toBool(exec, value));
     1763    }
     1764    return QVariant();
     1765}
     1766
     1767JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode)
     1768{
     1769    JSC::JSValue result;
     1770    if (!(resolveMode & QScriptValue::ResolvePrototype)) {
     1771        // Look in the object's own properties
     1772        JSC::JSObject *object = JSC::asObject(value);
     1773        JSC::PropertySlot slot(object);
     1774        if (object->getOwnPropertySlot(exec, id, slot))
     1775            result = slot.getValue(exec, id);
     1776    }
     1777    if (!result && (resolveMode & QScriptValue::ResolveScope)) {
     1778        // ### check if it's a function object and look in the scope chain
     1779        JSC::JSValue scope = property(exec, value, "__qt_scope__", QScriptValue::ResolveLocal);
     1780        if (isObject(scope))
     1781            result = property(exec, scope, id, resolveMode);
     1782    }
     1783    return result;
     1784}
     1785
     1786JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode)
     1787{
     1788    JSC::JSValue result;
     1789    if (!(resolveMode & QScriptValue::ResolvePrototype)) {
     1790        // Look in the object's own properties
     1791        JSC::JSObject *object = JSC::asObject(value);
     1792        JSC::PropertySlot slot(object);
     1793        if (object->getOwnPropertySlot(exec, index, slot))
     1794            result = slot.getValue(exec, index);
     1795    }
     1796    return result;
     1797}
     1798
     1799void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::Identifier &id,
     1800                                       JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
     1801{
     1802    JSC::JSObject *thisObject = JSC::asObject(objectValue);
     1803    JSC::JSValue setter = thisObject->lookupSetter(exec, id);
     1804    JSC::JSValue getter = thisObject->lookupGetter(exec, id);
     1805    if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
     1806        if (!value) {
     1807            // deleting getter/setter
     1808            if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) {
     1809                // deleting both: just delete the property
     1810                thisObject->deleteProperty(exec, id);
     1811            } else if (flags & QScriptValue::PropertyGetter) {
     1812                // preserve setter, if there is one
     1813                thisObject->deleteProperty(exec, id);
     1814                if (setter && setter.isObject())
     1815                    thisObject->defineSetter(exec, id, JSC::asObject(setter));
     1816            } else { // flags & QScriptValue::PropertySetter
     1817                // preserve getter, if there is one
     1818                thisObject->deleteProperty(exec, id);
     1819                if (getter && getter.isObject())
     1820                    thisObject->defineGetter(exec, id, JSC::asObject(getter));
     1821            }
     1822        } else {
     1823            if (value.isObject()) { // ### should check if it has callData()
     1824                // defining getter/setter
     1825                if (id == exec->propertyNames().underscoreProto) {
     1826                    qWarning("QScriptValue::setProperty() failed: "
     1827                             "cannot set getter or setter of native property `__proto__'");
     1828                } else {
     1829                    if (flags & QScriptValue::PropertyGetter)
     1830                        thisObject->defineGetter(exec, id, JSC::asObject(value));
     1831                    if (flags & QScriptValue::PropertySetter)
     1832                        thisObject->defineSetter(exec, id, JSC::asObject(value));
     1833                }
     1834            } else {
     1835                qWarning("QScriptValue::setProperty(): getter/setter must be a function");
     1836            }
     1837        }
     1838    } else {
     1839        // setting the value
     1840        if (getter && getter.isObject() && !(setter && setter.isObject())) {
     1841            qWarning("QScriptValue::setProperty() failed: "
     1842                     "property '%s' has a getter but no setter",
     1843                     qPrintable(QString(id.ustring())));
     1844            return;
     1845        }
     1846        if (!value) {
     1847            // ### check if it's a getter/setter property
     1848            thisObject->deleteProperty(exec, id);
     1849        } else if (flags != QScriptValue::KeepExistingFlags) {
     1850            if (thisObject->hasOwnProperty(exec, id))
     1851                thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes?
     1852            thisObject->putWithAttributes(exec, id, value, propertyFlagsToJSCAttributes(flags));
     1853        } else {
     1854            JSC::PutPropertySlot slot;
     1855            thisObject->put(exec, id, value, slot);
     1856        }
     1857    }
     1858}
     1859
     1860void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, quint32 index,
     1861                                       JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
     1862{
     1863    if (!value) {
     1864        JSC::asObject(objectValue)->deleteProperty(exec, index);
     1865    } else {
     1866        if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
     1867            // fall back to string-based setProperty(), since there is no
     1868            // JSC::JSObject::defineGetter(unsigned)
     1869            setProperty(exec, objectValue, JSC::Identifier::from(exec, index), value, flags);
     1870        } else {
     1871            if (flags != QScriptValue::KeepExistingFlags) {
     1872                //                if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex))
     1873                //                    JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex);
     1874                unsigned attribs = 0;
     1875                if (flags & QScriptValue::ReadOnly)
     1876                    attribs |= JSC::ReadOnly;
     1877                if (flags & QScriptValue::SkipInEnumeration)
     1878                    attribs |= JSC::DontEnum;
     1879                if (flags & QScriptValue::Undeletable)
     1880                    attribs |= JSC::DontDelete;
     1881                attribs |= flags & QScriptValue::UserRange;
     1882                JSC::asObject(objectValue)->putWithAttributes(exec, index, value, attribs);
     1883            } else {
     1884                JSC::asObject(objectValue)->put(exec, index, value);
     1885            }
     1886        }
     1887    }
     1888}
     1889
     1890QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id,
     1891                                                                const QScriptValue::ResolveFlags &mode)
     1892{
     1893    JSC::JSObject *object = JSC::asObject(value);
     1894    unsigned attribs = 0;
     1895    JSC::PropertyDescriptor descriptor;
     1896    if (object->getOwnPropertyDescriptor(exec, id, descriptor))
     1897        attribs = descriptor.attributes();
     1898    else {
     1899        if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
     1900            JSC::JSValue proto = object->prototype();
     1901            return propertyFlags(exec, proto, id, mode);
     1902        }
     1903        return 0;
     1904    }
     1905    QScriptValue::PropertyFlags result = 0;
     1906    if (attribs & JSC::ReadOnly)
     1907        result |= QScriptValue::ReadOnly;
     1908    if (attribs & JSC::DontEnum)
     1909        result |= QScriptValue::SkipInEnumeration;
     1910    if (attribs & JSC::DontDelete)
     1911        result |= QScriptValue::Undeletable;
     1912    //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?)
     1913    if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull())
     1914        result |= QScriptValue::PropertyGetter;
     1915    if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull())
     1916        result |= QScriptValue::PropertySetter;
     1917#ifndef QT_NO_QOBJECT
     1918    if (attribs & QScript::QObjectMemberAttribute)
     1919        result |= QScriptValue::QObjectMember;
     1920#endif
     1921    result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange);
     1922    return result;
     1923}
     1924
     1925QScriptString QScriptEnginePrivate::toStringHandle(const JSC::Identifier &name)
     1926{
     1927    QScriptString result;
     1928    QScriptStringPrivate *p = new QScriptStringPrivate(this, name, QScriptStringPrivate::HeapAllocated);
     1929    QScriptStringPrivate::init(result, p);
     1930    registerScriptString(p);
     1931    return result;
     1932}
     1933
     1934#ifdef QT_NO_QOBJECT
     1935
     1936QScriptEngine::QScriptEngine()
     1937    : d_ptr(new QScriptEnginePrivate)
     1938{
     1939    d_ptr->q_ptr = this;
     1940}
     1941
     1942/*! \internal
     1943*/
     1944QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd)
     1945    : d_ptr(&dd)
     1946{
     1947    d_ptr->q_ptr = this;
     1948}
     1949#else
     1950
     1951/*!
     1952    Constructs a QScriptEngine object.
     1953
     1954    The globalObject() is initialized to have properties as described in
     1955    \l{ECMA-262}, Section 15.1.
     1956*/
     1957QScriptEngine::QScriptEngine()
     1958    : QObject(*new QScriptEnginePrivate, 0)
     1959{
     1960}
     1961
     1962/*!
     1963    Constructs a QScriptEngine object with the given \a parent.
     1964
     1965    The globalObject() is initialized to have properties as described in
     1966    \l{ECMA-262}, Section 15.1.
     1967*/
     1968
     1969QScriptEngine::QScriptEngine(QObject *parent)
     1970    : QObject(*new QScriptEnginePrivate, parent)
     1971{
     1972}
     1973
     1974/*! \internal
     1975*/
     1976QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent)
     1977    : QObject(dd, parent)
     1978{
     1979}
     1980#endif
     1981
     1982/*!
     1983  Destroys this QScriptEngine.
     1984*/
     1985QScriptEngine::~QScriptEngine()
     1986{
     1987#ifdef QT_NO_QOBJECT
     1988    delete d_ptr;
     1989    d_ptr = 0;
     1990#endif
     1991}
     1992
     1993/*!
     1994  Returns this engine's Global Object.
     1995
     1996  By default, the Global Object contains the built-in objects that are
     1997  part of \l{ECMA-262}, such as Math, Date and String. Additionally,
     1998  you can set properties of the Global Object to make your own
     1999  extensions available to all script code. Non-local variables in
     2000  script code will be created as properties of the Global Object, as
     2001  well as local variables in global code.
     2002*/
     2003QScriptValue QScriptEngine::globalObject() const
     2004{
     2005    Q_D(const QScriptEngine);
     2006    QScript::APIShim shim(const_cast<QScriptEnginePrivate*>(d));
     2007    JSC::JSObject *result = d->globalObject();
     2008    return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result);
     2009}
     2010
     2011/*!
     2012  \since 4.5
     2013
     2014  Sets this engine's Global Object to be the given \a object.
     2015  If \a object is not a valid script object, this function does
     2016  nothing.
     2017
     2018  When setting a custom global object, you may want to use
     2019  QScriptValueIterator to copy the properties of the standard Global
     2020  Object; alternatively, you can set the internal prototype of your
     2021  custom object to be the original Global Object.
     2022*/
     2023void QScriptEngine::setGlobalObject(const QScriptValue &object)
     2024{
     2025    Q_D(QScriptEngine);
     2026    if (!object.isObject())
     2027        return;
     2028    QScript::APIShim shim(d);
     2029    JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object));
     2030    d->setGlobalObject(jscObject);
     2031}
     2032
     2033/*!
     2034  Returns a QScriptValue of the primitive type Null.
     2035
     2036  \sa undefinedValue()
     2037*/
     2038QScriptValue QScriptEngine::nullValue()
     2039{
     2040    Q_D(QScriptEngine);
     2041    return d->scriptValueFromJSCValue(JSC::jsNull());
     2042}
     2043
     2044/*!
     2045  Returns a QScriptValue of the primitive type Undefined.
     2046
     2047  \sa nullValue()
     2048*/
     2049QScriptValue QScriptEngine::undefinedValue()
     2050{
     2051    Q_D(QScriptEngine);
     2052    return d->scriptValueFromJSCValue(JSC::jsUndefined());
     2053}
     2054
     2055/*!
     2056  Creates a constructor function from \a fun, with the given \a length.
     2057  The \c{prototype} property of the resulting function is set to be the
     2058  given \a prototype. The \c{constructor} property of \a prototype is
     2059  set to be the resulting function.
     2060
     2061  When a function is called as a constructor (e.g. \c{new Foo()}), the
     2062  `this' object associated with the function call is the new object
     2063  that the function is expected to initialize; the prototype of this
     2064  default constructed object will be the function's public
     2065  \c{prototype} property. If you always want the function to behave as
     2066  a constructor (e.g. \c{Foo()} should also create a new object), or
     2067  if you need to create your own object rather than using the default
     2068  `this' object, you should make sure that the prototype of your
     2069  object is set correctly; either by setting it manually, or, when
     2070  wrapping a custom type, by having registered the defaultPrototype()
     2071  of that type. Example:
     2072
     2073  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
     2074
     2075  To wrap a custom type and provide a constructor for it, you'd typically
     2076  do something like this:
     2077
     2078  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
     2079*/
     2080QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun,
     2081                                        const QScriptValue &prototype,
     2082                                        int length)
     2083{
     2084    Q_D(QScriptEngine);
     2085    QScript::APIShim shim(d);
     2086    JSC::ExecState* exec = d->currentFrame;
     2087    JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
     2088    QScriptValue result = d->scriptValueFromJSCValue(function);
     2089    result.setProperty(QLatin1String("prototype"), prototype, QScriptValue::Undeletable);
     2090    const_cast<QScriptValue&>(prototype)
     2091        .setProperty(QLatin1String("constructor"), result,
     2092                     QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
     2093    return result;
     2094}
     2095
     2096#ifndef QT_NO_REGEXP
     2097
     2098/*!
     2099  Creates a QtScript object of class RegExp with the given
     2100  \a regexp.
     2101
     2102  \sa QScriptValue::toRegExp()
     2103*/
     2104QScriptValue QScriptEngine::newRegExp(const QRegExp &regexp)
     2105{
     2106    Q_D(QScriptEngine);
     2107    QScript::APIShim shim(d);
     2108    return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, regexp));
     2109}
     2110
     2111#endif // QT_NO_REGEXP
     2112
     2113/*!
     2114  Creates a QtScript object holding the given variant \a value.
     2115
     2116  If a default prototype has been registered with the meta type id of
     2117  \a value, then the prototype of the created object will be that
     2118  prototype; otherwise, the prototype will be the Object prototype
     2119  object.
     2120
     2121  \sa setDefaultPrototype(), QScriptValue::toVariant(), reportAdditionalMemoryCost()
     2122*/
     2123QScriptValue QScriptEngine::newVariant(const QVariant &value)
     2124{
     2125    Q_D(QScriptEngine);
     2126    QScript::APIShim shim(d);
     2127    return d->scriptValueFromJSCValue(d->newVariant(value));
     2128}
     2129
     2130/*!
     2131  \since 4.4
     2132  \overload
     2133
     2134  Initializes the given Qt Script \a object to hold the given variant
     2135  \a value, and returns the \a object.
     2136
     2137  This function enables you to "promote" a plain Qt Script object
     2138  (created by the newObject() function) to a variant, or to replace
     2139  the variant contained inside an object previously created by the
     2140  newVariant() function.
     2141
     2142  The prototype() of the \a object will remain unchanged.
     2143
     2144  If \a object is not an object, this function behaves like the normal
     2145  newVariant(), i.e. it creates a new script object and returns it.
     2146
     2147  This function is useful when you want to provide a script
     2148  constructor for a C++ type. If your constructor is invoked in a
     2149  \c{new} expression (QScriptContext::isCalledAsConstructor() returns
     2150  true), you can pass QScriptContext::thisObject() (the default
     2151  constructed script object) to this function to initialize the new
     2152  object.
     2153
     2154  \sa reportAdditionalMemoryCost()
     2155*/
     2156QScriptValue QScriptEngine::newVariant(const QScriptValue &object,
     2157                                       const QVariant &value)
     2158{
     2159    Q_D(QScriptEngine);
     2160    QScript::APIShim shim(d);
     2161    JSC::JSValue jsObject = d->scriptValueToJSCValue(object);
     2162    return d->scriptValueFromJSCValue(d->newVariant(jsObject, value));
     2163}
     2164
     2165#ifndef QT_NO_QOBJECT
     2166/*!
     2167  Creates a QtScript object that wraps the given QObject \a
     2168  object, using the given \a ownership. The given \a options control
     2169  various aspects of the interaction with the resulting script object.
     2170
     2171  Signals and slots, properties and children of \a object are
     2172  available as properties of the created QScriptValue. For more
     2173  information, see the \l{QtScript} documentation.
     2174
     2175  If \a object is a null pointer, this function returns nullValue().
     2176
     2177  If a default prototype has been registered for the \a object's class
     2178  (or its superclass, recursively), the prototype of the new script
     2179  object will be set to be that default prototype.
     2180
     2181  If the given \a object is deleted outside of QtScript's control, any
     2182  attempt to access the deleted QObject's members through the QtScript
     2183  wrapper object (either by script code or C++) will result in a
     2184  script exception.
     2185
     2186  \sa QScriptValue::toQObject(), reportAdditionalMemoryCost()
     2187*/
     2188QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership,
     2189                                       const QObjectWrapOptions &options)
     2190{
     2191    Q_D(QScriptEngine);
     2192    QScript::APIShim shim(d);
     2193    JSC::JSValue jscQObject = d->newQObject(object, ownership, options);
     2194    return d->scriptValueFromJSCValue(jscQObject);
     2195}
     2196
     2197/*!
     2198  \since 4.4
     2199  \overload
     2200
     2201  Initializes the given \a scriptObject to hold the given \a qtObject,
     2202  and returns the \a scriptObject.
     2203
     2204  This function enables you to "promote" a plain Qt Script object
     2205  (created by the newObject() function) to a QObject proxy, or to
     2206  replace the QObject contained inside an object previously created by
     2207  the newQObject() function.
     2208
     2209  The prototype() of the \a scriptObject will remain unchanged.
     2210
     2211  If \a scriptObject is not an object, this function behaves like the
     2212  normal newQObject(), i.e. it creates a new script object and returns
     2213  it.
     2214
     2215  This function is useful when you want to provide a script
     2216  constructor for a QObject-based class. If your constructor is
     2217  invoked in a \c{new} expression
     2218  (QScriptContext::isCalledAsConstructor() returns true), you can pass
     2219  QScriptContext::thisObject() (the default constructed script object)
     2220  to this function to initialize the new object.
     2221
     2222  \sa reportAdditionalMemoryCost()
     2223*/
     2224QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject,
     2225                                       QObject *qtObject,
     2226                                       ValueOwnership ownership,
     2227                                       const QObjectWrapOptions &options)
     2228{
     2229    Q_D(QScriptEngine);
     2230    if (!scriptObject.isObject())
     2231        return newQObject(qtObject, ownership, options);
     2232    QScript::APIShim shim(d);
     2233    JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue);
     2234    if (!jscObject->inherits(&QScriptObject::info)) {
     2235        qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported");
     2236        return QScriptValue();
     2237    }
     2238    QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
     2239    if (!scriptObject.isQObject()) {
     2240        jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options));
     2241    } else {
     2242        QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate());
     2243        delegate->setValue(qtObject);
     2244        delegate->setOwnership(ownership);
     2245        delegate->setOptions(options);
     2246    }
     2247    return scriptObject;
     2248}
     2249
     2250#endif // QT_NO_QOBJECT
     2251
     2252/*!
     2253  Creates a QtScript object of class Object.
     2254
     2255  The prototype of the created object will be the Object
     2256  prototype object.
     2257
     2258  \sa newArray(), QScriptValue::setProperty()
     2259*/
     2260QScriptValue QScriptEngine::newObject()
     2261{
     2262    Q_D(QScriptEngine);
     2263    QScript::APIShim shim(d);
     2264    return d->scriptValueFromJSCValue(d->newObject());
     2265}
     2266
     2267/*!
     2268  \since 4.4
     2269  \overload
     2270
     2271  Creates a QtScript Object of the given class, \a scriptClass.
     2272
     2273  The prototype of the created object will be the Object
     2274  prototype object.
     2275
     2276  \a data, if specified, is set as the internal data of the
     2277  new object (using QScriptValue::setData()).
     2278
     2279  \sa QScriptValue::scriptClass(), reportAdditionalMemoryCost()
     2280*/
     2281QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass,
     2282                                      const QScriptValue &data)
     2283{
     2284    Q_D(QScriptEngine);
     2285    QScript::APIShim shim(d);
     2286    JSC::ExecState* exec = d->currentFrame;
     2287    QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure);
     2288    result->setDelegate(new QScript::ClassObjectDelegate(scriptClass));
     2289    QScriptValue scriptObject = d->scriptValueFromJSCValue(result);
     2290    scriptObject.setData(data);
     2291    QScriptValue proto = scriptClass->prototype();
     2292    if (proto.isValid())
     2293        scriptObject.setPrototype(proto);
     2294    return scriptObject;
     2295}
     2296
     2297/*!
     2298  \internal
     2299*/
     2300QScriptValue QScriptEngine::newActivationObject()
     2301{
     2302    qWarning("QScriptEngine::newActivationObject() not implemented");
     2303    // ### JSActivation or JSVariableObject?
     2304    return QScriptValue();
     2305}
     2306
     2307/*!
     2308  Creates a QScriptValue that wraps a native (C++) function. \a fun
     2309  must be a C++ function with signature QScriptEngine::FunctionSignature.  \a
     2310  length is the number of arguments that \a fun expects; this becomes
     2311  the \c{length} property of the created QScriptValue.
     2312
     2313  Note that \a length only gives an indication of the number of
     2314  arguments that the function expects; an actual invocation of a
     2315  function can include any number of arguments. You can check the
     2316  \l{QScriptContext::argumentCount()}{argumentCount()} of the
     2317  QScriptContext associated with the invocation to determine the
     2318  actual number of arguments passed.
     2319
     2320  A \c{prototype} property is automatically created for the resulting
     2321  function object, to provide for the possibility that the function
     2322  will be used as a constructor.
     2323
     2324  By combining newFunction() and the property flags
     2325  QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
     2326  can create script object properties that behave like normal
     2327  properties in script code, but are in fact accessed through
     2328  functions (analogous to how properties work in \l{Qt's Property
     2329  System}). Example:
     2330
     2331  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
     2332
     2333  When the property \c{foo} of the script object is subsequently
     2334  accessed in script code, \c{getSetFoo()} will be invoked to handle
     2335  the access.  In this particular case, we chose to store the "real"
     2336  value of \c{foo} as a property of the accessor function itself; you
     2337  are of course free to do whatever you like in this function.
     2338
     2339  In the above example, a single native function was used to handle
     2340  both reads and writes to the property; the argument count is used to
     2341  determine if we are handling a read or write. You can also use two
     2342  separate functions; just specify the relevant flag
     2343  (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
     2344  setting the property, e.g.:
     2345
     2346  \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
     2347
     2348  \sa QScriptValue::call()
     2349*/
     2350QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
     2351{
     2352    Q_D(QScriptEngine);
     2353    QScript::APIShim shim(d);
     2354    JSC::ExecState* exec = d->currentFrame;
     2355    JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun);
     2356    QScriptValue result = d->scriptValueFromJSCValue(function);
     2357    QScriptValue proto = newObject();
     2358    result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
     2359    proto.setProperty(QLatin1String("constructor"), result,
     2360                      QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
     2361    return result;
     2362}
     2363
     2364/*!
     2365  \internal
     2366  \since 4.4
     2367*/
     2368QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg)
     2369{
     2370    Q_D(QScriptEngine);
     2371    QScript::APIShim shim(d);
     2372    JSC::ExecState* exec = d->currentFrame;
     2373    JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg);
     2374    QScriptValue result = d->scriptValueFromJSCValue(function);
     2375    QScriptValue proto = newObject();
     2376    result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable);
     2377    proto.setProperty(QLatin1String("constructor"), result,
     2378                      QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
     2379    return result;
     2380}
     2381
     2382/*!
     2383  Creates a QtScript object of class Array with the given \a length.
     2384
     2385  \sa newObject()
     2386*/
     2387QScriptValue QScriptEngine::newArray(uint length)
     2388{
     2389    Q_D(QScriptEngine);
     2390    QScript::APIShim shim(d);
     2391    return d->scriptValueFromJSCValue(d->newArray(d->currentFrame, length));
     2392}
     2393
     2394/*!
     2395  Creates a QtScript object of class RegExp with the given
     2396  \a pattern and \a flags.
     2397
     2398  The legal flags are 'g' (global), 'i' (ignore case), and 'm'
     2399  (multiline).
     2400*/
     2401QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags)
     2402{
     2403    Q_D(QScriptEngine);
     2404    QScript::APIShim shim(d);
     2405    return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, pattern, flags));
    19862406}
    19872407
     
    19942414{
    19952415    Q_D(QScriptEngine);
    1996     JSC::ExecState* exec = d->currentFrame;
    1997     JSC::JSValue val = JSC::jsNumber(exec, value);
    1998     JSC::ArgList args(&val, 1);
    1999     JSC::JSObject *result = JSC::constructDate(exec, args);
    2000     return d->scriptValueFromJSCValue(result);
     2416    QScript::APIShim shim(d);
     2417    return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value));
    20012418}
    20022419
     
    20082425QScriptValue QScriptEngine::newDate(const QDateTime &value)
    20092426{
    2010     return newDate(QScript::FromDateTime(value));
     2427    Q_D(QScriptEngine);
     2428    QScript::APIShim shim(d);
     2429    return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value));
    20112430}
    20122431
     
    20312450{
    20322451    Q_D(QScriptEngine);
     2452    QScript::APIShim shim(d);
    20332453    JSC::JSValue jscCtor = d->scriptValueToJSCValue(ctor);
    20342454    JSC::JSValue jscQMetaObject = d->newQMetaObject(metaObject, jscCtor);
     
    22052625{
    22062626    Q_D(QScriptEngine);
     2627    QScript::APIShim shim(d);
    22072628    WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
    22082629            = QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d);
     
    22112632
    22122633    JSC::ExecState* exec = d->currentFrame;
    2213     JSC::EvalExecutable executable(exec, source);
     2634    WTF::RefPtr<JSC::EvalExecutable> executable = JSC::EvalExecutable::create(exec, source);
    22142635    bool compile = true;
    2215     return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, &executable, compile));
    2216 }
    2217 
    2218 /*!
    2219   \internal
    2220   \since 4.6
     2636    return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, executable.get(), compile));
     2637}
     2638
     2639/*!
     2640  \since 4.7
    22212641
    22222642  Evaluates the given \a program and returns the result of the
     
    22302650        return QScriptValue();
    22312651
     2652    QScript::APIShim shim(d);
    22322653    JSC::ExecState* exec = d->currentFrame;
    22332654    JSC::EvalExecutable *executable = program_d->executable(exec, d);
     
    22812702{
    22822703    Q_D(QScriptEngine);
     2704    QScript::APIShim shim(d);
    22832705
    22842706    JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, d->currentFrame->globalData().dynamicGlobalObject,
     
    23412763            newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee);
    23422764        } else {
    2343             JSC::JSObject *jscObject = originalGlobalObject();
    2344             JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), jscObject);
    2345             newCallFrame->init(0, /*vPC=*/0, scn, exec, flags | ShouldRestoreCallFrame, argc, callee);
     2765            newCallFrame->init(0, /*vPC=*/0, globalExec()->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee);
    23462766        }
    23472767    } else {
     
    23722792        agent()->contextPop();
    23732793    Q_D(QScriptEngine);
     2794    QScript::APIShim shim(d);
    23742795    if (d->currentFrame->returnPC() != 0 || d->currentFrame->codeBlock() != 0
    23752796        || !currentContext()->parentContext()) {
     
    24072828  The exception state is cleared when evaluate() is called.
    24082829
    2409   \sa uncaughtException(), uncaughtExceptionLineNumber(),
    2410       uncaughtExceptionBacktrace()
     2830  \sa uncaughtException(), uncaughtExceptionLineNumber()
    24112831*/
    24122832bool QScriptEngine::hasUncaughtException() const
     
    24262846
    24272847  \sa hasUncaughtException(), uncaughtExceptionLineNumber(),
    2428       uncaughtExceptionBacktrace()
    24292848*/
    24302849QScriptValue QScriptEngine::uncaughtException() const
     
    24462865  the second argument to evaluate().
    24472866
    2448   \sa hasUncaughtException(), uncaughtExceptionBacktrace()
     2867  \sa hasUncaughtException()
    24492868*/
    24502869int QScriptEngine::uncaughtExceptionLineNumber() const
     
    24582877  Returns a human-readable backtrace of the last uncaught exception.
    24592878
    2460   Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}.
     2879  It is in the form \c{<function-name>()@<file-name>:<line-number>}.
    24612880
    24622881  \sa uncaughtException()
     
    25672986{
    25682987    Q_D(QScriptEngine);
    2569     return d->create(type, ptr);
    2570 }
    2571 
    2572 QScriptValue QScriptEnginePrivate::create(int type, const void *ptr)
    2573 {
    2574     Q_Q(QScriptEngine);
     2988    QScript::APIShim shim(d);
     2989    return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr));
     2990}
     2991
     2992JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const void *ptr)
     2993{
    25752994    Q_ASSERT(ptr != 0);
    2576     QScriptValue result;
    2577     QScriptTypeInfo *info = m_typeInfos.value(type);
     2995    JSC::JSValue result;
     2996    QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
     2997    QScriptTypeInfo *info = eng ? eng->m_typeInfos.value(type) : 0;
    25782998    if (info && info->marshal) {
    2579         result = info->marshal(q, ptr);
     2999        result = eng->scriptValueToJSCValue(info->marshal(eng->q_func(), ptr));
    25803000    } else {
    25813001        // check if it's one of the types we know
    25823002        switch (QMetaType::Type(type)) {
    25833003        case QMetaType::Void:
    2584             return QScriptValue(q, QScriptValue::UndefinedValue);
     3004            return JSC::jsUndefined();
    25853005        case QMetaType::Bool:
    2586             return QScriptValue(q, *reinterpret_cast<const bool*>(ptr));
     3006            return JSC::jsBoolean(*reinterpret_cast<const bool*>(ptr));
    25873007        case QMetaType::Int:
    2588             return QScriptValue(q, *reinterpret_cast<const int*>(ptr));
     3008            return JSC::jsNumber(exec, *reinterpret_cast<const int*>(ptr));
    25893009        case QMetaType::UInt:
    2590             return QScriptValue(q, *reinterpret_cast<const uint*>(ptr));
     3010            return JSC::jsNumber(exec, *reinterpret_cast<const uint*>(ptr));
    25913011        case QMetaType::LongLong:
    2592             return QScriptValue(q, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
     3012            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
    25933013        case QMetaType::ULongLong:
    25943014#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
    25953015#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
    2596             return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
     3016            return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
    25973017#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
    2598             return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
     3018            return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
    25993019#else
    2600             return QScriptValue(q, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
     3020            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
    26013021#endif
    26023022        case QMetaType::Double:
    2603             return QScriptValue(q, qsreal(*reinterpret_cast<const double*>(ptr)));
     3023            return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const double*>(ptr)));
    26043024        case QMetaType::QString:
    2605             return QScriptValue(q, *reinterpret_cast<const QString*>(ptr));
     3025            return JSC::jsString(exec, *reinterpret_cast<const QString*>(ptr));
    26063026        case QMetaType::Float:
    2607             return QScriptValue(q, *reinterpret_cast<const float*>(ptr));
     3027            return JSC::jsNumber(exec, *reinterpret_cast<const float*>(ptr));
    26083028        case QMetaType::Short:
    2609             return QScriptValue(q, *reinterpret_cast<const short*>(ptr));
     3029            return JSC::jsNumber(exec, *reinterpret_cast<const short*>(ptr));
    26103030        case QMetaType::UShort:
    2611             return QScriptValue(q, *reinterpret_cast<const unsigned short*>(ptr));
     3031            return JSC::jsNumber(exec, *reinterpret_cast<const unsigned short*>(ptr));
    26123032        case QMetaType::Char:
    2613             return QScriptValue(q, *reinterpret_cast<const char*>(ptr));
     3033            return JSC::jsNumber(exec, *reinterpret_cast<const char*>(ptr));
    26143034        case QMetaType::UChar:
    2615             return QScriptValue(q, *reinterpret_cast<const unsigned char*>(ptr));
     3035            return JSC::jsNumber(exec, *reinterpret_cast<const unsigned char*>(ptr));
    26163036        case QMetaType::QChar:
    2617             return QScriptValue(q, (*reinterpret_cast<const QChar*>(ptr)).unicode());
     3037            return JSC::jsNumber(exec, (*reinterpret_cast<const QChar*>(ptr)).unicode());
    26183038        case QMetaType::QStringList:
    2619             result = arrayFromStringList(*reinterpret_cast<const QStringList *>(ptr));
     3039            result = arrayFromStringList(exec, *reinterpret_cast<const QStringList *>(ptr));
    26203040            break;
    26213041        case QMetaType::QVariantList:
    2622             result = arrayFromVariantList(*reinterpret_cast<const QVariantList *>(ptr));
     3042            result = arrayFromVariantList(exec, *reinterpret_cast<const QVariantList *>(ptr));
    26233043            break;
    26243044        case QMetaType::QVariantMap:
    2625             result = objectFromVariantMap(*reinterpret_cast<const QVariantMap *>(ptr));
     3045            result = objectFromVariantMap(exec, *reinterpret_cast<const QVariantMap *>(ptr));
    26263046            break;
    26273047        case QMetaType::QDateTime:
    2628             result = q->newDate(*reinterpret_cast<const QDateTime *>(ptr));
     3048            result = newDate(exec, *reinterpret_cast<const QDateTime *>(ptr));
    26293049            break;
    26303050        case QMetaType::QDate:
    2631             result = q->newDate(QDateTime(*reinterpret_cast<const QDate *>(ptr)));
     3051            result = newDate(exec, QDateTime(*reinterpret_cast<const QDate *>(ptr)));
    26323052            break;
    26333053#ifndef QT_NO_REGEXP
    26343054        case QMetaType::QRegExp:
    2635             result = q->newRegExp(*reinterpret_cast<const QRegExp *>(ptr));
     3055            result = newRegExp(exec, *reinterpret_cast<const QRegExp *>(ptr));
    26363056            break;
    26373057#endif
     
    26393059        case QMetaType::QObjectStar:
    26403060        case QMetaType::QWidgetStar:
    2641             result = q->newQObject(*reinterpret_cast<QObject* const *>(ptr));
     3061            result = eng->newQObject(*reinterpret_cast<QObject* const *>(ptr));
    26423062            break;
    26433063#endif
     3064        case QMetaType::QVariant:
     3065            result = jscValueFromVariant(exec, *reinterpret_cast<const QVariant*>(ptr));
     3066            break;
    26443067        default:
    26453068            if (type == qMetaTypeId<QScriptValue>()) {
    2646                 result = *reinterpret_cast<const QScriptValue*>(ptr);
    2647                 if (!result.isValid())
    2648                     return QScriptValue(q, QScriptValue::UndefinedValue);
     3069                result = eng->scriptValueToJSCValue(*reinterpret_cast<const QScriptValue*>(ptr));
     3070                if (!result)
     3071                    return JSC::jsUndefined();
    26493072            }
    26503073
     
    26523075            // lazy registration of some common list types
    26533076            else if (type == qMetaTypeId<QObjectList>()) {
    2654                 qScriptRegisterSequenceMetaType<QObjectList>(q);
    2655                 return create(type, ptr);
     3077                qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
     3078                return create(exec, type, ptr);
    26563079            }
    26573080#endif
    26583081            else if (type == qMetaTypeId<QList<int> >()) {
    2659                 qScriptRegisterSequenceMetaType<QList<int> >(q);
    2660                 return create(type, ptr);
     3082                qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
     3083                return create(exec, type, ptr);
    26613084            }
    26623085
    26633086            else {
    26643087                QByteArray typeName = QMetaType::typeName(type);
    2665                 if (typeName == "QVariant")
    2666                     result = scriptValueFromVariant(*reinterpret_cast<const QVariant*>(ptr));
    26673088                if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr))
    2668                     return QScriptValue(q, QScriptValue::NullValue);
     3089                    return JSC::jsNull();
    26693090                else
    2670                     result = q->newVariant(QVariant(type, ptr));
     3091                    result = eng->newVariant(QVariant(type, ptr));
    26713092            }
    26723093        }
    26733094    }
    2674     if (result.isObject() && info && info->prototype
    2675         && JSC::JSValue::strictEqual(scriptValueToJSCValue(result.prototype()), originalGlobalObject()->objectPrototype())) {
    2676         result.setPrototype(scriptValueFromJSCValue(info->prototype));
     3095    if (result && result.isObject() && info && info->prototype
     3096        && JSC::JSValue::strictEqual(exec, JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) {
     3097        JSC::asObject(result)->setPrototype(info->prototype);
    26773098    }
    26783099    return result;
    26793100}
    26803101
    2681 bool QScriptEnginePrivate::convert(const QScriptValue &value,
    2682                                    int type, void *ptr,
    2683                                    QScriptEnginePrivate *eng)
    2684 {
    2685     if (!eng)
    2686         eng = QScriptValuePrivate::getEngine(value);
     3102bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value,
     3103                                        int type, void *ptr)
     3104{
     3105    QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
    26873106    if (eng) {
    26883107        QScriptTypeInfo *info = eng->m_typeInfos.value(type);
    26893108        if (info && info->demarshal) {
    2690             info->demarshal(value, ptr);
     3109            info->demarshal(eng->scriptValueFromJSCValue(value), ptr);
    26913110            return true;
    26923111        }
     
    26963115    switch (QMetaType::Type(type)) {
    26973116    case QMetaType::Bool:
    2698         *reinterpret_cast<bool*>(ptr) = value.toBoolean();
     3117        *reinterpret_cast<bool*>(ptr) = toBool(exec, value);
    26993118        return true;
    27003119    case QMetaType::Int:
    2701         *reinterpret_cast<int*>(ptr) = value.toInt32();
     3120        *reinterpret_cast<int*>(ptr) = toInt32(exec, value);
    27023121        return true;
    27033122    case QMetaType::UInt:
    2704         *reinterpret_cast<uint*>(ptr) = value.toUInt32();
     3123        *reinterpret_cast<uint*>(ptr) = toUInt32(exec, value);
    27053124        return true;
    27063125    case QMetaType::LongLong:
    2707         *reinterpret_cast<qlonglong*>(ptr) = qlonglong(value.toInteger());
     3126        *reinterpret_cast<qlonglong*>(ptr) = qlonglong(toInteger(exec, value));
    27083127        return true;
    27093128    case QMetaType::ULongLong:
    2710         *reinterpret_cast<qulonglong*>(ptr) = qulonglong(value.toInteger());
     3129        *reinterpret_cast<qulonglong*>(ptr) = qulonglong(toInteger(exec, value));
    27113130        return true;
    27123131    case QMetaType::Double:
    2713         *reinterpret_cast<double*>(ptr) = value.toNumber();
     3132        *reinterpret_cast<double*>(ptr) = toNumber(exec, value);
    27143133        return true;
    27153134    case QMetaType::QString:
     
    27173136            *reinterpret_cast<QString*>(ptr) = QString();
    27183137        else
    2719             *reinterpret_cast<QString*>(ptr) = value.toString();
     3138            *reinterpret_cast<QString*>(ptr) = toString(exec, value);
    27203139        return true;
    27213140    case QMetaType::Float:
    2722         *reinterpret_cast<float*>(ptr) = value.toNumber();
     3141        *reinterpret_cast<float*>(ptr) = toNumber(exec, value);
    27233142        return true;
    27243143    case QMetaType::Short:
    2725         *reinterpret_cast<short*>(ptr) = short(value.toInt32());
     3144        *reinterpret_cast<short*>(ptr) = short(toInt32(exec, value));
    27263145        return true;
    27273146    case QMetaType::UShort:
    2728         *reinterpret_cast<unsigned short*>(ptr) = value.toUInt16();
     3147        *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(toNumber(exec, value));
    27293148        return true;
    27303149    case QMetaType::Char:
    2731         *reinterpret_cast<char*>(ptr) = char(value.toInt32());
     3150        *reinterpret_cast<char*>(ptr) = char(toInt32(exec, value));
    27323151        return true;
    27333152    case QMetaType::UChar:
    2734         *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(value.toInt32());
     3153        *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(toInt32(exec, value));
    27353154        return true;
    27363155    case QMetaType::QChar:
    27373156        if (value.isString()) {
    2738             QString str = value.toString();
     3157            QString str = toString(exec, value);
    27393158            *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0);
    27403159        } else {
    2741             *reinterpret_cast<QChar*>(ptr) = QChar(value.toUInt16());
     3160            *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(toNumber(exec, value)));
    27423161        }
    27433162        return true;
    27443163    case QMetaType::QDateTime:
    2745         if (value.isDate()) {
    2746             *reinterpret_cast<QDateTime *>(ptr) = value.toDateTime();
     3164        if (isDate(value)) {
     3165            *reinterpret_cast<QDateTime *>(ptr) = toDateTime(exec, value);
    27473166            return true;
    27483167        } break;
    27493168    case QMetaType::QDate:
    2750         if (value.isDate()) {
    2751             *reinterpret_cast<QDate *>(ptr) = value.toDateTime().date();
     3169        if (isDate(value)) {
     3170            *reinterpret_cast<QDate *>(ptr) = toDateTime(exec, value).date();
    27523171            return true;
    27533172        } break;
    27543173#ifndef QT_NO_REGEXP
    27553174    case QMetaType::QRegExp:
    2756         if (value.isRegExp()) {
    2757             *reinterpret_cast<QRegExp *>(ptr) = value.toRegExp();
     3175        if (isRegExp(value)) {
     3176            *reinterpret_cast<QRegExp *>(ptr) = toRegExp(exec, value);
    27583177            return true;
    27593178        } break;
     
    27613180#ifndef QT_NO_QOBJECT
    27623181    case QMetaType::QObjectStar:
    2763         if (value.isQObject() || value.isNull()) {
    2764             *reinterpret_cast<QObject* *>(ptr) = value.toQObject();
     3182        if (isQObject(value) || value.isNull()) {
     3183            *reinterpret_cast<QObject* *>(ptr) = toQObject(exec, value);
    27653184            return true;
    27663185        } break;
    27673186    case QMetaType::QWidgetStar:
    2768         if (value.isQObject() || value.isNull()) {
    2769             QObject *qo = value.toQObject();
     3187        if (isQObject(value) || value.isNull()) {
     3188            QObject *qo = toQObject(exec, value);
    27703189            if (!qo || qo->isWidgetType()) {
    27713190                *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo);
     
    27753194#endif
    27763195    case QMetaType::QStringList:
    2777         if (value.isArray()) {
    2778             *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(value);
     3196        if (isArray(value)) {
     3197            *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(exec, value);
    27793198            return true;
    27803199        } break;
    27813200    case QMetaType::QVariantList:
    2782         if (value.isArray()) {
    2783             *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(value);
     3201        if (isArray(value)) {
     3202            *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, JSC::asArray(value));
    27843203            return true;
    27853204        } break;
    27863205    case QMetaType::QVariantMap:
    2787         if (value.isObject()) {
    2788             *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(value);
     3206        if (isObject(value)) {
     3207            *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, JSC::asObject(value));
    27893208            return true;
    27903209        } break;
     3210    case QMetaType::QVariant:
     3211        *reinterpret_cast<QVariant*>(ptr) = toVariant(exec, value);
     3212        return true;
    27913213    default:
    27923214    ;
     
    27953217    QByteArray name = QMetaType::typeName(type);
    27963218#ifndef QT_NO_QOBJECT
    2797     if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(ptr)))
     3219    if (convertToNativeQObject(exec, value, name, reinterpret_cast<void* *>(ptr)))
    27983220        return true;
    27993221#endif
    2800     if (value.isVariant() && name.endsWith('*')) {
     3222    if (isVariant(value) && name.endsWith('*')) {
    28013223        int valueType = QMetaType::type(name.left(name.size()-1));
    2802         QVariant &var = QScriptValuePrivate::get(value)->variantValue();
     3224        QVariant &var = variantValue(value);
    28033225        if (valueType == var.userType()) {
    28043226            *reinterpret_cast<void* *>(ptr) = var.data();
     
    28063228        } else {
    28073229            // look in the prototype chain
    2808             QScriptValue proto = value.prototype();
     3230            JSC::JSValue proto = JSC::asObject(value)->prototype();
    28093231            while (proto.isObject()) {
    28103232                bool canCast = false;
    2811                 if (proto.isVariant()) {
    2812                     canCast = (type == proto.toVariant().userType())
    2813                               || (valueType && (valueType == proto.toVariant().userType()));
     3233                if (isVariant(proto)) {
     3234                    canCast = (type == variantValue(proto).userType())
     3235                              || (valueType && (valueType == variantValue(proto).userType()));
    28143236                }
    28153237#ifndef QT_NO_QOBJECT
    2816                 else if (proto.isQObject()) {
     3238                else if (isQObject(proto)) {
    28173239                    QByteArray className = name.left(name.size()-1);
    2818                     if (QObject *qobject = proto.toQObject())
     3240                    if (QObject *qobject = toQObject(exec, proto))
    28193241                        canCast = qobject->qt_metacast(className) != 0;
    28203242                }
     
    28283250                    return true;
    28293251                }
    2830                 proto = proto.prototype();
     3252                proto = JSC::asObject(proto)->prototype();
    28313253            }
    28323254        }
     
    28373259        if (!eng)
    28383260            return false;
    2839         *reinterpret_cast<QScriptValue*>(ptr) = value;
    2840         return true;
    2841     } else if (name == "QVariant") {
    2842         *reinterpret_cast<QVariant*>(ptr) = value.toVariant();
     3261        *reinterpret_cast<QScriptValue*>(ptr) = eng->scriptValueFromJSCValue(value);
    28433262        return true;
    28443263    }
     
    28503269            return false;
    28513270        qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
    2852         return convert(value, type, ptr, eng);
     3271        return convertValue(exec, value, type, ptr);
    28533272    }
    28543273#endif
     
    28573276            return false;
    28583277        qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
    2859         return convert(value, type, ptr, eng);
     3278        return convertValue(exec, value, type, ptr);
    28603279    }
    28613280
     
    28693288}
    28703289
     3290bool QScriptEnginePrivate::convertNumber(qsreal value, int type, void *ptr)
     3291{
     3292    switch (QMetaType::Type(type)) {
     3293    case QMetaType::Bool:
     3294        *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
     3295        return true;
     3296    case QMetaType::Int:
     3297        *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
     3298        return true;
     3299    case QMetaType::UInt:
     3300        *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
     3301        return true;
     3302    case QMetaType::LongLong:
     3303        *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
     3304        return true;
     3305    case QMetaType::ULongLong:
     3306        *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
     3307        return true;
     3308    case QMetaType::Double:
     3309        *reinterpret_cast<double*>(ptr) = value;
     3310        return true;
     3311    case QMetaType::QString:
     3312        *reinterpret_cast<QString*>(ptr) = QScript::ToString(value);
     3313        return true;
     3314    case QMetaType::Float:
     3315        *reinterpret_cast<float*>(ptr) = value;
     3316        return true;
     3317    case QMetaType::Short:
     3318        *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
     3319        return true;
     3320    case QMetaType::UShort:
     3321        *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
     3322        return true;
     3323    case QMetaType::Char:
     3324        *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
     3325        return true;
     3326    case QMetaType::UChar:
     3327        *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
     3328        return true;
     3329    case QMetaType::QChar:
     3330        *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
     3331        return true;
     3332    default:
     3333        break;
     3334    }
     3335    return false;
     3336}
     3337
     3338bool QScriptEnginePrivate::convertString(const QString &value, int type, void *ptr)
     3339{
     3340    switch (QMetaType::Type(type)) {
     3341    case QMetaType::Bool:
     3342        *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
     3343        return true;
     3344    case QMetaType::Int:
     3345        *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
     3346        return true;
     3347    case QMetaType::UInt:
     3348        *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
     3349        return true;
     3350    case QMetaType::LongLong:
     3351        *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
     3352        return true;
     3353    case QMetaType::ULongLong:
     3354        *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
     3355        return true;
     3356    case QMetaType::Double:
     3357        *reinterpret_cast<double*>(ptr) = QScript::ToNumber(value);
     3358        return true;
     3359    case QMetaType::QString:
     3360        *reinterpret_cast<QString*>(ptr) = value;
     3361        return true;
     3362    case QMetaType::Float:
     3363        *reinterpret_cast<float*>(ptr) = QScript::ToNumber(value);
     3364        return true;
     3365    case QMetaType::Short:
     3366        *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
     3367        return true;
     3368    case QMetaType::UShort:
     3369        *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
     3370        return true;
     3371    case QMetaType::Char:
     3372        *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
     3373        return true;
     3374    case QMetaType::UChar:
     3375        *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
     3376        return true;
     3377    case QMetaType::QChar:
     3378        *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
     3379        return true;
     3380    default:
     3381        break;
     3382    }
     3383    return false;
     3384}
     3385
    28713386bool QScriptEnginePrivate::hasDemarshalFunction(int type) const
    28723387{
     
    28753390}
    28763391
     3392JSC::UString QScriptEnginePrivate::translationContextFromUrl(const JSC::UString &url)
     3393{
     3394    if (url != cachedTranslationUrl) {
     3395        cachedTranslationContext = QFileInfo(url).baseName();
     3396        cachedTranslationUrl = url;
     3397    }
     3398    return cachedTranslationContext;
     3399}
     3400
    28773401/*!
    28783402    \internal
     
    28813405{
    28823406    Q_D(QScriptEngine);
    2883     return QScriptEnginePrivate::convert(value, type, ptr, d);
     3407    QScript::APIShim shim(d);
     3408    return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr);
    28843409}
    28853410
     
    28893414bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr)
    28903415{
    2891     return QScriptEnginePrivate::convert(value, type, ptr, /*engine=*/0);
     3416    QScriptValuePrivate *vp = QScriptValuePrivate::get(value);
     3417    if (vp) {
     3418        switch (vp->type) {
     3419        case QScriptValuePrivate::JavaScriptCore: {
     3420            if (vp->engine) {
     3421                QScript::APIShim shim(vp->engine);
     3422                return QScriptEnginePrivate::convertValue(vp->engine->currentFrame, vp->jscValue, type, ptr);
     3423            } else {
     3424                return QScriptEnginePrivate::convertValue(0, vp->jscValue, type, ptr);
     3425            }
     3426        }
     3427        case QScriptValuePrivate::Number:
     3428            return QScriptEnginePrivate::convertNumber(vp->numberValue, type, ptr);
     3429        case QScriptValuePrivate::String:
     3430            return QScriptEnginePrivate::convertString(vp->stringValue, type, ptr);
     3431        }
     3432    }
     3433    return false;
    28923434}
    28933435
     
    29003442{
    29013443    Q_D(QScriptEngine);
     3444    QScript::APIShim shim(d);
    29023445    QScriptTypeInfo *info = d->m_typeInfos.value(type);
    29033446    if (!info) {
     
    29253468    \row    \o qsTranslate() \o QCoreApplication::translate()
    29263469    \row    \o QT_TRANSLATE_NOOP() \o QT_TRANSLATE_NOOP()
     3470    \row    \o qsTrId() (since 4.7) \o qtTrId()
     3471    \row    \o QT_TRID_NOOP() (since 4.7) \o QT_TRID_NOOP()
    29273472    \endtable
    29283473
     
    29323477{
    29333478    Q_D(QScriptEngine);
     3479    QScript::APIShim shim(d);
    29343480    JSC::ExecState* exec = d->currentFrame;
    29353481    JSC::JSValue jscObject = d->scriptValueToJSCValue(object);
     
    29403486    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate));
    29413487    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp));
    2942     JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::PrototypeFunction(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr));
     3488    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr));
    29433489    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TR_NOOP"), QScript::functionQsTrNoOp));
     3490    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "qsTrId"), QScript::functionQsTrId));
     3491    JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TRID_NOOP"), QScript::functionQsTrIdNoOp));
    29443492
    29453493    glob->stringPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "arg"), QScript::stringProtoFuncArg));
     
    29653513#else
    29663514    Q_D(QScriptEngine);
     3515    QScript::APIShim shim(d);
    29673516    if (d->importedExtensions.contains(extension))
    29683517        return undefinedValue(); // already imported
     
    34614010  request that garbage collection should be performed as soon as
    34624011  possible.
     4012
     4013  \sa reportAdditionalMemoryCost()
    34634014*/
    34644015void QScriptEngine::collectGarbage()
     
    34664017    Q_D(QScriptEngine);
    34674018    d->collectGarbage();
     4019}
     4020
     4021/*!
     4022  \since 4.7
     4023
     4024  Reports an additional memory cost of the given \a size, measured in
     4025  bytes, to the garbage collector.
     4026
     4027  This function can be called to indicate that a Qt Script object has
     4028  memory associated with it that isn't managed by Qt Script itself.
     4029  Reporting the additional cost makes it more likely that the garbage
     4030  collector will be triggered.
     4031
     4032  Note that if the additional memory is shared with objects outside
     4033  the scripting environment, the cost should not be reported, since
     4034  collecting the Qt Script object would not cause the memory to be
     4035  freed anyway.
     4036
     4037  Negative \a size values are ignored, i.e. this function can't be
     4038  used to report that the additional memory has been deallocated.
     4039
     4040  \sa collectGarbage()
     4041*/
     4042void QScriptEngine::reportAdditionalMemoryCost(int size)
     4043{
     4044    Q_D(QScriptEngine);
     4045    d->reportAdditionalMemoryCost(size);
    34684046}
    34694047
     
    35484126{
    35494127    Q_D(QScriptEngine);
    3550 
     4128    if (!isEvaluating())
     4129        return;
     4130    d->abortResult = result;
    35514131    d->timeoutChecker()->setShouldAbort(true);
    3552     d->abortResult = result;
     4132    JSC::throwError(d->currentFrame, JSC::createInterruptedExecutionException(&d->currentFrame->globalData()).toObject(d->currentFrame));
    35534133}
    35544134
     
    35764156        return false;
    35774157    QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
     4158    QScript::APIShim shim(engine);
    35784159    JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
    35794160    JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
     
    36024183        return false;
    36034184    QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine());
     4185    QScript::APIShim shim(engine);
    36044186    JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver);
    36054187    JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function);
     
    36464228        return;
    36474229    }
     4230    QScript::APIShim shim(d);
    36484231    if (d->activeAgent)
    36494232        QScriptEngineAgentPrivate::get(d->activeAgent)->detach();
     
    36814264{
    36824265    Q_D(QScriptEngine);
    3683     QScriptString result;
    3684     QScriptStringPrivate *p = new QScriptStringPrivate(d, JSC::Identifier(d->currentFrame, str), QScriptStringPrivate::HeapAllocated);
    3685     QScriptStringPrivate::init(result, p);
    3686     d->registerScriptString(p);
    3687     return result;
     4266    QScript::APIShim shim(d);
     4267    return d->toStringHandle(JSC::Identifier(d->currentFrame, str));
    36884268}
    36894269
     
    37104290{
    37114291    Q_D(QScriptEngine);
     4292    QScript::APIShim shim(d);
    37124293    JSC::JSValue jscValue = d->scriptValueToJSCValue(value);
    37134294    if (!jscValue || jscValue.isUndefined() || jscValue.isNull())
     
    38614442#endif
    38624443
     4444#ifdef Q_CC_MSVC
     4445// Try to prevent compiler from crashing.
     4446#pragma optimize("", off)
     4447#endif
     4448
    38634449QT_END_NAMESPACE
  • trunk/src/script/api/qscriptengine.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    126126        SkipMethodsInEnumeration = 0x0008,
    127127        ExcludeDeleteLater = 0x0010,
     128        ExcludeSlots = 0x0020,
    128129
    129130        AutoCreateDynamicProperties = 0x0100,
     
    233234
    234235    void collectGarbage();
     236    void reportAdditionalMemoryCost(int size);
    235237
    236238    void setProcessEventsInterval(int interval);
  • trunk/src/script/api/qscriptengine_p.h

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    3838#include "private/qobject_p.h"
    3939
     40#include <QtCore/qdatetime.h>
    4041#include <QtCore/qhash.h>
     42#include <QtCore/qnumeric.h>
     43#include <QtCore/qregexp.h>
    4144#include <QtCore/qset.h>
    4245#include "qscriptvalue_p.h"
    4346#include "qscriptstring_p.h"
    44 
     47#include "bridge/qscriptclassobject_p.h"
     48#include "bridge/qscriptdeclarativeclass_p.h"
     49#include "bridge/qscriptdeclarativeobject_p.h"
     50#include "bridge/qscriptobject_p.h"
     51#include "bridge/qscriptqobject_p.h"
     52#include "bridge/qscriptvariant_p.h"
     53
     54#include "DateConstructor.h"
     55#include "DateInstance.h"
    4556#include "Debugger.h"
     57#include "ErrorInstance.h"
     58#include "JSArray.h"
     59#include "Executable.h"
    4660#include "Lexer.h"
    4761#include "RefPtr.h"
     62#include "RegExpConstructor.h"
     63#include "RegExpObject.h"
    4864#include "SourceProvider.h"
    4965#include "Structure.h"
     66#include "UString.h"
    5067#include "JSGlobalObject.h"
    5168#include "JSValue.h"
     
    5875    class JSCell;
    5976    class JSGlobalObject;
    60     class UString;
    6177}
    6278
     
    7389class QScriptSyntaxCheckResult;
    7490class QScriptEngine;
     91class QScriptProgramPrivate;
    7592
    7693namespace QScript
     
    84101    class TimeoutCheckerProxy;
    85102
     103    qint32 ToInt32(qsreal);
     104    quint32 ToUInt32(qsreal);
     105    quint16 ToUInt16(qsreal);
     106    qsreal ToInteger(qsreal);
     107
     108    inline bool ToBool(qsreal);
     109    inline bool ToBool(const QString &);
     110    inline qint32 ToInt32(const QString &);
     111    inline quint32 ToUInt32(const QString &);
     112    inline quint16 ToUInt16(const QString &);
     113    inline qsreal ToInteger(const QString &);
     114#ifdef Q_CC_MSVC
     115    // MSVC2008 crashes if these are inlined.
     116    qsreal ToNumber(const QString &);
     117    QString ToString(qsreal);
     118#else
     119    inline qsreal ToNumber(const QString &);
     120    inline QString ToString(qsreal);
     121#endif
     122
     123    QDateTime MsToDateTime(JSC::ExecState *, qsreal);
     124    qsreal DateTimeToMs(JSC::ExecState *, const QDateTime &);
     125
    86126    //some conversion helper functions
    87127    inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec);
    88128    bool isFunction(JSC::JSValue value);
     129
     130    inline void convertToLatin1_helper(const UChar *i, int length, char *s);
     131    inline QByteArray convertToLatin1(const JSC::UString &str);
    89132
    90133    class UStringSourceProviderWithFeedback;
     
    115158    static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; }
    116159
    117     static bool convert(const QScriptValue &value,
    118                         int type, void *ptr,
    119                         QScriptEnginePrivate *eng);
    120     QScriptValue create(int type, const void *ptr);
     160    static inline bool isArray(JSC::JSValue);
     161    static inline bool isDate(JSC::JSValue);
     162    static inline bool isError(JSC::JSValue);
     163    static inline bool isObject(JSC::JSValue);
     164    static inline bool isRegExp(JSC::JSValue);
     165    static inline bool isVariant(JSC::JSValue);
     166    static inline bool isQObject(JSC::JSValue);
     167    static inline bool isQMetaObject(JSC::JSValue);
     168
     169    static inline bool toBool(JSC::ExecState *, JSC::JSValue);
     170    static inline qsreal toInteger(JSC::ExecState *, JSC::JSValue);
     171    static inline qsreal toNumber(JSC::ExecState *, JSC::JSValue);
     172    static inline qint32 toInt32(JSC::ExecState *, JSC::JSValue);
     173    static inline quint32 toUInt32(JSC::ExecState *, JSC::JSValue);
     174    static inline quint16 toUInt16(JSC::ExecState *, JSC::JSValue);
     175    static inline JSC::UString toString(JSC::ExecState *, JSC::JSValue);
     176
     177    static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue);
     178#ifndef QT_NO_REGEXP
     179    static QRegExp toRegExp(JSC::ExecState*, JSC::JSValue);
     180#endif
     181    static QVariant toVariant(JSC::ExecState *, JSC::JSValue);
     182    static inline QObject *toQObject(JSC::ExecState *, JSC::JSValue);
     183    static inline const QMetaObject *toQMetaObject(JSC::ExecState *, JSC::JSValue);
     184
     185    static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id,
     186                                 int resolveMode = QScriptValue::ResolvePrototype);
     187    static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, int resolveMode);
     188    static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, quint32 index,
     189                                 int resolveMode = QScriptValue::ResolvePrototype);
     190    static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, quint32, int resolveMode);
     191    static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::UString &, int resolveMode);
     192    static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::UString &name, JSC::JSValue,
     193                     const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
     194    static void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::Identifier &id, JSC::JSValue,
     195                     const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
     196    static void setProperty(JSC::ExecState*, JSC::JSValue object, quint32 index, JSC::JSValue,
     197                     const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
     198    static QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value,
     199                                              const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode);
     200    static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value,
     201                                              const JSC::UString &name, const QScriptValue::ResolveFlags &mode);
     202
     203    static bool convertValue(JSC::ExecState*, JSC::JSValue value,
     204                             int type, void *ptr);
     205    static bool convertNumber(qsreal, int type, void *ptr);
     206    static bool convertString(const QString &, int type, void *ptr);
     207    static JSC::JSValue create(JSC::ExecState*, int type, const void *ptr);
    121208    bool hasDemarshalFunction(int type) const;
    122209
    123210    inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value);
    124211    inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value);
    125 
    126     QScriptValue scriptValueFromVariant(const QVariant &value);
    127     QVariant scriptValueToVariant(const QScriptValue &value, int targetType);
    128 
    129     JSC::JSValue jscValueFromVariant(const QVariant &value);
    130     QVariant jscValueToVariant(JSC::JSValue value, int targetType);
    131 
    132     QScriptValue arrayFromStringList(const QStringList &lst);
    133     static QStringList stringListFromArray(const QScriptValue &arr);
    134 
    135     QScriptValue arrayFromVariantList(const QVariantList &lst);
    136     static QVariantList variantListFromArray(const QScriptValue &arr);
    137 
    138     QScriptValue objectFromVariantMap(const QVariantMap &vmap);
    139     static QVariantMap variantMapFromObject(const QScriptValue &obj);
     212    static inline unsigned propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags);
     213
     214    static inline JSC::JSValue jscValueFromVariant(JSC::ExecState*, const QVariant &value);
     215    static QVariant jscValueToVariant(JSC::ExecState*, JSC::JSValue value, int targetType);
     216    static inline QVariant &variantValue(JSC::JSValue value);
     217    static inline void setVariantValue(JSC::JSValue objectValue, const QVariant &value);
     218
     219    static JSC::JSValue arrayFromStringList(JSC::ExecState*, const QStringList &lst);
     220    static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr);
     221
     222    static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst);
     223    static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSArray *arr);
     224
     225    static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap);
     226    static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSObject *obj);
    140227
    141228    JSC::JSValue defaultPrototype(int metaTypeId) const;
     
    145232    static inline JSC::ExecState *frameForContext(QScriptContext *context);
    146233    static inline const JSC::ExecState *frameForContext(const QScriptContext *context);
     234
     235    static inline bool hasValidCodeBlockRegister(JSC::ExecState *frame);
    147236
    148237    JSC::JSGlobalObject *originalGlobalObject() const;
     
    163252    bool isCollecting() const;
    164253    void collectGarbage();
     254    void reportAdditionalMemoryCost(int size);
    165255
    166256    //flags that we set on the return value register for native function. (ie when codeBlock is 0)
     
    178268    void agentDeleted(QScriptEngineAgent *agent);
    179269
     270    static inline void saveException(JSC::ExecState *, JSC::JSValue *);
     271    static inline void restoreException(JSC::ExecState *, JSC::JSValue);
     272
    180273    void setCurrentException(QScriptValue exception) { m_currentException = exception; }
    181274    QScriptValue currentException() const { return m_currentException; }
    182275    void clearCurrentException() { m_currentException.d_ptr.reset(); }
     276
     277    static QScriptSyntaxCheckResult checkSyntax(const QString &program);
     278    static bool canEvaluate(const QString &program);
     279
     280    inline void registerScriptProgram(QScriptProgramPrivate *program);
     281    inline void unregisterScriptProgram(QScriptProgramPrivate *program);
     282    void detachAllRegisteredScriptPrograms();
     283
     284    inline QScriptValuePrivate *allocateScriptValuePrivate(size_t);
     285    inline void freeScriptValuePrivate(QScriptValuePrivate *p);
     286
     287    inline void registerScriptValue(QScriptValuePrivate *value);
     288    inline void unregisterScriptValue(QScriptValuePrivate *value);
     289    void detachAllRegisteredScriptValues();
     290
     291    inline void registerScriptString(QScriptStringPrivate *value);
     292    inline void unregisterScriptString(QScriptStringPrivate *value);
     293    void detachAllRegisteredScriptStrings();
     294    QScriptString toStringHandle(const JSC::Identifier &name);
     295
     296    static inline JSC::JSValue newArray(JSC::ExecState *, uint length);
     297    static inline JSC::JSValue newDate(JSC::ExecState *, qsreal value);
     298    static inline JSC::JSValue newDate(JSC::ExecState *, const QDateTime &);
     299    inline JSC::JSValue newObject();
     300
     301#ifndef QT_NO_REGEXP
     302    static JSC::JSValue newRegExp(JSC::ExecState *, const QRegExp &);
     303#endif
     304
     305    static JSC::JSValue newRegExp(JSC::ExecState *, const QString &pattern, const QString &flags);
     306    JSC::JSValue newVariant(const QVariant &);
     307    JSC::JSValue newVariant(JSC::JSValue objectValue, const QVariant &);
     308
     309    static inline QScriptDeclarativeClass *declarativeClass(JSC::JSValue);
     310    static inline QScriptDeclarativeClass::Object *declarativeObject(JSC::JSValue);
     311
     312    JSC::UString translationContextFromUrl(const JSC::UString &);
    183313
    184314#ifndef QT_NO_QOBJECT
     
    189319                                JSC::JSValue ctor);
    190320
    191     static QScriptSyntaxCheckResult checkSyntax(const QString &program);
    192     static bool canEvaluate(const QString &program);
    193     static bool convertToNativeQObject(const QScriptValue &value,
     321    static bool convertToNativeQObject(JSC::ExecState*, JSC::JSValue,
    194322                                       const QByteArray &targetType,
    195323                                       void **result);
     
    221349                          JSC::JSValue function);
    222350
    223     inline QScriptValuePrivate *allocateScriptValuePrivate(size_t);
    224     inline void freeScriptValuePrivate(QScriptValuePrivate *p);
    225 
    226     inline void registerScriptValue(QScriptValuePrivate *value);
    227     inline void unregisterScriptValue(QScriptValuePrivate *value);
    228     void detachAllRegisteredScriptValues();
    229 
    230     inline void registerScriptString(QScriptStringPrivate *value);
    231     inline void unregisterScriptString(QScriptStringPrivate *value);
    232     void detachAllRegisteredScriptStrings();
    233 
    234351    // private slots
    235352    void _q_objectDestroyed(QObject *);
     
    241358
    242359    WTF::RefPtr<JSC::Structure> scriptObjectStructure;
     360    WTF::RefPtr<JSC::Structure> staticScopeObjectStructure;
    243361
    244362    QScript::QObjectPrototype *qobjectPrototype;
     
    259377    int freeScriptValuesCount;
    260378    QScriptStringPrivate *registeredScriptStrings;
     379    QSet<QScriptProgramPrivate*> registeredScriptPrograms;
    261380    QHash<int, QScriptTypeInfo*> m_typeInfos;
    262381    int processEventsInterval;
    263382    QScriptValue abortResult;
    264383    bool inEval;
     384
     385    JSC::UString cachedTranslationUrl;
     386    JSC::UString cachedTranslationContext;
    265387
    266388    QSet<QString> importedExtensions;
     
    270392    QScriptValue m_currentException;
    271393
     394    QSet<JSC::JSObject*> visitedConversionObjects;
     395
    272396#ifndef QT_NO_QOBJECT
    273397    QHash<QObject*, QScript::QObjectData*> m_qobjectData;
     
    281405namespace QScript
    282406{
     407
     408class APIShim
     409{
     410public:
     411    APIShim(QScriptEnginePrivate *engine)
     412        : m_engine(engine), m_oldTable(JSC::setCurrentIdentifierTable(engine->globalData->identifierTable))
     413    {
     414    }
     415    ~APIShim()
     416    {
     417        JSC::setCurrentIdentifierTable(m_oldTable);
     418    }
     419
     420private:
     421    QScriptEnginePrivate *m_engine;
     422    JSC::IdentifierTable *m_oldTable;
     423};
    283424
    284425/*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts.
     
    373514}
    374515
     516#ifndef Q_CC_MSVC
     517// MSVC2008 crashes if these are inlined.
     518
     519inline QString ToString(qsreal value)
     520{
     521    return JSC::UString::from(value);
     522}
     523
     524inline qsreal ToNumber(const QString &value)
     525{
     526    return ((JSC::UString)value).toDouble();
     527}
     528
     529#endif
     530
     531inline qint32 ToInt32(const QString &value)
     532{
     533    return ToInt32(ToNumber(value));
     534}
     535
     536inline quint32 ToUInt32(const QString &value)
     537{
     538    return ToUInt32(ToNumber(value));
     539}
     540
     541inline quint16 ToUInt16(const QString &value)
     542{
     543    return ToUInt16(ToNumber(value));
     544}
     545
     546inline qsreal ToInteger(const QString &value)
     547{
     548    return ToInteger(ToNumber(value));
     549}
     550
     551inline bool ToBool(qsreal value)
     552{
     553    return (value != 0) && !qIsNaN(value);
     554}
     555
     556inline bool ToBool(const QString &value)
     557{
     558     return !value.isEmpty();
     559}
     560
     561inline void convertToLatin1_helper(const UChar *i, int length, char *s)
     562{
     563    const UChar *e = i + length;
     564    while (i != e)
     565        *(s++) = (uchar) *(i++);
     566    *s = '\0';
     567}
     568
     569inline QByteArray convertToLatin1(const JSC::UString &str)
     570{
     571    QByteArray ba(str.size(), Qt::Uninitialized);
     572    convertToLatin1_helper(str.data(), str.size(), ba.data());
     573    return ba;
     574}
     575
    375576} // namespace QScript
     577
     578inline void QScriptEnginePrivate::registerScriptProgram(QScriptProgramPrivate *program)
     579{
     580    Q_ASSERT(!registeredScriptPrograms.contains(program));
     581    registeredScriptPrograms.insert(program);
     582}
     583
     584inline void QScriptEnginePrivate::unregisterScriptProgram(QScriptProgramPrivate *program)
     585{
     586    Q_ASSERT(registeredScriptPrograms.contains(program));
     587    registeredScriptPrograms.remove(program);
     588}
    376589
    377590inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size)
     
    416629    value->prev = 0;
    417630    value->next = 0;
     631}
     632
     633inline JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(JSC::ExecState *exec, const QVariant &v)
     634{
     635    JSC::JSValue result = create(exec, v.userType(), v.data());
     636    Q_ASSERT(result);
     637    return result;
    418638}
    419639
     
    445665}
    446666
     667inline unsigned QScriptEnginePrivate::propertyFlagsToJSCAttributes(const QScriptValue::PropertyFlags &flags)
     668{
     669    unsigned attribs = 0;
     670    if (flags & QScriptValue::ReadOnly)
     671        attribs |= JSC::ReadOnly;
     672    if (flags & QScriptValue::SkipInEnumeration)
     673        attribs |= JSC::DontEnum;
     674    if (flags & QScriptValue::Undeletable)
     675        attribs |= JSC::DontDelete;
     676    attribs |= flags & QScriptValue::UserRange;
     677    return attribs;
     678}
     679
    447680inline QScriptValuePrivate::~QScriptValuePrivate()
    448681{
     
    479712}
    480713
    481 inline QScriptValue QScriptValuePrivate::property(const QString &name, int resolveMode) const
    482 {
    483     JSC::ExecState *exec = engine->currentFrame;
    484     return property(JSC::Identifier(exec, name), resolveMode);
    485 }
    486 
    487 inline QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const
    488 {
    489     Q_ASSERT(isObject());
    490     JSC::ExecState *exec = engine->currentFrame;
    491     JSC::JSObject *object = JSC::asObject(jscValue);
     714inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::UString &name, int resolveMode)
     715{
     716    return property(exec, value, JSC::Identifier(exec, name), resolveMode);
     717}
     718
     719inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode)
     720{
     721    Q_ASSERT(isObject(value));
     722    JSC::JSObject *object = JSC::asObject(value);
    492723    JSC::PropertySlot slot(object);
    493724    if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot))
    494         return engine->scriptValueFromJSCValue(slot.getValue(exec, id));
    495     return propertyHelper(id, resolveMode);
    496 }
    497 
    498 inline QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const
    499 {
    500     Q_ASSERT(isObject());
    501     JSC::ExecState *exec = engine->currentFrame;
    502     JSC::JSObject *object = JSC::asObject(jscValue);
     725        return slot.getValue(exec, id);
     726    return propertyHelper(exec, value, id, resolveMode);
     727}
     728
     729inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode)
     730{
     731    Q_ASSERT(isObject(value));
     732    JSC::JSObject *object = JSC::asObject(value);
    503733    JSC::PropertySlot slot(object);
    504734    if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot))
    505         return engine->scriptValueFromJSCValue(slot.getValue(exec, index));
    506     return propertyHelper(index, resolveMode);
     735        return slot.getValue(exec, index);
     736    return propertyHelper(exec, value, index, resolveMode);
     737}
     738
     739inline QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value,
     740                                                                       const JSC::UString &name,
     741                                                                       const QScriptValue::ResolveFlags &mode)
     742{
     743    return propertyFlags(exec, value, JSC::Identifier(exec, name), mode);
     744}
     745
     746inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::UString &name,
     747                                              JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
     748{
     749    setProperty(exec, objectValue, JSC::Identifier(exec, name), value, flags);
     750}
     751
     752inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, const QScriptValue::ResolveFlags &resolveMode) const
     753{
     754    return QScriptEnginePrivate::property(engine->currentFrame, jscValue, id, resolveMode);
     755}
     756
     757inline JSC::JSValue QScriptValuePrivate::property(quint32 index, const QScriptValue::ResolveFlags &resolveMode) const
     758{
     759    return QScriptEnginePrivate::property(engine->currentFrame, jscValue, index, resolveMode);
     760}
     761
     762inline JSC::JSValue QScriptValuePrivate::property(const JSC::UString &name, const QScriptValue::ResolveFlags &resolveMode) const
     763{
     764    JSC::ExecState *exec = engine->currentFrame;
     765    return QScriptEnginePrivate::property(exec, jscValue, JSC::Identifier(exec, name), resolveMode);
     766}
     767
     768inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(
     769        const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const
     770{
     771    return QScriptEnginePrivate::propertyFlags(engine->currentFrame, jscValue, id, mode);
     772}
     773
     774inline void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const JSC::JSValue &value,
     775                                             const QScriptValue::PropertyFlags &flags)
     776{
     777    QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, id, value, flags);
     778}
     779
     780inline void QScriptValuePrivate::setProperty(quint32 index, const JSC::JSValue &value,
     781                                             const QScriptValue::PropertyFlags &flags)
     782{
     783    QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, index, value, flags);
     784}
     785
     786inline void QScriptValuePrivate::setProperty(const JSC::UString &name, const JSC::JSValue &value,
     787                                             const QScriptValue::PropertyFlags &flags)
     788{
     789    JSC::ExecState *exec = engine->currentFrame;
     790    QScriptEnginePrivate::setProperty(exec, jscValue, JSC::Identifier(exec, name), value, flags);
    507791}
    508792
     
    523807}
    524808
    525 inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val)
     809inline void QScriptEnginePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val)
    526810{
    527811    if (exec) {
     
    533817}
    534818
    535 inline void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val)
     819inline void QScriptEnginePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val)
    536820{
    537821    if (exec && val)
     
    582866}
    583867
     868inline bool QScriptEnginePrivate::hasValidCodeBlockRegister(JSC::ExecState *frame)
     869{
     870#if ENABLE(JIT)
     871    // Frames created by the VM don't have their CodeBlock register
     872    // initialized. We can detect such frames by checking if the
     873    // callee is a host JSFunction.
     874    JSC::JSObject *callee = frame->callee();
     875    return !(callee && callee->inherits(&JSC::JSFunction::info)
     876             && JSC::asFunction(callee)->isHostFunction());
     877#else
     878    Q_UNUSED(frame);
     879    return true;
     880#endif
     881}
     882
    584883inline JSC::ExecState *QScriptEnginePrivate::globalExec() const
    585884{
     
    587886}
    588887
     888inline JSC::JSValue QScriptEnginePrivate::newArray(JSC::ExecState *exec, uint length)
     889{
     890    return JSC::constructEmptyArray(exec, length);
     891}
     892
     893inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, qsreal value)
     894{
     895    JSC::JSValue val = JSC::jsNumber(exec, value);
     896    JSC::ArgList args(&val, 1);
     897    return JSC::constructDate(exec, args);
     898}
     899
     900inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, const QDateTime &value)
     901{
     902    return newDate(exec, QScript::DateTimeToMs(exec, value));
     903}
     904
     905inline JSC::JSValue QScriptEnginePrivate::newObject()
     906{
     907    return new (currentFrame)QScriptObject(scriptObjectStructure);
     908}
     909
     910inline bool QScriptEnginePrivate::isObject(JSC::JSValue value)
     911{
     912    return value && value.isObject();
     913}
     914
     915inline bool QScriptEnginePrivate::isArray(JSC::JSValue value)
     916{
     917    return isObject(value) && value.inherits(&JSC::JSArray::info);
     918}
     919
     920inline bool QScriptEnginePrivate::isDate(JSC::JSValue value)
     921{
     922    return isObject(value) && value.inherits(&JSC::DateInstance::info);
     923}
     924
     925inline bool QScriptEnginePrivate::isError(JSC::JSValue value)
     926{
     927    return isObject(value) && value.inherits(&JSC::ErrorInstance::info);
     928}
     929
     930inline bool QScriptEnginePrivate::isRegExp(JSC::JSValue value)
     931{
     932    return isObject(value) && value.inherits(&JSC::RegExpObject::info);
     933}
     934
     935inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value)
     936{
     937    if (!isObject(value) || !value.inherits(&QScriptObject::info))
     938        return false;
     939    QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
     940    QScriptObjectDelegate *delegate = object->delegate();
     941    return (delegate && (delegate->type() == QScriptObjectDelegate::Variant));
     942}
     943
     944inline bool QScriptEnginePrivate::isQObject(JSC::JSValue value)
     945{
     946#ifndef QT_NO_QOBJECT
     947    if (!isObject(value) || !value.inherits(&QScriptObject::info))
     948        return false;
     949    QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
     950    QScriptObjectDelegate *delegate = object->delegate();
     951    return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject ||
     952                         (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject &&
     953                          static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject())));
     954#else
     955    return false;
     956#endif
     957}
     958
     959inline bool QScriptEnginePrivate::isQMetaObject(JSC::JSValue value)
     960{
     961#ifndef QT_NO_QOBJECT
     962    return isObject(value) && JSC::asObject(value)->inherits(&QScript::QMetaObjectWrapperObject::info);
     963#else
     964    return false;
     965#endif
     966}
     967
     968inline bool QScriptEnginePrivate::toBool(JSC::ExecState *exec, JSC::JSValue value)
     969{
     970    JSC::JSValue savedException;
     971    saveException(exec, &savedException);
     972    bool result = value.toBoolean(exec);
     973    restoreException(exec, savedException);
     974    return result;
     975}
     976
     977inline qsreal QScriptEnginePrivate::toInteger(JSC::ExecState *exec, JSC::JSValue value)
     978{
     979    JSC::JSValue savedException;
     980    saveException(exec, &savedException);
     981    qsreal result = value.toInteger(exec);
     982    restoreException(exec, savedException);
     983    return result;
     984}
     985
     986inline qsreal QScriptEnginePrivate::toNumber(JSC::ExecState *exec, JSC::JSValue value)
     987{
     988    JSC::JSValue savedException;
     989    saveException(exec, &savedException);
     990    qsreal result = value.toNumber(exec);
     991    restoreException(exec, savedException);
     992    return result;
     993}
     994
     995inline qint32 QScriptEnginePrivate::toInt32(JSC::ExecState *exec, JSC::JSValue value)
     996{
     997    JSC::JSValue savedException;
     998    saveException(exec, &savedException);
     999    qint32 result = value.toInt32(exec);
     1000    restoreException(exec, savedException);
     1001    return result;
     1002}
     1003
     1004inline quint32 QScriptEnginePrivate::toUInt32(JSC::ExecState *exec, JSC::JSValue value)
     1005{
     1006    JSC::JSValue savedException;
     1007    saveException(exec, &savedException);
     1008    quint32 result = value.toUInt32(exec);
     1009    restoreException(exec, savedException);
     1010    return result;
     1011}
     1012
     1013inline quint16 QScriptEnginePrivate::toUInt16(JSC::ExecState *exec, JSC::JSValue value)
     1014{
     1015    // ### no equivalent function in JSC
     1016    return QScript::ToUInt16(toNumber(exec, value));
     1017}
     1018
     1019inline JSC::UString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value)
     1020{
     1021    JSC::JSValue savedException;
     1022    saveException(exec, &savedException);
     1023    JSC::UString str = value.toString(exec);
     1024    if (exec && exec->hadException() && !str.size()) {
     1025        JSC::JSValue savedException2;
     1026        saveException(exec, &savedException2);
     1027        str = savedException2.toString(exec);
     1028        restoreException(exec, savedException2);
     1029    }
     1030    if (savedException)
     1031        restoreException(exec, savedException);
     1032    return str;
     1033}
     1034
     1035inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *exec, JSC::JSValue value)
     1036{
     1037    if (!isDate(value))
     1038        return QDateTime();
     1039    qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(value))->internalNumber();
     1040    return QScript::MsToDateTime(exec, t);
     1041}
     1042
     1043inline QObject *QScriptEnginePrivate::toQObject(JSC::ExecState *exec, JSC::JSValue value)
     1044{
     1045#ifndef QT_NO_QOBJECT
     1046    if (isObject(value) && value.inherits(&QScriptObject::info)) {
     1047        QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value));
     1048        QScriptObjectDelegate *delegate = object->delegate();
     1049        if (!delegate)
     1050            return 0;
     1051        if (delegate->type() == QScriptObjectDelegate::QtObject)
     1052            return static_cast<QScript::QObjectDelegate*>(delegate)->value();
     1053        if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject)
     1054            return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(declarativeObject(value));
     1055        if (delegate->type() == QScriptObjectDelegate::Variant) {
     1056            QVariant var = variantValue(value);
     1057            int type = var.userType();
     1058            if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar))
     1059                return *reinterpret_cast<QObject* const *>(var.constData());
     1060        }
     1061    }
     1062#endif
     1063    return 0;
     1064}
     1065
     1066inline const QMetaObject *QScriptEnginePrivate::toQMetaObject(JSC::ExecState*, JSC::JSValue value)
     1067{
     1068#ifndef QT_NO_QOBJECT
     1069    if (isQMetaObject(value))
     1070        return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(value))->value();
     1071#endif
     1072    return 0;
     1073}
     1074
     1075inline QVariant &QScriptEnginePrivate::variantValue(JSC::JSValue value)
     1076{
     1077    Q_ASSERT(value.inherits(&QScriptObject::info));
     1078    QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(value))->delegate();
     1079    Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
     1080    return static_cast<QScript::QVariantDelegate*>(delegate)->value();
     1081}
     1082
     1083inline void QScriptEnginePrivate::setVariantValue(JSC::JSValue objectValue, const QVariant &value)
     1084{
     1085    Q_ASSERT(objectValue.inherits(&QScriptObject::info));
     1086    QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(objectValue))->delegate();
     1087    Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
     1088    static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value);
     1089}
     1090
     1091inline QScriptDeclarativeClass *QScriptEnginePrivate::declarativeClass(JSC::JSValue v)
     1092{
     1093    if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info))
     1094        return 0;
     1095    QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v));
     1096    QScriptObjectDelegate *delegate = scriptObject->delegate();
     1097    if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
     1098        return 0;
     1099    return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass();
     1100}
     1101
     1102inline QScriptDeclarativeClass::Object *QScriptEnginePrivate::declarativeObject(JSC::JSValue v)
     1103{
     1104    if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info))
     1105        return 0;
     1106    QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v));
     1107    QScriptObjectDelegate *delegate = scriptObject->delegate();
     1108    if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
     1109        return 0;
     1110    return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object();
     1111}
     1112
    5891113QT_END_NAMESPACE
    5901114
  • trunk/src/script/api/qscriptengineagent.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    118118        engine->originalGlobalObject()->setDebugger(0);
    119119    JSC::Debugger::attach(engine->originalGlobalObject());
     120    if (!QScriptEnginePrivate::get(engine)->isEvaluating())
     121        JSC::Debugger::recompileAllJSFunctions(engine->globalData);
    120122}
    121123
     
    135137{
    136138    JSC::CallFrame *oldFrame = engine->currentFrame;
     139    int oldAgentLineNumber = engine->agentLineNumber;
    137140    engine->currentFrame = frame.callFrame();
    138141    QScriptValue value(engine->scriptValueFromJSCValue(frame.exception()));
     142    engine->agentLineNumber = value.property(QLatin1String("lineNumber")).toInt32();
    139143    q_ptr->exceptionThrow(sourceID, value, hasHandler);
     144    engine->agentLineNumber = oldAgentLineNumber;
    140145    engine->currentFrame = oldFrame;
    141146    engine->setCurrentException(value);
     
    152157}
    153158
    154 void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column)
     159void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/)
    155160{
    156161    QScript::UStringSourceProviderWithFeedback *source = engine->loadedScripts.value(sourceID);
     
    159164        return;
    160165    }
    161     column = source->columnNumberFromOffset(column);
     166//    column = source->columnNumberFromOffset(column);
     167    int column = 1;
    162168    JSC::CallFrame *oldFrame = engine->currentFrame;
    163169    int oldAgentLineNumber = engine->agentLineNumber;
     
    183189
    184190void QScriptEngineAgentPrivate::didReachBreakpoint(const JSC::DebuggerCallFrame& frame,
    185                                                    intptr_t sourceID, int lineno, int column)
     191                                                   intptr_t sourceID, int lineno/*, int column*/)
    186192{
    187193    if (q_ptr->supportsExtension(QScriptEngineAgent::DebuggerInvocationRequest)) {
     
    191197            return;
    192198        }
    193         column = source->columnNumberFromOffset(column);
     199//        column = source->columnNumberFromOffset(column);
     200        int column = 1;
    194201        JSC::CallFrame *oldFrame = engine->currentFrame;
    195202        int oldAgentLineNumber = engine->agentLineNumber;
     
    366373  This function is called when the engine is about to execute a new
    367374  statement in the script identified by \a scriptId.  The statement
    368   begins on the line and column specified by \a lineNumber and \a
    369   columnNumber.  This event is not generated for native Qt Script
    370   functions.
     375  begins on the line and column specified by \a lineNumber
     376  This event is not generated for native Qt Script functions.
    371377
    372378  Reimplement this function to handle this event. For example, a
     
    376382
    377383  The default implementation does nothing.
     384
     385  \note \a columnNumber is undefined
    378386
    379387  \sa scriptLoad(), functionEntry()
  • trunk/src/script/api/qscriptengineagent.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptengineagent_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    7676
    7777    //exceptions
    78     virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno)
     78    virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, bool hasHandler)
    7979    {
    8080        Q_UNUSED(frame);
    8181        Q_UNUSED(sourceID);
    8282        Q_UNUSED(lineno);
     83        Q_UNUSED(hasHandler);
    8384    };
    8485    virtual void exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler);
     
    8687
    8788    //statements
    88     virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int column);
     89    virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno/*, int column*/);
    8990    virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno)
    9091    {
     
    108109    virtual void functionExit(const JSC::JSValue& returnValue, intptr_t sourceID);
    109110    //others
    110     virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column);
     111    virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/);
    111112
    112113    virtual void evaluateStart(intptr_t sourceID)
  • trunk/src/script/api/qscriptextensioninterface.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptextensionplugin.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptextensionplugin.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptprogram.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    3333
    3434/*!
    35   \internal
    36 
    37   \since 4.6
     35  \since 4.7
    3836  \class QScriptProgram
    3937
     
    6462QScriptProgramPrivate::~QScriptProgramPrivate()
    6563{
    66     delete _executable;
     64    if (engine) {
     65        QScript::APIShim shim(engine);
     66        _executable.clear();
     67        engine->unregisterScriptProgram(this);
     68    }
    6769}
    6870
     
    7779    if (_executable) {
    7880        if (eng == engine)
    79             return _executable;
    80         delete _executable;
     81            return _executable.get();
     82        // "Migrating" to another engine; clean up old state
     83        QScript::APIShim shim(engine);
     84        _executable.clear();
     85        engine->unregisterScriptProgram(this);
    8186    }
    8287    WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
     
    8489    sourceId = provider->asID();
    8590    JSC::SourceCode source(provider, firstLineNumber); //after construction of SourceCode provider variable will be null.
    86     _executable = new JSC::EvalExecutable(exec, source);
     91    _executable = JSC::EvalExecutable::create(exec, source);
    8792    engine = eng;
     93    engine->registerScriptProgram(this);
    8894    isCompiled = false;
    89     return _executable;
     95    return _executable.get();
     96}
     97
     98void QScriptProgramPrivate::detachFromEngine()
     99{
     100    _executable.clear();
     101    sourceId = -1;
     102    isCompiled = false;
     103    engine = 0;
    90104}
    91105
     
    122136QScriptProgram::~QScriptProgram()
    123137{
    124     Q_D(QScriptProgram);
    125     //    if (d->engine && (d->ref == 1))
    126     //      d->engine->unregisterScriptProgram(d);
    127138}
    128139
     
    132143QScriptProgram &QScriptProgram::operator=(const QScriptProgram &other)
    133144{
    134   //    if (d_func() && d_func()->engine && (d_func()->ref == 1))
    135       //        d_func()->engine->unregisterScriptProgram(d_func());
    136   //    }
    137145    d_ptr = other.d_ptr;
    138146    return *this;
  • trunk/src/script/api/qscriptprogram.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptprogram_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    3838#include <QtCore/qobjectdefs.h>
    3939
     40#include "RefPtr.h"
     41
    4042namespace JSC
    4143{
     
    6062    JSC::EvalExecutable *executable(JSC::ExecState *exec,
    6163                                    QScriptEnginePrivate *engine);
     64    void detachFromEngine();
    6265
    6366    QBasicAtomicInt ref;
     
    6871
    6972    QScriptEnginePrivate *engine;
    70     JSC::EvalExecutable *_executable;
     73    WTF::RefPtr<JSC::EvalExecutable> _executable;
    7174    intptr_t sourceId;
    7275    bool isCompiled;
  • trunk/src/script/api/qscriptstring.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    9393            break;
    9494        case QScriptStringPrivate::HeapAllocated:
    95             if (d->engine && (d->ref == 1))
     95            if (d->engine && (d->ref == 1)) {
     96                // Make sure the identifier is removed from the correct engine.
     97                QScript::APIShim shim(d->engine);
     98                d->identifier = JSC::Identifier();
    9699                d->engine->unregisterScriptString(d);
     100            }
    97101            break;
    98102        }
  • trunk/src/script/api/qscriptstring.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptstring_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptvalue.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    3030#include "qscriptstring_p.h"
    3131
    32 #include "JSArray.h"
    3332#include "JSGlobalObject.h"
    3433#include "JSImmediate.h"
     
    3635#include "JSValue.h"
    3736#include "JSFunction.h"
    38 #include "DateInstance.h"
    39 #include "ErrorInstance.h"
    40 #include "RegExpObject.h"
    4137#include "Identifier.h"
    4238#include "Operations.h"
    4339#include "Arguments.h"
    4440
    45 #include <QtCore/qdatetime.h>
    46 #include <QtCore/qregexp.h>
    4741#include <QtCore/qvariant.h>
    4842#include <QtCore/qvarlengtharray.h>
    4943#include <QtCore/qnumeric.h>
    50 
    51 #include "utils/qscriptdate_p.h"
    52 #include "bridge/qscriptobject_p.h"
    53 #include "bridge/qscriptclassobject_p.h"
    54 #include "bridge/qscriptvariant_p.h"
    55 #include "bridge/qscriptqobject_p.h"
    56 #include "bridge/qscriptdeclarativeclass_p.h"
    57 #include "bridge/qscriptdeclarativeobject_p.h"
    5844
    5945/*!
     
    181167*/
    182168
    183 // ### move
    184 
    185 #include <QtCore/qnumeric.h>
    186 #include <math.h>
    187 
    188169QT_BEGIN_NAMESPACE
    189 
    190 namespace QScript
    191 {
    192 
    193 static const qsreal D32 = 4294967296.0;
    194 
    195 qint32 ToInt32(qsreal n)
    196 {
    197     if (qIsNaN(n) || qIsInf(n) || (n == 0))
    198         return 0;
    199 
    200     qsreal sign = (n < 0) ? -1.0 : 1.0;
    201     qsreal abs_n = fabs(n);
    202 
    203     n = ::fmod(sign * ::floor(abs_n), D32);
    204     const double D31 = D32 / 2.0;
    205 
    206     if (sign == -1 && n < -D31)
    207         n += D32;
    208 
    209     else if (sign != -1 && n >= D31)
    210         n -= D32;
    211 
    212     return qint32 (n);
    213 }
    214 
    215 quint32 ToUint32(qsreal n)
    216 {
    217     if (qIsNaN(n) || qIsInf(n) || (n == 0))
    218         return 0;
    219 
    220     qsreal sign = (n < 0) ? -1.0 : 1.0;
    221     qsreal abs_n = fabs(n);
    222 
    223     n = ::fmod(sign * ::floor(abs_n), D32);
    224 
    225     if (n < 0)
    226         n += D32;
    227 
    228     return quint32 (n);
    229 }
    230 
    231 quint16 ToUint16(qsreal n)
    232 {
    233     static const qsreal D16 = 65536.0;
    234 
    235     if (qIsNaN(n) || qIsInf(n) || (n == 0))
    236         return 0;
    237 
    238     qsreal sign = (n < 0) ? -1.0 : 1.0;
    239     qsreal abs_n = fabs(n);
    240 
    241     n = ::fmod(sign * ::floor(abs_n), D16);
    242 
    243     if (n < 0)
    244         n += D16;
    245 
    246     return quint16 (n);
    247 }
    248 
    249 qsreal ToInteger(qsreal n)
    250 {
    251     if (qIsNaN(n))
    252         return 0;
    253 
    254     if (n == 0 || qIsInf(n))
    255         return n;
    256 
    257     int sign = n < 0 ? -1 : 1;
    258     return sign * ::floor(::fabs(n));
    259 }
    260 
    261 } // namespace QScript
    262 
    263 QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const
    264 {
    265     JSC::JSValue result;
    266     if (!(resolveMode & QScriptValue::ResolvePrototype)) {
    267         // Look in the object's own properties
    268         JSC::ExecState *exec = engine->currentFrame;
    269         JSC::JSObject *object = JSC::asObject(jscValue);
    270         JSC::PropertySlot slot(object);
    271         if (object->getOwnPropertySlot(exec, id, slot))
    272             result = slot.getValue(exec, id);
    273     }
    274     if (!result && (resolveMode & QScriptValue::ResolveScope)) {
    275         // ### check if it's a function object and look in the scope chain
    276         QScriptValue scope = property(QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal);
    277         if (scope.isObject())
    278             result = engine->scriptValueToJSCValue(QScriptValuePrivate::get(scope)->property(id, resolveMode));
    279     }
    280     return engine->scriptValueFromJSCValue(result);
    281 }
    282 
    283 QScriptValue QScriptValuePrivate::propertyHelper(quint32 index, int resolveMode) const
    284 {
    285     JSC::JSValue result;
    286     if (!(resolveMode & QScriptValue::ResolvePrototype)) {
    287         // Look in the object's own properties
    288         JSC::ExecState *exec = engine->currentFrame;
    289         JSC::JSObject *object = JSC::asObject(jscValue);
    290         JSC::PropertySlot slot(object);
    291         if (object->getOwnPropertySlot(exec, index, slot))
    292             result = slot.getValue(exec, index);
    293     }
    294     return engine->scriptValueFromJSCValue(result);
    295 }
    296 
    297 void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptValue &value,
    298                                       const QScriptValue::PropertyFlags &flags)
    299 {
    300     QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value);
    301     if (valueEngine && (valueEngine != engine)) {
    302         qWarning("QScriptValue::setProperty(%s) failed: "
    303                  "cannot set value created in a different engine",
    304                  qPrintable(QString(id.ustring())));
    305         return;
    306     }
    307     JSC::ExecState *exec = engine->currentFrame;
    308     JSC::JSValue jsValue = engine->scriptValueToJSCValue(value);
    309     JSC::JSObject *thisObject = JSC::asObject(jscValue);
    310     JSC::JSValue setter = thisObject->lookupSetter(exec, id);
    311     JSC::JSValue getter = thisObject->lookupGetter(exec, id);
    312     if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
    313         if (!jsValue) {
    314             // deleting getter/setter
    315             if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) {
    316                 // deleting both: just delete the property
    317                 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
    318             } else if (flags & QScriptValue::PropertyGetter) {
    319                 // preserve setter, if there is one
    320                 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
    321                 if (setter && setter.isObject())
    322                     thisObject->defineSetter(exec, id, JSC::asObject(setter));
    323             } else { // flags & QScriptValue::PropertySetter
    324                 // preserve getter, if there is one
    325                 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
    326                 if (getter && getter.isObject())
    327                     thisObject->defineGetter(exec, id, JSC::asObject(getter));
    328             }
    329         } else {
    330             if (jsValue.isObject()) { // ### should check if it has callData()
    331                 // defining getter/setter
    332                 if (id == exec->propertyNames().underscoreProto) {
    333                     qWarning("QScriptValue::setProperty() failed: "
    334                              "cannot set getter or setter of native property `__proto__'");
    335                 } else {
    336                     if (flags & QScriptValue::PropertyGetter)
    337                         thisObject->defineGetter(exec, id, JSC::asObject(jsValue));
    338                     if (flags & QScriptValue::PropertySetter)
    339                         thisObject->defineSetter(exec, id, JSC::asObject(jsValue));
    340                 }
    341             } else {
    342                 qWarning("QScriptValue::setProperty(): getter/setter must be a function");
    343             }
    344         }
    345     } else {
    346         // setting the value
    347         if (getter && getter.isObject() && !(setter && setter.isObject())) {
    348             qWarning("QScriptValue::setProperty() failed: "
    349                      "property '%s' has a getter but no setter",
    350                      qPrintable(QString(id.ustring())));
    351             return;
    352         }
    353         if (!jsValue) {
    354             // ### check if it's a getter/setter property
    355             thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
    356         } else if (flags != QScriptValue::KeepExistingFlags) {
    357             if (thisObject->hasOwnProperty(exec, id))
    358                 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes?
    359             unsigned attribs = 0;
    360             if (flags & QScriptValue::ReadOnly)
    361                 attribs |= JSC::ReadOnly;
    362             if (flags & QScriptValue::SkipInEnumeration)
    363                 attribs |= JSC::DontEnum;
    364             if (flags & QScriptValue::Undeletable)
    365                 attribs |= JSC::DontDelete;
    366             attribs |= flags & QScriptValue::UserRange;
    367             thisObject->putWithAttributes(exec, id, jsValue, attribs);
    368         } else {
    369             JSC::PutPropertySlot slot;
    370             thisObject->put(exec, id, jsValue, slot);
    371         }
    372     }
    373 }
    374 
    375 QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identifier &id,
    376                                                                const QScriptValue::ResolveFlags &mode) const
    377 {
    378     JSC::ExecState *exec = engine->currentFrame;
    379     JSC::JSObject *object = JSC::asObject(jscValue);
    380     unsigned attribs = 0;
    381     JSC::PropertyDescriptor descriptor;
    382     if (object->getOwnPropertyDescriptor(exec, id, descriptor))
    383         attribs = descriptor.attributes();
    384     else if (!object->getPropertyAttributes(exec, id, attribs)) {
    385         if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
    386             QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype());
    387             return QScriptValuePrivate::get(proto)->propertyFlags(id, mode);
    388         }
    389         return 0;
    390     }
    391     QScriptValue::PropertyFlags result = 0;
    392     if (attribs & JSC::ReadOnly)
    393         result |= QScriptValue::ReadOnly;
    394     if (attribs & JSC::DontEnum)
    395         result |= QScriptValue::SkipInEnumeration;
    396     if (attribs & JSC::DontDelete)
    397         result |= QScriptValue::Undeletable;
    398     //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?)
    399     if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull())
    400         result |= QScriptValue::PropertyGetter;
    401     if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull())
    402         result |= QScriptValue::PropertySetter;
    403     if (attribs & QScript::QObjectMemberAttribute)
    404         result |= QScriptValue::QObjectMember;
    405     result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange);
    406     return result;
    407 }
    408 
    409 QVariant &QScriptValuePrivate::variantValue() const
    410 {
    411     Q_ASSERT(jscValue.inherits(&QScriptObject::info));
    412     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate();
    413     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
    414     return static_cast<QScript::QVariantDelegate*>(delegate)->value();
    415 }
    416 
    417 void QScriptValuePrivate::setVariantValue(const QVariant &value)
    418 {
    419     Q_ASSERT(jscValue.inherits(&QScriptObject::info));
    420     QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate();
    421     Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
    422     static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value);
    423 }
    424170
    425171void QScriptValuePrivate::detachFromEngine()
     
    708454{
    709455    Q_D(const QScriptValue);
    710     if (!d || !d->isObject())
     456    if (!d || !d->isJSC())
    711457        return false;
    712     return d->jscValue.inherits(&JSC::ErrorInstance::info);
     458    return QScriptEnginePrivate::isError(d->jscValue);
    713459}
    714460
     
    722468{
    723469    Q_D(const QScriptValue);
    724     if (!d || !d->isObject())
     470    if (!d || !d->isJSC())
    725471        return false;
    726     return d->jscValue.inherits(&JSC::JSArray::info);
     472    return QScriptEnginePrivate::isArray(d->jscValue);
    727473}
    728474
     
    736482{
    737483    Q_D(const QScriptValue);
    738     if (!d || !d->isObject())
     484    if (!d || !d->isJSC())
    739485        return false;
    740     return d->jscValue.inherits(&JSC::DateInstance::info);
     486    return QScriptEnginePrivate::isDate(d->jscValue);
    741487}
    742488
     
    750496{
    751497    Q_D(const QScriptValue);
    752     if (!d || !d->isObject())
     498    if (!d || !d->isJSC())
    753499        return false;
    754     return d->jscValue.inherits(&JSC::RegExpObject::info);
     500    return QScriptEnginePrivate::isRegExp(d->jscValue);
    755501}
    756502
     
    825571    if (!d || !d->isObject())
    826572        return QScriptValue();
     573    QScript::APIShim shim(d->engine);
    827574    // ### make hidden property
    828     return d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal);
     575    JSC::JSValue result = d->property("__qt_scope__", QScriptValue::ResolveLocal);
     576    return d->engine->scriptValueFromJSCValue(result);
    829577}
    830578
     
    913661}
    914662
    915 QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference)
     663static QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference)
    916664{
    917665    Q_ASSERT(object.isObject());
    918666    QScriptValuePrivate *pp = QScriptValuePrivate::get(object);
    919667    Q_ASSERT(pp->engine != 0);
     668    QScript::APIShim shim(pp->engine);
    920669    JSC::ExecState *exec = pp->engine->currentFrame;
    921670    JSC::JSValue savedException;
    922     QScriptValuePrivate::saveException(exec, &savedException);
     671    QScriptEnginePrivate::saveException(exec, &savedException);
    923672    JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint);
    924     QScriptValuePrivate::restoreException(exec, savedException);
     673    QScriptEnginePrivate::restoreException(exec, savedException);
    925674    return pp->engine->scriptValueFromJSCValue(result);
    926675}
     
    1111860            eng_p = other.d_ptr->engine;
    1112861        if (eng_p) {
     862            QScript::APIShim shim(eng_p);
    1113863            JSC::ExecState *exec = eng_p->currentFrame;
    1114864            JSC::JSValue savedException;
    1115             QScriptValuePrivate::saveException(exec, &savedException);
     865            QScriptEnginePrivate::saveException(exec, &savedException);
    1116866            bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue);
    1117             QScriptValuePrivate::restoreException(exec, savedException);
     867            QScriptEnginePrivate::restoreException(exec, savedException);
    1118868            return result;
    1119869        }
     
    1161911            QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine;
    1162912            if (eng_p)
    1163                 return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other));
     913                return JSC::JSValue::strictEqual(eng_p->currentFrame, d->jscValue, eng_p->scriptValueToJSCValue(other));
    1164914        } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) {
    1165915            QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine;
    1166916            if (eng_p)
    1167                 return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
     917                return JSC::JSValue::strictEqual(eng_p->currentFrame, eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
    1168918        }
    1169919
     
    1171921    }
    1172922    switch (d->type) {
    1173     case QScriptValuePrivate::JavaScriptCore:
    1174         return JSC::JSValue::strictEqual(d->jscValue, other.d_ptr->jscValue);
     923    case QScriptValuePrivate::JavaScriptCore: {
     924        QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine;
     925        JSC::ExecState *exec = eng_p ? eng_p->currentFrame : 0;
     926        return JSC::JSValue::strictEqual(exec, d->jscValue, other.d_ptr->jscValue);
     927    }
    1175928    case QScriptValuePrivate::Number:
    1176929        return (d->numberValue == other.d_ptr->numberValue);
     
    1200953    switch (d->type) {
    1201954    case QScriptValuePrivate::JavaScriptCore: {
    1202         JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
    1203         JSC::JSValue savedException;
    1204         QScriptValuePrivate::saveException(exec, &savedException);
    1205         JSC::UString str = d->jscValue.toString(exec);
    1206         if (exec && exec->hadException() && !str.size()) {
    1207             JSC::JSValue savedException2;
    1208             QScriptValuePrivate::saveException(exec, &savedException2);
    1209             str = savedException2.toString(exec);
    1210             QScriptValuePrivate::restoreException(exec, savedException2);
    1211         }
    1212         if (savedException)
    1213             QScriptValuePrivate::restoreException(exec, savedException);
    1214         return str;
    1215     }
     955        if (d->engine) {
     956            QScript::APIShim shim(d->engine);
     957            return QScriptEnginePrivate::toString(d->engine->currentFrame, d->jscValue);
     958        } else {
     959            return QScriptEnginePrivate::toString(0, d->jscValue);
     960        }    }
    1216961    case QScriptValuePrivate::Number:
    1217         return JSC::UString::from(d->numberValue);
     962        return QScript::ToString(d->numberValue);
    1218963    case QScriptValuePrivate::String:
    1219964        return d->stringValue;
     
    1241986    switch (d->type) {
    1242987    case QScriptValuePrivate::JavaScriptCore: {
    1243         JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
    1244         JSC::JSValue savedException;
    1245         QScriptValuePrivate::saveException(exec, &savedException);
    1246         qsreal result = d->jscValue.toNumber(exec);
    1247         QScriptValuePrivate::restoreException(exec, savedException);
    1248         return result;
     988        if (d->engine) {
     989            QScript::APIShim shim(d->engine);
     990            return QScriptEnginePrivate::toNumber(d->engine->currentFrame, d->jscValue);
     991        } else {
     992            return QScriptEnginePrivate::toNumber(0, d->jscValue);
     993        }
    1249994    }
    1250995    case QScriptValuePrivate::Number:
    1251996        return d->numberValue;
    1252997    case QScriptValuePrivate::String:
    1253         return ((JSC::UString)d->stringValue).toDouble();
     998        return QScript::ToNumber(d->stringValue);
    1254999    }
    12551000    return 0;
     
    12681013    switch (d->type) {
    12691014    case QScriptValuePrivate::JavaScriptCore: {
    1270         JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
    1271         JSC::JSValue savedException;
    1272         QScriptValuePrivate::saveException(exec, &savedException);
    1273         bool result = d->jscValue.toBoolean(exec);
    1274         QScriptValuePrivate::restoreException(exec, savedException);
    1275         return result;
     1015        if (d->engine) {
     1016            QScript::APIShim shim(d->engine);
     1017            return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue);
     1018        } else {
     1019            return QScriptEnginePrivate::toBool(0, d->jscValue);
     1020        }
    12761021    }
    12771022    case QScriptValuePrivate::Number:
    1278         return (d->numberValue != 0) && !qIsNaN(d->numberValue);
     1023        return QScript::ToBool(d->numberValue);
    12791024    case QScriptValuePrivate::String:
    1280         return (!d->stringValue.isEmpty());
     1025        return QScript::ToBool(d->stringValue);
    12811026    }
    12821027    return false;
     
    13041049    switch (d->type) {
    13051050    case QScriptValuePrivate::JavaScriptCore: {
    1306         JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
    1307         JSC::JSValue savedException;
    1308         QScriptValuePrivate::saveException(exec, &savedException);
    1309         bool result = d->jscValue.toBoolean(exec);
    1310         QScriptValuePrivate::restoreException(exec, savedException);
    1311         return result;
     1051        if (d->engine) {
     1052            QScript::APIShim shim(d->engine);
     1053            return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue);
     1054        } else {
     1055            return QScriptEnginePrivate::toBool(0, d->jscValue);
     1056        }
    13121057    }
    13131058    case QScriptValuePrivate::Number:
    1314         return (d->numberValue != 0) && !qIsNaN(d->numberValue);
     1059        return QScript::ToBool(d->numberValue);
    13151060    case QScriptValuePrivate::String:
    1316         return (!d->stringValue.isEmpty());
     1061        return QScript::ToBool(d->stringValue);
    13171062    }
    13181063    return false;
     
    13381083    switch (d->type) {
    13391084    case QScriptValuePrivate::JavaScriptCore: {
    1340         JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
    1341         JSC::JSValue savedException;
    1342         QScriptValuePrivate::saveException(exec, &savedException);
    1343         qint32 result = d->jscValue.toInt32(exec);
    1344         QScriptValuePrivate::restoreException(exec, savedException);
    1345         return result;
     1085        if (d->engine) {
     1086            QScript::APIShim shim(d->engine);
     1087            return QScriptEnginePrivate::toInt32(d->engine->currentFrame, d->jscValue);
     1088        } else {
     1089            return QScriptEnginePrivate::toInt32(0, d->jscValue);
     1090        }
    13461091    }
    13471092    case QScriptValuePrivate::Number:
    13481093        return QScript::ToInt32(d->numberValue);
    13491094    case QScriptValuePrivate::String:
    1350         return QScript::ToInt32(((JSC::UString)d->stringValue).toDouble());
     1095        return QScript::ToInt32(d->stringValue);
    13511096    }
    13521097    return 0;
     
    13721117    switch (d->type) {
    13731118    case QScriptValuePrivate::JavaScriptCore: {
    1374         JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
    1375         JSC::JSValue savedException;
    1376         QScriptValuePrivate::saveException(exec, &savedException);
    1377         quint32 result = d->jscValue.toUInt32(exec);
    1378         QScriptValuePrivate::restoreException(exec, savedException);
    1379         return result;
     1119        if (d->engine) {
     1120            QScript::APIShim shim(d->engine);
     1121            return QScriptEnginePrivate::toUInt32(d->engine->currentFrame, d->jscValue);
     1122        } else {
     1123            return QScriptEnginePrivate::toUInt32(0, d->jscValue);
     1124        }
    13801125    }
    13811126    case QScriptValuePrivate::Number:
    1382         return QScript::ToUint32(d->numberValue);
     1127        return QScript::ToUInt32(d->numberValue);
    13831128    case QScriptValuePrivate::String:
    1384         return QScript::ToUint32(((JSC::UString)d->stringValue).toDouble());
     1129        return QScript::ToUInt32(d->stringValue);
    13851130    }
    13861131    return 0;
     
    14061151    switch (d->type) {
    14071152    case QScriptValuePrivate::JavaScriptCore: {
    1408         // ### no equivalent function in JSC
    1409         return QScript::ToUint16(toNumber());
     1153        if (d->engine) {
     1154            QScript::APIShim shim(d->engine);
     1155            return QScriptEnginePrivate::toUInt16(d->engine->currentFrame, d->jscValue);
     1156        } else {
     1157            return QScriptEnginePrivate::toUInt16(0, d->jscValue);
     1158        }
    14101159    }
    14111160    case QScriptValuePrivate::Number:
    1412         return QScript::ToUint16(d->numberValue);
     1161        return QScript::ToUInt16(d->numberValue);
    14131162    case QScriptValuePrivate::String:
    1414         return QScript::ToUint16(((JSC::UString)d->stringValue).toDouble());
     1163        return QScript::ToUInt16(d->stringValue);
    14151164    }
    14161165    return 0;
     
    14361185    switch (d->type) {
    14371186    case QScriptValuePrivate::JavaScriptCore: {
    1438         JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
    1439         JSC::JSValue savedException;
    1440         QScriptValuePrivate::saveException(exec, &savedException);
    1441         qsreal result = d->jscValue.toInteger(exec);
    1442         QScriptValuePrivate::restoreException(exec, savedException);
    1443         return result;
     1187        if (d->engine) {
     1188            QScript::APIShim shim(d->engine);
     1189            return QScriptEnginePrivate::toInteger(d->engine->currentFrame, d->jscValue);
     1190        } else {
     1191            return QScriptEnginePrivate::toInteger(0, d->jscValue);
     1192        }
    14441193    }
    14451194    case QScriptValuePrivate::Number:
    14461195        return QScript::ToInteger(d->numberValue);
    14471196    case QScriptValuePrivate::String:
    1448         return QScript::ToInteger(((JSC::UString)d->stringValue).toDouble());
     1197        return QScript::ToInteger(d->stringValue);
    14491198    }
    14501199    return 0;
     
    14671216    \row    \o Date Object \o A QVariant containing the date value (toDateTime()).
    14681217    \row    \o RegExp Object \o A QVariant containing the regular expression value (toRegExp()).
    1469     \row    \o Array Object \o The array is converted to a QVariantList.
    1470     \row    \o Object     \o If the value is primitive, then the result is converted to a QVariant according to the above rules; otherwise, an invalid QVariant is returned.
     1218    \row    \o Array Object \o The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed.
     1219    \row    \o Object     \o The object is converted to a QVariantMap. Each property is converted to a QVariant, recursively; cyclic references are not followed.
    14711220    \endtable
    14721221
     
    14791228        return QVariant();
    14801229    switch (d->type) {
    1481     case QScriptValuePrivate::JavaScriptCore:
    1482         if (isObject()) {
    1483             if (isVariant())
    1484                 return d->variantValue();
    1485 #ifndef QT_NO_QOBJECT
    1486             else if (isQObject())
    1487                 return qVariantFromValue(toQObject());
    1488 #endif
    1489             else if (isDate())
    1490                 return QVariant(toDateTime());
    1491 #ifndef QT_NO_REGEXP
    1492             else if (isRegExp())
    1493                 return QVariant(toRegExp());
    1494 #endif
    1495             else if (isArray())
    1496                 return QScriptEnginePrivate::variantListFromArray(*this);
    1497             else if (QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(*this))
    1498                 return dc->toVariant(QScriptDeclarativeClass::object(*this));
    1499             // try to convert to primitive
    1500             JSC::ExecState *exec = d->engine->currentFrame;
    1501             JSC::JSValue savedException;
    1502             QScriptValuePrivate::saveException(exec, &savedException);
    1503             JSC::JSValue prim = d->jscValue.toPrimitive(exec);
    1504             QScriptValuePrivate::restoreException(exec, savedException);
    1505             if (!prim.isObject())
    1506                 return d->engine->scriptValueFromJSCValue(prim).toVariant();
    1507         } else if (isNumber()) {
    1508             return QVariant(toNumber());
    1509         } else if (isString()) {
    1510             return QVariant(toString());
    1511         } else if (isBool()) {
    1512             return QVariant(toBool());
     1230    case QScriptValuePrivate::JavaScriptCore: {
     1231        if (d->engine) {
     1232            QScript::APIShim shim(d->engine);
     1233            return QScriptEnginePrivate::toVariant(d->engine->currentFrame, d->jscValue);
     1234        } else {
     1235            return QScriptEnginePrivate::toVariant(0, d->jscValue);
    15131236        }
    1514         return QVariant();
     1237    }
    15151238    case QScriptValuePrivate::Number:
    15161239        return QVariant(d->numberValue);
     
    15441267{
    15451268    Q_D(const QScriptValue);
    1546     if (!isDate())
     1269    if (!d || !d->engine)
    15471270        return QDateTime();
    1548     qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(d->jscValue))->internalNumber();
    1549     return QScript::ToDateTime(t, Qt::LocalTime);
     1271    QScript::APIShim shim(d->engine);
     1272    return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue);
    15501273}
    15511274
     
    15611284{
    15621285    Q_D(const QScriptValue);
    1563     if (!isRegExp())
    1564         return QRegExp();
    1565     QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString();
    1566     Qt::CaseSensitivity kase = Qt::CaseSensitive;
    1567     if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool())
    1568         kase = Qt::CaseInsensitive;
    1569     return QRegExp(pattern, kase, QRegExp::RegExp2);
     1286    if (!d || !d->engine)
     1287         return QRegExp();
     1288    QScript::APIShim shim(d->engine);
     1289    return QScriptEnginePrivate::toRegExp(d->engine->currentFrame, d->jscValue);
    15701290}
    15711291#endif // QT_NO_REGEXP
     
    15841304{
    15851305    Q_D(const QScriptValue);
    1586     if (isQObject()) {
    1587         QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
    1588         QScriptObjectDelegate *delegate = object->delegate();
    1589         if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject)
    1590             return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(QScriptDeclarativeClass::object(*this));
    1591         return static_cast<QScript::QObjectDelegate*>(delegate)->value();
    1592     } else if (isVariant()) {
    1593         QVariant var = toVariant();
    1594         int type = var.userType();
    1595         if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar))
    1596             return *reinterpret_cast<QObject* const *>(var.constData());
    1597     }
    1598     return 0;
     1306    if (!d || !d->engine)
     1307        return 0;
     1308    QScript::APIShim shim(d->engine);
     1309    return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue);
    15991310}
    16001311
     
    16081319{
    16091320    Q_D(const QScriptValue);
    1610     if (isQMetaObject())
    1611         return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(d->jscValue))->value();
    1612     return 0;
     1321    if (!d || !d->engine)
     1322        return 0;
     1323    QScript::APIShim shim(d->engine);
     1324    return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue);
    16131325}
    16141326
     
    16441356    if (!d || !d->isObject())
    16451357        return;
    1646     JSC::ExecState *exec = d->engine->currentFrame;
    1647     d->setProperty(JSC::Identifier(exec, name), value, flags);
     1358    QScript::APIShim shim(d->engine);
     1359    QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value);
     1360    if (valueEngine && (valueEngine != d->engine)) {
     1361        qWarning("QScriptValue::setProperty(%s) failed: "
     1362                 "cannot set value created in a different engine",
     1363                 qPrintable(name));
     1364        return;
     1365    }
     1366    JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value);
     1367    d->setProperty(name, jsValue, flags);
    16481368}
    16491369
     
    16691389    if (!d || !d->isObject())
    16701390        return QScriptValue();
    1671     return d->property(name, mode);
     1391    QScript::APIShim shim(d->engine);
     1392    return d->engine->scriptValueFromJSCValue(d->property(name, mode));
    16721393}
    16731394
     
    16911412    if (!d || !d->isObject())
    16921413        return QScriptValue();
    1693     return d->property(arrayIndex, mode);
     1414    QScript::APIShim shim(d->engine);
     1415    return d->engine->scriptValueFromJSCValue(d->property(arrayIndex, mode));
    16941416}
    16951417
     
    17181440        return;
    17191441    }
    1720     JSC::ExecState *exec = d->engine->currentFrame;
    1721     JSC::JSValue jscValue = d->engine->scriptValueToJSCValue(value);
    1722     if (!jscValue) {
    1723         JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex, /*checkDontDelete=*/false);
    1724     } else {
    1725         if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
    1726             // fall back to string-based setProperty(), since there is no
    1727             // JSC::JSObject::defineGetter(unsigned)
    1728             d->setProperty(JSC::Identifier::from(exec, arrayIndex), value, flags);
    1729         } else {
    1730             if (flags != QScriptValue::KeepExistingFlags) {
    1731 //                if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex))
    1732 //                    JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex);
    1733                 unsigned attribs = 0;
    1734                 if (flags & QScriptValue::ReadOnly)
    1735                     attribs |= JSC::ReadOnly;
    1736                 if (flags & QScriptValue::SkipInEnumeration)
    1737                     attribs |= JSC::DontEnum;
    1738                 if (flags & QScriptValue::Undeletable)
    1739                     attribs |= JSC::DontDelete;
    1740                 attribs |= flags & QScriptValue::UserRange;
    1741                 JSC::asObject(d->jscValue)->putWithAttributes(exec, arrayIndex, jscValue, attribs);
    1742             } else {
    1743                 JSC::asObject(d->jscValue)->put(exec, arrayIndex, jscValue);
    1744             }
    1745         }
    1746     }
     1442    QScript::APIShim shim(d->engine);
     1443    JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value);
     1444    d->setProperty(arrayIndex, jsValue, flags);
    17471445}
    17481446
     
    17651463    if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
    17661464        return QScriptValue();
    1767     return d->property(name.d_ptr->identifier, mode);
     1465    QScript::APIShim shim(d->engine);
     1466    return d->engine->scriptValueFromJSCValue(d->property(name.d_ptr->identifier, mode));
    17681467}
    17691468
     
    17881487    if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
    17891488        return;
    1790     d->setProperty(name.d_ptr->identifier, value, flags);
     1489    QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value);
     1490    if (valueEngine && (valueEngine != d->engine)) {
     1491        qWarning("QScriptValue::setProperty(%s) failed: "
     1492                 "cannot set value created in a different engine",
     1493                 qPrintable(name.toString()));
     1494        return;
     1495    }
     1496    QScript::APIShim shim(d->engine);
     1497    JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value);
     1498    d->setProperty(name.d_ptr->identifier, jsValue, flags);
    17911499}
    17921500
     
    18031511    if (!d || !d->isObject())
    18041512        return 0;
     1513    QScript::APIShim shim(d->engine);
    18051514    JSC::ExecState *exec = d->engine->currentFrame;
    18061515    return d->propertyFlags(JSC::Identifier(exec, name), mode);
     
    18521561{
    18531562    Q_D(const QScriptValue);
    1854     if (!d || !d->isJSC())
     1563    if (!d || !d->isObject())
    18551564        return QScriptValue();
     1565    QScript::APIShim shim(d->engine);
    18561566    JSC::JSValue callee = d->jscValue;
    18571567    JSC::CallData callData;
     
    18921602
    18931603    JSC::JSValue savedException;
    1894     QScriptValuePrivate::saveException(exec, &savedException);
     1604    QScriptEnginePrivate::saveException(exec, &savedException);
    18951605    JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs);
    18961606    if (exec->hadException()) {
    18971607        result = exec->exception();
    18981608    } else {
    1899         QScriptValuePrivate::restoreException(exec, savedException);
     1609        QScriptEnginePrivate::restoreException(exec, savedException);
    19001610    }
    19011611    return d->engine->scriptValueFromJSCValue(result);
     
    19291639{
    19301640    Q_D(QScriptValue);
    1931     if (!d || !d->isJSC())
     1641    if (!d || !d->isObject())
    19321642        return QScriptValue();
     1643    QScript::APIShim shim(d->engine);
    19331644    JSC::JSValue callee = d->jscValue;
    19341645    JSC::CallData callData;
     
    19721683
    19731684    JSC::JSValue savedException;
    1974     QScriptValuePrivate::saveException(exec, &savedException);
     1685    QScriptEnginePrivate::saveException(exec, &savedException);
    19751686    JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs);
    19761687    if (exec->hadException()) {
    19771688        result = exec->exception();
    19781689    } else {
    1979         QScriptValuePrivate::restoreException(exec, savedException);
     1690        QScriptEnginePrivate::restoreException(exec, savedException);
    19801691    }
    19811692    return d->engine->scriptValueFromJSCValue(result);
     
    20031714{
    20041715    Q_D(const QScriptValue);
    2005     if (!d || !d->isJSC())
     1716    if (!d || !d->isObject())
    20061717        return QScriptValue();
     1718    QScript::APIShim shim(d->engine);
    20071719    JSC::JSValue callee = d->jscValue;
    20081720    JSC::ConstructData constructData;
     
    20241736
    20251737    JSC::JSValue savedException;
    2026     QScriptValuePrivate::saveException(exec, &savedException);
    2027     JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs);
     1738    QScriptEnginePrivate::saveException(exec, &savedException);
     1739    JSC::JSValue result;
     1740    JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, jscArgs);
    20281741    if (exec->hadException()) {
    2029         result = JSC::asObject(exec->exception());
     1742        result = exec->exception();
    20301743    } else {
    2031         QScriptValuePrivate::restoreException(exec, savedException);
     1744        result = newObject;
     1745        QScriptEnginePrivate::restoreException(exec, savedException);
    20321746    }
    20331747    return d->engine->scriptValueFromJSCValue(result);
     
    20521766{
    20531767    Q_D(QScriptValue);
    2054     if (!d || !d->isJSC())
     1768    if (!d || !d->isObject())
    20551769        return QScriptValue();
     1770    QScript::APIShim shim(d->engine);
    20561771    JSC::JSValue callee = d->jscValue;
    20571772    JSC::ConstructData constructData;
     
    20831798
    20841799    JSC::JSValue savedException;
    2085     QScriptValuePrivate::saveException(exec, &savedException);
    2086     JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs);
     1800    QScriptEnginePrivate::saveException(exec, &savedException);
     1801    JSC::JSValue result;
     1802    JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, applyArgs);
    20871803    if (exec->hadException()) {
    2088         if (exec->exception().isObject())
    2089             result = JSC::asObject(exec->exception());
     1804        result = exec->exception();
    20901805    } else {
    2091         QScriptValuePrivate::restoreException(exec, savedException);
     1806        result = newObject;
     1807        QScriptEnginePrivate::restoreException(exec, savedException);
    20921808    }
    20931809    return d->engine->scriptValueFromJSCValue(result);
     
    22381954{
    22391955    Q_D(const QScriptValue);
    2240     if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
     1956    if (!d || !d->isJSC())
    22411957        return false;
    2242     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
    2243     QScriptObjectDelegate *delegate = object->delegate();
    2244     return (delegate && (delegate->type() == QScriptObjectDelegate::Variant));
     1958    return QScriptEnginePrivate::isVariant(d->jscValue);
    22451959}
    22461960
     
    22571971{
    22581972    Q_D(const QScriptValue);
    2259     if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
     1973    if (!d || !d->isJSC())
    22601974        return false;
    2261     QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
    2262     QScriptObjectDelegate *delegate = object->delegate();
    2263     return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject ||
    2264                          (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject &&
    2265                           static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject())));
     1975    return QScriptEnginePrivate::isQObject(d->jscValue);
    22661976}
    22671977
     
    22751985{
    22761986    Q_D(const QScriptValue);
    2277     if (!d || !d->isObject())
     1987    if (!d || !d->isJSC())
    22781988        return false;
    2279     return JSC::asObject(d->jscValue)->inherits(&QScript::QMetaObjectWrapperObject::info);
     1989    return QScriptEnginePrivate::isQMetaObject(d->jscValue);
    22801990}
    22811991
     
    23082018    } else {
    23092019        // ### make hidden property
    2310         return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal);
     2020        return property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal);
    23112021    }
    23122022}
     
    23192029  accessible to scripts, but may be retrieved in C++ using the data()
    23202030  function.
     2031
     2032  \sa QScriptEngine::reportAdditionalMemoryCost()
    23212033*/
    23222034void QScriptValue::setData(const QScriptValue &data)
     
    23252037    if (!d || !d->isObject())
    23262038        return;
     2039    QScript::APIShim shim(d->engine);
    23272040    JSC::JSValue other = d->engine->scriptValueToJSCValue(data);
    23282041    if (d->jscValue.inherits(&QScriptObject::info)) {
  • trunk/src/script/api/qscriptvalue.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/script/api/qscriptvalue_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    7070    inline bool isObject() const;
    7171
    72     QVariant &variantValue() const;
    73     void setVariantValue(const QVariant &value);
    74 
    7572    static inline QScriptValuePrivate *get(const QScriptValue &q)
    7673    {
     
    9087    }
    9188
    92     inline QScriptValue property(const JSC::Identifier &id, int resolveMode) const;
    93     QScriptValue propertyHelper(const JSC::Identifier &id, int resolveMode) const;
    94     inline QScriptValue property(quint32 index, int resolveMode) const;
    95     QScriptValue propertyHelper(quint32, int resolveMode) const;
    96     inline QScriptValue property(const QString &, int resolveMode) const;
    97     void setProperty(const JSC::Identifier &id, const QScriptValue &value,
    98                      const QScriptValue::PropertyFlags &flags);
    99     QScriptValue::PropertyFlags propertyFlags(
    100         const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const;
     89    inline JSC::JSValue property(const JSC::Identifier &id,
     90                                 const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
     91    inline JSC::JSValue property(quint32 index, const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
     92    inline JSC::JSValue property(const JSC::UString &, const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
     93    inline void setProperty(const JSC::UString &name, const JSC::JSValue &value,
     94                            const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
     95    inline void setProperty(const JSC::Identifier &id, const JSC::JSValue &value,
     96                            const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
     97    inline void setProperty(quint32 index, const JSC::JSValue &value,
     98                            const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
     99    inline QScriptValue::PropertyFlags propertyFlags(
     100        const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
    101101
    102102    void detachFromEngine();
     
    104104    qint64 objectId()
    105105    {
    106         if ( (type == JavaScriptCore) && (engine) )
     106        if ( (type == JavaScriptCore) && (engine) && jscValue.isCell() )
    107107            return (qint64)jscValue.asCell();
    108108        else
    109109            return -1;
    110110    }
    111 
    112     static inline void saveException(JSC::ExecState*, JSC::JSValue*);
    113     static inline void restoreException(JSC::ExecState*, JSC::JSValue);
    114111
    115112    QScriptEnginePrivate *engine;
  • trunk/src/script/api/qscriptvalueiterator.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    8585        : initialized(false)
    8686    {}
     87
     88    ~QScriptValueIteratorPrivate()
     89    {
     90        if (!initialized)
     91            return;
     92        QScriptEnginePrivate *eng_p = engine();
     93        if (!eng_p)
     94            return;
     95        QScript::APIShim shim(eng_p);
     96        propertyNames.clear(); //destroying the identifiers need to be done under the APIShim guard
     97    }
     98
     99    QScriptValuePrivate *object() const
     100    {
     101        return QScriptValuePrivate::get(objectValue);
     102    }
     103
     104    QScriptEnginePrivate *engine() const
     105    {
     106        return QScriptEnginePrivate::get(objectValue.engine());
     107    }
     108
    87109    void ensureInitialized()
    88110    {
    89111        if (initialized)
    90112            return;
    91         QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(object.engine());
     113        QScriptEnginePrivate *eng_p = engine();
     114        QScript::APIShim shim(eng_p);
    92115        JSC::ExecState *exec = eng_p->globalExec();
    93116        JSC::PropertyNameArray propertyNamesArray(exec);
    94         propertyNamesArray.setShouldCache(false);
    95         JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, /*includeNonEnumerable=*/true);
     117        JSC::asObject(object()->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, JSC::IncludeDontEnumProperties);
    96118
    97119        JSC::PropertyNameArray::const_iterator propertyNamesIt = propertyNamesArray.begin();
    98120        for(; propertyNamesIt != propertyNamesArray.end(); ++propertyNamesIt) {
    99             propertyNames.append(propertyNamesIt->ustring());
     121            propertyNames.append(*propertyNamesIt);
    100122        }
    101123        it = propertyNames.begin();
     
    103125    }
    104126
    105     QScriptValue object;
    106     QLinkedList<JSC::UString> propertyNames;
    107     QLinkedList<JSC::UString>::iterator it;
    108     QLinkedList<JSC::UString>::iterator current;
     127    QScriptValue objectValue;
     128    QLinkedList<JSC::Identifier> propertyNames;
     129    QLinkedList<JSC::Identifier>::iterator it;
     130    QLinkedList<JSC::Identifier>::iterator current;
    109131    bool initialized;
    110132};
     
    120142    if (object.isObject()) {
    121143        d_ptr.reset(new QScriptValueIteratorPrivate());
    122         d_ptr->object = object;
     144        d_ptr->objectValue = object;
    123145    }
    124146}
     
    241263{
    242264    Q_D(const QScriptValueIterator);
    243     if (!d || !d->initialized)
     265    if (!d || !d->initialized || !d->engine())
    244266        return QString();
    245     return *d->current;
     267    return d->current->ustring();
    246268}
    247269
     
    255277{
    256278    Q_D(const QScriptValueIterator);
    257     if (!d || !d->initialized)
     279    if (!d || !d->initialized || !d->engine())
    258280        return QScriptString();
    259     return d->object.engine()->toStringHandle(name());
     281    return d->engine()->toStringHandle(*d->current);
    260282}
    261283
     
    269291{
    270292    Q_D(const QScriptValueIterator);
    271     if (!d || !d->initialized)
     293    if (!d || !d->initialized || !d->engine())
    272294        return QScriptValue();
    273     return d->object.property(name());
     295    QScript::APIShim shim(d->engine());
     296    JSC::JSValue jsValue = d->object()->property(*d->current);
     297    return d->engine()->scriptValueFromJSCValue(jsValue);
    274298}
    275299
     
    283307{
    284308    Q_D(QScriptValueIterator);
    285     if (!d || !d->initialized)
    286         return;
    287     d->object.setProperty(name(), value);
     309    if (!d || !d->initialized || !d->engine())
     310        return;
     311    QScript::APIShim shim(d->engine());
     312    JSC::JSValue jsValue = d->engine()->scriptValueToJSCValue(value);
     313    d->object()->setProperty(*d->current, jsValue);
    288314}
    289315
     
    297323{
    298324    Q_D(const QScriptValueIterator);
    299     if (!d || !d->initialized)
     325    if (!d || !d->initialized || !d->engine())
    300326        return 0;
    301     return d->object.propertyFlags(name());
     327    QScript::APIShim shim(d->engine());
     328    return d->object()->propertyFlags(*d->current);
    302329}
    303330
     
    311338{
    312339    Q_D(QScriptValueIterator);
    313     if (!d || !d->initialized)
    314         return;
    315     d->object.setProperty(name(), QScriptValue());
     340    if (!d || !d->initialized || !d->engine())
     341        return;
     342    QScript::APIShim shim(d->engine());
     343    d->object()->setProperty(*d->current, JSC::JSValue());
    316344    d->propertyNames.erase(d->current);
    317345}
     
    327355    if (object.isObject()) {
    328356        d_ptr.reset(new QScriptValueIteratorPrivate());
    329         d_ptr->object = object;
     357        d_ptr->objectValue = object;
    330358    }
    331359    return *this;
  • trunk/src/script/api/qscriptvalueiterator.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
Note: See TracChangeset for help on using the changeset viewer.