📄 qscriptengine_p.cpp
字号:
m_string_hash_size = DefaultHashSize; m_string_hash_base = new QScriptNameIdImpl* [m_string_hash_size]; memset(m_string_hash_base, 0, sizeof(QScriptNameIdImpl*) * m_string_hash_size); m_class_prev_id = QScript::CustomType; m_class_activation = registerClass(QLatin1String("activation"), QScript::ActivationType); m_class_boolean = registerClass(QLatin1String("boolean"), QScript::BooleanType); m_class_double = registerClass(QLatin1String("qsreal"), QScript::NumberType); m_class_function = registerClass(QLatin1String("Function"), QScript::FunctionType); m_class_int = registerClass(QLatin1String("integer"), QScript::IntegerType); m_class_null = registerClass(QLatin1String("null"), QScript::NullType); m_class_object = registerClass(QLatin1String("Object"), QScript::ObjectType); m_class_pointer = registerClass(QLatin1String("pointer"), QScript::PointerType); m_class_reference = registerClass(QLatin1String("reference"), QScript::ReferenceType); m_class_string = registerClass(QLatin1String("string"), QScript::StringType); m_class_undefined = registerClass(QLatin1String("undefined"), QScript::UndefinedType); m_class_variant = registerClass(QLatin1String("variant"), QScript::VariantType); m_class_qobject = registerClass(QLatin1String("qobject"), QScript::QObjectType); m_class_qmetaobject = registerClass(QLatin1String("qmetaobject"), QScript::QMetaObjectType); m_class_arguments = registerClass(QLatin1String("arguments"), QScript::ObjectType); QExplicitlySharedDataPointer<QScriptClassData> data2(new QScript::ArgumentsClassData()); m_class_arguments->setData(data2); m_class_with = registerClass(QLatin1String("__qscript_internal_with"), QScript::ObjectType); QExplicitlySharedDataPointer<QScriptClassData> data3(new QScript::WithClassData()); m_class_with->setData(data3); // public name ids m_id_table.id_constructor = nameId(QLatin1String("constructor"), true); m_id_table.id_false = nameId(QLatin1String("false"), true); m_id_table.id_null = nameId(QLatin1String("null"), true); m_id_table.id_object = nameId(QLatin1String("object"), true); m_id_table.id_pointer = nameId(QLatin1String("pointer"), true); m_id_table.id_prototype = nameId(QLatin1String("prototype"), true); m_id_table.id_arguments = nameId(QLatin1String("arguments"), true); m_id_table.id_this = nameId(QLatin1String("this"), true); m_id_table.id_toString = nameId(QLatin1String("toString"), true); m_id_table.id_true = nameId(QLatin1String("true"), true); m_id_table.id_undefined = nameId(QLatin1String("undefined"), true); m_id_table.id_valueOf = nameId(QLatin1String("valueOf"), true); m_id_table.id_length = nameId(QLatin1String("length"), true); m_id_table.id_callee = nameId(QLatin1String("callee"), true); m_id_table.id___proto__ = nameId(QLatin1String("__proto__"), true); m_id_table.id___fileName__ = nameId(QLatin1String("__fileName__"), true); m_id_table.id___qt_sender__ = nameId(QLatin1String("__qt_sender__"), true); const int TEMP_STACK_SIZE = 10 * 1024; tempStackBegin = new QScriptValueImpl[TEMP_STACK_SIZE]; tempStackEnd = tempStackBegin + TEMP_STACK_SIZE; newUndefined(&tempStackBegin[0]); objectAllocator.blockGC(true); // GC requires that GlobalObject is the first object created QScript::Ecma::Global::construct(&m_globalObject, this); // create the prototypes first... objectConstructor = new QScript::Ecma::Object(this, m_class_object); functionConstructor = new QScript::Ecma::Function(this, m_class_function); // ... then we can initialize functionConstructor->initialize(); objectConstructor->initialize(); numberConstructor = new QScript::Ecma::Number(this); booleanConstructor = new QScript::Ecma::Boolean(this); stringConstructor = new QScript::Ecma::String(this); dateConstructor = new QScript::Ecma::Date(this); arrayConstructor = new QScript::Ecma::Array(this); regexpConstructor = new QScript::Ecma::RegExp(this); errorConstructor = new QScript::Ecma::Error(this); QScript::Ecma::Global::initialize(&m_globalObject, this); const QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration; m_globalObject.setProperty(QLatin1String("Object"), objectConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("Function"), functionConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("Number"), numberConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("Boolean"), booleanConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("String"), stringConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("Date"), dateConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("Array"), arrayConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("RegExp"), regexpConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("Error"), errorConstructor->ctor, flags); m_globalObject.setProperty(QLatin1String("EvalError"), errorConstructor->evalErrorCtor, flags); m_globalObject.setProperty(QLatin1String("RangeError"), errorConstructor->rangeErrorCtor, flags); m_globalObject.setProperty(QLatin1String("ReferenceError"), errorConstructor->referenceErrorCtor, flags); m_globalObject.setProperty(QLatin1String("SyntaxError"), errorConstructor->syntaxErrorCtor, flags); m_globalObject.setProperty(QLatin1String("TypeError"), errorConstructor->typeErrorCtor, flags); m_globalObject.setProperty(QLatin1String("URIError"), errorConstructor->uriErrorCtor, flags); QScriptValueImpl tmp; // ### fixme m_evalFunction = new QScript::EvalFunction(this); functionConstructor->newFunction(&tmp, m_evalFunction); m_globalObject.setProperty(QLatin1String("eval"), tmp, flags); QScriptValueImpl mathObject; QScript::Ecma::Math::construct(&mathObject, this); m_globalObject.setProperty(QLatin1String("Math"), mathObject, flags); enumerationConstructor = new QScript::Ext::Enumeration(this); m_globalObject.setProperty(QLatin1String("Enumeration"), enumerationConstructor->ctor, flags); variantConstructor = new QScript::Ext::Variant(this, m_class_variant); m_globalObject.setProperty(QLatin1String("Variant"), variantConstructor->ctor, flags);#ifndef QT_NO_QOBJECT qobjectConstructor = new QScript::ExtQObject(this, m_class_qobject); m_globalObject.setProperty(QLatin1String("QObject"), qobjectConstructor->ctor, flags); qmetaObjectConstructor = new QScript::ExtQMetaObject(this, m_class_qmetaobject); m_globalObject.setProperty(QLatin1String("QMetaObject"), qmetaObjectConstructor->ctor, flags);#endif objectAllocator.blockGC(false); QScriptContext *context = pushContext(); QScriptContextPrivate *context_p = QScriptContextPrivate::get(context); context_p->setActivationObject(m_globalObject); context_p->setThisObject(m_globalObject);}#if !defined(QT_NO_QOBJECT) && !defined(QT_NO_LIBRARY)static QScriptValueImpl __setupPackage__(QScriptContextPrivate *ctx, QScriptEnginePrivate *eng, QScriptClassInfo *){ QString path = ctx->argument(0).toString(); QStringList components = path.split(QLatin1Char('.')); QScriptValueImpl o = eng->globalObject(); for (int i = 0; i < components.count(); ++i) { QString name = components.at(i); QScriptValueImpl oo = o.property(name); if (!oo.isValid()) { oo = eng->newObject(); o.setProperty(name, oo); } o = oo; } return o;}#endifQScriptValueImpl QScriptEnginePrivate::importExtension(const QString &extension){#if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) Q_UNUSED(extension);#else Q_Q(QScriptEngine); if (m_importedExtensions.contains(extension)) return undefinedValue(); // already imported QScriptContextPrivate *context = QScriptContextPrivate::get(currentContext()); QCoreApplication *app = QCoreApplication::instance(); if (!app) return context->throwError(QLatin1String("No application object")); QStringList libraryPaths = app->libraryPaths(); QString dot = QLatin1String("."); QStringList pathComponents = extension.split(dot); QString dotJs = QLatin1String(".js"); QString initDotJs = QLatin1String("__init__.js"); QString ext; for (int i = 0; i < pathComponents.count(); ++i) { if (!ext.isEmpty()) ext.append(dot); ext.append(pathComponents.at(i)); if (m_importedExtensions.contains(ext)) continue; // already imported if (m_extensionsBeingImported.contains(ext)) { return context->throwError(QString::fromLatin1("recursive import of %0") .arg(extension)); } m_extensionsBeingImported.insert(ext); // look for the extension in library paths bool loaded = false; for (int j = 0; j < libraryPaths.count(); ++j) { QString libPath = libraryPaths.at(j) + QDir::separator() + QLatin1String("script"); QDir dir(libPath); if (!dir.exists(dot)) continue; // look for C++ plugin QScriptExtensionInterface *iface = 0; QFileInfoList files = dir.entryInfoList(QDir::Files); for (int k = 0; k < files.count(); ++k) { QFileInfo entry = files.at(k); QString filePath = entry.canonicalFilePath(); QPluginLoader loader(filePath); iface = qobject_cast<QScriptExtensionInterface*>(loader.instance()); if (iface) { if (iface->keys().contains(ext)) break; // use this one else iface = 0; // keep looking } } // look for __init__.js in the corresponding dir QDir dirdir(libPath); bool dirExists = dirdir.exists(); for (int k = 0; dirExists && (k <= i); ++k) dirExists = dirdir.cd(pathComponents.at(k)); QString initjsContents; QString initjsFileName; if (dirExists && dirdir.exists(initDotJs)) { QFile file(dirdir.canonicalPath() + QDir::separator() + initDotJs); if (file.open(QIODevice::ReadOnly)) { QTextStream ts(&file); initjsContents = ts.readAll(); initjsFileName = file.fileName(); file.close(); } } if (!iface && initjsContents.isEmpty()) continue; // initialize the extension in a new context QScriptContext *ctx = pushContext(); QScriptContextPrivate *ctx_p = QScriptContextPrivate::get(ctx); ctx_p->setThisObject(globalObject()); newActivation(&ctx_p->m_activation); QScriptObject *activation_data = ctx_p->m_activation.m_object_value; activation_data->m_scope = globalObject(); activation_data->m_members.resize(4); activation_data->m_objects.resize(4); activation_data->m_members[0].object( nameId(QLatin1String("__extension__")), 0, QScriptValue::ReadOnly | QScriptValue::Undeletable); activation_data->m_objects[0] = QScriptValueImpl(this, ext); activation_data->m_members[1].object( nameId(QLatin1String("__setupPackage__")), 1, 0); activation_data->m_objects[1] = createFunction(__setupPackage__, 0, 0); activation_data->m_members[2].object( nameId(QLatin1String("__all__")), 2, 0); activation_data->m_objects[2] = undefinedValue(); activation_data->m_members[3].object( nameId(QLatin1String("__postInit__")), 3, 0); activation_data->m_objects[3] = undefinedValue(); // the script is evaluated first if (!initjsContents.isEmpty()) { evaluate(ctx_p, initjsContents, 0, initjsFileName); if (hasUncaughtException()) { QScriptValueImpl r = ctx_p->returnValue(); popContext(); return r; } } // next, the C++ plugin is called if (iface) { iface->initialize(ext, q); if (hasUncaughtException()) { QScriptValueImpl r = ctx_p->returnValue(); popContext(); return r; } } // if the __postInit__ function has been set, we call it QScriptValueImpl postInit = ctx_p->m_activation.property(QLatin1String("__postInit__")); if (postInit.isFunction()) { postInit.call(globalObject()); if (hasUncaughtException()) { QScriptValueImpl r = ctx_p->returnValue(); popContext(); return r; } } popContext(); m_importedExtensions.insert(ext); m_extensionsBeingImported.remove(ext); loaded = true; break; } // for (j) if (!loaded) { return context->throwError( QString::fromLatin1("Unable to import %0: no such extension") .arg(extension)); } } // for (i)#endif // QT_NO_QOBJECT return undefinedValue();}void QScriptEnginePrivate::gc(){ if (!objectAllocator.blocked()) { // do the GC now maybeGC_helper(/*do_string_gc=*/true); } else { // GC will be performed the next time maybeGC() // is called and the allocator is not blocked objectAllocator.requestGC(); }}QStringList QScriptEnginePrivate::uncaughtExceptionBacktrace() const{ QScriptValueImpl value = uncaughtException(); if (!value.isError()) return QStringList(); return QScript::Ecma::Error::backtrace(value);}void QScriptEnginePrivate::processEvents(){#ifndef QT_NO_QOBJECT if (m_nextProcessEvents < m_processEventTracker.elapsed()) { QCoreApplication::processEvents(); m_nextProcessEvents = m_nextProcessEvents + m_processEventsInterval; }#endif}void QScriptEnginePrivate::setupProcessEvents(){ if (m_processEventsInterval > 0) { m_nextProcessEvents = m_processEventsInterval; m_processEventTracker.restart(); }}#endif // QT_NO_SCRIPT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -