📄 qt_runtime.cpp
字号:
/* * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */#include "config.h"#include "qt_runtime.h"#include "DateInstance.h"#include "DateMath.h"#include "DatePrototype.h"#include "FunctionPrototype.h"#include "Interpreter.h"#include "JSArray.h"#include "JSByteArray.h"#include "JSDOMBinding.h"#include "JSGlobalObject.h"#include "JSLock.h"#include "JSObject.h"#include "ObjectPrototype.h"#include "PropertyNameArray.h"#include "RegExpConstructor.h"#include "RegExpObject.h"#include "qdatetime.h"#include "qdebug.h"#include "qmetaobject.h"#include "qmetatype.h"#include "qobject.h"#include "qstringlist.h"#include "qt_instance.h"#include "qvarlengtharray.h"#include <JSFunction.h>#include <limits.h>#include <runtime.h>#include <runtime_array.h>#include <runtime_object.h>#include "BooleanObject.h"// QtScript has theseQ_DECLARE_METATYPE(QObjectList);Q_DECLARE_METATYPE(QList<int>);Q_DECLARE_METATYPE(QVariant);using namespace WebCore;namespace JSC {namespace Bindings {// Debugging//#define QTWK_RUNTIME_CONVERSION_DEBUG//#define QTWK_RUNTIME_MATCH_DEBUGclass QWKNoDebug{public: inline QWKNoDebug(){} inline ~QWKNoDebug(){} template<typename T> inline QWKNoDebug &operator<<(const T &) { return *this; }};#ifdef QTWK_RUNTIME_CONVERSION_DEBUG#define qConvDebug() qDebug()#else#define qConvDebug() QWKNoDebug()#endif#ifdef QTWK_RUNTIME_MATCH_DEBUG#define qMatchDebug() qDebug()#else#define qMatchDebug() QWKNoDebug()#endiftypedef enum { Variant = 0, Number, Boolean, String, Date, RegExp, Array, QObj, Object, Null, RTArray, JSByteArray} JSRealType;#if defined(QTWK_RUNTIME_CONVERSION_DEBUG) || defined(QTWK_RUNTIME_MATCH_DEBUG)QDebug operator<<(QDebug dbg, const JSRealType &c){ const char *map[] = { "Variant", "Number", "Boolean", "String", "Date", "RegExp", "Array", "RTObject", "Object", "Null", "RTArray"}; dbg.nospace() << "JSType(" << ((int)c) << ", " << map[c] << ")"; return dbg.space();}#endifstatic JSRealType valueRealType(ExecState* exec, JSValuePtr val){ if (val.isNumber()) return Number; else if (val.isString()) return String; else if (val.isBoolean()) return Boolean; else if (val.isNull()) return Null; else if (isJSByteArray(&exec->globalData(), val)) return JSByteArray; else if (val.isObject()) { JSObject *object = val.toObject(exec); if (object->inherits(&RuntimeArray::s_info)) // RuntimeArray 'inherits' from Array, but not in C++ return RTArray; else if (object->inherits(&JSArray::info)) return Array; else if (object->inherits(&DateInstance::info)) return Date; else if (object->inherits(&RegExpObject::info)) return RegExp; else if (object->inherits(&RuntimeObjectImp::s_info)) return QObj; return Object; } return String; // I don't know.}QVariant convertValueToQVariant(ExecState* exec, JSValuePtr value, QMetaType::Type hint, int *distance, HashSet<JSObject*>* visitedObjects){ JSObject* object = 0; if (value.isObject()) { object = value.toObject(exec); if (visitedObjects->contains(object)) return QVariant(); visitedObjects->add(object); } // check magic pointer values before dereferencing value if (value == jsNaN(exec) || (value == jsUndefined() && hint != QMetaType::QString && hint != (QMetaType::Type) qMetaTypeId<QVariant>())) { if (distance) *distance = -1; return QVariant(); } JSLock lock(false); JSRealType type = valueRealType(exec, value); if (hint == QMetaType::Void) { switch(type) { case Number: hint = QMetaType::Double; break; case Boolean: hint = QMetaType::Bool; break; case String: default: hint = QMetaType::QString; break; case Date: hint = QMetaType::QDateTime; break; case RegExp: hint = QMetaType::QRegExp; break; case Object: if (object->inherits(&NumberObject::info)) hint = QMetaType::Double; else if (object->inherits(&BooleanObject::info)) hint = QMetaType::Bool; else hint = QMetaType::QVariantMap; break; case QObj: hint = QMetaType::QObjectStar; break; case JSByteArray: hint = QMetaType::QByteArray; break; case Array: case RTArray: hint = QMetaType::QVariantList; break; } } qConvDebug() << "convertValueToQVariant: jstype is " << type << ", hint is" << hint; if (value == jsNull() && hint != QMetaType::QObjectStar && hint != QMetaType::VoidStar && hint != QMetaType::QString && hint != (QMetaType::Type) qMetaTypeId<QVariant>()) { if (distance) *distance = -1; return QVariant(); } QVariant ret; int dist = -1; switch (hint) { case QMetaType::Bool: if (type == Object && object->inherits(&BooleanObject::info)) ret = QVariant(asBooleanObject(value)->internalValue().toBoolean(exec)); else ret = QVariant(value.toBoolean(exec)); if (type == Boolean) dist = 0; else dist = 10; break; case QMetaType::Int: case QMetaType::UInt: case QMetaType::Long: case QMetaType::ULong: case QMetaType::LongLong: case QMetaType::ULongLong: case QMetaType::Short: case QMetaType::UShort: case QMetaType::Float: case QMetaType::Double: ret = QVariant(value.toNumber(exec)); ret.convert((QVariant::Type)hint); if (type == Number) { switch (hint) { case QMetaType::Double: dist = 0; break; case QMetaType::Float: dist = 1; break; case QMetaType::LongLong: case QMetaType::ULongLong: dist = 2; break; case QMetaType::Long: case QMetaType::ULong: dist = 3; break; case QMetaType::Int: case QMetaType::UInt: dist = 4; break; case QMetaType::Short: case QMetaType::UShort: dist = 5; break; break; default: dist = 10; break; } } else { dist = 10; } break; case QMetaType::QChar: if (type == Number || type == Boolean) { ret = QVariant(QChar((ushort)value.toNumber(exec))); if (type == Boolean) dist = 3; else dist = 6; } else { UString str = value.toString(exec); ret = QVariant(QChar(str.size() ? *(const ushort*)str.rep()->data() : 0)); if (type == String) dist = 3; else dist = 10; } break; case QMetaType::QString: { if (value.isUndefinedOrNull()) { if (distance) *distance = 1; return QString(); } else { UString ustring = value.toString(exec); ret = QVariant(QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size())); if (type == String) dist = 0; else dist = 10; } break; } case QMetaType::QVariantMap: if (type == Object || type == Array || type == RTArray) { // Enumerate the contents of the object PropertyNameArray properties(exec); object->getPropertyNames(exec, properties); PropertyNameArray::const_iterator it = properties.begin(); QVariantMap result; int objdist = 0; while(it != properties.end()) { if (object->propertyIsEnumerable(exec, *it)) { JSValuePtr val = object->get(exec, *it); QVariant v = convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects); if (objdist >= 0) { UString ustring = (*it).ustring(); QString id = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); result.insert(id, v); } } ++it; } dist = 1; ret = QVariant(result); } break; case QMetaType::QVariantList: if (type == RTArray) { RuntimeArray* rtarray = static_cast<RuntimeArray*>(object); QVariantList result; int len = rtarray->getLength(); int objdist = 0; qConvDebug() << "converting a " << len << " length Array"; for (int i = 0; i < len; ++i) { JSValuePtr val = rtarray->getConcreteArray()->valueAt(exec, i); result.append(convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects)); if (objdist == -1) { qConvDebug() << "Failed converting element at index " << i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -