⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qt_runtime.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if ((m.name() == name)/* && (scope.isEmpty() || (m.scope() == scope))*/)            return i;    }    return -1;}// Helper function for resolving methods// Largely based on code in QtScript for compatibility reasonsstatic int findMethodIndex(ExecState* exec,                           const QMetaObject* meta,                           const QByteArray& signature,                           bool allowPrivate,                           const ArgList& jsArgs,                           QVarLengthArray<QVariant, 10> &vars,                           void** vvars,                           JSObject **pError){    QList<int> matchingIndices;    bool overloads = !signature.contains('(');    int count = meta->methodCount();    for (int i = count - 1; i >= 0; --i) {        const QMetaMethod m = meta->method(i);        // Don't choose private methods        if (m.access() == QMetaMethod::Private && !allowPrivate)            continue;        // try and find all matching named methods        if (m.signature() == signature)            matchingIndices.append(i);        else if (overloads) {            QByteArray rawsignature = m.signature();            rawsignature.truncate(rawsignature.indexOf('('));            if (rawsignature == signature)                matchingIndices.append(i);        }    }    int chosenIndex = -1;    *pError = 0;    QVector<QtMethodMatchType> chosenTypes;    QVarLengthArray<QVariant, 10> args;    QVector<QtMethodMatchData> candidates;    QVector<QtMethodMatchData> unresolved;    QVector<int> tooFewArgs;    QVector<int> conversionFailed;    foreach(int index, matchingIndices) {        QMetaMethod method = meta->method(index);        QVector<QtMethodMatchType> types;        bool unresolvedTypes = false;        // resolve return type        QByteArray returnTypeName = method.typeName();        int rtype = QMetaType::type(returnTypeName);        if ((rtype == 0) && !returnTypeName.isEmpty()) {            if (returnTypeName == "QVariant") {                types.append(QtMethodMatchType::variant());            } else if (returnTypeName.endsWith('*')) {                types.append(QtMethodMatchType::metaType(QMetaType::VoidStar, returnTypeName));            } else {                int enumIndex = indexOfMetaEnum(meta, returnTypeName);                if (enumIndex != -1)                    types.append(QtMethodMatchType::metaEnum(enumIndex, returnTypeName));                else {                    unresolvedTypes = true;                    types.append(QtMethodMatchType::unresolved(returnTypeName));                }            }        } else {            if (returnTypeName == "QVariant")                types.append(QtMethodMatchType::variant());            else                types.append(QtMethodMatchType::metaType(rtype, returnTypeName));        }        // resolve argument types        QList<QByteArray> parameterTypeNames = method.parameterTypes();        for (int i = 0; i < parameterTypeNames.count(); ++i) {            QByteArray argTypeName = parameterTypeNames.at(i);            int atype = QMetaType::type(argTypeName);            if (atype == 0) {                if (argTypeName == "QVariant") {                    types.append(QtMethodMatchType::variant());                } else {                    int enumIndex = indexOfMetaEnum(meta, argTypeName);                    if (enumIndex != -1)                        types.append(QtMethodMatchType::metaEnum(enumIndex, argTypeName));                    else {                        unresolvedTypes = true;                        types.append(QtMethodMatchType::unresolved(argTypeName));                    }                }            } else {                if (argTypeName == "QVariant")                    types.append(QtMethodMatchType::variant());                else                    types.append(QtMethodMatchType::metaType(atype, argTypeName));            }        }        // If the native method requires more arguments than what was passed from JavaScript        if (jsArgs.size() < (types.count() - 1)) {            qMatchDebug() << "Match:too few args for" << method.signature();            tooFewArgs.append(index);            continue;        }        if (unresolvedTypes) {            qMatchDebug() << "Match:unresolved arg types for" << method.signature();            // remember it so we can give an error message later, if necessary            unresolved.append(QtMethodMatchData(/*matchDistance=*/INT_MAX, index,                                                   types, QVarLengthArray<QVariant, 10>()));            continue;        }        // Now convert arguments        if (args.count() != types.count())            args.resize(types.count());        QtMethodMatchType retType = types[0];        args[0] = QVariant(retType.typeId(), (void *)0); // the return value        bool converted = true;        int matchDistance = 0;        for (int i = 0; converted && i < types.count() - 1; ++i) {            JSValuePtr arg = i < jsArgs.size() ? jsArgs.at(exec, i) : jsUndefined();            int argdistance = -1;            QVariant v = convertValueToQVariant(exec, arg, types.at(i+1).typeId(), &argdistance);            if (argdistance >= 0) {                matchDistance += argdistance;                args[i+1] = v;            } else {                qMatchDebug() << "failed to convert argument " << i << "type" << types.at(i+1).typeId() << QMetaType::typeName(types.at(i+1).typeId());                converted = false;            }        }        qMatchDebug() << "Match: " << method.signature() << (converted ? "converted":"failed to convert") << "distance " << matchDistance;        if (converted) {            if ((jsArgs.size() == types.count() - 1)                && (matchDistance == 0)) {                // perfect match, use this one                chosenIndex = index;                break;            } else {                QtMethodMatchData currentMatch(matchDistance, index, types, args);                if (candidates.isEmpty()) {                    candidates.append(currentMatch);                } else {                    QtMethodMatchData bestMatchSoFar = candidates.at(0);                    if ((args.count() > bestMatchSoFar.args.count())                        || ((args.count() == bestMatchSoFar.args.count())                            && (matchDistance <= bestMatchSoFar.matchDistance))) {                        candidates.prepend(currentMatch);                    } else {                        candidates.append(currentMatch);                    }                }            }        } else {            conversionFailed.append(index);        }        if (!overloads)            break;    }    if (chosenIndex == -1 && candidates.count() == 0) {        // No valid functions at all - format an error message        if (!conversionFailed.isEmpty()) {            QString message = QString::fromLatin1("incompatible type of argument(s) in call to %0(); candidates were\n")                              .arg(QLatin1String(signature));            for (int i = 0; i < conversionFailed.size(); ++i) {                if (i > 0)                    message += QLatin1String("\n");                QMetaMethod mtd = meta->method(conversionFailed.at(i));                message += QString::fromLatin1("    %0").arg(QString::fromLatin1(mtd.signature()));            }            *pError = throwError(exec, TypeError, message.toLatin1().constData());        } else if (!unresolved.isEmpty()) {            QtMethodMatchData argsInstance = unresolved.first();            int unresolvedIndex = argsInstance.firstUnresolvedIndex();            Q_ASSERT(unresolvedIndex != -1);            QtMethodMatchType unresolvedType = argsInstance.types.at(unresolvedIndex);            QString message = QString::fromLatin1("cannot call %0(): unknown type `%1'")                .arg(QString::fromLatin1(signature))                .arg(QLatin1String(unresolvedType.name()));            *pError = throwError(exec, TypeError, message.toLatin1().constData());        } else {            QString message = QString::fromLatin1("too few arguments in call to %0(); candidates are\n")                              .arg(QLatin1String(signature));            for (int i = 0; i < tooFewArgs.size(); ++i) {                if (i > 0)                    message += QLatin1String("\n");                QMetaMethod mtd = meta->method(tooFewArgs.at(i));                message += QString::fromLatin1("    %0").arg(QString::fromLatin1(mtd.signature()));            }            *pError = throwError(exec, SyntaxError, message.toLatin1().constData());        }    }    if (chosenIndex == -1 && candidates.count() > 0) {        QtMethodMatchData bestMatch = candidates.at(0);        if ((candidates.size() > 1)            && (bestMatch.args.count() == candidates.at(1).args.count())            && (bestMatch.matchDistance == candidates.at(1).matchDistance)) {            // ambiguous call            QString message = QString::fromLatin1("ambiguous call of overloaded function %0(); candidates were\n")                                .arg(QLatin1String(signature));            for (int i = 0; i < candidates.size(); ++i) {                // Only candidate for overload if argument count and match distance is same as best match                if (candidates.at(i).args.count() == bestMatch.args.count()                    || candidates.at(i).matchDistance == bestMatch.matchDistance) {                    if (i > 0)                        message += QLatin1String("\n");                    QMetaMethod mtd = meta->method(candidates.at(i).index);                    message += QString::fromLatin1("    %0").arg(QString::fromLatin1(mtd.signature()));                }            }            *pError = throwError(exec, TypeError, message.toLatin1().constData());        } else {            chosenIndex = bestMatch.index;            args = bestMatch.args;        }    }    if (chosenIndex != -1) {        /* Copy the stuff over */        int i;        vars.resize(args.count());        for (i=0; i < args.count(); i++) {            vars[i] = args[i];            vvars[i] = vars[i].data();        }    }    return chosenIndex;}// Signals are not fuzzy matched as much as methodsstatic int findSignalIndex(const QMetaObject* meta, int initialIndex, QByteArray signature){    int index = initialIndex;    QMetaMethod method = meta->method(index);    bool overloads = !signature.contains('(');    if (overloads && (method.attributes() & QMetaMethod::Cloned)) {        // find the most general method        do {            method = meta->method(--index);        } while (method.attributes() & QMetaMethod::Cloned);    }    return index;}QtRuntimeMetaMethod::QtRuntimeMetaMethod(ExecState* exec, const Identifier& ident, PassRefPtr<QtInstance> inst, int index, const QByteArray& signature, bool allowPrivate)    : QtRuntimeMethod (new QtRuntimeMetaMethodData(), exec, ident, inst){    QW_D(QtRuntimeMetaMethod);    d->m_signature = signature;    d->m_index = index;    d->m_connect = 0;    d->m_disconnect = 0;    d->m_allowPrivate = allowPrivate;}void QtRuntimeMetaMethod::mark(){    QtRuntimeMethod::mark();    QW_D(QtRuntimeMetaMethod);    if (d->m_connect)        d->m_connect->mark();    if (d->m_disconnect)        d->m_disconnect->mark();}JSValuePtr QtRuntimeMetaMethod::call(ExecState* exec, JSObject* functionObject, JSValuePtr thisValue, const ArgList& args){    QtRuntimeMetaMethodData* d = static_cast<QtRuntimeMetaMethod *>(functionObject)->d_func();    // We're limited to 10 args    if (args.size() > 10)        return jsUndefined();    // We have to pick a method that matches..    JSLock lock(false);    QObject *obj = d->m_instance->getObject();    if (obj) {        QVarLengthArray<QVariant, 10> vargs;        void *qargs[11];        int methodIndex;        JSObject* errorObj = 0;        if ((methodIndex = findMethodIndex(exec, obj->metaObject(), d->m_signature, d->m_allowPrivate, args, vargs, (void **)qargs, &errorObj)) != -1) {            if (obj->qt_metacall(QMetaObject::InvokeMetaMethod, methodIndex, qargs) >= 0)                return jsUndefined();            if (vargs[0].isValid())                return convertQVariantToValue(exec, d->m_instance->rootObject(), vargs[0]);        }        if (errorObj)            return errorObj;    } else {        return throwError(exec, GeneralError, "cannot call function of deleted QObject");    }    // void functions return undefined    return jsUndefined();}CallType QtRuntimeMetaMethod::getCallData(CallData& callData){    callData.native.function = call;    return CallTypeHost;}bool QtRuntimeMetaMethod::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot){    if (propertyName == "connect") {        slot.setCustom(this, connectGetter);        return true;    } else if (propertyName == "disconnect") {        slot.setCustom(this, disconnectGetter);        return true;    } else if (propertyName == exec->propertyNames().length) {        slot.setCustom(this, lengthGetter);        return true;    }    return QtRuntimeMethod::getOwnPropertySlot(exec, propertyName, slot);}JSValuePtr QtRuntimeMetaMethod::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot&){    // QtScript always returns 0    return jsNumber(exec, 0);}JSValuePtr QtRuntimeMetaMethod::connectGetter(ExecState* exec, const Identifier& ident, const PropertySlot& slot){    QtRuntimeMetaMethod* thisObj = static_cast<QtRuntimeMetaMethod*>(asObject(slot.slotBase()));    QW_DS(QtRuntimeMetaMethod, thisObj);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -