From cea4a039d713173d423c35fa56a6994a4ebefd2c Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 5 Jan 2017 13:06:23 +0100 Subject: Convert builtins in TypedArray, ArrayBuffer and DataView Change-Id: I091020406f438f2dedf9ccae950fb328f2cf5522 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4arraybuffer.cpp | 69 +++++++++--------- src/qml/jsruntime/qv4arraybuffer_p.h | 8 +-- src/qml/jsruntime/qv4dataview.cpp | 133 ++++++++++++++++------------------- src/qml/jsruntime/qv4dataview_p.h | 18 ++--- src/qml/jsruntime/qv4object.cpp | 21 ++++++ src/qml/jsruntime/qv4object_p.h | 4 ++ src/qml/jsruntime/qv4typedarray.cpp | 101 +++++++++++++------------- src/qml/jsruntime/qv4typedarray_p.h | 12 ++-- 8 files changed, 186 insertions(+), 180 deletions(-) diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp index 23075aa78c..ffe9aa846f 100644 --- a/src/qml/jsruntime/qv4arraybuffer.cpp +++ b/src/qml/jsruntime/qv4arraybuffer.cpp @@ -81,16 +81,19 @@ void ArrayBufferCtor::call(const Managed *that, Scope &scope, CallData *callData construct(that, scope, callData); } -ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx) +void ArrayBufferCtor::method_isView(const BuiltinFunction *, Scope &scope, CallData *callData) { - QV4::Scope scope(ctx); - QV4::Scoped a(scope, ctx->argument(0)); - if (!!a) - return Encode(true); - QV4::Scoped v(scope, ctx->argument(0)); - if (!!v) - return Encode(true); - return Encode(false); + QV4::Scoped a(scope, callData->argument(0)); + if (!!a) { + scope.result = Encode(true); + return; + } + QV4::Scoped v(scope, callData->argument(0)); + if (!!v) { + scope.result = Encode(true); + return; + } + scope.result = Encode(false); } @@ -160,54 +163,48 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("toString"), method_toString, 0); } -ReturnedValue ArrayBufferPrototype::method_get_byteLength(CallContext *ctx) +void ArrayBufferPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->data->size); + scope.result = Encode(v->d()->data->size); } -ReturnedValue ArrayBufferPrototype::method_slice(CallContext *ctx) +void ArrayBufferPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped a(scope, ctx->thisObject()); + Scoped a(scope, callData->thisObject); if (!a) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - double start = ctx->argc() > 0 ? ctx->args()[0].toInteger() : 0; - double end = (ctx->argc() < 2 || ctx->args()[1].isUndefined()) ? - a->d()->data->size : ctx->args()[1].toInteger(); - if (scope.engine->hasException) - return Encode::undefined(); + double start = callData->argc > 0 ? callData->args[0].toInteger() : 0; + double end = (callData->argc < 2 || callData->args[1].isUndefined()) ? + a->d()->data->size : callData->args[1].toInteger(); + CHECK_EXCEPTION(); double first = (start < 0) ? qMax(a->d()->data->size + start, 0.) : qMin(start, (double)a->d()->data->size); double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size); ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor())); if (!constructor) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - ScopedCallData callData(scope, 1); + ScopedCallData cData(scope, 1); double newLen = qMax(final - first, 0.); - callData->args[0] = QV4::Encode(newLen); - constructor->construct(scope, callData); - QV4::Scoped newBuffer(scope, scope.result.asReturnedValue()); + cData->args[0] = QV4::Encode(newLen); + constructor->construct(scope, cData); + QV4::Scoped newBuffer(scope, scope.result); if (!newBuffer || newBuffer->d()->data->size < (int)newLen) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen); - - return newBuffer.asReturnedValue(); } -ReturnedValue ArrayBufferPrototype::method_toString(CallContext *ctx) +void ArrayBufferPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped a(scope, ctx->thisObject()); + Scoped a(scope, callData->thisObject); if (!a) - return Encode::undefined(); - return Encode(ctx->engine()->newString(QString::fromUtf8(a->asByteArray()))); + RETURN_UNDEFINED(); + scope.result = scope.engine->newString(QString::fromUtf8(a->asByteArray())); } diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index bc56d1ea31..4f7926d3dc 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -81,7 +81,7 @@ struct ArrayBufferCtor: FunctionObject static void construct(const Managed *m, Scope &scope, CallData *callData); static void call(const Managed *that, Scope &scope, CallData *callData); - static ReturnedValue method_isView(CallContext *ctx); + static void method_isView(const BuiltinFunction *, Scope &scope, CallData *callData); }; @@ -104,9 +104,9 @@ struct ArrayBufferPrototype: Object { void init(ExecutionEngine *engine, Object *ctor); - static ReturnedValue method_get_byteLength(CallContext *ctx); - static ReturnedValue method_slice(CallContext *ctx); - static ReturnedValue method_toString(CallContext *ctx); + static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index db8376272d..a810b38f24 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -129,90 +129,84 @@ void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("setUInt32"), method_set, 0); } -ReturnedValue DataViewPrototype::method_get_buffer(CallContext *ctx) +void DataViewPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->buffer->asReturnedValue()); + scope.result = v->d()->buffer; } -ReturnedValue DataViewPrototype::method_get_byteLength(CallContext *ctx) +void DataViewPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->byteLength); + scope.result = Encode(v->d()->byteLength); } -ReturnedValue DataViewPrototype::method_get_byteOffset(CallContext *ctx) +void DataViewPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->byteOffset); + scope.result = Encode(v->d()->byteOffset); } template -ReturnedValue DataViewPrototype::method_getChar(CallContext *ctx) +void DataViewPrototype::method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); - if (!v || ctx->argc() < 1) - return scope.engine->throwTypeError(); - double l = ctx->args()[0].toNumber(); + Scoped v(scope, callData->thisObject); + if (!v || callData->argc < 1) + THROW_TYPE_ERROR(); + double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); idx += v->d()->byteOffset; T t = T(v->d()->buffer->data->data()[idx]); - return Encode((int)t); + scope.result = Encode((int)t); } template -ReturnedValue DataViewPrototype::method_get(CallContext *ctx) +void DataViewPrototype::method_get(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); - if (!v || ctx->argc() < 1) - return scope.engine->throwTypeError(); - double l = ctx->args()[0].toNumber(); + Scoped v(scope, callData->thisObject); + if (!v || callData->argc < 1) + THROW_TYPE_ERROR(); + double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); idx += v->d()->byteOffset; - bool littleEndian = ctx->argc() < 2 ? false : ctx->args()[1].toBoolean(); + bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean(); T t = littleEndian ? qFromLittleEndian((uchar *)v->d()->buffer->data->data() + idx) : qFromBigEndian((uchar *)v->d()->buffer->data->data() + idx); - return Encode(t); + scope.result = Encode(t); } template -ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx) +void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); - if (!v || ctx->argc() < 1) - return scope.engine->throwTypeError(); - double l = ctx->args()[0].toNumber(); + Scoped v(scope, callData->thisObject); + if (!v || callData->argc < 1) + THROW_TYPE_ERROR(); + double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); idx += v->d()->byteOffset; - bool littleEndian = ctx->argc() < 2 ? false : ctx->args()[1].toBoolean(); + bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean(); if (sizeof(T) == 4) { // float @@ -223,7 +217,7 @@ ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx) u.i = littleEndian ? qFromLittleEndian((uchar *)v->d()->buffer->data->data() + idx) : qFromBigEndian((uchar *)v->d()->buffer->data->data() + idx); - return Encode(u.f); + scope.result = Encode(u.f); } else { Q_ASSERT(sizeof(T) == 8); union { @@ -233,69 +227,66 @@ ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx) u.i = littleEndian ? qFromLittleEndian((uchar *)v->d()->buffer->data->data() + idx) : qFromBigEndian((uchar *)v->d()->buffer->data->data() + idx); - return Encode(u.d); + scope.result = Encode(u.d); } } template -ReturnedValue DataViewPrototype::method_setChar(CallContext *ctx) +void DataViewPrototype::method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); - if (!v || ctx->argc() < 1) - return scope.engine->throwTypeError(); - double l = ctx->args()[0].toNumber(); + Scoped v(scope, callData->thisObject); + if (!v || callData->argc < 1) + THROW_TYPE_ERROR(); + double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); idx += v->d()->byteOffset; - int val = ctx->argc() >= 2 ? ctx->args()[1].toInt32() : 0; + int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0; v->d()->buffer->data->data()[idx] = (char)val; - return Encode::undefined(); + RETURN_UNDEFINED(); } template -ReturnedValue DataViewPrototype::method_set(CallContext *ctx) +void DataViewPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); - if (!v || ctx->argc() < 1) - return scope.engine->throwTypeError(); - double l = ctx->args()[0].toNumber(); + Scoped v(scope, callData->thisObject); + if (!v || callData->argc < 1) + THROW_TYPE_ERROR(); + double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); idx += v->d()->byteOffset; - int val = ctx->argc() >= 2 ? ctx->args()[1].toInt32() : 0; + int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0; - bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean(); + bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean(); if (littleEndian) qToLittleEndian(val, (uchar *)v->d()->buffer->data->data() + idx); else qToBigEndian(val, (uchar *)v->d()->buffer->data->data() + idx); - return Encode::undefined(); + RETURN_UNDEFINED(); } template -ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx) +void DataViewPrototype::method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); - if (!v || ctx->argc() < 1) - return scope.engine->throwTypeError(); - double l = ctx->args()[0].toNumber(); + Scoped v(scope, callData->thisObject); + if (!v || callData->argc < 1) + THROW_TYPE_ERROR(); + double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); idx += v->d()->byteOffset; - double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qt_qnan(); - bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean(); + double val = callData->argc >= 2 ? callData->args[1].toNumber() : qt_qnan(); + bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean(); if (sizeof(T) == 4) { // float @@ -320,5 +311,5 @@ ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx) else qToBigEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx); } - return Encode::undefined(); + RETURN_UNDEFINED(); } diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h index 246124394a..11cc0a6bd9 100644 --- a/src/qml/jsruntime/qv4dataview_p.h +++ b/src/qml/jsruntime/qv4dataview_p.h @@ -92,21 +92,21 @@ struct DataViewPrototype: Object { void init(ExecutionEngine *engine, Object *ctor); - static ReturnedValue method_get_buffer(CallContext *ctx); - static ReturnedValue method_get_byteLength(CallContext *ctx); - static ReturnedValue method_get_byteOffset(CallContext *ctx); + static void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData); template - static ReturnedValue method_getChar(CallContext *ctx); + static void method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData); template - static ReturnedValue method_get(CallContext *ctx); + static void method_get(const BuiltinFunction *, Scope &scope, CallData *callData); template - static ReturnedValue method_getFloat(CallContext *ctx); + static void method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData); template - static ReturnedValue method_setChar(CallContext *ctx); + static void method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData); template - static ReturnedValue method_set(CallContext *ctx); + static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData); template - static ReturnedValue method_setFloat(CallContext *ctx); + static void method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index cb13069ca0..5d6c479477 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -216,6 +216,27 @@ void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(CallCo insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable); } +void Object::defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *), + void (*setter)(const BuiltinFunction *, Scope &, CallData *)) +{ + ExecutionEngine *e = engine(); + Scope scope(e); + ScopedString s(scope, e->newIdentifier(name)); + defineAccessorProperty(s, getter, setter); +} + +void Object::defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *), + void (*setter)(const BuiltinFunction *, Scope &, CallData *)) +{ + ExecutionEngine *v4 = engine(); + QV4::Scope scope(v4); + ScopedProperty p(scope); + ExecutionContext *global = v4->rootContext(); + p->setGetter(ScopedFunctionObject(scope, (getter ? BuiltinFunction::create(global, name, getter) : 0))); + p->setSetter(ScopedFunctionObject(scope, (setter ? BuiltinFunction::create(global, name, setter) : 0))); + insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable); +} + void Object::defineReadonlyProperty(const QString &name, const Value &value) { QV4::ExecutionEngine *e = engine(); diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index cf9d7bbcdf..4a78690f47 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -243,6 +243,10 @@ struct Q_QML_EXPORT Object: Managed { void defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0); void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *)); void defineAccessorProperty(String *name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *)); + void defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *), + void (*setter)(const BuiltinFunction *, Scope &, CallData *)); + void defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *), + void (*setter)(const BuiltinFunction *, Scope &, CallData *)); /* Fixed: Writable: false, Enumerable: false, Configurable: false */ void defineReadonlyProperty(const QString &name, const Value &value); void defineReadonlyProperty(String *name, const Value &value); diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index 009c573bf8..cecd1e6958 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -438,79 +438,74 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor) defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0); } -ReturnedValue TypedArrayPrototype::method_get_buffer(CallContext *ctx) +void TypedArrayPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->buffer->asReturnedValue()); + scope.result = v->d()->buffer; } -ReturnedValue TypedArrayPrototype::method_get_byteLength(CallContext *ctx) +void TypedArrayPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->byteLength); + scope.result = Encode(v->d()->byteLength); } -ReturnedValue TypedArrayPrototype::method_get_byteOffset(CallContext *ctx) +void TypedArrayPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->byteOffset); + scope.result = Encode(v->d()->byteOffset); } -ReturnedValue TypedArrayPrototype::method_get_length(CallContext *ctx) +void TypedArrayPrototype::method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped v(scope, ctx->thisObject()); + Scoped v(scope, callData->thisObject); if (!v) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); - return Encode(v->d()->byteLength/v->d()->type->bytesPerElement); + scope.result = Encode(v->d()->byteLength/v->d()->type->bytesPerElement); } -ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx) +void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped a(scope, ctx->thisObject()); + Scoped a(scope, callData->thisObject); if (!a) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); Scoped buffer(scope, a->d()->buffer); if (!buffer) scope.engine->throwTypeError(); - double doffset = ctx->argc() >= 2 ? ctx->args()[1].toInteger() : 0; + double doffset = callData->argc >= 2 ? callData->args[1].toInteger() : 0; if (scope.engine->hasException) - return Encode::undefined(); + RETURN_UNDEFINED(); if (doffset < 0 || doffset >= UINT_MAX) - return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")); + RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); uint offset = (uint)doffset; uint elementSize = a->d()->type->bytesPerElement; - Scoped srcTypedArray(scope, ctx->args()[0]); + Scoped srcTypedArray(scope, callData->args[0]); if (!srcTypedArray) { // src is a regular object - ScopedObject o(scope, ctx->args()[0].toObject(scope.engine)); + ScopedObject o(scope, callData->args[0].toObject(scope.engine)); if (scope.engine->hasException || !o) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); double len = ScopedValue(scope, o->get(scope.engine->id_length()))->toNumber(); uint l = (uint)len; if (scope.engine->hasException || l != len) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); if (offset + l > a->length()) - return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")); + RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); uint idx = 0; char *b = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize; @@ -519,28 +514,28 @@ ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx) val = o->getIndexed(idx); a->d()->type->write(scope.engine, b, 0, val); if (scope.engine->hasException) - return Encode::undefined(); + RETURN_UNDEFINED(); ++idx; b += elementSize; } - return Encode::undefined(); + RETURN_UNDEFINED(); } // src is a typed array Scoped srcBuffer(scope, srcTypedArray->d()->buffer); if (!srcBuffer) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); uint l = srcTypedArray->length(); if (offset + l > a->length()) - return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")); + RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); char *dest = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize; const char *src = srcBuffer->d()->data->data() + srcTypedArray->d()->byteOffset; if (srcTypedArray->d()->type == a->d()->type) { // same type of typed arrays, use memmove (as srcbuffer and buffer could be the same) memmove(dest, src, srcTypedArray->d()->byteLength); - return Encode::undefined(); + RETURN_UNDEFINED(); } char *srcCopy = 0; @@ -564,28 +559,27 @@ ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx) if (srcCopy) delete [] srcCopy; - return Encode::undefined(); + RETURN_UNDEFINED(); } -ReturnedValue TypedArrayPrototype::method_subarray(CallContext *ctx) +void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData) { - Scope scope(ctx); - Scoped a(scope, ctx->thisObject()); + Scoped a(scope, callData->thisObject); if (!a) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); Scoped buffer(scope, a->d()->buffer); if (!buffer) - return scope.engine->throwTypeError(); + THROW_TYPE_ERROR(); int len = a->length(); - double b = ctx->argc() > 0 ? ctx->args()[0].toInteger() : 0; + double b = callData->argc > 0 ? callData->args[0].toInteger() : 0; if (b < 0) b = len + b; uint begin = (uint)qBound(0., b, (double)len); - double e = ctx->argc() < 2 || ctx->args()[1].isUndefined() ? len : ctx->args()[1].toInteger(); + double e = callData->argc < 2 || callData->args[1].isUndefined() ? len : callData->args[1].toInteger(); if (e < 0) e = len + e; uint end = (uint)qBound(0., e, (double)len); @@ -593,18 +587,17 @@ ReturnedValue TypedArrayPrototype::method_subarray(CallContext *ctx) end = begin; if (scope.engine->hasException) - return Encode::undefined(); + RETURN_UNDEFINED(); int newLen = end - begin; ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor())); if (!constructor) - return scope.engine->throwTypeError(); - - ScopedCallData callData(scope, 3); - callData->args[0] = buffer; - callData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement); - callData->args[2] = Encode(newLen); - constructor->construct(scope, callData); - return scope.result.asReturnedValue(); + THROW_TYPE_ERROR(); + + ScopedCallData cData(scope, 3); + cData->args[0] = buffer; + cData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement); + cData->args[2] = Encode(newLen); + constructor->construct(scope, cData); } diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index 0112d2e4a1..eefed2db4b 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -151,13 +151,13 @@ struct TypedArrayPrototype : Object void init(ExecutionEngine *engine, TypedArrayCtor *ctor); - static ReturnedValue method_get_buffer(CallContext *ctx); - static ReturnedValue method_get_byteLength(CallContext *ctx); - static ReturnedValue method_get_byteOffset(CallContext *ctx); - static ReturnedValue method_get_length(CallContext *ctx); + static void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData); - static ReturnedValue method_set(CallContext *ctx); - static ReturnedValue method_subarray(CallContext *ctx); + static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData); + static void method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData); }; inline void -- cgit v1.2.3