aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp54
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h8
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp222
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h48
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp19
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4context.cpp12
-rw-r--r--src/qml/jsruntime/qv4context_p.h4
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp80
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h18
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp435
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h102
-rw-r--r--src/qml/jsruntime/qv4engine.cpp9
-rw-r--r--src/qml/jsruntime/qv4engine_p.h10
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp19
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp64
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h19
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp48
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h20
-rw-r--r--src/qml/jsruntime/qv4include.cpp7
-rw-r--r--src/qml/jsruntime/qv4include_p.h2
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp21
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp40
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h38
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp163
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h20
-rw-r--r--src/qml/jsruntime/qv4object.cpp12
-rw-r--r--src/qml/jsruntime/qv4object_p.h12
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp322
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h54
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp8
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp64
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h18
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h34
-rw-r--r--src/qml/jsruntime/qv4script.cpp5
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp297
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h48
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp58
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h12
-rw-r--r--src/qml/jsruntime/qv4value_p.h19
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp36
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h8
47 files changed, 1331 insertions, 1200 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);
};
}