852 freeScriptValues = p->next; |
962 freeScriptValues = p->next; |
853 qFree(p); |
963 qFree(p); |
854 } |
964 } |
855 } |
965 } |
856 |
966 |
857 QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v) |
967 QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType) |
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) |
|
866 { |
968 { |
867 QVariant v(targetType, (void *)0); |
969 QVariant v(targetType, (void *)0); |
868 if (QScriptEnginePrivate::convert(value, targetType, v.data(), this)) |
970 if (convertValue(exec, value, targetType, v.data())) |
869 return v; |
971 return v; |
870 if (uint(targetType) == QVariant::LastType) |
972 if (uint(targetType) == QVariant::LastType) |
871 return value.toVariant(); |
973 return toVariant(exec, value); |
872 if (value.isVariant()) { |
974 if (isVariant(value)) { |
873 v = value.toVariant(); |
975 v = variantValue(value); |
874 if (v.canConvert(QVariant::Type(targetType))) { |
976 if (v.canConvert(QVariant::Type(targetType))) { |
875 v.convert(QVariant::Type(targetType)); |
977 v.convert(QVariant::Type(targetType)); |
876 return v; |
978 return v; |
877 } |
979 } |
878 QByteArray typeName = v.typeName(); |
980 QByteArray typeName = v.typeName(); |
879 if (typeName.endsWith('*') |
981 if (typeName.endsWith('*') |
880 && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) { |
982 && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) { |
881 return QVariant(targetType, *reinterpret_cast<void* *>(v.data())); |
983 return QVariant(targetType, *reinterpret_cast<void* *>(v.data())); |
882 } |
984 } |
883 } |
985 } |
884 |
|
885 return QVariant(); |
986 return QVariant(); |
886 } |
987 } |
887 |
988 |
888 JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(const QVariant &v) |
989 JSC::JSValue QScriptEnginePrivate::arrayFromStringList(JSC::ExecState *exec, const QStringList &lst) |
889 { |
990 { |
890 // ### it's inefficient to convert to QScriptValue and then to JSValue |
991 JSC::JSValue arr = newArray(exec, lst.size()); |
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()); |
|
916 for (int i = 0; i < lst.size(); ++i) |
992 for (int i = 0; i < lst.size(); ++i) |
917 arr.setProperty(i, QScriptValue(q, lst.at(i))); |
993 setProperty(exec, arr, i, JSC::jsString(exec, lst.at(i))); |
918 return arr; |
994 return arr; |
919 } |
995 } |
920 |
996 |
921 QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValue &arr) |
997 QStringList QScriptEnginePrivate::stringListFromArray(JSC::ExecState *exec, JSC::JSValue arr) |
922 { |
998 { |
923 QStringList lst; |
999 QStringList lst; |
924 uint len = arr.property(QLatin1String("length")).toUInt32(); |
1000 uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); |
925 for (uint i = 0; i < len; ++i) |
1001 for (uint i = 0; i < len; ++i) |
926 lst.append(arr.property(i).toString()); |
1002 lst.append(toString(exec, property(exec, arr, i))); |
927 return lst; |
1003 return lst; |
928 } |
1004 } |
929 |
1005 |
930 QScriptValue QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst) |
1006 JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, const QVariantList &lst) |
931 { |
1007 { |
932 Q_Q(QScriptEngine); |
1008 JSC::JSValue arr = newArray(exec, lst.size()); |
933 QScriptValue arr = q->newArray(lst.size()); |
|
934 for (int i = 0; i < lst.size(); ++i) |
1009 for (int i = 0; i < lst.size(); ++i) |
935 arr.setProperty(i, scriptValueFromVariant(lst.at(i))); |
1010 setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i))); |
936 return arr; |
1011 return arr; |
937 } |
1012 } |
938 |
1013 |
939 QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValue &arr) |
1014 QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr) |
940 { |
1015 { |
941 QVariantList lst; |
1016 QVariantList lst; |
942 uint len = arr.property(QLatin1String("length")).toUInt32(); |
1017 uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); |
943 for (uint i = 0; i < len; ++i) |
1018 for (uint i = 0; i < len; ++i) |
944 lst.append(arr.property(i).toVariant()); |
1019 lst.append(toVariant(exec, property(exec, arr, i))); |
945 return lst; |
1020 return lst; |
946 } |
1021 } |
947 |
1022 |
948 QScriptValue QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap) |
1023 JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap) |
949 { |
1024 { |
950 Q_Q(QScriptEngine); |
1025 JSC::JSValue obj = JSC::constructEmptyObject(exec); |
951 QScriptValue obj = q->newObject(); |
|
952 QVariantMap::const_iterator it; |
1026 QVariantMap::const_iterator it; |
953 for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) |
1027 for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) |
954 obj.setProperty(it.key(), scriptValueFromVariant(it.value())); |
1028 setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value())); |
955 return obj; |
1029 return obj; |
956 } |
1030 } |
957 |
1031 |
958 QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValue &obj) |
1032 QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj) |
959 { |
1033 { |
|
1034 JSC::PropertyNameArray propertyNames(exec); |
|
1035 JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties); |
960 QVariantMap vmap; |
1036 QVariantMap vmap; |
961 QScriptValueIterator it(obj); |
1037 JSC::PropertyNameArray::const_iterator it = propertyNames.begin(); |
962 while (it.hasNext()) { |
1038 for( ; it != propertyNames.end(); ++it) |
963 it.next(); |
1039 vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it))); |
964 vmap.insert(it.name(), it.value().toVariant()); |
|
965 } |
|
966 return vmap; |
1040 return vmap; |
967 } |
1041 } |
968 |
1042 |
969 JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const |
1043 JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const |
970 { |
1044 { |
1660 if (regexp.caseSensitivity() == Qt::CaseInsensitive) |
1574 if (regexp.caseSensitivity() == Qt::CaseInsensitive) |
1661 flags.append(QLatin1Char('i')); |
1575 flags.append(QLatin1Char('i')); |
1662 JSC::UString jscFlags = flags; |
1576 JSC::UString jscFlags = flags; |
1663 buf[0] = JSC::jsString(exec, jscPattern); |
1577 buf[0] = JSC::jsString(exec, jscPattern); |
1664 buf[1] = JSC::jsString(exec, jscFlags); |
1578 buf[1] = JSC::jsString(exec, jscFlags); |
1665 JSC::JSObject* result = JSC::constructRegExp(exec, args); |
1579 return JSC::constructRegExp(exec, args); |
1666 return d->scriptValueFromJSCValue(result); |
1580 } |
1667 } |
1581 |
1668 |
1582 #endif |
1669 #endif // QT_NO_REGEXP |
1583 |
1670 |
1584 JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QString &pattern, const QString &flags) |
1671 /*! |
1585 { |
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; |
|
1971 JSC::JSValue buf[2]; |
1586 JSC::JSValue buf[2]; |
1972 JSC::ArgList args(buf, sizeof(buf)); |
1587 JSC::ArgList args(buf, sizeof(buf)); |
1973 JSC::UString jscPattern = pattern; |
1588 JSC::UString jscPattern = pattern; |
1974 QString strippedFlags; |
1589 QString strippedFlags; |
1975 if (flags.contains(QLatin1Char('i'))) |
1590 if (flags.contains(QLatin1Char('i'))) |
1979 if (flags.contains(QLatin1Char('g'))) |
1594 if (flags.contains(QLatin1Char('g'))) |
1980 strippedFlags += QLatin1Char('g'); |
1595 strippedFlags += QLatin1Char('g'); |
1981 JSC::UString jscFlags = strippedFlags; |
1596 JSC::UString jscFlags = strippedFlags; |
1982 buf[0] = JSC::jsString(exec, jscPattern); |
1597 buf[0] = JSC::jsString(exec, jscPattern); |
1983 buf[1] = JSC::jsString(exec, jscFlags); |
1598 buf[1] = JSC::jsString(exec, jscFlags); |
1984 JSC::JSObject* result = JSC::constructRegExp(exec, args); |
1599 return JSC::constructRegExp(exec, args); |
1985 return d->scriptValueFromJSCValue(result); |
1600 } |
|
1601 |
|
1602 JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value) |
|
1603 { |
|
1604 QScriptObject *obj = new (currentFrame) QScriptObject(variantWrapperObjectStructure); |
|
1605 obj->setDelegate(new QScript::QVariantDelegate(value)); |
|
1606 JSC::JSValue proto = defaultPrototype(value.userType()); |
|
1607 if (proto) |
|
1608 obj->setPrototype(proto); |
|
1609 return obj; |
|
1610 } |
|
1611 |
|
1612 JSC::JSValue QScriptEnginePrivate::newVariant(JSC::JSValue objectValue, |
|
1613 const QVariant &value) |
|
1614 { |
|
1615 if (!isObject(objectValue)) |
|
1616 return newVariant(value); |
|
1617 JSC::JSObject *jscObject = JSC::asObject(objectValue); |
|
1618 if (!jscObject->inherits(&QScriptObject::info)) { |
|
1619 qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported"); |
|
1620 return JSC::JSValue(); |
|
1621 } |
|
1622 QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject); |
|
1623 if (!isVariant(objectValue)) { |
|
1624 jscScriptObject->setDelegate(new QScript::QVariantDelegate(value)); |
|
1625 } else { |
|
1626 setVariantValue(objectValue, value); |
|
1627 } |
|
1628 return objectValue; |
|
1629 } |
|
1630 |
|
1631 #ifndef QT_NO_REGEXP |
|
1632 |
|
1633 QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value) |
|
1634 { |
|
1635 if (!isRegExp(value)) |
|
1636 return QRegExp(); |
|
1637 QString pattern = toString(exec, property(exec, value, "source", QScriptValue::ResolvePrototype)); |
|
1638 Qt::CaseSensitivity kase = Qt::CaseSensitive; |
|
1639 if (toBool(exec, property(exec, value, "ignoreCase", QScriptValue::ResolvePrototype))) |
|
1640 kase = Qt::CaseInsensitive; |
|
1641 return QRegExp(pattern, kase, QRegExp::RegExp2); |
|
1642 } |
|
1643 |
|
1644 #endif |
|
1645 |
|
1646 QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue value) |
|
1647 { |
|
1648 if (!value) { |
|
1649 return QVariant(); |
|
1650 } else if (isObject(value)) { |
|
1651 if (isVariant(value)) |
|
1652 return variantValue(value); |
|
1653 #ifndef QT_NO_QOBJECT |
|
1654 else if (isQObject(value)) |
|
1655 return qVariantFromValue(toQObject(exec, value)); |
|
1656 #endif |
|
1657 else if (isDate(value)) |
|
1658 return QVariant(toDateTime(exec, value)); |
|
1659 #ifndef QT_NO_REGEXP |
|
1660 else if (isRegExp(value)) |
|
1661 return QVariant(toRegExp(exec, value)); |
|
1662 #endif |
|
1663 else if (isArray(value)) |
|
1664 return variantListFromArray(exec, value); |
|
1665 else if (QScriptDeclarativeClass *dc = declarativeClass(value)) |
|
1666 return dc->toVariant(declarativeObject(value)); |
|
1667 // try to convert to primitive |
|
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()) { |
|
1675 return QVariant(toNumber(exec, value)); |
|
1676 } else if (value.isString()) { |
|
1677 return QVariant(toString(exec, value)); |
|
1678 } else if (value.isBoolean()) { |
|
1679 return QVariant(toBool(exec, value)); |
|
1680 } |
|
1681 return QVariant(); |
|
1682 } |
|
1683 |
|
1684 JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode) |
|
1685 { |
|
1686 JSC::JSValue result; |
|
1687 if (!(resolveMode & QScriptValue::ResolvePrototype)) { |
|
1688 // Look in the object's own properties |
|
1689 JSC::JSObject *object = JSC::asObject(value); |
|
1690 JSC::PropertySlot slot(object); |
|
1691 if (object->getOwnPropertySlot(exec, id, slot)) |
|
1692 result = slot.getValue(exec, id); |
|
1693 } |
|
1694 if (!result && (resolveMode & QScriptValue::ResolveScope)) { |
|
1695 // ### check if it's a function object and look in the scope chain |
|
1696 JSC::JSValue scope = property(exec, value, "__qt_scope__", QScriptValue::ResolveLocal); |
|
1697 if (isObject(scope)) |
|
1698 result = property(exec, scope, id, resolveMode); |
|
1699 } |
|
1700 return result; |
|
1701 } |
|
1702 |
|
1703 JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode) |
|
1704 { |
|
1705 JSC::JSValue result; |
|
1706 if (!(resolveMode & QScriptValue::ResolvePrototype)) { |
|
1707 // Look in the object's own properties |
|
1708 JSC::JSObject *object = JSC::asObject(value); |
|
1709 JSC::PropertySlot slot(object); |
|
1710 if (object->getOwnPropertySlot(exec, index, slot)) |
|
1711 result = slot.getValue(exec, index); |
|
1712 } |
|
1713 return result; |
|
1714 } |
|
1715 |
|
1716 void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::Identifier &id, |
|
1717 JSC::JSValue value, const QScriptValue::PropertyFlags &flags) |
|
1718 { |
|
1719 JSC::JSObject *thisObject = JSC::asObject(objectValue); |
|
1720 JSC::JSValue setter = thisObject->lookupSetter(exec, id); |
|
1721 JSC::JSValue getter = thisObject->lookupGetter(exec, id); |
|
1722 if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { |
|
1723 if (!value) { |
|
1724 // deleting getter/setter |
|
1725 if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { |
|
1726 // deleting both: just delete the property |
|
1727 thisObject->deleteProperty(exec, id); |
|
1728 } else if (flags & QScriptValue::PropertyGetter) { |
|
1729 // preserve setter, if there is one |
|
1730 thisObject->deleteProperty(exec, id); |
|
1731 if (setter && setter.isObject()) |
|
1732 thisObject->defineSetter(exec, id, JSC::asObject(setter)); |
|
1733 } else { // flags & QScriptValue::PropertySetter |
|
1734 // preserve getter, if there is one |
|
1735 thisObject->deleteProperty(exec, id); |
|
1736 if (getter && getter.isObject()) |
|
1737 thisObject->defineGetter(exec, id, JSC::asObject(getter)); |
|
1738 } |
|
1739 } else { |
|
1740 if (value.isObject()) { // ### should check if it has callData() |
|
1741 // defining getter/setter |
|
1742 if (id == exec->propertyNames().underscoreProto) { |
|
1743 qWarning("QScriptValue::setProperty() failed: " |
|
1744 "cannot set getter or setter of native property `__proto__'"); |
|
1745 } else { |
|
1746 if (flags & QScriptValue::PropertyGetter) |
|
1747 thisObject->defineGetter(exec, id, JSC::asObject(value)); |
|
1748 if (flags & QScriptValue::PropertySetter) |
|
1749 thisObject->defineSetter(exec, id, JSC::asObject(value)); |
|
1750 } |
|
1751 } else { |
|
1752 qWarning("QScriptValue::setProperty(): getter/setter must be a function"); |
|
1753 } |
|
1754 } |
|
1755 } else { |
|
1756 // setting the value |
|
1757 if (getter && getter.isObject() && !(setter && setter.isObject())) { |
|
1758 qWarning("QScriptValue::setProperty() failed: " |
|
1759 "property '%s' has a getter but no setter", |
|
1760 qPrintable(QString(id.ustring()))); |
|
1761 return; |
|
1762 } |
|
1763 if (!value) { |
|
1764 // ### check if it's a getter/setter property |
|
1765 thisObject->deleteProperty(exec, id); |
|
1766 } else if (flags != QScriptValue::KeepExistingFlags) { |
|
1767 if (thisObject->hasOwnProperty(exec, id)) |
|
1768 thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes? |
|
1769 unsigned attribs = 0; |
|
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 { |
|
1779 JSC::PutPropertySlot slot; |
|
1780 thisObject->put(exec, id, value, slot); |
|
1781 } |
|
1782 } |
|
1783 } |
|
1784 |
|
1785 void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, quint32 index, |
|
1786 JSC::JSValue value, const QScriptValue::PropertyFlags &flags) |
|
1787 { |
|
1788 if (!value) { |
|
1789 JSC::asObject(objectValue)->deleteProperty(exec, index); |
|
1790 } else { |
|
1791 if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { |
|
1792 // fall back to string-based setProperty(), since there is no |
|
1793 // JSC::JSObject::defineGetter(unsigned) |
|
1794 setProperty(exec, objectValue, JSC::Identifier::from(exec, index), value, flags); |
|
1795 } else { |
|
1796 if (flags != QScriptValue::KeepExistingFlags) { |
|
1797 // if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex)) |
|
1798 // JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex); |
|
1799 unsigned attribs = 0; |
|
1800 if (flags & QScriptValue::ReadOnly) |
|
1801 attribs |= JSC::ReadOnly; |
|
1802 if (flags & QScriptValue::SkipInEnumeration) |
|
1803 attribs |= JSC::DontEnum; |
|
1804 if (flags & QScriptValue::Undeletable) |
|
1805 attribs |= JSC::DontDelete; |
|
1806 attribs |= flags & QScriptValue::UserRange; |
|
1807 JSC::asObject(objectValue)->putWithAttributes(exec, index, value, attribs); |
|
1808 } else { |
|
1809 JSC::asObject(objectValue)->put(exec, index, value); |
|
1810 } |
|
1811 } |
|
1812 } |
|
1813 } |
|
1814 |
|
1815 QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, |
|
1816 const QScriptValue::ResolveFlags &mode) |
|
1817 { |
|
1818 JSC::JSObject *object = JSC::asObject(value); |
|
1819 unsigned attribs = 0; |
|
1820 JSC::PropertyDescriptor descriptor; |
|
1821 if (object->getOwnPropertyDescriptor(exec, id, descriptor)) |
|
1822 attribs = descriptor.attributes(); |
|
1823 else { |
|
1824 if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { |
|
1825 JSC::JSValue proto = object->prototype(); |
|
1826 return propertyFlags(exec, proto, id, mode); |
|
1827 } |
|
1828 return 0; |
|
1829 } |
|
1830 QScriptValue::PropertyFlags result = 0; |
|
1831 if (attribs & JSC::ReadOnly) |
|
1832 result |= QScriptValue::ReadOnly; |
|
1833 if (attribs & JSC::DontEnum) |
|
1834 result |= QScriptValue::SkipInEnumeration; |
|
1835 if (attribs & JSC::DontDelete) |
|
1836 result |= QScriptValue::Undeletable; |
|
1837 //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?) |
|
1838 if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull()) |
|
1839 result |= QScriptValue::PropertyGetter; |
|
1840 if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull()) |
|
1841 result |= QScriptValue::PropertySetter; |
|
1842 #ifndef QT_NO_QOBJECT |
|
1843 if (attribs & QScript::QObjectMemberAttribute) |
|
1844 result |= QScriptValue::QObjectMember; |
|
1845 #endif |
|
1846 result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange); |
|
1847 return result; |
|
1848 } |
|
1849 |
|
1850 QScriptString QScriptEnginePrivate::toStringHandle(const JSC::Identifier &name) |
|
1851 { |
|
1852 QScriptString result; |
|
1853 QScriptStringPrivate *p = new QScriptStringPrivate(this, name, QScriptStringPrivate::HeapAllocated); |
|
1854 QScriptStringPrivate::init(result, p); |
|
1855 registerScriptString(p); |
|
1856 return result; |
|
1857 } |
|
1858 |
|
1859 #ifdef QT_NO_QOBJECT |
|
1860 |
|
1861 QScriptEngine::QScriptEngine() |
|
1862 : d_ptr(new QScriptEnginePrivate) |
|
1863 { |
|
1864 d_ptr->q_ptr = this; |
|
1865 } |
|
1866 |
|
1867 /*! \internal |
|
1868 */ |
|
1869 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd) |
|
1870 : d_ptr(&dd) |
|
1871 { |
|
1872 d_ptr->q_ptr = this; |
|
1873 } |
|
1874 #else |
|
1875 |
|
1876 /*! |
|
1877 Constructs a QScriptEngine object. |
|
1878 |
|
1879 The globalObject() is initialized to have properties as described in |
|
1880 \l{ECMA-262}, Section 15.1. |
|
1881 */ |
|
1882 QScriptEngine::QScriptEngine() |
|
1883 : QObject(*new QScriptEnginePrivate, 0) |
|
1884 { |
|
1885 } |
|
1886 |
|
1887 /*! |
|
1888 Constructs a QScriptEngine object with the given \a parent. |
|
1889 |
|
1890 The globalObject() is initialized to have properties as described in |
|
1891 \l{ECMA-262}, Section 15.1. |
|
1892 */ |
|
1893 |
|
1894 QScriptEngine::QScriptEngine(QObject *parent) |
|
1895 : QObject(*new QScriptEnginePrivate, parent) |
|
1896 { |
|
1897 } |
|
1898 |
|
1899 /*! \internal |
|
1900 */ |
|
1901 QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent) |
|
1902 : QObject(dd, parent) |
|
1903 { |
|
1904 } |
|
1905 #endif |
|
1906 |
|
1907 /*! |
|
1908 Destroys this QScriptEngine. |
|
1909 */ |
|
1910 QScriptEngine::~QScriptEngine() |
|
1911 { |
|
1912 #ifdef QT_NO_QOBJECT |
|
1913 delete d_ptr; |
|
1914 d_ptr = 0; |
|
1915 #endif |
|
1916 } |
|
1917 |
|
1918 /*! |
|
1919 Returns this engine's Global Object. |
|
1920 |
|
1921 By default, the Global Object contains the built-in objects that are |
|
1922 part of \l{ECMA-262}, such as Math, Date and String. Additionally, |
|
1923 you can set properties of the Global Object to make your own |
|
1924 extensions available to all script code. Non-local variables in |
|
1925 script code will be created as properties of the Global Object, as |
|
1926 well as local variables in global code. |
|
1927 */ |
|
1928 QScriptValue QScriptEngine::globalObject() const |
|
1929 { |
|
1930 Q_D(const QScriptEngine); |
|
1931 QScript::APIShim shim(const_cast<QScriptEnginePrivate*>(d)); |
|
1932 JSC::JSObject *result = d->globalObject(); |
|
1933 return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result); |
|
1934 } |
|
1935 |
|
1936 /*! |
|
1937 \since 4.5 |
|
1938 |
|
1939 Sets this engine's Global Object to be the given \a object. |
|
1940 If \a object is not a valid script object, this function does |
|
1941 nothing. |
|
1942 |
|
1943 When setting a custom global object, you may want to use |
|
1944 QScriptValueIterator to copy the properties of the standard Global |
|
1945 Object; alternatively, you can set the internal prototype of your |
|
1946 custom object to be the original Global Object. |
|
1947 */ |
|
1948 void QScriptEngine::setGlobalObject(const QScriptValue &object) |
|
1949 { |
|
1950 Q_D(QScriptEngine); |
|
1951 if (!object.isObject()) |
|
1952 return; |
|
1953 QScript::APIShim shim(d); |
|
1954 JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object)); |
|
1955 d->setGlobalObject(jscObject); |
|
1956 } |
|
1957 |
|
1958 /*! |
|
1959 Returns a QScriptValue of the primitive type Null. |
|
1960 |
|
1961 \sa undefinedValue() |
|
1962 */ |
|
1963 QScriptValue QScriptEngine::nullValue() |
|
1964 { |
|
1965 Q_D(QScriptEngine); |
|
1966 return d->scriptValueFromJSCValue(JSC::jsNull()); |
|
1967 } |
|
1968 |
|
1969 /*! |
|
1970 Returns a QScriptValue of the primitive type Undefined. |
|
1971 |
|
1972 \sa nullValue() |
|
1973 */ |
|
1974 QScriptValue QScriptEngine::undefinedValue() |
|
1975 { |
|
1976 Q_D(QScriptEngine); |
|
1977 return d->scriptValueFromJSCValue(JSC::jsUndefined()); |
|
1978 } |
|
1979 |
|
1980 /*! |
|
1981 Creates a constructor function from \a fun, with the given \a length. |
|
1982 The \c{prototype} property of the resulting function is set to be the |
|
1983 given \a prototype. The \c{constructor} property of \a prototype is |
|
1984 set to be the resulting function. |
|
1985 |
|
1986 When a function is called as a constructor (e.g. \c{new Foo()}), the |
|
1987 `this' object associated with the function call is the new object |
|
1988 that the function is expected to initialize; the prototype of this |
|
1989 default constructed object will be the function's public |
|
1990 \c{prototype} property. If you always want the function to behave as |
|
1991 a constructor (e.g. \c{Foo()} should also create a new object), or |
|
1992 if you need to create your own object rather than using the default |
|
1993 `this' object, you should make sure that the prototype of your |
|
1994 object is set correctly; either by setting it manually, or, when |
|
1995 wrapping a custom type, by having registered the defaultPrototype() |
|
1996 of that type. Example: |
|
1997 |
|
1998 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9 |
|
1999 |
|
2000 To wrap a custom type and provide a constructor for it, you'd typically |
|
2001 do something like this: |
|
2002 |
|
2003 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10 |
|
2004 */ |
|
2005 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, |
|
2006 const QScriptValue &prototype, |
|
2007 int length) |
|
2008 { |
|
2009 Q_D(QScriptEngine); |
|
2010 QScript::APIShim shim(d); |
|
2011 JSC::ExecState* exec = d->currentFrame; |
|
2012 JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun); |
|
2013 QScriptValue result = d->scriptValueFromJSCValue(function); |
|
2014 result.setProperty(QLatin1String("prototype"), prototype, QScriptValue::Undeletable); |
|
2015 const_cast<QScriptValue&>(prototype) |
|
2016 .setProperty(QLatin1String("constructor"), result, |
|
2017 QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); |
|
2018 return result; |
|
2019 } |
|
2020 |
|
2021 #ifndef QT_NO_REGEXP |
|
2022 |
|
2023 Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); |
|
2024 |
|
2025 /*! |
|
2026 Creates a QtScript object of class RegExp with the given |
|
2027 \a regexp. |
|
2028 |
|
2029 \sa QScriptValue::toRegExp() |
|
2030 */ |
|
2031 QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) |
|
2032 { |
|
2033 Q_D(QScriptEngine); |
|
2034 QScript::APIShim shim(d); |
|
2035 return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, regexp)); |
|
2036 } |
|
2037 |
|
2038 #endif // QT_NO_REGEXP |
|
2039 |
|
2040 /*! |
|
2041 Creates a QtScript object holding the given variant \a value. |
|
2042 |
|
2043 If a default prototype has been registered with the meta type id of |
|
2044 \a value, then the prototype of the created object will be that |
|
2045 prototype; otherwise, the prototype will be the Object prototype |
|
2046 object. |
|
2047 |
|
2048 \sa setDefaultPrototype(), QScriptValue::toVariant(), reportAdditionalMemoryCost() |
|
2049 */ |
|
2050 QScriptValue QScriptEngine::newVariant(const QVariant &value) |
|
2051 { |
|
2052 Q_D(QScriptEngine); |
|
2053 QScript::APIShim shim(d); |
|
2054 return d->scriptValueFromJSCValue(d->newVariant(value)); |
|
2055 } |
|
2056 |
|
2057 /*! |
|
2058 \since 4.4 |
|
2059 \overload |
|
2060 |
|
2061 Initializes the given Qt Script \a object to hold the given variant |
|
2062 \a value, and returns the \a object. |
|
2063 |
|
2064 This function enables you to "promote" a plain Qt Script object |
|
2065 (created by the newObject() function) to a variant, or to replace |
|
2066 the variant contained inside an object previously created by the |
|
2067 newVariant() function. |
|
2068 |
|
2069 The prototype() of the \a object will remain unchanged. |
|
2070 |
|
2071 If \a object is not an object, this function behaves like the normal |
|
2072 newVariant(), i.e. it creates a new script object and returns it. |
|
2073 |
|
2074 This function is useful when you want to provide a script |
|
2075 constructor for a C++ type. If your constructor is invoked in a |
|
2076 \c{new} expression (QScriptContext::isCalledAsConstructor() returns |
|
2077 true), you can pass QScriptContext::thisObject() (the default |
|
2078 constructed script object) to this function to initialize the new |
|
2079 object. |
|
2080 |
|
2081 \sa reportAdditionalMemoryCost() |
|
2082 */ |
|
2083 QScriptValue QScriptEngine::newVariant(const QScriptValue &object, |
|
2084 const QVariant &value) |
|
2085 { |
|
2086 Q_D(QScriptEngine); |
|
2087 QScript::APIShim shim(d); |
|
2088 JSC::JSValue jsObject = d->scriptValueToJSCValue(object); |
|
2089 return d->scriptValueFromJSCValue(d->newVariant(jsObject, value)); |
|
2090 } |
|
2091 |
|
2092 #ifndef QT_NO_QOBJECT |
|
2093 /*! |
|
2094 Creates a QtScript object that wraps the given QObject \a |
|
2095 object, using the given \a ownership. The given \a options control |
|
2096 various aspects of the interaction with the resulting script object. |
|
2097 |
|
2098 Signals and slots, properties and children of \a object are |
|
2099 available as properties of the created QScriptValue. For more |
|
2100 information, see the \l{QtScript} documentation. |
|
2101 |
|
2102 If \a object is a null pointer, this function returns nullValue(). |
|
2103 |
|
2104 If a default prototype has been registered for the \a object's class |
|
2105 (or its superclass, recursively), the prototype of the new script |
|
2106 object will be set to be that default prototype. |
|
2107 |
|
2108 If the given \a object is deleted outside of QtScript's control, any |
|
2109 attempt to access the deleted QObject's members through the QtScript |
|
2110 wrapper object (either by script code or C++) will result in a |
|
2111 script exception. |
|
2112 |
|
2113 \sa QScriptValue::toQObject(), reportAdditionalMemoryCost() |
|
2114 */ |
|
2115 QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership, |
|
2116 const QObjectWrapOptions &options) |
|
2117 { |
|
2118 Q_D(QScriptEngine); |
|
2119 QScript::APIShim shim(d); |
|
2120 JSC::JSValue jscQObject = d->newQObject(object, ownership, options); |
|
2121 return d->scriptValueFromJSCValue(jscQObject); |
|
2122 } |
|
2123 |
|
2124 /*! |
|
2125 \since 4.4 |
|
2126 \overload |
|
2127 |
|
2128 Initializes the given \a scriptObject to hold the given \a qtObject, |
|
2129 and returns the \a scriptObject. |
|
2130 |
|
2131 This function enables you to "promote" a plain Qt Script object |
|
2132 (created by the newObject() function) to a QObject proxy, or to |
|
2133 replace the QObject contained inside an object previously created by |
|
2134 the newQObject() function. |
|
2135 |
|
2136 The prototype() of the \a scriptObject will remain unchanged. |
|
2137 |
|
2138 If \a scriptObject is not an object, this function behaves like the |
|
2139 normal newQObject(), i.e. it creates a new script object and returns |
|
2140 it. |
|
2141 |
|
2142 This function is useful when you want to provide a script |
|
2143 constructor for a QObject-based class. If your constructor is |
|
2144 invoked in a \c{new} expression |
|
2145 (QScriptContext::isCalledAsConstructor() returns true), you can pass |
|
2146 QScriptContext::thisObject() (the default constructed script object) |
|
2147 to this function to initialize the new object. |
|
2148 |
|
2149 \sa reportAdditionalMemoryCost() |
|
2150 */ |
|
2151 QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, |
|
2152 QObject *qtObject, |
|
2153 ValueOwnership ownership, |
|
2154 const QObjectWrapOptions &options) |
|
2155 { |
|
2156 Q_D(QScriptEngine); |
|
2157 if (!scriptObject.isObject()) |
|
2158 return newQObject(qtObject, ownership, options); |
|
2159 QScript::APIShim shim(d); |
|
2160 JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue); |
|
2161 if (!jscObject->inherits(&QScriptObject::info)) { |
|
2162 qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported"); |
|
2163 return QScriptValue(); |
|
2164 } |
|
2165 QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject); |
|
2166 if (!scriptObject.isQObject()) { |
|
2167 jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options)); |
|
2168 } else { |
|
2169 QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate()); |
|
2170 delegate->setValue(qtObject); |
|
2171 delegate->setOwnership(ownership); |
|
2172 delegate->setOptions(options); |
|
2173 } |
|
2174 return scriptObject; |
|
2175 } |
|
2176 |
|
2177 #endif // QT_NO_QOBJECT |
|
2178 |
|
2179 /*! |
|
2180 Creates a QtScript object of class Object. |
|
2181 |
|
2182 The prototype of the created object will be the Object |
|
2183 prototype object. |
|
2184 |
|
2185 \sa newArray(), QScriptValue::setProperty() |
|
2186 */ |
|
2187 QScriptValue QScriptEngine::newObject() |
|
2188 { |
|
2189 Q_D(QScriptEngine); |
|
2190 QScript::APIShim shim(d); |
|
2191 return d->scriptValueFromJSCValue(d->newObject()); |
|
2192 } |
|
2193 |
|
2194 /*! |
|
2195 \since 4.4 |
|
2196 \overload |
|
2197 |
|
2198 Creates a QtScript Object of the given class, \a scriptClass. |
|
2199 |
|
2200 The prototype of the created object will be the Object |
|
2201 prototype object. |
|
2202 |
|
2203 \a data, if specified, is set as the internal data of the |
|
2204 new object (using QScriptValue::setData()). |
|
2205 |
|
2206 \sa QScriptValue::scriptClass(), reportAdditionalMemoryCost() |
|
2207 */ |
|
2208 QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass, |
|
2209 const QScriptValue &data) |
|
2210 { |
|
2211 Q_D(QScriptEngine); |
|
2212 QScript::APIShim shim(d); |
|
2213 JSC::ExecState* exec = d->currentFrame; |
|
2214 QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure); |
|
2215 result->setDelegate(new QScript::ClassObjectDelegate(scriptClass)); |
|
2216 QScriptValue scriptObject = d->scriptValueFromJSCValue(result); |
|
2217 scriptObject.setData(data); |
|
2218 QScriptValue proto = scriptClass->prototype(); |
|
2219 if (proto.isValid()) |
|
2220 scriptObject.setPrototype(proto); |
|
2221 return scriptObject; |
|
2222 } |
|
2223 |
|
2224 /*! |
|
2225 \internal |
|
2226 */ |
|
2227 QScriptValue QScriptEngine::newActivationObject() |
|
2228 { |
|
2229 qWarning("QScriptEngine::newActivationObject() not implemented"); |
|
2230 // ### JSActivation or JSVariableObject? |
|
2231 return QScriptValue(); |
|
2232 } |
|
2233 |
|
2234 /*! |
|
2235 Creates a QScriptValue that wraps a native (C++) function. \a fun |
|
2236 must be a C++ function with signature QScriptEngine::FunctionSignature. \a |
|
2237 length is the number of arguments that \a fun expects; this becomes |
|
2238 the \c{length} property of the created QScriptValue. |
|
2239 |
|
2240 Note that \a length only gives an indication of the number of |
|
2241 arguments that the function expects; an actual invocation of a |
|
2242 function can include any number of arguments. You can check the |
|
2243 \l{QScriptContext::argumentCount()}{argumentCount()} of the |
|
2244 QScriptContext associated with the invocation to determine the |
|
2245 actual number of arguments passed. |
|
2246 |
|
2247 A \c{prototype} property is automatically created for the resulting |
|
2248 function object, to provide for the possibility that the function |
|
2249 will be used as a constructor. |
|
2250 |
|
2251 By combining newFunction() and the property flags |
|
2252 QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you |
|
2253 can create script object properties that behave like normal |
|
2254 properties in script code, but are in fact accessed through |
|
2255 functions (analogous to how properties work in \l{Qt's Property |
|
2256 System}). Example: |
|
2257 |
|
2258 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11 |
|
2259 |
|
2260 When the property \c{foo} of the script object is subsequently |
|
2261 accessed in script code, \c{getSetFoo()} will be invoked to handle |
|
2262 the access. In this particular case, we chose to store the "real" |
|
2263 value of \c{foo} as a property of the accessor function itself; you |
|
2264 are of course free to do whatever you like in this function. |
|
2265 |
|
2266 In the above example, a single native function was used to handle |
|
2267 both reads and writes to the property; the argument count is used to |
|
2268 determine if we are handling a read or write. You can also use two |
|
2269 separate functions; just specify the relevant flag |
|
2270 (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when |
|
2271 setting the property, e.g.: |
|
2272 |
|
2273 \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12 |
|
2274 |
|
2275 \sa QScriptValue::call() |
|
2276 */ |
|
2277 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length) |
|
2278 { |
|
2279 Q_D(QScriptEngine); |
|
2280 QScript::APIShim shim(d); |
|
2281 JSC::ExecState* exec = d->currentFrame; |
|
2282 JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun); |
|
2283 QScriptValue result = d->scriptValueFromJSCValue(function); |
|
2284 QScriptValue proto = newObject(); |
|
2285 result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable); |
|
2286 proto.setProperty(QLatin1String("constructor"), result, |
|
2287 QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); |
|
2288 return result; |
|
2289 } |
|
2290 |
|
2291 /*! |
|
2292 \internal |
|
2293 \since 4.4 |
|
2294 */ |
|
2295 QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg) |
|
2296 { |
|
2297 Q_D(QScriptEngine); |
|
2298 QScript::APIShim shim(d); |
|
2299 JSC::ExecState* exec = d->currentFrame; |
|
2300 JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg); |
|
2301 QScriptValue result = d->scriptValueFromJSCValue(function); |
|
2302 QScriptValue proto = newObject(); |
|
2303 result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable); |
|
2304 proto.setProperty(QLatin1String("constructor"), result, |
|
2305 QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); |
|
2306 return result; |
|
2307 } |
|
2308 |
|
2309 /*! |
|
2310 Creates a QtScript object of class Array with the given \a length. |
|
2311 |
|
2312 \sa newObject() |
|
2313 */ |
|
2314 QScriptValue QScriptEngine::newArray(uint length) |
|
2315 { |
|
2316 Q_D(QScriptEngine); |
|
2317 QScript::APIShim shim(d); |
|
2318 return d->scriptValueFromJSCValue(d->newArray(d->currentFrame, length)); |
|
2319 } |
|
2320 |
|
2321 /*! |
|
2322 Creates a QtScript object of class RegExp with the given |
|
2323 \a pattern and \a flags. |
|
2324 |
|
2325 The legal flags are 'g' (global), 'i' (ignore case), and 'm' |
|
2326 (multiline). |
|
2327 */ |
|
2328 QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags) |
|
2329 { |
|
2330 Q_D(QScriptEngine); |
|
2331 QScript::APIShim shim(d); |
|
2332 return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, pattern, flags)); |
1986 } |
2333 } |
1987 |
2334 |
1988 /*! |
2335 /*! |
1989 Creates a QtScript object of class Date with the given |
2336 Creates a QtScript object of class Date with the given |
1990 \a value (the number of milliseconds since 01 January 1970, |
2337 \a value (the number of milliseconds since 01 January 1970, |
1991 UTC). |
2338 UTC). |
1992 */ |
2339 */ |
1993 QScriptValue QScriptEngine::newDate(qsreal value) |
2340 QScriptValue QScriptEngine::newDate(qsreal value) |
1994 { |
2341 { |
1995 Q_D(QScriptEngine); |
2342 Q_D(QScriptEngine); |
1996 JSC::ExecState* exec = d->currentFrame; |
2343 QScript::APIShim shim(d); |
1997 JSC::JSValue val = JSC::jsNumber(exec, value); |
2344 return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); |
1998 JSC::ArgList args(&val, 1); |
|
1999 JSC::JSObject *result = JSC::constructDate(exec, args); |
|
2000 return d->scriptValueFromJSCValue(result); |
|
2001 } |
2345 } |
2002 |
2346 |
2003 /*! |
2347 /*! |
2004 Creates a QtScript object of class Date from the given \a value. |
2348 Creates a QtScript object of class Date from the given \a value. |
2005 |
2349 |
2006 \sa QScriptValue::toDateTime() |
2350 \sa QScriptValue::toDateTime() |
2007 */ |
2351 */ |
2008 QScriptValue QScriptEngine::newDate(const QDateTime &value) |
2352 QScriptValue QScriptEngine::newDate(const QDateTime &value) |
2009 { |
2353 { |
2010 return newDate(QScript::FromDateTime(value)); |
2354 Q_D(QScriptEngine); |
|
2355 QScript::APIShim shim(d); |
|
2356 return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); |
2011 } |
2357 } |
2012 |
2358 |
2013 #ifndef QT_NO_QOBJECT |
2359 #ifndef QT_NO_QOBJECT |
2014 /*! |
2360 /*! |
2015 Creates a QtScript object that represents a QObject class, using the |
2361 Creates a QtScript object that represents a QObject class, using the |
2564 \internal |
2915 \internal |
2565 */ |
2916 */ |
2566 QScriptValue QScriptEngine::create(int type, const void *ptr) |
2917 QScriptValue QScriptEngine::create(int type, const void *ptr) |
2567 { |
2918 { |
2568 Q_D(QScriptEngine); |
2919 Q_D(QScriptEngine); |
2569 return d->create(type, ptr); |
2920 QScript::APIShim shim(d); |
2570 } |
2921 return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr)); |
2571 |
2922 } |
2572 QScriptValue QScriptEnginePrivate::create(int type, const void *ptr) |
2923 |
2573 { |
2924 JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const void *ptr) |
2574 Q_Q(QScriptEngine); |
2925 { |
2575 Q_ASSERT(ptr != 0); |
2926 Q_ASSERT(ptr != 0); |
2576 QScriptValue result; |
2927 JSC::JSValue result; |
2577 QScriptTypeInfo *info = m_typeInfos.value(type); |
2928 QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0; |
|
2929 QScriptTypeInfo *info = eng ? eng->m_typeInfos.value(type) : 0; |
2578 if (info && info->marshal) { |
2930 if (info && info->marshal) { |
2579 result = info->marshal(q, ptr); |
2931 result = eng->scriptValueToJSCValue(info->marshal(eng->q_func(), ptr)); |
2580 } else { |
2932 } else { |
2581 // check if it's one of the types we know |
2933 // check if it's one of the types we know |
2582 switch (QMetaType::Type(type)) { |
2934 switch (QMetaType::Type(type)) { |
2583 case QMetaType::Void: |
2935 case QMetaType::Void: |
2584 return QScriptValue(q, QScriptValue::UndefinedValue); |
2936 return JSC::jsUndefined(); |
2585 case QMetaType::Bool: |
2937 case QMetaType::Bool: |
2586 return QScriptValue(q, *reinterpret_cast<const bool*>(ptr)); |
2938 return JSC::jsBoolean(*reinterpret_cast<const bool*>(ptr)); |
2587 case QMetaType::Int: |
2939 case QMetaType::Int: |
2588 return QScriptValue(q, *reinterpret_cast<const int*>(ptr)); |
2940 return JSC::jsNumber(exec, *reinterpret_cast<const int*>(ptr)); |
2589 case QMetaType::UInt: |
2941 case QMetaType::UInt: |
2590 return QScriptValue(q, *reinterpret_cast<const uint*>(ptr)); |
2942 return JSC::jsNumber(exec, *reinterpret_cast<const uint*>(ptr)); |
2591 case QMetaType::LongLong: |
2943 case QMetaType::LongLong: |
2592 return QScriptValue(q, qsreal(*reinterpret_cast<const qlonglong*>(ptr))); |
2944 return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qlonglong*>(ptr))); |
2593 case QMetaType::ULongLong: |
2945 case QMetaType::ULongLong: |
2594 #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804 |
2946 #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804 |
2595 #pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.") |
2947 #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))); |
2948 return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); |
2597 #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) |
2949 #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) |
2598 return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); |
2950 return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); |
2599 #else |
2951 #else |
2600 return QScriptValue(q, qsreal(*reinterpret_cast<const qulonglong*>(ptr))); |
2952 return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qulonglong*>(ptr))); |
2601 #endif |
2953 #endif |
2602 case QMetaType::Double: |
2954 case QMetaType::Double: |
2603 return QScriptValue(q, qsreal(*reinterpret_cast<const double*>(ptr))); |
2955 return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const double*>(ptr))); |
2604 case QMetaType::QString: |
2956 case QMetaType::QString: |
2605 return QScriptValue(q, *reinterpret_cast<const QString*>(ptr)); |
2957 return JSC::jsString(exec, *reinterpret_cast<const QString*>(ptr)); |
2606 case QMetaType::Float: |
2958 case QMetaType::Float: |
2607 return QScriptValue(q, *reinterpret_cast<const float*>(ptr)); |
2959 return JSC::jsNumber(exec, *reinterpret_cast<const float*>(ptr)); |
2608 case QMetaType::Short: |
2960 case QMetaType::Short: |
2609 return QScriptValue(q, *reinterpret_cast<const short*>(ptr)); |
2961 return JSC::jsNumber(exec, *reinterpret_cast<const short*>(ptr)); |
2610 case QMetaType::UShort: |
2962 case QMetaType::UShort: |
2611 return QScriptValue(q, *reinterpret_cast<const unsigned short*>(ptr)); |
2963 return JSC::jsNumber(exec, *reinterpret_cast<const unsigned short*>(ptr)); |
2612 case QMetaType::Char: |
2964 case QMetaType::Char: |
2613 return QScriptValue(q, *reinterpret_cast<const char*>(ptr)); |
2965 return JSC::jsNumber(exec, *reinterpret_cast<const char*>(ptr)); |
2614 case QMetaType::UChar: |
2966 case QMetaType::UChar: |
2615 return QScriptValue(q, *reinterpret_cast<const unsigned char*>(ptr)); |
2967 return JSC::jsNumber(exec, *reinterpret_cast<const unsigned char*>(ptr)); |
2616 case QMetaType::QChar: |
2968 case QMetaType::QChar: |
2617 return QScriptValue(q, (*reinterpret_cast<const QChar*>(ptr)).unicode()); |
2969 return JSC::jsNumber(exec, (*reinterpret_cast<const QChar*>(ptr)).unicode()); |
2618 case QMetaType::QStringList: |
2970 case QMetaType::QStringList: |
2619 result = arrayFromStringList(*reinterpret_cast<const QStringList *>(ptr)); |
2971 result = arrayFromStringList(exec, *reinterpret_cast<const QStringList *>(ptr)); |
2620 break; |
2972 break; |
2621 case QMetaType::QVariantList: |
2973 case QMetaType::QVariantList: |
2622 result = arrayFromVariantList(*reinterpret_cast<const QVariantList *>(ptr)); |
2974 result = arrayFromVariantList(exec, *reinterpret_cast<const QVariantList *>(ptr)); |
2623 break; |
2975 break; |
2624 case QMetaType::QVariantMap: |
2976 case QMetaType::QVariantMap: |
2625 result = objectFromVariantMap(*reinterpret_cast<const QVariantMap *>(ptr)); |
2977 result = objectFromVariantMap(exec, *reinterpret_cast<const QVariantMap *>(ptr)); |
2626 break; |
2978 break; |
2627 case QMetaType::QDateTime: |
2979 case QMetaType::QDateTime: |
2628 result = q->newDate(*reinterpret_cast<const QDateTime *>(ptr)); |
2980 result = newDate(exec, *reinterpret_cast<const QDateTime *>(ptr)); |
2629 break; |
2981 break; |
2630 case QMetaType::QDate: |
2982 case QMetaType::QDate: |
2631 result = q->newDate(QDateTime(*reinterpret_cast<const QDate *>(ptr))); |
2983 result = newDate(exec, QDateTime(*reinterpret_cast<const QDate *>(ptr))); |
2632 break; |
2984 break; |
2633 #ifndef QT_NO_REGEXP |
2985 #ifndef QT_NO_REGEXP |
2634 case QMetaType::QRegExp: |
2986 case QMetaType::QRegExp: |
2635 result = q->newRegExp(*reinterpret_cast<const QRegExp *>(ptr)); |
2987 result = newRegExp(exec, *reinterpret_cast<const QRegExp *>(ptr)); |
2636 break; |
2988 break; |
2637 #endif |
2989 #endif |
2638 #ifndef QT_NO_QOBJECT |
2990 #ifndef QT_NO_QOBJECT |
2639 case QMetaType::QObjectStar: |
2991 case QMetaType::QObjectStar: |
2640 case QMetaType::QWidgetStar: |
2992 case QMetaType::QWidgetStar: |
2641 result = q->newQObject(*reinterpret_cast<QObject* const *>(ptr)); |
2993 result = eng->newQObject(*reinterpret_cast<QObject* const *>(ptr)); |
2642 break; |
2994 break; |
2643 #endif |
2995 #endif |
|
2996 case QMetaType::QVariant: |
|
2997 result = jscValueFromVariant(exec, *reinterpret_cast<const QVariant*>(ptr)); |
|
2998 break; |
2644 default: |
2999 default: |
2645 if (type == qMetaTypeId<QScriptValue>()) { |
3000 if (type == qMetaTypeId<QScriptValue>()) { |
2646 result = *reinterpret_cast<const QScriptValue*>(ptr); |
3001 result = eng->scriptValueToJSCValue(*reinterpret_cast<const QScriptValue*>(ptr)); |
2647 if (!result.isValid()) |
3002 if (!result) |
2648 return QScriptValue(q, QScriptValue::UndefinedValue); |
3003 return JSC::jsUndefined(); |
2649 } |
3004 } |
2650 |
3005 |
2651 #ifndef QT_NO_QOBJECT |
3006 #ifndef QT_NO_QOBJECT |
2652 // lazy registration of some common list types |
3007 // lazy registration of some common list types |
2653 else if (type == qMetaTypeId<QObjectList>()) { |
3008 else if (type == qMetaTypeId<QObjectList>()) { |
2654 qScriptRegisterSequenceMetaType<QObjectList>(q); |
3009 qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func()); |
2655 return create(type, ptr); |
3010 return create(exec, type, ptr); |
2656 } |
3011 } |
2657 #endif |
3012 #endif |
2658 else if (type == qMetaTypeId<QList<int> >()) { |
3013 else if (type == qMetaTypeId<QList<int> >()) { |
2659 qScriptRegisterSequenceMetaType<QList<int> >(q); |
3014 qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func()); |
2660 return create(type, ptr); |
3015 return create(exec, type, ptr); |
2661 } |
3016 } |
2662 |
3017 |
2663 else { |
3018 else { |
2664 QByteArray typeName = QMetaType::typeName(type); |
3019 QByteArray typeName = QMetaType::typeName(type); |
2665 if (typeName == "QVariant") |
|
2666 result = scriptValueFromVariant(*reinterpret_cast<const QVariant*>(ptr)); |
|
2667 if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr)) |
3020 if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr)) |
2668 return QScriptValue(q, QScriptValue::NullValue); |
3021 return JSC::jsNull(); |
2669 else |
3022 else |
2670 result = q->newVariant(QVariant(type, ptr)); |
3023 result = eng->newVariant(QVariant(type, ptr)); |
2671 } |
3024 } |
2672 } |
3025 } |
2673 } |
3026 } |
2674 if (result.isObject() && info && info->prototype |
3027 if (result && result.isObject() && info && info->prototype |
2675 && JSC::JSValue::strictEqual(scriptValueToJSCValue(result.prototype()), originalGlobalObject()->objectPrototype())) { |
3028 && JSC::JSValue::strictEqual(exec, JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) { |
2676 result.setPrototype(scriptValueFromJSCValue(info->prototype)); |
3029 JSC::asObject(result)->setPrototype(info->prototype); |
2677 } |
3030 } |
2678 return result; |
3031 return result; |
2679 } |
3032 } |
2680 |
3033 |
2681 bool QScriptEnginePrivate::convert(const QScriptValue &value, |
3034 bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value, |
2682 int type, void *ptr, |
3035 int type, void *ptr) |
2683 QScriptEnginePrivate *eng) |
3036 { |
2684 { |
3037 QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0; |
2685 if (!eng) |
|
2686 eng = QScriptValuePrivate::getEngine(value); |
|
2687 if (eng) { |
3038 if (eng) { |
2688 QScriptTypeInfo *info = eng->m_typeInfos.value(type); |
3039 QScriptTypeInfo *info = eng->m_typeInfos.value(type); |
2689 if (info && info->demarshal) { |
3040 if (info && info->demarshal) { |
2690 info->demarshal(value, ptr); |
3041 info->demarshal(eng->scriptValueFromJSCValue(value), ptr); |
2691 return true; |
3042 return true; |
2692 } |
3043 } |
2693 } |
3044 } |
2694 |
3045 |
2695 // check if it's one of the types we know |
3046 // check if it's one of the types we know |
2696 switch (QMetaType::Type(type)) { |
3047 switch (QMetaType::Type(type)) { |
2697 case QMetaType::Bool: |
3048 case QMetaType::Bool: |
2698 *reinterpret_cast<bool*>(ptr) = value.toBoolean(); |
3049 *reinterpret_cast<bool*>(ptr) = toBool(exec, value); |
2699 return true; |
3050 return true; |
2700 case QMetaType::Int: |
3051 case QMetaType::Int: |
2701 *reinterpret_cast<int*>(ptr) = value.toInt32(); |
3052 *reinterpret_cast<int*>(ptr) = toInt32(exec, value); |
2702 return true; |
3053 return true; |
2703 case QMetaType::UInt: |
3054 case QMetaType::UInt: |
2704 *reinterpret_cast<uint*>(ptr) = value.toUInt32(); |
3055 *reinterpret_cast<uint*>(ptr) = toUInt32(exec, value); |
2705 return true; |
3056 return true; |
2706 case QMetaType::LongLong: |
3057 case QMetaType::LongLong: |
2707 *reinterpret_cast<qlonglong*>(ptr) = qlonglong(value.toInteger()); |
3058 *reinterpret_cast<qlonglong*>(ptr) = qlonglong(toInteger(exec, value)); |
2708 return true; |
3059 return true; |
2709 case QMetaType::ULongLong: |
3060 case QMetaType::ULongLong: |
2710 *reinterpret_cast<qulonglong*>(ptr) = qulonglong(value.toInteger()); |
3061 *reinterpret_cast<qulonglong*>(ptr) = qulonglong(toInteger(exec, value)); |
2711 return true; |
3062 return true; |
2712 case QMetaType::Double: |
3063 case QMetaType::Double: |
2713 *reinterpret_cast<double*>(ptr) = value.toNumber(); |
3064 *reinterpret_cast<double*>(ptr) = toNumber(exec, value); |
2714 return true; |
3065 return true; |
2715 case QMetaType::QString: |
3066 case QMetaType::QString: |
2716 if (value.isUndefined() || value.isNull()) |
3067 if (value.isUndefined() || value.isNull()) |
2717 *reinterpret_cast<QString*>(ptr) = QString(); |
3068 *reinterpret_cast<QString*>(ptr) = QString(); |
2718 else |
3069 else |
2719 *reinterpret_cast<QString*>(ptr) = value.toString(); |
3070 *reinterpret_cast<QString*>(ptr) = toString(exec, value); |
2720 return true; |
3071 return true; |
2721 case QMetaType::Float: |
3072 case QMetaType::Float: |
2722 *reinterpret_cast<float*>(ptr) = value.toNumber(); |
3073 *reinterpret_cast<float*>(ptr) = toNumber(exec, value); |
2723 return true; |
3074 return true; |
2724 case QMetaType::Short: |
3075 case QMetaType::Short: |
2725 *reinterpret_cast<short*>(ptr) = short(value.toInt32()); |
3076 *reinterpret_cast<short*>(ptr) = short(toInt32(exec, value)); |
2726 return true; |
3077 return true; |
2727 case QMetaType::UShort: |
3078 case QMetaType::UShort: |
2728 *reinterpret_cast<unsigned short*>(ptr) = value.toUInt16(); |
3079 *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(toNumber(exec, value)); |
2729 return true; |
3080 return true; |
2730 case QMetaType::Char: |
3081 case QMetaType::Char: |
2731 *reinterpret_cast<char*>(ptr) = char(value.toInt32()); |
3082 *reinterpret_cast<char*>(ptr) = char(toInt32(exec, value)); |
2732 return true; |
3083 return true; |
2733 case QMetaType::UChar: |
3084 case QMetaType::UChar: |
2734 *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(value.toInt32()); |
3085 *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(toInt32(exec, value)); |
2735 return true; |
3086 return true; |
2736 case QMetaType::QChar: |
3087 case QMetaType::QChar: |
2737 if (value.isString()) { |
3088 if (value.isString()) { |
2738 QString str = value.toString(); |
3089 QString str = toString(exec, value); |
2739 *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0); |
3090 *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0); |
2740 } else { |
3091 } else { |
2741 *reinterpret_cast<QChar*>(ptr) = QChar(value.toUInt16()); |
3092 *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(toNumber(exec, value))); |
2742 } |
3093 } |
2743 return true; |
3094 return true; |
2744 case QMetaType::QDateTime: |
3095 case QMetaType::QDateTime: |
2745 if (value.isDate()) { |
3096 if (isDate(value)) { |
2746 *reinterpret_cast<QDateTime *>(ptr) = value.toDateTime(); |
3097 *reinterpret_cast<QDateTime *>(ptr) = toDateTime(exec, value); |
2747 return true; |
3098 return true; |
2748 } break; |
3099 } break; |
2749 case QMetaType::QDate: |
3100 case QMetaType::QDate: |
2750 if (value.isDate()) { |
3101 if (isDate(value)) { |
2751 *reinterpret_cast<QDate *>(ptr) = value.toDateTime().date(); |
3102 *reinterpret_cast<QDate *>(ptr) = toDateTime(exec, value).date(); |
2752 return true; |
3103 return true; |
2753 } break; |
3104 } break; |
2754 #ifndef QT_NO_REGEXP |
3105 #ifndef QT_NO_REGEXP |
2755 case QMetaType::QRegExp: |
3106 case QMetaType::QRegExp: |
2756 if (value.isRegExp()) { |
3107 if (isRegExp(value)) { |
2757 *reinterpret_cast<QRegExp *>(ptr) = value.toRegExp(); |
3108 *reinterpret_cast<QRegExp *>(ptr) = toRegExp(exec, value); |
2758 return true; |
3109 return true; |
2759 } break; |
3110 } break; |
2760 #endif |
3111 #endif |
2761 #ifndef QT_NO_QOBJECT |
3112 #ifndef QT_NO_QOBJECT |
2762 case QMetaType::QObjectStar: |
3113 case QMetaType::QObjectStar: |
2763 if (value.isQObject() || value.isNull()) { |
3114 if (isQObject(value) || value.isNull()) { |
2764 *reinterpret_cast<QObject* *>(ptr) = value.toQObject(); |
3115 *reinterpret_cast<QObject* *>(ptr) = toQObject(exec, value); |
2765 return true; |
3116 return true; |
2766 } break; |
3117 } break; |
2767 case QMetaType::QWidgetStar: |
3118 case QMetaType::QWidgetStar: |
2768 if (value.isQObject() || value.isNull()) { |
3119 if (isQObject(value) || value.isNull()) { |
2769 QObject *qo = value.toQObject(); |
3120 QObject *qo = toQObject(exec, value); |
2770 if (!qo || qo->isWidgetType()) { |
3121 if (!qo || qo->isWidgetType()) { |
2771 *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo); |
3122 *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo); |
2772 return true; |
3123 return true; |
2773 } |
3124 } |
2774 } break; |
3125 } break; |
2775 #endif |
3126 #endif |
2776 case QMetaType::QStringList: |
3127 case QMetaType::QStringList: |
2777 if (value.isArray()) { |
3128 if (isArray(value)) { |
2778 *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(value); |
3129 *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(exec, value); |
2779 return true; |
3130 return true; |
2780 } break; |
3131 } break; |
2781 case QMetaType::QVariantList: |
3132 case QMetaType::QVariantList: |
2782 if (value.isArray()) { |
3133 if (isArray(value)) { |
2783 *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(value); |
3134 *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, value); |
2784 return true; |
3135 return true; |
2785 } break; |
3136 } break; |
2786 case QMetaType::QVariantMap: |
3137 case QMetaType::QVariantMap: |
2787 if (value.isObject()) { |
3138 if (isObject(value)) { |
2788 *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(value); |
3139 *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, value); |
2789 return true; |
3140 return true; |
2790 } break; |
3141 } break; |
|
3142 case QMetaType::QVariant: |
|
3143 *reinterpret_cast<QVariant*>(ptr) = toVariant(exec, value); |
|
3144 return true; |
2791 default: |
3145 default: |
2792 ; |
3146 ; |
2793 } |
3147 } |
2794 |
3148 |
2795 QByteArray name = QMetaType::typeName(type); |
3149 QByteArray name = QMetaType::typeName(type); |
2796 #ifndef QT_NO_QOBJECT |
3150 #ifndef QT_NO_QOBJECT |
2797 if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(ptr))) |
3151 if (convertToNativeQObject(exec, value, name, reinterpret_cast<void* *>(ptr))) |
2798 return true; |
3152 return true; |
2799 #endif |
3153 #endif |
2800 if (value.isVariant() && name.endsWith('*')) { |
3154 if (isVariant(value) && name.endsWith('*')) { |
2801 int valueType = QMetaType::type(name.left(name.size()-1)); |
3155 int valueType = QMetaType::type(name.left(name.size()-1)); |
2802 QVariant &var = QScriptValuePrivate::get(value)->variantValue(); |
3156 QVariant &var = variantValue(value); |
2803 if (valueType == var.userType()) { |
3157 if (valueType == var.userType()) { |
2804 *reinterpret_cast<void* *>(ptr) = var.data(); |
3158 *reinterpret_cast<void* *>(ptr) = var.data(); |
2805 return true; |
3159 return true; |
2806 } else { |
3160 } else { |
2807 // look in the prototype chain |
3161 // look in the prototype chain |
2808 QScriptValue proto = value.prototype(); |
3162 JSC::JSValue proto = JSC::asObject(value)->prototype(); |
2809 while (proto.isObject()) { |
3163 while (proto.isObject()) { |
2810 bool canCast = false; |
3164 bool canCast = false; |
2811 if (proto.isVariant()) { |
3165 if (isVariant(proto)) { |
2812 canCast = (type == proto.toVariant().userType()) |
3166 canCast = (type == variantValue(proto).userType()) |
2813 || (valueType && (valueType == proto.toVariant().userType())); |
3167 || (valueType && (valueType == variantValue(proto).userType())); |
2814 } |
3168 } |
2815 #ifndef QT_NO_QOBJECT |
3169 #ifndef QT_NO_QOBJECT |
2816 else if (proto.isQObject()) { |
3170 else if (isQObject(proto)) { |
2817 QByteArray className = name.left(name.size()-1); |
3171 QByteArray className = name.left(name.size()-1); |
2818 if (QObject *qobject = proto.toQObject()) |
3172 if (QObject *qobject = toQObject(exec, proto)) |
2819 canCast = qobject->qt_metacast(className) != 0; |
3173 canCast = qobject->qt_metacast(className) != 0; |
2820 } |
3174 } |
2821 #endif |
3175 #endif |
2822 if (canCast) { |
3176 if (canCast) { |
2823 QByteArray varTypeName = QMetaType::typeName(var.userType()); |
3177 QByteArray varTypeName = QMetaType::typeName(var.userType()); |