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; }
/*! 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); }
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); } }
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); }
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(); }