diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-01-25 14:30:30 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-01-25 14:31:06 +0100 |
commit | 00d3f3e9da071efce92d320884b331ea559fb292 (patch) | |
tree | 0649bd5c1be5a8ca01617655ac54c6373322f14a /src/qml/jsruntime/qv4functionobject.cpp | |
parent | 5c2ba6db53b2190160081695faff521bc367e33d (diff) | |
parent | b07a6cf8c5788b7e4ca722c9aa8c06e76e688c5d (diff) |
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Change-Id: I7b6437740077a4e2c9b2c36ee1cd4eb472f1f49f
Diffstat (limited to 'src/qml/jsruntime/qv4functionobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 134 |
1 files changed, 78 insertions, 56 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 64f7b98618..b2d89220ea 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -270,23 +270,22 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor) } -ReturnedValue FunctionPrototype::method_toString(CallContext *ctx) +void FunctionPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *fun = ctx->thisObject().as<FunctionObject>(); + FunctionObject *fun = callData->thisObject.as<FunctionObject>(); if (!fun) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - return ctx->d()->engine->newString(QStringLiteral("function() { [code] }"))->asReturnedValue(); + scope.result = scope.engine->newString(QStringLiteral("function() { [code] }")); } -ReturnedValue FunctionPrototype::method_apply(CallContext *ctx) +void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *o = ctx->thisObject().as<FunctionObject>(); + FunctionObject *o = callData->thisObject.as<FunctionObject>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - Scope scope(ctx); - ScopedValue arg(scope, ctx->argument(1)); + ScopedValue arg(scope, callData->argument(1)); ScopedObject arr(scope, arg); @@ -294,75 +293,71 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx) if (!arr) { len = 0; if (!arg->isNullOrUndefined()) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); } else { len = arr->getLength(); } - ScopedCallData callData(scope, len); + ScopedCallData cData(scope, len); if (len) { if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) { QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>(); int l = qMin(len, (uint)a->d()->context->callData->argc); - memcpy(callData->args, a->d()->context->callData->args, l*sizeof(Value)); + memcpy(cData->args, a->d()->context->callData->args, l*sizeof(Value)); for (quint32 i = l; i < len; ++i) - callData->args[i] = Primitive::undefinedValue(); + cData->args[i] = Primitive::undefinedValue(); } else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) { auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData()); uint alen = sad ? sad->len : 0; if (alen > len) alen = len; for (uint i = 0; i < alen; ++i) - callData->args[i] = sad->data(i); + cData->args[i] = sad->data(i); for (quint32 i = alen; i < len; ++i) - callData->args[i] = Primitive::undefinedValue(); + cData->args[i] = Primitive::undefinedValue(); } else { for (quint32 i = 0; i < len; ++i) - callData->args[i] = arr->getIndexed(i); + cData->args[i] = arr->getIndexed(i); } } - callData->thisObject = ctx->argument(0); - o->call(scope, callData); - return scope.result.asReturnedValue(); + cData->thisObject = callData->argument(0); + o->call(scope, cData); } -ReturnedValue FunctionPrototype::method_call(CallContext *ctx) +void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *o = ctx->thisObject().as<FunctionObject>(); + FunctionObject *o = callData->thisObject.as<FunctionObject>(); if (!o) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - Scope scope(ctx); - ScopedCallData callData(scope, ctx->argc() ? ctx->argc() - 1 : 0); - if (ctx->argc()) { - for (int i = 1; i < ctx->argc(); ++i) - callData->args[i - 1] = ctx->args()[i]; + ScopedCallData cData(scope, callData->argc ? callData->argc - 1 : 0); + if (callData->argc) { + for (int i = 1; i < callData->argc; ++i) + cData->args[i - 1] = callData->args[i]; } - callData->thisObject = ctx->argument(0); + cData->thisObject = callData->argument(0); - o->call(scope, callData); - return scope.result.asReturnedValue(); + o->call(scope, cData); } -ReturnedValue FunctionPrototype::method_bind(CallContext *ctx) +void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallData *callData) { - FunctionObject *target = ctx->thisObject().as<FunctionObject>(); + FunctionObject *target = callData->thisObject.as<FunctionObject>(); if (!target) - return ctx->engine()->throwTypeError(); + THROW_TYPE_ERROR(); - Scope scope(ctx); - ScopedValue boundThis(scope, ctx->argument(0)); + ScopedValue boundThis(scope, callData->argument(0)); Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)0); - if (ctx->argc() > 1) { - boundArgs = MemberData::allocate(scope.engine, ctx->argc() - 1); - boundArgs->d()->size = ctx->argc() - 1; - memcpy(boundArgs->data(), ctx->args() + 1, (ctx->argc() - 1)*sizeof(Value)); + if (callData->argc > 1) { + boundArgs = MemberData::allocate(scope.engine, callData->argc - 1); + boundArgs->d()->size = callData->argc - 1; + memcpy(boundArgs->data(), callData->args + 1, (callData->argc - 1)*sizeof(Value)); } ExecutionContext *global = scope.engine->rootContext(); - return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue(); + scope.result = BoundFunction::create(global, target, boundThis, boundArgs); } DEFINE_OBJECT_VTABLE(ScriptFunction); @@ -459,22 +454,22 @@ Heap::Object *ScriptFunction::protoForConstructor() const -DEFINE_OBJECT_VTABLE(BuiltinFunction); +DEFINE_OBJECT_VTABLE(OldBuiltinFunction); -void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *)) +void Heap::OldBuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *)) { Heap::FunctionObject::init(scope, name); this->code = code; } -void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *) +void OldBuiltinFunction::construct(const Managed *f, Scope &scope, CallData *) { - scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError(); + scope.result = static_cast<const OldBuiltinFunction *>(f)->internalClass()->engine->throwTypeError(); } -void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData) +void OldBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData) { - const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that); + const OldBuiltinFunction *f = static_cast<const OldBuiltinFunction *>(that); ExecutionEngine *v4 = scope.engine; if (v4->hasException) { scope.result = Encode::undefined(); @@ -484,15 +479,41 @@ void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData ExecutionContextSaver ctxSaver(scope); - CallContext::Data ctx = CallContext::Data::createOnStack(v4); - ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context? - ctx.callData = callData; - v4->pushContext(&ctx); - Q_ASSERT(v4->current == &ctx); + CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext(v4); + ctx->strictMode = f->scope()->strictMode; // ### needed? scope or parent context? + ctx->callData = callData; + v4->pushContext(ctx); + Q_ASSERT(v4->current == ctx); scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext)); + v4->memoryManager->freeSimpleCallContext(); +} + +DEFINE_OBJECT_VTABLE(BuiltinFunction); + +void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *)) +{ + Heap::FunctionObject::init(scope, name); + this->code = code; +} + +void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *) +{ + scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError(); +} + +void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData) +{ + const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that); + ExecutionEngine *v4 = scope.engine; + if (v4->hasException) { + scope.result = Encode::undefined(); + return; + } + f->d()->code(f, scope, callData); } + void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData) { const IndexedBuiltinFunction *f = static_cast<const IndexedBuiltinFunction *>(that); @@ -505,13 +526,14 @@ void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *c ExecutionContextSaver ctxSaver(scope); - CallContext::Data ctx = CallContext::Data::createOnStack(v4); - ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context? - ctx.callData = callData; - v4->pushContext(&ctx); - Q_ASSERT(v4->current == &ctx); + CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext(v4); + ctx->strictMode = f->scope()->strictMode; // ### needed? scope or parent context? + ctx->callData = callData; + v4->pushContext(ctx); + Q_ASSERT(v4->current == ctx); scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext), f->d()->index); + v4->memoryManager->freeSimpleCallContext(); } DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction); |