QDocumentCursor cursorFromValue(const QScriptValue& value){
	QDocumentCursor * c = qobject_cast<QDocumentCursor*> (value.toQObject());
	if (!c) {
		if (value.engine() && value.engine()->currentContext()) value.engine()->currentContext()->throwError(scriptengine::tr("Expected cursor object"));
		return QDocumentCursor();
	}
	return *c;
}
void UndoStackScriptingInterface::pushCommand(QScriptValue undoFunction, QScriptValue undoData,
                                              QScriptValue redoFunction, QScriptValue redoData) {
    if (undoFunction.engine()) {
        ScriptUndoCommand* undoCommand = new ScriptUndoCommand(undoFunction, undoData, redoFunction, redoData);
        undoCommand->moveToThread(undoFunction.engine()->thread());
        _undoStack->push(undoCommand);
    }
}
void qScriptValueToStringPtr(const QScriptValue &value, QString* &str) {
	str = 0;
	QString* s = getStrPtr(value);
	if (!s) {
		if (!value.isObject()) return;
		s = new QString(); //memory leak. But better than null pointer
		QScriptValue(value).setProperty("dataStore",value.engine()->newVariant((quintptr)(s) ^ pointerObsfuscationKey()),QScriptValue::Undeletable | QScriptValue::ReadOnly);
		QScriptValue(value).setProperty("value", value.engine()->newFunction(&getSetStrValue), QScriptValue::Undeletable | QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
	}
	str = s;
}
/*!
  \overload

  Sets the property at the given \a arrayIndex to the given \a value.

  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 setProperty() was called with the string representation of \a
  arrayIndex.
*/
void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value,
                               const PropertyFlags &flags)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject())
        return;
    if (value.engine() && (value.engine() != engine())) {
        qWarning("QScriptValue::setProperty() failed: "
                 "cannot set value created in a different engine");
        return;
    }
    d->value.setProperty(arrayIndex, d->value.engine()->toImpl(value), flags);
}
/*!
  Returns true if this QScriptValue is equal to \a other using strict
  comparison (no conversion), otherwise returns false. The comparison
  follows the behavior described in \l{ECMA-262} section 11.9.6, "The
  Strict Equality Comparison Algorithm".

  If the type of this QScriptValue is different from the type of the
  \a other value, this function returns false. If the types are equal,
  the result depends on the type, as shown in the following table:

    \table
    \header \o Type \o Result
    \row    \o Undefined  \o true
    \row    \o Null       \o true
    \row    \o Boolean    \o true if both values are true, false otherwise
    \row    \o Number     \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise
    \row    \o String     \o true if both values are exactly the same sequence of characters, false otherwise
    \row    \o Object     \o true if both values refer to the same object, false otherwise
    \endtable
  
  \sa equals()
*/
bool QScriptValue::strictlyEquals(const QScriptValue &other) const
{
    if (!isValid() || !other.isValid())
        return isValid() == other.isValid();
    if (other.engine() && engine() && (other.engine() != engine())) {
        qWarning("QScriptValue::strictlyEquals: "
                 "cannot compare to a value created in "
                 "a different engine");
        return false;
    }
    return QScriptEnginePrivate::strictlyEquals(QScriptValuePrivate::valueOf(*this),
                                                QScriptValuePrivate::valueOf(other));
}
/*!
  Sets the value of this QScriptValue's property with the given \a name to
  the given \a value.

  If this QScriptValue is not an object, this function does nothing.

  If this QScriptValue does not already have a property with name \a name,
  a new property is created; the given \a flags then specify how this
  property may be accessed by script code.

  If \a value is invalid, the property is removed.

  If the property is implemented using a setter function (i.e. has the
  PropertySetter flag set), calling setProperty() has side-effects on
  the script engine, since the setter function will be called with the
  given \a value as argument (possibly resulting in an uncaught script
  exception).

  Note that you cannot specify custom getter or setter functions for
  built-in properties, such as the \c{length} property of Array objects
  or meta properties of QObject objects.

  \sa property()
*/
void QScriptValue::setProperty(const QString &name, const QScriptValue &value,
                               const PropertyFlags &flags)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject())
        return;
    if (value.engine() && (value.engine() != engine())) {
        qWarning("QScriptValue::setProperty(%s) failed: "
                 "cannot set value created in a different engine",
                 qPrintable(name));
        return;
    }
    d->value.setProperty(name, d->value.engine()->toImpl(value), flags);
}
/*!
    \since 4.6

    Sets the \a scope object of this QScriptValue. This function is only
    relevant for function objects. Changing the scope is useful when creating
    closures; see \l{Nested Functions and the Scope Chain}.
*/
void QScriptValue::setScope(const QScriptValue &scope)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject())
        return;
    if (scope.isValid() && scope.engine()
        && (scope.engine() != engine())) {
        qWarning("QScriptValue::setScope() failed: "
                 "cannot set a scope object created in "
                 "a different engine");
        return;
    }
    d->value.setScope(d->value.engine()->toImpl(scope));
}
/*!
  \since 4.4

  Sets the value of this QScriptValue's property with the given \a
  name to the given \a value. The given \a flags specify how this
  property may be accessed by script code.

  This overload of setProperty() is useful when you need to set the
  same property repeatedly, since the operation can be performed
  faster when the name is represented as an interned string.

  \sa QScriptEngine::toStringHandle()
*/
void QScriptValue::setProperty(const QScriptString &name,
                               const QScriptValue &value,
                               const PropertyFlags &flags)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject() || !name.isValid())
        return;
    if (value.engine() && (value.engine() != engine())) {
        qWarning("QScriptValue::setProperty() failed: "
                 "cannot set value created in a different engine");
        return;
    }
    QScriptStringPrivate *s = QScriptStringPrivate::get(name);
    d->value.setProperty(s->nameId, d->value.engine()->toImpl(value), flags);
}
/*!
  \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));
}
Beispiel #10
0
static void setArtifactProperty(QScriptValue &obj, const QString &name,
        QScriptValue (*func)(QScriptContext *, QScriptEngine *, const Artifact *),
        const Artifact *artifact)
{
    obj.setProperty(name, static_cast<ScriptEngine *>(obj.engine())->newFunction(func, artifact),
                    QScriptValue::PropertyGetter);
}
void tst_QScriptValueGenerated::assignAndCopyConstruct_test(const char *, const QScriptValue &value)
{
    QScriptValue copy(value);
    QCOMPARE(copy.strictlyEquals(value), !value.isNumber() || !qIsNaN(value.toNumber()));
    QCOMPARE(copy.engine(), value.engine());

    QScriptValue assigned = copy;
    QCOMPARE(assigned.strictlyEquals(value), !copy.isNumber() || !qIsNaN(copy.toNumber()));
    QCOMPARE(assigned.engine(), assigned.engine());

    QScriptValue other(!value.toBool());
    assigned = other;
    QVERIFY(!assigned.strictlyEquals(copy));
    QVERIFY(assigned.strictlyEquals(other));
    QCOMPARE(assigned.engine(), other.engine());
}
/*!
  Sets the `this' object associated with this QScriptContext to be
  \a thisObject.

  If \a thisObject is not an object, this function does nothing.
*/
void QScriptContext::setThisObject(const QScriptValue &thisObject)
{
    JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
    if (!thisObject.isObject())
        return;
    if (thisObject.engine() != engine()) {
        qWarning("QScriptContext::setThisObject() failed: "
                 "cannot set an object created in "
                 "a different engine");
        return;
    }
    if (frame == frame->lexicalGlobalObject()->globalExec()) {
        engine()->setGlobalObject(thisObject);
        return;
    }
    JSC::JSValue jscThisObject = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(thisObject);
    JSC::CodeBlock *cb = frame->codeBlock();
    if (cb != 0) {
        frame[cb->thisRegister()] = jscThisObject;
    } else {
        JSC::Register* thisRegister = QScriptEnginePrivate::thisRegisterForFrame(frame);
        thisRegister[0] = jscThisObject;
    }
}
/*!
  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)));
}
void EvaluatorScriptClass::convertToPropertyType(const Item *item, const PropertyDeclaration& decl,
                                                 const Value *value, QScriptValue &v)
{
    if (value->type() == Value::VariantValueType && v.isUndefined() && !decl.isScalar()) {
        v = v.engine()->newArray(); // QTBUG-51237
        return;
    }
    convertToPropertyType_impl(m_pathPropertiesBaseDir, item, decl, value->location(), v);
}
void qtscript_initialize_com_trolltech_qt_gui_bindings(QScriptValue &extensionObject)
{
    QScriptEngine *engine = extensionObject.engine();
    for (int i = 0; i < 349; ++i) {
        extensionObject.setProperty(qtscript_com_trolltech_qt_gui_class_names[i],
            qtscript_com_trolltech_qt_gui_class_functions[i](engine),
            QScriptValue::SkipInEnumeration);
    }
}
/*!
  Returns true if this QScriptValue is equal to \a other, otherwise
  returns false. The comparison follows the behavior described in
  \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison
  Algorithm".

  This function can return true even if the type of this QScriptValue
  is different from the type of the \a other value; i.e. the
  comparison is not strict.  For example, comparing the number 9 to
  the string "9" returns true; comparing an undefined value to a null
  value returns true; comparing a \c{Number} object whose primitive
  value is 6 to a \c{String} object whose primitive value is "6"
  returns true; and comparing the number 1 to the boolean value
  \c{true} returns true. If you want to perform a comparison
  without such implicit value conversion, use strictlyEquals().

  Note that if this QScriptValue or the \a other value are objects,
  calling this function has side effects on the script engine, since
  the engine will call the object's valueOf() function (and possibly
  toString()) in an attempt to convert the object to a primitive value
  (possibly resulting in an uncaught script exception).

  \sa strictlyEquals(), lessThan()
*/
bool QScriptValue::equals(const QScriptValue &other) const
{
    if (isValid() && other.isValid() && (other.engine() != engine())) {
        qWarning("QScriptValue::equals: "
                 "cannot compare to a value created in "
                 "a different engine");
        return false;
    }
    return QScriptValuePrivate::valueOf(*this).equals(QScriptValuePrivate::valueOf(other));
}
QScriptValue ScriptFunctionWrapper::callWith(const QScriptValue &val) {
	//qDebug() << "Call called" << d->name;
	QScriptEngine *eng = val.engine();
	if (!eng) {
		qDebug() << "We cannot access the script-engine, fail!";
		return QScriptValue();
	}
	QScriptContext *ctx = eng->currentContext();
	return d->object.property(d->name).call(QScriptValue(), ctx->argumentsObject());
}
/*!
  \overload

  Sets the property at the given \a arrayIndex to the given \a value.

  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 setProperty() was called with the string representation of \a
  arrayIndex.
*/
void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value,
                               const PropertyFlags &flags)
{
    if (isValid() && value.isValid() && (value.engine() != engine())) {
        qWarning("QScriptValue::setProperty() failed: "
                 "cannot set value created in a different engine");
        return;
    }
    QScriptValuePrivate::valueOf(*this).setProperty(
        arrayIndex, QScriptValuePrivate::valueOf(value), flags);
}
/*!
  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)
{
    Q_D(QScriptValue);
    if (!d || !d->value.isObject())
        return;
    if (prototype.isValid() && prototype.engine()
        && (prototype.engine() != engine())) {
        qWarning("QScriptValue::setPrototype() failed: "
                 "cannot set a prototype created in "
                 "a different engine");
        return;
    }
    QScriptValueImpl was = d->value.prototype();
    d->value.setPrototype(d->value.engine()->toImpl(prototype));
    if (d->value.detectedCycle()) {
        qWarning("QScriptValue::setPrototype() failed: "
                 "cyclic prototype value");
        d->value.setPrototype(was);
    }
}
Beispiel #20
0
void ModuleProperties::init(QScriptValue objectWithProperties, const void *ptr,
                            const QString &type)
{
    QScriptEngine * const engine = objectWithProperties.engine();
    objectWithProperties.setProperty(QLatin1String("moduleProperties"),
                                     engine->newFunction(ModuleProperties::js_moduleProperties, 2));
    objectWithProperties.setProperty(QLatin1String("moduleProperty"),
                                     engine->newFunction(ModuleProperties::js_moduleProperty, 2));
    objectWithProperties.setProperty(ptrKey(), engine->toScriptValue(quintptr(ptr)));
    objectWithProperties.setProperty(typeKey(), type);
}
Beispiel #21
0
void ScriptManager::handleException(const QScriptValue& value)
{
    DEBUG_BLOCK

    QScriptEngine * engine = value.engine();
    if (!engine)
        return;

    Amarok::Components::logger()->longMessage( i18n( "Script error reported by: %1\n%2" )
            .arg( scriptNameForEngine( engine ), value.toString() ), Amarok::Logger::Error );
}
/*!
  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)
{
    if (isFunction() && thisObject.isValid() && (thisObject.engine() != engine())) {
        qWarning("QScriptValue::call() failed: "
                 "cannot call function with thisObject created in "
                 "a different engine");
        return QScriptValue();
    }
    return QScriptValuePrivate::valueOf(*this).call(QScriptValuePrivate::valueOf(thisObject),
                                                    QScriptValuePrivate::valueOf(arguments));
}
/*!
  \internal
*/
void QScriptValue::setScope(const QScriptValue &scope)
{
    if (!isObject())
        return;
    if (scope.isValid() && (scope.engine() != engine())) {
        qWarning("QScriptValue::setScope() failed: "
                 "cannot set a scope object created in "
                 "a different engine");
        return;
    }
    QScriptValuePrivate::valueOf(*this).setScope(QScriptValuePrivate::valueOf(scope));
}
/*!
  Sets the value of this QScriptValue's property with the given \a name to
  the given \a value.

  If this QScriptValue is not an object, this function does nothing.

  If this QScriptValue does not already have a property with name \a name,
  a new property is created; the given \a flags then specify how this
  property may be accessed by script code.

  If \a value is invalid, the property is removed.

  If the property is implemented using a setter function (i.e. has the
  PropertySetter flag set), calling setProperty() has side-effects on
  the script engine, since the setter function will be called with the
  given \a value as argument (possibly resulting in an uncaught script
  exception).

  Note that you cannot specify custom getter or setter functions for
  built-in properties, such as the \c{length} property of Array objects
  or meta properties of QObject objects.

  \sa property()
*/
void QScriptValue::setProperty(const QString &name, const QScriptValue &value,
                               const PropertyFlags &flags)
{
    if (isValid() && value.isValid() && (value.engine() != engine())) {
        qWarning("QScriptValue::setProperty(%s) failed: "
                 "cannot set value created in a different engine",
                 qPrintable(name));
        return;
    }
    QScriptValuePrivate::valueOf(*this).setProperty(
        name, QScriptValuePrivate::valueOf(value), flags);
}
Beispiel #25
0
void HttpHandlerQtScript::setScriptFunction(const QScriptValue &scriptFunction)
{
	if (_scriptFunction.strictlyEquals(scriptFunction)) return;
	_scriptFunction = scriptFunction;

	if (!_scriptFunction.isValid())
		qWarning() << "HttpHandlerQtScript::setScriptFunction: passed an invalid QScriptValue; this handler will not be able to handle requests.";
	else if (!_scriptFunction.isFunction())
		qWarning() << "HttpHandlerQtScript::setScriptFunction: passed a non-function QScriptValue; this handler will not be able to handle requests.";
	else
		registerMarshallers(scriptFunction.engine());
}
Beispiel #26
0
/*!
  Sets the `this' object associated with this QScriptContext to be
  \a thisObject.

  If \a thisObject is not an object, this function does nothing.
*/
void QScriptContext::setThisObject(const QScriptValue &thisObject)
{
    Q_D(QScriptContext);
    if (!thisObject.isObject()) {
    } else if (thisObject.engine() != engine()) {
        qWarning("QScriptContext::setThisObject() failed: "
                 "cannot set an object created in "
                 "a different engine");
    } else {
        d->m_thisObject = d->engine()->toImpl(thisObject);
    }
}
Beispiel #27
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.
*/
void QScriptContext::setActivationObject(const QScriptValue &activation)
{
    Q_D(QScriptContext);
    if (!activation.isObject()) {
        return;
    } else if (activation.engine() != engine()) {
        qWarning("QScriptContext::setActivationObject() failed: "
                 "cannot set an object created in "
                 "a different engine");
    } else {
        d->m_activation = d->engine()->toImpl(activation);
    }
}
/*!
  Returns true if this QScriptValue is an instance of
  \a other; otherwise returns false.

  This QScriptValue is considered to be an instance of \a other if
  \a other is a function and the value of the \c{prototype}
  property of \a other is in the prototype chain of this
  QScriptValue.
*/
bool QScriptValue::instanceOf(const QScriptValue &other) const
{
    if (!isValid() || !other.isValid())
        return false;
    if (other.engine() != engine()) {
        qWarning("QScriptValue::instanceof: "
                 "cannot perform operation on a value created in "
                 "a different engine");
        return false;
    }
    return QScriptValuePrivate::valueOf(*this)
        .instanceOf(QScriptValuePrivate::valueOf(other));
}
Beispiel #29
0
void AnimVariantMap::animVariantMapFromScriptValue(const QScriptValue& source) {
    if (QThread::currentThread() != source.engine()->thread()) {
        qCWarning(animation) << "Cannot examine Javacript object from non-script thread" << QThread::currentThread();
        Q_ASSERT(false);
        return;
    }
    // POTENTIAL OPTIMIZATION: cache the types we've seen. I.e, keep a dictionary mapping property names to an enumeration of types.
    // Whenever we identify a new outbound type in animVariantMapToScriptValue above, or a new inbound type in the code that follows here,
    // we would enter it into the dictionary. Then switch on that type here, with the code that follow being executed only if
    // the type is not known. One problem with that is that there is no checking that two different script use the same name differently.
    QScriptValueIterator property(source);
    // Note: QScriptValueIterator iterates only over source's own properties. It does not follow the prototype chain.
    while (property.hasNext()) {
        property.next();
        QScriptValue value = property.value();
        if (value.isBool()) {
            set(property.name(), value.toBool());
        } else if (value.isString()) {
            set(property.name(), value.toString());
        } else if (value.isNumber()) {
            int asInteger = value.toInt32();
            float asFloat = value.toNumber();
            if (asInteger == asFloat) {
                set(property.name(), asInteger);
            } else {
                set(property.name(), asFloat);
            }
        } else { // Try to get x,y,z and possibly w
            if (value.isObject()) {
                QScriptValue x = value.property("x");
                if (x.isNumber()) {
                    QScriptValue y = value.property("y");
                    if (y.isNumber()) {
                        QScriptValue z = value.property("z");
                        if (z.isNumber()) {
                            QScriptValue w = value.property("w");
                            if (w.isNumber()) {
                                set(property.name(), glm::quat(w.toNumber(), x.toNumber(), y.toNumber(), z.toNumber()));
                            } else {
                                set(property.name(), glm::vec3(x.toNumber(), y.toNumber(), z.toNumber()));
                            }
                            continue; // we got either a vector or quaternion object, so don't fall through to warning
                        }
                    }
                }
            }
            qCWarning(animation) << "Ignoring unrecognized data" << value.toString() << "for animation property" << property.name();
            Q_ASSERT(false);
        }
    }
}
/*!
  Returns true if this QScriptValue is an instance of
  \a other; otherwise returns false.

  This QScriptValue is considered to be an instance of \a other if
  \a other is a function and the value of the \c{prototype}
  property of \a other is in the prototype chain of this
  QScriptValue.
*/
bool QScriptValue::instanceOf(const QScriptValue &other) const
{
    Q_D(const QScriptValue);
    if (!isObject() || !other.isObject())
        return false;
    if (other.engine() != engine()) {
        qWarning("QScriptValue::instanceof: "
                 "cannot perform operation on a value created in "
                 "a different engine");
        return false;
    }
    return d->value.engine()->toImpl(*this)
        .instanceOf(d->value.engine()->toImpl(other));
}