bool QScriptValueImpl::hasInstance(const QScriptValueImpl &value) const { Q_ASSERT(isObject()); if (QScriptClassData *odata = classInfo()->data()) { if (odata->implementsHasInstance(*this)) return odata->hasInstance(*this, value); } if (!isFunction()) return false; // [[HasInstance] for function objects if (!value.isObject()) return false; QScriptEnginePrivate *eng = engine(); QScriptValueImpl proto = property(eng->idTable()->id_prototype); if (!proto.isObject()) { QScriptContextPrivate *ctx = eng->currentContext(); ctx->throwTypeError(QLatin1String("instanceof: 'prototype' property is not an object")); return false; } QScriptObject *target = proto.m_object_value; QScriptValueImpl v = value; while (true) { v = v.prototype(); if (!v.isObject()) break; if (target == v.m_object_value) return true; } return false; }
QStringList Error::backtrace(const QScriptValueImpl &error) { QStringList result; QScriptValueImpl stack = error.property(QLatin1String("stack")); int frameCount = stack.property(QLatin1String("length")).toInt32(); for (int i = 0; i < frameCount; ++i) { QScriptValueImpl o = stack.property(i); QScriptValueImpl frame = o.property(QLatin1String("frame")); QString s; QString functionName = o.property(QLatin1String("functionName")).toString(); if (functionName.isEmpty()) { if (i == frameCount-1) s += QLatin1String("<global>"); else s += QLatin1String("<anonymous>"); } else { s += functionName; } s += QLatin1Char('('); QScriptValueImpl arguments = frame.property(QLatin1String("arguments")); if (arguments.isObject()) { int argCount = arguments.property(QLatin1String("length")).toInt32(); for (int j = 0; j < argCount; ++j) { if (j > 0) s += QLatin1Char(','); s += arguments.property(j).toString(); } } s += QLatin1String(")@") + o.property(QLatin1String("fileName")).toString() + QLatin1Char(':') + o.property(QLatin1String("lineNumber")).toString(); result.append(s); } return result; }
void QScriptValueIteratorImpl::setObject(const QScriptValueImpl &obj) { Q_ASSERT(obj.isObject()); m_object = obj; if (m_classDataIterator) { delete m_classDataIterator; m_classDataIterator = 0; } toFront(); }
QScriptValueImpl Object::method_isPrototypeOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) { bool result = false; if (context->thisObject().isObject() && (context->argumentCount() > 0)) { QScriptValueImpl arg = context->argument(0); if (arg.isObject()) { QScriptValueImpl proto = arg.prototype(); if (proto.isObject()) { QScriptValueImpl self = context->thisObject(); result = self.objectValue() == proto.objectValue(); } } } return (QScriptValueImpl(result)); }
QVariant QScriptValueImpl::toVariant() const { switch (m_type) { case QScript::InvalidType: return QVariant(); case QScript::UndefinedType: case QScript::NullType: case QScript::PointerType: case QScript::ReferenceType: break; case QScript::BooleanType: return QVariant(m_bool_value); case QScript::IntegerType: return QVariant(m_int_value); case QScript::NumberType: return QVariant(m_number_value); case QScript::StringType: return QVariant(m_string_value->s); case QScript::LazyStringType: return QVariant(*m_lazy_string_value); case QScript::ObjectType: if (isDate()) return QVariant(toDateTime()); #ifndef QT_NO_REGEXP if (isRegExp()) return QVariant(toRegExp()); #endif if (isVariant()) return variantValue(); #ifndef QT_NO_QOBJECT if (isQObject()) return qVariantFromValue(toQObject()); #endif QScriptValueImpl v = engine()->toPrimitive(*this); if (!v.isObject()) return v.toVariant(); break; } // switch return QVariant(); }
void Enumeration::newEnumeration(QScriptValueImpl *result, const QScriptValueImpl &object) { Instance *instance = new Instance(); instance->object = object; if (object.isObject()) { instance->it = new QScriptValueIteratorImpl(object); instance->it->setIgnoresDontEnum(false); instance->it->setEnumeratePrototype(true); } else { instance->it = 0; } engine()->newObject(result, publicPrototype, classInfo()); result->setObjectData(instance); }
QScriptValueIteratorImpl::QScriptValueIteratorImpl(const QScriptValueImpl &obj) { Q_ASSERT(obj.isObject()); m_frontObject = obj; m_member.invalidate(); m_foundMember.invalidate(); m_foundForward = false; m_object = obj; m_searchIndex = 0; m_searchClassDataIterator = false; m_classDataIterator = 0; m_ignoresDontEnum = true; m_enumerateProto = false; }
QScriptValueImpl Function::method_call(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { if (! context->thisObject().isFunction()) { return context->throwError(QScriptContext::TypeError, QLatin1String("Function.prototype.call")); } QScriptValueImpl thisObject = context->argument(0).toObject(); if (! (thisObject.isValid () && thisObject.isObject())) thisObject = eng->globalObject(); QScriptValueImplList args; for (int i = 1; i < context->argumentCount(); ++i) args << context->argument(i); return context->thisObject().call(thisObject, args); }
QScriptValueImpl Variant::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) { if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { QString result; QScriptValueImpl value = method_valueOf(context, eng, classInfo); if (value.isObject()) { result = instance->value.toString(); if (result.isEmpty()) { result = QString::fromLatin1("QVariant(%0)") .arg(QLatin1String(instance->value.typeName())); } } else { result = value.toString(); } return QScriptValueImpl(eng, result); } return context->throwError(QScriptContext::TypeError, QLatin1String("QVariant.prototype.toString")); }
/*! \internal \since 4.5 Returns the scope chain of this QScriptContext. */ QScriptValueList QScriptContext::scopeChain() const { Q_D(const QScriptContext); // make sure arguments properties are initialized const QScriptContextPrivate *ctx = d; while (ctx) { (void)ctx->activationObject(); ctx = ctx->previous; } QScriptValueList result; QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine()); QScriptValueImpl scope = d->m_scopeChain; while (scope.isObject()) { if (scope.classInfo() == eng_p->m_class_with) result.append(eng_p->toPublic(scope.prototype())); else result.append(eng_p->toPublic(scope)); scope = scope.scope(); } return result; }
QScriptValueImpl Function::method_apply(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { if (! context->thisObject().isFunction()) { return context->throwError(QScriptContext::TypeError, QLatin1String("Function.prototype.apply")); } QScriptValueImpl thisObject = context->argument(0).toObject(); if (! (thisObject.isValid () && thisObject.isObject())) thisObject = eng->globalObject(); QScriptValueImplList args; QScriptValueImpl undefined = eng->undefinedValue(); QScriptValueImpl arg = context->argument(1); if (Ecma::Array::Instance *arr = eng->arrayConstructor->get(arg)) { QScript::Array actuals = arr->value; for (quint32 i = 0; i < actuals.count(); ++i) { QScriptValueImpl a = actuals.at(i); if (! a.isValid()) args << undefined; else args << a; } } else if (arg.classInfo() == eng->m_class_arguments) { QScript::ArgumentsObjectData *arguments; arguments = static_cast<QScript::ArgumentsObjectData*> (arg.objectData()); QScriptObject *activation = arguments->activation.objectValue(); for (uint i = 0; i < arguments->length; ++i) args << activation->m_objects[i]; } else if (!(arg.isUndefined() || arg.isNull())) { return context->throwError(QScriptContext::TypeError, QLatin1String("Function.prototype.apply: second argument is not an array")); } return context->thisObject().call(thisObject, args); }
bool QScriptValueImpl::instanceOf(const QScriptValueImpl &value) const { if (! isObject() || ! value.isObject() || !value.implementsHasInstance()) return false; return value.hasInstance(*this); }
QDebug &operator<<(QDebug &d, const QScriptValueImpl &object) { d.nospace() << "QScriptValue("; switch (object.type()) { case QScript::InvalidType: d.nospace() << "Invalid)"; return d; case QScript::BooleanType: d.nospace() << "bool=" << object.toBoolean(); break; case QScript::IntegerType: d.nospace() << "int=" << object.toInt32(); break; case QScript::NumberType: d.nospace() << "qsreal=" << object.toNumber(); break; case QScript::LazyStringType: case QScript::StringType: d.nospace() << "string=" << object.toString(); break; case QScript::ReferenceType: d.nospace() << "reference"; break; case QScript::NullType: d.nospace() << "null"; break; case QScript::UndefinedType: d.nospace() << "undefined"; break; case QScript::PointerType: d.nospace() << "pointer"; break; case QScript::ObjectType: d.nospace() << object.classInfo()->name() << ",{"; QScriptObject *od = object.objectValue(); for (int i=0; i<od->memberCount(); ++i) { if (i != 0) d << ","; QScript::Member m; od->member(i, &m); if (m.isValid() && m.isObjectProperty()) { d << object.engine()->toString(m.nameId()); QScriptValueImpl o; od->get(m, &o); d.nospace() << QLatin1String(":") << (o.classInfo() ? o.classInfo()->name() : QLatin1String("?")); } } d.nospace() << "} scope={"; QScriptValueImpl scope = object.scope(); while (scope.isValid()) { Q_ASSERT(scope.isObject()); d.nospace() << " " << scope.objectValue(); scope = scope.scope(); } d.nospace() << "}"; break; } d << ")"; return d; }