diff -r b72c6db6890b -r 5dc02b23752f src/script/api/qscriptvalue.cpp --- a/src/script/api/qscriptvalue.cpp Wed Jun 23 19:07:03 2010 +0300 +++ b/src/script/api/qscriptvalue.cpp Tue Jul 06 15:10:48 2010 +0300 @@ -29,33 +29,19 @@ #include "qscriptengine_p.h" #include "qscriptstring_p.h" -#include "JSArray.h" #include "JSGlobalObject.h" #include "JSImmediate.h" #include "JSObject.h" #include "JSValue.h" #include "JSFunction.h" -#include "DateInstance.h" -#include "ErrorInstance.h" -#include "RegExpObject.h" #include "Identifier.h" #include "Operations.h" #include "Arguments.h" -#include -#include #include #include #include -#include "utils/qscriptdate_p.h" -#include "bridge/qscriptobject_p.h" -#include "bridge/qscriptclassobject_p.h" -#include "bridge/qscriptvariant_p.h" -#include "bridge/qscriptqobject_p.h" -#include "bridge/qscriptdeclarativeclass_p.h" -#include "bridge/qscriptdeclarativeobject_p.h" - /*! \since 4.3 \class QScriptValue @@ -180,248 +166,8 @@ \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. */ -// ### move - -#include -#include - QT_BEGIN_NAMESPACE -namespace QScript -{ - -static const qsreal D32 = 4294967296.0; - -qint32 ToInt32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D32); - const double D31 = D32 / 2.0; - - if (sign == -1 && n < -D31) - n += D32; - - else if (sign != -1 && n >= D31) - n -= D32; - - return qint32 (n); -} - -quint32 ToUint32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D32); - - if (n < 0) - n += D32; - - return quint32 (n); -} - -quint16 ToUint16(qsreal n) -{ - static const qsreal D16 = 65536.0; - - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D16); - - if (n < 0) - n += D16; - - return quint16 (n); -} - -qsreal ToInteger(qsreal n) -{ - if (qIsNaN(n)) - return 0; - - if (n == 0 || qIsInf(n)) - return n; - - int sign = n < 0 ? -1 : 1; - return sign * ::floor(::fabs(n)); -} - -} // namespace QScript - -QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const -{ - JSC::JSValue result; - if (!(resolveMode & QScriptValue::ResolvePrototype)) { - // Look in the object's own properties - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(object); - if (object->getOwnPropertySlot(exec, id, slot)) - result = slot.getValue(exec, id); - } - if (!result && (resolveMode & QScriptValue::ResolveScope)) { - // ### check if it's a function object and look in the scope chain - QScriptValue scope = property(QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal); - if (scope.isObject()) - result = engine->scriptValueToJSCValue(QScriptValuePrivate::get(scope)->property(id, resolveMode)); - } - return engine->scriptValueFromJSCValue(result); -} - -QScriptValue QScriptValuePrivate::propertyHelper(quint32 index, int resolveMode) const -{ - JSC::JSValue result; - if (!(resolveMode & QScriptValue::ResolvePrototype)) { - // Look in the object's own properties - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(object); - if (object->getOwnPropertySlot(exec, index, slot)) - result = slot.getValue(exec, index); - } - return engine->scriptValueFromJSCValue(result); -} - -void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptValue &value, - const QScriptValue::PropertyFlags &flags) -{ - QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); - if (valueEngine && (valueEngine != engine)) { - qWarning("QScriptValue::setProperty(%s) failed: " - "cannot set value created in a different engine", - qPrintable(QString(id.ustring()))); - return; - } - JSC::ExecState *exec = engine->currentFrame; - JSC::JSValue jsValue = engine->scriptValueToJSCValue(value); - JSC::JSObject *thisObject = JSC::asObject(jscValue); - JSC::JSValue setter = thisObject->lookupSetter(exec, id); - JSC::JSValue getter = thisObject->lookupGetter(exec, id); - if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { - if (!jsValue) { - // deleting getter/setter - if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { - // deleting both: just delete the property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - } else if (flags & QScriptValue::PropertyGetter) { - // preserve setter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - if (setter && setter.isObject()) - thisObject->defineSetter(exec, id, JSC::asObject(setter)); - } else { // flags & QScriptValue::PropertySetter - // preserve getter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - if (getter && getter.isObject()) - thisObject->defineGetter(exec, id, JSC::asObject(getter)); - } - } else { - if (jsValue.isObject()) { // ### should check if it has callData() - // defining getter/setter - if (id == exec->propertyNames().underscoreProto) { - qWarning("QScriptValue::setProperty() failed: " - "cannot set getter or setter of native property `__proto__'"); - } else { - if (flags & QScriptValue::PropertyGetter) - thisObject->defineGetter(exec, id, JSC::asObject(jsValue)); - if (flags & QScriptValue::PropertySetter) - thisObject->defineSetter(exec, id, JSC::asObject(jsValue)); - } - } else { - qWarning("QScriptValue::setProperty(): getter/setter must be a function"); - } - } - } else { - // setting the value - if (getter && getter.isObject() && !(setter && setter.isObject())) { - qWarning("QScriptValue::setProperty() failed: " - "property '%s' has a getter but no setter", - qPrintable(QString(id.ustring()))); - return; - } - if (!jsValue) { - // ### check if it's a getter/setter property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - } else if (flags != QScriptValue::KeepExistingFlags) { - if (thisObject->hasOwnProperty(exec, id)) - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes? - unsigned attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - attribs |= flags & QScriptValue::UserRange; - thisObject->putWithAttributes(exec, id, jsValue, attribs); - } else { - JSC::PutPropertySlot slot; - thisObject->put(exec, id, jsValue, slot); - } - } -} - -QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identifier &id, - const QScriptValue::ResolveFlags &mode) const -{ - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - unsigned attribs = 0; - JSC::PropertyDescriptor descriptor; - if (object->getOwnPropertyDescriptor(exec, id, descriptor)) - attribs = descriptor.attributes(); - else if (!object->getPropertyAttributes(exec, id, attribs)) { - if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { - QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype()); - return QScriptValuePrivate::get(proto)->propertyFlags(id, mode); - } - return 0; - } - QScriptValue::PropertyFlags result = 0; - if (attribs & JSC::ReadOnly) - result |= QScriptValue::ReadOnly; - if (attribs & JSC::DontEnum) - result |= QScriptValue::SkipInEnumeration; - if (attribs & JSC::DontDelete) - result |= QScriptValue::Undeletable; - //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?) - if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull()) - result |= QScriptValue::PropertyGetter; - if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull()) - result |= QScriptValue::PropertySetter; - if (attribs & QScript::QObjectMemberAttribute) - result |= QScriptValue::QObjectMember; - result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange); - return result; -} - -QVariant &QScriptValuePrivate::variantValue() const -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - return static_cast(delegate)->value(); -} - -void QScriptValuePrivate::setVariantValue(const QVariant &value) -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - static_cast(delegate)->setValue(value); -} - void QScriptValuePrivate::detachFromEngine() { if (isJSC()) @@ -707,9 +453,9 @@ bool QScriptValue::isError() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::ErrorInstance::info); + return QScriptEnginePrivate::isError(d->jscValue); } /*! @@ -721,9 +467,9 @@ bool QScriptValue::isArray() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::JSArray::info); + return QScriptEnginePrivate::isArray(d->jscValue); } /*! @@ -735,9 +481,9 @@ bool QScriptValue::isDate() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::DateInstance::info); + return QScriptEnginePrivate::isDate(d->jscValue); } /*! @@ -749,9 +495,9 @@ bool QScriptValue::isRegExp() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::RegExpObject::info); + return QScriptEnginePrivate::isRegExp(d->jscValue); } /*! @@ -824,8 +570,10 @@ Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); // ### make hidden property - return d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); + JSC::JSValue result = d->property("__qt_scope__", QScriptValue::ResolveLocal); + return d->engine->scriptValueFromJSCValue(result); } /*! @@ -912,16 +660,17 @@ return Object; } -QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference) +static QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference) { Q_ASSERT(object.isObject()); QScriptValuePrivate *pp = QScriptValuePrivate::get(object); Q_ASSERT(pp->engine != 0); + QScript::APIShim shim(pp->engine); JSC::ExecState *exec = pp->engine->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return pp->engine->scriptValueFromJSCValue(result); } @@ -1110,11 +859,12 @@ if (!eng_p) eng_p = other.d_ptr->engine; if (eng_p) { + QScript::APIShim shim(eng_p); JSC::ExecState *exec = eng_p->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } } @@ -1160,18 +910,21 @@ if (d->type == QScriptValuePrivate::JavaScriptCore) { QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; if (eng_p) - return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other)); + return JSC::JSValue::strictEqual(eng_p->currentFrame, d->jscValue, eng_p->scriptValueToJSCValue(other)); } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) { QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine; if (eng_p) - return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + return JSC::JSValue::strictEqual(eng_p->currentFrame, eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); } return false; } switch (d->type) { - case QScriptValuePrivate::JavaScriptCore: - return JSC::JSValue::strictEqual(d->jscValue, other.d_ptr->jscValue); + case QScriptValuePrivate::JavaScriptCore: { + QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; + JSC::ExecState *exec = eng_p ? eng_p->currentFrame : 0; + return JSC::JSValue::strictEqual(exec, d->jscValue, other.d_ptr->jscValue); + } case QScriptValuePrivate::Number: return (d->numberValue == other.d_ptr->numberValue); case QScriptValuePrivate::String: @@ -1199,22 +952,14 @@ return QString(); switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - JSC::UString str = d->jscValue.toString(exec); - if (exec && exec->hadException() && !str.size()) { - JSC::JSValue savedException2; - QScriptValuePrivate::saveException(exec, &savedException2); - str = savedException2.toString(exec); - QScriptValuePrivate::restoreException(exec, savedException2); - } - if (savedException) - QScriptValuePrivate::restoreException(exec, savedException); - return str; - } + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toString(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toString(0, d->jscValue); + } } case QScriptValuePrivate::Number: - return JSC::UString::from(d->numberValue); + return QScript::ToString(d->numberValue); case QScriptValuePrivate::String: return d->stringValue; } @@ -1240,17 +985,17 @@ return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toNumber(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toNumber(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toNumber(0, d->jscValue); + } } case QScriptValuePrivate::Number: return d->numberValue; case QScriptValuePrivate::String: - return ((JSC::UString)d->stringValue).toDouble(); + return QScript::ToNumber(d->stringValue); } return 0; } @@ -1267,17 +1012,17 @@ return false; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toBool(0, d->jscValue); + } } case QScriptValuePrivate::Number: - return (d->numberValue != 0) && !qIsNaN(d->numberValue); + return QScript::ToBool(d->numberValue); case QScriptValuePrivate::String: - return (!d->stringValue.isEmpty()); + return QScript::ToBool(d->stringValue); } return false; } @@ -1303,17 +1048,17 @@ return false; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toBool(0, d->jscValue); + } } case QScriptValuePrivate::Number: - return (d->numberValue != 0) && !qIsNaN(d->numberValue); + return QScript::ToBool(d->numberValue); case QScriptValuePrivate::String: - return (!d->stringValue.isEmpty()); + return QScript::ToBool(d->stringValue); } return false; } @@ -1337,17 +1082,17 @@ return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - qint32 result = d->jscValue.toInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toInt32(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toInt32(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToInt32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToInt32(d->stringValue); } return 0; } @@ -1371,17 +1116,17 @@ return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - quint32 result = d->jscValue.toUInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toUInt32(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toUInt32(0, d->jscValue); + } } case QScriptValuePrivate::Number: - return QScript::ToUint32(d->numberValue); + return QScript::ToUInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUint32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt32(d->stringValue); } return 0; } @@ -1405,13 +1150,17 @@ return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - // ### no equivalent function in JSC - return QScript::ToUint16(toNumber()); + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toUInt16(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toUInt16(0, d->jscValue); + } } case QScriptValuePrivate::Number: - return QScript::ToUint16(d->numberValue); + return QScript::ToUInt16(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUint16(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt16(d->stringValue); } return 0; } @@ -1435,17 +1184,17 @@ return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toInteger(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toInteger(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toInteger(0, d->jscValue); + } } case QScriptValuePrivate::Number: return QScript::ToInteger(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToInteger(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToInteger(d->stringValue); } return 0; } @@ -1478,40 +1227,14 @@ if (!d) return QVariant(); switch (d->type) { - case QScriptValuePrivate::JavaScriptCore: - if (isObject()) { - if (isVariant()) - return d->variantValue(); -#ifndef QT_NO_QOBJECT - else if (isQObject()) - return qVariantFromValue(toQObject()); -#endif - else if (isDate()) - return QVariant(toDateTime()); -#ifndef QT_NO_REGEXP - else if (isRegExp()) - return QVariant(toRegExp()); -#endif - else if (isArray()) - return QScriptEnginePrivate::variantListFromArray(*this); - else if (QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(*this)) - return dc->toVariant(QScriptDeclarativeClass::object(*this)); - // try to convert to primitive - JSC::ExecState *exec = d->engine->currentFrame; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - JSC::JSValue prim = d->jscValue.toPrimitive(exec); - QScriptValuePrivate::restoreException(exec, savedException); - if (!prim.isObject()) - return d->engine->scriptValueFromJSCValue(prim).toVariant(); - } else if (isNumber()) { - return QVariant(toNumber()); - } else if (isString()) { - return QVariant(toString()); - } else if (isBool()) { - return QVariant(toBool()); + case QScriptValuePrivate::JavaScriptCore: { + if (d->engine) { + QScript::APIShim shim(d->engine); + return QScriptEnginePrivate::toVariant(d->engine->currentFrame, d->jscValue); + } else { + return QScriptEnginePrivate::toVariant(0, d->jscValue); } - return QVariant(); + } case QScriptValuePrivate::Number: return QVariant(d->numberValue); case QScriptValuePrivate::String: @@ -1543,10 +1266,9 @@ QDateTime QScriptValue::toDateTime() const { Q_D(const QScriptValue); - if (!isDate()) + if (!d || !d->engine) return QDateTime(); - qsreal t = static_cast(JSC::asObject(d->jscValue))->internalNumber(); - return QScript::ToDateTime(t, Qt::LocalTime); + return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue); } #ifndef QT_NO_REGEXP @@ -1560,13 +1282,9 @@ QRegExp QScriptValue::toRegExp() const { Q_D(const QScriptValue); - if (!isRegExp()) - return QRegExp(); - QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); - Qt::CaseSensitivity kase = Qt::CaseSensitive; - if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) - kase = Qt::CaseInsensitive; - return QRegExp(pattern, kase, QRegExp::RegExp2); + if (!d || !d->engine) + return QRegExp(); + return QScriptEnginePrivate::toRegExp(d->engine->currentFrame, d->jscValue); } #endif // QT_NO_REGEXP @@ -1583,19 +1301,9 @@ QObject *QScriptValue::toQObject() const { Q_D(const QScriptValue); - if (isQObject()) { - QScriptObject *object = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) - return static_cast(delegate)->scriptClass()->toQObject(QScriptDeclarativeClass::object(*this)); - return static_cast(delegate)->value(); - } else if (isVariant()) { - QVariant var = toVariant(); - int type = var.userType(); - if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) - return *reinterpret_cast(var.constData()); - } - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1607,9 +1315,9 @@ const QMetaObject *QScriptValue::toQMetaObject() const { Q_D(const QScriptValue); - if (isQMetaObject()) - return static_cast(JSC::asObject(d->jscValue))->value(); - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1643,8 +1351,16 @@ Q_D(QScriptValue); if (!d || !d->isObject()) return; - JSC::ExecState *exec = d->engine->currentFrame; - d->setProperty(JSC::Identifier(exec, name), value, flags); + QScript::APIShim shim(d->engine); + QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); + if (valueEngine && (valueEngine != d->engine)) { + qWarning("QScriptValue::setProperty(%s) failed: " + "cannot set value created in a different engine", + qPrintable(name)); + return; + } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(name, jsValue, flags); } /*! @@ -1668,7 +1384,8 @@ Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); - return d->property(name, mode); + QScript::APIShim shim(d->engine); + return d->engine->scriptValueFromJSCValue(d->property(name, mode)); } /*! @@ -1690,7 +1407,7 @@ Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); - return d->property(arrayIndex, mode); + return d->engine->scriptValueFromJSCValue(d->property(arrayIndex, mode)); } /*! @@ -1717,33 +1434,8 @@ "cannot set value created in a different engine"); return; } - JSC::ExecState *exec = d->engine->currentFrame; - JSC::JSValue jscValue = d->engine->scriptValueToJSCValue(value); - if (!jscValue) { - JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex, /*checkDontDelete=*/false); - } else { - if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { - // fall back to string-based setProperty(), since there is no - // JSC::JSObject::defineGetter(unsigned) - d->setProperty(JSC::Identifier::from(exec, arrayIndex), value, flags); - } else { - if (flags != QScriptValue::KeepExistingFlags) { -// if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex)) -// JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex); - unsigned attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - attribs |= flags & QScriptValue::UserRange; - JSC::asObject(d->jscValue)->putWithAttributes(exec, arrayIndex, jscValue, attribs); - } else { - JSC::asObject(d->jscValue)->put(exec, arrayIndex, jscValue); - } - } - } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(arrayIndex, jsValue, flags); } /*! @@ -1764,7 +1456,8 @@ Q_D(const QScriptValue); if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return QScriptValue(); - return d->property(name.d_ptr->identifier, mode); + QScript::APIShim shim(d->engine); + return d->engine->scriptValueFromJSCValue(d->property(name.d_ptr->identifier, mode)); } /*! @@ -1787,7 +1480,16 @@ Q_D(QScriptValue); if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return; - d->setProperty(name.d_ptr->identifier, value, flags); + QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); + if (valueEngine && (valueEngine != d->engine)) { + qWarning("QScriptValue::setProperty(%s) failed: " + "cannot set value created in a different engine", + qPrintable(name.toString())); + return; + } + QScript::APIShim shim(d->engine); + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(name.d_ptr->identifier, jsValue, flags); } /*! @@ -1802,6 +1504,7 @@ Q_D(const QScriptValue); if (!d || !d->isObject()) return 0; + QScript::APIShim shim(d->engine); JSC::ExecState *exec = d->engine->currentFrame; return d->propertyFlags(JSC::Identifier(exec, name), mode); @@ -1851,8 +1554,9 @@ const QScriptValueList &args) { Q_D(const QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::CallData callData; JSC::CallType callType = callee.getCallData(callData); @@ -1891,12 +1595,12 @@ JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs); if (exec->hadException()) { result = exec->exception(); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -1928,8 +1632,9 @@ const QScriptValue &arguments) { Q_D(QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::CallData callData; JSC::CallType callType = callee.getCallData(callData); @@ -1971,12 +1676,12 @@ } JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs); if (exec->hadException()) { result = exec->exception(); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2002,8 +1707,9 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args) { Q_D(const QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::ConstructData constructData; JSC::ConstructType constructType = callee.getConstructData(constructData); @@ -2023,12 +1729,12 @@ JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs); if (exec->hadException()) { result = JSC::asObject(exec->exception()); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2051,8 +1757,9 @@ QScriptValue QScriptValue::construct(const QScriptValue &arguments) { Q_D(QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::ConstructData constructData; JSC::ConstructType constructType = callee.getConstructData(constructData); @@ -2082,13 +1789,13 @@ } JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs); if (exec->hadException()) { if (exec->exception().isObject()) result = JSC::asObject(exec->exception()); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2237,11 +1944,9 @@ bool QScriptValue::isVariant() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return false; - QScriptObject *object = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return QScriptEnginePrivate::isVariant(d->jscValue); } /*! @@ -2256,13 +1961,9 @@ bool QScriptValue::isQObject() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return false; - QScriptObject *object = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || - (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && - static_cast(delegate)->scriptClass()->isQObject()))); + return QScriptEnginePrivate::isQObject(d->jscValue); } /*! @@ -2274,9 +1975,9 @@ bool QScriptValue::isQMetaObject() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return JSC::asObject(d->jscValue)->inherits(&QScript::QMetaObjectWrapperObject::info); + return QScriptEnginePrivate::isQMetaObject(d->jscValue); } /*! @@ -2307,7 +2008,7 @@ return d->engine->scriptValueFromJSCValue(scriptObject->data()); } else { // ### make hidden property - return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); + return property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); } } @@ -2318,6 +2019,8 @@ this function to set object-specific data that won't be directly accessible to scripts, but may be retrieved in C++ using the data() function. + + \sa QScriptEngine::reportAdditionalMemoryCost() */ void QScriptValue::setData(const QScriptValue &data) {