62 #include "bridge/qscriptclassobject_p.h" |
62 #include "bridge/qscriptclassobject_p.h" |
63 #include "bridge/qscriptvariant_p.h" |
63 #include "bridge/qscriptvariant_p.h" |
64 #include "bridge/qscriptqobject_p.h" |
64 #include "bridge/qscriptqobject_p.h" |
65 #include "bridge/qscriptglobalobject_p.h" |
65 #include "bridge/qscriptglobalobject_p.h" |
66 #include "bridge/qscriptactivationobject_p.h" |
66 #include "bridge/qscriptactivationobject_p.h" |
|
67 #include "bridge/qscriptstaticscopeobject_p.h" |
67 |
68 |
68 #ifndef QT_NO_QOBJECT |
69 #ifndef QT_NO_QOBJECT |
69 #include <QtCore/qcoreapplication.h> |
70 #include <QtCore/qcoreapplication.h> |
70 #include <QtCore/qdir.h> |
71 #include <QtCore/qdir.h> |
71 #include <QtCore/qfile.h> |
72 #include <QtCore/qfile.h> |
434 { |
435 { |
435 return ((JSC::UString)value).toDouble(); |
436 return ((JSC::UString)value).toDouble(); |
436 } |
437 } |
437 |
438 |
438 #endif |
439 #endif |
|
440 |
|
441 static const qsreal MsPerSecond = 1000.0; |
|
442 |
|
443 static inline int MsFromTime(qsreal t) |
|
444 { |
|
445 int r = int(::fmod(t, MsPerSecond)); |
|
446 return (r >= 0) ? r : r + int(MsPerSecond); |
|
447 } |
|
448 |
|
449 /*! |
|
450 \internal |
|
451 Converts a JS date value (milliseconds) to a QDateTime (local time). |
|
452 */ |
|
453 QDateTime MsToDateTime(JSC::ExecState *exec, qsreal t) |
|
454 { |
|
455 if (qIsNaN(t)) |
|
456 return QDateTime(); |
|
457 JSC::GregorianDateTime tm; |
|
458 JSC::msToGregorianDateTime(exec, t, /*output UTC=*/true, tm); |
|
459 int ms = MsFromTime(t); |
|
460 QDateTime convertedUTC = QDateTime(QDate(tm.year + 1900, tm.month + 1, tm.monthDay), |
|
461 QTime(tm.hour, tm.minute, tm.second, ms), Qt::UTC); |
|
462 return convertedUTC.toLocalTime(); |
|
463 } |
|
464 |
|
465 /*! |
|
466 \internal |
|
467 Converts a QDateTime to a JS date value (milliseconds). |
|
468 */ |
|
469 qsreal DateTimeToMs(JSC::ExecState *exec, const QDateTime &dt) |
|
470 { |
|
471 if (!dt.isValid()) |
|
472 return qSNaN(); |
|
473 QDateTime utc = dt.toUTC(); |
|
474 QDate date = utc.date(); |
|
475 QTime time = utc.time(); |
|
476 JSC::GregorianDateTime tm; |
|
477 tm.year = date.year() - 1900; |
|
478 tm.month = date.month() - 1; |
|
479 tm.monthDay = date.day(); |
|
480 tm.weekDay = date.dayOfWeek(); |
|
481 tm.yearDay = date.dayOfYear(); |
|
482 tm.hour = time.hour(); |
|
483 tm.minute = time.minute(); |
|
484 tm.second = time.second(); |
|
485 return JSC::gregorianDateTimeToMS(exec, tm, time.msec(), /*inputIsUTC=*/true); |
|
486 } |
439 |
487 |
440 void GlobalClientData::mark(JSC::MarkStack& markStack) |
488 void GlobalClientData::mark(JSC::MarkStack& markStack) |
441 { |
489 { |
442 engine->mark(markStack); |
490 engine->mark(markStack); |
443 } |
491 } |
903 JSC::JSGlobalObject *globalObject = new (globalData)QScript::GlobalObject(); |
951 JSC::JSGlobalObject *globalObject = new (globalData)QScript::GlobalObject(); |
904 |
952 |
905 JSC::ExecState* exec = globalObject->globalExec(); |
953 JSC::ExecState* exec = globalObject->globalExec(); |
906 |
954 |
907 scriptObjectStructure = QScriptObject::createStructure(globalObject->objectPrototype()); |
955 scriptObjectStructure = QScriptObject::createStructure(globalObject->objectPrototype()); |
|
956 staticScopeObjectStructure = QScriptStaticScopeObject::createStructure(JSC::jsNull()); |
908 |
957 |
909 qobjectPrototype = new (exec) QScript::QObjectPrototype(exec, QScript::QObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); |
958 qobjectPrototype = new (exec) QScript::QObjectPrototype(exec, QScript::QObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); |
910 qobjectWrapperObjectStructure = QScriptObject::createStructure(qobjectPrototype); |
959 qobjectWrapperObjectStructure = QScriptObject::createStructure(qobjectPrototype); |
911 |
960 |
912 qmetaobjectPrototype = new (exec) QScript::QMetaObjectPrototype(exec, QScript::QMetaObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); |
961 qmetaobjectPrototype = new (exec) QScript::QMetaObjectPrototype(exec, QScript::QMetaObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); |
1009 for (int i = 0; i < lst.size(); ++i) |
1058 for (int i = 0; i < lst.size(); ++i) |
1010 setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i))); |
1059 setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i))); |
1011 return arr; |
1060 return arr; |
1012 } |
1061 } |
1013 |
1062 |
1014 QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr) |
1063 QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSArray *arr) |
1015 { |
1064 { |
|
1065 QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec); |
|
1066 if (eng->visitedConversionObjects.contains(arr)) |
|
1067 return QVariantList(); // Avoid recursion. |
|
1068 eng->visitedConversionObjects.insert(arr); |
1016 QVariantList lst; |
1069 QVariantList lst; |
1017 uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); |
1070 uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); |
1018 for (uint i = 0; i < len; ++i) |
1071 for (uint i = 0; i < len; ++i) |
1019 lst.append(toVariant(exec, property(exec, arr, i))); |
1072 lst.append(toVariant(exec, property(exec, arr, i))); |
|
1073 eng->visitedConversionObjects.remove(arr); |
1020 return lst; |
1074 return lst; |
1021 } |
1075 } |
1022 |
1076 |
1023 JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap) |
1077 JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap) |
1024 { |
1078 { |
1027 for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) |
1081 for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) |
1028 setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value())); |
1082 setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value())); |
1029 return obj; |
1083 return obj; |
1030 } |
1084 } |
1031 |
1085 |
1032 QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj) |
1086 QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSObject *obj) |
1033 { |
1087 { |
|
1088 QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec); |
|
1089 if (eng->visitedConversionObjects.contains(obj)) |
|
1090 return QVariantMap(); // Avoid recursion. |
|
1091 eng->visitedConversionObjects.insert(obj); |
1034 JSC::PropertyNameArray propertyNames(exec); |
1092 JSC::PropertyNameArray propertyNames(exec); |
1035 JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties); |
1093 obj->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties); |
1036 QVariantMap vmap; |
1094 QVariantMap vmap; |
1037 JSC::PropertyNameArray::const_iterator it = propertyNames.begin(); |
1095 JSC::PropertyNameArray::const_iterator it = propertyNames.begin(); |
1038 for( ; it != propertyNames.end(); ++it) |
1096 for( ; it != propertyNames.end(); ++it) |
1039 vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it))); |
1097 vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it))); |
|
1098 eng->visitedConversionObjects.remove(obj); |
1040 return vmap; |
1099 return vmap; |
1041 } |
1100 } |
1042 |
1101 |
1043 JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const |
1102 JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const |
1044 { |
1103 { |
1523 registeredScriptStrings = 0; |
1582 registeredScriptStrings = 0; |
1524 } |
1583 } |
1525 |
1584 |
1526 #ifndef QT_NO_REGEXP |
1585 #ifndef QT_NO_REGEXP |
1527 |
1586 |
1528 Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); |
1587 Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); |
1529 |
1588 |
1530 JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp ®exp) |
1589 JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp ®exp) |
1531 { |
1590 { |
1532 JSC::JSValue buf[2]; |
1591 JSC::JSValue buf[2]; |
1533 JSC::ArgList args(buf, sizeof(buf)); |
1592 JSC::ArgList args(buf, sizeof(buf)); |
1659 #ifndef QT_NO_REGEXP |
1718 #ifndef QT_NO_REGEXP |
1660 else if (isRegExp(value)) |
1719 else if (isRegExp(value)) |
1661 return QVariant(toRegExp(exec, value)); |
1720 return QVariant(toRegExp(exec, value)); |
1662 #endif |
1721 #endif |
1663 else if (isArray(value)) |
1722 else if (isArray(value)) |
1664 return variantListFromArray(exec, value); |
1723 return variantListFromArray(exec, JSC::asArray(value)); |
1665 else if (QScriptDeclarativeClass *dc = declarativeClass(value)) |
1724 else if (QScriptDeclarativeClass *dc = declarativeClass(value)) |
1666 return dc->toVariant(declarativeObject(value)); |
1725 return dc->toVariant(declarativeObject(value)); |
1667 // try to convert to primitive |
1726 return variantMapFromObject(exec, JSC::asObject(value)); |
1668 JSC::JSValue savedException; |
|
1669 saveException(exec, &savedException); |
|
1670 JSC::JSValue prim = value.toPrimitive(exec); |
|
1671 restoreException(exec, savedException); |
|
1672 if (!prim.isObject()) |
|
1673 return toVariant(exec, prim); |
|
1674 } else if (value.isNumber()) { |
1727 } else if (value.isNumber()) { |
1675 return QVariant(toNumber(exec, value)); |
1728 return QVariant(toNumber(exec, value)); |
1676 } else if (value.isString()) { |
1729 } else if (value.isString()) { |
1677 return QVariant(toString(exec, value)); |
1730 return QVariant(toString(exec, value)); |
1678 } else if (value.isBoolean()) { |
1731 } else if (value.isBoolean()) { |
1764 // ### check if it's a getter/setter property |
1817 // ### check if it's a getter/setter property |
1765 thisObject->deleteProperty(exec, id); |
1818 thisObject->deleteProperty(exec, id); |
1766 } else if (flags != QScriptValue::KeepExistingFlags) { |
1819 } else if (flags != QScriptValue::KeepExistingFlags) { |
1767 if (thisObject->hasOwnProperty(exec, id)) |
1820 if (thisObject->hasOwnProperty(exec, id)) |
1768 thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes? |
1821 thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes? |
1769 unsigned attribs = 0; |
1822 thisObject->putWithAttributes(exec, id, value, propertyFlagsToJSCAttributes(flags)); |
1770 if (flags & QScriptValue::ReadOnly) |
|
1771 attribs |= JSC::ReadOnly; |
|
1772 if (flags & QScriptValue::SkipInEnumeration) |
|
1773 attribs |= JSC::DontEnum; |
|
1774 if (flags & QScriptValue::Undeletable) |
|
1775 attribs |= JSC::DontDelete; |
|
1776 attribs |= flags & QScriptValue::UserRange; |
|
1777 thisObject->putWithAttributes(exec, id, value, attribs); |
|
1778 } else { |
1823 } else { |
1779 JSC::PutPropertySlot slot; |
1824 JSC::PutPropertySlot slot; |
1780 thisObject->put(exec, id, value, slot); |
1825 thisObject->put(exec, id, value, slot); |
1781 } |
1826 } |
1782 } |
1827 } |
3129 *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(exec, value); |
3172 *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(exec, value); |
3130 return true; |
3173 return true; |
3131 } break; |
3174 } break; |
3132 case QMetaType::QVariantList: |
3175 case QMetaType::QVariantList: |
3133 if (isArray(value)) { |
3176 if (isArray(value)) { |
3134 *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, value); |
3177 *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, JSC::asArray(value)); |
3135 return true; |
3178 return true; |
3136 } break; |
3179 } break; |
3137 case QMetaType::QVariantMap: |
3180 case QMetaType::QVariantMap: |
3138 if (isObject(value)) { |
3181 if (isObject(value)) { |
3139 *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, value); |
3182 *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, JSC::asObject(value)); |
3140 return true; |
3183 return true; |
3141 } break; |
3184 } break; |
3142 case QMetaType::QVariant: |
3185 case QMetaType::QVariant: |
3143 *reinterpret_cast<QVariant*>(ptr) = toVariant(exec, value); |
3186 *reinterpret_cast<QVariant*>(ptr) = toVariant(exec, value); |
3144 return true; |
3187 return true; |