bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object,
                                             JSC::ExecState *exec,
                                             const JSC::Identifier &propertyName,
                                             JSC::PropertySlot &slot)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    // for compatibility with the old back-end, normal JS properties
    // are queried first.
    if (QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot))
        return true;

    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
    if (flags & QScriptClass::HandlesReadAccess) {
        QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
        slot.setValue(engine->scriptValueToJSCValue(value));
        return true;
    }
    return false;
}
bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object,
                                             JSC::ExecState *exec,
                                             const JSC::Identifier &propertyName,
                                             JSC::PropertySlot &slot)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    // for compatibility with the old back-end, normal JS properties
    // are queried first.
    if (QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot))
        return true;

    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
    if (flags & QScriptClass::HandlesReadAccess) {
        QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
        if (!value.isValid()) {
            // The class claims to have the property, but returned an invalid
            // value. Silently convert to undefined to avoid the invalid value
            // "escaping" into JS.
            value = QScriptValue(QScriptValue::UndefinedValue);
        }
        slot.setValue(engine->scriptValueToJSCValue(value));
        return true;
    }
    return false;
}
Example #3
0
/*!
  \internal
  \since 4.5

  Adds the given \a object to the front of this context's scope chain.

  If \a object is not an object, this function does nothing.
*/
void QScriptContext::pushScope(const QScriptValue &object)
{
    activationObject(); //ensure the creation of the normal scope for native context
    if (!object.isObject())
        return;
    else if (object.engine() != engine()) {
        qWarning("QScriptContext::pushScope() failed: "
                 "cannot push an object created in "
                 "a different engine");
        return;
    }
    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
    QScript::APIShim shim(engine);
    JSC::JSObject *jscObject = JSC::asObject(engine->scriptValueToJSCValue(object));
    if (jscObject == engine->originalGlobalObjectProxy)
        jscObject = engine->originalGlobalObject();
    JSC::ScopeChainNode *scope = frame->scopeChain();
    Q_ASSERT(scope != 0);
    if (!scope->object) {
        // pushing to an "empty" chain
        if (!jscObject->isGlobalObject()) {
            qWarning("QScriptContext::pushScope() failed: initial object in scope chain has to be the Global Object");
            return;
        }
        scope->object = jscObject;
    }
    else
        frame->setScopeChain(scope->push(jscObject));
}
bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC::ExecState *exec,
                                                const JSC::Identifier &propertyName,
                                                unsigned &attribs) const
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
    if (flags & QScriptClass::HandlesReadAccess) {
        QScriptValue::PropertyFlags flags = m_scriptClass->propertyFlags(scriptObject, scriptName, id);
        attribs = 0;
        if (flags & QScriptValue::ReadOnly)
            attribs |= JSC::ReadOnly;
        if (flags & QScriptValue::SkipInEnumeration)
            attribs |= JSC::DontEnum;
        if (flags & QScriptValue::Undeletable)
            attribs |= JSC::DontDelete;
        if (flags & QScriptValue::PropertyGetter)
            attribs |= JSC::Getter;
        if (flags & QScriptValue::PropertySetter)
            attribs |= JSC::Setter;
        attribs |= flags & QScriptValue::UserRange;
        return true;
    }
    return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs);
}
Example #5
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;
}
Example #6
0
/*!
  Creates a new \c{Object} and calls this QScriptValue as a
  constructor, using the created object as the `this' object and
  passing \a arguments as arguments. If the return value from the
  constructor call is an object, then that object is returned;
  otherwise the default constructed object is returned.

  If this QScriptValue is not a function, construct() does nothing
  and returns an invalid QScriptValue.

  \a arguments can be an arguments object, an array, null or
  undefined. Any other type will cause a TypeError to be thrown.

  \sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject()
*/
QScriptValue QScriptValue::construct(const QScriptValue &arguments)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject())
        return QScriptValue();
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine());
    return eng->toPublic(d->value.construct(eng->toImpl(arguments)));
}
Example #7
0
/*!
  \since 4.4

  Sets the internal \a data of this QScriptValue object. You can use
  this function to set object-specific data that won't be directly
  accessible to scripts, but may be retrieved in C++ using the data()
  function.
*/
void QScriptValue::setData(const QScriptValue &data)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject())
        return;
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine());
    d->value.setInternalValue(eng->toImpl(data));
}
Example #8
0
/*!
    \since 4.6

    Returns the scope object of this QScriptValue. This function is only
    relevant for function objects. The scope determines how variables are
    resolved when the function is invoked.
*/
QScriptValue QScriptValue::scope() const
{
    Q_D(const QScriptValue);
    if (!d || !d->value.isObject())
        return QScriptValue();
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine());
    return eng->toPublic(d->value.scope());
}
Example #9
0
/*!
  Returns the value of this QScriptValue's property with the given \a name,
  using the given \a mode to resolve the property.

  If no such property exists, an invalid QScriptValue is returned.

  If the property is implemented using a getter function (i.e. has the
  PropertyGetter flag set), calling property() has side-effects on the
  script engine, since the getter function will be called (possibly
  resulting in an uncaught script exception). If an exception
  occurred, property() returns the value that was thrown (typically
  an \c{Error} object).

  \sa setProperty(), propertyFlags(), QScriptValueIterator
*/
QScriptValue QScriptValue::property(const QString &name,
                                    const ResolveFlags &mode) const
{
    Q_D(const QScriptValue);
    if (!d || !d->value.isObject())
        return QScriptValue();
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine());
    return eng->toPublic(d->value.property(name, mode));
}
Example #10
0
/*!
  \overload

  Returns the property at the given \a arrayIndex, using the given \a
  mode to resolve the property.

  This function is provided for convenience and performance when
  working with array objects.

  If this QScriptValue is not an Array object, this function behaves
  as if property() was called with the string representation of \a
  arrayIndex.
*/
QScriptValue QScriptValue::property(quint32 arrayIndex,
                                    const ResolveFlags &mode) const
{
    Q_D(const QScriptValue);
    if (!d || !d->value.isObject())
        return QScriptValue();
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine());
    return eng->toPublic(d->value.property(arrayIndex, mode));
}
Example #11
0
/*!
  Returns the `this' object associated with this QScriptContext.
*/
QScriptValue QScriptContext::thisObject() const
{
    JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this));
    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
    QScript::APIShim shim(engine);
    JSC::JSValue result = engine->thisForContext(frame);
    if (!result || result.isNull())
        result = frame->globalThisValue();
    return engine->scriptValueFromJSCValue(result);
}
Example #12
0
/*!
  \obsolete

  This function is obsolete; use QScriptEngine::toObject() instead.
*/
QScriptValue QScriptValue::toObject() const
{
    Q_D(const QScriptValue);
    if (!d)
        return QScriptValue();
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine());
    if (!eng)
        return QScriptValue();
    return eng->toPublic(eng->toObject(d->value));
}
/*!
  Checks the syntax of the given \a program. Returns a
  QScriptSyntaxCheckResult object that contains the result of the check.
*/
QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program)
{
    // FIXME This is not optimal.
    // The JSC C API needs a context to perform a syntax check, it means that a QScriptEnginePrivate
    // had to be created. This function is static so we have to create QScriptEnginePrivate for each
    // call. We can't remove the "static" for compatibility reason, at least up to Qt5.
    // QScriptSyntaxCheckResultPrivate takes ownership of newly created engine. The engine will be
    // kept as long as it is needed for lazy evaluation of properties of
    // the QScriptSyntaxCheckResultPrivate.
    QScriptEnginePrivate* engine = new QScriptEnginePrivate(/* q_ptr */ 0);
    return QScriptSyntaxCheckResultPrivate::get(engine->checkSyntax(program));
}
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);
    }
}
Example #15
0
/*!
  Returns the callee. The callee is the function object that this
  QScriptContext represents an invocation of.
*/
QScriptValue QScriptContext::callee() const
{
    const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(frame);
    QScript::APIShim shim(eng);
    if (frame->callee() == eng->originalGlobalObject()) {
        // This is a pushContext()-created context; the callee is a lie.
        Q_ASSERT(QScriptEnginePrivate::contextFlags(const_cast<JSC::CallFrame*>(frame)) & QScriptEnginePrivate::NativeContext);
        return QScriptValue();
    }
    return eng->scriptValueFromJSCValue(frame->callee());
}
QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine, 
                                                QScriptDeclarativeClass *scriptClass, 
                                                Object *object)
{
    Q_ASSERT(engine);
    Q_ASSERT(scriptClass);

    QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine)); 

    JSC::ExecState* exec = p->currentFrame;
    QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure);
    result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object));
    return p->scriptValueFromJSCValue(result);
}
void Function::initialize()
{
    QScriptEnginePrivate *eng = engine();
    eng->newConstructor(&ctor, this, publicPrototype);

    addPrototypeFunction(QLatin1String("toString"), method_toString, 1);
    addPrototypeFunction(QLatin1String("apply"), method_apply, 1);
    addPrototypeFunction(QLatin1String("call"), method_call, 1);
    addPrototypeFunction(QLatin1String("connect"), method_connect, 1);
    addPrototypeFunction(QLatin1String("disconnect"), method_disconnect, 1);

    QExplicitlySharedDataPointer<QScriptClassData> data(new FunctionClassData(classInfo()));
    classInfo()->setData(data);
}
bool GlobalObject::getOwnPropertySlot(JSC::ExecState* exec,
                                      const JSC::Identifier& propertyName,
                                      JSC::PropertySlot& slot)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    if (propertyName == exec->propertyNames().arguments && engine->currentFrame->argumentCount() > 0) {
        JSC::JSValue args = engine->scriptValueToJSCValue(engine->contextForFrame(engine->currentFrame)->argumentsObject());
        slot.setValue(args);
        return true;
    }
    if (customGlobalObject)
        return customGlobalObject->getOwnPropertySlot(exec, propertyName, slot);
    return JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot);
}
Example #19
0
/*!
  Sets the activation object of this QScriptContext to be the given \a
  activation.

  If \a activation is not an object, this function does nothing.

  \note For a context corresponding to a JavaScript function, this is only
  guaranteed to work if there was an QScriptEngineAgent active on the
  engine while the function was evaluated.
*/
void QScriptContext::setActivationObject(const QScriptValue &activation)
{
    if (!activation.isObject())
        return;
    else if (activation.engine() != engine()) {
        qWarning("QScriptContext::setActivationObject() failed: "
                 "cannot set an object created in "
                 "a different engine");
        return;
    }
    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
    QScript::APIShim shim(engine);
    JSC::JSObject *object = JSC::asObject(engine->scriptValueToJSCValue(activation));
    if (object == engine->originalGlobalObjectProxy)
        object = engine->originalGlobalObject();

    uint flags = QScriptEnginePrivate::contextFlags(frame);
    if ((flags & QScriptEnginePrivate::NativeContext) && !(flags & QScriptEnginePrivate::HasScopeContext)) {
        //For native functions, we create a scope node
        JSC::JSObject *scope = object;
        if (!scope->isVariableObject()) {
            // Create a QScriptActivationObject that acts as a proxy
            scope = new (frame) QScript::QScriptActivationObject(frame, scope);
        }
        frame->setScopeChain(frame->scopeChain()->copy()->push(scope));
        QScriptEnginePrivate::setContextFlags(frame, flags | QScriptEnginePrivate::HasScopeContext);
        return;
    }

    // else replace the first activation object in the scope chain
    JSC::ScopeChainNode *node = frame->scopeChain();
    while (node != 0) {
        if (node->object && node->object->isVariableObject()) {
            if (!object->isVariableObject()) {
                if (node->object->inherits(&QScript::QScriptActivationObject::info)) {
                    static_cast<QScript::QScriptActivationObject*>(node->object)->setDelegate(object);
                } else {
                    // Create a QScriptActivationObject that acts as a proxy
                    node->object = new (frame) QScript::QScriptActivationObject(frame, object);
                }
            } else {
                node->object = object;
            }
            break;
        }
        node = node->next;
    }
}
void Enumeration::Instance::next(QScriptContextPrivate *context, QScriptValueImpl *result)
{
    QScriptEnginePrivate *eng = context->engine();
    Q_ASSERT(it != 0);
    it->next();
    QScript::Member *member = it->member();
    if (member->isObjectProperty() || member->nameId())
        eng->newNameId(result, member->nameId());

    else if (member->isNativeProperty() && !member->nameId())
        *result = QScriptValueImpl(uint(member->id()));

    else
        *result = eng->undefinedValue();
}
Example #21
0
void Object::initialize()
{
    QScriptEnginePrivate *eng = engine();

    eng->newConstructor(&ctor, this, publicPrototype);

    addPrototypeFunction(QLatin1String("toString"), method_toString, 1);
    addPrototypeFunction(QLatin1String("toLocaleString"), method_toLocaleString, 1);
    addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0);
    addPrototypeFunction(QLatin1String("hasOwnProperty"), method_hasOwnProperty, 1);
    addPrototypeFunction(QLatin1String("isPrototypeOf"), method_isPrototypeOf, 1);
    addPrototypeFunction(QLatin1String("propertyIsEnumerable"), method_propertyIsEnumerable, 1);
    addPrototypeFunction(QLatin1String("__defineGetter__"), method_defineGetter, 2);
    addPrototypeFunction(QLatin1String("__defineSetter__"), method_defineSetter, 2);
}
bool GlobalObject::getOwnPropertyDescriptor(JSC::ExecState* exec,
                                            const JSC::Identifier& propertyName,
                                            JSC::PropertyDescriptor& descriptor)
{
    // Must match the logic of getOwnPropertySlot().
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    if (propertyName == exec->propertyNames().arguments && engine->currentFrame->argumentCount() > 0) {
        // ### Can we get rid of this special handling of the arguments property?
        JSC::JSValue args = engine->scriptValueToJSCValue(engine->contextForFrame(engine->currentFrame)->argumentsObject());
        descriptor.setValue(args);
        return true;
    }
    if (customGlobalObject)
        return customGlobalObject->getOwnPropertyDescriptor(exec, propertyName, descriptor);
    return JSC::JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
/*!
  Enters a new execution context and returns the associated
  QScriptContext object.

  Once you are done with the context, you should call popContext() to
  restore the old context.

  By default, the `this' object of the new context is the Global Object.
  The context's \l{QScriptContext::callee()}{callee}() will be invalid.

  Unlike pushContext(), the default scope chain is reset to include
  only the global object and the QScriptContext's activation object.

  \sa QScriptEngine::popContext()
*/
QScriptContext * QScriptDeclarativeClass::pushCleanContext(QScriptEngine *engine)
{
    if (!engine)
        return 0;

    QScriptEnginePrivate *d = QScriptEnginePrivate::get(engine);

    JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, 
                                              d->currentFrame->globalData().dynamicGlobalObject,
                                              JSC::ArgList(), /*callee = */0, false, true);

    if (engine->agent())
        engine->agent()->contextPush();

    return d->contextForFrame(newFrame);
}
Example #24
0
/*!
  Calls this QScriptValue as a function, using \a thisObject as
  the `this' object in the function call, and passing \a arguments
  as arguments to the function. Returns the value returned from
  the function.

  If this QScriptValue is not a function, call() does nothing
  and returns an invalid QScriptValue.

  \a arguments can be an arguments object, an array, null or
  undefined; any other type will cause a TypeError to be thrown.

  Note that if \a thisObject is not an object, the global object
  (see \l{QScriptEngine::globalObject()}) will be used as the
  `this' object.

  One common usage of this function is to forward native function
  calls to another function:

  \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 3

  \sa construct(), QScriptContext::argumentsObject()
*/
QScriptValue QScriptValue::call(const QScriptValue &thisObject,
                                const QScriptValue &arguments)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject())
        return QScriptValue();
    if (isFunction() && thisObject.isValid() && thisObject.engine()
        && (thisObject.engine() != engine())) {
        qWarning("QScriptValue::call() failed: "
                 "cannot call function with thisObject created in "
                 "a different engine");
        return QScriptValue();
    }
    QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine());
    return eng->toPublic(d->value.call(eng->toImpl(thisObject),
                                       eng->toImpl(arguments)));
}
Example #25
0
/*!
  \internal
  \since 4.5

  Removes the front object from this context's scope chain, and
  returns the removed object.

  If the scope chain is already empty, this function returns an
  invalid QScriptValue.
*/
QScriptValue QScriptContext::popScope()
{
    activationObject(); //ensure the creation of the normal scope for native context
    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    JSC::ScopeChainNode *scope = frame->scopeChain();
    Q_ASSERT(scope != 0);
    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
    QScript::APIShim shim(engine);
    QScriptValue result = engine->scriptValueFromJSCValue(scope->object);
    if (!scope->next) {
        // We cannot have a null scope chain, so just zap the object pointer.
        scope->object = 0;
    } else {
        frame->setScopeChain(scope->pop());
    }
    return result;
}
bool ClassObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object,
                                                   JSC::ExecState *exec,
                                                   const JSC::Identifier &propertyName,
                                                   JSC::PropertyDescriptor &descriptor)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    // for compatibility with the old back-end, normal JS properties
    // are queried first.
    if (QScriptObjectDelegate::getOwnPropertyDescriptor(object, exec, propertyName, descriptor))
        return true;

    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags qflags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
    if (qflags & QScriptClass::HandlesReadAccess) {
        QScriptValue::PropertyFlags pflags = m_scriptClass->propertyFlags(scriptObject, scriptName, id);
        unsigned attribs = 0;
        if (pflags & QScriptValue::ReadOnly)
            attribs |= JSC::ReadOnly;
        if (pflags & QScriptValue::SkipInEnumeration)
            attribs |= JSC::DontEnum;
        if (pflags & QScriptValue::Undeletable)
            attribs |= JSC::DontDelete;
        if (pflags & QScriptValue::PropertyGetter)
            attribs |= JSC::Getter;
        if (pflags & QScriptValue::PropertySetter)
            attribs |= JSC::Setter;
        attribs |= pflags & QScriptValue::UserRange;
        // Rather than calling the getter, we could return an access descriptor here.
        QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
        if (!value.isValid()) {
            // The class claims to have the property, but returned an invalid
            // value. Silently convert to undefined to avoid the invalid value
            // "escaping" into JS.
            value = QScriptValue(QScriptValue::UndefinedValue);
        }
        descriptor.setDescriptor(engine->scriptValueToJSCValue(value), attribs);
        return true;
    }
    return false;
}
void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec,
                                              JSC::PropertyNameArray &propertyNames,
                                              bool includeNonEnumerable)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptClassPropertyIterator *it = m_scriptClass->newIterator(scriptObject);
    if (it != 0) {
        while (it->hasNext()) {
            it->next();
            QString name = it->name().toString();
            propertyNames.add(JSC::Identifier(exec, name));
        }
        delete it;
    }
    QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable);
}
Example #28
0
/*
Returns the scope chain entry at \a index.  If index is less than 0, returns
entries starting at the end.  For example, scopeChainValue(context, -1) will return
the value last in the scope chain.
*/
QScriptValue QScriptDeclarativeClass::scopeChainValue(QScriptContext *context, int index)
{
    context->activationObject(); //ensure the creation of the normal scope for native context
    const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(context);
    QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame);
    QScript::APIShim shim(engine);

    JSC::ScopeChainNode *node = frame->scopeChain();
    JSC::ScopeChainIterator it(node);

    if (index < 0) {
        int count = 0;
        for (it = node->begin(); it != node->end(); ++it) 
            ++count;

        index = qAbs(index);
        if (index > count)
            return QScriptValue();
        else
            index = count - index;
    }

    for (it = node->begin(); it != node->end(); ++it) {

        if (index == 0) {

            JSC::JSObject *object = *it;
            if (!object) return QScriptValue();

            if (object->inherits(&QScript::QScriptActivationObject::info)
                    && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) {
                // Return the object that property access is being delegated to
                object = static_cast<QScript::QScriptActivationObject*>(object)->delegate();
            }
            return engine->scriptValueFromJSCValue(object);

        } else {
            --index;
        }

    }

    return QScriptValue();
}
void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
                              const JSC::Identifier &propertyName,
                              JSC::JSValue value, JSC::PutPropertySlot &slot)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScript::SaveFrameHelper saveFrame(engine, exec);
    QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
    QScriptString scriptName;
    QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
    QScriptStringPrivate::init(scriptName, &scriptName_d);
    uint id = 0;
    QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
        scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id);
    if (flags & QScriptClass::HandlesWriteAccess) {
        m_scriptClass->setProperty(scriptObject, scriptName, id, engine->scriptValueFromJSCValue(value));
        return;
    }
    QScriptObjectDelegate::put(object, exec, propertyName, value, slot);
}
void DeclarativeObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
                                    const JSC::Identifier &propertyName,
                                    JSC::JSValue value, JSC::PutPropertySlot &slot)
{
    QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
    QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep();

    QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class);
    p->context = reinterpret_cast<QScriptContext *>(exec);
    QScriptClass::QueryFlags flags =
        m_class->queryProperty(m_object, identifier, QScriptClass::HandlesWriteAccess);
    if (flags & QScriptClass::HandlesWriteAccess) {
        m_class->setProperty(m_object, identifier, engine->scriptValueFromJSCValue(value));
        p->context = 0;
        return;
    }
    p->context = 0;

    QScriptObjectDelegate::put(object, exec, propertyName, value, slot);
}