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:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • 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)) {
Note: See TracChangeset for help on using the changeset viewer.