diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-04 18:53:51 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-08 18:58:14 +0000 |
commit | 50e7badd5f261bd69db9d8f03d5651e346087218 (patch) | |
tree | 73c2771fbc98168280182e77337b06efa39f4a7b /src/qml | |
parent | 8abb6c41bf055d59c6b57a809e3b027293568848 (diff) |
Remove Scope::result and convert calling convention for builtins
Allow for faster calling of builtins, and completely avoid
scope creation in many cases.
Change-Id: I0f1681e19e9908db10def85a74e134a87fc2e44c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
65 files changed, 1951 insertions, 1747 deletions
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp index 05a7176061..3f0ff10e58 100644 --- a/src/qml/jsruntime/qv4arraybuffer.cpp +++ b/src/qml/jsruntime/qv4arraybuffer.cpp @@ -77,19 +77,16 @@ ReturnedValue ArrayBufferCtor::call(const Managed *that, CallData *callData) return construct(that, callData); } -void ArrayBufferCtor::method_isView(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayBufferCtor::method_isView(const BuiltinFunction *, CallData *callData) { - QV4::Scoped<TypedArray> a(scope, callData->argument(0)); - if (!!a) { - scope.result = Encode(true); - return; - } - QV4::Scoped<DataView> v(scope, callData->argument(0)); - if (!!v) { - scope.result = Encode(true); - return; - } - scope.result = Encode(false); + if (callData->argc < 1) + return Encode(false); + + if (callData->args[0].as<TypedArray>() || + callData->args[0].as<DataView>()) + return Encode(true); + + return Encode(false); } @@ -159,47 +156,52 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("toString"), method_toString, 0); } -void ArrayBufferPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayBufferPrototype::method_get_byteLength(const BuiltinFunction *b, CallData *callData) { - Scoped<ArrayBuffer> v(scope, callData->thisObject); - if (!v) - THROW_TYPE_ERROR(); + ArrayBuffer *a = callData->thisObject.as<ArrayBuffer>(); + if (!a) + return b->engine()->throwTypeError(); - scope.result = Encode(v->d()->data->size); + return Encode(a->d()->data->size); } -void ArrayBufferPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayBufferPrototype::method_slice(const BuiltinFunction *b, CallData *callData) { - Scoped<ArrayBuffer> a(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + ArrayBuffer *a = callData->thisObject.as<ArrayBuffer>(); if (!a) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); 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(); + if (v4->hasException) + return QV4::Encode::undefined(); 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); + Scope scope(v4); ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor())); if (!constructor) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); ScopedCallData cData(scope, 1); double newLen = qMax(final - first, 0.); cData->args[0] = QV4::Encode(newLen); QV4::Scoped<ArrayBuffer> newBuffer(scope, constructor->construct(cData)); if (!newBuffer || newBuffer->d()->data->size < (int)newLen) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen); + return Encode::undefined(); } -void ArrayBufferPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayBufferPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { - Scoped<ArrayBuffer> a(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + ArrayBuffer *a = callData->thisObject.as<ArrayBuffer>(); if (!a) RETURN_UNDEFINED(); - scope.result = scope.engine->newString(QString::fromUtf8(a->asByteArray())); + return Encode(v4->newString(QString::fromUtf8(a->asByteArray()))); } diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index 1b3f09dea8..b35324c472 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -81,7 +81,7 @@ struct ArrayBufferCtor: FunctionObject static ReturnedValue construct(const Managed *m, CallData *callData); static ReturnedValue call(const Managed *that, CallData *callData); - static void method_isView(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_isView(const BuiltinFunction *, CallData *callData); }; @@ -104,9 +104,9 @@ struct ArrayBufferPrototype: Object { void init(ExecutionEngine *engine, Object *ctor); - 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); + static ReturnedValue method_get_byteLength(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_slice(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 4663faa640..7e32c948ac 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -118,14 +118,15 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1); } -void ArrayPrototype::method_isArray(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_isArray(const BuiltinFunction *, CallData *callData) { bool isArray = callData->argc && callData->args[0].as<ArrayObject>(); - scope.result = Encode(isArray); + return Encode(isArray); } -void ArrayPrototype::method_toString(const BuiltinFunction *builtin, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_toString(const BuiltinFunction *builtin, CallData *callData) { + Scope scope(builtin); ScopedObject o(scope, callData->thisObject, ScopedObject::Convert); CHECK_EXCEPTION(); ScopedString s(scope, scope.engine->newString(QStringLiteral("join"))); @@ -133,19 +134,19 @@ void ArrayPrototype::method_toString(const BuiltinFunction *builtin, Scope &scop if (!!f) { ScopedCallData d(scope, 0); d->thisObject = callData->thisObject; - scope.result = f->call(d); - return; + return f->call(d); } - ObjectPrototype::method_toString(builtin, scope, callData); + return ObjectPrototype::method_toString(builtin, callData); } -void ArrayPrototype::method_toLocaleString(const BuiltinFunction *builtin, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_toLocaleString(const BuiltinFunction *builtin, CallData *callData) { - return method_toString(builtin, scope, callData); + return method_toString(builtin, callData); } -void ArrayPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_concat(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject thisObject(scope, callData->thisObject.toObject(scope.engine)); if (!thisObject) RETURN_UNDEFINED(); @@ -179,11 +180,12 @@ void ArrayPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallDa } } - scope.result = result; + return result.asReturnedValue(); } -void ArrayPrototype::method_find(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_find(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -199,6 +201,7 @@ void ArrayPrototype::method_find(const BuiltinFunction *, Scope &scope, CallData cData->args[2] = instance; ScopedValue v(scope); + ScopedValue result(scope); for (uint k = 0; k < len; ++k) { v = instance->getIndexed(k); @@ -206,18 +209,19 @@ void ArrayPrototype::method_find(const BuiltinFunction *, Scope &scope, CallData cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - scope.result = callback->call(cData); + result = callback->call(cData); CHECK_EXCEPTION(); - if (scope.result.toBoolean()) - RETURN_RESULT(v); + if (result->toBoolean()) + return v->asReturnedValue(); } RETURN_UNDEFINED(); } -void ArrayPrototype::method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_findIndex(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -233,6 +237,7 @@ void ArrayPrototype::method_findIndex(const BuiltinFunction *, Scope &scope, Cal cData->args[2] = instance; ScopedValue v(scope); + ScopedValue result(scope); for (uint k = 0; k < len; ++k) { v = instance->getIndexed(k); @@ -240,25 +245,24 @@ void ArrayPrototype::method_findIndex(const BuiltinFunction *, Scope &scope, Cal cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - scope.result = callback->call(cData); + result = callback->call(cData); CHECK_EXCEPTION(); - if (scope.result.toBoolean()) - RETURN_RESULT(Encode(k)); + if (result->toBoolean()) + return Encode(k); } - RETURN_RESULT(Encode(-1)); + return Encode(-1); } -void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_join(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedValue arg(scope, callData->argument(0)); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); - if (!instance) { - scope.result = scope.engine->newString(); - return; - } + if (!instance) + return Encode(scope.engine->newString()); QString r4; if (arg->isUndefined()) @@ -269,10 +273,8 @@ void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData ScopedValue length(scope, instance->get(scope.engine->id_length())); const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32(); - if (!r2) { - scope.result = scope.engine->newString(); - return; - } + if (!r2) + return Encode(scope.engine->newString()); QString R; @@ -310,11 +312,12 @@ void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData } } - scope.result = scope.engine->newString(R); + return Encode(scope.engine->newString(R)); } -void ArrayPrototype::method_pop(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_pop(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -337,11 +340,12 @@ void ArrayPrototype::method_pop(const BuiltinFunction *, Scope &scope, CallData instance->setArrayLength(len - 1); else instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1))); - scope.result = result; + return result->asReturnedValue(); } -void ArrayPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_push(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -364,11 +368,9 @@ void ArrayPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen))); else { ScopedString str(scope, scope.engine->newString(QStringLiteral("Array.prototype.push: Overflow"))); - scope.result = scope.engine->throwRangeError(str); - return; + return scope.engine->throwRangeError(str); } - scope.result = Encode(newLen); - return; + return Encode(newLen); } if (!callData->argc) @@ -386,11 +388,12 @@ void ArrayPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData else instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len))); - scope.result = Encode(len); + return Encode(len); } -void ArrayPrototype::method_reverse(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_reverse(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -416,11 +419,12 @@ void ArrayPrototype::method_reverse(const BuiltinFunction *, Scope &scope, CallD else instance->deleteIndexedProperty(hi); } - scope.result = instance; + return instance->asReturnedValue(); } -void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_shift(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -436,10 +440,11 @@ void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallDat RETURN_UNDEFINED(); } + ScopedValue result(scope); if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len && instance->arrayData()->type != Heap::ArrayData::Custom) { - scope.result = instance->arrayData()->vtable()->pop_front(instance); + result = instance->arrayData()->vtable()->pop_front(instance); } else { - scope.result = instance->getIndexed(0); + result = instance->getIndexed(0); CHECK_EXCEPTION(); ScopedValue v(scope); // do it the slow way @@ -461,10 +466,13 @@ void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallDat instance->setArrayLengthUnchecked(len - 1); else instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1))); + + return result->asReturnedValue(); } -void ArrayPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_slice(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->thisObject.toObject(scope.engine)); if (!o) RETURN_UNDEFINED(); @@ -500,11 +508,12 @@ void ArrayPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallDat result->arraySet(n, v); ++n; } - scope.result = result; + return result->asReturnedValue(); } -void ArrayPrototype::method_sort(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_sort(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -513,11 +522,12 @@ void ArrayPrototype::method_sort(const BuiltinFunction *, Scope &scope, CallData ScopedValue comparefn(scope, callData->argument(0)); ArrayData::sort(scope.engine, instance, comparefn, len); - scope.result = callData->thisObject; + return callData->thisObject.asReturnedValue(); } -void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_splice(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -587,12 +597,13 @@ void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallDa scope.engine->current->strictMode = true; instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount))); - scope.result = newArray; scope.engine->current->strictMode = wasStrict; + return newArray->asReturnedValue(); } -void ArrayPrototype::method_unshift(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_unshift(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -625,20 +636,19 @@ void ArrayPrototype::method_unshift(const BuiltinFunction *, Scope &scope, CallD else instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen))); - scope.result = Encode(newLen); + return Encode(newLen); } -void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_indexOf(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); uint len = instance->getLength(); - if (!len) { - scope.result = Encode(-1); - return; - } + if (!len) + return Encode(-1); ScopedValue searchValue(scope, callData->argument(0)); uint fromIndex = 0; @@ -646,10 +656,8 @@ void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallD if (callData->argc >= 2) { double f = callData->args[1].toInteger(); CHECK_EXCEPTION(); - if (f >= len) { - scope.result = Encode(-1); - return; - } + if (f >= len) + return Encode(-1); if (f < 0) f = qMax(len + f, 0.); fromIndex = (uint) f; @@ -660,13 +668,10 @@ void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallD for (uint k = fromIndex; k < len; ++k) { bool exists; v = instance->getIndexed(k, &exists); - if (exists && RuntimeHelpers::strictEqual(v, searchValue)) { - scope.result = Encode(k); - return; - } + if (exists && RuntimeHelpers::strictEqual(v, searchValue)) + return Encode(k); } - scope.result = Encode(-1); - return; + return Encode(-1); } ScopedValue value(scope); @@ -678,14 +683,11 @@ void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallD bool exists; value = instance->getIndexed(i, &exists); CHECK_EXCEPTION(); - if (exists && RuntimeHelpers::strictEqual(value, searchValue)) { - scope.result = Encode(i); - return; - } + if (exists && RuntimeHelpers::strictEqual(value, searchValue)) + return Encode(i); } } else if (!instance->arrayData()) { - scope.result = Encode(-1); - return; + return Encode(-1); } else { Q_ASSERT(instance->arrayType() == Heap::ArrayData::Simple || instance->arrayType() == Heap::ArrayData::Complex); Heap::SimpleArrayData *sa = instance->d()->arrayData.cast<Heap::SimpleArrayData>(); @@ -695,27 +697,24 @@ void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallD while (idx < len) { value = sa->data(idx); CHECK_EXCEPTION(); - if (RuntimeHelpers::strictEqual(value, searchValue)) { - scope.result = Encode(idx); - return; - } + if (RuntimeHelpers::strictEqual(value, searchValue)) + return Encode(idx); ++idx; } } - scope.result = Encode(-1); + return Encode(-1); } -void ArrayPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_lastIndexOf(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); uint len = instance->getLength(); - if (!len) { - scope.result = Encode(-1); - return; - } + if (!len) + return Encode(-1); ScopedValue searchValue(scope); uint fromIndex = len; @@ -732,10 +731,8 @@ void ArrayPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, C f = qMin(f, (double)(len - 1)); else if (f < 0) { f = len + f; - if (f < 0) { - scope.result = Encode(-1); - return; - } + if (f < 0) + return Encode(-1); } fromIndex = (uint) f + 1; } @@ -746,16 +743,15 @@ void ArrayPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, C bool exists; v = instance->getIndexed(k, &exists); CHECK_EXCEPTION(); - if (exists && RuntimeHelpers::strictEqual(v, searchValue)) { - scope.result = Encode(k); - return; - } + if (exists && RuntimeHelpers::strictEqual(v, searchValue)) + return Encode(k); } - scope.result = Encode(-1); + return Encode(-1); } -void ArrayPrototype::method_every(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_every(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -784,11 +780,12 @@ void ArrayPrototype::method_every(const BuiltinFunction *, Scope &scope, CallDat r = callback->call(cData); ok = r->toBoolean(); } - scope.result = Encode(ok); + return Encode(ok); } -void ArrayPrototype::method_some(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_some(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -803,6 +800,7 @@ void ArrayPrototype::method_some(const BuiltinFunction *, Scope &scope, CallData cData->thisObject = callData->argument(1); cData->args[2] = instance; ScopedValue v(scope); + ScopedValue result(scope); for (uint k = 0; k < len; ++k) { bool exists; @@ -812,17 +810,16 @@ void ArrayPrototype::method_some(const BuiltinFunction *, Scope &scope, CallData cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - scope.result = callback->call(cData); - if (scope.result.toBoolean()) { - scope.result = Encode(true); - return; - } + result = callback->call(cData); + if (result->toBoolean()) + return Encode(true); } - scope.result = Encode(false); + return Encode(false); } -void ArrayPrototype::method_forEach(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_forEach(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -846,13 +843,14 @@ void ArrayPrototype::method_forEach(const BuiltinFunction *, Scope &scope, CallD cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - scope.result = callback->call(cData); + callback->call(cData); } RETURN_UNDEFINED(); } -void ArrayPrototype::method_map(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_map(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -884,11 +882,12 @@ void ArrayPrototype::method_map(const BuiltinFunction *, Scope &scope, CallData mapped = callback->call(cData); a->arraySet(k, mapped); } - scope.result = a.asReturnedValue(); + return a.asReturnedValue(); } -void ArrayPrototype::method_filter(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_filter(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -924,11 +923,12 @@ void ArrayPrototype::method_filter(const BuiltinFunction *, Scope &scope, CallDa ++to; } } - scope.result = a.asReturnedValue(); + return a.asReturnedValue(); } -void ArrayPrototype::method_reduce(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_reduce(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -973,11 +973,12 @@ void ArrayPrototype::method_reduce(const BuiltinFunction *, Scope &scope, CallDa } ++k; } - scope.result = acc->asReturnedValue(); + return acc->asReturnedValue(); } -void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ArrayPrototype::method_reduceRight(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -991,8 +992,7 @@ void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, C if (len == 0) { if (callData->argc == 1) THROW_TYPE_ERROR(); - scope.result = callData->argument(1); - return; + return callData->argument(1); } uint k = len; @@ -1027,6 +1027,6 @@ void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, C } --k; } - scope.result = acc->asReturnedValue(); + return acc->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h index b6ee5c5dac..7c4b86dac5 100644 --- a/src/qml/jsruntime/qv4arrayobject_p.h +++ b/src/qml/jsruntime/qv4arrayobject_p.h @@ -78,30 +78,30 @@ struct ArrayPrototype: ArrayObject { void init(ExecutionEngine *engine, Object *ctor); - static void method_isArray(const BuiltinFunction *, Scope &, CallData *callData); - static void method_toString(const BuiltinFunction *, Scope &, CallData *callData); - static void method_toLocaleString(const BuiltinFunction *builtin, Scope &, CallData *callData); - static void method_concat(const BuiltinFunction *, Scope &, CallData *callData); - static void method_find(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_join(const BuiltinFunction *, Scope &, CallData *callData); - static void method_pop(const BuiltinFunction *, Scope &, CallData *callData); - static void method_push(const BuiltinFunction *, Scope &, CallData *callData); - static void method_reverse(const BuiltinFunction *, Scope &, CallData *callData); - static void method_shift(const BuiltinFunction *, Scope &, CallData *callData); - static void method_slice(const BuiltinFunction *, Scope &, CallData *callData); - static void method_sort(const BuiltinFunction *, Scope &, CallData *callData); - static void method_splice(const BuiltinFunction *, Scope &, CallData *callData); - static void method_unshift(const BuiltinFunction *, Scope &, CallData *callData); - static void method_indexOf(const BuiltinFunction *, Scope &, CallData *callData); - static void method_lastIndexOf(const BuiltinFunction *, Scope &, CallData *callData); - static void method_every(const BuiltinFunction *, Scope &, CallData *callData); - static void method_some(const BuiltinFunction *, Scope &, CallData *callData); - static void method_forEach(const BuiltinFunction *, Scope &, CallData *callData); - static void method_map(const BuiltinFunction *, Scope &, CallData *callData); - static void method_filter(const BuiltinFunction *, Scope &, CallData *callData); - static void method_reduce(const BuiltinFunction *, Scope &, CallData *callData); - static void method_reduceRight(const BuiltinFunction *, Scope &, CallData *callData); + static ReturnedValue method_isArray(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_concat(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_find(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_findIndex(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_join(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_pop(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_push(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_reverse(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_shift(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_slice(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_sort(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_splice(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_unshift(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_indexOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_lastIndexOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_every(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_some(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_forEach(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_map(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_filter(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_reduce(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_reduceRight(const BuiltinFunction *, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp index 0ed8471753..d74750fa8c 100644 --- a/src/qml/jsruntime/qv4booleanobject.cpp +++ b/src/qml/jsruntime/qv4booleanobject.cpp @@ -73,31 +73,30 @@ void BooleanPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(engine->id_valueOf(), method_valueOf); } -void BooleanPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue BooleanPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); bool result; if (callData->thisObject.isBoolean()) { result = callData->thisObject.booleanValue(); } else { const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>(); if (!thisObject) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); result = thisObject->value(); } - scope.result = result ? scope.engine->id_true() : scope.engine->id_false(); + return Encode(result ? v4->id_true() : v4->id_false()); } -void BooleanPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue BooleanPrototype::method_valueOf(const BuiltinFunction *b, CallData *callData) { - if (callData->thisObject.isBoolean()) { - scope.result = callData->thisObject.asReturnedValue(); - return; - } + if (callData->thisObject.isBoolean()) + return callData->thisObject.asReturnedValue(); const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>(); if (!thisObject) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); - scope.result = Encode(thisObject->value()); + return Encode(thisObject->value()); } diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h index 9a004c7749..78fe59cc7e 100644 --- a/src/qml/jsruntime/qv4booleanobject_p.h +++ b/src/qml/jsruntime/qv4booleanobject_p.h @@ -79,8 +79,8 @@ struct BooleanPrototype: BooleanObject V4_PROTOTYPE(objectPrototype) void init(ExecutionEngine *engine, Object *ctor); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_valueOf(const BuiltinFunction *, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index b1fb017f99..db85bc6cef 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -232,7 +232,7 @@ bool ExecutionContext::deleteProperty(String *name) } // Do a standard call with this execution context as the outer scope -void ExecutionContext::call(Scope &scope, CallData *callData, Function *function, const FunctionObject *f) +ReturnedValue ExecutionContext::call(Scope &scope, CallData *callData, Function *function, const FunctionObject *f) { ExecutionContextSaver ctxSaver(scope); @@ -241,14 +241,16 @@ void ExecutionContext::call(Scope &scope, CallData *callData, Function *function ctx->d()->function.set(scope.engine, f->d()); scope.engine->pushContext(ctx); - scope.result = Q_V4_PROFILE(scope.engine, function); + ReturnedValue res = Q_V4_PROFILE(scope.engine, function); if (function->hasQmlDependencies) QQmlPropertyCapture::registerQmlDependencies(function->compiledFunction, scope); + + return res; } // Do a simple, fast call with this execution context as the outer scope -void QV4::ExecutionContext::simpleCall(Scope &scope, CallData *callData, Function *function) +ReturnedValue QV4::ExecutionContext::simpleCall(Scope &scope, CallData *callData, Function *function) { Q_ASSERT(function->canUseSimpleFunction()); @@ -266,11 +268,13 @@ void QV4::ExecutionContext::simpleCall(Scope &scope, CallData *callData, Functio scope.engine->pushContext(ctx); Q_ASSERT(scope.engine->current == ctx); - scope.result = Q_V4_PROFILE(scope.engine, function); + ReturnedValue res = Q_V4_PROFILE(scope.engine, function); if (function->hasQmlDependencies) QQmlPropertyCapture::registerQmlDependencies(function->compiledFunction, scope); scope.engine->memoryManager->freeSimpleCallContext(); + + return res; } void ExecutionContext::setProperty(String *name, const Value &value) diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 9408f85d66..bb8f9b13fa 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -223,8 +223,8 @@ struct Q_QML_EXPORT ExecutionContext : public Managed return d()->callData->argument(i); } - void call(Scope &scope, CallData *callData, QV4::Function *function, const QV4::FunctionObject *f = 0); - void simpleCall(Scope &scope, CallData *callData, QV4::Function *function); + ReturnedValue call(Scope &scope, CallData *callData, QV4::Function *function, const QV4::FunctionObject *f = 0); + ReturnedValue simpleCall(Scope &scope, CallData *callData, QV4::Function *function); }; struct Q_QML_EXPORT CallContext : public ExecutionContext diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index b4e21b7ce5..57b5045f57 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -119,60 +119,60 @@ void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("setUInt32"), method_set<unsigned int>, 0); } -void DataViewPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_get_buffer(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); - scope.result = v->d()->buffer; + return v->d()->buffer->asReturnedValue(); } -void DataViewPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_get_byteLength(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); - scope.result = Encode(v->d()->byteLength); + return Encode(v->d()->byteLength); } -void DataViewPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_get_byteOffset(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); - scope.result = Encode(v->d()->byteOffset); + return Encode(v->d()->byteOffset); } template <typename T> -void DataViewPrototype::method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_getChar(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v || callData->argc < 1) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); idx += v->d()->byteOffset; T t = T(v->d()->buffer->data->data()[idx]); - scope.result = Encode((int)t); + return Encode((int)t); } template <typename T> -void DataViewPrototype::method_get(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_get(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v || callData->argc < 1) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); idx += v->d()->byteOffset; bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean(); @@ -181,19 +181,19 @@ void DataViewPrototype::method_get(const BuiltinFunction *, Scope &scope, CallDa ? qFromLittleEndian<T>((uchar *)v->d()->buffer->data->data() + idx) : qFromBigEndian<T>((uchar *)v->d()->buffer->data->data() + idx); - scope.result = Encode(t); + return Encode(t); } template <typename T> -void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_getFloat(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v || callData->argc < 1) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); idx += v->d()->byteOffset; bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean(); @@ -207,7 +207,7 @@ void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, C u.i = littleEndian ? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data->data() + idx) : qFromBigEndian<uint>((uchar *)v->d()->buffer->data->data() + idx); - scope.result = Encode(u.f); + return Encode(u.f); } else { Q_ASSERT(sizeof(T) == 8); union { @@ -217,20 +217,20 @@ void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, C u.i = littleEndian ? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx) : qFromBigEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx); - scope.result = Encode(u.d); + return Encode(u.d); } } template <typename T> -void DataViewPrototype::method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_setChar(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v || callData->argc < 1) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); idx += v->d()->byteOffset; int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0; @@ -240,15 +240,15 @@ void DataViewPrototype::method_setChar(const BuiltinFunction *, Scope &scope, Ca } template <typename T> -void DataViewPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_set(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v || callData->argc < 1) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); idx += v->d()->byteOffset; int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0; @@ -264,15 +264,15 @@ void DataViewPrototype::method_set(const BuiltinFunction *, Scope &scope, CallDa } template <typename T> -void DataViewPrototype::method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DataViewPrototype::method_setFloat(const BuiltinFunction *b, CallData *callData) { - Scoped<DataView> v(scope, callData->thisObject); + DataView *v = callData->thisObject.as<DataView>(); if (!v || callData->argc < 1) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); double l = callData->args[0].toNumber(); uint idx = (uint)l; if (l != idx || idx + sizeof(T) > v->d()->byteLength) - THROW_TYPE_ERROR(); + return b->engine()->throwTypeError(); idx += v->d()->byteOffset; double val = callData->argc >= 2 ? callData->args[1].toNumber() : qt_qnan(); diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h index 123a290e28..2d1a5d8be9 100644 --- a/src/qml/jsruntime/qv4dataview_p.h +++ b/src/qml/jsruntime/qv4dataview_p.h @@ -93,21 +93,21 @@ struct DataViewPrototype: Object { void init(ExecutionEngine *engine, Object *ctor); - 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 ReturnedValue method_get_buffer(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_byteLength(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_byteOffset(const BuiltinFunction *, CallData *callData); template <typename T> - static void method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_getChar(const BuiltinFunction *, CallData *callData); template <typename T> - static void method_get(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_get(const BuiltinFunction *, CallData *callData); template <typename T> - static void method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_getFloat(const BuiltinFunction *, CallData *callData); template <typename T> - static void method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_setChar(const BuiltinFunction *, CallData *callData); template <typename T> - static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_set(const BuiltinFunction *, CallData *callData); template <typename T> - static void method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_setFloat(const BuiltinFunction *, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 0e681f9946..2802483ff9 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -796,25 +796,25 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("toJSON"), method_toJSON, 1); } -double DatePrototype::getThisDate(Scope &scope, CallData *callData) +double DatePrototype::getThisDate(ExecutionEngine *v4, CallData *callData) { if (DateObject *thisObject = callData->thisObject.as<DateObject>()) return thisObject->date(); else { - scope.engine->throwTypeError(); + v4->throwTypeError(); return 0; } } -void DatePrototype::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_parse(const BuiltinFunction *, CallData *callData) { if (!callData->argc) - scope.result = Encode(qt_qnan()); + return Encode(qt_qnan()); else - scope.result = Encode(ParseString(callData->args[0].toQString())); + return Encode(ParseString(callData->args[0].toQString())); } -void DatePrototype::method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_UTC(const BuiltinFunction *, CallData *callData) { const int numArgs = callData->argc; if (numArgs >= 2) { @@ -829,306 +829,349 @@ void DatePrototype::method_UTC(const BuiltinFunction *, Scope &scope, CallData * year += 1900; double t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms)); - scope.result = Encode(TimeClip(t)); - return; + return Encode(TimeClip(t)); } RETURN_UNDEFINED(); } -void DatePrototype::method_now(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_now(const BuiltinFunction *, CallData *callData) { Q_UNUSED(callData); - double t = currentTime(); - scope.result = Encode(t); + return Encode(currentTime()); } -void DatePrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toString(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = scope.engine->newString(ToString(t)); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(v4->newString(ToString(t))); } -void DatePrototype::method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toDateString(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = scope.engine->newString(ToDateString(t)); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(v4->newString(ToDateString(t))); } -void DatePrototype::method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toTimeString(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = scope.engine->newString(ToTimeString(t)); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(v4->newString(ToTimeString(t))); } -void DatePrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toLocaleString(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = scope.engine->newString(ToLocaleString(t)); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(v4->newString(ToLocaleString(t))); } -void DatePrototype::method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toLocaleDateString(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = scope.engine->newString(ToLocaleDateString(t)); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(v4->newString(ToLocaleDateString(t))); } -void DatePrototype::method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toLocaleTimeString(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = scope.engine->newString(ToLocaleTimeString(t)); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(v4->newString(ToLocaleTimeString(t))); } -void DatePrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_valueOf(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = Encode(t); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(t); } -void DatePrototype::method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getTime(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); - scope.result = Encode(t); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); + return Encode(t); } -void DatePrototype::method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getYear(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = YearFromTime(LocalTime(t)) - 1900; - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getFullYear(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = YearFromTime(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCFullYear(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = YearFromTime(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getMonth(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = MonthFromTime(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCMonth(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = MonthFromTime(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getDate(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = DateFromTime(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCDate(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = DateFromTime(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getDay(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = WeekDay(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCDay(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = WeekDay(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getHours(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = HourFromTime(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCHours(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = HourFromTime(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getMinutes(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = MinFromTime(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCMinutes(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = MinFromTime(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getSeconds(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = SecFromTime(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCSeconds(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = SecFromTime(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getMilliseconds(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = msFromTime(LocalTime(t)); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getUTCMilliseconds(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = msFromTime(t); - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_getTimezoneOffset(const BuiltinFunction *b, CallData *callData) { - double t = getThisDate(scope, callData); + ExecutionEngine *v4 = b->engine(); + double t = getThisDate(v4, callData); if (!std::isnan(t)) t = (t - LocalTime(t)) / msPerMinute; - scope.result = Encode(t); + return Encode(t); } -void DatePrototype::method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setTime(const BuiltinFunction *b, CallData *callData) { - Scoped<DateObject> self(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); self->setDate(TimeClip(t)); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setMilliseconds(const BuiltinFunction *b, CallData *callData) { - Scoped<DateObject> self(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = LocalTime(self->date()); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))))); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setUTCMilliseconds(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setSeconds(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = LocalTime(self->date()); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setUTCSeconds(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan(); double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber(); t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setMinutes(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = LocalTime(self->date()); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double min = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double sec = (callData->argc < 2) ? SecFromTime(t) : callData->args[1].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setUTCMinutes(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); double min = callData->argc ? callData->args[0].toNumber() : qt_qnan(); @@ -1136,35 +1179,42 @@ void DatePrototype::method_setUTCMinutes(const BuiltinFunction *, Scope &scope, double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber(); t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setHours(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = LocalTime(self->date()); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double min = (callData->argc < 2) ? MinFromTime(t) : callData->args[1].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double sec = (callData->argc < 3) ? SecFromTime(t) : callData->args[2].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms)))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setUTCHours(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan(); @@ -1173,75 +1223,87 @@ void DatePrototype::method_setUTCHours(const BuiltinFunction *, Scope &scope, Ca double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber(); t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setDate(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = LocalTime(self->date()); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double date = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setUTCDate(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double date = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setMonth(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = LocalTime(self->date()); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double month = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setUTCMonth(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); double month = callData->argc ? callData->args[0].toNumber() : qt_qnan(); double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber(); t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setYear(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); if (std::isnan(t)) @@ -1260,14 +1322,15 @@ void DatePrototype::method_setYear(const BuiltinFunction *, Scope &scope, CallDa r = TimeClip(r); } self->setDate(r); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setUTCFullYear(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); double year = callData->argc ? callData->args[0].toNumber() : qt_qnan(); @@ -1275,38 +1338,44 @@ void DatePrototype::method_setUTCFullYear(const BuiltinFunction *, Scope &scope, double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber(); t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_setFullYear(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = LocalTime(self->date()); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); if (std::isnan(t)) t = 0; double year = callData->argc ? callData->args[0].toNumber() : qt_qnan(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double month = (callData->argc < 2) ? MonthFromTime(t) : callData->args[1].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber(); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)))); self->setDate(t); - scope.result = Encode(self->date()); + return Encode(self->date()); } -void DatePrototype::method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toUTCString(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); - scope.result = scope.engine->newString(ToUTCString(t)); + return Encode(v4->newString(ToUTCString(t))); } static void addZeroPrefixedInt(QString &str, int num, int nDigits) @@ -1322,21 +1391,22 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits) } } -void DatePrototype::method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toISOString(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); DateObject *self = callData->thisObject.as<DateObject>(); if (!self) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); double t = self->date(); if (!std::isfinite(t)) - RETURN_RESULT(scope.engine->throwRangeError(callData->thisObject)); + RETURN_RESULT(v4->throwRangeError(callData->thisObject)); QString result; int year = (int)YearFromTime(t); if (year < 0 || year > 9999) { if (qAbs(year) >= 1000000) - RETURN_RESULT(scope.engine->newString(QStringLiteral("Invalid Date"))); + RETURN_RESULT(v4->newString(QStringLiteral("Invalid Date"))); result += year < 0 ? QLatin1Char('-') : QLatin1Char('+'); year = qAbs(year); addZeroPrefixedInt(result, year, 6); @@ -1357,29 +1427,32 @@ void DatePrototype::method_toISOString(const BuiltinFunction *, Scope &scope, Ca addZeroPrefixedInt(result, msFromTime(t), 3); result += QLatin1Char('Z'); - scope.result = scope.engine->newString(result); + return Encode(v4->newString(result)); } -void DatePrototype::method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue DatePrototype::method_toJSON(const BuiltinFunction *b, CallData *callData) { - ScopedObject O(scope, callData->thisObject.toObject(scope.engine)); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + Scope scope(v4); + ScopedObject O(scope, callData->thisObject.toObject(v4)); + if (v4->hasException) + return QV4::Encode::undefined(); ScopedValue tv(scope, RuntimeHelpers::toPrimitive(O, NUMBER_HINT)); if (tv->isNumber() && !std::isfinite(tv->toNumber())) RETURN_RESULT(Encode::null()); - ScopedString s(scope, scope.engine->newString(QStringLiteral("toISOString"))); + ScopedString s(scope, v4->newString(QStringLiteral("toISOString"))); ScopedValue v(scope, O->get(s)); FunctionObject *toIso = v->as<FunctionObject>(); if (!toIso) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); ScopedCallData cData(scope); cData->thisObject = callData->thisObject; - scope.result = toIso->call(cData); + return toIso->call(cData); } void DatePrototype::timezoneUpdated() diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index 2455861319..a1f6dd9a7d 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -118,57 +118,57 @@ struct DatePrototype: Object void init(ExecutionEngine *engine, Object *ctor); - static double getThisDate(Scope &scope, CallData *callData); - - static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_now(const BuiltinFunction *, Scope &scope, CallData *callData); - - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData); + static double getThisDate(ExecutionEngine *v4, CallData *callData); + + static ReturnedValue method_parse(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_UTC(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_now(const BuiltinFunction *, CallData *callData); + + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toDateString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toTimeString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleDateString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleTimeString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_valueOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getTime(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getYear(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getFullYear(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCFullYear(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getMonth(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCMonth(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getDate(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCDate(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getDay(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCDay(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getHours(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCHours(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getMinutes(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCMinutes(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getSeconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCSeconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getMilliseconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getUTCMilliseconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getTimezoneOffset(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setTime(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setMilliseconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setUTCMilliseconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setSeconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setUTCSeconds(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setMinutes(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setUTCMinutes(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setHours(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setUTCHours(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setDate(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setUTCDate(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setMonth(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setUTCMonth(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setYear(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setFullYear(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_setUTCFullYear(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toUTCString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toISOString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toJSON(const BuiltinFunction *, CallData *callData); static void timezoneUpdated(); }; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 8d0f401f58..ad090682cc 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -101,9 +101,9 @@ using namespace QV4; static QBasicAtomicInt engineSerial = Q_BASIC_ATOMIC_INITIALIZER(1); -void throwTypeError(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue throwTypeError(const BuiltinFunction *b, CallData *) { - scope.result = scope.engine->throwTypeError(); + return b->engine()->throwTypeError(); } @@ -1554,11 +1554,6 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) return 0; } -void ExecutionEngine::failStackLimitCheck(Scope &scope) -{ - scope.result = throwRangeError(QStringLiteral("Maximum call stack size exceeded.")); -} - // Converts a JS value to a meta-type. // data must point to a place that can store a value of the given type. // Returns true if conversion succeeded, false otherwise. diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 922c65fbe8..a628af94cd 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -449,11 +449,9 @@ public: bool metaTypeFromJS(const Value *value, int type, void *data); QV4::ReturnedValue metaTypeToJS(int type, const void *data); - bool checkStackLimits(Scope &scope); + bool checkStackLimits(); private: - void failStackLimitCheck(Scope &scope); - #ifndef QT_NO_QML_DEBUGGER QV4::Debugging::Debugger *m_debugger; QV4::Profiling::Profiler *m_profiler; @@ -535,7 +533,7 @@ inline void Managed::mark(MarkStack *markStack) m()->mark(markStack); } -#define CHECK_STACK_LIMITS(v4, scope) if ((v4)->checkStackLimits(scope)) return Encode::undefined(); \ +#define CHECK_STACK_LIMITS(v4) if ((v4)->checkStackLimits()) return Encode::undefined(); \ ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4); struct ExecutionEngineCallDepthRecorder @@ -546,10 +544,10 @@ struct ExecutionEngineCallDepthRecorder ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; } }; -inline bool ExecutionEngine::checkStackLimits(Scope &scope) +inline bool ExecutionEngine::checkStackLimits() { if (Q_UNLIKELY((jsStackTop > jsStackLimit) || (callDepth >= maxCallDepth))) { - failStackLimitCheck(scope); + throwRangeError(QStringLiteral("Maximum call stack size exceeded.")); return true; } diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index aef4e64964..be2bc0be9b 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -152,11 +152,12 @@ const char *ErrorObject::className(Heap::ErrorObject::ErrorType t) Q_UNREACHABLE(); } -void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ErrorObject::method_get_stack(const BuiltinFunction *b, CallData *callData) { - Scoped<ErrorObject> This(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + ErrorObject *This = callData->thisObject.as<ErrorObject>(); if (!This) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); if (!This->d()->stack) { QString trace; for (int i = 0; i < This->d()->stackTrace->count(); ++i) { @@ -167,9 +168,9 @@ void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallDa if (frame.line >= 0) trace += QLatin1Char(':') + QString::number(frame.line); } - This->d()->stack.set(scope.engine, scope.engine->newString(trace)); + This->d()->stack.set(v4, v4->newString(trace)); } - scope.result = This->d()->stack; + return This->d()->stack->asReturnedValue(); } DEFINE_OBJECT_VTABLE(ErrorObject); @@ -315,12 +316,14 @@ void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, He obj->defineDefaultProperty(engine->id_toString(), method_toString, 0); } -void ErrorPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ErrorPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); Object *o = callData->thisObject.as<Object>(); if (!o) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); + Scope scope(v4); ScopedValue name(scope, o->get(scope.engine->id_name())); QString qname; if (name->isUndefined()) @@ -343,5 +346,5 @@ void ErrorPrototype::method_toString(const BuiltinFunction *, Scope &scope, Call str = qname + QLatin1String(": ") + qmessage; } - scope.result = scope.engine->newString(str)->asReturnedValue(); + return scope.engine->newString(str)->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index 2a0d15a63c..8e235a32de 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -175,7 +175,7 @@ struct ErrorObject: Object { static const char *className(Heap::ErrorObject::ErrorType t); - static void method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_get_stack(const BuiltinFunction *, CallData *callData); }; template<> @@ -286,7 +286,7 @@ struct ErrorPrototype : ErrorObject void init(ExecutionEngine *engine, Object *ctor) { init(engine, ctor, this, Heap::ErrorObject::Error); } static void init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); }; struct EvalErrorPrototype : ErrorObject diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 9a88ee326a..061971ec30 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -254,20 +254,23 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor) } -void FunctionPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue FunctionPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); FunctionObject *fun = callData->thisObject.as<FunctionObject>(); if (!fun) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); - scope.result = scope.engine->newString(QStringLiteral("function() { [code] }")); + return Encode(v4->newString(QStringLiteral("function() { [code] }"))); } -void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue FunctionPrototype::method_apply(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); + Scope scope(v4); FunctionObject *o = callData->thisObject.as<FunctionObject>(); if (!o) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); ScopedValue arg(scope, callData->argument(1)); @@ -277,7 +280,7 @@ void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, Call if (!arr) { len = 0; if (!arg->isNullOrUndefined()) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); } else { len = arr->getLength(); } @@ -307,14 +310,15 @@ void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, Call } cData->thisObject = callData->argument(0); - scope.result = o->call(cData); + return o->call(cData); } -void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue FunctionPrototype::method_call(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); FunctionObject *o = callData->thisObject.as<FunctionObject>(); if (!o) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); ScopedCallData cData(scope, callData->argc ? callData->argc - 1 : 0); if (callData->argc) { @@ -323,14 +327,15 @@ void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallD } cData->thisObject = callData->argument(0); - scope.result = o->call(cData); + return o->call(cData); } -void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue FunctionPrototype::method_bind(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); FunctionObject *target = callData->thisObject.as<FunctionObject>(); if (!target) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); ScopedValue boundThis(scope, callData->argument(0)); Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)0); @@ -342,7 +347,7 @@ void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallD } ExecutionContext *global = scope.engine->rootContext(); - scope.result = BoundFunction::create(global, target, boundThis, boundArgs); + return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue(); } DEFINE_OBJECT_VTABLE(ScriptFunction); @@ -352,10 +357,9 @@ ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData) ExecutionEngine *v4 = that->engine(); if (Q_UNLIKELY(v4->hasException)) return Encode::undefined(); + CHECK_STACK_LIMITS(v4); Scope scope(v4); - CHECK_STACK_LIMITS(v4, scope); - ExecutionContextSaver ctxSaver(scope); Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that)); @@ -369,16 +373,17 @@ ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData) Q_ASSERT(v4Function); ScopedContext c(scope, f->scope()); + ScopedValue result(scope); if (v4Function->canUseSimpleCall) - c->simpleCall(scope, callData, v4Function); + result = c->simpleCall(scope, callData, v4Function); else - c->call(scope, callData, v4Function, f); + result = c->call(scope, callData, v4Function, f); if (Q_UNLIKELY(v4->hasException)) return Encode::undefined(); - else if (!scope.result.isObject()) + else if (!result->isObject()) return obj.asReturnedValue(); - return Encode(scope.result); + return result->asReturnedValue(); } ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData) @@ -386,10 +391,9 @@ ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData) ExecutionEngine *v4 = that->engine(); if (Q_UNLIKELY(v4->hasException)) return Encode::undefined(); + CHECK_STACK_LIMITS(v4); Scope scope(v4); - CHECK_STACK_LIMITS(v4, scope); - Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that)); QV4::Function *v4Function = f->function(); @@ -397,10 +401,9 @@ ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData) ScopedContext c(scope, f->scope()); if (v4Function->canUseSimpleCall) - c->simpleCall(scope, callData, v4Function); + return c->simpleCall(scope, callData, v4Function); else - c->call(scope, callData, v4Function, f); - return Encode(scope.result); + return c->call(scope, callData, v4Function, f); } void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function) @@ -447,7 +450,7 @@ InternalClass *ScriptFunction::classForConstructor() const DEFINE_OBJECT_VTABLE(BuiltinFunction); -void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *)) +void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *)) { Heap::FunctionObject::init(scope, name); this->code = code; @@ -465,9 +468,7 @@ ReturnedValue BuiltinFunction::call(const Managed *that, CallData *callData) if (v4->hasException) return Encode::undefined(); - Scope scope(v4); - f->d()->code(f, scope, callData); - return Encode(scope.result); + return f->d()->code(f, callData); } @@ -477,10 +478,9 @@ ReturnedValue IndexedBuiltinFunction::call(const Managed *that, CallData *callDa ExecutionEngine *v4 = f->engine(); if (v4->hasException) return Encode::undefined(); + CHECK_STACK_LIMITS(v4); Scope scope(v4); - CHECK_STACK_LIMITS(v4, scope); - ExecutionContextSaver ctxSaver(scope); CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext(); @@ -489,9 +489,9 @@ ReturnedValue IndexedBuiltinFunction::call(const Managed *that, CallData *callDa v4->pushContext(ctx); Q_ASSERT(v4->current == ctx); - scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext), f->d()->index); + ReturnedValue result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext), f->d()->index); v4->memoryManager->freeSimpleCallContext(); - return Encode(scope.result); + return result; } DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction); diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index e62ffae20b..5eea262e2e 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -96,14 +96,9 @@ struct FunctionPrototype : FunctionObject { void init(); }; -struct Q_QML_EXPORT OldBuiltinFunction : FunctionObject { - void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *)); - ReturnedValue (*code)(QV4::CallContext *); -}; - struct Q_QML_EXPORT BuiltinFunction : FunctionObject { - void init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *)); - void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *); + void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *)); + ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *); }; struct IndexedBuiltinFunction : FunctionObject { @@ -188,17 +183,17 @@ struct FunctionPrototype: FunctionObject void init(ExecutionEngine *engine, Object *ctor); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_apply(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_call(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_bind(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_apply(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_call(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_bind(const BuiltinFunction *, CallData *callData); }; struct Q_QML_EXPORT BuiltinFunction : FunctionObject { V4_OBJECT2(BuiltinFunction, FunctionObject) V4_INTERNALCLASS(BuiltinFunction) - static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *)) + static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(const BuiltinFunction *, CallData *)) { return scope->engine()->memoryManager->allocObject<BuiltinFunction>(scope, name, code); } diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 35961e6f75..dab6de572d 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -414,8 +414,9 @@ static inline int toInt(const QChar &qc, int R) } // parseInt [15.1.2.2] -void GlobalFunctions::method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_parseInt(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedValue inputString(scope, callData->argument(0)); ScopedValue radix(scope, callData->argument(1)); int R = radix->isUndefined() ? 0 : radix->toInt32(); @@ -494,8 +495,9 @@ void GlobalFunctions::method_parseInt(const BuiltinFunction *, Scope &scope, Cal } // parseFloat [15.1.2.3] -void GlobalFunctions::method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_parseFloat(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); // [15.1.2.3] step by step: ScopedString inputString(scope, callData->argument(0), ScopedString::Convert); CHECK_EXCEPTION(); @@ -520,7 +522,7 @@ void GlobalFunctions::method_parseFloat(const BuiltinFunction *, Scope &scope, C } /// isNaN [15.1.2.4] -void GlobalFunctions::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_isNaN(const BuiltinFunction *, CallData *callData) { if (!callData->argc) // undefined gets converted to NaN @@ -534,7 +536,7 @@ void GlobalFunctions::method_isNaN(const BuiltinFunction *, Scope &scope, CallDa } /// isFinite [15.1.2.5] -void GlobalFunctions::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_isFinite(const BuiltinFunction *, CallData *callData) { if (!callData->argc) // undefined gets converted to NaN @@ -548,87 +550,97 @@ void GlobalFunctions::method_isFinite(const BuiltinFunction *, Scope &scope, Cal } /// decodeURI [15.1.3.1] -void GlobalFunctions::method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_decodeURI(const BuiltinFunction *b, CallData *callData) { if (callData->argc == 0) RETURN_UNDEFINED(); + ExecutionEngine *v4 = b->engine(); QString uriString = callData->args[0].toQString(); bool ok; QString out = decode(uriString, DecodeNonReserved, &ok); if (!ok) { + Scope scope(v4); ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); RETURN_RESULT(scope.engine->throwURIError(s)); } - RETURN_RESULT(scope.engine->newString(out)); + RETURN_RESULT(v4->newString(out)); } /// decodeURIComponent [15.1.3.2] -void GlobalFunctions::method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_decodeURIComponent(const BuiltinFunction *b, CallData *callData) { if (callData->argc == 0) RETURN_UNDEFINED(); + ExecutionEngine *v4 = b->engine(); QString uriString = callData->args[0].toQString(); bool ok; QString out = decode(uriString, DecodeAll, &ok); if (!ok) { + Scope scope(v4); ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); RETURN_RESULT(scope.engine->throwURIError(s)); } - RETURN_RESULT(scope.engine->newString(out)); + RETURN_RESULT(v4->newString(out)); } /// encodeURI [15.1.3.3] -void GlobalFunctions::method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_encodeURI(const BuiltinFunction *b, CallData *callData) { if (callData->argc == 0) RETURN_UNDEFINED(); + ExecutionEngine *v4 = b->engine(); QString uriString = callData->args[0].toQString(); bool ok; QString out = encode(uriString, uriUnescapedReserved, &ok); if (!ok) { + Scope scope(v4); ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); RETURN_RESULT(scope.engine->throwURIError(s)); } - RETURN_RESULT(scope.engine->newString(out)); + RETURN_RESULT(v4->newString(out)); } /// encodeURIComponent [15.1.3.4] -void GlobalFunctions::method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_encodeURIComponent(const BuiltinFunction *b, CallData *callData) { if (callData->argc == 0) RETURN_UNDEFINED(); + ExecutionEngine *v4 = b->engine(); QString uriString = callData->args[0].toQString(); bool ok; QString out = encode(uriString, uriUnescaped, &ok); if (!ok) { + Scope scope(v4); ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence"))); RETURN_RESULT(scope.engine->throwURIError(s)); } - RETURN_RESULT(scope.engine->newString(out)); + RETURN_RESULT(v4->newString(out)); } -void GlobalFunctions::method_escape(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_escape(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); if (!callData->argc) - RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined"))); + RETURN_RESULT(v4->newString(QStringLiteral("undefined"))); QString str = callData->args[0].toQString(); - RETURN_RESULT(scope.engine->newString(escape(str))); + RETURN_RESULT(v4->newString(escape(str))); } -void GlobalFunctions::method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalFunctions::method_unescape(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); if (!callData->argc) - RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined"))); + RETURN_RESULT(v4->newString(QStringLiteral("undefined"))); QString str = callData->args[0].toQString(); - RETURN_RESULT(scope.engine->newString(unescape(str))); + RETURN_RESULT(v4->newString(unescape(str))); } diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h index 152b69001b..5489a9fbb0 100644 --- a/src/qml/jsruntime/qv4globalobject_p.h +++ b/src/qml/jsruntime/qv4globalobject_p.h @@ -76,16 +76,16 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject struct GlobalFunctions { - static void method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_escape(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_parseInt(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_parseFloat(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isNaN(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isFinite(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_decodeURI(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_decodeURIComponent(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_encodeURI(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_encodeURIComponent(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_escape(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_unescape(const BuiltinFunction *, CallData *callData); }; } diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index 2f00022659..49ccb7c2e9 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -195,8 +195,9 @@ void QV4Include::finished() /* Documented in qv8engine.cpp */ -void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +QV4::ReturnedValue QV4Include::method_include(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); if (!callData->argc) RETURN_UNDEFINED(); @@ -260,13 +261,13 @@ void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, callback(callbackFunction, result); } - scope.result = result; #else QV4::ScopedValue result(scope); result = resultValue(scope.engine, NetworkError); callback(callbackFunction, result); - scope.result = result; #endif + + return result->asReturnedValue(); } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h index 5908d6bfde..68537ba2e8 100644 --- a/src/qml/jsruntime/qv4include_p.h +++ b/src/qml/jsruntime/qv4include_p.h @@ -77,7 +77,7 @@ public: Exception = 3 }; - static void method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static QV4::ReturnedValue method_include(const QV4::BuiltinFunction *, QV4::CallData *callData); private Q_SLOTS: void finished(); diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 60d1f13358..27cce52512 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -883,25 +883,28 @@ void Heap::JsonObject::init() } -void JsonObject::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue JsonObject::method_parse(const BuiltinFunction *b, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - QString jtext = v->toQString(); + ExecutionEngine *v4 = b->engine(); + QString jtext; + if (callData->argc > 0) + jtext = callData->args[0].toQString(); DEBUG << "parsing source = " << jtext; - JsonParser parser(scope.engine, jtext.constData(), jtext.length()); + JsonParser parser(v4, jtext.constData(), jtext.length()); QJsonParseError error; - ScopedValue result(scope, parser.parse(&error)); + ReturnedValue result = parser.parse(&error); if (error.error != QJsonParseError::NoError) { DEBUG << "parse error" << error.errorString(); - RETURN_RESULT(scope.engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"))); + RETURN_RESULT(v4->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"))); } - scope.result = result; + return result; } -void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue JsonObject::method_stringify(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); Stringify stringify(scope.engine); ScopedObject o(scope, callData->argument(1)); @@ -946,7 +949,7 @@ void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallDat QString result = stringify.Str(QString(), arg0); if (result.isEmpty() || scope.engine->hasException) RETURN_UNDEFINED(); - scope.result = scope.engine->newString(result); + return Encode(scope.engine->newString(result)); } diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h index a73ce1c74e..19dba14aef 100644 --- a/src/qml/jsruntime/qv4jsonobject_p.h +++ b/src/qml/jsruntime/qv4jsonobject_p.h @@ -88,8 +88,8 @@ private: typedef QSet<ObjectItem> V4ObjectSet; public: - static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_parse(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_stringify(const BuiltinFunction *, CallData *callData); static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value); static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object); diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp index 98a5e5f1f7..2c1fefe9f8 100644 --- a/src/qml/jsruntime/qv4mathobject.cpp +++ b/src/qml/jsruntime/qv4mathobject.cpp @@ -92,7 +92,7 @@ static Q_ALWAYS_INLINE double copySign(double x, double y) return ::copysign(x, y); } -void MathObject::method_abs(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_abs(const BuiltinFunction *, CallData *callData) { if (!callData->argc) RETURN_RESULT(Encode(qt_qnan())); @@ -109,7 +109,7 @@ void MathObject::method_abs(const BuiltinFunction *, Scope &scope, CallData *cal RETURN_RESULT(Encode(v < 0 ? -v : v)); } -void MathObject::method_acos(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_acos(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : 2; if (v > 1) @@ -118,7 +118,7 @@ void MathObject::method_acos(const BuiltinFunction *, Scope &scope, CallData *ca RETURN_RESULT(Encode(std::acos(v))); } -void MathObject::method_asin(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_asin(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : 2; if (v > 1) @@ -127,7 +127,7 @@ void MathObject::method_asin(const BuiltinFunction *, Scope &scope, CallData *ca RETURN_RESULT(Encode(std::asin(v))); } -void MathObject::method_atan(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_atan(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); if (v == 0.0) @@ -136,7 +136,7 @@ void MathObject::method_atan(const BuiltinFunction *, Scope &scope, CallData *ca RETURN_RESULT(Encode(std::atan(v))); } -void MathObject::method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_atan2(const BuiltinFunction *, CallData *callData) { double v1 = callData->argc ? callData->args[0].toNumber() : qt_qnan(); double v2 = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan(); @@ -154,7 +154,7 @@ void MathObject::method_atan2(const BuiltinFunction *, Scope &scope, CallData *c RETURN_RESULT(Encode(std::atan2(v1, v2))); } -void MathObject::method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_ceil(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); if (v < 0.0 && v > -1.0) @@ -163,13 +163,13 @@ void MathObject::method_ceil(const BuiltinFunction *, Scope &scope, CallData *ca RETURN_RESULT(Encode(std::ceil(v))); } -void MathObject::method_cos(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_cos(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); RETURN_RESULT(Encode(std::cos(v))); } -void MathObject::method_exp(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_exp(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); if (qt_is_inf(v)) { @@ -182,7 +182,7 @@ void MathObject::method_exp(const BuiltinFunction *, Scope &scope, CallData *cal } } -void MathObject::method_floor(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_floor(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); Value result = Primitive::fromDouble(std::floor(v)); @@ -190,7 +190,7 @@ void MathObject::method_floor(const BuiltinFunction *, Scope &scope, CallData *c RETURN_RESULT(result); } -void MathObject::method_log(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_log(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); if (v < 0) @@ -199,7 +199,7 @@ void MathObject::method_log(const BuiltinFunction *, Scope &scope, CallData *cal RETURN_RESULT(Encode(std::log(v))); } -void MathObject::method_max(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_max(const BuiltinFunction *, CallData *callData) { double mx = -qt_inf(); for (int i = 0; i < callData->argc; ++i) { @@ -210,7 +210,7 @@ void MathObject::method_max(const BuiltinFunction *, Scope &scope, CallData *cal RETURN_RESULT(Encode(mx)); } -void MathObject::method_min(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_min(const BuiltinFunction *, CallData *callData) { double mx = qt_inf(); for (int i = 0; i < callData->argc; ++i) { @@ -223,7 +223,7 @@ void MathObject::method_min(const BuiltinFunction *, Scope &scope, CallData *cal RETURN_RESULT(Encode(mx)); } -void MathObject::method_pow(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_pow(const BuiltinFunction *, CallData *callData) { double x = callData->argc > 0 ? callData->args[0].toNumber() : qt_qnan(); double y = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan(); @@ -275,12 +275,12 @@ void MathObject::method_pow(const BuiltinFunction *, Scope &scope, CallData *cal Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage); -void MathObject::method_random(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue MathObject::method_random(const BuiltinFunction *b, CallData *) { if (!seedCreatedStorage()->hasLocalData()) { int msecs = QTime(0,0,0).msecsTo(QTime::currentTime()); Q_ASSERT(msecs >= 0); - qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(scope.engine))); + qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(b))); seedCreatedStorage()->setLocalData(new bool(true)); } // rand()/qrand() return a value where the upperbound is RAND_MAX inclusive. So, instead of @@ -289,14 +289,14 @@ void MathObject::method_random(const BuiltinFunction *, Scope &scope, CallData * RETURN_RESULT(Encode(qrand() / double(upperLimit))); } -void MathObject::method_round(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_round(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); v = copySign(std::floor(v + 0.5), v); RETURN_RESULT(Encode(v)); } -void MathObject::method_sign(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_sign(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); @@ -309,19 +309,19 @@ void MathObject::method_sign(const BuiltinFunction *, Scope &scope, CallData *ca RETURN_RESULT(Encode(std::signbit(v) ? -1 : 1)); } -void MathObject::method_sin(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_sin(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); RETURN_RESULT(Encode(std::sin(v))); } -void MathObject::method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_sqrt(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); RETURN_RESULT(Encode(std::sqrt(v))); } -void MathObject::method_tan(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue MathObject::method_tan(const BuiltinFunction *, CallData *callData) { double v = callData->argc ? callData->args[0].toNumber() : qt_qnan(); if (v == 0.0) diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h index e617712905..016f0c16ca 100644 --- a/src/qml/jsruntime/qv4mathobject_p.h +++ b/src/qml/jsruntime/qv4mathobject_p.h @@ -69,25 +69,25 @@ struct MathObject: Object V4_OBJECT2(MathObject, Object) Q_MANAGED_TYPE(MathObject) - static void method_abs(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_acos(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_asin(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_atan(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_cos(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_exp(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_floor(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_max(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_min(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_pow(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_random(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_round(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_sign(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_sin(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_tan(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_abs(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_acos(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_asin(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_atan(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_atan2(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_ceil(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_cos(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_exp(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_floor(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_log(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_max(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_min(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_pow(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_random(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_round(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_sign(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_sin(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_sqrt(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_tan(const BuiltinFunction *, CallData *callData); }; } diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 40586b558b..1db5079355 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -124,117 +124,99 @@ QT_WARNING_POP defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision, 1); } -inline ReturnedValue thisNumberValue(Scope &scope, CallData *callData) +inline ReturnedValue thisNumberValue(ExecutionEngine *v4, CallData *callData) { if (callData->thisObject.isNumber()) return callData->thisObject.asReturnedValue(); NumberObject *n = callData->thisObject.as<NumberObject>(); if (!n) { - scope.engine->throwTypeError(); + v4->throwTypeError(); return Encode::undefined(); } return Encode(n->value()); } -inline double thisNumber(Scope &scope, CallData *callData) +inline double thisNumber(ExecutionEngine *engine, CallData *callData) { if (callData->thisObject.isNumber()) return callData->thisObject.asDouble(); NumberObject *n = callData->thisObject.as<NumberObject>(); if (!n) { - scope.engine->throwTypeError(); + engine->throwTypeError(); return 0; } return n->value(); } -void NumberPrototype::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isFinite(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); double v = callData->args[0].toNumber(); - scope.result = Encode(!std::isnan(v) && !qt_is_inf(v)); + return Encode(!std::isnan(v) && !qt_is_inf(v)); } -void NumberPrototype::method_isInteger(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isInteger(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); const Value &v = callData->args[0]; - if (!v.isNumber()) { - scope.result = Encode(false); - return; - } + if (!v.isNumber()) + return Encode(false); double dv = v.toNumber(); - if (std::isnan(dv) || qt_is_inf(dv)) { - scope.result = Encode(false); - return; - } + if (std::isnan(dv) || qt_is_inf(dv)) + return Encode(false); double iv = v.toInteger(); - scope.result = Encode(dv == iv); + return Encode(dv == iv); } -void NumberPrototype::method_isSafeInteger(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isSafeInteger(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); const Value &v = callData->args[0]; - if (!v.isNumber()) { - scope.result = Encode(false); - return; - } + if (!v.isNumber()) + return Encode(false); double dv = v.toNumber(); - if (std::isnan(dv) || qt_is_inf(dv)) { - scope.result = Encode(false); - return; - } + if (std::isnan(dv) || qt_is_inf(dv)) + return Encode(false); double iv = v.toInteger(); - scope.result = Encode(dv == iv && std::fabs(iv) <= (2^53)-1); + return Encode(dv == iv && std::fabs(iv) <= (2^53)-1); } -void NumberPrototype::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_isNaN(const BuiltinFunction *, CallData *callData) { - if (!callData->argc) { - scope.result = Encode(false); - return; - } + if (!callData->argc) + return Encode(false); double v = callData->args[0].toNumber(); - scope.result = Encode(std::isnan(v)); + return Encode(std::isnan(v)); } -void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { - double num = thisNumber(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + double num = thisNumber(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); if (callData->argc && !callData->args[0].isUndefined()) { int radix = callData->args[0].toInt32(); if (radix < 2 || radix > 36) { - scope.result = scope.engine->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix") - .arg(radix)); - return; + return v4->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix").arg(radix)); } if (std::isnan(num)) { - scope.result = scope.engine->newString(QStringLiteral("NaN")); - return; + return Encode(v4->newString(QStringLiteral("NaN"))); } else if (qt_is_inf(num)) { - scope.result = scope.engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity")); - return; + return Encode(v4->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"))); } if (radix != 10) { @@ -264,30 +246,31 @@ void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, Cal } if (negative) str.prepend(QLatin1Char('-')); - scope.result = scope.engine->newString(str); - return; + return Encode(v4->newString(str)); } } - scope.result = Primitive::fromDouble(num).toString(scope.engine); + return Encode(Primitive::fromDouble(num).toString(v4)); } -void NumberPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toLocaleString(const BuiltinFunction *b, CallData *callData) { - ScopedValue v(scope, thisNumberValue(scope, callData)); - scope.result = v->toString(scope.engine); - CHECK_EXCEPTION(); + Scope scope(b); + ScopedValue v(scope, thisNumberValue(b->engine(), callData)); + return Encode(v->toString(scope.engine)); } -void NumberPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_valueOf(const BuiltinFunction *b, CallData *callData) { - scope.result = thisNumberValue(scope, callData); + return thisNumberValue(b->engine(), callData); } -void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toFixed(const BuiltinFunction *b, CallData *callData) { - double v = thisNumber(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + double v = thisNumber(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); double fdigits = 0; @@ -297,10 +280,8 @@ void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, Call if (std::isnan(fdigits)) fdigits = 0; - if (fdigits < 0 || fdigits > 20) { - scope.result = scope.engine->throwRangeError(callData->thisObject); - return; - } + if (fdigits < 0 || fdigits > 20) + return v4->throwRangeError(callData->thisObject); QString str; if (std::isnan(v)) @@ -310,49 +291,51 @@ void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, Call else if (v < 1.e21) str = NumberLocale::instance()->toString(v, 'f', int(fdigits)); else { - scope.result = RuntimeHelpers::stringFromNumber(scope.engine, v); - return; + return Encode(RuntimeHelpers::stringFromNumber(v4, v)); } - scope.result = scope.engine->newString(str); + return Encode(v4->newString(str)); } -void NumberPrototype::method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toExponential(const BuiltinFunction *b, CallData *callData) { - double d = thisNumber(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + double d = thisNumber(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); + int fdigits = NumberLocale::instance()->defaultDoublePrecision; if (callData->argc && !callData->args[0].isUndefined()) { fdigits = callData->args[0].toInt32(); if (fdigits < 0 || fdigits > 20) { - ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range"))); - scope.result = scope.engine->throwRangeError(error); - return; + Scope scope(v4); + ScopedString error(scope, v4->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range"))); + return v4->throwRangeError(error); } } QString result = NumberLocale::instance()->toString(d, 'e', fdigits); - scope.result = scope.engine->newString(result); + return Encode(v4->newString(result)); } -void NumberPrototype::method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue NumberPrototype::method_toPrecision(const BuiltinFunction *b, CallData *callData) { - ScopedValue v(scope, thisNumberValue(scope, callData)); - CHECK_EXCEPTION(); + Scope scope(b); + ScopedValue v(scope, thisNumberValue(scope.engine, callData)); + if (scope.engine->hasException) + return QV4::Encode::undefined(); - if (!callData->argc || callData->args[0].isUndefined()) { - scope.result = v->toString(scope.engine); - return; - } + + if (!callData->argc || callData->args[0].isUndefined()) + return Encode(v->toString(scope.engine)); int precision = callData->args[0].toInt32(); if (precision < 1 || precision > 21) { ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range"))); - scope.result = scope.engine->throwRangeError(error); - return; + return scope.engine->throwRangeError(error); } QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision); - scope.result = scope.engine->newString(result); + return Encode(scope.engine->newString(result)); } diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index 5622bf4728..6a2b5953a6 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -88,16 +88,16 @@ struct NumberPrototype: NumberObject V4_PROTOTYPE(objectPrototype) void init(ExecutionEngine *engine, Object *ctor); - static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isInteger(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isSafeInteger(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_isFinite(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isInteger(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isSafeInteger(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isNaN(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_valueOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toFixed(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toExponential(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toPrecision(const BuiltinFunction *, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 9c1cbf2357..543968f6ec 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -153,7 +153,7 @@ void Object::defineDefaultProperty(const QString &name, const Value &value) defineDefaultProperty(s, value); } -void Object::defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount) +void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount) { ExecutionEngine *e = engine(); Scope scope(e); @@ -164,7 +164,7 @@ void Object::defineDefaultProperty(const QString &name, void (*code)(const Built defineDefaultProperty(s, function); } -void Object::defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount) +void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount) { ExecutionEngine *e = engine(); Scope scope(e); @@ -174,8 +174,8 @@ void Object::defineDefaultProperty(String *name, void (*code)(const BuiltinFunct defineDefaultProperty(name, function); } -void Object::defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *), - void (*setter)(const BuiltinFunction *, Scope &, CallData *)) +void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *), + ReturnedValue (*setter)(const BuiltinFunction *, CallData *)) { ExecutionEngine *e = engine(); Scope scope(e); @@ -183,8 +183,8 @@ void Object::defineAccessorProperty(const QString &name, void (*getter)(const Bu defineAccessorProperty(s, getter, setter); } -void Object::defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *), - void (*setter)(const BuiltinFunction *, Scope &, CallData *)) +void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *), + ReturnedValue (*setter)(const BuiltinFunction *, CallData *)) { ExecutionEngine *v4 = engine(); QV4::Scope scope(v4); diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 5c642bef0a..fc9a42921e 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -288,12 +288,12 @@ struct Q_QML_EXPORT Object: Managed { insertMember(name, value, Attr_Data|Attr_NotEnumerable); } void defineDefaultProperty(const QString &name, const Value &value); - void defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0); - void defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0); - 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 *)); + void defineDefaultProperty(const QString &name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount = 0); + void defineDefaultProperty(String *name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount = 0); + void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *), + ReturnedValue (*setter)(const BuiltinFunction *, CallData *)); + void defineAccessorProperty(String *name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *), + ReturnedValue (*setter)(const BuiltinFunction *, 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/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 27bab52064..6dff3107cf 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -125,58 +125,78 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor) insertMember(v4->id___proto__(), p, Attr_Accessor|Attr_NotEnumerable); } -void ObjectPrototype::method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_getPrototypeOf(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); + if (callData->argc < 1) + return scope.engine->throwTypeError(); + ScopedObject o(scope, callData->args[0].toObject(scope.engine)); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedObject p(scope, o->prototype()); - scope.result = !!p ? p->asReturnedValue() : Encode::null(); + return (!!p ? p->asReturnedValue() : Encode::null()); } -void ObjectPrototype::method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); + if (callData->argc < 1) + return scope.engine->throwTypeError(); + ScopedObject O(scope, callData->args[0].toObject(scope.engine)); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); if (ArgumentsObject::isNonStrictArgumentsObject(O)) static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate(); ScopedValue v(scope, callData->argument(1)); ScopedString name(scope, v->toString(scope.engine)); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); PropertyAttributes attrs; ScopedProperty desc(scope); O->getOwnProperty(name, &attrs, desc); - scope.result = fromPropertyDescriptor(scope.engine, desc, attrs); + return fromPropertyDescriptor(scope.engine, desc, attrs); } -void ObjectPrototype::method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_getOwnPropertyNames(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); + if (callData->argc < 1) + return scope.engine->throwTypeError(); + ScopedObject O(scope, callData->args[0].toObject(scope.engine)); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); - scope.result = getOwnPropertyNames(scope.engine, callData->args[0]); + return Encode(getOwnPropertyNames(scope.engine, callData->args[0])); } // 19.1.2.1 -void ObjectPrototype::method_assign(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_assign(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); + if (callData->argc < 1) + return scope.engine->throwTypeError(); + ScopedObject to(scope, callData->args[0].toObject(scope.engine)); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); - if (callData->argc == 1) { - scope.result = to; - return; - } + if (callData->argc == 1) + return to.asReturnedValue(); for (int i = 1; i < callData->argc; ++i) { if (callData->args[i].isUndefined() || callData->args[i].isNull()) continue; ScopedObject from(scope, callData->args[i].toObject(scope.engine)); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); QV4::ScopedArrayObject keys(scope, QV4::ObjectPrototype::getOwnPropertyNames(scope.engine, from)); quint32 length = keys->getLength(); @@ -197,64 +217,66 @@ void ObjectPrototype::method_assign(const BuiltinFunction *, Scope &scope, CallD propValue = from->get(nextKey); to->set(nextKey, propValue, Object::DoThrowOnRejection); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); } } - scope.result = to; + return to.asReturnedValue(); } -void ObjectPrototype::method_create(const BuiltinFunction *builtin, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_create(const BuiltinFunction *builtin, CallData *callData) { + Scope scope(builtin); ScopedValue O(scope, callData->argument(0)); - if (!O->isObject() && !O->isNull()) { - scope.result = scope.engine->throwTypeError(); - return; - } + if (!O->isObject() && !O->isNull()) + return scope.engine->throwTypeError(); ScopedObject newObject(scope, scope.engine->newObject()); newObject->setPrototype(O->as<Object>()); if (callData->argc > 1 && !callData->args[1].isUndefined()) { callData->args[0] = newObject; - method_defineProperties(builtin, scope, callData); - return; + return method_defineProperties(builtin, callData); } - scope.result = newObject; + return newObject.asReturnedValue(); } -void ObjectPrototype::method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_defineProperty(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject O(scope, callData->argument(0)); - if (!O) { - scope.result = scope.engine->throwTypeError(); - return; - } + if (!O) + return scope.engine->throwTypeError(); ScopedString name(scope, callData->argument(1), ScopedString::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedValue attributes(scope, callData->argument(2)); ScopedProperty pd(scope); PropertyAttributes attrs; toPropertyDescriptor(scope.engine, attributes, pd, &attrs); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); if (!O->__defineOwnProperty__(scope.engine, name, pd, attrs)) THROW_TYPE_ERROR(); - scope.result = O; + return O.asReturnedValue(); } -void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_defineProperties(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject O(scope, callData->argument(0)); if (!O) THROW_TYPE_ERROR(); ScopedObject o(scope, callData->argument(1), ScopedObject::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedValue val(scope); @@ -271,7 +293,8 @@ void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &sc PropertyAttributes nattrs; val = o->getValue(pd->value, attrs); toPropertyDescriptor(scope.engine, val, n, &nattrs); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); bool ok; if (name) ok = O->__defineOwnProperty__(scope.engine, name, n, nattrs); @@ -281,17 +304,16 @@ void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &sc THROW_TYPE_ERROR(); } - scope.result = O; + return O.asReturnedValue(); } -void ObjectPrototype::method_seal(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_seal(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->argument(0)); - if (!o) { + if (!o) // 19.1.2.17, 1 - scope.result = callData->argument(0); - return; - } + return callData->argument(0); o->setInternalClass(o->internalClass()->sealed()); @@ -303,17 +325,16 @@ void ObjectPrototype::method_seal(const BuiltinFunction *, Scope &scope, CallDat } } - scope.result = o; + return o.asReturnedValue(); } -void ObjectPrototype::method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_freeze(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->argument(0)); - if (!o) { + if (!o) // 19.1.2.5, 1 - scope.result = callData->argument(0); - return; - } + return callData->argument(0); if (ArgumentsObject::isNonStrictArgumentsObject(o)) static_cast<ArgumentsObject *>(o.getPointer())->fullyCreate(); @@ -329,116 +350,94 @@ void ObjectPrototype::method_freeze(const BuiltinFunction *, Scope &scope, CallD o->arrayData()->attrs[i].setWritable(false); } } - scope.result = o; + return o.asReturnedValue(); } -void ObjectPrototype::method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_preventExtensions(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->args[0].toObject(scope.engine)); - if (!o) { - scope.result = callData->argument(0); - return; - } + if (!o) + return callData->argument(0); o->setInternalClass(o->internalClass()->nonExtensible()); - scope.result = o; + return o.asReturnedValue(); } -void ObjectPrototype::method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_isSealed(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->args[0].toObject(scope.engine)); - if (!o) { - scope.result = Encode(true); - return; - } + if (!o) + return Encode(true); - if (o->isExtensible()) { - scope.result = Encode(false); - return; - } + if (o->isExtensible()) + return Encode(false); - if (o->internalClass() != o->internalClass()->sealed()) { - scope.result = Encode(false); - return; - } + if (o->internalClass() != o->internalClass()->sealed()) + return Encode(false); - if (!o->arrayData() || !o->arrayData()->length()) { - scope.result = Encode(true); - return; - } + if (!o->arrayData() || !o->arrayData()->length()) + return Encode(true); Q_ASSERT(o->arrayData() && o->arrayData()->length()); - if (!o->arrayData()->attrs) { - scope.result = Encode(false); - return; - } + if (!o->arrayData()->attrs) + return Encode(false); for (uint i = 0; i < o->arrayData()->values.alloc; ++i) { if (!o->arrayData()->isEmpty(i)) - if (o->arrayData()->attributes(i).isConfigurable()) { - scope.result = Encode(false); - return; - } + if (o->arrayData()->attributes(i).isConfigurable()) + return Encode(false); } - scope.result = Encode(true); + return Encode(true); } -void ObjectPrototype::method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_isFrozen(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->args[0].toObject(scope.engine)); - if (!o) { - scope.result = Encode(true); - return; - } + if (!o) + return Encode(true); - if (o->isExtensible()) { - scope.result = Encode(false); - return; - } + if (o->isExtensible()) + return Encode(false); - if (o->internalClass() != o->internalClass()->frozen()) { - scope.result = Encode(false); - return; - } + if (o->internalClass() != o->internalClass()->frozen()) + return Encode(false); - if (!o->arrayData() || !o->arrayData()->length()) { - scope.result = Encode(true); - return; - } + if (!o->arrayData() || !o->arrayData()->length()) + return Encode(true); Q_ASSERT(o->arrayData() && o->arrayData()->length()); - if (!o->arrayData()->attrs) { - scope.result = Encode(false); - return; - } + if (!o->arrayData()->attrs) + return Encode(false); for (uint i = 0; i < o->arrayData()->values.alloc; ++i) { if (!o->arrayData()->isEmpty(i)) - if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable()) { - scope.result = Encode(false); - return; - } + if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable()) + return Encode(false); } - scope.result = Encode(true); + return Encode(true); } -void ObjectPrototype::method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_isExtensible(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->args[0].toObject(scope.engine)); - if (!o) { - scope.result = Encode(false); - return; - } + if (!o) + return Encode(false); - scope.result = Encode((bool)o->isExtensible()); + return Encode((bool)o->isExtensible()); } -void ObjectPrototype::method_keys(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_keys(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->args[0].toObject(scope.engine)); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedArrayObject a(scope, scope.engine->newArrayObject()); @@ -451,24 +450,27 @@ void ObjectPrototype::method_keys(const BuiltinFunction *, Scope &scope, CallDat a->push_back(name); } - scope.result = a; + return a.asReturnedValue(); } -void ObjectPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); if (callData->thisObject.isUndefined()) { - scope.result = scope.engine->newString(QStringLiteral("[object Undefined]")); + return Encode(v4->newString(QStringLiteral("[object Undefined]"))); } else if (callData->thisObject.isNull()) { - scope.result = scope.engine->newString(QStringLiteral("[object Null]")); + return Encode(v4->newString(QStringLiteral("[object Null]"))); } else { + Scope scope(v4); ScopedObject obj(scope, callData->thisObject.toObject(scope.engine)); QString className = obj->className(); - scope.result = scope.engine->newString(QStringLiteral("[object %1]").arg(className)); + return Encode(v4->newString(QStringLiteral("[object %1]").arg(className))); } } -void ObjectPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_toLocaleString(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->thisObject.toObject(scope.engine)); if (!o) RETURN_UNDEFINED(); @@ -478,61 +480,66 @@ void ObjectPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scop THROW_TYPE_ERROR(); ScopedCallData cData(scope); cData->thisObject = o; - scope.result = f->call(callData); + return f->call(callData); } -void ObjectPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_valueOf(const BuiltinFunction *b, CallData *callData) { - scope.result = callData->thisObject.toObject(scope.engine); + return Encode(callData->thisObject.toObject(b->engine())); } -void ObjectPrototype::method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_hasOwnProperty(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedString P(scope, callData->argument(0), ScopedString::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedObject O(scope, callData->thisObject, ScopedObject::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); bool r = O->hasOwnProperty(P); if (!r) r = !O->query(P).isEmpty(); - scope.result = Encode(r); + return Encode(r); } -void ObjectPrototype::method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_isPrototypeOf(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject V(scope, callData->argument(0)); - if (!V) { - scope.result = Encode(false); - return; - } + if (!V) + return Encode(false); ScopedObject O(scope, callData->thisObject, ScopedObject::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedObject proto(scope, V->prototype()); while (proto) { - if (O->d() == proto->d()) { - scope.result = Encode(true); - return; - } + if (O->d() == proto->d()) + return Encode(true); proto = proto->prototype(); } - scope.result = Encode(false); + return Encode(false); } -void ObjectPrototype::method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_propertyIsEnumerable(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedString p(scope, callData->argument(0), ScopedString::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedObject o(scope, callData->thisObject, ScopedObject::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); PropertyAttributes attrs; o->getOwnProperty(p, &attrs); - scope.result = Encode(attrs.isEnumerable()); + return Encode(attrs.isEnumerable()); } -void ObjectPrototype::method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_defineGetter(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); if (callData->argc < 2) THROW_TYPE_ERROR(); @@ -541,7 +548,8 @@ void ObjectPrototype::method_defineGetter(const BuiltinFunction *, Scope &scope, THROW_TYPE_ERROR(); ScopedString prop(scope, callData->argument(0), ScopedString::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedObject o(scope, callData->thisObject); if (!o) { @@ -557,8 +565,9 @@ void ObjectPrototype::method_defineGetter(const BuiltinFunction *, Scope &scope, RETURN_UNDEFINED(); } -void ObjectPrototype::method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_defineSetter(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); if (callData->argc < 2) THROW_TYPE_ERROR(); @@ -567,7 +576,8 @@ void ObjectPrototype::method_defineSetter(const BuiltinFunction *, Scope &scope, THROW_TYPE_ERROR(); ScopedString prop(scope, callData->argument(0), ScopedString::Convert); - CHECK_EXCEPTION(); + if (scope.engine->hasException) + return QV4::Encode::undefined(); ScopedObject o(scope, callData->thisObject); if (!o) { @@ -583,17 +593,19 @@ void ObjectPrototype::method_defineSetter(const BuiltinFunction *, Scope &scope, RETURN_UNDEFINED(); } -void ObjectPrototype::method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_get_proto(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->thisObject.as<Object>()); if (!o) THROW_TYPE_ERROR(); - scope.result = o->prototype(); + return Encode(o->prototype()); } -void ObjectPrototype::method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ObjectPrototype::method_set_proto(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject o(scope, callData->thisObject); if (!o || !callData->argc) THROW_TYPE_ERROR(); @@ -612,10 +624,8 @@ void ObjectPrototype::method_set_proto(const BuiltinFunction *, Scope &scope, Ca ok = o->setPrototype(p); } } - if (!ok) { - scope.result = scope.engine->throwTypeError(QStringLiteral("Cyclic __proto__ value")); - return; - } + if (!ok) + return scope.engine->throwTypeError(QStringLiteral("Cyclic __proto__ value")); RETURN_UNDEFINED(); } diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h index d1383df192..c3c63de8ce 100644 --- a/src/qml/jsruntime/qv4objectproto_p.h +++ b/src/qml/jsruntime/qv4objectproto_p.h @@ -78,33 +78,33 @@ struct ObjectPrototype: Object { void init(ExecutionEngine *engine, Object *ctor); - static void method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_assign(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_create(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_seal(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_keys(const BuiltinFunction *, Scope &scope, CallData *callData); - - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData); - - static void method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData); - - static void method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_getPrototypeOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getOwnPropertyDescriptor(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_getOwnPropertyNames(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_assign(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_create(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_defineProperty(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_defineProperties(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_seal(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_freeze(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_preventExtensions(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isSealed(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isFrozen(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isExtensible(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_keys(const BuiltinFunction *, CallData *callData); + + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_valueOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_hasOwnProperty(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_isPrototypeOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_propertyIsEnumerable(const BuiltinFunction *, CallData *callData); + + static ReturnedValue method_defineGetter(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_defineSetter(const BuiltinFunction *, CallData *callData); + + static ReturnedValue method_get_proto(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_set_proto(const BuiltinFunction *, CallData *callData); static void toPropertyDescriptor(ExecutionEngine *engine, const Value &v, Property *desc, PropertyAttributes *attrs); static ReturnedValue fromPropertyDescriptor(ExecutionEngine *engine, const Property *desc, PropertyAttributes attrs); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index b710fd8444..d7f10ece97 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -899,8 +899,10 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase } // namespace QV4 -void QObjectWrapper::method_connect(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QObjectWrapper::method_connect(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); + if (callData->argc == 0) THROW_GENERIC_ERROR("Function.prototype.connect: no arguments given"); @@ -949,8 +951,10 @@ void QObjectWrapper::method_connect(const BuiltinFunction *, Scope &scope, CallD RETURN_UNDEFINED(); } -void QObjectWrapper::method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QObjectWrapper::method_disconnect(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); + if (callData->argc == 0) THROW_GENERIC_ERROR("Function.prototype.disconnect: no arguments given"); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 9188bba990..3999b641f9 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -198,8 +198,8 @@ protected: static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); static void markObjects(Heap::Base *that, QV4::MarkStack *markStack); - static void method_connect(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_connect(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_disconnect(const BuiltinFunction *, CallData *callData); private: Q_NEVER_INLINE static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object); diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 4df9d47e7d..8a23da24cc 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -313,11 +313,12 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor) defineDefaultProperty(QStringLiteral("compile"), method_compile, 2); } -void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue RegExpPrototype::method_exec(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>()); if (!r) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); ScopedValue arg(scope, callData->argument(0)); ScopedString str(scope, arg->toString(scope.engine)); @@ -366,35 +367,36 @@ void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallDat if (r->global()) r->setLastIndex(matchOffsets[1]); - scope.result = array; + return array.asReturnedValue(); } -void RegExpPrototype::method_test(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue RegExpPrototype::method_test(const BuiltinFunction *b, CallData *callData) { - method_exec(b, scope, callData); - scope.result = Encode(!scope.result.isNull()); + Value res = Value::fromReturnedValue(method_exec(b, callData)); + return Encode(!res.isNull()); } -void RegExpPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue RegExpPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { - Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>()); + ExecutionEngine *v4 = b->engine(); + RegExpObject *r = callData->thisObject.as<RegExpObject>(); if (!r) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); - scope.result = scope.engine->newString(r->toString()); + return Encode(v4->newString(r->toString())); } -void RegExpPrototype::method_compile(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue RegExpPrototype::method_compile(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>()); if (!r) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); ScopedCallData cData(scope, callData->argc); memcpy(cData->args, callData->args, callData->argc*sizeof(Value)); - scope.result = scope.engine->regExpCtor()->as<FunctionObject>()->construct(cData); - Scoped<RegExpObject> re(scope, scope.result.asReturnedValue()); + Scoped<RegExpObject> re(scope, scope.engine->regExpCtor()->as<FunctionObject>()->construct(cData)); r->d()->value.set(scope.engine, re->value()); r->d()->global = re->global(); @@ -402,39 +404,45 @@ void RegExpPrototype::method_compile(const BuiltinFunction *, Scope &scope, Call } template <int index> -void RegExpPrototype::method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue RegExpPrototype::method_get_lastMatch_n(const BuiltinFunction *b, CallData *) { + Scope scope(b); ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch()); - scope.result = lastMatch ? lastMatch->getIndexed(index) : Encode::undefined(); - if (scope.result.isUndefined()) - scope.result = scope.engine->newString(); + ScopedValue res(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined()); + if (res->isUndefined()) + res = scope.engine->newString(); + return res->asReturnedValue(); } -void RegExpPrototype::method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue RegExpPrototype::method_get_lastParen(const BuiltinFunction *b, CallData *) { + Scope scope(b); ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch()); - scope.result = lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined(); - if (scope.result.isUndefined()) - scope.result = scope.engine->newString(); + ScopedValue res(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined()); + if (res->isUndefined()) + res = scope.engine->newString(); + return res->asReturnedValue(); } -void RegExpPrototype::method_get_input(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue RegExpPrototype::method_get_input(const BuiltinFunction *b, CallData *) { - scope.result = static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastInput(); + return static_cast<RegExpCtor*>(b->engine()->regExpCtor())->lastInput()->asReturnedValue(); } -void RegExpPrototype::method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue RegExpPrototype::method_get_leftContext(const BuiltinFunction *b, CallData *) { + Scope scope(b); Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor()); QString lastInput = regExpCtor->lastInput()->toQString(); - scope.result = scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart())); + return Encode(scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart()))); } -void RegExpPrototype::method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue RegExpPrototype::method_get_rightContext(const BuiltinFunction *b, CallData *) { + Scope scope(b); Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor()); QString lastInput = regExpCtor->lastInput()->toQString(); - scope.result = scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd())); + return Encode(scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()))); } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index ea16591445..f04940255b 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -158,17 +158,17 @@ struct RegExpPrototype: RegExpObject { void init(ExecutionEngine *engine, Object *ctor); - static void method_exec(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_test(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_compile(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_exec(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_test(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_compile(const BuiltinFunction *, CallData *callData); template <int index> - static void method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_input(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_get_lastMatch_n(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_lastParen(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_input(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_leftContext(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_rightContext(const BuiltinFunction *, CallData *callData); }; } diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 04a0c74133..7df723e9d0 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -71,50 +71,39 @@ struct ScopedValue; #define CHECK_EXCEPTION() \ do { \ if (scope.hasException()) { \ - scope.result = QV4::Encode::undefined(); \ - return; \ + return QV4::Encode::undefined(); \ } \ } while (false) #define RETURN_UNDEFINED() \ - do { \ - scope.result = QV4::Encode::undefined(); \ - return; \ - } while (false) + return QV4::Encode::undefined() #define RETURN_RESULT(r) \ - do { \ - scope.result = r; \ - return; \ - } while (false) + return QV4::Encode(r) #define THROW_TYPE_ERROR() \ - do { \ - scope.result = scope.engine->throwTypeError(); \ - return; \ - } while (false) + return scope.engine->throwTypeError() #define THROW_GENERIC_ERROR(str) \ - do { \ - scope.result = scope.engine->throwError(QString::fromUtf8(str)); \ - return; \ - } while (false) + return scope.engine->throwError(QString::fromUtf8(str)) struct Scope { inline Scope(ExecutionContext *ctx) : engine(ctx->engine()) , mark(engine->jsStackTop) - , result(*engine->jsAlloca(1)) { - result = Encode::undefined(); } explicit Scope(ExecutionEngine *e) : engine(e) , mark(engine->jsStackTop) - , result(*engine->jsAlloca(1)) { - result = Encode::undefined(); + } + + inline Scope(const Managed *m) + : engine(m->engine()) + , mark(engine->jsStackTop) + { } ~Scope() { @@ -139,7 +128,6 @@ struct Scope { ExecutionEngine *engine; Value *mark; - Value &result; private: Q_DISABLE_COPY(Scope) diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 7868b1a7d2..019fa54fb0 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -159,10 +159,9 @@ ReturnedValue Script::run() ScopedCallData callData(valueScope); callData->thisObject = Primitive::undefinedValue(); if (vmFunction->canUseSimpleFunction()) - qml->simpleCall(valueScope, callData, vmFunction); + return qml->simpleCall(valueScope, callData, vmFunction); else - qml->call(valueScope, callData, vmFunction); - return valueScope.result.asReturnedValue(); + return qml->call(valueScope, callData, vmFunction); } } diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index ec3ff0ea1d..08c64aaa27 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -450,8 +450,9 @@ public: storeReference(); } - static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData) + static QV4::ReturnedValue method_get_length(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >()); if (!This) THROW_TYPE_ERROR(); @@ -464,8 +465,9 @@ public: RETURN_RESULT(Encode(qint32(This->d()->container->size()))); } - static void method_set_length(const BuiltinFunction *, Scope &scope, CallData *callData) + static QV4::ReturnedValue method_set_length(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >()); if (!This) THROW_TYPE_ERROR(); @@ -647,14 +649,20 @@ void SequencePrototype::init() } #undef REGISTER_QML_SEQUENCE_METATYPE -void SequencePrototype::method_sort(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue SequencePrototype::method_valueOf(const BuiltinFunction *f, CallData *callData) { + return Encode(callData->thisObject.toString(f->engine())); +} + +ReturnedValue SequencePrototype::method_sort(const BuiltinFunction *b, CallData *callData) +{ + Scope scope(b); QV4::ScopedObject o(scope, callData->thisObject); if (!o || !o->isListType()) THROW_TYPE_ERROR(); if (callData->argc >= 2) - RETURN_RESULT(o); + return o.asReturnedValue(); #define CALL_SORT(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \ if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \ @@ -665,7 +673,7 @@ void SequencePrototype::method_sort(const BuiltinFunction *b, Scope &scope, Call #undef CALL_SORT {} - RETURN_RESULT(o); + return o.asReturnedValue(); } #define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \ diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h index 2b8d1ea716..169a48c2f9 100644 --- a/src/qml/jsruntime/qv4sequenceobject_p.h +++ b/src/qml/jsruntime/qv4sequenceobject_p.h @@ -68,12 +68,8 @@ struct SequencePrototype : public QV4::Object V4_PROTOTYPE(arrayPrototype) void init(); - static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) - { - scope.result = callData->thisObject.toString(scope.engine); - } - - static void method_sort(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_valueOf(const BuiltinFunction *f, CallData *callData); + static ReturnedValue method_sort(const BuiltinFunction *, CallData *callData); static bool isSequenceType(int sequenceTypeId); static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 16998c4728..d21dd4808f 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -207,35 +207,38 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("trim"), method_trim); } -static QString getThisString(Scope &scope, CallData *callData) +static QString getThisString(ExecutionEngine *v4, CallData *callData) { - ScopedValue t(scope, callData->thisObject); + Value *t = &callData->thisObject; if (String *s = t->stringValue()) return s->toQString(); if (StringObject *thisString = t->as<StringObject>()) return thisString->d()->string->toQString(); if (t->isUndefined() || t->isNull()) { - scope.engine->throwTypeError(); + v4->throwTypeError(); return QString(); } return t->toQString(); } -void StringPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { if (callData->thisObject.isString()) RETURN_RESULT(callData->thisObject); + ExecutionEngine *v4 = b->engine(); StringObject *o = callData->thisObject.as<StringObject>(); if (!o) - THROW_TYPE_ERROR(); - scope.result = o->d()->string; + return v4->throwTypeError(); + return o->d()->string->asReturnedValue(); } -void StringPrototype::method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_charAt(const BuiltinFunction *b, CallData *callData) { - const QString str = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString str = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); int pos = 0; if (callData->argc > 0) @@ -245,13 +248,15 @@ void StringPrototype::method_charAt(const BuiltinFunction *, Scope &scope, CallD if (pos >= 0 && pos < str.length()) result += str.at(pos); - scope.result = scope.engine->newString(result); + return Encode(v4->newString(result)); } -void StringPrototype::method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_charCodeAt(const BuiltinFunction *b, CallData *callData) { - const QString str = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString str = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); int pos = 0; if (callData->argc > 0) @@ -261,35 +266,41 @@ void StringPrototype::method_charCodeAt(const BuiltinFunction *, Scope &scope, C if (pos >= 0 && pos < str.length()) RETURN_RESULT(Encode(str.at(pos).unicode())); - scope.result = Encode(qt_qnan()); + return Encode(qt_qnan()); } -void StringPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_concat(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); + Scope scope(v4); ScopedString s(scope); for (int i = 0; i < callData->argc; ++i) { s = callData->args[i].toString(scope.engine); - CHECK_EXCEPTION(); + if (v4->hasException) + return QV4::Encode::undefined(); Q_ASSERT(s->isString()); value += s->toQString(); } - scope.result = scope.engine->newString(value); + return Encode(v4->newString(value)); } -void StringPrototype::method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_endsWith(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); QString searchString; if (callData->argc) { if (callData->args[0].as<RegExpObject>()) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); searchString = callData->args[0].toQString(); } @@ -301,13 +312,15 @@ void StringPrototype::method_endsWith(const BuiltinFunction *, Scope &scope, Cal RETURN_RESULT(Encode(value.endsWith(searchString))); QStringRef stringToSearch = value.leftRef(pos); - scope.result = Encode(stringToSearch.endsWith(searchString)); + return Encode(stringToSearch.endsWith(searchString)); } -void StringPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_indexOf(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); QString searchString; if (callData->argc) @@ -321,26 +334,28 @@ void StringPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, Call if (! value.isEmpty()) index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length())); - scope.result = Encode(index); + return Encode(index); } -void StringPrototype::method_includes(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_includes(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); QString searchString; if (callData->argc) { if (callData->args[0].as<RegExpObject>()) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); searchString = callData->args[0].toQString(); } int pos = 0; if (callData->argc > 1) { - ScopedValue posArg(scope, callData->argument(1)); - pos = (int) posArg->toInteger(); - if (!posArg->isInteger() && posArg->isNumber() && qIsInf(posArg->toNumber())) + Value &posArg = callData->args[1]; + pos = (int) posArg.toInteger(); + if (!posArg.isInteger() && posArg.isNumber() && qIsInf(posArg.toNumber())) pos = value.length(); } @@ -348,20 +363,21 @@ void StringPrototype::method_includes(const BuiltinFunction *, Scope &scope, Cal RETURN_RESULT(Encode(value.contains(searchString))); QStringRef stringToSearch = value.midRef(pos); - scope.result = Encode(stringToSearch.contains(searchString)); + return Encode(stringToSearch.contains(searchString)); } -void StringPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_lastIndexOf(const BuiltinFunction *b, CallData *callData) { - const QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); QString searchString; if (callData->argc) searchString = callData->args[0].toQString(); - ScopedValue posArg(scope, callData->argument(1)); - double position = RuntimeHelpers::toNumber(posArg); + double position = callData->argc > 1 ? RuntimeHelpers::toNumber(callData->args[1]) : +qInf(); if (std::isnan(position)) position = +qInf(); else @@ -373,24 +389,30 @@ void StringPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, if (searchString.isNull() && pos == 0) RETURN_RESULT(Encode(-1)); int index = value.lastIndexOf(searchString, pos); - scope.result = Encode(index); + return Encode(index); } -void StringPrototype::method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_localeCompare(const BuiltinFunction *b, CallData *callData) { - const QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); + + if (callData->argc < 1) + callData->args[0] = Encode::undefined(); - ScopedValue v(scope, callData->argument(0)); - const QString that = v->toQString(); - scope.result = Encode(QString::localeAwareCompare(value, that)); + const QString that = callData->args[0].toQString(); + return Encode(QString::localeAwareCompare(value, that)); } -void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_match(const BuiltinFunction *b, CallData *callData) { + ExecutionEngine *v4 = b->engine(); if (callData->thisObject.isUndefined() || callData->thisObject.isNull()) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); + Scope scope(v4); ScopedString s(scope, callData->thisObject.toString(scope.engine)); ScopedValue regexp(scope, callData->argument(0)); @@ -403,7 +425,7 @@ void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallDa if (!rx) // ### CHECK - THROW_TYPE_ERROR(); + return v4->throwTypeError(); bool global = rx->global(); @@ -414,10 +436,8 @@ void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallDa ScopedCallData cData(scope, 1); cData->thisObject = rx; cData->args[0] = s; - if (!global) { - scope.result = exec->call(cData); - return; - } + if (!global) + return exec->call(cData); ScopedString lastIndex(scope, scope.engine->newString(QStringLiteral("lastIndex"))); rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0))); @@ -427,11 +447,12 @@ void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallDa uint n = 0; ScopedValue matchStr(scope); ScopedValue index(scope); + ScopedValue result(scope); while (1) { - scope.result = exec->call(cData); - if (scope.result.isNull()) + result = exec->call(cData); + if (result->isNull()) break; - assert(scope.result.isObject()); + assert(result->isObject()); index = rx->get(lastIndex, 0); double thisIndex = index->toInteger(); if (previousLastIndex == thisIndex) { @@ -440,29 +461,30 @@ void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallDa } else { previousLastIndex = thisIndex; } - matchStr = scope.result.objectValue()->getIndexed(0); + matchStr = result->objectValue()->getIndexed(0); a->arraySet(n, matchStr); ++n; } if (!n) - scope.result = Encode::null(); + result = Encode::null(); else - scope.result = a; + result = a.asReturnedValue(); + return result->asReturnedValue(); } -void StringPrototype::method_repeat(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_repeat(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); double repeats = callData->args[0].toInteger(); - if (repeats < 0 || qIsInf(repeats)) { - scope.result = scope.engine->throwRangeError(QLatin1String("Invalid count value")); - return; - } + if (repeats < 0 || qIsInf(repeats)) + return v4->throwRangeError(QLatin1String("Invalid count value")); - scope.result = scope.engine->newString(value.repeated(int(repeats))); + return Encode(v4->newString(value.repeated(int(repeats)))); } static void appendReplacementString(QString *result, const QString &input, const QString& replaceValue, uint* matchOffsets, int captureCount) @@ -511,7 +533,7 @@ static void appendReplacementString(QString *result, const QString &input, const } } -void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_replace(const BuiltinFunction *b, CallData *callData) { QString string; if (StringObject *thisString = callData->thisObject.as<StringObject>()) @@ -526,6 +548,7 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call uint _matchOffsets[64]; uint *matchOffsets = _matchOffsets; + Scope scope(b); ScopedValue searchValue(scope, callData->argument(0)); Scoped<RegExpObject> regExp(scope, searchValue); if (regExp) { @@ -622,38 +645,44 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call if (matchOffsets != _matchOffsets) free(matchOffsets); - scope.result = scope.engine->newString(result); + return Encode(scope.engine->newString(result)); } -void StringPrototype::method_search(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_search(const BuiltinFunction *b, CallData *callData) { - QString string = getThisString(scope, callData); - scope.result = callData->argument(0); - CHECK_EXCEPTION(); + Scope scope(b); + ScopedValue regExpObj(scope); + QString string = getThisString(scope.engine, callData); + regExpObj = callData->argument(0); + if (scope.engine->hasException) + return QV4::Encode::undefined(); - Scoped<RegExpObject> regExp(scope, scope.result.as<RegExpObject>()); + RegExpObject *regExp = regExpObj->as<RegExpObject>(); if (!regExp) { ScopedCallData callData(scope, 1); - callData->args[0] = scope.result; - scope.result = scope.engine->regExpCtor()->construct(callData); - CHECK_EXCEPTION(); + callData->args[0] = regExpObj; + regExpObj = scope.engine->regExpCtor()->construct(callData); + if (scope.engine->hasException) + return QV4::Encode::undefined(); - regExp = scope.result.as<RegExpObject>(); + regExp = regExpObj->as<RegExpObject>(); Q_ASSERT(regExp); } Scoped<RegExp> re(scope, regExp->value()); Q_ALLOCA_VAR(uint, matchOffsets, regExp->value()->captureCount() * 2 * sizeof(uint)); uint result = re->match(string, /*offset*/0, matchOffsets); if (result == JSC::Yarr::offsetNoMatch) - scope.result = Encode(-1); + return Encode(-1); else - scope.result = Encode(result); + return Encode(result); } -void StringPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_slice(const BuiltinFunction *b, CallData *callData) { - const QString text = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString text = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); const double length = text.length(); @@ -675,14 +704,17 @@ void StringPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallDa const int intEnd = int(end); int count = qMax(0, intEnd - intStart); - scope.result = scope.engine->newString(text.mid(intStart, count)); + return Encode(v4->newString(text.mid(intStart, count))); } -void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_split(const BuiltinFunction *b, CallData *callData) { - QString text = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + QString text = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); + Scope scope(v4); ScopedValue separatorValue(scope, callData->argument(0)); ScopedValue limitValue(scope, callData->argument(1)); @@ -692,7 +724,7 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa if (limitValue->isUndefined()) { ScopedString s(scope, scope.engine->newString(text)); array->push_back(s); - RETURN_RESULT(array); + return array.asReturnedValue(); } RETURN_RESULT(scope.engine->newString(text.left(limitValue->toInteger()))); } @@ -700,7 +732,7 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32(); if (limit == 0) - RETURN_RESULT(array); + return array.asReturnedValue(); Scoped<RegExpObject> re(scope, separatorValue); if (re) { @@ -741,7 +773,7 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa if (separator.isEmpty()) { for (uint i = 0; i < qMin(limit, uint(text.length())); ++i) array->push_back((s = scope.engine->newString(text.mid(i, 1)))); - RETURN_RESULT(array); + return array.asReturnedValue(); } int start = 0; @@ -755,18 +787,20 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa if (array->getLength() < limit && start != -1) array->push_back((s = scope.engine->newString(text.mid(start)))); } - RETURN_RESULT(array); + return array.asReturnedValue(); } -void StringPrototype::method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_startsWith(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); QString searchString; if (callData->argc) { if (callData->args[0].as<RegExpObject>()) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); searchString = callData->args[0].toQString(); } @@ -775,16 +809,18 @@ void StringPrototype::method_startsWith(const BuiltinFunction *, Scope &scope, C pos = (int) callData->args[1].toInteger(); if (pos == 0) - RETURN_RESULT(Encode(value.startsWith(searchString))); + return Encode(value.startsWith(searchString)); QStringRef stringToSearch = value.midRef(pos); RETURN_RESULT(Encode(stringToSearch.startsWith(searchString))); } -void StringPrototype::method_substr(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_substr(const BuiltinFunction *b, CallData *callData) { - const QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); double start = 0; if (callData->argc > 0) @@ -802,13 +838,15 @@ void StringPrototype::method_substr(const BuiltinFunction *, Scope &scope, CallD qint32 x = Primitive::toInt32(start); qint32 y = Primitive::toInt32(length); - scope.result = scope.engine->newString(value.mid(x, y)); + return Encode(v4->newString(value.mid(x, y))); } -void StringPrototype::method_substring(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_substring(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); int length = value.length(); @@ -818,9 +856,8 @@ void StringPrototype::method_substring(const BuiltinFunction *, Scope &scope, Ca if (callData->argc > 0) start = callData->args[0].toInteger(); - ScopedValue endValue(scope, callData->argument(1)); - if (!endValue->isUndefined()) - end = endValue->toInteger(); + if (callData->argc > 1 && !callData->args[1].isUndefined()) + end = callData->args[1].toInteger(); if (std::isnan(start) || start < 0) start = 0; @@ -842,36 +879,40 @@ void StringPrototype::method_substring(const BuiltinFunction *, Scope &scope, Ca qint32 x = (int)start; qint32 y = (int)(end - start); - scope.result = scope.engine->newString(value.mid(x, y)); + return Encode(v4->newString(value.mid(x, y))); } -void StringPrototype::method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_toLowerCase(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); - scope.result = scope.engine->newString(value.toLower()); + return Encode(v4->newString(value.toLower())); } -void StringPrototype::method_toLocaleLowerCase(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_toLocaleLowerCase(const BuiltinFunction *b, CallData *callData) { - method_toLowerCase(b, scope, callData); + return method_toLowerCase(b, callData); } -void StringPrototype::method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_toUpperCase(const BuiltinFunction *b, CallData *callData) { - QString value = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + const QString value = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); - scope.result = scope.engine->newString(value.toUpper()); + return Encode(v4->newString(value.toUpper())); } -void StringPrototype::method_toLocaleUpperCase(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_toLocaleUpperCase(const BuiltinFunction *b, CallData *callData) { - return method_toUpperCase(b, scope, callData); + return method_toUpperCase(b, callData); } -void StringPrototype::method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_fromCharCode(const BuiltinFunction *b, CallData *callData) { QString str(callData->argc, Qt::Uninitialized); QChar *ch = str.data(); @@ -879,13 +920,15 @@ void StringPrototype::method_fromCharCode(const BuiltinFunction *, Scope &scope, *ch = QChar(callData->args[i].toUInt16()); ++ch; } - scope.result = scope.engine->newString(str); + return Encode(b->engine()->newString(str)); } -void StringPrototype::method_trim(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue StringPrototype::method_trim(const BuiltinFunction *b, CallData *callData) { - QString s = getThisString(scope, callData); - CHECK_EXCEPTION(); + ExecutionEngine *v4 = b->engine(); + QString s = getThisString(v4, callData); + if (v4->hasException) + return QV4::Encode::undefined(); const QChar *chars = s.constData(); int start, end; @@ -898,5 +941,5 @@ void StringPrototype::method_trim(const BuiltinFunction *, Scope &scope, CallDat break; } - scope.result = scope.engine->newString(QString(chars + start, end - start + 1)); + return Encode(v4->newString(QString(chars + start, end - start + 1))); } diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index f1c0c2904e..af5a5bead5 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -115,30 +115,30 @@ struct StringPrototype: StringObject V4_PROTOTYPE(objectPrototype) void init(ExecutionEngine *engine, Object *ctor); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_concat(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_includes(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_match(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_repeat(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_replace(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_search(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_split(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_substr(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_substring(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLocaleLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toLocaleUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_trim(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_charAt(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_charCodeAt(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_concat(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_endsWith(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_indexOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_includes(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_lastIndexOf(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_localeCompare(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_match(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_repeat(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_replace(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_search(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_slice(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_split(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_startsWith(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_substr(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_substring(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLowerCase(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleLowerCase(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toUpperCase(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toLocaleUpperCase(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_fromCharCode(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_trim(const BuiltinFunction *, CallData *callData); }; } diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index 1944e0b87e..12b01bd578 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -413,47 +413,52 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor) defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0); } -void TypedArrayPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue TypedArrayPrototype::method_get_buffer(const BuiltinFunction *b, CallData *callData) { - Scoped<TypedArray> v(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + TypedArray *v = callData->thisObject.as<TypedArray>(); if (!v) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); - scope.result = v->d()->buffer; + return v->d()->buffer->asReturnedValue(); } -void TypedArrayPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue TypedArrayPrototype::method_get_byteLength(const BuiltinFunction *b, CallData *callData) { - Scoped<TypedArray> v(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + TypedArray *v = callData->thisObject.as<TypedArray>(); if (!v) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); - scope.result = Encode(v->d()->byteLength); + return Encode(v->d()->byteLength); } -void TypedArrayPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue TypedArrayPrototype::method_get_byteOffset(const BuiltinFunction *b, CallData *callData) { - Scoped<TypedArray> v(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + TypedArray *v = callData->thisObject.as<TypedArray>(); if (!v) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); - scope.result = Encode(v->d()->byteOffset); + return Encode(v->d()->byteOffset); } -void TypedArrayPrototype::method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue TypedArrayPrototype::method_get_length(const BuiltinFunction *b, CallData *callData) { - Scoped<TypedArray> v(scope, callData->thisObject); + ExecutionEngine *v4 = b->engine(); + TypedArray *v = callData->thisObject.as<TypedArray>(); if (!v) - THROW_TYPE_ERROR(); + return v4->throwTypeError(); - scope.result = Encode(v->d()->byteLength/v->d()->type->bytesPerElement); + return Encode(v->d()->byteLength/v->d()->type->bytesPerElement); } -void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue TypedArrayPrototype::method_set(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); Scoped<TypedArray> a(scope, callData->thisObject); if (!a) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); Scoped<ArrayBuffer> buffer(scope, a->d()->buffer); if (!buffer) scope.engine->throwTypeError(); @@ -472,12 +477,12 @@ void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, Call // src is a regular object ScopedObject o(scope, callData->args[0].toObject(scope.engine)); if (scope.engine->hasException || !o) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); double len = ScopedValue(scope, o->get(scope.engine->id_length()))->toNumber(); uint l = (uint)len; if (scope.engine->hasException || l != len) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); if (offset + l > a->length()) RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); @@ -499,7 +504,7 @@ void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, Call // src is a typed array Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer); if (!srcBuffer) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); uint l = srcTypedArray->length(); if (offset + l > a->length()) @@ -537,16 +542,17 @@ void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, Call RETURN_UNDEFINED(); } -void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue TypedArrayPrototype::method_subarray(const BuiltinFunction *builtin, CallData *callData) { + Scope scope(builtin); Scoped<TypedArray> a(scope, callData->thisObject); if (!a) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); Scoped<ArrayBuffer> buffer(scope, a->d()->buffer); if (!buffer) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); int len = a->length(); double b = callData->argc > 0 ? callData->args[0].toInteger() : 0; @@ -568,11 +574,11 @@ void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope, ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor())); if (!constructor) - THROW_TYPE_ERROR(); + return scope.engine->throwTypeError(); 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); - scope.result = constructor->construct(cData); + return constructor->construct(cData); } diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index fad7901428..fc7aa78cda 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -153,13 +153,13 @@ struct TypedArrayPrototype : Object void init(ExecutionEngine *engine, TypedArrayCtor *ctor); - 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_get_buffer(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_byteLength(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_byteOffset(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_length(const BuiltinFunction *, CallData *callData); - static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_set(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_subarray(const BuiltinFunction *, CallData *callData); }; inline void diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index e34ee0ccbe..b6f2e837ba 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -667,30 +667,35 @@ struct Encode { return Primitive::nullValue().rawValue(); } - Encode(bool b) { + explicit Encode(bool b) { val = Primitive::fromBoolean(b).rawValue(); } - Encode(double d) { + explicit Encode(double d) { val = Primitive::fromDouble(d).rawValue(); } - Encode(int i) { + explicit Encode(int i) { val = Primitive::fromInt32(i).rawValue(); } - Encode(uint i) { + explicit Encode(uint i) { val = Primitive::fromUInt32(i).rawValue(); } - Encode(ReturnedValue v) { + explicit Encode(ReturnedValue v) { val = v; } Encode(Value v) { val = v.rawValue(); } - Encode(Heap::Base *o) { + explicit Encode(Heap::Base *o) { Q_ASSERT(o); val = Value::fromHeapObject(o).asReturnedValue(); } + explicit Encode(Value *o) { + Q_ASSERT(o); + val = o->asReturnedValue(); + } + static ReturnedValue smallestNumber(double d) { if (static_cast<int>(d) == d && !(d == 0. && std::signbit(d))) return Encode(static_cast<int>(d)); @@ -703,7 +708,7 @@ struct Encode { } quint64 val; private: - Encode(void *); + explicit Encode(void *); }; template<typename T> diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index f2ff5d307e..00be90b3c2 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -113,17 +113,17 @@ void VariantPrototype::init() defineDefaultProperty(engine()->id_toString(), method_toString, 0); } -void VariantPrototype::method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue VariantPrototype::method_preserve(const BuiltinFunction *, CallData *callData) { - Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>()); + VariantObject *o = callData->thisObject.as<QV4::VariantObject>(); if (o && o->d()->isScarce()) o->d()->addVmePropertyReference(); RETURN_UNDEFINED(); } -void VariantPrototype::method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue VariantPrototype::method_destroy(const BuiltinFunction *, CallData *callData) { - Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>()); + VariantObject *o = callData->thisObject.as<QV4::VariantObject>(); if (o) { if (o->d()->isScarce()) o->d()->addVmePropertyReference(); @@ -132,9 +132,10 @@ void VariantPrototype::method_destroy(const BuiltinFunction *, Scope &scope, Cal RETURN_UNDEFINED(); } -void VariantPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue VariantPrototype::method_toString(const BuiltinFunction *b, CallData *callData) { - Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>()); + ExecutionEngine *v4 = b->engine(); + VariantObject *o = callData->thisObject.as<QV4::VariantObject>(); if (!o) RETURN_UNDEFINED(); QString result = o->d()->data().toString(); @@ -143,38 +144,33 @@ void VariantPrototype::method_toString(const BuiltinFunction *, Scope &scope, Ca + QLatin1String(o->d()->data().typeName()) + QLatin1Char(')'); } - scope.result = scope.engine->newString(result); + return Encode(v4->newString(result)); } -void VariantPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue VariantPrototype::method_valueOf(const BuiltinFunction *b, CallData *callData) { - Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>()); + VariantObject *o = callData->thisObject.as<QV4::VariantObject>(); if (o) { QVariant v = o->d()->data(); switch (v.type()) { case QVariant::Invalid: - scope.result = Encode::undefined(); - return; + return Encode::undefined(); case QVariant::String: - scope.result = scope.engine->newString(v.toString()); - return; + return Encode(b->engine()->newString(v.toString())); case QVariant::Int: - scope.result = Encode(v.toInt()); - return; + return Encode(v.toInt()); case QVariant::Double: case QVariant::UInt: - scope.result = Encode(v.toDouble()); - return; + return Encode(v.toDouble()); case QVariant::Bool: - scope.result = Encode(v.toBool()); - return; + return Encode(v.toBool()); default: if (QMetaType::typeFlags(v.userType()) & QMetaType::IsEnumeration) RETURN_RESULT(Encode(v.toInt())); break; } } - scope.result = callData->thisObject; + return callData->thisObject.asReturnedValue(); } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h index a7c6fa320c..07b3310e91 100644 --- a/src/qml/jsruntime/qv4variantobject_p.h +++ b/src/qml/jsruntime/qv4variantobject_p.h @@ -108,10 +108,10 @@ public: V4_PROTOTYPE(objectPrototype) void init(); - static void method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_preserve(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_destroy(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_valueOf(const BuiltinFunction *, CallData *callData); }; } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index b22fa31d13..a736fb9f9d 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1096,11 +1096,11 @@ struct QmlIncubatorObject : public QV4::Object V4_OBJECT2(QmlIncubatorObject, Object) V4_NEEDS_DESTROY - static void method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_get_statusChanged(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_set_statusChanged(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_status(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_object(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_forceCompletion(const BuiltinFunction *, CallData *callData); void statusChanged(QQmlIncubator::Status); void setInitialState(QObject *); @@ -1446,17 +1446,19 @@ QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4) incubationProto.set(v4, proto); } -void QV4::QmlIncubatorObject::method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData) +QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) THROW_TYPE_ERROR(); - scope.result = QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object()); + return QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object()); } -void QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData) +QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) THROW_TYPE_ERROR(); @@ -1466,26 +1468,29 @@ void QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *, Sc RETURN_UNDEFINED(); } -void QV4::QmlIncubatorObject::method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData) +QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) THROW_TYPE_ERROR(); - scope.result = QV4::Encode(o->d()->incubator->status()); + return QV4::Encode(o->d()->incubator->status()); } -void QV4::QmlIncubatorObject::method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData) +QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o) THROW_TYPE_ERROR(); - scope.result = o->d()->statusChanged; + return QV4::Encode(o->d()->statusChanged); } -void QV4::QmlIncubatorObject::method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData) +QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>()); if (!o || callData->argc < 1) THROW_TYPE_ERROR(); diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index 5f274b8da5..a32a9dd783 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -105,8 +105,9 @@ void QQmlDelayedCallQueue::init(QV4::ExecutionEngine* engine) m_tickedMethod = metaObject.method(methodIndex); } -void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); if (callData->argc == 0) THROW_GENERIC_ERROR("Qt.callLater: no arguments given"); @@ -169,7 +170,7 @@ void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction m_tickedMethod.invoke(this, Qt::QueuedConnection); m_callbackOutstanding = true; } - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine) diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h index cffde4f0c0..5b3043cfed 100644 --- a/src/qml/qml/qqmldelayedcallqueue_p.h +++ b/src/qml/qml/qqmldelayedcallqueue_p.h @@ -70,7 +70,7 @@ public: void init(QV4::ExecutionEngine *); - void addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + QV4::ReturnedValue addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::CallData *callData); public Q_SLOTS: void ticked(); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 6c5c00e8ae..981f55a399 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -227,11 +227,10 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b QV4::ExecutionContext *outer = static_cast<QV4::ExecutionContext *>(m_qmlScope.valueRef()); if (v4Function->canUseSimpleFunction()) { - outer->simpleCall(scope, callData, v4Function); + result = outer->simpleCall(scope, callData, v4Function); } else { - outer->call(scope, callData, v4Function); + result = outer->call(scope, callData, v4Function); } - result = scope.result; if (scope.hasException()) { if (watcher.wasDeleted()) diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 43677e0d78..8204400956 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -171,8 +171,9 @@ void PropertyListPrototype::init(ExecutionEngine *) defineDefaultProperty(QStringLiteral("push"), method_push, 1); } -void PropertyListPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue PropertyListPrototype::method_push(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); if (!instance) RETURN_UNDEFINED(); @@ -189,6 +190,7 @@ void PropertyListPrototype::method_push(const BuiltinFunction *, Scope &scope, C if (QV4::QObjectWrapper *wrapper = so->as<QV4::QObjectWrapper>()) w->d()->property().append(&w->d()->property(), wrapper->object() ); } + return Encode::undefined(); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h index 84dadba01a..0b53395d2b 100644 --- a/src/qml/qml/qqmllistwrapper_p.h +++ b/src/qml/qml/qqmllistwrapper_p.h @@ -103,7 +103,7 @@ struct PropertyListPrototype : Object { void init(ExecutionEngine *engine); - static void method_push(const BuiltinFunction *, Scope &, CallData *callData); + static ReturnedValue method_push(const BuiltinFunction *, CallData *callData); }; } diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 326b36c5cd..862d9e1f14 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -58,8 +58,7 @@ DEFINE_OBJECT_VTABLE(QQmlLocaleData); #define THROW_ERROR(string) \ do { \ - scope.result = scope.engine->throwError(QString::fromUtf8(string)); \ - return; \ + return scope.engine->throwError(QString::fromUtf8(string)); \ } while (false) @@ -87,18 +86,15 @@ void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine) engine->dateCtor()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated); } -void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, CallData *callData) { - if (callData->argc > 2) { - QV4::DatePrototype::method_toLocaleString(b, scope, callData); - return; - } + Scope scope(b); + if (callData->argc > 2) + return QV4::DatePrototype::method_toLocaleString(b, callData); QV4::DateObject *date = callData->thisObject.as<DateObject>(); - if (!date) { - QV4::DatePrototype::method_toLocaleString(b, scope, callData); - return; - } + if (!date) + return QV4::DatePrototype::method_toLocaleString(b, callData); QDateTime dt = date->toQDateTime(); @@ -108,10 +104,8 @@ void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &s RETURN_RESULT(scope.engine->newString(locale.toString(dt))); } - if (!isLocaleObject(callData->args[0])) { - QV4::DatePrototype::method_toLocaleString(b, scope, callData); // Use the default Date toLocaleString() - return; - } + if (!isLocaleObject(callData->args[0])) + return QV4::DatePrototype::method_toLocaleString(b, callData); // Use the default Date toLocaleString() GET_LOCALE_DATA_RESOURCE(callData->args[0]); @@ -132,21 +126,18 @@ void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &s formattedDt = r->d()->locale->toString(dt, enumFormat); } - scope.result = scope.engine->newString(formattedDt); + RETURN_RESULT(scope.engine->newString(formattedDt)); } -void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, CallData *callData) { - if (callData->argc > 2) { - QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); - return; - } + Scope scope(b); + if (callData->argc > 2) + return QV4::DatePrototype::method_toLocaleTimeString(b, callData); QV4::DateObject *date = callData->thisObject.as<DateObject>(); - if (!date) { - QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); - return; - } + if (!date) + return QV4::DatePrototype::method_toLocaleTimeString(b, callData); QDateTime dt = date->toQDateTime(); QTime time = dt.time(); @@ -158,7 +149,7 @@ void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scop } if (!isLocaleObject(callData->args[0])) - return QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); // Use the default Date toLocaleTimeString() + return QV4::DatePrototype::method_toLocaleTimeString(b, callData); // Use the default Date toLocaleTimeString() GET_LOCALE_DATA_RESOURCE(callData->args[0]); @@ -179,21 +170,18 @@ void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scop formattedTime = r->d()->locale->toString(time, enumFormat); } - scope.result = scope.engine->newString(formattedTime); + RETURN_RESULT(scope.engine->newString(formattedTime)); } -void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, CallData *callData) { - if (callData->argc > 2) { - QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); - return; - } + Scope scope(b); + if (callData->argc > 2) + return QV4::DatePrototype::method_toLocaleDateString(b, callData); QV4::DateObject *dateObj = callData->thisObject.as<DateObject>(); - if (!dateObj) { - QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); - return; - } + if (!dateObj) + return QV4::DatePrototype::method_toLocaleDateString(b, callData); QDateTime dt = dateObj->toQDateTime(); QDate date = dt.date(); @@ -205,7 +193,7 @@ void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scop } if (!isLocaleObject(callData->args[0])) - return QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); // Use the default Date toLocaleDateString() + return QV4::DatePrototype::method_toLocaleDateString(b, callData); // Use the default Date toLocaleDateString() GET_LOCALE_DATA_RESOURCE(callData->args[0]); @@ -226,11 +214,12 @@ void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scop formattedDate = r->d()->locale->toString(date, enumFormat); } - scope.result = scope.engine->newString(formattedDate); + RETURN_RESULT(scope.engine->newString(formattedDate)); } -void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::ExecutionEngine * const engine = scope.engine; if (callData->argc == 1) { if (String *s = callData->args[0].stringValue()) { @@ -264,11 +253,12 @@ void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope & dt = r->d()->locale->toDateTime(dateString, enumFormat); } - scope.result = engine->newDateObject(dt); + RETURN_RESULT(engine->newDateObject(dt)); } -void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::ExecutionEngine * const engine = scope.engine; if (callData->argc == 1) { @@ -314,8 +304,9 @@ void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Sco RETURN_RESULT(engine->newDateObject(dt)); } -void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QV4::ExecutionEngine * const engine = scope.engine; if (callData->argc == 1) { @@ -353,8 +344,9 @@ void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Sco RETURN_RESULT(engine->newDateObject(QDateTime(dt))); } -void QQmlDateExtension::method_timeZoneUpdated(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlDateExtension::method_timeZoneUpdated(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 0) THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments"); @@ -373,8 +365,9 @@ void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine) engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString); } -void QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData) +QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc > 3) THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); @@ -386,10 +379,8 @@ void QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, Scope RETURN_RESULT(scope.engine->newString(locale.toString(number))); } - if (!isLocaleObject(callData->args[0])) { - QV4::NumberPrototype::method_toLocaleString(b, scope, callData); // Use the default Number toLocaleString() - return; - } + if (!isLocaleObject(callData->args[0])) + return QV4::NumberPrototype::method_toLocaleString(b, callData); // Use the default Number toLocaleString() GET_LOCALE_DATA_RESOURCE(callData->args[0]); @@ -408,11 +399,12 @@ void QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, Scope prec = callData->args[2].toInt32(); } - scope.result = scope.engine->newString(r->d()->locale->toString(number, (char)format, prec)); + RETURN_RESULT(scope.engine->newString(r->d()->locale->toString(number, (char)format, prec))); } -void QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc > 2) THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments"); @@ -439,8 +431,9 @@ void QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *, RETURN_RESULT(scope.engine->newString(r->d()->locale->toCurrencyString(number, symbol))); } -void QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 1 || callData->argc > 2) THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments"); @@ -467,45 +460,49 @@ void QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *, Scope if (!ok) THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format"); - scope.result = QV4::Encode(val); + RETURN_RESULT(QV4::Encode(val)); } //-------------- // Locale object -void QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QLocale *locale = getThisLocale(scope, callData); if (!locale) - return; + return Encode::undefined(); int fdow = int(locale->firstDayOfWeek()); if (fdow == 7) fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date - scope.result = QV4::Encode(fdow); + RETURN_RESULT(fdow); } -void QQmlLocaleData::method_get_measurementSystem(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlLocaleData::method_get_measurementSystem(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QLocale *locale = getThisLocale(scope, callData); if (!locale) - return; - scope.result = QV4::Encode(locale->measurementSystem()); + return Encode::undefined(); + return QV4::Encode(locale->measurementSystem()); } -void QQmlLocaleData::method_get_textDirection(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlLocaleData::method_get_textDirection(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QLocale *locale = getThisLocale(scope, callData); if (!locale) - return; + return Encode::undefined(); - scope.result = QV4::Encode(locale->textDirection()); + return QV4::Encode(locale->textDirection()); } -void QQmlLocaleData::method_get_weekDays(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlLocaleData::method_get_weekDays(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QLocale *locale = getThisLocale(scope, callData); if (!locale) - return; + return Encode::undefined(); QList<Qt::DayOfWeek> days = locale->weekdays(); @@ -519,14 +516,15 @@ void QQmlLocaleData::method_get_weekDays(const BuiltinFunction *, Scope &scope, } result->setArrayLengthUnchecked(days.size()); - scope.result = result.asReturnedValue(); + return result.asReturnedValue(); } -void QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QLocale *locale = getThisLocale(scope, callData); if (!locale) - return; + return Encode::undefined(); QStringList langs = locale->uiLanguages(); QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject()); @@ -537,14 +535,15 @@ void QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *, Scope &scop result->setArrayLengthUnchecked(langs.size()); - scope.result = result.asReturnedValue(); + return result.asReturnedValue(); } -void QQmlLocaleData::method_currencySymbol(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlLocaleData::method_currencySymbol(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QLocale *locale = getThisLocale(scope, callData); if (!locale) - return; + return Encode::undefined(); if (callData->argc > 1) THROW_ERROR("Locale: currencySymbol(): Invalid arguments"); @@ -555,14 +554,15 @@ void QQmlLocaleData::method_currencySymbol(const BuiltinFunction *, Scope &scope format = QLocale::CurrencySymbolFormat(intFormat); } - scope.result = scope.engine->newString(locale->currencySymbol(format)); + RETURN_RESULT(scope.engine->newString(locale->currencySymbol(format))); } #define LOCALE_FORMAT(FUNC) \ -void QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *, Scope &scope, CallData *callData) { \ +ReturnedValue QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *b, CallData *callData) { \ + QV4::Scope scope(b); \ QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return; \ + return Encode::undefined(); \ if (callData->argc > 1) \ THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \ QLocale::FormatType format = QLocale::LongFormat;\ @@ -570,7 +570,7 @@ void QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *, Scope &scope, Call quint32 intFormat = callData->args[0].toUInt32(); \ format = QLocale::FormatType(intFormat); \ } \ - scope.result = scope.engine->newString(locale-> FUNC (format)); \ + RETURN_RESULT(scope.engine->newString(locale-> FUNC (format))); \ } LOCALE_FORMAT(dateTimeFormat) @@ -579,10 +579,11 @@ LOCALE_FORMAT(dateFormat) // +1 added to idx because JS is 0-based, whereas QLocale months begin at 1. #define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \ -void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\ +ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *b, CallData *callData) {\ + Scope scope(b); \ QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return; \ + return Encode::undefined(); \ if (callData->argc < 1 || callData->argc > 2) \ THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ QLocale::FormatType enumFormat = QLocale::LongFormat; \ @@ -601,15 +602,16 @@ void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, } else { \ name = locale-> VARIABLE(idx, enumFormat); \ } \ - scope.result = scope.engine->newString(name); \ + RETURN_RESULT(scope.engine->newString(name)); \ } // 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date #define LOCALE_FORMATTED_DAYNAME(VARIABLE) \ -void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\ +ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *b, CallData *callData) {\ + Scope scope(b); \ QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return; \ + return Encode::undefined(); \ if (callData->argc < 1 || callData->argc > 2) \ THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \ QLocale::FormatType enumFormat = QLocale::LongFormat; \ @@ -629,7 +631,7 @@ void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, } else { \ name = locale-> VARIABLE(idx, enumFormat); \ } \ - scope.result = scope.engine->newString(name); \ + RETURN_RESULT(scope.engine->newString(name)); \ } LOCALE_FORMATTED_MONTHNAME(monthName) @@ -637,12 +639,14 @@ LOCALE_FORMATTED_MONTHNAME(standaloneMonthName) LOCALE_FORMATTED_DAYNAME(dayName) LOCALE_FORMATTED_DAYNAME(standaloneDayName) -#define LOCALE_STRING_PROPERTY(VARIABLE) void QQmlLocaleData::method_get_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) \ +#define LOCALE_STRING_PROPERTY(VARIABLE) \ +ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const BuiltinFunction *b, CallData *callData) \ { \ + Scope scope(b); \ QLocale *locale = getThisLocale(scope, callData); \ if (!locale) \ - return; \ - scope.result = scope.engine->newString(locale-> VARIABLE());\ + return Encode::undefined(); \ + RETURN_RESULT(scope.engine->newString(locale-> VARIABLE()));\ } LOCALE_STRING_PROPERTY(name) @@ -833,22 +837,18 @@ void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine) engine->stringPrototype()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare); } -void QQmlLocale::method_localeCompare(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue QQmlLocale::method_localeCompare(const BuiltinFunction *b, CallData *callData) { - if (callData->argc != 1 || (!callData->args[0].isString() && !callData->args[0].as<StringObject>())) { - QV4::StringPrototype::method_localeCompare(b, scope, callData); - return; - } + if (callData->argc != 1 || (!callData->args[0].isString() && !callData->args[0].as<StringObject>())) + return QV4::StringPrototype::method_localeCompare(b, callData); - if (!callData->thisObject.isString() && !callData->thisObject.as<StringObject>()) { - QV4::StringPrototype::method_localeCompare(b, scope, callData); - return; - } + if (!callData->thisObject.isString() && !callData->thisObject.as<StringObject>()) + return QV4::StringPrototype::method_localeCompare(b, callData); QString thisString = callData->thisObject.toQStringNoThrow(); QString thatString = callData->args[0].toQStringNoThrow(); - scope.result = QV4::Encode(QString::localeAwareCompare(thisString, thatString)); + return QV4::Encode(QString::localeAwareCompare(thisString, thatString)); } /*! diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 1a2ffc72b0..a81fe07b8e 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -67,13 +67,13 @@ public: static void registerExtension(QV4::ExecutionEngine *engine); private: - static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_toLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_toLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_fromLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_fromLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_timeZoneUpdated(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static QV4::ReturnedValue method_toLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_toLocaleTimeString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_toLocaleDateString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_fromLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_fromLocaleTimeString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_fromLocaleDateString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_timeZoneUpdated(const QV4::BuiltinFunction *, QV4::CallData *callData); }; @@ -83,9 +83,9 @@ public: static void registerExtension(QV4::ExecutionEngine *engine); private: - static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_toLocaleCurrencyString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static QV4::ReturnedValue method_toLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_fromLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_toLocaleCurrencyString(const QV4::BuiltinFunction *, QV4::CallData *callData); }; @@ -135,7 +135,7 @@ public: private: QQmlLocale(); - static void method_localeCompare(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static QV4::ReturnedValue method_localeCompare(const QV4::BuiltinFunction *, QV4::CallData *callData); }; namespace QV4 { @@ -168,33 +168,33 @@ struct QQmlLocaleData : public QV4::Object return thisObject->d()->locale; } - static void method_currencySymbol(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_dateTimeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_timeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_dateFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_monthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_standaloneMonthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_dayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_standaloneDayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - - static void method_get_firstDayOfWeek(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_measurementSystem(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_textDirection(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_weekDays(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_uiLanguages(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - - static void method_get_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_nativeLanguageName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_nativeCountryName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_decimalPoint(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_groupSeparator(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_percent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_zeroDigit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_negativeSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_positiveSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_exponential(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_amText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_pmText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static QV4::ReturnedValue method_currencySymbol(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_dateTimeFormat(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_timeFormat(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_dateFormat(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_monthName(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_standaloneMonthName(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_dayName(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_standaloneDayName(const QV4::BuiltinFunction *, QV4::CallData *callData); + + static QV4::ReturnedValue method_get_firstDayOfWeek(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_measurementSystem(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_textDirection(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_weekDays(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_uiLanguages(const QV4::BuiltinFunction *, QV4::CallData *callData); + + static QV4::ReturnedValue method_get_name(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_nativeLanguageName(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_nativeCountryName(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_decimalPoint(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_groupSeparator(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_percent(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_zeroDigit(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_negativeSign(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_positiveSign(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_exponential(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_amText(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue method_get_pmText(const QV4::BuiltinFunction *, QV4::CallData *callData); }; } diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index bca7391ffc..532c4b1454 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -316,8 +316,9 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const return true; } -void QQmlValueTypeWrapper::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QQmlValueTypeWrapper::method_toString(const BuiltinFunction *b, CallData *callData) { + Scope scope(b); Object *o = callData->thisObject.as<Object>(); if (!o) THROW_TYPE_ERROR(); @@ -350,7 +351,7 @@ void QQmlValueTypeWrapper::method_toString(const BuiltinFunction *, Scope &scope } result += QLatin1Char(')'); } - scope.result = scope.engine->newString(result); + return Encode(scope.engine->newString(result)); } ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *hasProperty) diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index 630b405c84..da03af6dbc 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -112,7 +112,7 @@ public: static PropertyAttributes query(const Managed *, String *name); static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); - static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData); static void initProto(ExecutionEngine *v4); }; diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 59db5bd9ac..526522cb10 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -74,8 +74,7 @@ using namespace QV4; #define V4THROW_REFERENCE(string) \ do { \ ScopedObject error(scope, scope.engine->newReferenceErrorObject(QStringLiteral(string))); \ - scope.result = scope.engine->throwError(error); \ - return; \ + return scope.engine->throwError(error); \ } while (false) QT_BEGIN_NAMESPACE @@ -276,25 +275,25 @@ public: static void initClass(ExecutionEngine *engine); // JS API - static void method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - - static void method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - - //static void ownerDocument(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - //static void namespaceURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - //static void prefix(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - //static void localName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - //static void baseURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - //static void textContent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static ReturnedValue method_get_nodeName(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_nodeValue(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_nodeType(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_namespaceUri(const BuiltinFunction *b, QV4::CallData *callData); + + static ReturnedValue method_get_parentNode(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_childNodes(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_firstChild(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_lastChild(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_previousSibling(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_nextSibling(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_attributes(const BuiltinFunction *b, QV4::CallData *callData); + + //static ReturnedValue ownerDocument(const BuiltinFunction *b, QV4::CallData *callData); + //static ReturnedValue namespaceURI(const BuiltinFunction *b, QV4::CallData *callData); + //static ReturnedValue prefix(const BuiltinFunction *b, QV4::CallData *callData); + //static ReturnedValue localName(const BuiltinFunction *b, QV4::CallData *callData); + //static ReturnedValue baseURI(const BuiltinFunction *b, QV4::CallData *callData); + //static ReturnedValue textContent(const BuiltinFunction *b, QV4::CallData *callData); static ReturnedValue getProto(ExecutionEngine *v4); @@ -355,10 +354,10 @@ class Attr : public Node { public: // JS API - static void method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static ReturnedValue method_name(const BuiltinFunction *b, QV4::CallData *callData); // static void specified(CallContext *); - static void method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static ReturnedValue method_value(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_ownerElement(const BuiltinFunction *b, QV4::CallData *callData); // static void schemaTypeInfo(CallContext *); // static void isId(CallContext *c); @@ -370,7 +369,7 @@ class CharacterData : public Node { public: // JS API - static void method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static ReturnedValue method_length(const BuiltinFunction *b, QV4::CallData *callData); // C++ API static ReturnedValue prototype(ExecutionEngine *v4); @@ -380,8 +379,8 @@ class Text : public CharacterData { public: // JS API - static void method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static ReturnedValue method_isElementContentWhitespace(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_wholeText(const BuiltinFunction *b, QV4::CallData *callData); // C++ API static ReturnedValue prototype(ExecutionEngine *); @@ -398,10 +397,10 @@ class Document : public Node { public: // JS API - static void method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static ReturnedValue method_xmlVersion(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_xmlEncoding(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_xmlStandalone(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_documentElement(const BuiltinFunction *b, QV4::CallData *callData); // C++ API static ReturnedValue prototype(ExecutionEngine *); @@ -420,8 +419,9 @@ void NodeImpl::release() document->release(); } -void NodePrototype::method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_nodeName(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); @@ -441,11 +441,12 @@ void NodePrototype::method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope name = r->d()->d->name; break; } - scope.result = Encode(scope.engine->newString(name)); + return Encode(scope.engine->newString(name)); } -void NodePrototype::method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_nodeValue(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); @@ -459,74 +460,81 @@ void NodePrototype::method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scop r->d()->d->type == NodeImpl::Notation) RETURN_RESULT(Encode::null()); - scope.result = Encode(scope.engine->newString(r->d()->d->data)); + return Encode(scope.engine->newString(r->d()->d->data)); } -void NodePrototype::method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_nodeType(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); - scope.result = Encode(r->d()->d->type); + return Encode(r->d()->d->type); } -void NodePrototype::method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_namespaceUri(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); - scope.result = Encode(scope.engine->newString(r->d()->d->namespaceUri)); + return Encode(scope.engine->newString(r->d()->d->namespaceUri)); } -void NodePrototype::method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_parentNode(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); if (r->d()->d->parent) - scope.result = Node::create(scope.engine, r->d()->d->parent); + return Node::create(scope.engine, r->d()->d->parent); else - scope.result = Encode::null(); + return Encode::null(); } -void NodePrototype::method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_childNodes(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); - scope.result = NodeList::create(scope.engine, r->d()->d); + return NodeList::create(scope.engine, r->d()->d); } -void NodePrototype::method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_firstChild(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); if (r->d()->d->children.isEmpty()) - scope.result = Encode::null(); + return Encode::null(); else - scope.result = Node::create(scope.engine, r->d()->d->children.constFirst()); + return Node::create(scope.engine, r->d()->d->children.constFirst()); } -void NodePrototype::method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_lastChild(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); if (r->d()->d->children.isEmpty()) - scope.result = Encode::null(); + return Encode::null(); else - scope.result = Node::create(scope.engine, r->d()->d->children.constLast()); + return Node::create(scope.engine, r->d()->d->children.constLast()); } -void NodePrototype::method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_previousSibling(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); @@ -537,18 +545,18 @@ void NodePrototype::method_get_previousSibling(const QV4::BuiltinFunction *, QV4 for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) { if (r->d()->d->parent->children.at(ii) == r->d()->d) { if (ii == 0) - scope.result = Encode::null(); + return Encode::null(); else - scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1)); - return; + return Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1)); } } - scope.result = Encode::null(); + return Encode::null(); } -void NodePrototype::method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_nextSibling(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); @@ -559,26 +567,26 @@ void NodePrototype::method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Sc for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) { if (r->d()->d->parent->children.at(ii) == r->d()->d) { if ((ii + 1) == r->d()->d->parent->children.count()) - scope.result = Encode::null(); + return Encode::null(); else - scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1)); - return; + return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1)); } } - scope.result = Encode::null(); + return Encode::null(); } -void NodePrototype::method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue NodePrototype::method_get_attributes(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) THROW_TYPE_ERROR(); if (r->d()->d->type != NodeImpl::Element) - scope.result = Encode::null(); + return Encode::null(); else - scope.result = NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes); + return NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes); } ReturnedValue NodePrototype::getProto(ExecutionEngine *v4) @@ -659,40 +667,44 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine) return d->attrPrototype.value(); } -void Attr::method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Attr::method_name(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) RETURN_UNDEFINED(); - scope.result = scope.engine->newString(r->d()->d->name); + return Encode(scope.engine->newString(r->d()->d->name)); } -void Attr::method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Attr::method_value(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) RETURN_UNDEFINED(); - scope.result = scope.engine->newString(r->d()->d->data); + return Encode(scope.engine->newString(r->d()->d->data)); } -void Attr::method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Attr::method_ownerElement(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) RETURN_UNDEFINED(); - scope.result = Node::create(scope.engine, r->d()->d->parent); + return Node::create(scope.engine, r->d()->d->parent); } -void CharacterData::method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue CharacterData::method_length(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) RETURN_UNDEFINED(); - scope.result = Encode(r->d()->d->data.length()); + return Encode(r->d()->d->data.length()); } ReturnedValue CharacterData::prototype(ExecutionEngine *v4) @@ -711,22 +723,24 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4) return d->characterDataPrototype.value(); } -void Text::method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Text::method_isElementContentWhitespace(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) RETURN_UNDEFINED(); - scope.result = Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty()); + return Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty()); } -void Text::method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Text::method_wholeText(const BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r) RETURN_UNDEFINED(); - scope.result = scope.engine->newString(r->d()->d->data); + return Encode(scope.engine->newString(r->d()->d->data)); } ReturnedValue Text::prototype(ExecutionEngine *v4) @@ -952,40 +966,44 @@ ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data) return (v4->memoryManager->allocObject<NodeList>(data))->asReturnedValue(); } -void Document::method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Document::method_documentElement(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) RETURN_UNDEFINED(); - scope.result = Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root); + return Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root); } -void Document::method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Document::method_xmlStandalone(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) RETURN_UNDEFINED(); - scope.result = Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone); + return Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone); } -void Document::method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Document::method_xmlVersion(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) RETURN_UNDEFINED(); - scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version); + return Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version)); } -void Document::method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue Document::method_xmlEncoding(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<Node> r(scope, callData->thisObject.as<Node>()); if (!r || r->d()->d->type != NodeImpl::Document) RETURN_UNDEFINED(); - scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding); + return Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding)); } class QQmlXMLHttpRequest : public QObject @@ -1637,21 +1655,21 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject void setupProto(); - static void method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - - static void method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static ReturnedValue method_open(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_setRequestHeader(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_send(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_abort(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_getResponseHeader(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_getAllResponseHeaders(const BuiltinFunction *b, QV4::CallData *callData); + + static ReturnedValue method_get_readyState(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_status(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_statusText(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_responseText(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_responseXML(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_response(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_get_responseType(const BuiltinFunction *b, QV4::CallData *callData); + static ReturnedValue method_set_responseType(const BuiltinFunction *b, QV4::CallData *callData); }; } @@ -1713,8 +1731,9 @@ void QQmlXMLHttpRequestCtor::setupProto() // XMLHttpRequest methods -void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_open(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1761,11 +1780,12 @@ void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scop if (!username.isNull()) url.setUserName(username); if (!password.isNull()) url.setPassword(password); - scope.result = r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad); + return r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad); } -void QQmlXMLHttpRequestCtor::method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1810,8 +1830,9 @@ void QQmlXMLHttpRequestCtor::method_setRequestHeader(const QV4::BuiltinFunction RETURN_UNDEFINED(); } -void QQmlXMLHttpRequestCtor::method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_send(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1825,21 +1846,23 @@ void QQmlXMLHttpRequestCtor::method_send(const QV4::BuiltinFunction *, QV4::Scop if (callData->argc > 0) data = callData->args[0].toQStringNoThrow().toUtf8(); - scope.result = r->send(w, scope.engine->callingQmlContext(), data); + return r->send(w, scope.engine->callingQmlContext(), data); } -void QQmlXMLHttpRequestCtor::method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_abort(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - scope.result = r->abort(w, scope.engine->callingQmlContext()); + return r->abort(w, scope.engine->callingQmlContext()); } -void QQmlXMLHttpRequestCtor::method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1853,11 +1876,12 @@ void QQmlXMLHttpRequestCtor::method_getResponseHeader(const QV4::BuiltinFunction r->readyState() != QQmlXMLHttpRequest::HeadersReceived) THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); - scope.result = scope.engine->newString(r->header(callData->args[0].toQStringNoThrow())); + return Encode(scope.engine->newString(r->header(callData->args[0].toQStringNoThrow()))); } -void QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1871,22 +1895,24 @@ void QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const QV4::BuiltinFunc r->readyState() != QQmlXMLHttpRequest::HeadersReceived) THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); - scope.result = scope.engine->newString(r->headers()); + return Encode(scope.engine->newString(r->headers())); } // XMLHttpRequest properties -void QQmlXMLHttpRequestCtor::method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - scope.result = Encode(r->readyState()); + return Encode(r->readyState()); } -void QQmlXMLHttpRequestCtor::method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1897,13 +1923,14 @@ void QQmlXMLHttpRequestCtor::method_get_status(const QV4::BuiltinFunction *, QV4 THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); if (r->errorFlag()) - scope.result = Encode(0); + return Encode(0); else - scope.result = Encode(r->replyStatus()); + return Encode(r->replyStatus()); } -void QQmlXMLHttpRequestCtor::method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1914,13 +1941,14 @@ void QQmlXMLHttpRequestCtor::method_get_statusText(const QV4::BuiltinFunction *, THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state"); if (r->errorFlag()) - scope.result = scope.engine->newString(QString()); + return Encode(scope.engine->newString(QString())); else - scope.result = scope.engine->newString(r->replyStatusText()); + return Encode(scope.engine->newString(r->replyStatusText())); } -void QQmlXMLHttpRequestCtor::method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1928,13 +1956,14 @@ void QQmlXMLHttpRequestCtor::method_get_responseText(const QV4::BuiltinFunction if (r->readyState() != QQmlXMLHttpRequest::Loading && r->readyState() != QQmlXMLHttpRequest::Done) - scope.result = scope.engine->newString(QString()); + return Encode(scope.engine->newString(QString())); else - scope.result = scope.engine->newString(r->responseBody()); + return Encode(scope.engine->newString(r->responseBody())); } -void QQmlXMLHttpRequestCtor::method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1943,16 +1972,17 @@ void QQmlXMLHttpRequestCtor::method_get_responseXML(const QV4::BuiltinFunction * if (!r->receivedXml() || (r->readyState() != QQmlXMLHttpRequest::Loading && r->readyState() != QQmlXMLHttpRequest::Done)) { - scope.result = Encode::null(); + return Encode::null(); } else { if (r->responseType().isEmpty()) r->setResponseType(QLatin1String("document")); - scope.result = r->xmlResponseBody(scope.engine); + return r->xmlResponseBody(scope.engine); } } -void QQmlXMLHttpRequestCtor::method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1977,17 +2007,19 @@ void QQmlXMLHttpRequestCtor::method_get_response(const QV4::BuiltinFunction *, Q } -void QQmlXMLHttpRequestCtor::method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); QQmlXMLHttpRequest *r = w->d()->request; - scope.result = scope.engine->newString(r->responseType()); + return Encode(scope.engine->newString(r->responseType())); } -void QQmlXMLHttpRequestCtor::method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(const BuiltinFunction *b, QV4::CallData *callData) { + Scope scope(b); Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>()); if (!w) V4THROW_REFERENCE("Not an XMLHttpRequest object"); @@ -1999,7 +2031,7 @@ void QQmlXMLHttpRequestCtor::method_set_responseType(const QV4::BuiltinFunction // Argument 0 - response type r->setResponseType(callData->args[0].toQStringNoThrow()); - scope.result = Encode::undefined(); + return Encode::undefined(); } void qt_rem_qmlxmlhttprequest(ExecutionEngine * /* engine */, void *d) diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 459d9afe2a..ebf8918d31 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -87,8 +87,7 @@ DEFINE_OBJECT_VTABLE(QtObject); #define THROW_TYPE_ERROR_WITH_MESSAGE(msg) \ do { \ - scope.result = scope.engine->throwTypeError(QString::fromUtf8(msg)); \ - return; \ + return scope.engine->throwTypeError(QString::fromUtf8(msg)); \ } while (false) struct StaticQtMetaObject : public QObject @@ -229,12 +228,12 @@ void QtObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint \qmlmethod bool Qt::isQtObject(object) Returns true if \c object is a valid reference to a Qt or QML object, otherwise false. */ -void QtObject::method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_isQtObject(const BuiltinFunction *, CallData *callData) { if (callData->argc == 0) RETURN_RESULT(QV4::Encode(false)); - scope.result = QV4::Encode(callData->args[0].as<QV4::QObjectWrapper>() != 0); + return QV4::Encode(callData->args[0].as<QV4::QObjectWrapper>() != 0); } /*! @@ -243,8 +242,9 @@ void QtObject::method_isQtObject(const BuiltinFunction *, Scope &scope, CallData Returns a color with the specified \c red, \c green, \c blue and \c alpha components. All components should be in the range 0-1 inclusive. */ -void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_rgba(const BuiltinFunction *builtin, CallData *callData) { + QV4::Scope scope(builtin); int argCount = callData->argc; if (argCount < 3 || argCount > 4) THROW_GENERIC_ERROR("Qt.rgba(): Invalid arguments"); @@ -263,7 +263,7 @@ void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *call if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)); + return scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)); } /*! @@ -272,8 +272,9 @@ void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *call Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components. All components should be in the range 0-1 inclusive. */ -void QtObject::method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_hsla(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); int argCount = callData->argc; if (argCount < 3 || argCount > 4) THROW_GENERIC_ERROR("Qt.hsla(): Invalid arguments"); @@ -292,7 +293,7 @@ void QtObject::method_hsla(const BuiltinFunction *, Scope &scope, CallData *call if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)); + return scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)); } /*! @@ -303,8 +304,9 @@ All components should be in the range 0-1 inclusive. \since 5.5 */ -void QtObject::method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_hsva(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); int argCount = callData->argc; if (argCount < 3 || argCount > 4) THROW_GENERIC_ERROR("Qt.hsva(): Invalid arguments"); @@ -319,7 +321,7 @@ void QtObject::method_hsva(const BuiltinFunction *, Scope &scope, CallData *call v = qBound(0.0, v, 1.0); a = qBound(0.0, a, 1.0); - scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a)); + return scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a)); } /*! @@ -330,8 +332,9 @@ may be either color values or string values. If a string value is supplied it must be convertible to a color, as described for the \l{colorbasictypedocs}{color} basic type. */ -void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_colorEqual(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 2) THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments"); @@ -358,7 +361,7 @@ void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData } bool equal = (lhs == rhs); - scope.result = QV4::Encode(equal); + return QV4::Encode(equal); } /*! @@ -368,8 +371,9 @@ Returns a \c rect with the top-left corner at \c x, \c y and the specified \c wi The returned object has \c x, \c y, \c width and \c height attributes with the given values. */ -void QtObject::method_rect(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_rect(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 4) THROW_GENERIC_ERROR("Qt.rect(): Invalid arguments"); @@ -378,37 +382,39 @@ void QtObject::method_rect(const BuiltinFunction *, Scope &scope, CallData *call double w = callData->args[2].toNumber(); double h = callData->args[3].toNumber(); - scope.result = scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))); + return scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))); } /*! \qmlmethod point Qt::point(int x, int y) Returns a Point with the specified \c x and \c y coordinates. */ -void QtObject::method_point(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_point(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 2) THROW_GENERIC_ERROR("Qt.point(): Invalid arguments"); double x = callData->args[0].toNumber(); double y = callData->args[1].toNumber(); - scope.result = scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y))); + return scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y))); } /*! \qmlmethod Qt::size(int width, int height) Returns a Size with the specified \c width and \c height. */ -void QtObject::method_size(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_size(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 2) THROW_GENERIC_ERROR("Qt.size(): Invalid arguments"); double w = callData->args[0].toNumber(); double h = callData->args[1].toNumber(); - scope.result = scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h))); + return scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h))); } /*! @@ -419,8 +425,9 @@ key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's subproperty names, and the values are valid values for each subproperty. Invalid keys will be ignored. */ -void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_font(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1 || !callData->args[0].isObject()) THROW_GENERIC_ERROR("Qt.font(): Invalid arguments"); @@ -429,7 +436,7 @@ void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *call QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(callData->args[0]), v4, &ok); if (!ok) THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified"); - scope.result = scope.engine->fromVariant(v); + return scope.engine->fromVariant(v); } @@ -438,8 +445,9 @@ void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *call \qmlmethod Qt::vector2d(real x, real y) Returns a Vector2D with the specified \c x and \c y. */ -void QtObject::method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_vector2d(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 2) THROW_GENERIC_ERROR("Qt.vector2d(): Invalid arguments"); @@ -448,15 +456,16 @@ void QtObject::method_vector2d(const BuiltinFunction *, Scope &scope, CallData * xy[1] = callData->args[1].toNumber(); const void *params[] = { xy }; - scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params)); + return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params)); } /*! \qmlmethod Qt::vector3d(real x, real y, real z) Returns a Vector3D with the specified \c x, \c y and \c z. */ -void QtObject::method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_vector3d(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 3) THROW_GENERIC_ERROR("Qt.vector3d(): Invalid arguments"); @@ -466,15 +475,16 @@ void QtObject::method_vector3d(const BuiltinFunction *, Scope &scope, CallData * xyz[2] = callData->args[2].toNumber(); const void *params[] = { xyz }; - scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)); + return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)); } /*! \qmlmethod Qt::vector4d(real x, real y, real z, real w) Returns a Vector4D with the specified \c x, \c y, \c z and \c w. */ -void QtObject::method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_vector4d(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 4) THROW_GENERIC_ERROR("Qt.vector4d(): Invalid arguments"); @@ -485,15 +495,16 @@ void QtObject::method_vector4d(const BuiltinFunction *, Scope &scope, CallData * xyzw[3] = callData->args[3].toNumber(); const void *params[] = { xyzw }; - scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)); + return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)); } /*! \qmlmethod Qt::quaternion(real scalar, real x, real y, real z) Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z. */ -void QtObject::method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_quaternion(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 4) THROW_GENERIC_ERROR("Qt.quaternion(): Invalid arguments"); @@ -504,7 +515,7 @@ void QtObject::method_quaternion(const BuiltinFunction *, Scope &scope, CallData sxyz[3] = callData->args[3].toNumber(); const void *params[] = { sxyz }; - scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params)); + return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params)); } /*! @@ -516,22 +527,20 @@ matrix values. Finally, the function may be called with no arguments and the resulting matrix will be the identity matrix. */ -void QtObject::method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_matrix4x4(const BuiltinFunction *b, CallData *callData) { - QV4::ExecutionEngine *v4 = scope.engine; + QV4::Scope scope(b); if (callData->argc == 0) { - scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR)); - return; + return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR)); } if (callData->argc == 1 && callData->args[0].isObject()) { bool ok = false; - QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(callData->args[0]), v4, &ok); + QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(callData->args[0]), scope.engine, &ok); if (!ok) THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array"); - scope.result = scope.engine->fromVariant(v); - return; + return scope.engine->fromVariant(v); } if (callData->argc != 16) @@ -556,7 +565,7 @@ void QtObject::method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData vals[15] = callData->args[15].toNumber(); const void *params[] = { vals }; - scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params)); + return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params)); } /*! @@ -573,8 +582,9 @@ by factor and converts the color back to RGB. If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5). */ -void QtObject::method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_lighter(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1 && callData->argc != 2) THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments"); @@ -583,19 +593,17 @@ void QtObject::method_lighter(const BuiltinFunction *, Scope &scope, CallData *c bool ok = false; v = QQmlStringConverters::colorFromString(v.toString(), &ok); if (!ok) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } } else if (v.userType() != QVariant::Color) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } qreal factor = 1.5; if (callData->argc == 2) factor = callData->args[1].toNumber(); - scope.result = scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor)); + return scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor)); } /*! @@ -613,8 +621,9 @@ by factor and converts the color back to RGB. If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0). */ -void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_darker(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1 && callData->argc != 2) THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments"); @@ -623,19 +632,17 @@ void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *ca bool ok = false; v = QQmlStringConverters::colorFromString(v.toString(), &ok); if (!ok) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } } else if (v.userType() != QVariant::Color) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } qreal factor = 2.0; if (callData->argc == 2) factor = callData->args[1].toNumber(); - scope.result = scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor)); + return scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor)); } /*! @@ -662,8 +669,9 @@ void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *ca Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color. */ -void QtObject::method_tint(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_tint(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 2) THROW_GENERIC_ERROR("Qt.tint(): Invalid arguments"); @@ -673,12 +681,10 @@ void QtObject::method_tint(const BuiltinFunction *, Scope &scope, CallData *call bool ok = false; v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok); if (!ok) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } } else if (v1.userType() != QVariant::Color) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } // tint color @@ -687,15 +693,13 @@ void QtObject::method_tint(const BuiltinFunction *, Scope &scope, CallData *call bool ok = false; v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok); if (!ok) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } } else if (v2.userType() != QVariant::Color) { - scope.result = QV4::Encode::null(); - return; + return QV4::Encode::null(); } - scope.result = scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2)); + return scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2)); } /*! @@ -714,8 +718,9 @@ If \a format is not specified, \a date is formatted using \sa Locale */ -void QtObject::method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_formatDate(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 1 || callData->argc > 2) THROW_GENERIC_ERROR("Qt.formatDate(): Invalid arguments"); @@ -738,7 +743,7 @@ void QtObject::method_formatDate(const BuiltinFunction *, Scope &scope, CallData formattedDate = date.toString(enumFormat); } - scope.result = scope.engine->newString(formattedDate); + return Encode(scope.engine->newString(formattedDate)); } /*! @@ -756,8 +761,9 @@ If \a format is not specified, \a time is formatted using \sa Locale */ -void QtObject::method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_formatTime(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 1 || callData->argc > 2) THROW_GENERIC_ERROR("Qt.formatTime(): Invalid arguments"); @@ -786,7 +792,7 @@ void QtObject::method_formatTime(const BuiltinFunction *, Scope &scope, CallData formattedTime = time.toString(enumFormat); } - scope.result = scope.engine->newString(formattedTime); + return Encode(scope.engine->newString(formattedTime)); } /*! @@ -879,8 +885,9 @@ with the \a format values below to produce the following results: \sa Locale */ -void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_formatDateTime(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 1 || callData->argc > 2) THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid arguments"); @@ -903,7 +910,7 @@ void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, Call formattedDt = dt.toString(enumFormat); } - scope.result = scope.engine->newString(formattedDt); + return Encode(scope.engine->newString(formattedDt)); } /*! @@ -917,94 +924,97 @@ void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, Call still fail to launch or fail to open the requested URL. This result will not be reported back to the application. */ -void QtObject::method_openUrlExternally(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_openUrlExternally(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) { - scope.result = QV4::Encode(false); - return; + return QV4::Encode(false); } - method_resolvedUrl(b, scope, callData); - QUrl url(scope.result.toQStringNoThrow()); - scope.result = scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url)); + ScopedValue result(scope, method_resolvedUrl(b, callData)); + QUrl url(result->toQStringNoThrow()); + return scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url)); } /*! \qmlmethod url Qt::resolvedUrl(url url) Returns \a url resolved relative to the URL of the caller. */ -void QtObject::method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_resolvedUrl(const BuiltinFunction *b, CallData *callData) { - ExecutionEngine *v4 = scope.engine; + QV4::Scope scope(b); - QUrl url = v4->toVariant(callData->args[0], -1).toUrl(); - QQmlEngine *e = v4->qmlEngine(); + QUrl url = scope.engine->toVariant(callData->args[0], -1).toUrl(); + QQmlEngine *e = scope.engine->qmlEngine(); QQmlEnginePrivate *p = 0; if (e) p = QQmlEnginePrivate::get(e); if (p) { - QQmlContextData *ctxt = v4->callingQmlContext(); + QQmlContextData *ctxt = scope.engine->callingQmlContext(); if (ctxt) - scope.result = v4->newString(ctxt->resolvedUrl(url).toString()); + return Encode(scope.engine->newString(ctxt->resolvedUrl(url).toString())); else - scope.result = v4->newString(url.toString()); - return; + return Encode(scope.engine->newString(url.toString())); } - scope.result = v4->newString(e->baseUrl().resolved(url).toString()); + return Encode(scope.engine->newString(e->baseUrl().resolved(url).toString())); } /*! \qmlmethod list<string> Qt::fontFamilies() Returns a list of the font families available to the application. */ -void QtObject::method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_fontFamilies(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 0) THROW_GENERIC_ERROR("Qt.fontFamilies(): Invalid arguments"); - scope.result = scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())); + return scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())); } /*! \qmlmethod string Qt::md5(data) Returns a hex string of the md5 hash of \c data. */ -void QtObject::method_md5(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_md5(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("Qt.md5(): Invalid arguments"); QByteArray data = callData->args[0].toQStringNoThrow().toUtf8(); QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5); - scope.result = scope.engine->newString(QLatin1String(result.toHex())); + return Encode(scope.engine->newString(QLatin1String(result.toHex()))); } /*! \qmlmethod string Qt::btoa(data) Binary to ASCII - this function returns a base64 encoding of \c data. */ -void QtObject::method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_btoa(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("Qt.btoa(): Invalid arguments"); QByteArray data = callData->args[0].toQStringNoThrow().toUtf8(); - scope.result = scope.engine->newString(QLatin1String(data.toBase64())); + return Encode(scope.engine->newString(QLatin1String(data.toBase64()))); } /*! \qmlmethod string Qt::atob(data) ASCII to binary - this function decodes the base64 encoded \a data string and returns it. */ -void QtObject::method_atob(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_atob(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("Qt.atob(): Invalid arguments"); QByteArray data = callData->args[0].toQStringNoThrow().toLatin1(); - scope.result = scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data))); + return Encode(scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data)))); } /*! @@ -1016,10 +1026,10 @@ QQmlEngine::quit() signal to the QCoreApplication::quit() slot. \sa exit() */ -void QtObject::method_quit(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue QtObject::method_quit(const BuiltinFunction *b, CallData *) { - QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendQuit(); - scope.result = Encode::undefined(); + QQmlEnginePrivate::get(b->engine()->qmlEngine())->sendQuit(); + return Encode::undefined(); } /*! @@ -1033,15 +1043,16 @@ void QtObject::method_quit(const BuiltinFunction *, Scope &scope, CallData *) \sa quit() */ -void QtObject::method_exit(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_exit(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("Qt.exit(): Invalid arguments"); int retCode = callData->args[0].toNumber(); QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendExit(retCode); - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } /*! @@ -1068,8 +1079,9 @@ If this is the case, consider using \l{QtQml::Qt::createComponent()}{Qt.createCo See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function. */ -void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_createQmlObject(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 2 || callData->argc > 3) THROW_GENERIC_ERROR("Qt.createQmlObject(): Invalid arguments"); @@ -1168,13 +1180,12 @@ void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, Cal if (component.isError()) { ScopedValue v(scope, Error::create(scope.engine, component.errors())); - scope.result = scope.engine->throwError(v); - return; + return scope.engine->throwError(v); } Q_ASSERT(obj); - scope.result = QV4::QObjectWrapper::wrap(scope.engine, obj); + return QV4::QObjectWrapper::wrap(scope.engine, obj); } /*! @@ -1221,8 +1232,9 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi To create a QML object from an arbitrary string of QML (instead of a file), use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}. */ -void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_createComponent(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 1 || callData->argc > 3) THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments"); @@ -1280,7 +1292,7 @@ void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, Cal QQmlData::get(c, true)->explicitIndestructibleSet = false; QQmlData::get(c)->indestructible = false; - scope.result = QV4::QObjectWrapper::wrap(scope.engine, c); + return QV4::QObjectWrapper::wrap(scope.engine, c); } /*! @@ -1303,8 +1315,9 @@ void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, Cal \sa Locale */ -void QtObject::method_locale(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_locale(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); QString code; if (callData->argc > 1) THROW_GENERIC_ERROR("locale() requires 0 or 1 argument"); @@ -1314,7 +1327,7 @@ void QtObject::method_locale(const BuiltinFunction *, Scope &scope, CallData *ca if (callData->argc == 1) code = callData->args[0].toQStringNoThrow(); - scope.result = QQmlLocale::locale(scope.engine, code); + return QQmlLocale::locale(scope.engine, code); } void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction) @@ -1376,20 +1389,22 @@ DEFINE_OBJECT_VTABLE(QQmlBindingFunction); \since 5.0 */ -void QtObject::method_binding(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_binding(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("binding() requires 1 argument"); const QV4::FunctionObject *f = callData->args[0].as<FunctionObject>(); if (!f) THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function"); - scope.result = scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f); + return Encode(scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f)); } -void QtObject::method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_get_platform(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); // ### inefficient. Should be just a value based getter Object *o = callData->thisObject.as<Object>(); if (!o) @@ -1402,11 +1417,12 @@ void QtObject::method_get_platform(const BuiltinFunction *, Scope &scope, CallDa // Only allocate a platform object once qt->d()->platform = new QQmlPlatform(scope.engine->jsEngine()); - scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform); + return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform); } -void QtObject::method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_get_application(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); // ### inefficient. Should be just a value based getter Object *o = callData->thisObject.as<Object>(); if (!o) @@ -1419,19 +1435,19 @@ void QtObject::method_get_application(const BuiltinFunction *, Scope &scope, Cal // Only allocate an application object once qt->d()->application = QQml_guiProvider()->application(scope.engine->jsEngine()); - scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application); + return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application); } -void QtObject::method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue QtObject::method_get_inputMethod(const BuiltinFunction *b, CallData *) { QObject *o = QQml_guiProvider()->inputMethod(); - scope.result = QV4::QObjectWrapper::wrap(scope.engine, o); + return QV4::QObjectWrapper::wrap(b->engine(), o); } -void QtObject::method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue QtObject::method_get_styleHints(const BuiltinFunction *b, CallData *) { QObject *o = QQml_guiProvider()->styleHints(); - scope.result = QV4::QObjectWrapper::wrap(scope.engine, o); + return QV4::QObjectWrapper::wrap(b->engine(), o); } @@ -1491,11 +1507,12 @@ static QString jsStack(QV4::ExecutionEngine *engine) { return stack; } -static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *callData, - ConsoleLogTypes logType, bool printStack = false) +static ReturnedValue writeToConsole(const BuiltinFunction *b, CallData *callData, + ConsoleLogTypes logType, bool printStack = false) { QLoggingCategory *loggingCategory = 0; QString result; + QV4::Scope scope(b); QV4::ExecutionEngine *v4 = scope.engine; int start = 0; @@ -1556,31 +1573,32 @@ static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *call break; } - scope.result = QV4::Encode::undefined(); + return Encode::undefined(); } DEFINE_OBJECT_VTABLE(ConsoleObject); -void ConsoleObject::method_error(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_error(const BuiltinFunction *b, CallData *callData) { - writeToConsole(b, scope, callData, Error); + return writeToConsole(b, callData, Error); } -void ConsoleObject::method_log(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_log(const BuiltinFunction *b, CallData *callData) { //console.log //console.debug //print - writeToConsole(b, scope, callData, Log); + return writeToConsole(b, callData, Log); } -void ConsoleObject::method_info(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_info(const BuiltinFunction *b, CallData *callData) { - writeToConsole(b, scope, callData, Info); + return writeToConsole(b, callData, Info); } -void ConsoleObject::method_profile(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue ConsoleObject::method_profile(const BuiltinFunction *b, CallData *) { + QV4::Scope scope(b); QV4::ExecutionEngine *v4 = scope.engine; QV4::EngineBase::StackFrame *frame = v4->currentStackFrame; @@ -1595,11 +1613,12 @@ void ConsoleObject::method_profile(const BuiltinFunction *, Scope &scope, CallDa logger.debug("Profiling started."); } - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void ConsoleObject::method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue ConsoleObject::method_profileEnd(const BuiltinFunction *b, CallData *) { + QV4::Scope scope(b); QV4::ExecutionEngine *v4 = scope.engine; QV4::EngineBase::StackFrame *frame = v4->currentStackFrame; @@ -1615,11 +1634,12 @@ void ConsoleObject::method_profileEnd(const BuiltinFunction *, Scope &scope, Cal logger.debug("Profiling ended."); } - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void ConsoleObject::method_time(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_time(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("console.time(): Invalid arguments"); @@ -1627,11 +1647,12 @@ void ConsoleObject::method_time(const BuiltinFunction *, Scope &scope, CallData QString name = callData->args[0].toQStringNoThrow(); v8engine->startTimer(name); - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void ConsoleObject::method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_timeEnd(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments"); @@ -1643,16 +1664,17 @@ void ConsoleObject::method_timeEnd(const BuiltinFunction *, Scope &scope, CallDa if (wasRunning) { qDebug("%s: %llims", qPrintable(name), elapsed); } - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void ConsoleObject::method_count(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_count(const BuiltinFunction *b, CallData *callData) { // first argument: name to print. Ignore any additional arguments QString name; if (callData->argc > 0) name = callData->args[0].toQStringNoThrow(); + Scope scope(b); QV4::ExecutionEngine *v4 = scope.engine; QV8Engine *v8engine = scope.engine->v8Engine; @@ -1667,11 +1689,12 @@ void ConsoleObject::method_count(const BuiltinFunction *, Scope &scope, CallData qPrintable(frame->function())) .debug("%s", qPrintable(message)); - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void ConsoleObject::method_trace(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_trace(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 0) THROW_GENERIC_ERROR("console.trace(): Invalid arguments"); @@ -1684,16 +1707,17 @@ void ConsoleObject::method_trace(const BuiltinFunction *, Scope &scope, CallData frame->function().toUtf8().constData()) .debug("%s", qPrintable(stack)); - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void ConsoleObject::method_warn(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_warn(const BuiltinFunction *b, CallData *callData) { - return writeToConsole(b, scope, callData, Warn); + return writeToConsole(b, callData, Warn); } -void ConsoleObject::method_assert(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_assert(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc == 0) THROW_GENERIC_ERROR("console.assert(): Missing argument"); @@ -1716,17 +1740,16 @@ void ConsoleObject::method_assert(const BuiltinFunction *, Scope &scope, CallDat .critical("%s\n%s",qPrintable(message), qPrintable(stack)); } - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void ConsoleObject::method_exception(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue ConsoleObject::method_exception(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc == 0) THROW_GENERIC_ERROR("console.exception(): Missing argument"); - writeToConsole(b, scope, callData, Error, true); - - scope.result = QV4::Encode::undefined(); + return writeToConsole(b, callData, Error, true); } @@ -1782,8 +1805,9 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext \sa {Internationalization and Localization with Qt Quick} */ -void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalExtensions::method_qsTranslate(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 2) THROW_GENERIC_ERROR("qsTranslate() requires at least two arguments"); if (!callData->args[0].isString()) @@ -1813,7 +1837,7 @@ void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope, comment.toUtf8().constData(), n); - scope.result = scope.engine->newString(result); + return Encode(scope.engine->newString(result)); } /*! @@ -1838,12 +1862,13 @@ void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope, \sa {Internationalization and Localization with Qt Quick} */ -void GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 2) - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); else - scope.result = callData->args[1]; + return callData->args[1].asReturnedValue(); } /*! @@ -1863,8 +1888,9 @@ void GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *, Scope &sc \sa {Internationalization and Localization with Qt Quick} */ -void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalExtensions::method_qsTr(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 1) THROW_GENERIC_ERROR("qsTr() requires at least one argument"); if (!callData->args[0].isString()) @@ -1912,7 +1938,7 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(), comment.toUtf8().constData(), n); - scope.result = scope.engine->newString(result); + return Encode(scope.engine->newString(result)); } /*! @@ -1937,12 +1963,12 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa \sa {Internationalization and Localization with Qt Quick} */ -void GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, CallData *callData) { if (callData->argc < 1) - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); else - scope.result = callData->args[0]; + return callData->args[0].asReturnedValue(); } /*! @@ -1975,8 +2001,9 @@ void GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, Scope &scope, Ca \sa QT_TRID_NOOP(), {Internationalization and Localization with Qt Quick} */ -void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalExtensions::method_qsTrId(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc < 1) THROW_GENERIC_ERROR("qsTrId() requires at least one argument"); if (!callData->args[0].isString()) @@ -1988,7 +2015,7 @@ void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, Call if (callData->argc > 1) n = callData->args[1].toInt32(); - scope.result = scope.engine->newString(qtTrId(callData->args[0].toQStringNoThrow().toUtf8().constData(), n)); + return Encode(scope.engine->newString(qtTrId(callData->args[0].toQStringNoThrow().toUtf8().constData(), n))); } /*! @@ -2007,27 +2034,28 @@ void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, Call \sa qsTrId(), {Internationalization and Localization with Qt Quick} */ -void GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, CallData *callData) { if (callData->argc < 1) - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); else - scope.result = callData->args[0]; + return callData->args[0].asReturnedValue(); } #endif // translation -void GlobalExtensions::method_gc(const BuiltinFunction *, Scope &scope, CallData *) +ReturnedValue GlobalExtensions::method_gc(const BuiltinFunction *b, CallData *) { - scope.engine->memoryManager->runGC(); + b->engine()->memoryManager->runGC(); - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } -void GlobalExtensions::method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData) +ReturnedValue GlobalExtensions::method_string_arg(const BuiltinFunction *b, CallData *callData) { + QV4::Scope scope(b); if (callData->argc != 1) THROW_GENERIC_ERROR("String.arg(): Invalid arguments"); @@ -2064,10 +2092,10 @@ be passed on to the function invoked. Note that if redundant calls are eliminated, then only the last set of arguments will be passed to the function. */ -void QtObject::method_callLater(const BuiltinFunction *b, Scope &scope, CallData *callData) +ReturnedValue QtObject::method_callLater(const BuiltinFunction *b, CallData *callData) { - QV8Engine *v8engine = scope.engine->v8Engine; - v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, scope, callData); + QV8Engine *v8engine = b->engine()->v8Engine; + return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, callData); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index 21613b7c10..7d61aa0ada 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -93,45 +93,45 @@ struct QtObject : Object static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); - static void method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_font(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_rect(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_point(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_size(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_darker(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_tint(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_openUrlExternally(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_md5(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_atob(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_quit(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_exit(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_locale(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_binding(const BuiltinFunction *, Scope &scope, CallData *callData); - - static void method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *callData); - - static void method_callLater(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_isQtObject(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_rgba(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_hsla(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_hsva(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_colorEqual(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_font(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_rect(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_point(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_size(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_vector2d(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_vector3d(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_vector4d(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_quaternion(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_matrix4x4(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_lighter(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_darker(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_tint(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_formatDate(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_formatTime(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_formatDateTime(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_openUrlExternally(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_fontFamilies(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_md5(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_btoa(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_atob(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_quit(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_exit(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_resolvedUrl(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_createQmlObject(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_createComponent(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_locale(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_binding(const BuiltinFunction *, CallData *callData); + + static ReturnedValue method_get_platform(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_application(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_inputMethod(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_get_styleHints(const BuiltinFunction *, CallData *callData); + + static ReturnedValue method_callLater(const BuiltinFunction *, CallData *callData); private: void addAll(); @@ -142,18 +142,18 @@ struct ConsoleObject : Object { V4_OBJECT2(ConsoleObject, Object) - static void method_error(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_info(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_profile(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_time(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_count(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_trace(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_warn(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_assert(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_exception(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_error(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_log(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_info(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_profile(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_profileEnd(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_time(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_timeEnd(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_count(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_trace(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_warn(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_assert(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_exception(const BuiltinFunction *, CallData *callData); }; @@ -161,17 +161,17 @@ struct Q_QML_PRIVATE_EXPORT GlobalExtensions { static void init(Object *globalObject, QJSEngine::Extensions extensions); #if QT_CONFIG(translation) - static void method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData); - static void method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_qsTranslate(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_qsTranslateNoOp(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_qsTr(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_qsTrNoOp(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_qsTrId(const BuiltinFunction *, CallData *callData); + static ReturnedValue method_qsTrIdNoOp(const BuiltinFunction *, CallData *callData); #endif - static void method_gc(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_gc(const BuiltinFunction *, CallData *callData); // on String:prototype - static void method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData); + static ReturnedValue method_string_arg(const BuiltinFunction *, CallData *callData); }; diff --git a/src/qml/qml/v8/qv4domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h index a9bdbe01ae..06a70a13e9 100644 --- a/src/qml/qml/v8/qv4domerrors_p.h +++ b/src/qml/qml/v8/qv4domerrors_p.h @@ -78,8 +78,7 @@ QT_BEGIN_NAMESPACE QV4::ScopedValue v(scope, scope.engine->newString(QStringLiteral(string))); \ QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \ ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(error))); \ - scope.result = scope.engine->throwError(ex); \ - return; \ + return scope.engine->throwError(ex); \ } namespace QV4 { diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index a1e3fde1b6..ded38345d7 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -1795,26 +1795,24 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const return groupFlags; } -void QQmlDelegateModelItem::get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +QV4::ReturnedValue QQmlDelegateModelItem::get_model(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>()); - if (!o) { - scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return; - } + if (!o) + return b->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object")); if (!o->d()->item->metaType->model) RETURN_UNDEFINED(); - scope.result = o->d()->item->get(); + return o->d()->item->get(); } -void QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +QV4::ReturnedValue QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>()); - if (!o) { - scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return; - } + if (!o) + return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")); QStringList groups; for (int i = 1; i < o->d()->item->metaType->groupCount; ++i) { @@ -1822,16 +1820,15 @@ void QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *, QV4::Scope groups.append(o->d()->item->metaType->groupNames.at(i - 1)); } - scope.result = scope.engine->fromVariant(groups); + return scope.engine->fromVariant(groups); } -void QQmlDelegateModelItem::set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +QV4::ReturnedValue QQmlDelegateModelItem::set_groups(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>()); - if (!o) { - scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return; - } + if (!o) + return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")); if (!callData->argc) THROW_TYPE_ERROR(); @@ -1844,7 +1841,7 @@ void QQmlDelegateModelItem::set_groups(const QV4::BuiltinFunction *, QV4::Scope const int cacheIndex = model->m_cache.indexOf(o->d()->item); Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex); model->setGroups(it, 1, Compositor::Cache, groupFlags); - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &) @@ -3211,25 +3208,28 @@ struct QQmlDelegateModelGroupChange : QV4::Object return e->memoryManager->allocObject<QQmlDelegateModelGroupChange>(); } - static void method_get_index(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { + static QV4::ReturnedValue method_get_index(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>()); if (!that) THROW_TYPE_ERROR(); - scope.result = QV4::Encode(that->d()->change.index); + return QV4::Encode(that->d()->change.index); } - static void method_get_count(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { + static QV4::ReturnedValue method_get_count(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>()); if (!that) THROW_TYPE_ERROR(); - scope.result = QV4::Encode(that->d()->change.count); + return QV4::Encode(that->d()->change.count); } - static void method_get_moveId(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) { + static QV4::ReturnedValue method_get_moveId(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>()); if (!that) THROW_TYPE_ERROR(); if (that->d()->change.moveId < 0) RETURN_UNDEFINED(); - scope.result = QV4::Encode(that->d()->change.moveId); + return QV4::Encode(that->d()->change.moveId); } }; diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 4ebfd9b938..4de6fd0745 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -126,9 +126,9 @@ public: virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); } virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; } - static void get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); - static void set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static QV4::ReturnedValue get_model(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue get_groups(const QV4::BuiltinFunction *, QV4::CallData *callData); + static QV4::ReturnedValue set_groups(const QV4::BuiltinFunction *, QV4::CallData *callData); static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &); static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index 743bcbc5a3..ce7635218e 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -185,7 +185,7 @@ public: int m_nextId; - static void method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); + static QV4::ReturnedValue method_sendMessage(const QV4::BuiltinFunction *, QV4::CallData *callData); signals: void stopThread(); @@ -246,7 +246,7 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init() Q_ASSERT(!scope.engine->hasException); QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage"))); QV4::ScopedValue function(scope, QV4::BuiltinFunction::create(globalContext, name, - QQuickWorkerScriptEnginePrivate::method_sendMessage)); + QQuickWorkerScriptEnginePrivate::method_sendMessage)); QV4::ScopedCallData callData(scope, 1); callData->args[0] = function; callData->thisObject = global(); @@ -292,8 +292,10 @@ QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *eng { } -void QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunction *b, + QV4::CallData *callData) { + QV4::Scope scope(b); WorkerEngine *engine = (WorkerEngine*)scope.engine->v8Engine; int id = callData->argc > 1 ? callData->args[1].toInt32() : 0; @@ -306,7 +308,7 @@ void QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunct if (script && script->owner) QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data)); - scope.result = QV4::Encode::undefined(); + return QV4::Encode::undefined(); } QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script) diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index b9f6ea461a..1f2da174b9 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -61,8 +61,9 @@ public: V4_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData) -static void get_index(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) +static QV4::ReturnedValue get_index(const QV4::BuiltinFunction *f, QV4::CallData *callData) { + QV4::Scope scope(f); QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>()); if (!o) RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"))); @@ -194,8 +195,9 @@ public: dataType->watchedRoles += newRoles; } - static void get_hasModelChildren(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) + static QV4::ReturnedValue get_hasModelChildren(const QV4::BuiltinFunction *b, QV4::CallData *callData) { + QV4::Scope scope(b); QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>()); if (!o) RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"))); @@ -581,25 +583,27 @@ public: } } - static void get_modelData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) + static QV4::ReturnedValue get_modelData(const QV4::BuiltinFunction *b, QV4::CallData *callData) { - QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>()); + QV4::ExecutionEngine *v4 = b->engine(); + QQmlDelegateModelItemObject *o = callData->thisObject.as<QQmlDelegateModelItemObject>(); if (!o) - RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"))); + return v4->throwTypeError(QStringLiteral("Not a valid VisualData object")); - RETURN_RESULT(scope.engine->fromVariant(static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData)); + return v4->fromVariant(static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData); } - static void set_modelData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) + static QV4::ReturnedValue set_modelData(const QV4::BuiltinFunction *b, QV4::CallData *callData) { - QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>()); + QV4::ExecutionEngine *v4 = b->engine(); + QQmlDelegateModelItemObject *o = callData->thisObject.as<QQmlDelegateModelItemObject>(); if (!o) - RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"))); + return v4->throwTypeError(QStringLiteral("Not a valid VisualData object")); if (!callData->argc) - RETURN_RESULT(scope.engine->throwTypeError()); + return v4->throwTypeError(); - static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(scope.engine->toVariant(callData->args[0], QVariant::Invalid)); - RETURN_RESULT(QV4::Encode::undefined()); + static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(callData->args[0], QVariant::Invalid)); + return QV4::Encode::undefined(); } QV4::ReturnedValue get() override |