Esempio n. 1
0
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;
}
/*!
  If this QScriptValue is an object, sets the internal prototype
  (\c{__proto__} property) of this object to be \a prototype;
  otherwise does nothing.

  The internal prototype should not be confused with the public
  property with name "prototype"; the public prototype is usually
  only set on functions that act as constructors.

  \sa prototype(), isObject()
*/
void QScriptValue::setPrototype(const QScriptValue &prototype)
{
    if (!isObject())
        return;
    if (prototype.isValid() && (prototype.engine() != engine())) {
        qWarning("QScriptValue::setPrototype() failed: "
                 "cannot set a prototype created in "
                 "a different engine");
        return;
    }
    QScriptValueImpl self = QScriptValuePrivate::valueOf(*this);
    QScriptValueImpl was = self.prototype();
    self.setPrototype(QScriptValuePrivate::valueOf(prototype));
    if (self.detectedCycle()) {
        qWarning("QScriptValue::setPrototype() failed: "
                 "cyclic prototype value");
        self.setPrototype(was);
    }
}
Esempio n. 3
0
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));
}
Esempio n. 4
0
/*!
  \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;
}
bool QScriptValueIteratorImpl::hasNext()
{
    if (m_foundMember.isValid() && m_foundForward) {
        // we have the information about the next element already
        return true;
    }

    int idx, count;
    QScriptValueImpl obj = m_object;

    if (m_searchClassDataIterator) {
        Q_ASSERT(m_classDataIterator != 0);
        if (m_foundMember.isValid()) {
            // undo effect of hasPrevious()
            m_foundMember.invalidate();
            QScript::Member dummy;
            m_classDataIterator->next(&dummy);
        }
        goto LSearchClassData;
    }

    idx = m_searchIndex;
    if (m_foundMember.isValid()) {
        // undo effect of hasPrevious()
        m_foundMember.invalidate();
        ++idx;
    }

 LSearchObjectData:
    count = obj.memberCount();
    for (int i = idx; i < count; ++i) {
        QScript::Member m;
        obj.member(i, &m);
        if (acceptsMember(obj, m)) {
            m_foundObject = obj;
            m_foundMember = m;
            m_foundForward = true;
            m_searchIndex = i + 1;
            return true;
        }
    }

    if (!m_classDataIterator) {
        QScriptClassData *data = obj.classInfo()->data();
        if (!data)
            goto LNext;
        m_classDataIterator = data->newIterator(obj);
        if (!m_classDataIterator)
            goto LNext;
    }
    m_searchClassDataIterator = true;

 LSearchClassData:
    Q_ASSERT(m_classDataIterator != 0);
    while (m_classDataIterator->hasNext()) {
        QScript::Member m;
        m_classDataIterator->next(&m);
        if (acceptsMember(obj, m)) {
            m_foundObject = obj;
            m_foundMember = m;
            m_foundForward = true;
            return true;
        }
    }

 LNext:
    if (!m_enumerateProto || !obj.prototype().isObject())
        return false;

    // look in prototype
    obj = obj.prototype();
    idx = 0;
    if (m_classDataIterator) {
        delete m_classDataIterator;
        m_classDataIterator = 0;
        m_searchClassDataIterator = false;
    }
    goto LSearchObjectData;
}