void QEnginioCollectionObjectPrivate::QmlCallbackFunctor::operator ()(QEnginioOperationObject *aOperation)
{
    using namespace QV4;

    if (!aOperation)
        return;

    if (iCallback.isCallable()) {
        QJSValuePrivate *prv=QJSValuePrivate::get(iCallback);
        FunctionObject *f =prv->value.asFunctionObject();

        if (f) {
            ExecutionEngine *engine = prv->engine;
            Q_ASSERT(engine);

            Scope scope(engine);
            ScopedCallData callData(scope, 1); // args.length());
            callData->thisObject = engine->globalObject->asReturnedValue();

            ScopedValue result(scope);
            QV4::ExecutionContext *ctx = engine->currentContext();

            callData->args[0] = QObjectWrapper::wrap(engine,aOperation);

            result = f->call(callData);
            if (scope.hasException()) {
                result = ctx->catchException();
            }
            QJSValue tmp(new QJSValuePrivate(engine, result));
        }
    }

    delete aOperation;
}
Beispiel #2
0
/*!
  Calls this QJSValue as a function, using \a instance as
  the `this' object in the function call, and passing \a args
  as arguments to the function. Returns the value returned from
  the function.

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

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

  Calling call() can cause an exception to occur in the script engine;
  in that case, call() returns the value that was thrown (typically an
  \c{Error} object). You can call isError() on the return value to
  determine whether an exception occurred.

  \sa call()
*/
QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args)
{
    FunctionObject *f = d->value.asFunctionObject();
    if (!f)
        return QJSValue();

    ExecutionEngine *engine = d->engine;
    assert(engine);
    Scope scope(engine);

    if (!instance.d->checkEngine(engine)) {
        qWarning("QJSValue::call() failed: cannot call function with thisObject created in a different engine");
        return QJSValue();
    }

    ScopedCallData callData(scope, args.size());
    callData->thisObject = instance.d->getValue(engine);
    for (int i = 0; i < args.size(); ++i) {
        if (!args.at(i).d->checkEngine(engine)) {
            qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
            return QJSValue();
        }
        callData->args[i] = args.at(i).d->getValue(engine);
    }

    ScopedValue result(scope);
    QV4::ExecutionContext *ctx = engine->currentContext();
    result = f->call(callData);
    if (scope.hasException())
        result = ctx->catchException();

    return new QJSValuePrivate(engine, result);
}
ReturnedValue Object::getValue(const ValueRef thisObject, const Property *p, PropertyAttributes attrs)
{
    if (!attrs.isAccessor())
        return p->value.asReturnedValue();
    FunctionObject *getter = p->getter();
    if (!getter)
        return Encode::undefined();

    Scope scope(getter->engine());
    ScopedCallData callData(scope, 0);
    callData->thisObject = *thisObject;
    return getter->call(callData);
}
Beispiel #4
0
ReturnedValue Script::run()
{
    struct ContextStateSaver {
        ExecutionContext *savedContext;
        bool strictMode;
        Lookup *lookups;
        CompiledData::CompilationUnit *compilationUnit;

        ContextStateSaver(ExecutionContext *context)
            : savedContext(context)
            , strictMode(context->strictMode)
            , lookups(context->lookups)
            , compilationUnit(context->compilationUnit)
        {}

        ~ContextStateSaver()
        {
            savedContext->strictMode = strictMode;
            savedContext->lookups = lookups;
            savedContext->compilationUnit = compilationUnit;
        }
    };

    if (!parsed)
        parse();
    if (!vmFunction)
        return Encode::undefined();

    QV4::ExecutionEngine *engine = scope->engine;
    QV4::Scope valueScope(engine);

    if (qml.isUndefined()) {
        TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);

        ExecutionContextSaver ctxSaver(scope);
        ContextStateSaver stateSaver(scope);
        scope->strictMode = vmFunction->isStrict();
        scope->lookups = vmFunction->compilationUnit->runtimeLookups;
        scope->compilationUnit = vmFunction->compilationUnit;

        return vmFunction->code(scope, vmFunction->codeData);
    } else {
        ScopedObject qmlObj(valueScope, qml.value());
        FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qmlObj);
        ScopedCallData callData(valueScope, 0);
        callData->thisObject = Primitive::undefinedValue();
        return f->call(callData);
    }
}
Beispiel #5
0
ReturnedValue FunctionPrototype::method_call(CallContext *ctx)
{
    Scope scope(ctx);

    FunctionObject *o = ctx->callData->thisObject.asFunctionObject();
    if (!o)
        return ctx->throwTypeError();

    ScopedCallData callData(scope, ctx->callData->argc ? ctx->callData->argc - 1 : 0);
    if (ctx->callData->argc) {
        std::copy(ctx->callData->args + 1,
                  ctx->callData->args + ctx->callData->argc, callData->args);
    }
    callData->thisObject = ctx->argument(0);
    return o->call(callData);
}
ReturnedValue DatePrototype::method_toJSON(CallContext *ctx)
{
    Scope scope(ctx);
    ScopedValue O(scope, RuntimeHelpers::toObject(ctx, ValueRef(&ctx->d()->callData->thisObject)));
    ScopedValue tv(scope, RuntimeHelpers::toPrimitive(O, NUMBER_HINT));

    if (tv->isNumber() && !std::isfinite(tv->toNumber()))
        return Encode::null();

    ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toISOString")));
    ScopedValue v(scope, O->objectValue()->get(s.getPointer()));
    FunctionObject *toIso = v->asFunctionObject();

    if (!toIso)
        return ctx->throwTypeError();

    ScopedCallData callData(scope, 0);
    callData->thisObject = ctx->d()->callData->thisObject;
    return toIso->call(callData);
}
Beispiel #7
0
ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
{
    Scope scope(ctx);
    FunctionObject *o = ctx->callData->thisObject.asFunctionObject();
    if (!o)
        return ctx->throwTypeError();

    ScopedValue arg(scope, ctx->argument(1));

    ScopedObject arr(scope, arg);

    quint32 len;
    if (!arr) {
        len = 0;
        if (!arg->isNullOrUndefined())
            return ctx->throwTypeError();
    } else {
        len = ArrayPrototype::getLength(ctx, arr);
    }

    ScopedCallData callData(scope, len);

    if (len) {
        if (!(arr->flags & SimpleArray) || arr->protoHasArray() || arr->hasAccessorProperty) {
            for (quint32 i = 0; i < len; ++i)
                callData->args[i] = arr->getIndexed(i);
        } else {
            int alen = qMin(len, arr->arrayDataLen);
            for (int i = 0; i < alen; ++i)
                callData->args[i] = arr->arrayData[i].value;
            for (quint32 i = alen; i < len; ++i)
                callData->args[i] = Primitive::undefinedValue();
        }
    }

    callData->thisObject = ctx->argument(0);
    return o->call(callData);
}
QString Stringify::Str(const QString &key, ValueRef v)
{
    Scope scope(ctx);

    ScopedValue value(scope, *v);
    ScopedObject o(scope, value);
    if (o) {
        ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toJSON")));
        Scoped<FunctionObject> toJSON(scope, o->get(s.getPointer()));
        if (!!toJSON) {
            ScopedCallData callData(scope, 1);
            callData->thisObject = value;
            callData->args[0] = ctx->d()->engine->newString(key);
            value = toJSON->call(callData);
        }
    }

    if (replacerFunction) {
        ScopedObject holder(scope, ctx->d()->engine->newObject());
        holder->put(ctx, QString(), value);
        ScopedCallData callData(scope, 2);
        callData->args[0] = ctx->d()->engine->newString(key);
        callData->args[1] = value;
        callData->thisObject = holder;
        value = replacerFunction->call(callData);
    }

    o = value.asReturnedValue();
    if (o) {
        if (NumberObject *n = o->asNumberObject())
            value = n->value();
        else if (StringObject *so = o->asStringObject())
            value = so->d()->value;
        else if (BooleanObject *b =o->asBooleanObject())
            value = b->value();
    }

    if (value->isNull())
        return QStringLiteral("null");
    if (value->isBoolean())
        return value->booleanValue() ? QStringLiteral("true") : QStringLiteral("false");
    if (value->isString())
        return quote(value->stringValue()->toQString());

    if (value->isNumber()) {
        double d = value->toNumber();
        return std::isfinite(d) ? value->toString(ctx)->toQString() : QStringLiteral("null");
    }

    o = value.asReturnedValue();
    if (o) {
        if (!o->asFunctionObject()) {
            if (o->asArrayObject()) {
                ScopedArrayObject a(scope, o);
                return JA(a);
            } else {
                return JO(o);
            }
        }
    }

    return QString();
}