QScriptValueImpl Object::method_propertyIsEnumerable(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { bool result = false; if (context->thisObject().isObject() && (context->argumentCount() > 0)) { QScriptValueImpl arg = context->argument(0); QScriptNameIdImpl *id = 0; if (arg.isString()) id = arg.stringValue(); if (! id || ! id->unique) { QString str = arg.toString(); id = eng->nameId(str); } QScript::Member member; QScriptValueImpl base; QScriptValueImpl self = context->thisObject(); if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) { result = ! member.dontEnum(); if (result) { QScriptValueImpl tmp; base.get(member, &tmp); result = tmp.isValid(); } } } return (QScriptValueImpl(result)); }
QScriptValueImpl Error::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { QScriptValueImpl name = context->thisObject().property(QLatin1String("name"), QScriptValue::ResolvePrototype); QScriptValueImpl message = context->thisObject().property(QLatin1String("message"), QScriptValue::ResolvePrototype); QString result = QLatin1String(""); if (name.isValid()) result = name.toString(); if (message.isValid()) { QString str = message.toString(); if (!str.isEmpty()) { if (!result.isEmpty()) result += QLatin1String(": "); result += str; } } return (QScriptValueImpl(eng, result)); }
void EnumerationClassData::mark(const QScriptValueImpl &object, int generation) { Q_ASSERT(object.isValid()); QScriptEnginePrivate *eng = object.engine(); if (Enumeration::Instance *instance = Enumeration::Instance::get(object, classInfo())) { eng->markObject(instance->object, generation); if (instance->it) eng->markObject(instance->it->object(), generation); } }
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); }
QScriptValueImpl RegExp::method_exec(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) { QScriptValueImpl self = context->thisObject(); if (self.classInfo() != classInfo) { return throwThisObjectTypeError( context, QLatin1String("RegExp.prototype.exec")); } Instance *rx_data = Instance::get(self, classInfo); Q_ASSERT(rx_data != 0); QString S = context->argument(0).toString(); int length = S.length(); QScriptValueImpl lastIndex = self.property(QLatin1String("lastIndex")); int i = lastIndex.isValid() ? int (lastIndex.toInteger()) : 0; bool global = self.property(QLatin1String("global")).toBoolean(); if (! global) i = 0; if (i < 0 || i >= length) return (eng->nullValue()); #ifndef QT_NO_REGEXP int index = rx_data->value.indexIn(S, i); if (index == -1) #endif // QT_NO_REGEXP return eng->nullValue(); #ifndef QT_NO_REGEXP int e = index + rx_data->value.matchedLength(); if (global) self.setProperty(QLatin1String("lastIndex"), QScriptValueImpl(e)); QScript::Array elts(eng); QStringList capturedTexts = rx_data->value.capturedTexts(); for (int i = 0; i < capturedTexts.count(); ++i) elts.assign(i, QScriptValueImpl(eng, capturedTexts.at(i))); QScriptValueImpl r = eng->newArray(elts); r.setProperty(QLatin1String("index"), QScriptValueImpl(index)); r.setProperty(QLatin1String("input"), QScriptValueImpl(eng, S)); return r; #endif // QT_NO_REGEXP }
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); }
void Object::execute(QScriptContextPrivate *context) { #ifndef Q_SCRIPT_NO_EVENT_NOTIFY engine()->notifyFunctionEntry(context); #endif QScriptValueImpl value; if (context->argumentCount() > 0) value = engine()->toObject(context->argument(0)); else value.invalidate(); if (! value.isValid()) newObject(&value); context->setReturnValue(value); #ifndef Q_SCRIPT_NO_EVENT_NOTIFY engine()->notifyFunctionExit(context); #endif }
/*! Returns true if there is at least one item behind the iterator (i.e. the iterator is \e not at the front of the property sequence); otherwise returns false. \sa previous(), hasNext() */ bool QScriptValueIterator::hasPrevious() const { Q_D(const QScriptValueIterator); if ((d->nextIndex != -1) && !d->forward) return true; if (!d->object.isObject()) return false; QScriptValueImpl v = QScriptValuePrivate::valueOf(d->object); int i = d->index; if ((i != -1) && d->forward) ++i; bool found = false; while (! found && --i >= 0) { QScript::Member member; v.member(i, &member); found = member.isValid(); if (found) { QScriptValueImpl vv; v.get(member, &vv); found = vv.isValid(); } } QScriptValueIteratorPrivate *that; that = const_cast<QScriptValueIteratorPrivate*>(d); if (found) { that->forward = false; that->nextIndex = i; return true; } else { that->nextIndex = -1; return false; } }
/*! Returns true if there is at least one item ahead of the iterator (i.e. the iterator is \e not at the back of the property sequence); otherwise returns false. \sa next(), hasPrevious() */ bool QScriptValueIterator::hasNext() const { Q_D(const QScriptValueIterator); if ((d->nextIndex != -1) && d->forward) return true; if (!d->object.isObject()) return false; QScriptValueImpl v = QScriptValuePrivate::valueOf(d->object); int i = d->index; if ((i != -1) && !d->forward) --i; int count = v.memberCount(); bool found = false; while (! found && ++i < count) { QScript::Member member; v.member(i, &member); found = member.isValid(); if (found && (member.isObjectProperty() || v.isArray())) { QScriptValueImpl vv; v.get(member, &vv); found = vv.isValid(); } } QScriptValueIteratorPrivate *that; that = const_cast<QScriptValueIteratorPrivate*>(d); if (found) { that->forward = true; that->nextIndex = i; return true; } else { that->nextIndex = -1; return false; } }
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; }
void QScriptValueImpl::setProperty(QScriptNameIdImpl *nameId, const QScriptValueImpl &value, const QScriptValue::PropertyFlags &flags) { if (!isObject()) return; QScriptValueImpl base; QScript::Member member; QScriptValue::ResolveFlags mode = QScriptValue::ResolveLocal; // if we are not setting a setter or getter, look in prototype too if (!(flags & (QScriptValue::PropertyGetter | QScriptValue::PropertySetter))) mode |= QScriptValue::ResolvePrototype; if (resolve(nameId, &member, &base, mode, QScript::ReadWrite)) { // we resolved an existing property with that name if (flags & (QScriptValue::PropertyGetter | QScriptValue::PropertySetter)) { // setting the getter or setter of a property in this object if (member.isNativeProperty()) { if (value.isValid()) { qWarning("QScriptValue::setProperty() failed: " "cannot set getter or setter of native property `%s'", qPrintable(nameId->s)); } return; } if (member.isSetter()) { // the property we resolved is a setter if (!(flags & QScriptValue::PropertySetter) && !member.isGetter()) { // find the getter, if not, create one if (!m_object_value->findGetter(&member)) { if (!value.isValid()) return; // don't create property for invalid value createMember(nameId, &member, flags); } } } else if (member.isGetter()) { // the property we resolved is a getter if (!(flags & QScriptValue::PropertyGetter)) { // find the setter, if not, create one if (!m_object_value->findSetter(&member)) { if (!value.isValid()) return; // don't create property for invalid value createMember(nameId, &member, flags); } } } else { // the property is a normal property -- change the flags uint newFlags = flags & ~QScript::Member::InternalRange; newFlags |= QScript::Member::ObjectProperty; member.resetFlags(newFlags); base.m_object_value->m_members[member.id()].resetFlags(newFlags); } Q_ASSERT(member.isValid()); if (!value.isValid()) { // remove the property removeMember(member); return; } } else { // setting the value if (member.isGetterOrSetter()) { // call the setter QScriptValueImpl setter; if (member.isObjectProperty() && !member.isSetter()) { if (!base.m_object_value->findSetter(&member)) { qWarning("QScriptValue::setProperty() failed: " "property '%s' has a getter but no setter", qPrintable(nameId->s)); return; } } base.get(member, &setter); setter.call(*this, QScriptValueImplList() << value); return; } else { if (base.m_object_value != m_object_value) { if (!value.isValid()) return; // don't create property for invalid value createMember(nameId, &member, flags); base = *this; } else { if (!value.isValid()) { // remove the property removeMember(member); return; } } if (flags != QScriptValue::KeepExistingFlags) { // change flags if (member.isNativeProperty()) { qWarning("QScriptValue::setProperty(%s): " "cannot change flags of a native property", qPrintable(nameId->s)); } else { uint newFlags = member.flags() & QScript::Member::InternalRange; newFlags |= flags & ~QScript::Member::InternalRange; base.m_object_value->m_members[member.id()].resetFlags(newFlags); } } } } } else { // property does not exist if (!value.isValid()) return; // don't create property for invalid value createMember(nameId, &member, flags & ~QScript::Member::InternalRange); base = *this; } base.put(member, value); }