📄 qscriptengine_p.cpp
字号:
if (QScriptClassData *data = object.m_class->data()) data->mark(object, generation); if (instance->m_prototype.isObject()) markObject(instance->m_prototype, generation); if (instance->m_scope.isObject()) markObject(instance->m_scope, generation); const QScriptValueImpl &internalValue = instance->m_internalValue; if (internalValue.isValid()) { if (internalValue.isObject()) markObject(internalValue, generation); else if (internalValue.isString()) markString(internalValue.m_string_value, generation); } int garbage = 0; for (int i = 0; i < instance->memberCount(); ++i) { QScript::Member m; instance->member(i, &m); if (! m.isValid()) { ++garbage; continue; } Q_ASSERT(m.isObjectProperty()); QScriptValueImpl child; instance->get(m, &child); if (m.nameId()) markString(m.nameId(), generation); if (! child.isValid()) continue; else if (child.isObject()) markObject(child, generation); else if (child.isString()) markString(child.m_string_value, generation); } --m_gc_depth; if (garbage < 128) // ### return; int j = 0; for (int i = 0; i < instance->memberCount(); ++i) { QScript::Member m; instance->member(i, &m); if (! m.isValid()) continue; if (i != j) { instance->m_members[j].object(m.nameId(), j, m.flags()); instance->m_objects[j] = instance->m_objects[i]; } ++j; } //qDebug() << "==> old:" << instance->m_members.size() << "new:" << j; instance->m_members.resize(j); instance->m_objects.resize(j);}void QScriptEnginePrivate::markFrame(QScriptContextPrivate *context, int generation){ QScriptValueImpl activation = context->activationObject(); QScriptValueImpl thisObject = context->thisObject(); QScriptValueImpl scopeChain = context->m_scopeChain; QScriptValueImpl callee = context->m_callee; QScriptValueImpl arguments = context->m_arguments; if (activation.isObject()) markObject(activation, generation); if (scopeChain.isObject()) markObject(scopeChain, generation); if (thisObject.isObject()) markObject(thisObject, generation); if (callee.isObject()) markObject(callee, generation); if (arguments.isObject()) markObject(arguments, generation); if (context->returnValue().isValid()) { if (context->returnValue().isObject()) markObject(context->returnValue(), generation); else if (context->returnValue().isString()) markString(context->returnValue().m_string_value, generation); } if (context->baseStackPointer() != context->currentStackPointer()) { // mark the temp stack for (const QScriptValueImpl *it = context->baseStackPointer(); it != (context->currentStackPointer() + 1); ++it) { if (! it) { qWarning() << "no temp stack!!!"; break; } else if (! it->isValid()) // ### assert? continue; else if (it->isObject()) markObject(*it, generation); else if (it->isString()) markString(it->m_string_value, generation); } }}void QScriptEnginePrivate::maybeGC_helper(bool do_string_gc){ // qDebug() << "==>" << objectAllocator.newAllocatedBlocks() << "free:" << objectAllocator.freeBlocks(); Q_ASSERT(objectAllocator.head() == QScript::GCBlock::get(m_globalObject.objectValue())); m_gc_depth = 0; int generation = objectAllocator.generation(m_globalObject.objectValue()) + 1; markObject(m_globalObject, generation); { QHash<QScriptObject*, QScriptValuePrivate*>::const_iterator it; for (it = m_objectHandles.constBegin(); it != m_objectHandles.constEnd(); ++it) markObject((*it)->value, generation); } { QHash<QScriptNameIdImpl*, QScriptValuePrivate*>::const_iterator it; for (it = m_stringHandles.constBegin(); it != m_stringHandles.constEnd(); ++it) markString((*it)->value.stringValue(), generation); }#ifndef QT_NO_QOBJECT# ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE { QHash<const QMetaObject*, QScriptMetaObject*>::const_iterator it; for (it = m_cachedMetaObjects.constBegin(); it != m_cachedMetaObjects.constEnd(); ++it) { { QList<QScriptNameIdImpl*> memberNames = (*it)->registeredMemberNames(); QList<QScriptNameIdImpl*>::const_iterator it2; for (it2 = memberNames.constBegin(); it2 != memberNames.constEnd(); ++it2) markString(*it2, generation); } { QList<QScriptValueImpl> propertyAccessors = (*it)->registeredPropertyAccessors(); QList<QScriptValueImpl>::const_iterator it2; for (it2 = propertyAccessors.constBegin(); it2 != propertyAccessors.constEnd(); ++it2) markObject(*it2, generation); } } }# endif#endif { QScriptContext *current = currentContext(); while (current != 0) { markFrame (QScriptContextPrivate::get(current), generation); current = current->parentContext(); } } { QHash<int, QScriptCustomTypeInfo>::const_iterator it; for (it = m_customTypes.constBegin(); it != m_customTypes.constEnd(); ++it) (*it).prototype.mark(generation); } // mark the objects we couldn't process due to recursion depth while (!m_markStack.isEmpty()) markObject(m_markStack.takeLast(), generation); objectAllocator.sweep(generation); //qDebug() << "free blocks:" << objectAllocator.freeBlocks(); Q_ASSERT(objectAllocator.head() == QScript::GCBlock::get(m_globalObject.objectValue())); if (! do_string_gc) return;#if 0 qDebug() << "do_string_gc:" << do_string_gc << ((m_stringRepository.size() - m_oldStringRepositorySize) > 256) << ((m_tempStringRepository.size() - m_oldTempStringRepositorySize) > 2048);#endif QVector<QScriptNameIdImpl*> compressed; compressed.reserve(m_stringRepository.size()); for (int i = 0; i < m_stringRepository.size(); ++i) { QScriptNameIdImpl *entry = m_stringRepository.at(i); if (entry->used || entry->persistent) { compressed.append(entry); entry->used = false; } else { //qDebug() << "deleted unique:" << entry->s; delete entry; } } // qDebug() << "before:" << m_stringRepository.size() << "after:" << compressed.size() << globalObject.objectValue()->m_members.size(); m_stringRepository = compressed; rehashStringRepository(/*resize=*/ false); m_oldStringRepositorySize = m_stringRepository.size(); compressed.clear(); for (int i = 0; i < m_tempStringRepository.size(); ++i) { QScriptNameIdImpl *entry = m_tempStringRepository.at(i); if (entry->used || entry->persistent) { compressed.append(entry); entry->used = false; } else { //qDebug() << "deleted:" << entry->s; delete entry; } } //qDebug() << "before:" << m_tempStringRepository.size() << "after:" << compressed.size(); m_tempStringRepository = compressed; m_oldTempStringRepositorySize = m_tempStringRepository.size();}void QScriptEnginePrivate::evaluate(QScriptContextPrivate *context, const QString &contents, int lineNumber, const QString &fileName){ // ### try to remove cast QScript::EvalFunction *evalFunction = static_cast<QScript::EvalFunction*>(m_evalFunction); evalFunction->evaluate(context, contents, lineNumber, fileName, /*calledFromScript=*/ false);}qsreal QScriptEnginePrivate::convertToNativeDouble_helper(const QScriptValueImpl &object){ QScriptClassInfo *klass = object.m_class; Q_ASSERT(klass != 0); switch (klass->type()) { case QScript::UndefinedType: case QScript::PointerType: case QScript::FunctionType: break; case QScript::NullType: return 0; case QScript::BooleanType: return object.m_bool_value; case QScript::IntegerType: return object.m_int_value; case QScript::NumberType: return object.m_number_value; case QScript::StringType: return toNumber(toString(object.m_string_value)); default: { QScriptValueImpl p = toPrimitive(object, QScriptValueImpl::NumberTypeHint); if (! p.isValid() || p.isObject()) break; return convertToNativeDouble(p); } // default } // switch return SNaN();}bool QScriptEnginePrivate::convertToNativeBoolean_helper(const QScriptValueImpl &object){ Q_ASSERT (object.isValid()); QScriptClassInfo *klass = object.m_class; Q_ASSERT(klass != 0); switch (klass->type()) { case QScript::UndefinedType: case QScript::PointerType: case QScript::NullType: return false; case QScript::FunctionType: return true; case QScript::BooleanType: return object.m_bool_value; case QScript::IntegerType: return object.m_int_value != 0; case QScript::NumberType: return object.m_number_value != 0 && !isNaN(object.m_number_value); case QScript::StringType: return toString(object.m_string_value).length() != 0; case QScript::VariantType: { QScriptValueImpl p = toPrimitive(object, QScriptValueImpl::NumberTypeHint); if (! p.isValid() || p.isObject()) break; return convertToNativeBoolean(p); } default: if (object.isObject()) return true; break; } // switch return false;}QString QScriptEnginePrivate::convertToNativeString_helper(const QScriptValueImpl &object){ QScriptClassInfo *klass = object.m_class; Q_ASSERT(klass != 0); const QScript::IdTable *ids = idTable(); switch (klass->type()) { case QScript::UndefinedType: return toString(ids->id_undefined); case QScript::NullType: return toString(ids->id_null);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -