diff options
Diffstat (limited to 'src/qml/jsruntime/qv4arrayobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 93 |
1 files changed, 86 insertions, 7 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 4d15c6c137..20ba11fd75 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -49,9 +49,9 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(ArrayCtor); -Heap::ArrayCtor::ArrayCtor(QV4::ExecutionContext *scope) - : Heap::FunctionObject(scope, QStringLiteral("Array")) +void Heap::ArrayCtor::init(QV4::ExecutionContext *scope) { + Heap::FunctionObject::init(scope, QStringLiteral("Array")); } void ArrayCtor::construct(const Managed *m, Scope &scope, CallData *callData) @@ -96,6 +96,8 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(engine->id_toString(), method_toString, 0); defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString, 0); defineDefaultProperty(QStringLiteral("concat"), method_concat, 1); + defineDefaultProperty(QStringLiteral("find"), method_find, 1); + defineDefaultProperty(QStringLiteral("findIndex"), method_findIndex, 1); defineDefaultProperty(QStringLiteral("join"), method_join, 1); defineDefaultProperty(QStringLiteral("pop"), method_pop, 0); defineDefaultProperty(QStringLiteral("push"), method_push, 1); @@ -182,10 +184,88 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx) return result.asReturnedValue(); } +ReturnedValue ArrayPrototype::method_find(CallContext *ctx) +{ + Scope scope(ctx); + ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine)); + if (!instance) + return Encode::undefined(); + + uint len = instance->getLength(); + + ScopedFunctionObject callback(scope, ctx->argument(0)); + if (!callback) + return ctx->engine()->throwTypeError(); + + ScopedCallData callData(scope, 3); + callData->thisObject = ctx->argument(1); + callData->args[2] = instance; + + ScopedValue v(scope); + + for (uint k = 0; k < len; ++k) { + v = instance->getIndexed(k); + if (scope.hasException()) + return Encode::undefined(); + + callData->args[0] = v; + callData->args[1] = Primitive::fromDouble(k); + callback->call(scope, callData); + + if (scope.hasException()) + return Encode::undefined(); + else if (scope.result.toBoolean()) + return v->asReturnedValue(); + } + + return Encode::undefined(); +} + +ReturnedValue ArrayPrototype::method_findIndex(CallContext *ctx) +{ + Scope scope(ctx); + ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine)); + if (!instance) + return Encode::undefined(); + + uint len = instance->getLength(); + + ScopedFunctionObject callback(scope, ctx->argument(0)); + if (!callback) + return ctx->engine()->throwTypeError(); + + ScopedCallData callData(scope, 3); + callData->thisObject = ctx->argument(1); + callData->args[2] = instance; + + ScopedValue v(scope); + + for (uint k = 0; k < len; ++k) { + v = instance->getIndexed(k); + if (scope.hasException()) + return Encode::undefined(); + + callData->args[0] = v; + callData->args[1] = Primitive::fromDouble(k); + callback->call(scope, callData); + + if (scope.hasException()) + return Encode::undefined(); + else if (scope.result.toBoolean()) + return Encode(k); + } + + return Encode(-1); +} + ReturnedValue ArrayPrototype::method_join(CallContext *ctx) { Scope scope(ctx); ScopedValue arg(scope, ctx->argument(0)); + ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine)); + + if (!instance) + return ctx->d()->engine->newString()->asReturnedValue(); QString r4; if (arg->isUndefined()) @@ -193,8 +273,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx) else r4 = arg->toQString(); - ScopedObject self(scope, ctx->thisObject()); - ScopedValue length(scope, self->get(ctx->d()->engine->id_length())); + ScopedValue length(scope, instance->get(ctx->d()->engine->id_length())); const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32(); if (!r2) @@ -203,7 +282,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx) QString R; // ### FIXME - if (ArrayObject *a = self->as<ArrayObject>()) { + if (ArrayObject *a = instance->as<ArrayObject>()) { ScopedValue e(scope); for (uint i = 0; i < a->getLength(); ++i) { if (i) @@ -220,7 +299,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx) // crazy! // ScopedString name(scope, ctx->d()->engine->newString(QStringLiteral("0"))); - ScopedValue r6(scope, self->get(name)); + ScopedValue r6(scope, instance->get(name)); if (!r6->isNullOrUndefined()) R = r6->toQString(); @@ -229,7 +308,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx) R += r4; name = Primitive::fromDouble(k).toString(scope.engine); - r12 = self->get(name); + r12 = instance->get(name); if (scope.hasException()) return Encode::undefined(); |