aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-09-16 22:02:27 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-22 01:06:20 +0200
commite441692b0b8f8fffdfdfa8a21c570adcd5cbae7a (patch)
tree9b764401d87682012328c46dc947721f47b428b2
parenta0f8be4021caa9bb5055923f0eea3bee0e345235 (diff)
Further work towards an exact GC
Add some more convenience in the helper classes in qscopedvalue_p.h Make accesses to CallData safer, and change ExecutionEngine::newObject() to return a safe pointer. Change-Id: I980909754ce9681cf6faa1355bab3a1e5d6dd186 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/imports/localstorage/plugin.cpp40
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp5
-rw-r--r--src/particles/qquickv4particledata.cpp38
-rw-r--r--src/qml/jsapi/qjsengine.cpp2
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp141
-rw-r--r--src/qml/jsruntime/qv4context.cpp6
-rw-r--r--src/qml/jsruntime/qv4context_p.h18
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp93
-rw-r--r--src/qml/jsruntime/qv4engine.cpp14
-rw-r--r--src/qml/jsruntime/qv4engine_p.h6
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h5
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp85
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h5
-rw-r--r--src/qml/jsruntime/qv4global_p.h5
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp45
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4include.cpp5
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp32
-rw-r--r--src/qml/jsruntime/qv4managed_p.h53
-rw-r--r--src/qml/jsruntime/qv4mm.cpp2
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp17
-rw-r--r--src/qml/jsruntime/qv4object_p.h15
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp190
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp5
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h158
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp4
-rw-r--r--src/qml/jsruntime/qv4string_p.h15
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp40
-rw-r--r--src/qml/jsruntime/qv4value.cpp30
-rw-r--r--src/qml/jsruntime/qv4value_def_p.h31
-rw-r--r--src/qml/jsruntime/qv4value_p.h18
-rw-r--r--src/qml/qml/qqmlcomponent.cpp5
-rw-r--r--src/qml/qml/qqmllocale.cpp26
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp5
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp104
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp7
-rw-r--r--src/qml/qml/v8/qv4domerrors.cpp5
-rw-r--r--src/qml/qml/v8/qv4sqlerrors.cpp5
-rw-r--r--src/qml/qml/v8/qv8engine.cpp10
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp18
-rw-r--r--src/qml/types/qquickworkerscript.cpp29
-rw-r--r--src/qml/util/qqmladaptormodel.cpp10
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp235
-rw-r--r--src/quick/items/qquickitem.cpp10
45 files changed, 1000 insertions, 600 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 246ddd96c5..900a5a09a3 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -201,12 +201,13 @@ static QString qmlsqldatabase_databaseFile(const QString& connectionName, QV8Eng
static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
{
+ Scope scope(v4);
QV8Engine *v8 = v4->v8Engine;
if (r->sqlQuery.at() == (int)index || r->sqlQuery.seek(index)) {
QSqlRecord record = r->sqlQuery.record();
// XXX optimize
- Object *row = v4->newObject();
+ Scoped<Object> row(scope, v4->newObject());
for (int ii = 0; ii < record.count(); ++ii) {
QVariant v = record.value(ii);
if (v.isNull()) {
@@ -217,11 +218,11 @@ static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, Execut
}
if (hasProperty)
*hasProperty = true;
- return Value::fromObject(row).asReturnedValue();
+ return row.asReturnedValue();
} else {
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue().asReturnedValue();
+ return Encode::undefined();
}
}
@@ -247,7 +248,7 @@ static ReturnedValue qmlsqldatabase_rows_item(SimpleCallContext *ctx)
static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx)
{
QV4::Scope scope(ctx);
- QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
+ Scoped<QQmlSqlDatabaseWrapper> r(scope, ctx->thisObject);
if (!r || r->type != QQmlSqlDatabaseWrapper::Query)
V4THROW_REFERENCE("Not a SQLDatabase::Query object");
@@ -258,7 +259,7 @@ static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx)
QSqlDatabase db = r->database;
- QString sql = ctx->argument(0).toQStringNoThrow();
+ QString sql = ctx->argumentCount ? ctx->arguments[0].toQString() : QString();
if (r->readonly && !sql.startsWith(QLatin1String("SELECT"),Qt::CaseInsensitive)) {
V4THROW_SQL(SQLEXCEPTION_SYNTAX_ERR, QQmlEngine::tr("Read-only Transaction"));
@@ -303,8 +304,8 @@ static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx)
rows->database = db;
rows->sqlQuery = query;
- Object *resultObject = ctx->engine->newObject();
- result = Value::fromObject(resultObject);
+ Scoped<Object> resultObject(scope, ctx->engine->newObject());
+ result = resultObject.asValue();
// XXX optimize
resultObject->put(ctx->engine->newIdentifier("rowsAffected"), Value::fromInt32(query.numRowsAffected()));
resultObject->put(ctx->engine->newIdentifier("insertId"), engine->toString(query.lastInsertId().toString()));
@@ -328,16 +329,16 @@ static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
Scope scope(ctx);
- QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
+ Scoped<QQmlSqlDatabaseWrapper> r(scope, ctx->thisObject);
if (!r || r->type != QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
QV8Engine *engine = ctx->engine->v8Engine;
QSqlDatabase db = r->database;
- QString from_version = ctx->arguments[0].toQStringNoThrow();
- QString to_version = ctx->arguments[1].toQStringNoThrow();
- Value callback = ctx->argument(2);
+ QString from_version = ctx->arguments[0].toQString();
+ QString to_version = ctx->arguments[1].toQString();
+ Scoped<FunctionObject> callback(scope, ctx->argument(2));
if (from_version != r->version)
V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(r->version));
@@ -350,7 +351,7 @@ static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
w->inTransaction = true;
bool ok = true;
- if (FunctionObject *f = callback.asFunctionObject()) {
+ if (!!callback) {
ok = false;
db.transaction();
@@ -358,7 +359,7 @@ static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
callData->thisObject = engine->global();
callData->args[0] = Value::fromObject(w);
try {
- f->call(callData);
+ callback->call(callData);
} catch (Exception &) {
db.rollback();
throw;
@@ -442,24 +443,25 @@ static ReturnedValue qmlsqldatabase_read_transaction(SimpleCallContext *ctx)
QQmlSqlDatabaseData::QQmlSqlDatabaseData(QV8Engine *engine)
{
ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ Scope scope(v4);
{
- Object *proto = v4->newObject();
+ Scoped<Object> proto(scope, v4->newObject());
proto->defineDefaultProperty(v4, QStringLiteral("transaction"), qmlsqldatabase_transaction);
proto->defineDefaultProperty(v4, QStringLiteral("readTransaction"), qmlsqldatabase_read_transaction);
Property *p = proto->insertMember(v4->newString(QStringLiteral("version")),
Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->newString(QStringLiteral("version")), qmlsqldatabase_version));
proto->defineDefaultProperty(v4, QStringLiteral("changeVersion"), qmlsqldatabase_changeVersion);
- databaseProto = Value::fromObject(proto);
+ databaseProto = proto;
}
{
- Object *proto = v4->newObject();
+ Scoped<Object> proto(scope, v4->newObject());
proto->defineDefaultProperty(v4, QStringLiteral("executeSql"), qmlsqldatabase_executeSql);
- queryProto = Value::fromObject(proto);
+ queryProto = proto;
}
{
- Object *proto = v4->newObject();
+ Scoped<Object> proto(scope, v4->newObject());
proto->defineDefaultProperty(v4, QStringLiteral("item"), qmlsqldatabase_rows_item);
Property *p = proto->insertMember(v4->newString(QStringLiteral("length")),
Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
@@ -468,7 +470,7 @@ QQmlSqlDatabaseData::QQmlSqlDatabaseData(QV8Engine *engine)
Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->newString(QStringLiteral("forwardOnly")), qmlsqldatabase_rows_forwardOnly));
p->setSetter(v4->newBuiltinFunction(v4->rootContext, v4->newString(QStringLiteral("setForwardOnly")), qmlsqldatabase_rows_setForwardOnly));
- rowsProto = Value::fromObject(proto);
+ rowsProto = proto;
}
}
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
index 9f6437625d..f87273be40 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
@@ -923,13 +923,14 @@ QQmlV4Handle QQuickXmlListModel::get(int index) const
QQmlEngine *engine = qmlContext(this)->engine();
QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine);
ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
- Object *o = v4engine->newObject();
+ Scope scope(v4engine);
+ Scoped<Object> o(scope, v4engine->newObject());
for (int ii = 0; ii < d->roleObjects.count(); ++ii) {
Property *p = o->insertMember(v4engine->newIdentifier(d->roleObjects[ii]->name()), PropertyAttributes());
p->value = Value::fromReturnedValue(v8engine->fromVariant(d->data.value(ii).value(index)));
}
- return QQmlV4Handle(Value::fromObject(o));
+ return QQmlV4Handle(o.asValue());
}
/*!
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp
index 1a574600e0..23018677ea 100644
--- a/src/particles/qquickv4particledata.cpp
+++ b/src/particles/qquickv4particledata.cpp
@@ -328,7 +328,8 @@ static QV4::ReturnedValue particleData_curSize(QV4::SimpleCallContext *ctx)
}
#define COLOR_GETTER_AND_SETTER(VAR, NAME) static QV4::ReturnedValue particleData_get_ ## NAME (QV4::SimpleCallContext *ctx) \
{ \
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
@@ -337,18 +338,21 @@ static QV4::ReturnedValue particleData_curSize(QV4::SimpleCallContext *ctx)
\
static QV4::ReturnedValue particleData_set_ ## NAME (QV4::SimpleCallContext *ctx)\
{\
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
- r->datum->color. VAR = qMin(255, qMax(0, (int)floor(ctx->argument(0).toNumber() * 255.0)));\
+ double d = ctx->argumentCount ? ctx->arguments[0].toNumber() : 0; \
+ r->datum->color. VAR = qMin(255, qMax(0, (int)floor(d * 255.0)));\
return QV4::Encode::undefined(); \
}
#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
{ \
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
@@ -357,17 +361,19 @@ static QV4::ReturnedValue particleData_set_ ## NAME (QV4::SimpleCallContext *ctx
\
static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
{\
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
- r->datum-> VARIABLE = ctx->argument(0).toBoolean() ? 1.0 : 0.0;\
+ r->datum-> VARIABLE = (ctx->argumentCount && ctx->arguments[0].toBoolean()) ? 1.0 : 0.0;\
return QV4::Encode::undefined(); \
}
#define FLOAT_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
{ \
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
@@ -376,17 +382,19 @@ static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext
\
static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
{\
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
- r->datum-> VARIABLE = ctx->argument(0).toNumber();\
+ r->datum-> VARIABLE = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();\
return QV4::Encode::undefined(); \
}
#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static QV4::ReturnedValue particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
{ \
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
@@ -395,11 +403,12 @@ static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext
\
static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
{\
- QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
+ QV4::Scope scope(ctx); \
+ QV4::Scoped<QV4ParticleData> r(scope, ctx->thisObject); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
- r->datum-> SETTER ( ctx->argument(0).toNumber() );\
+ r->datum-> SETTER (ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN());\
return QV4::Encode::undefined(); \
}
@@ -444,7 +453,8 @@ FAKE_FLOAT_GETTER_AND_SETTER(curAY, curAY, setInstantaneousAY)
QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QV4::Object *p = v4->newObject();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> p(scope, v4->newObject());
p->defineDefaultProperty(v4, QStringLiteral("discard"), particleData_discard);
p->defineDefaultProperty(v4, QStringLiteral("lifeLeft"), particleData_lifeLeft);
@@ -485,7 +495,7 @@ QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine)
REGISTER_ACCESSOR(p, v4, blue, blue);
REGISTER_ACCESSOR(p, v4, alpha, alpha);
- proto = QV4::Value::fromObject(p);
+ proto = p;
}
QV8ParticleDataDeletable::~QV8ParticleDataDeletable()
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index b66dd51648..f99463256e 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -286,7 +286,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
*/
QJSValue QJSEngine::newObject()
{
- return new QJSValuePrivate(d->m_v4Engine->newObject());
+ return new QJSValuePrivate(d->m_v4Engine->newObject()->getPointer());
}
/*!
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 6c028de372..62937921aa 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -84,12 +84,12 @@ ArgumentsObject::ArgumentsObject(CallContext *context)
ensureArrayAttributes();
context->engine->requireArgumentsAccessors(numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
- mappedArguments.append(context->argument(i));
+ mappedArguments.append(context->arguments[i]);
arrayData[i] = context->engine->argumentsAccessors.at(i);
arrayAttributes[i] = Attr_Accessor;
}
for (uint i = numAccessors; i < argCount; ++i) {
- arrayData[i] = Property::fromValue(context->argument(i));
+ arrayData[i] = Property::fromValue(context->arguments[i]);
arrayAttributes[i] = Attr_Data;
}
arrayDataLen = argCount;
@@ -160,7 +160,7 @@ ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
getter->engine()->current->throwTypeError();
assert(g->index < o->context->argumentCount);
- return o->context->argument(g->index).asReturnedValue();
+ return o->context->argument(g->index);
}
DEFINE_MANAGED_VTABLE(ArgumentsSetterFunction);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 1f09b97d5c..ce6bdca627 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -131,9 +131,8 @@ uint ArrayPrototype::getLength(ExecutionContext *ctx, Object *o)
ReturnedValue ArrayPrototype::method_isArray(SimpleCallContext *ctx)
{
- Value arg = ctx->argument(0);
- bool isArray = arg.asArrayObject();
- return Value::fromBoolean(isArray).asReturnedValue();
+ bool isArray = ctx->argumentCount ? ctx->arguments[0].asArrayObject() : false;
+ return Encode(isArray);
}
ReturnedValue ArrayPrototype::method_toString(SimpleCallContext *ctx)
@@ -174,13 +173,11 @@ ReturnedValue ArrayPrototype::method_concat(SimpleCallContext *ctx)
}
for (uint i = 0; i < ctx->argumentCount; ++i) {
- Value arg = ctx->argument(i);
-
- if (ArrayObject *elt = arg.asArrayObject())
+ if (ArrayObject *elt = ctx->arguments[i].asArrayObject())
result->arrayConcat(elt);
else
- result->arraySet(getLength(ctx, result.getPointer()), arg);
+ result->arraySet(getLength(ctx, result.getPointer()), ctx->arguments[i]);
}
return result.asReturnedValue();
@@ -189,13 +186,13 @@ ReturnedValue ArrayPrototype::method_concat(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_join(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Value arg = ctx->argument(0);
+ ScopedValue arg(scope, ctx->argument(0));
QString r4;
- if (arg.isUndefined())
+ if (arg->isUndefined())
r4 = QStringLiteral(",");
else
- r4 = arg.toString(ctx)->toQString();
+ r4 = arg->toQString();
Scoped<Object> self(scope, ctx->thisObject);
ScopedValue length(scope, self->get(ctx->engine->id_length));
@@ -276,9 +273,9 @@ ReturnedValue ArrayPrototype::method_push(SimpleCallContext *ctx)
if (len + ctx->argumentCount < len) {
// ughh...
double l = len;
- for (double i = 0; i < ctx->argumentCount; ++i) {
+ for (int i = 0; i < ctx->argumentCount; ++i) {
Value idx = Value::fromDouble(l + i);
- instance->put(idx.toString(ctx), ctx->argument(i));
+ instance->put(idx.toString(ctx), ctx->arguments[i]);
}
double newLen = l + ctx->argumentCount;
if (!instance->isArrayObject())
@@ -290,7 +287,7 @@ ReturnedValue ArrayPrototype::method_push(SimpleCallContext *ctx)
if (!instance->protoHasArray() && instance->arrayDataLen <= len) {
for (uint i = 0; i < ctx->argumentCount; ++i) {
- Value v = ctx->argument(i);
+ Value v = ctx->arguments[i];
if (!instance->sparseArray) {
if (len >= instance->arrayAlloc)
@@ -307,7 +304,7 @@ ReturnedValue ArrayPrototype::method_push(SimpleCallContext *ctx)
}
} else {
for (uint i = 0; i < ctx->argumentCount; ++i)
- instance->putIndexed(len + i, ctx->argument(i));
+ instance->putIndexed(len + i, ctx->arguments[i]);
len += ctx->argumentCount;
}
if (instance->isArrayObject())
@@ -408,7 +405,7 @@ ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx)
Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject());
uint len = ArrayPrototype::getLength(ctx, o);
- double s = ctx->argument(0).toInteger();
+ double s = ScopedValue(scope, ctx->argument(0))->toInteger();
uint start;
if (s < 0)
start = (uint)qMax(len + s, 0.);
@@ -417,8 +414,8 @@ ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx)
else
start = (uint) s;
uint end = len;
- if (!ctx->argument(1).isUndefined()) {
- double e = ctx->argument(1).toInteger();
+ if (ctx->argumentCount > 1 && !ctx->arguments[1].isUndefined()) {
+ double e = ctx->arguments[1].toInteger();
if (e < 0)
end = (uint)qMax(len + e, 0.);
else if (e > len)
@@ -442,12 +439,13 @@ ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_sort(SimpleCallContext *ctx)
{
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scope scope(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- Value comparefn = ctx->argument(0);
- instance->arraySort(ctx, instance, comparefn, len);
+ ScopedValue comparefn(scope, ctx->argument(0));
+ instance->arraySort(ctx, instance.getPointer(), comparefn, len);
return ctx->thisObject.asReturnedValue();
}
@@ -459,14 +457,14 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx)
Scoped<ArrayObject> newArray(scope, ctx->engine->newArrayObject());
- double rs = ctx->argument(0).toInteger();
+ double rs = ScopedValue(scope, ctx->argument(0))->toInteger();
uint start;
if (rs < 0)
start = (uint) qMax(0., len + rs);
else
start = (uint) qMin(rs, (double)len);
- uint deleteCount = (uint)qMin(qMax(ctx->argument(1).toInteger(), 0.), (double)(len - start));
+ uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, ctx->argument(1))->toInteger(), 0.), (double)(len - start));
newArray->arrayReserve(deleteCount);
Property *pd = newArray->arrayData;
@@ -505,7 +503,7 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx)
}
for (uint i = 0; i < itemCount; ++i)
- instance->putIndexed(start + i, ctx->argument(i + 2));
+ instance->putIndexed(start + i, ctx->arguments[i + 2]);
ctx->strictMode = true;
instance->put(ctx->engine->id_length, Value::fromDouble(len - deleteCount + itemCount));
@@ -520,8 +518,9 @@ ReturnedValue ArrayPrototype::method_unshift(SimpleCallContext *ctx)
uint len = getLength(ctx, instance);
if (!instance->protoHasArray() && instance->arrayDataLen <= len) {
+ ScopedValue v(scope);
for (int i = ctx->argumentCount - 1; i >= 0; --i) {
- Value v = ctx->argument(i);
+ v = ctx->argument(i);
if (!instance->sparseArray) {
if (!instance->arrayOffset)
@@ -551,7 +550,7 @@ ReturnedValue ArrayPrototype::method_unshift(SimpleCallContext *ctx)
instance->deleteIndexedProperty(k + ctx->argumentCount - 1);
}
for (uint i = 0; i < ctx->argumentCount; ++i)
- instance->putIndexed(i, ctx->argument(i));
+ instance->putIndexed(i, ctx->arguments[i]);
}
uint newLen = len + ctx->argumentCount;
@@ -578,14 +577,14 @@ ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
uint fromIndex = 0;
if (ctx->argumentCount >= 1)
- searchValue = ctx->argument(0);
+ searchValue = ctx->arguments[0];
else
searchValue = Value::undefinedValue();
if (ctx->argumentCount >= 2) {
- double f = ctx->argument(1).toInteger();
+ double f = ctx->arguments[1].toInteger();
if (f >= len)
- return Value::fromInt32(-1).asReturnedValue();
+ return Encode(-1);
if (f < 0)
f = qMax(len + f, 0.);
fromIndex = (uint) f;
@@ -597,9 +596,9 @@ ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
bool exists;
v = instance->getIndexed(k, &exists);
if (exists && __qmljs_strict_equal(v, searchValue))
- return Value::fromDouble(k).asReturnedValue();
+ return Encode(k);
}
- return Value::fromInt32(-1).asReturnedValue();
+ return Encode(-1);
}
return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance);
@@ -623,13 +622,13 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
searchValue = Value::undefinedValue();
if (ctx->argumentCount >= 2) {
- double f = ctx->argument(1).toInteger();
+ double f = ctx->arguments[1].toInteger();
if (f > 0)
f = qMin(f, (double)(len - 1));
else if (f < 0) {
f = len + f;
if (f < 0)
- return Value::fromInt32(-1).asReturnedValue();
+ return Encode(-1);
}
fromIndex = (uint) f + 1;
}
@@ -648,19 +647,17 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_every(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- FunctionObject *callback = ctx->argument(0).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
ctx->throwTypeError();
- Value thisArg = ctx->argument(1);
-
ScopedCallData callData(scope, 3);
- callData->args[2] = Value::fromObject(instance);
- callData->thisObject = thisArg;
+ callData->args[2] = instance.asValue();
+ callData->thisObject = ctx->argument(1);
ScopedValue r(scope);
ScopedValue v(scope);
@@ -682,17 +679,17 @@ ReturnedValue ArrayPrototype::method_every(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_some(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- FunctionObject *callback = ctx->argument(0).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
ctx->throwTypeError();
ScopedCallData callData(scope, 3);
callData->thisObject = ctx->argument(1);
- callData->args[2] = Value::fromObject(instance);
+ callData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -705,25 +702,25 @@ ReturnedValue ArrayPrototype::method_some(SimpleCallContext *ctx)
callData->args[1] = Value::fromDouble(k);
Value r = Value::fromReturnedValue(callback->call(callData));
if (r.toBoolean())
- return Value::fromBoolean(true).asReturnedValue();
+ return Encode(true);
}
- return Value::fromBoolean(false).asReturnedValue();
+ return Encode(false);
}
ReturnedValue ArrayPrototype::method_forEach(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- FunctionObject *callback = ctx->argument(0).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
ctx->throwTypeError();
ScopedCallData callData(scope, 3);
callData->thisObject = ctx->argument(1);
- callData->args[2] = Value::fromObject(instance);
+ callData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -736,30 +733,28 @@ ReturnedValue ArrayPrototype::method_forEach(SimpleCallContext *ctx)
callData->args[1] = Value::fromDouble(k);
callback->call(callData);
}
- return Value::undefinedValue().asReturnedValue();
+ return Encode::undefined();
}
ReturnedValue ArrayPrototype::method_map(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- FunctionObject *callback = ctx->argument(0).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
ctx->throwTypeError();
- Value thisArg = ctx->argument(1);
-
Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
a->arrayReserve(len);
a->setArrayLengthUnchecked(len);
ScopedValue mapped(scope);
ScopedCallData callData(scope, 3);
- callData->thisObject = thisArg;
- callData->args[2] = Value::fromObject(instance);
+ callData->thisObject = ctx->argument(1);
+ callData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -779,23 +774,21 @@ ReturnedValue ArrayPrototype::method_map(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_filter(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- FunctionObject *callback = ctx->argument(0).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
ctx->throwTypeError();
- Value thisArg = ctx->argument(1);
-
Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
a->arrayReserve(len);
ScopedValue selected(scope);
ScopedCallData callData(scope, 3);
- callData->thisObject = thisArg;
- callData->args[2] = Value::fromObject(instance);
+ callData->thisObject = ctx->argument(1);
+ callData->args[2] = instance;
ScopedValue v(scope);
@@ -820,11 +813,11 @@ ReturnedValue ArrayPrototype::method_filter(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_reduce(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- FunctionObject *callback = ctx->argument(0).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
ctx->throwTypeError();
@@ -849,7 +842,7 @@ ReturnedValue ArrayPrototype::method_reduce(SimpleCallContext *ctx)
ScopedCallData callData(scope, 4);
callData->thisObject = Value::undefinedValue();
callData->args[0] = acc;
- callData->args[3] = Value::fromObject(instance);
+ callData->args[3] = instance;
while (k < len) {
bool kPresent;
@@ -868,18 +861,18 @@ ReturnedValue ArrayPrototype::method_reduce(SimpleCallContext *ctx)
ReturnedValue ArrayPrototype::method_reduceRight(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Object *instance = ctx->thisObject.toObject(ctx);
+ Scoped<Object> instance(scope, ctx->thisObject.toObject(ctx));
- uint len = getLength(ctx, instance);
+ uint len = getLength(ctx, instance.getPointer());
- FunctionObject *callback = ctx->argument(0).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
ctx->throwTypeError();
if (len == 0) {
if (ctx->argumentCount == 1)
ctx->throwTypeError();
- return ctx->argument(1).asReturnedValue();
+ return ctx->argument(1);
}
uint k = len;
@@ -901,7 +894,7 @@ ReturnedValue ArrayPrototype::method_reduceRight(SimpleCallContext *ctx)
ScopedCallData callData(scope, 4);
callData->thisObject = Value::undefinedValue();
- callData->args[3] = Value::fromObject(instance);
+ callData->args[3] = instance;
while (k > 0) {
bool kPresent;
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 6a97b9cfab..01cb2dd780 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -64,7 +64,7 @@ CallContext *ExecutionContext::newCallContext(void *stackSpace, FunctionObject *
c->function = function;
// ###
- c->arguments = const_cast<Value *>(callData->args);
+ c->arguments = const_cast<SafeValue *>(callData->args);
c->realArgumentCount = callData->argc;
c->argumentCount = callData->argc;
c->thisObject = callData->thisObject;
@@ -135,7 +135,7 @@ CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData
std::fill(c->locals, c->locals + function->varCount, Value::undefinedValue());
c->argumentCount = qMax((uint)callData->argc, function->formalParameterCount);
- c->arguments = c->locals + function->varCount;
+ c->arguments = static_cast<SafeValue *>(c->locals + function->varCount);
if (callData->argc)
::memcpy(c->arguments, callData->args, callData->argc * sizeof(Value));
if (callData->argc < function->formalParameterCount)
@@ -182,7 +182,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
if (ctx->type >= Type_CallContext) {
CallContext *c = static_cast<CallContext *>(ctx);
if (!c->activation)
- c->activation = engine->newObject();
+ c->activation = engine->newObject()->getPointer();
activation = c->activation;
break;
}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 0c3b189401..fe15a53fd2 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -148,8 +148,6 @@ struct Q_QML_EXPORT ExecutionContext
ReturnedValue getPropertyAndBase(String *name, Object **base);
bool deleteProperty(String *name);
- inline Value argument(unsigned int index = 0);
-
void mark();
inline CallContext *asCallContext();
@@ -160,9 +158,13 @@ struct SimpleCallContext : public ExecutionContext
{
void initSimpleCallContext(ExecutionEngine *engine);
FunctionObject *function;
- Value *arguments;
+ SafeValue *arguments;
unsigned int realArgumentCount;
unsigned int argumentCount;
+
+ ReturnedValue argument(uint i) {
+ return i < argumentCount ? arguments[i].asReturnedValue() : Value::undefinedValue().asReturnedValue();
+ }
};
struct CallContext : public SimpleCallContext
@@ -196,16 +198,6 @@ struct WithContext : public ExecutionContext
void initWithContext(ExecutionContext *p, Object *with);
};
-inline Value ExecutionContext::argument(unsigned int index)
-{
- if (type >= Type_SimpleCallContext) {
- CallContext *ctx = static_cast<CallContext *>(this);
- if (index < ctx->argumentCount)
- return ctx->arguments[index];
- }
- return Value::undefinedValue();
-}
-
inline CallContext *ExecutionContext::asCallContext()
{
return type >= Type_CallContext ? static_cast<CallContext *>(this) : 0;
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 76d712656a..14e54a2e53 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -772,20 +772,22 @@ double DatePrototype::getThisDate(ExecutionContext *ctx)
ReturnedValue DatePrototype::method_parse(SimpleCallContext *ctx)
{
- return Encode(ParseString(ctx->argument(0).toString(ctx)->toQString()));
+ if (!ctx->argumentCount)
+ return Encode(qSNaN());
+ return Encode(ParseString(ctx->arguments[0].toString(ctx)->toQString()));
}
ReturnedValue DatePrototype::method_UTC(SimpleCallContext *ctx)
{
const int numArgs = ctx->argumentCount;
if (numArgs >= 2) {
- double year = ctx->argument(0).toNumber();
- double month = ctx->argument(1).toNumber();
- double day = numArgs >= 3 ? ctx->argument(2).toNumber() : 1;
- double hours = numArgs >= 4 ? ctx->argument(3).toNumber() : 0;
- double mins = numArgs >= 5 ? ctx->argument(4).toNumber() : 0;
- double secs = numArgs >= 6 ? ctx->argument(5).toNumber() : 0;
- double ms = numArgs >= 7 ? ctx->argument(6).toNumber() : 0;
+ double year = ctx->arguments[0].toNumber();
+ double month = ctx->arguments[1].toNumber();
+ double day = numArgs >= 3 ? ctx->arguments[2].toNumber() : 1;
+ double hours = numArgs >= 4 ? ctx->arguments[3].toNumber() : 0;
+ double mins = numArgs >= 5 ? ctx->arguments[4].toNumber() : 0;
+ double secs = numArgs >= 6 ? ctx->arguments[5].toNumber() : 0;
+ double ms = numArgs >= 7 ? ctx->arguments[6].toNumber() : 0;
if (year >= 0 && year <= 99)
year += 1900;
double t = MakeDate(MakeDay(year, month, day),
@@ -996,22 +998,25 @@ ReturnedValue DatePrototype::method_getTimezoneOffset(SimpleCallContext *ctx)
ReturnedValue DatePrototype::method_setTime(SimpleCallContext *ctx)
{
- DateObject *self = ctx->thisObject.asDateObject();
+ Scope scope(ctx);
+ Scoped<DateObject> self(scope, ctx->thisObject);
if (!self)
ctx->throwTypeError();
- self->value.setDouble(TimeClip(ctx->argument(0).toNumber()));
+ double t = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ self->value.setDouble(TimeClip(t));
return self->value.asReturnedValue();
}
ReturnedValue DatePrototype::method_setMilliseconds(SimpleCallContext *ctx)
{
- DateObject *self = ctx->thisObject.asDateObject();
+ Scope scope(ctx);
+ Scoped<DateObject> self(scope, ctx->thisObject);
if (!self)
ctx->throwTypeError();
double t = LocalTime(self->value.asDouble());
- double ms = ctx->argument(0).toNumber();
+ double ms = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
self->value.setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
return self->value.asReturnedValue();
}
@@ -1023,7 +1028,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = self->value.asDouble();
- double ms = ctx->argument(0).toNumber();
+ double ms = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
self->value.setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
return self->value.asReturnedValue();
}
@@ -1035,8 +1040,8 @@ ReturnedValue DatePrototype::method_setSeconds(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = LocalTime(self->value.asDouble());
- double sec = ctx->argument(0).toNumber();
- double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber();
+ double sec = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->arguments[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1049,8 +1054,8 @@ ReturnedValue DatePrototype::method_setUTCSeconds(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = self->value.asDouble();
- double sec = ctx->argument(0).toNumber();
- double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber();
+ double sec = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->arguments[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1063,9 +1068,9 @@ ReturnedValue DatePrototype::method_setMinutes(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = LocalTime(self->value.asDouble());
- double min = ctx->argument(0).toNumber();
- double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->argument(1).toNumber();
- double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber();
+ double min = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->arguments[1].toNumber();
+ double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->arguments[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1078,9 +1083,9 @@ ReturnedValue DatePrototype::method_setUTCMinutes(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = self->value.asDouble();
- double min = ctx->argument(0).toNumber();
- double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->argument(1).toNumber();
- double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber();
+ double min = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double sec = (ctx->argumentCount < 2) ? SecFromTime(t) : ctx->arguments[1].toNumber();
+ double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->arguments[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1093,10 +1098,10 @@ ReturnedValue DatePrototype::method_setHours(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = LocalTime(self->value.asDouble());
- double hour = ctx->argument(0).toNumber();
- double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->argument(1).toNumber();
- double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->argument(2).toNumber();
- double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber();
+ double hour = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->arguments[1].toNumber();
+ double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->arguments[2].toNumber();
+ double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->arguments[3].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1109,10 +1114,10 @@ ReturnedValue DatePrototype::method_setUTCHours(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = self->value.asDouble();
- double hour = ctx->argument(0).toNumber();
- double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->argument(1).toNumber();
- double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->argument(2).toNumber();
- double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber();
+ double hour = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double min = (ctx->argumentCount < 2) ? MinFromTime(t) : ctx->arguments[1].toNumber();
+ double sec = (ctx->argumentCount < 3) ? SecFromTime(t) : ctx->arguments[2].toNumber();
+ double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->arguments[3].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1125,7 +1130,7 @@ ReturnedValue DatePrototype::method_setDate(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = LocalTime(self->value.asDouble());
- double date = ctx->argument(0).toNumber();
+ double date = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1138,7 +1143,7 @@ ReturnedValue DatePrototype::method_setUTCDate(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = self->value.asDouble();
- double date = ctx->argument(0).toNumber();
+ double date = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1151,8 +1156,8 @@ ReturnedValue DatePrototype::method_setMonth(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = LocalTime(self->value.asDouble());
- double month = ctx->argument(0).toNumber();
- double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber();
+ double month = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->arguments[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1165,8 +1170,8 @@ ReturnedValue DatePrototype::method_setUTCMonth(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = self->value.asDouble();
- double month = ctx->argument(0).toNumber();
- double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber();
+ double month = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->arguments[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1183,7 +1188,7 @@ ReturnedValue DatePrototype::method_setYear(SimpleCallContext *ctx)
t = 0;
else
t = LocalTime(t);
- double year = ctx->argument(0).toNumber();
+ double year = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
double r;
if (std::isnan(year)) {
r = qSNaN();
@@ -1205,9 +1210,9 @@ ReturnedValue DatePrototype::method_setUTCFullYear(SimpleCallContext *ctx)
ctx->throwTypeError();
double t = self->value.asDouble();
- double year = ctx->argument(0).toNumber();
- double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber();
- double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber();
+ double year = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->arguments[1].toNumber();
+ double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->arguments[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->value.setDouble(t);
return self->value.asReturnedValue();
@@ -1222,9 +1227,9 @@ ReturnedValue DatePrototype::method_setFullYear(SimpleCallContext *ctx)
double t = LocalTime(self->value.asDouble());
if (std::isnan(t))
t = 0;
- double year = ctx->argument(0).toNumber();
- double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->argument(1).toNumber();
- double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber();
+ double year = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
+ double month = (ctx->argumentCount < 2) ? MonthFromTime(t) : ctx->arguments[1].toNumber();
+ double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->arguments[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->value.setDouble(t);
return self->value.asReturnedValue();
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index daa58d5e81..5bde6b8e46 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -248,7 +248,7 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
//
// set up the global object
//
- globalObject = newObject();
+ globalObject = newObject()->getPointer();
rootContext->global = globalObject;
rootContext->thisObject = Value::fromObject(globalObject);
@@ -350,25 +350,25 @@ FunctionObject *ExecutionEngine::newBuiltinFunction(ExecutionContext *scope, Str
return f;
}
-BoundFunction *ExecutionEngine::newBoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs)
+Returned<BoundFunction> *ExecutionEngine::newBoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs)
{
assert(target);
BoundFunction *f = new (memoryManager) BoundFunction(scope, target, boundThis, boundArgs);
- return f;
+ return f->asReturned<BoundFunction>();
}
-Object *ExecutionEngine::newObject()
+Returned<Object> *ExecutionEngine::newObject()
{
Object *object = new (memoryManager) Object(this);
- return object;
+ return object->asReturned<Object>();
}
-Object *ExecutionEngine::newObject(InternalClass *internalClass)
+Returned<Object> *ExecutionEngine::newObject(InternalClass *internalClass)
{
Object *object = new (memoryManager) Object(internalClass);
- return object;
+ return object->asReturned<Object>();
}
String *ExecutionEngine::newString(const QString &s)
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 297f756033..d00ef0ea35 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -262,10 +262,10 @@ struct Q_QML_EXPORT ExecutionEngine
ExecutionContext *popContext();
FunctionObject *newBuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *));
- BoundFunction *newBoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs);
+ Returned<BoundFunction> *newBoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs);
- Object *newObject();
- Object *newObject(InternalClass *internalClass);
+ Returned<Object> *newObject();
+ Returned<Object> *newObject(InternalClass *internalClass);
String *newString(const QString &s);
String *newIdentifier(const QString &text);
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 73d9362a6d..fb526e9b1e 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -77,6 +77,11 @@ struct ErrorObject: Object {
static void destroy(Managed *that) { static_cast<ErrorObject *>(that)->~ErrorObject(); }
};
+template<>
+inline ErrorObject *value_cast(const Value &v) {
+ return v.asErrorObject();
+}
+
struct EvalErrorObject: ErrorObject {
EvalErrorObject(ExecutionEngine *engine, const Value &message);
};
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 0cf235475e..011ea34b7d 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -92,9 +92,10 @@ FunctionObject::FunctionObject(ExecutionContext *scope, String *name, bool creat
#endif
if (createProto) {
- Object *proto = scope->engine->newObject(scope->engine->protoClass);
+ Scope s(scope);
+ Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass));
proto->memberData[Index_ProtoConstructor].value = Value::fromObject(this);
- memberData[Index_Prototype].value = Value::fromObject(proto);
+ memberData[Index_Prototype].value = proto.asValue();
}
if (name)
@@ -158,16 +159,16 @@ bool FunctionObject::hasInstance(Managed *that, const Value &value)
ReturnedValue FunctionObject::construct(Managed *that, CallData *)
{
- FunctionObject *f = static_cast<FunctionObject *>(that);
- ExecutionEngine *v4 = f->engine();
+ ExecutionEngine *v4 = that->engine();
Scope scope(v4);
+ Scoped<FunctionObject> f(scope, that, Scoped<FunctionObject>::Cast);
InternalClass *ic = v4->objectClass;
Scoped<Object> proto(scope, f->get(v4->id_prototype));
if (!!proto)
ic = v4->emptyClass->changePrototype(proto.getPointer());
- Object *obj = v4->newObject(ic);
- return Value::fromObject(obj).asReturnedValue();
+ Scoped<Object> obj(scope, v4->newObject(ic));
+ return obj.asReturnedValue();
}
ReturnedValue FunctionObject::call(Managed *, CallData *)
@@ -298,20 +299,19 @@ ReturnedValue FunctionPrototype::method_apply(SimpleCallContext *ctx)
if (!o)
ctx->throwTypeError();
- Value thisArg = ctx->argument(0);
- Value arg = ctx->argument(1);
+ ScopedValue arg(scope, ctx->argument(1));
- Object *arr = arg.asObject();
+ Scoped<Object> arr(scope, arg);
quint32 len;
if (!arr) {
len = 0;
- if (!arg.isNullOrUndefined()) {
+ if (!arg->isNullOrUndefined()) {
ctx->throwTypeError();
return Encode::undefined();
}
} else {
- len = ArrayPrototype::getLength(ctx, arr);
+ len = ArrayPrototype::getLength(ctx, arr.getPointer());
}
ScopedCallData callData(scope, len);
@@ -329,14 +329,13 @@ ReturnedValue FunctionPrototype::method_apply(SimpleCallContext *ctx)
}
}
- callData->thisObject = thisArg;
+ callData->thisObject = ctx->argument(0);
return o->call(callData);
}
ReturnedValue FunctionPrototype::method_call(SimpleCallContext *ctx)
{
Scope scope(ctx);
- Value thisArg = ctx->argument(0);
FunctionObject *o = ctx->thisObject.asFunctionObject();
if (!o)
@@ -347,24 +346,23 @@ ReturnedValue FunctionPrototype::method_call(SimpleCallContext *ctx)
std::copy(ctx->arguments + 1,
ctx->arguments + ctx->argumentCount, callData->args);
}
- callData->thisObject = thisArg;
+ callData->thisObject = ctx->argument(0);
return o->call(callData);
}
ReturnedValue FunctionPrototype::method_bind(SimpleCallContext *ctx)
{
- FunctionObject *target = ctx->thisObject.asFunctionObject();
+ Scope scope(ctx);
+ Scoped<FunctionObject> target(scope, ctx->thisObject);
if (!target)
ctx->throwTypeError();
- Value boundThis = ctx->argument(0);
+ ScopedValue boundThis(scope, ctx->argument(0));
QVector<Value> boundArgs;
for (uint i = 1; i < ctx->argumentCount; ++i)
- boundArgs += ctx->argument(i);
+ boundArgs += ctx->arguments[i];
-
- BoundFunction *f = ctx->engine->newBoundFunction(ctx->engine->rootContext, target, boundThis, boundArgs);
- return Value::fromObject(f).asReturnedValue();
+ return ctx->engine->newBoundFunction(ctx->engine->rootContext, target.getPointer(), boundThis, boundArgs)->asReturnedValue();
}
@@ -411,19 +409,19 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
{
- ScriptFunction *f = static_cast<ScriptFunction *>(that);
- ExecutionEngine *v4 = f->engine();
+ ExecutionEngine *v4 = that->engine();
Scope scope(v4);
+ Scoped<ScriptFunction> f(scope, static_cast<ScriptFunction *>(that));
InternalClass *ic = v4->objectClass;
Value proto = f->memberData[Index_Prototype].value;
if (proto.isObject())
ic = v4->emptyClass->changePrototype(proto.objectValue());
- Object *obj = v4->newObject(ic);
+ Scoped<Object> obj(scope, v4->newObject(ic));
ExecutionContext *context = v4->current;
- callData->thisObject = Value::fromObject(obj);
- ExecutionContext *ctx = context->newCallContext(f, callData);
+ callData->thisObject = obj.asValue();
+ ExecutionContext *ctx = context->newCallContext(f.getPointer(), callData);
ScopedValue result(scope);
SAVE_JS_STACK(f->scope);
@@ -438,7 +436,7 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
if (result->isObject())
return result.asReturnedValue();
- return Value::fromObject(obj).asReturnedValue();
+ return obj.asReturnedValue();
}
ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
@@ -507,35 +505,32 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu
ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
{
- SimpleScriptFunction *f = static_cast<SimpleScriptFunction *>(that);
- ExecutionEngine *v4 = f->engine();
+ ExecutionEngine *v4 = that->engine();
Scope scope(v4);
+ Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that));
InternalClass *ic = v4->objectClass;
- Value proto = f->memberData[Index_Prototype].value;
- if (proto.isObject())
- ic = v4->emptyClass->changePrototype(proto.objectValue());
- Object *obj = v4->newObject(ic);
+ Scoped<Object> proto(scope, f->memberData[Index_Prototype].value);
+ if (!!proto)
+ ic = v4->emptyClass->changePrototype(proto.getPointer());
+ Scoped<Object> obj(scope, v4->newObject(ic));
ExecutionContext *context = v4->current;
void *stackSpace = alloca(requiredMemoryForExecutionContectSimple(f));
- callData->thisObject = Value::fromObject(obj);
- ExecutionContext *ctx = context->newCallContext(stackSpace, f, callData);
+ callData->thisObject = obj;
+ ExecutionContext *ctx = context->newCallContext(stackSpace, f.getPointer(), callData);
- ScopedValue result(scope);
- SAVE_JS_STACK(f->scope);
try {
- result = f->function->code(ctx, f->function->codeData);
+ Scoped<Object> result(scope, f->function->code(ctx, f->function->codeData));
+ ctx->engine->popContext();
+
+ if (!result)
+ return obj.asReturnedValue();
+ return result.asReturnedValue();
} catch (Exception &ex) {
ex.partiallyUnwindContext(context);
throw;
}
- CHECK_JS_STACK(f->scope);
- ctx->engine->popContext();
-
- if (result->isObject())
- return result.asReturnedValue();
- return Value::fromObject(obj).asReturnedValue();
}
ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
@@ -598,7 +593,7 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context?
ctx.thisObject = callData->thisObject;
// ### const_cast
- ctx.arguments = const_cast<Value *>(callData->args);
+ ctx.arguments = const_cast<SafeValue *>(callData->args);
ctx.argumentCount = callData->argc;
v4->pushContext(&ctx);
@@ -626,7 +621,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
ctx.strictMode = f->scope->strictMode; // ### needed? scope or parent context?
ctx.thisObject = callData->thisObject;
// ### const_cast
- ctx.arguments = const_cast<Value *>(callData->args);
+ ctx.arguments = const_cast<SafeValue *>(callData->args);
ctx.argumentCount = callData->argc;
v4->pushContext(&ctx);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 333b95ad74..a0f4cf9463 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -142,6 +142,11 @@ protected:
{ static_cast<FunctionObject*>(that)->~FunctionObject(); }
};
+template<>
+inline FunctionObject *value_cast(const Value &v) {
+ return v.asFunctionObject();
+}
+
struct FunctionCtor: FunctionObject
{
Q_MANAGED
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 096187d91f..389468cc39 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -105,6 +105,11 @@ struct QObjectWrapper;
// will return it in a register on all platforms.
// It will be returned in rax on x64, [eax,edx] on x86 and [r0,r1] on arm
typedef quint64 ReturnedValue;
+template<typename T> struct Scoped;
+template<typename T> struct Returned;
+struct CallData;
+struct ScopedValue;
+struct ValueRef;
namespace Global {
enum {
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index e0cbee11ca..9ec70f59be 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -444,7 +444,7 @@ ReturnedValue EvalFunction::call(Managed *that, CallData *callData)
{
// indirect call
// ### const_cast
- return static_cast<EvalFunction *>(that)->evalCall(callData->thisObject, const_cast<Value *>(callData->args), callData->argc, false);
+ return static_cast<EvalFunction *>(that)->evalCall(callData->thisObject, const_cast<Value *>(static_cast<const Value *>(callData->args)), callData->argc, false);
}
@@ -465,14 +465,15 @@ static inline int toInt(const QChar &qc, int R)
}
// parseInt [15.1.2.2]
-ReturnedValue GlobalFunctions::method_parseInt(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_parseInt(SimpleCallContext *ctx)
{
- Value string = context->argument(0);
- Value radix = context->argument(1);
- int R = radix.isUndefined() ? 0 : radix.toInt32();
+ Scope scope(ctx);
+ ScopedValue string(scope, ctx->argument(0));
+ ScopedValue radix(scope, ctx->argument(1));
+ int R = radix->isUndefined() ? 0 : radix->toInt32();
// [15.1.2.2] step by step:
- String *inputString = string.toString(context); // 1
+ String *inputString = string->toString(ctx); // 1
QString trimmed = inputString->toQString().trimmed(); // 2
const QChar *pos = trimmed.constData();
const QChar *end = pos + trimmed.length();
@@ -544,12 +545,12 @@ ReturnedValue GlobalFunctions::method_parseInt(SimpleCallContext *context)
}
// parseFloat [15.1.2.3]
-ReturnedValue GlobalFunctions::method_parseFloat(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_parseFloat(SimpleCallContext *ctx)
{
- Value string = context->argument(0);
+ Scope scope(ctx);
// [15.1.2.3] step by step:
- String *inputString = string.toString(context); // 1
+ Scoped<String> inputString(scope, ctx->argument(0), Scoped<String>::Convert);
QString trimmed = inputString->toQString().trimmed(); // 2
// 4:
@@ -570,24 +571,30 @@ ReturnedValue GlobalFunctions::method_parseFloat(SimpleCallContext *context)
}
/// isNaN [15.1.2.4]
-ReturnedValue GlobalFunctions::method_isNaN(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_isNaN(SimpleCallContext *ctx)
{
- const Value &v = context->argument(0);
- if (v.integerCompatible())
+ if (!ctx->argumentCount)
+ // undefined gets converted to NaN
+ return Encode(true);
+
+ if (ctx->arguments[0].integerCompatible())
return Encode(false);
- double d = v.toNumber();
+ double d = ctx->arguments[0].toNumber();
return Encode((bool)std::isnan(d));
}
/// isFinite [15.1.2.5]
-ReturnedValue GlobalFunctions::method_isFinite(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_isFinite(SimpleCallContext *ctx)
{
- const Value &v = context->argument(0);
- if (v.integerCompatible())
+ if (!ctx->argumentCount)
+ // undefined gets converted to NaN
+ return Encode(false);
+
+ if (ctx->arguments[0].integerCompatible())
return Encode(true);
- double d = v.toNumber();
+ double d = ctx->arguments[0].toNumber();
return Encode((bool)std::isfinite(d));
}
@@ -656,7 +663,7 @@ ReturnedValue GlobalFunctions::method_escape(SimpleCallContext *context)
if (!context->argumentCount)
return Value::fromString(context, QStringLiteral("undefined")).asReturnedValue();
- QString str = context->argument(0).toString(context)->toQString();
+ QString str = context->arguments[0].toString(context)->toQString();
return Value::fromString(context, escape(str)).asReturnedValue();
}
@@ -665,6 +672,6 @@ ReturnedValue GlobalFunctions::method_unescape(SimpleCallContext *context)
if (!context->argumentCount)
return Value::fromString(context, QStringLiteral("undefined")).asReturnedValue();
- QString str = context->argument(0).toString(context)->toQString();
+ QString str = context->arguments[0].toString(context)->toQString();
return Value::fromString(context, unescape(str)).asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index 90b3395baa..f49c8ebbb8 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -64,7 +64,7 @@ struct GlobalFunctions
static ReturnedValue method_parseInt(SimpleCallContext *context);
static ReturnedValue method_parseFloat(SimpleCallContext *context);
static ReturnedValue method_isNaN(SimpleCallContext *context);
- static ReturnedValue method_isFinite(SimpleCallContext *context);
+ static ReturnedValue method_isFinite(SimpleCallContext *ctx);
static ReturnedValue method_decodeURI(SimpleCallContext *context);
static ReturnedValue method_decodeURIComponent(SimpleCallContext *context);
static ReturnedValue method_encodeURI(SimpleCallContext *context);
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 740bb406f3..4d9573b990 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -84,9 +84,10 @@ QV4Include::~QV4Include()
QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status)
{
+ QV4::Scope scope(v4);
// XXX It seems inefficient to create this object from scratch each time.
- QV4::Object *o = v4->newObject();
+ QV4::Scoped<QV4::Object> o(scope, v4->newObject());
o->put(v4->newString("OK"), QV4::Value::fromInt32(Ok));
o->put(v4->newString("LOADING"), QV4::Value::fromInt32(Loading));
o->put(v4->newString("NETWORK_ERROR"), QV4::Value::fromInt32(NetworkError));
@@ -94,7 +95,7 @@ QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4, Status stat
o->put(v4->newString("status"), QV4::Value::fromInt32(status));
- return QV4::Value::fromObject(o).asReturnedValue();
+ return o.asReturnedValue();
}
void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 2bb755b537..aa6b261928 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -713,13 +713,12 @@ QString Stringify::Str(const QString &key, Value value)
}
if (replacerFunction) {
- Object *holder = ctx->engine->newObject();
- Value holderValue = Value::fromObject(holder);
+ Scoped<Object> holder(scope, ctx->engine->newObject());
holder->put(ctx, QString(), value);
ScopedCallData callData(scope, 2);
callData->args[0] = Value::fromString(ctx, key);
callData->args[1] = value;
- callData->thisObject = holderValue;
+ callData->thisObject = holder;
value = Value::fromReturnedValue(replacerFunction->call(callData));
}
@@ -878,12 +877,14 @@ JsonObject::JsonObject(ExecutionContext *context)
ReturnedValue JsonObject::method_parse(SimpleCallContext *ctx)
{
- QString jtext = ctx->argument(0).toString(ctx)->toQString();
+ Scope scope(ctx);
+ ScopedValue v(scope, ctx->argument(0));
+ QString jtext = v->toString(ctx)->toQString();
DEBUG << "parsing source = " << jtext;
JsonParser parser(ctx, jtext.constData(), jtext.length());
QJsonParseError error;
- Value result = parser.parse(&error);
+ ScopedValue result(scope, parser.parse(&error));
if (error.error != QJsonParseError::NoError) {
DEBUG << "parse error" << error.errorString();
ctx->throwSyntaxError("JSON.parse: Parse error");
@@ -898,7 +899,7 @@ ReturnedValue JsonObject::method_stringify(SimpleCallContext *ctx)
Stringify stringify(ctx);
- Object *o = ctx->argument(1).asObject();
+ Scoped<Object> o(scope, ctx->argument(1));
if (o) {
stringify.replacerFunction = o->asFunctionObject();
if (o->isArrayObject()) {
@@ -917,20 +918,21 @@ ReturnedValue JsonObject::method_stringify(SimpleCallContext *ctx)
}
}
- Value s = ctx->argument(2);
- if (NumberObject *n = s.asNumberObject())
+ ScopedValue s(scope, ctx->argument(2));
+ if (NumberObject *n = s->asNumberObject())
s = n->value;
- else if (StringObject *so = s.asStringObject())
+ else if (StringObject *so = s->asStringObject())
s = so->value;
- if (s.isNumber()) {
- stringify.gap = QString(qMin(10, (int)s.toInteger()), ' ');
- } else if (s.isString()) {
- stringify.gap = s.stringValue()->toQString().left(10);
+ if (s->isNumber()) {
+ stringify.gap = QString(qMin(10, (int)s->toInteger()), ' ');
+ } else if (s->isString()) {
+ stringify.gap = s->stringValue()->toQString().left(10);
}
- QString result = stringify.Str(QString(), ctx->argument(0));
+ ScopedValue arg0(scope, ctx->argument(0));
+ QString result = stringify.Str(QString(), arg0);
if (result.isEmpty())
return Encode::undefined();
return Value::fromString(ctx, result).asReturnedValue();
@@ -978,7 +980,7 @@ QJsonValue JsonObject::toJsonValue(const QV4::Value &value,
QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object)
{
Scope scope(engine);
- Scoped<Object> o(scope, Value::fromObject(engine->newObject()));
+ Scoped<Object> o(scope, engine->newObject());
for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it)
o->put(engine->newString(it.key()), Value::fromReturnedValue(fromJsonValue(engine, it.value())));
return o.asReturnedValue();
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index f13f699748..4c1675ef88 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -89,21 +89,6 @@ struct GCDeletable
bool lastCall;
};
-struct CallData
-{
- // below is to be compatible with Value. Initialize tag to 0
-#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
- uint tag;
-#endif
- int argc;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- uint tag;
-#endif
-
- Value thisObject;
- Value args[1];
-};
-
struct ManagedVTable
{
ReturnedValue (*call)(Managed *, CallData *data);
@@ -245,14 +230,8 @@ public:
return vtbl == &T::static_vtbl ? static_cast<const T *>(this) : 0;
}
- template<typename T>
- static T *cast(const Value &v) {
- return v.as<T>();
- }
- static Managed *cast(const Value &v) {
- return v.asManaged();
- }
-
+ String *asString() { return type == Type_String ? reinterpret_cast<String *>(this) : 0; }
+ Object *asObject() { return type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
FunctionObject *asFunctionObject() { return type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
BooleanObject *asBooleanObject() { return type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
@@ -353,6 +332,34 @@ private:
friend struct ObjectIterator;
};
+template<>
+inline Managed *value_cast(const Value &v) {
+ return v.asManaged();
+}
+
+template<typename T>
+inline T *managed_cast(Managed *m)
+{
+ return m->as<T>();
+}
+
+template<>
+inline String *managed_cast(Managed *m)
+{
+ return m->asString();
+}
+template<>
+inline Object *managed_cast(Managed *m)
+{
+ return m->asObject();
+}
+template<>
+inline FunctionObject *managed_cast(Managed *m)
+{
+ return m->asFunctionObject();
+}
+
+
inline ReturnedValue Managed::construct(CallData *d) {
return vtbl->construct(this, d);
}
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index 2d53fa3fe5..a7e485a2a2 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -340,7 +340,7 @@ std::size_t MemoryManager::sweep(bool lastSweep)
}
if (Managed *m = weak->value.asManaged()) {
if (!m->markBit) {
- weak->value = Value::emptyValue();
+ weak->value = Value::undefinedValue();
PersistentValuePrivate *n = weak->next;
weak->removeFromList();
weak = n;
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 3702428553..b9b64cf534 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -110,9 +110,8 @@ ReturnedValue NumberPrototype::method_toString(SimpleCallContext *ctx)
{
double num = thisNumberValue(ctx).asDouble();
- Value arg = ctx->argument(0);
- if (!arg.isUndefined()) {
- int radix = arg.toInt32();
+ if (ctx->argumentCount && !ctx->arguments[0].isUndefined()) {
+ int radix = ctx->arguments[0].toInt32();
if (radix < 2 || radix > 36) {
ctx->throwError(QString::fromLatin1("Number.prototype.toString: %0 is not a valid radix")
.arg(radix));
@@ -180,7 +179,7 @@ ReturnedValue NumberPrototype::method_toFixed(SimpleCallContext *ctx)
double fdigits = 0;
if (ctx->argumentCount > 0)
- fdigits = ctx->argument(0).toInteger();
+ fdigits = ctx->arguments[0].toInteger();
if (std::isnan(fdigits))
fdigits = 0;
@@ -204,11 +203,10 @@ ReturnedValue NumberPrototype::method_toExponential(SimpleCallContext *ctx)
{
double d = thisNumberValue(ctx).asDouble();
- Value fraction = ctx->argument(0);
int fdigits = -1;
- if (!fraction.isUndefined()) {
- int fdigits = ctx->argument(0).toInt32();
+ if (ctx->argumentCount && !ctx->arguments[0].isUndefined()) {
+ int fdigits = ctx->arguments[0].toInt32();
if (fdigits < 0 || fdigits > 20) {
String *error = ctx->engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range"));
ctx->throwRangeError(Value::fromString(error));
@@ -229,11 +227,10 @@ ReturnedValue NumberPrototype::method_toPrecision(SimpleCallContext *ctx)
ScopedValue v(scope, thisNumberValue(ctx));
- Value prec = ctx->argument(0);
- if (prec.isUndefined())
+ if (!ctx->argumentCount || ctx->arguments[0].isUndefined())
return __qmljs_to_string(v, ctx);
- double precision = prec.toInt32();
+ double precision = ctx->arguments[0].toInt32();
if (precision < 1 || precision > 21) {
String *error = ctx->engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range"));
ctx->throwRangeError(Value::fromString(error));
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 7cb3fe45c2..83c7d864ff 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -178,10 +178,6 @@ struct Q_QML_EXPORT Object: Managed {
inline ExecutionEngine *engine() const { return internalClass->engine; }
- static Object *cast(const Value &v) {
- return v.asObject();
- }
-
// Array handling
uint allocArrayValue() {
@@ -464,6 +460,17 @@ inline void Object::arraySet(uint index, const Property *pd)
*arrayInsert(index) = *pd;
}
+template<>
+inline Object *value_cast(const Value &v) {
+ return v.asObject();
+}
+
+template<>
+inline ReturnedValue value_convert<Object>(ExecutionContext *ctx, const Value &v)
+{
+ return v.toObject(ctx)->asReturnedValue();
+}
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 073d588e56..82215e4fc5 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -85,11 +85,11 @@ ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
Scope scope(v4);
ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) {
- Object *obj = v4->newObject();
+ Scoped<Object> obj(scope, v4->newObject());
Scoped<Object> proto(scope, ctor->get(v4->id_prototype));
if (!!proto)
obj->setPrototype(proto.getPointer());
- return Value::fromObject(obj).asReturnedValue();
+ return obj.asReturnedValue();
}
return Value::fromReturnedValue(__qmljs_to_object(v4->current, ValueRef(&callData->args[0]))).asReturnedValue();
}
@@ -97,7 +97,7 @@ ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
{
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull())
- return Value::fromObject(m->engine()->newObject()).asReturnedValue();
+ return m->engine()->newObject()->asReturnedValue();
return __qmljs_to_object(m->engine()->current, ValueRef(&callData->args[0]));
}
@@ -137,23 +137,26 @@ void ObjectPrototype::init(ExecutionContext *ctx, const Value &ctor)
ReturnedValue ObjectPrototype::method_getPrototypeOf(SimpleCallContext *ctx)
{
- Value o = ctx->argument(0);
- if (! o.isObject())
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
ctx->throwTypeError();
- Object *p = o.objectValue()->prototype();
- return p ? Value::fromObject(p).asReturnedValue() : Encode::null();
+ Scoped<Object> p(scope, o->prototype());
+ return !!p ? p->asReturnedValue() : Encode::null();
}
ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext *ctx)
{
- Value O = ctx->argument(0);
- if (!O.isObject())
+ Scope scope(ctx);
+ Scoped<Object> O(scope, ctx->argument(0));
+ if (!O)
ctx->throwTypeError();
- String *name = ctx->argument(1).toString(ctx);
+ ScopedValue v(scope, ctx->argument(1));
+ Scoped<String> name(scope, v->toString(ctx));
PropertyAttributes attrs;
- Property *desc = O.objectValue()->__getOwnProperty__(name, &attrs);
+ Property *desc = O->__getOwnProperty__(name.getPointer(), &attrs);
return fromPropertyDescriptor(ctx, desc, attrs);
}
@@ -169,36 +172,37 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyNames(SimpleCallContext *con
ReturnedValue ObjectPrototype::method_create(SimpleCallContext *ctx)
{
- Value O = ctx->argument(0);
- if (!O.isObject() && !O.isNull())
+ Scope scope(ctx);
+ ScopedValue O(scope, ctx->argument(0));
+ if (!O->isObject() && !O->isNull())
ctx->throwTypeError();
- Object *newObject = ctx->engine->newObject();
- newObject->setPrototype(O.asObject());
+ Scoped<Object> newObject(scope, ctx->engine->newObject());
+ newObject->setPrototype(O->asObject());
- Value objValue = Value::fromObject(newObject);
- if (ctx->argumentCount > 1 && !ctx->argument(1).isUndefined()) {
- ctx->arguments[0] = objValue;
- method_defineProperties(ctx);
+ if (ctx->argumentCount > 1 && !ctx->arguments[1].isUndefined()) {
+ ctx->arguments[0] = newObject.asValue();
+ return method_defineProperties(ctx);
}
- return objValue.asReturnedValue();
+ return newObject.asReturnedValue();
}
ReturnedValue ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
{
- Value O = ctx->argument(0);
- if (!O.isObject())
+ Scope scope(ctx);
+ Scoped<Object> O(scope, ctx->argument(0));
+ if (!O)
ctx->throwTypeError();
- String *name = ctx->argument(1).toString(ctx);
+ Scoped<String> name(scope, ctx->argument(1), Scoped<String>::Convert);
- Value attributes = ctx->argument(2);
+ ScopedValue attributes(scope, ctx->argument(2));
Property pd;
PropertyAttributes attrs;
toPropertyDescriptor(ctx, attributes, &pd, &attrs);
- if (!O.objectValue()->__defineOwnProperty__(ctx, name, pd, attrs))
+ if (!O->__defineOwnProperty__(ctx, name.getPointer(), pd, attrs))
ctx->throwTypeError();
return O.asReturnedValue();
@@ -206,13 +210,14 @@ ReturnedValue ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
{
- Value O = ctx->argument(0);
- if (!O.isObject())
+ Scope scope(ctx);
+ Scoped<Object> O(scope, ctx->argument(0));
+ if (!O)
ctx->throwTypeError();
- Object *o = ctx->argument(1).toObject(ctx);
+ Scoped<Object> o(scope, ctx->argument(1), Scoped<Object>::Convert);
- ObjectIterator it(o, ObjectIterator::EnumerableOnly);
+ ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly);
while (1) {
uint index;
String *name;
@@ -225,9 +230,9 @@ ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
toPropertyDescriptor(ctx, Value::fromReturnedValue(o->getValue(pd, attrs)), &n, &nattrs);
bool ok;
if (name)
- ok = O.objectValue()->__defineOwnProperty__(ctx, name, n, nattrs);
+ ok = O->__defineOwnProperty__(ctx, name, n, nattrs);
else
- ok = O.objectValue()->__defineOwnProperty__(ctx, index, n, nattrs);
+ ok = O->__defineOwnProperty__(ctx, index, n, nattrs);
if (!ok)
ctx->throwTypeError();
}
@@ -237,10 +242,11 @@ ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
ReturnedValue ObjectPrototype::method_seal(SimpleCallContext *ctx)
{
- if (!ctx->argument(0).isObject())
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
ctx->throwTypeError();
- Object *o = ctx->argument(0).objectValue();
o->extensible = false;
o->internalClass = o->internalClass->sealed();
@@ -251,15 +257,16 @@ ReturnedValue ObjectPrototype::method_seal(SimpleCallContext *ctx)
o->arrayAttributes[i].setConfigurable(false);
}
- return ctx->argument(0).asReturnedValue();
+ return o.asReturnedValue();
}
ReturnedValue ObjectPrototype::method_freeze(SimpleCallContext *ctx)
{
- if (!ctx->argument(0).isObject())
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
ctx->throwTypeError();
- Object *o = ctx->argument(0).objectValue();
o->extensible = false;
o->internalClass = o->internalClass->frozen();
@@ -271,25 +278,27 @@ ReturnedValue ObjectPrototype::method_freeze(SimpleCallContext *ctx)
if (o->arrayAttributes[i].isData())
o->arrayAttributes[i].setWritable(false);
}
- return ctx->argument(0).asReturnedValue();
+ return o.asReturnedValue();
}
ReturnedValue ObjectPrototype::method_preventExtensions(SimpleCallContext *ctx)
{
- if (!ctx->argument(0).isObject())
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
ctx->throwTypeError();
- Object *o = ctx->argument(0).objectValue();
o->extensible = false;
- return ctx->argument(0).asReturnedValue();
+ return o.asReturnedValue();
}
ReturnedValue ObjectPrototype::method_isSealed(SimpleCallContext *ctx)
{
- if (!ctx->argument(0).isObject())
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
ctx->throwTypeError();
- Object *o = ctx->argument(0).objectValue();
if (o->extensible)
return Encode(false);
@@ -313,10 +322,11 @@ ReturnedValue ObjectPrototype::method_isSealed(SimpleCallContext *ctx)
ReturnedValue ObjectPrototype::method_isFrozen(SimpleCallContext *ctx)
{
- if (!ctx->argument(0).isObject())
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
ctx->throwTypeError();
- Object *o = ctx->argument(0).objectValue();
if (o->extensible)
return Encode(false);
@@ -340,24 +350,24 @@ ReturnedValue ObjectPrototype::method_isFrozen(SimpleCallContext *ctx)
ReturnedValue ObjectPrototype::method_isExtensible(SimpleCallContext *ctx)
{
- if (!ctx->argument(0).isObject())
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
ctx->throwTypeError();
- Object *o = ctx->argument(0).objectValue();
return Encode((bool)o->extensible);
}
ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx)
{
- if (!ctx->argument(0).isObject())
- ctx->throwTypeError();
-
Scope scope(ctx);
- Object *o = ctx->argument(0).objectValue();
+ Scoped<Object> o(scope, ctx->argument(0));
+ if (!o)
+ ctx->throwTypeError();
Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
- ObjectIterator it(o, ObjectIterator::EnumerableOnly);
+ ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly);
ScopedValue name(scope);
while (1) {
name = it.nextPropertyNameAsString();
@@ -401,24 +411,26 @@ ReturnedValue ObjectPrototype::method_valueOf(SimpleCallContext *ctx)
ReturnedValue ObjectPrototype::method_hasOwnProperty(SimpleCallContext *ctx)
{
- String *P = ctx->argument(0).toString(ctx);
- Object *O = ctx->thisObject.toObject(ctx);
- bool r = O->__getOwnProperty__(P) != 0;
+ Scope scope(ctx);
+ Scoped<String> P(scope, ctx->argument(0), Scoped<String>::Convert);
+ Scoped<Object> O(scope, ctx->thisObject, Scoped<Object>::Convert);
+ bool r = O->__getOwnProperty__(P.getPointer()) != 0;
if (!r)
- r = !O->query(P).isEmpty();
+ r = !O->query(P.getPointer()).isEmpty();
return Encode(r);
}
ReturnedValue ObjectPrototype::method_isPrototypeOf(SimpleCallContext *ctx)
{
- Value V = ctx->argument(0);
- if (! V.isObject())
+ Scope scope(ctx);
+ Scoped<Object> V(scope, ctx->argument(0));
+ if (!V)
return Encode(false);
- Object *O = ctx->thisObject.toObject(ctx);
- Object *proto = V.objectValue()->prototype();
+ Scoped<Object> O(scope, ctx->thisObject, Scoped<Object>::Convert);
+ Scoped<Object> proto(scope, V->prototype());
while (proto) {
- if (O == proto)
+ if (O.getPointer() == proto.getPointer())
return Encode(true);
proto = proto->prototype();
}
@@ -427,11 +439,12 @@ ReturnedValue ObjectPrototype::method_isPrototypeOf(SimpleCallContext *ctx)
ReturnedValue ObjectPrototype::method_propertyIsEnumerable(SimpleCallContext *ctx)
{
- String *p = ctx->argument(0).toString(ctx);
+ Scope scope(ctx);
+ Scoped<String> p(scope, ctx->argument(0), Scoped<String>::Convert);
- Object *o = ctx->thisObject.toObject(ctx);
+ Scoped<Object> o(scope, ctx->thisObject, Scoped<Object>::Convert);
PropertyAttributes attrs;
- o->__getOwnProperty__(p, &attrs);
+ o->__getOwnProperty__(p.getPointer(), &attrs);
return Encode(attrs.isEnumerable());
}
@@ -439,21 +452,23 @@ ReturnedValue ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
ctx->throwTypeError();
- String *prop = ctx->argument(0).toString(ctx);
- FunctionObject *f = ctx->argument(1).asFunctionObject();
+ Scope scope(ctx);
+ Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
+
+ Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
ctx->throwTypeError();
- Object *o = ctx->thisObject.asObject();
+ Scoped<Object> o(scope, ctx->thisObject);
if (!o) {
if (!ctx->thisObject.isUndefined())
return Encode::undefined();
o = ctx->engine->globalObject;
}
- Property pd = Property::fromAccessor(f, 0);
- o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
+ Property pd = Property::fromAccessor(f.getPointer(), 0);
+ o->__defineOwnProperty__(ctx, prop.getPointer(), pd, Attr_Accessor);
return Encode::undefined();
}
@@ -461,21 +476,23 @@ ReturnedValue ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
ctx->throwTypeError();
- String *prop = ctx->argument(0).toString(ctx);
- FunctionObject *f = ctx->argument(1).asFunctionObject();
+ Scope scope(ctx);
+ Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
+
+ Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
ctx->throwTypeError();
- Object *o = ctx->thisObject.asObject();
+ Scoped<Object> o(scope, ctx->thisObject);
if (!o) {
if (!ctx->thisObject.isUndefined())
return Encode::undefined();
o = ctx->engine->globalObject;
}
- Property pd = Property::fromAccessor(0, f);
- o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
+ Property pd = Property::fromAccessor(0, f.getPointer());
+ o->__defineOwnProperty__(ctx, prop.getPointer(), pd, Attr_Accessor);
return Encode::undefined();
}
@@ -490,20 +507,23 @@ ReturnedValue ObjectPrototype::method_get_proto(SimpleCallContext *ctx)
ReturnedValue ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
{
- Object *o = ctx->thisObject.asObject();
- if (!o)
+ Scope scope(ctx);
+ Scoped<Object> o(scope, ctx->thisObject);
+ if (!o || !ctx->argumentCount)
ctx->throwTypeError();
- Value proto = ctx->argument(0);
- bool ok = false;
- if (proto.isNull()) {
+ if (ctx->arguments[0].isNull()) {
o->setPrototype(0);
- ok = true;
- } else if (Object *p = proto.asObject()) {
- if (o->prototype() == p) {
+ return Encode::undefined();
+ }
+
+ Scoped<Object> p(scope, ctx->arguments[0]);
+ bool ok = false;
+ if (!!p) {
+ if (o->prototype() == p.getPointer()) {
ok = true;
} else if (o->extensible) {
- ok = o->setPrototype(p);
+ ok = o->setPrototype(p.getPointer());
}
}
if (!ok)
@@ -532,6 +552,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (o->__hasProperty__(ctx->engine->id_get)) {
ScopedValue get(scope, o->get(ctx->engine->id_get));
FunctionObject *f = get->asFunctionObject();
+ qDebug() << "get" << (void *)get.asReturnedValue() << f;
if (f) {
desc->setGetter(f);
} else if (get->isUndefined()) {
@@ -581,8 +602,9 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con
return Encode::undefined();
ExecutionEngine *engine = ctx->engine;
+ Scope scope(engine);
// Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
- Object *o = engine->newObject();
+ Scoped<Object> o(scope, engine->newObject());
Property pd;
if (attrs.isData()) {
@@ -601,7 +623,7 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con
pd.value = Value::fromBoolean(attrs.isConfigurable());
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("configurable")), pd, Attr_Data);
- return Value::fromObject(o).asReturnedValue();
+ return o.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 2bd201e2a1..446ea9df3a 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1196,8 +1196,9 @@ void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const ValueRef
ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, const QV4::Value *args, int classId)
{
+ Scope scope(ctx);
QV4::InternalClass *klass = ctx->compilationUnit->runtimeClasses[classId];
- Object *o = ctx->engine->newObject(klass);
+ Scoped<Object> o(scope, ctx->engine->newObject(klass));
for (int i = 0; i < klass->size; ++i) {
if (klass->propertyData[i].isData())
@@ -1210,7 +1211,7 @@ ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx,
}
}
- return Value::fromObject(o).asReturnedValue();
+ return o.asReturnedValue();
}
QV4::ReturnedValue __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx)
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 1e05b6170c..711c79eb1d 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -51,32 +51,6 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct ScopedValueArray {
- ScopedValueArray(ExecutionEngine *e, int size)
- : engine(e)
-#ifndef QT_NO_DEBUG
- , size(size)
-#endif
- {
- ptr = e->stackPush(size);
- }
-
- ~ScopedValueArray() {
-#ifndef QT_NO_DEBUG
- engine->stackPop(size);
- Q_ASSERT(engine->jsStackTop == ptr);
-#else
- engine->jsStackTop = ptr;
-#endif
- }
-
- ExecutionEngine *engine;
-#ifndef QT_NO_DEBUG
- int size;
-#endif
- Value *ptr;
-};
-
struct ScopedValue;
struct Scope {
@@ -189,6 +163,9 @@ struct ScopedValue
template<typename T>
struct Scoped
{
+ enum _Convert { Convert };
+ enum _Cast { Cast };
+
inline void setPointer(Managed *p) {
#if QT_POINTER_SIZE == 8
ptr->val = (quint64)p;
@@ -209,7 +186,24 @@ struct Scoped
Scoped(const Scope &scope, const Value &v)
{
ptr = scope.engine->jsStackTop++;
- setPointer(T::cast(v));
+ setPointer(value_cast<T>(v));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+ Scoped(const Scope &scope, const ScopedValue &v)
+ {
+ ptr = scope.engine->jsStackTop++;
+ setPointer(value_cast<T>(*v.ptr));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+
+ Scoped(const Scope &scope, const Value &v, _Convert)
+ {
+ ptr = scope.engine->jsStackTop++;
+ ptr->val = value_convert<T>(scope.engine->current, v);
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -226,6 +220,16 @@ struct Scoped
#endif
}
template<typename X>
+ Scoped(const Scope &scope, X *t, _Cast)
+ {
+ ptr = scope.engine->jsStackTop++;
+ setPointer(managed_cast<T>(t));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+
+ template<typename X>
Scoped(const Scope &scope, Returned<X> *x)
{
ptr = scope.engine->jsStackTop++;
@@ -238,21 +242,29 @@ struct Scoped
Scoped(const Scope &scope, const ReturnedValue &v)
{
ptr = scope.engine->jsStackTop++;
- setPointer(T::cast(QV4::Value::fromReturnedValue(v)));
+ setPointer(value_cast<T>(QV4::Value::fromReturnedValue(v)));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+ Scoped(const Scope &scope, const ReturnedValue &v, _Convert)
+ {
+ ptr = scope.engine->jsStackTop++;
+ ptr->val = value_convert<T>(scope.engine->current, QV4::Value::fromReturnedValue(v));
#ifndef QT_NO_DEBUG
++scope.size;
#endif
}
Scoped<T> &operator=(const Value &v) {
- setPointer(T::cast(v));
+ setPointer(value_cast<T>(v));
return *this;
}
Scoped<T> &operator=(const ValueRef &v);
Scoped<T> &operator=(const ReturnedValue &v) {
- setPointer(T::cast(QV4::Value::fromReturnedValue(v)));
+ setPointer(value_cast<T>(QV4::Value::fromReturnedValue(v)));
return *this;
}
@@ -280,7 +292,7 @@ struct Scoped
bool operator!() const {
return !ptr->managed();
}
- operator bool() const {
+ operator void *() const {
return ptr->managed();
}
@@ -307,6 +319,21 @@ struct Scoped
Value *ptr;
};
+struct CallData
+{
+ // below is to be compatible with Value. Initialize tag to 0
+#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
+ uint tag;
+#endif
+ int argc;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ uint tag;
+#endif
+
+ SafeValue thisObject;
+ SafeValue args[1];
+};
+
struct ScopedCallData {
ScopedCallData(Scope &scope, int argc)
{
@@ -388,7 +415,7 @@ template<typename T>
inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v)
{
ptr = scope.engine->jsStackTop++;
- setPointer(T::cast(*v.operator ->()));
+ setPointer(value_cast<T>(*v.operator ->()));
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -397,11 +424,10 @@ inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v)
template<typename T>
inline Scoped<T> &Scoped<T>::operator=(const ValueRef &v)
{
- setPointer(T::cast(*v.operator ->()));
+ setPointer(value_cast<T>(*v.operator ->()));
return *this;
}
-
struct CallDataRef {
CallDataRef(const ScopedCallData &c)
: ptr(c.ptr) {}
@@ -474,6 +500,70 @@ struct Encode : private Value {
}
};
+inline SafeValue &SafeValue::operator =(const ScopedValue &v)
+{
+ val = v.ptr->val;
+ return *this;
+}
+
+template<typename T>
+inline SafeValue &SafeValue::operator=(Returned<T> *t)
+{
+ val = t->getPointer()->asReturnedValue();
+ return *this;
+}
+
+template<typename T>
+inline SafeValue &SafeValue::operator=(const Scoped<T> &t)
+{
+ val = t.ptr->val;
+ return *this;
+}
+
+template<typename T>
+inline Returned<T> *SafeValue::as()
+{
+ return Returned<T>::create(value_cast<T>(*this));
+}
+
+template<typename T>
+PersistentValue::PersistentValue(Returned<T> *obj)
+ : d(new PersistentValuePrivate(QV4::Value::fromManaged(obj->getPointer())))
+{
+}
+
+template<typename T>
+inline PersistentValue::PersistentValue(const Scoped<T> &obj)
+ : d(new PersistentValuePrivate(*obj.ptr))
+{
+}
+
+template<typename T>
+inline PersistentValue &PersistentValue::operator=(Returned<T> *obj)
+{
+ return operator=(QV4::Value::fromManaged(obj->getPointer()).asReturnedValue());
+}
+
+template<typename T>
+inline PersistentValue &PersistentValue::operator=(const Scoped<T> &obj)
+{
+ return operator=(*obj.ptr);
+}
+
+
+template<typename T>
+inline WeakValue::WeakValue(Returned<T> *obj)
+ : d(new PersistentValuePrivate(QV4::Value::fromManaged(obj->getPointer()), /*engine*/0, /*weak*/true))
+{
+}
+
+template<typename T>
+inline WeakValue &WeakValue::operator=(Returned<T> *obj)
+{
+ return operator=(QV4::Value::fromManaged(obj->getPointer()).asReturnedValue());
+}
+
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index 41481ac1b8..35022acfd5 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -328,7 +328,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
case WorkerObject:
{
quint32 size = headersize(header);
- QV4::Object *o = v4->newObject();
+ Scoped<Object> o(scope, v4->newObject());
ScopedValue name(scope);
ScopedValue value(scope);
for (quint32 ii = 0; ii < size; ++ii) {
@@ -336,7 +336,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
value = deserialize(data, engine);
o->put(name->asString(), value);
}
- return QV4::Value::fromObject(o).asReturnedValue();
+ return o.asReturnedValue();
}
case WorkerInt32:
return QV4::Encode((qint32)popUint32(data));
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 7dd912a41f..7ad428a502 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -120,10 +120,6 @@ struct Q_QML_EXPORT String : public Managed {
return _text.length();
}
- static String *cast(const Value &v) {
- return v.asString();
- }
-
QString _text;
mutable Identifier *identifier;
mutable uint stringHash;
@@ -142,6 +138,17 @@ protected:
static bool isEqualTo(Managed *that, Managed *o);
};
+template<>
+inline String *value_cast(const Value &v) {
+ return v.asString();
+}
+
+template<>
+inline ReturnedValue value_convert<String>(ExecutionContext *ctx, const Value &v)
+{
+ return v.toString(ctx)->asReturnedValue();
+}
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 811c5b26b9..afd6e440dc 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -472,8 +472,8 @@ ReturnedValue StringPrototype::method_replace(SimpleCallContext *ctx)
uint *matchOffsets = _matchOffsets;
uint nMatchOffsets = 0;
- Value searchValue = ctx->argument(0);
- RegExpObject *regExp = searchValue.as<RegExpObject>();
+ ScopedValue searchValue(scope, ctx->argument(0));
+ Scoped<RegExpObject> regExp(scope, searchValue);
if (regExp) {
uint offset = 0;
while (true) {
@@ -501,7 +501,7 @@ ReturnedValue StringPrototype::method_replace(SimpleCallContext *ctx)
numCaptures = regExp->value->captureCount();
} else {
numCaptures = 1;
- QString searchString = searchValue.toString(ctx)->toQString();
+ QString searchString = searchValue->toString(ctx)->toQString();
int idx = string.indexOf(searchString);
if (idx != -1) {
numStringMatches = 1;
@@ -512,9 +512,10 @@ ReturnedValue StringPrototype::method_replace(SimpleCallContext *ctx)
}
QString result;
- Value replaceValue = ctx->argument(1);
ScopedValue replacement(scope);
- if (FunctionObject* searchCallback = replaceValue.asFunctionObject()) {
+ ScopedValue replaceValue(scope, ctx->argument(1));
+ Scoped<FunctionObject> searchCallback(scope, replaceValue);
+ if (!!searchCallback) {
result.reserve(string.length() + 10*numStringMatches);
ScopedCallData callData(scope, numCaptures + 2);
callData->thisObject = Value::undefinedValue();
@@ -542,7 +543,7 @@ ReturnedValue StringPrototype::method_replace(SimpleCallContext *ctx)
}
result += string.midRef(lastEnd);
} else {
- QString newString = replaceValue.toString(ctx)->toQString();
+ QString newString = replaceValue->toString(ctx)->toQString();
result.reserve(string.length() + numStringMatches*newString.size());
int lastEnd = 0;
@@ -595,9 +596,9 @@ ReturnedValue StringPrototype::method_slice(SimpleCallContext *ctx)
const QString text = getThisString(ctx);
const double length = text.length();
- double start = ctx->argument(0).toInteger();
- double end = ctx->argument(1).isUndefined()
- ? length : ctx->argument(1).toInteger();
+ double start = ctx->argumentCount ? ctx->arguments[0].toInteger() : 0;
+ double end = (ctx->argumentCount < 2 || ctx->arguments[1].isUndefined())
+ ? length : ctx->arguments[1].toInteger();
if (start < 0)
start = qMax(length + start, 0.);
@@ -625,32 +626,33 @@ ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx)
else
text = ctx->thisObject.toString(ctx)->toQString();
- Value separatorValue = ctx->argumentCount > 0 ? ctx->argument(0) : Value::undefinedValue();
- Value limitValue = ctx->argumentCount > 1 ? ctx->argument(1) : Value::undefinedValue();
+ ScopedValue separatorValue(scope, ctx->argument(0));
+ ScopedValue limitValue(scope, ctx->argument(1));
Scoped<ArrayObject> array(scope, ctx->engine->newArrayObject());
- if (separatorValue.isUndefined()) {
- if (limitValue.isUndefined()) {
+ if (separatorValue->isUndefined()) {
+ if (limitValue->isUndefined()) {
array->push_back(Value::fromString(ctx, text));
return array.asReturnedValue();
}
- return Value::fromString(ctx, text.left(limitValue.toInteger())).asReturnedValue();
+ return Value::fromString(ctx, text.left(limitValue->toInteger())).asReturnedValue();
}
- uint limit = limitValue.isUndefined() ? UINT_MAX : limitValue.toUInt32();
+ uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32();
if (limit == 0)
return array.asReturnedValue();
- if (RegExpObject* re = separatorValue.as<RegExpObject>()) {
+ Scoped<RegExpObject> re(scope, separatorValue);
+ if (!!re) {
if (re->value->pattern().isEmpty()) {
- re = 0;
+ re = (RegExpObject *)0;
separatorValue = Value::fromString(ctx, QString());
}
}
- if (RegExpObject* re = separatorValue.as<RegExpObject>()) {
+ if (!!re) {
uint offset = 0;
uint* matchOffsets = (uint*)alloca(re->value->captureCount() * 2 * sizeof(uint));
while (true) {
@@ -675,7 +677,7 @@ ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx)
if (array->arrayLength() < limit)
array->push_back(Value::fromString(ctx, text.mid(offset)));
} else {
- QString separator = separatorValue.toString(ctx)->toQString();
+ QString separator = separatorValue->toString(ctx)->toQString();
if (separator.isEmpty()) {
for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
array->push_back(Value::fromString(ctx, text.mid(i, 1)));
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index f97aa66669..570ba9e82e 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -288,6 +288,11 @@ PersistentValue::PersistentValue(const Value &val)
{
}
+PersistentValue::PersistentValue(const ScopedValue &val)
+ : d(new PersistentValuePrivate(*val.operator ->()))
+{
+}
+
PersistentValue::PersistentValue(ReturnedValue val)
: d(new PersistentValuePrivate(Value::fromReturnedValue(val)))
{
@@ -326,6 +331,16 @@ PersistentValue &PersistentValue::operator =(const Value &other)
return *this;
}
+PersistentValue &PersistentValue::operator =(const ScopedValue &other)
+{
+ return operator=(*other.operator ->());
+}
+
+PersistentValue &PersistentValue::operator =(const ValueRef other)
+{
+ return operator=(*other.operator ->());
+}
+
PersistentValue &PersistentValue::operator =(const ReturnedValue &other)
{
if (!d) {
@@ -354,6 +369,11 @@ WeakValue::WeakValue(const WeakValue &other)
d->ref();
}
+WeakValue::WeakValue(ReturnedValue val)
+ : d(new PersistentValuePrivate(Value::fromReturnedValue(val), /*engine*/0, /*weak*/true))
+{
+}
+
WeakValue &WeakValue::operator=(const WeakValue &other)
{
if (d == other.d)
@@ -380,6 +400,16 @@ WeakValue &WeakValue::operator =(const Value &other)
return *this;
}
+WeakValue &WeakValue::operator =(const ReturnedValue &other)
+{
+ if (!d) {
+ d = new PersistentValuePrivate(Value::fromReturnedValue(other), /*engine*/0, /*weak*/true);
+ return *this;
+ }
+ d = d->detach(Value::fromReturnedValue(other), /*weak*/true);
+ return *this;
+}
+
WeakValue::~WeakValue()
{
diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h
index 76f694c0e9..7d97d4531e 100644
--- a/src/qml/jsruntime/qv4value_def_p.h
+++ b/src/qml/jsruntime/qv4value_def_p.h
@@ -341,6 +341,37 @@ struct Q_QML_EXPORT Value
inline void mark() const;
};
+struct SafeValue : public Value
+{
+ SafeValue &operator =(const ScopedValue &v);
+ template<typename T>
+ SafeValue &operator=(Returned<T> *t);
+ SafeValue &operator=(ReturnedValue v) {
+ val = v;
+ return *this;
+ }
+ template<typename T>
+ SafeValue &operator=(const Scoped<T> &t);
+ SafeValue &operator=(const Value &v) {
+ val = v.val;
+ return *this;
+ }
+
+ template<typename T>
+ Returned<T> *as();
+};
+
+template<typename T>
+T *value_cast(const Value &v)
+{
+ return v.as<T>();
+}
+
+template<typename T>
+ReturnedValue value_convert(ExecutionContext *ctx, const Value &v);
+
+
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index de00a2264c..6cefe13ae6 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -372,11 +372,22 @@ public:
PersistentValue() : d(0) {}
PersistentValue(const Value &val);
+ PersistentValue(const ScopedValue &val);
PersistentValue(ReturnedValue val);
+ template<typename T>
+ PersistentValue(Returned<T> *obj);
+ template<typename T>
+ PersistentValue(const Scoped<T> &obj);
PersistentValue(const PersistentValue &other);
PersistentValue &operator=(const PersistentValue &other);
PersistentValue &operator=(const Value &other);
+ PersistentValue &operator=(const ScopedValue &other);
+ PersistentValue &operator=(const ValueRef other);
PersistentValue &operator =(const ReturnedValue &other);
+ template<typename T>
+ PersistentValue &operator=(Returned<T> *obj);
+ template<typename T>
+ PersistentValue &operator=(const Scoped<T> &obj);
~PersistentValue();
Value value() const {
@@ -408,8 +419,15 @@ public:
WeakValue() : d(0) {}
WeakValue(const Value &val);
WeakValue(const WeakValue &other);
+ WeakValue(ReturnedValue val);
+ template<typename T>
+ WeakValue(Returned<T> *obj);
WeakValue &operator=(const WeakValue &other);
WeakValue &operator=(const Value &other);
+ WeakValue &operator =(const ReturnedValue &other);
+ template<typename T>
+ WeakValue &operator=(Returned<T> *obj);
+
~WeakValue();
Value value() const {
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 5ed75a1e06..149cbf2c49 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1408,7 +1408,8 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu
QQmlComponentExtension::QQmlComponentExtension(QV8Engine *engine)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QV4::Object *proto = v4->newObject();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> proto(scope, v4->newObject());
QV4::Property *s = proto->insertMember(v4->newString(QStringLiteral("onStatusChanged")),
QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
s->setGetter(V4FUNCTION(QmlIncubatorObject::method_get_statusChanged, v4));
@@ -1421,7 +1422,7 @@ QQmlComponentExtension::QQmlComponentExtension(QV8Engine *engine)
s->setGetter(V4FUNCTION(QmlIncubatorObject::method_get_object, v4));
proto->defineDefaultProperty(v4, QStringLiteral("forceCompletion"), QmlIncubatorObject::method_forceCompletion);
- incubationProto = QV4::Value::fromObject(proto);
+ incubationProto = proto;
}
QV4::ReturnedValue QmlIncubatorObject::method_get_object(QV4::SimpleCallContext *ctx)
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 405411e65c..d4998ec5ba 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -112,7 +112,7 @@ private:
DEFINE_MANAGED_VTABLE(QQmlLocaleData);
#define GET_LOCALE_DATA_RESOURCE(OBJECT) \
- QQmlLocaleData *r = OBJECT.as<QQmlLocaleData>(); \
+ QV4::Scoped<QQmlLocaleData> r(scope, OBJECT.as<QQmlLocaleData>()); \
if (!r) \
V4THROW_ERROR("Not a valid Locale object")
@@ -140,6 +140,8 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::SimpleCallConte
if (ctx->argumentCount > 2)
return QV4::DatePrototype::method_toLocaleString(ctx);
+ QV4::Scope scope(ctx);
+
QV4::DateObject *date = ctx->thisObject.asDateObject();
if (!date)
return QV4::DatePrototype::method_toLocaleString(ctx);
@@ -182,6 +184,8 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::SimpleCallC
if (ctx->argumentCount > 2)
return QV4::DatePrototype::method_toLocaleTimeString(ctx);
+ QV4::Scope scope(ctx);
+
QV4::DateObject *date = ctx->thisObject.asDateObject();
if (!date)
return QV4::DatePrototype::method_toLocaleTimeString(ctx);
@@ -225,6 +229,8 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::SimpleCallC
if (ctx->argumentCount > 2)
return QV4::DatePrototype::method_toLocaleDateString(ctx);
+ QV4::Scope scope(ctx);
+
QV4::DateObject *dateObj = ctx->thisObject.asDateObject();
if (!dateObj)
return QV4::DatePrototype::method_toLocaleDateString(ctx);
@@ -273,6 +279,8 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleString(QV4::SimpleCallCon
return QV4::Encode(engine->newDateObject(dt));
}
+ QV4::Scope scope(ctx);
+
if (ctx->argumentCount < 1 || ctx->argumentCount > 3 || !isLocaleObject(ctx->arguments[0]))
V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
@@ -315,6 +323,8 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::SimpleCal
if (ctx->argumentCount < 1 || ctx->argumentCount > 3 || !isLocaleObject(ctx->arguments[0]))
V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
+ QV4::Scope scope(ctx);
+
GET_LOCALE_DATA_RESOURCE(ctx->arguments[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
@@ -355,6 +365,8 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleDateString(QV4::SimpleCal
if (ctx->argumentCount < 1 || ctx->argumentCount > 3 || !isLocaleObject(ctx->arguments[0]))
V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
+ QV4::Scope scope(ctx);
+
GET_LOCALE_DATA_RESOURCE(ctx->arguments[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
@@ -414,6 +426,8 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::SimpleCallCon
if (!isLocaleObject(ctx->arguments[0]))
return QV4::NumberPrototype::method_toLocaleString(ctx); // Use the default Number toLocaleString()
+ QV4::Scope scope(ctx);
+
GET_LOCALE_DATA_RESOURCE(ctx->arguments[0]);
quint16 format = 'f';
@@ -450,6 +464,8 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::Simpl
if (!isLocaleObject(ctx->arguments[0]))
V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
+ QV4::Scope scope(ctx);
+
GET_LOCALE_DATA_RESOURCE(ctx->arguments[0]);
QString symbol;
@@ -470,6 +486,8 @@ QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::SimpleCallC
int numberIdx = 0;
QLocale locale;
+ QV4::Scope scope(ctx);
+
if (ctx->argumentCount == 2) {
if (!isLocaleObject(ctx->arguments[0]))
V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
@@ -671,8 +689,8 @@ public:
QV8LocaleDataDeletable::QV8LocaleDataDeletable(QV8Engine *engine)
{
QV4::ExecutionEngine *eng = QV8Engine::getV4(engine);
- QV4::Object *o = eng->newObject();
- prototype = QV4::Value::fromObject(o);
+ QV4::Scope scope(eng);
+ QV4::Scoped<QV4::Object> o(scope, eng->newObject());
o->defineDefaultProperty(eng, QStringLiteral("dateFormat"), QQmlLocaleData::method_dateFormat, 0);
o->defineDefaultProperty(eng, QStringLiteral("standaloneDayName"), QQmlLocaleData::method_standaloneDayName, 0);
@@ -699,6 +717,8 @@ QV8LocaleDataDeletable::QV8LocaleDataDeletable(QV8Engine *engine)
o->defineAccessorProperty(eng, QStringLiteral("amText"), QQmlLocaleData::method_get_amText, 0);
o->defineAccessorProperty(eng, QStringLiteral("measurementSystem"), QQmlLocaleData::method_get_measurementSystem, 0);
o->defineAccessorProperty(eng, QStringLiteral("exponential"), QQmlLocaleData::method_get_exponential, 0);
+
+ prototype = o;
}
QV8LocaleDataDeletable::~QV8LocaleDataDeletable()
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index f89ce15a57..b5073763b8 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -134,9 +134,10 @@ void QmlValueTypeWrapper::initProto(ExecutionEngine *v4)
if (v4->qmlExtensions()->valueTypeWrapperPrototype)
return;
- Object *o = v4->newObject();
+ Scope scope(v4);
+ Scoped<Object> o(scope, v4->newObject());
o->defineDefaultProperty(v4, QStringLiteral("toString"), method_toString, 1);
- v4->qmlExtensions()->valueTypeWrapperPrototype = o;
+ v4->qmlExtensions()->valueTypeWrapperPrototype = o.getPointer();
}
ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type)
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index dc98bd176e..bef943fd51 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -65,6 +65,7 @@
#include <QtCore/qdebug.h>
#include <private/qv4objectproto_p.h>
+#include <private/qv4scopedvalue_p.h>
using namespace QV4;
@@ -99,15 +100,15 @@ static inline QQmlXMLHttpRequestData *xhrdata(QV8Engine *engine)
return (QQmlXMLHttpRequestData *)engine->xmlHttpRequestData();
}
-static Value constructMeObject(const Value &thisObj, QV8Engine *e)
+static ReturnedValue constructMeObject(const Value &thisObj, QV8Engine *e)
{
ExecutionEngine *v4 = QV8Engine::getV4(e);
Scope scope(v4);
- Object *meObj = v4->newObject();
+ Scoped<Object> meObj(scope, v4->newObject());
meObj->put(v4->newString(QStringLiteral("ThisObject")), thisObj);
ScopedValue v(scope, QmlContextWrapper::qmlScope(e, e->callingContext(), 0));
meObj->put(v4->newString(QStringLiteral("ActivationObject")), v);
- return Value::fromObject(meObj);
+ return meObj.asReturnedValue();
}
QQmlXMLHttpRequestData::QQmlXMLHttpRequestData()
@@ -625,10 +626,11 @@ Value Element::prototype(ExecutionEngine *engine)
{
QQmlXMLHttpRequestData *d = xhrdata(engine->v8Engine);
if (d->elementPrototype.isEmpty()) {
- Object *p = engine->newObject();
+ Scope scope(engine);
+ Scoped<Object> p(scope, engine->newObject());
p->setPrototype(NodePrototype::getProto(engine).asObject());
p->defineAccessorProperty(engine, QStringLiteral("tagName"), NodePrototype::method_get_nodeName, 0);
- d->elementPrototype = Value::fromObject(p);
+ d->elementPrototype = p;
engine->v8Engine->freezeObject(d->elementPrototype.value());
}
return d->elementPrototype.value();
@@ -638,12 +640,13 @@ Value Attr::prototype(ExecutionEngine *engine)
{
QQmlXMLHttpRequestData *d = xhrdata(engine->v8Engine);
if (d->attrPrototype.isEmpty()) {
- Object *p = engine->newObject();
+ Scope scope(engine);
+ Scoped<Object> p(scope, engine->newObject());
p->setPrototype(NodePrototype::getProto(engine).asObject());
p->defineAccessorProperty(engine, QStringLiteral("name"), method_name, 0);
p->defineAccessorProperty(engine, QStringLiteral("value"), method_value, 0);
p->defineAccessorProperty(engine, QStringLiteral("ownerElement"), method_ownerElement, 0);
- d->attrPrototype = Value::fromObject(p);
+ d->attrPrototype = p;
engine->v8Engine->freezeObject(d->attrPrototype.value());
}
return d->attrPrototype.value();
@@ -693,11 +696,12 @@ Value CharacterData::prototype(ExecutionEngine *v4)
{
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->characterDataPrototype.isEmpty()) {
- Object *p = v4->newObject();
+ Scope scope(v4);
+ Scoped<Object> p(scope, v4->newObject());
p->setPrototype(NodePrototype::getProto(v4).asObject());
p->defineAccessorProperty(v4, QStringLiteral("data"), NodePrototype::method_get_nodeValue, 0);
p->defineAccessorProperty(v4, QStringLiteral("length"), method_length, 0);
- d->characterDataPrototype = Value::fromObject(p);
+ d->characterDataPrototype = p;
v4->v8Engine->freezeObject(d->characterDataPrototype);
}
return d->characterDataPrototype.value();
@@ -725,11 +729,12 @@ Value Text::prototype(ExecutionEngine *v4)
{
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->textPrototype.isEmpty()) {
- Object *p = v4->newObject();
+ Scope scope(v4);
+ Scoped<Object> p(scope, v4->newObject());
p->setPrototype(CharacterData::prototype(v4).asObject());
p->defineAccessorProperty(v4, QStringLiteral("isElementContentWhitespace"), method_isElementContentWhitespace, 0);
p->defineAccessorProperty(v4, QStringLiteral("wholeText"), method_wholeText, 0);
- d->textPrototype = Value::fromObject(p);
+ d->textPrototype = p;
v4->v8Engine->freezeObject(d->textPrototype);
}
return d->textPrototype.value();
@@ -740,9 +745,10 @@ Value CDATA::prototype(ExecutionEngine *v4)
// ### why not just use TextProto???
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->cdataPrototype.isEmpty()) {
- Object *p = v4->newObject();
+ Scope scope(v4);
+ Scoped<Object> p(scope, v4->newObject());
p->setPrototype(Text::prototype(v4).asObject());
- d->cdataPrototype = Value::fromObject(p);
+ d->cdataPrototype = p;
v4->v8Engine->freezeObject(d->cdataPrototype);
}
return d->cdataPrototype.value();
@@ -752,13 +758,14 @@ Value Document::prototype(ExecutionEngine *v4)
{
QQmlXMLHttpRequestData *d = xhrdata(v4->v8Engine);
if (d->documentPrototype.isEmpty()) {
- Object *p = v4->newObject();
+ Scope scope(v4);
+ Scoped<Object> p(scope, v4->newObject());
p->setPrototype(NodePrototype::getProto(v4).asObject());
p->defineAccessorProperty(v4, QStringLiteral("xmlVersion"), method_xmlVersion, 0);
p->defineAccessorProperty(v4, QStringLiteral("xmlEncoding"), method_xmlEncoding, 0);
p->defineAccessorProperty(v4, QStringLiteral("xmlStandalone"), method_xmlStandalone, 0);
p->defineAccessorProperty(v4, QStringLiteral("documentElement"), method_documentElement, 0);
- d->documentPrototype = Value::fromObject(p);
+ d->documentPrototype = p;
v4->v8Engine->freezeObject(d->documentPrototype);
}
return d->documentPrototype.value();
@@ -1016,9 +1023,9 @@ public:
int replyStatus() const;
QString replyStatusText() const;
- Value open(const Value &me, const QString &, const QUrl &);
- Value send(const Value &me, const QByteArray &);
- Value abort(const Value &me);
+ ReturnedValue open(const ValueRef me, const QString &, const QUrl &);
+ ReturnedValue send(const ValueRef me, const QByteArray &);
+ ReturnedValue abort(const ValueRef me);
void addHeader(const QString &, const QString &);
QString header(const QString &name);
@@ -1060,11 +1067,11 @@ private:
#endif
void readEncoding();
- Value getMe() const;
- void setMe(const Value &me);
+ ReturnedValue getMe() const;
+ void setMe(const ValueRef me);
PersistentValue m_me;
- void dispatchCallback(const Value &me);
+ void dispatchCallback(const ValueRef me);
void printError(const Exception &e);
int m_status;
@@ -1115,8 +1122,7 @@ QString QQmlXMLHttpRequest::replyStatusText() const
return m_statusText;
}
-Value QQmlXMLHttpRequest::open(const Value &me, const QString &method,
- const QUrl &url)
+ReturnedValue QQmlXMLHttpRequest::open(const ValueRef me, const QString &method, const QUrl &url)
{
destroyNetwork();
m_sendFlag = false;
@@ -1127,7 +1133,7 @@ Value QQmlXMLHttpRequest::open(const Value &me, const QString &method,
m_state = Opened;
m_addedHeaders.clear();
dispatchCallback(me);
- return Value::undefinedValue();
+ return Encode::undefined();
}
void QQmlXMLHttpRequest::addHeader(const QString &name, const QString &value)
@@ -1241,7 +1247,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
this, SLOT(finished()));
}
-Value QQmlXMLHttpRequest::send(const Value &me, const QByteArray &data)
+ReturnedValue QQmlXMLHttpRequest::send(const ValueRef me, const QByteArray &data)
{
m_errorFlag = false;
m_sendFlag = true;
@@ -1252,10 +1258,10 @@ Value QQmlXMLHttpRequest::send(const Value &me, const QByteArray &data)
requestFromUrl(m_url);
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value QQmlXMLHttpRequest::abort(const Value &me)
+ReturnedValue QQmlXMLHttpRequest::abort(const ValueRef me)
{
destroyNetwork();
m_responseEntityBody = QByteArray();
@@ -1273,15 +1279,15 @@ Value QQmlXMLHttpRequest::abort(const Value &me)
m_state = Unsent;
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value QQmlXMLHttpRequest::getMe() const
+ReturnedValue QQmlXMLHttpRequest::getMe() const
{
- return m_me.value();
+ return m_me.value().asReturnedValue();
}
-void QQmlXMLHttpRequest::setMe(const Value &me)
+void QQmlXMLHttpRequest::setMe(const ValueRef me)
{
m_me = me;
}
@@ -1293,18 +1299,22 @@ void QQmlXMLHttpRequest::readyRead()
m_statusText =
QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
+ Scope scope(v4);
+ ScopedValue me(scope, m_me.value());
+
// ### We assume if this is called the headers are now available
if (m_state < HeadersReceived) {
m_state = HeadersReceived;
fillHeadersList ();
- dispatchCallback(m_me.value());
+ dispatchCallback(me);
}
bool wasEmpty = m_responseEntityBody.isEmpty();
m_responseEntityBody.append(m_network->readAll());
if (wasEmpty && !m_responseEntityBody.isEmpty())
m_state = Loading;
- dispatchCallback(m_me.value());
+
+ dispatchCallback(me);
}
static const char *errorToString(QNetworkReply::NetworkError error)
@@ -1335,6 +1345,9 @@ void QQmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
qWarning().nospace() << " " << error << ' ' << errorToString(error) << ' ' << m_statusText;
}
+ Scope scope(v4);
+ ScopedValue me(scope, m_me.value());
+
if (error == QNetworkReply::ContentAccessDenied ||
error == QNetworkReply::ContentOperationNotPermittedError ||
error == QNetworkReply::ContentNotFoundError ||
@@ -1342,7 +1355,7 @@ void QQmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
error == QNetworkReply::ContentReSendError ||
error == QNetworkReply::UnknownContentError) {
m_state = Loading;
- dispatchCallback(m_me.value());
+ dispatchCallback(me);
} else {
m_errorFlag = true;
m_responseEntityBody = QByteArray();
@@ -1350,7 +1363,7 @@ void QQmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
m_state = Done;
- dispatchCallback(m_me.value());
+ dispatchCallback(me);
}
#define XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION 15
@@ -1405,7 +1418,9 @@ void QQmlXMLHttpRequest::finished()
dispatchCallback(m_me);
- setMe(Value::emptyValue());
+ Scope scope(v4);
+ ScopedValue v(scope, Value::emptyValue());
+ setMe(v);
}
@@ -1483,12 +1498,12 @@ const QByteArray &QQmlXMLHttpRequest::rawResponseBody() const
return m_responseEntityBody;
}
-void QQmlXMLHttpRequest::dispatchCallback(const Value &me)
+void QQmlXMLHttpRequest::dispatchCallback(const ValueRef me)
{
ExecutionContext *ctx = v4->current;
QV4::Scope scope(v4);
try {
- Object *o = me.asObject();
+ Scoped<Object> o(scope, me);
if (!o)
ctx->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject"));
@@ -1631,7 +1646,9 @@ DEFINE_MANAGED_VTABLE(QQmlXMLHttpRequestCtor);
void QQmlXMLHttpRequestCtor::setupProto()
{
ExecutionEngine *v4 = engine();
- proto = v4->newObject();
+ Scope scope(v4);
+ Scoped<Object> p(scope, v4->newObject());
+ proto = p.getPointer();
// Methods
proto->defineDefaultProperty(v4, QStringLiteral("open"), method_open);
@@ -1704,7 +1721,8 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(SimpleCallContext *ctx)
if (!username.isNull()) url.setUserName(username);
if (!password.isNull()) url.setPassword(password);
- return r->open(constructMeObject(ctx->thisObject, engine), method, url).asReturnedValue();
+ ScopedValue meObject(scope, constructMeObject(ctx->thisObject, engine));
+ return r->open(meObject, method, url);
}
ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(SimpleCallContext *ctx)
@@ -1774,7 +1792,8 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_send(SimpleCallContext *ctx)
if (ctx->argumentCount > 0)
data = ctx->arguments[0].toQStringNoThrow().toUtf8();
- return r->send(constructMeObject(ctx->thisObject, engine), data).asReturnedValue();
+ ScopedValue meObject(scope, constructMeObject(ctx->thisObject, engine));
+ return r->send(meObject, data);
}
ReturnedValue QQmlXMLHttpRequestCtor::method_abort(SimpleCallContext *ctx)
@@ -1786,7 +1805,8 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_abort(SimpleCallContext *ctx)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->request;
- return r->abort(constructMeObject(ctx->thisObject, ctx->engine->v8Engine)).asReturnedValue();
+ ScopedValue meObject(scope, constructMeObject(ctx->thisObject, ctx->engine->v8Engine));
+ return r->abort(meObject);
}
ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(SimpleCallContext *ctx)
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 6389ad2715..40b5075ddd 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -962,12 +962,12 @@ ReturnedValue QtObject::method_createQmlObject(SimpleCallContext *ctx)
for (int ii = 0; ii < errors.count(); ++ii) {
const QQmlError &error = errors.at(ii);
errorstr += QLatin1String("\n ") + error.toString();
- QV4::Object *qmlerror = v4->newObject();
+ QV4::Scoped<QV4::Object> qmlerror(scope, v4->newObject());
qmlerror->put(v4->newString("lineNumber"), QV4::Value::fromInt32(error.line()));
qmlerror->put(v4->newString("columnNumber"), QV4::Value::fromInt32(error.column()));
qmlerror->put(v4->newString("fileName"), Value::fromString(v4->newString(error.url().toString())));
qmlerror->put(v4->newString("message"), Value::fromString(v4->newString(error.description())));
- qmlerrors->putIndexed(ii, QV4::Value::fromObject(qmlerror));
+ qmlerrors->putIndexed(ii, qmlerror.asValue());
}
Scoped<Object> errorObject(scope, v4->newErrorObject(Value::fromString(v4->newString(errorstr))));
@@ -1001,7 +1001,8 @@ ReturnedValue QtObject::method_createQmlObject(SimpleCallContext *ctx)
url = context->resolvedUrl(url);
QObject *parentArg = 0;
- if (QV4::QObjectWrapper *qobjectWrapper = ctx->arguments[1].as<QV4::QObjectWrapper>())
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, ctx->arguments[1]);
+ if (!!qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
V4THROW_ERROR("Qt.createQmlObject(): Missing parent object");
diff --git a/src/qml/qml/v8/qv4domerrors.cpp b/src/qml/qml/v8/qv4domerrors.cpp
index 63c79f85c2..f89831fa2f 100644
--- a/src/qml/qml/v8/qv4domerrors.cpp
+++ b/src/qml/qml/v8/qv4domerrors.cpp
@@ -48,7 +48,8 @@ using namespace QV4;
void qt_add_domexceptions(ExecutionEngine *e)
{
- Object *domexception = e->newObject();
+ Scope scope(e);
+ Scoped<Object> domexception(scope, e->newObject());
domexception->defineReadonlyProperty(e, QStringLiteral("INDEX_SIZE_ERR"), Value::fromInt32(DOMEXCEPTION_INDEX_SIZE_ERR));
domexception->defineReadonlyProperty(e, QStringLiteral("DOMSTRING_SIZE_ERR"), Value::fromInt32(DOMEXCEPTION_DOMSTRING_SIZE_ERR));
domexception->defineReadonlyProperty(e, QStringLiteral("HIERARCHY_REQUEST_ERR"), Value::fromInt32(DOMEXCEPTION_HIERARCHY_REQUEST_ERR));
@@ -66,7 +67,7 @@ void qt_add_domexceptions(ExecutionEngine *e)
domexception->defineReadonlyProperty(e, QStringLiteral("INVALID_ACCESS_ERR"), Value::fromInt32(DOMEXCEPTION_INVALID_ACCESS_ERR));
domexception->defineReadonlyProperty(e, QStringLiteral("VALIDATION_ERR"), Value::fromInt32(DOMEXCEPTION_VALIDATION_ERR));
domexception->defineReadonlyProperty(e, QStringLiteral("TYPE_MISMATCH_ERR"), Value::fromInt32(DOMEXCEPTION_TYPE_MISMATCH_ERR));
- e->globalObject->defineDefaultProperty(e->current, QStringLiteral("DOMException"), Value::fromObject(domexception));
+ e->globalObject->defineDefaultProperty(e->current, QStringLiteral("DOMException"), domexception.asValue());
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv4sqlerrors.cpp b/src/qml/qml/v8/qv4sqlerrors.cpp
index bd5a9fdc83..a203fd9980 100644
--- a/src/qml/qml/v8/qv4sqlerrors.cpp
+++ b/src/qml/qml/v8/qv4sqlerrors.cpp
@@ -49,7 +49,8 @@ using namespace QV4;
void qt_add_sqlexceptions(QV4::ExecutionEngine *engine)
{
- Object *sqlexception = engine->newObject();
+ Scope scope(engine);
+ Scoped<Object> sqlexception(scope, engine->newObject());
sqlexception->defineReadonlyProperty(engine, QStringLiteral("UNKNOWN_ERR"), Value::fromInt32(SQLEXCEPTION_UNKNOWN_ERR));
sqlexception->defineReadonlyProperty(engine, QStringLiteral("DATABASE_ERR"), Value::fromInt32(SQLEXCEPTION_DATABASE_ERR));
sqlexception->defineReadonlyProperty(engine, QStringLiteral("VERSION_ERR"), Value::fromInt32(SQLEXCEPTION_VERSION_ERR));
@@ -58,7 +59,7 @@ void qt_add_sqlexceptions(QV4::ExecutionEngine *engine)
sqlexception->defineReadonlyProperty(engine, QStringLiteral("SYNTAX_ERR"), Value::fromInt32(SQLEXCEPTION_SYNTAX_ERR));
sqlexception->defineReadonlyProperty(engine, QStringLiteral("CONSTRAINT_ERR"), Value::fromInt32(SQLEXCEPTION_CONSTRAINT_ERR));
sqlexception->defineReadonlyProperty(engine, QStringLiteral("TIMEOUT_ERR"), Value::fromInt32(SQLEXCEPTION_TIMEOUT_ERR));
- engine->globalObject->defineDefaultProperty(engine->current, QStringLiteral("SQLException"), Value::fromObject(sqlexception));
+ engine->globalObject->defineDefaultProperty(engine->current, QStringLiteral("SQLException"), sqlexception.asValue());
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 08bbd4c960..b62d8c173d 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -212,10 +212,11 @@ static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariant
static QV4::ReturnedValue objectFromVariantMap(QV8Engine *engine, const QVariantMap &map)
{
QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
- QV4::Object *o = e->newObject();
+ QV4::Scope scope(e);
+ QV4::Scoped<QV4::Object> o(scope, e->newObject());
for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter)
o->put(e->newString(iter.key()), QV4::Value::fromReturnedValue(engine->fromVariant(iter.value())));
- return QV4::Value::fromObject(o).asReturnedValue();
+ return o.asReturnedValue();
}
Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
@@ -566,13 +567,14 @@ QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a,
// the QVariantMap converted to JS, recursively.
QV4::ReturnedValue QV8Engine::variantMapToJS(const QVariantMap &vmap)
{
- QV4::Object *o = m_v4Engine->newObject();
+ QV4::Scope scope(m_v4Engine);
+ QV4::Scoped<QV4::Object> o(scope, m_v4Engine->newObject());
QVariantMap::const_iterator it;
for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
QV4::Property *p = o->insertMember(m_v4Engine->newIdentifier(it.key()), QV4::Attr_Data);
p->value = QV4::Value::fromReturnedValue(variantToJS(it.value()));
}
- return QV4::Value::fromObject(o).asReturnedValue();
+ return o.asReturnedValue();
}
// Converts a JS Object to a QVariantMap.
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 0457adb348..b9f78da96e 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -83,10 +83,12 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
static QV4::ReturnedValue call(QV4::Managed *that, QV4::CallData *callData)
{
- DelegateModelGroupFunction *f = static_cast<DelegateModelGroupFunction *>(that);
- QQmlDelegateModelItemObject *o = callData->thisObject.as<QQmlDelegateModelItemObject>();
+ QV4::ExecutionEngine *v4 = that->engine();
+ QV4::Scope scope(v4);
+ QV4::Scoped<DelegateModelGroupFunction> f(scope, that, QV4::Scoped<DelegateModelGroupFunction>::Cast);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject);
if (!o)
- that->engine()->current->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ v4->current->throwTypeError(QStringLiteral("Not a valid VisualData object"));
QV4::Value v = callData->argc ? callData->args[0] : QV4::Value::undefinedValue();
return f->code(o->item, f->flag, v);
@@ -1622,8 +1624,9 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
{
QQmlDelegateModelEngineData *data = engineData(v8Engine);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8Engine);
+ QV4::Scope scope(v4);
- QV4::Object *proto = v4->newObject();
+ QV4::Scoped<QV4::Object> proto(scope, v4->newObject());
proto->defineAccessorProperty(v4, QStringLiteral("model"), QQmlDelegateModelItem::get_model, 0);
proto->defineAccessorProperty(v4, QStringLiteral("groups"), QQmlDelegateModelItem::get_groups, QQmlDelegateModelItem::set_groups);
QV4::Property *p = proto->insertMember(v4->newString(QStringLiteral("isUnresolved")),
@@ -1656,7 +1659,7 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
p = proto->insertMember(v4->newString(propertyName), QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, i + 1, QQmlDelegateModelItem::get_index));
}
- modelItemProto = QV4::Value::fromObject(proto);
+ modelItemProto = proto;
}
int QQmlDelegateModelItemMetaType::parseGroups(const QStringList &groups) const
@@ -3233,15 +3236,16 @@ private:
QQmlDelegateModelEngineData::QQmlDelegateModelEngineData(QV8Engine *e)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(e);
+ QV4::Scope scope(v4);
- QV4::Object *proto = v4->newObject();
+ QV4::Scoped<QV4::Object> proto(scope, v4->newObject());
QV4::Property *p = proto->insertMember(v4->newString(QStringLiteral("index")), QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, QQmlDelegateModelGroupChange::method_get_index));
p = proto->insertMember(v4->newString(QStringLiteral("count")), QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, QQmlDelegateModelGroupChange::method_get_count));
p = proto->insertMember(v4->newString(QStringLiteral("moveId")), QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, QQmlDelegateModelGroupChange::method_get_moveId));
- changeProto = QV4::Value::fromObject(proto);
+ changeProto = proto;
}
QQmlDelegateModelEngineData::~QQmlDelegateModelEngineData()
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 4e39682d84..d80df760fa 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -177,7 +177,7 @@ public:
};
QHash<int, WorkerScript *> workers;
- QV4::Value getWorker(WorkerScript *);
+ QV4::ReturnedValue getWorker(WorkerScript *);
int m_nextId;
@@ -282,9 +282,9 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(QV4::Simp
{
WorkerEngine *engine = (WorkerEngine*)ctx->engine->v8Engine;
- int id = ctx->argument(1).toInt32();
+ int id = ctx->argumentCount > 1 ? ctx->arguments[1].toInt32() : 0;
- QByteArray data = QV4::Serialize::serialize(ctx->argument(2), engine);
+ QByteArray data = QV4::Serialize::serialize(ctx->argumentCount > 2 ? ctx->arguments[2] : QV4::Value::undefinedValue(), engine);
QMutexLocker locker(&engine->p->m_lock);
WorkerScript *script = engine->p->workers.value(id);
@@ -298,27 +298,29 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(QV4::Simp
}
// Requires handle scope and context scope
-QV4::Value QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script)
+QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script)
{
if (!script->initialized) {
script->initialized = true;
QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine);
+ QV4::Scope scope(v4);
script->object = QV4::QmlContextWrapper::urlScope(workerEngine, script->source);
- QV4::QmlContextWrapper *w = script->object.value().asObject()->as<QV4::QmlContextWrapper>();
+ QV4::Scoped<QV4::QmlContextWrapper> w(scope, script->object.value());
+ Q_ASSERT(!!w);
w->setReadOnly(false);
- QV4::Object *api = v4->newObject();
+ QV4::Scoped<QV4::Object> api(scope, v4->newObject());
api->put(v4->newString("sendMessage"), workerEngine->sendFunction(script->id));
- script->object.value().asObject()->put(v4->newString("WorkerScript"), QV4::Value::fromObject(api));
+ script->object.value().asObject()->put(v4->newString("WorkerScript"), api.asValue());
w->setReadOnly(true);
}
- return script->object.value();
+ return script->object.value().asReturnedValue();
}
bool QQuickWorkerScriptEnginePrivate::event(QEvent *event)
@@ -386,12 +388,15 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
if (!script)
return;
script->source = url;
- QV4::Value activation = getWorker(script);
- if (activation.isEmpty())
- return;
QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine);
- QV4::Script program(v4, activation.asObject(), sourceCode, url.toString());
+ QV4::Scope scope(v4);
+
+ QV4::Scoped<QV4::Object> activation(scope, getWorker(script));
+ if (!activation)
+ return;
+
+ QV4::Script program(v4, activation.getPointer(), sourceCode, url.toString());
QV4::ExecutionContext *ctx = v4->current;
try {
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index 9812e2a4a6..add422b8da 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -213,7 +213,8 @@ public:
void initializeConstructor(QQmlAdaptorModelEngineData *const data)
{
QV4::ExecutionEngine *v4 = data->v4;
- QV4::Object *proto = v4->newObject();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> proto(scope, v4->newObject());
QV4::Property *p = proto->insertMember(v4->newString(QStringLiteral("index")),
QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, get_index));
@@ -232,7 +233,7 @@ public:
p->setGetter(new (v4->memoryManager) QV4::IndexedBuiltinFunction(v4->rootContext, propertyId, QQmlDMCachedModelData::get_property));
p->setSetter(new (v4->memoryManager) QV4::IndexedBuiltinFunction(v4->rootContext, propertyId, QQmlDMCachedModelData::set_property));
}
- prototype = QV4::Value::fromObject(proto);
+ prototype = proto.asValue();
}
// QAbstractDynamicMetaObject
@@ -955,7 +956,8 @@ void QQmlAdaptorModel::objectDestroyed(QObject *)
QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV8Engine *e)
: v4(QV8Engine::getV4(e))
{
- QV4::Object *proto = v4->newObject();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> proto(scope, v4->newObject());
QV4::Property *p = proto->insertMember(v4->newString(QStringLiteral("index")),
QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, get_index));
@@ -963,7 +965,7 @@ QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV8Engine *e)
QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, QQmlDMListAccessorData::get_modelData));
p->setSetter(v4->newBuiltinFunction(v4->rootContext, v4->id_undefined, QQmlDMListAccessorData::set_modelData));
- listItemProto = QV4::Value::fromObject(proto);
+ listItemProto = proto;
}
QQmlAdaptorModelEngineData::~QQmlAdaptorModelEngineData()
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 3a84404d66..82fbbd0862 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -941,6 +941,8 @@ static QV4::Value qt_create_image_data(qreal w, qreal h, QV8Engine* engine, cons
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -955,6 +957,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::SimpleCall
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -968,6 +972,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(QV4::SimpleCallCon
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1008,6 +1014,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(QV4::SimpleCallConte
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1036,6 +1044,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(QV4::SimpleCallContex
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1063,6 +1073,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::SimpleCallCont
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1107,6 +1119,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::SimpleCallConte
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1135,6 +1149,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::SimpleCa
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1181,6 +1197,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(QV4::SimpleCallC
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1198,6 +1216,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(QV4::Simple
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1225,10 +1245,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_globalAlpha(QV4::SimpleCallCont
QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- double globalAlpha = ctx->argument(0).toNumber();
+ double globalAlpha = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
if (!qIsFinite(globalAlpha))
return QV4::Encode::undefined();
@@ -1268,6 +1290,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::SimpleCallCont
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1276,10 +1300,15 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(QV4::S
QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString mode = ctx->argument(0).toQStringNoThrow();
+ if (!ctx->argumentCount)
+ ctx->throwTypeError();
+
+ QString mode = ctx->arguments[0].toQString();
QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
if (cm == QPainter::CompositionMode_SourceOver && mode != QStringLiteral("source-over"))
return QV4::Encode::undefined();
@@ -1316,6 +1345,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(QV4::S
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1336,20 +1367,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(QV4::SimpleCallContex
QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QV4::Value value = ctx->argument(0);
+ QV4::ScopedValue value(scope, ctx->argument(0));
QV8Engine *engine = ctx->engine->v8Engine;
- if (value.asObject()) {
+ if (value->asObject()) {
QColor color = engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->context->state.fillStyle = color;
r->context->buffer()->setFillStyle(color);
r->context->m_fillStyle = value;
} else {
- QQuickContext2DStyle *style = value.as<QQuickContext2DStyle>();
+ QQuickContext2DStyle *style = value->as<QQuickContext2DStyle>();
if (style && style->brush != r->context->state.fillStyle) {
r->context->state.fillStyle = style->brush;
r->context->buffer()->setFillStyle(style->brush, style->patternRepeatX, style->patternRepeatY);
@@ -1358,7 +1391,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::SimpleCallContex
r->context->state.fillPatternRepeatY = style->patternRepeatY;
}
}
- } else if (value.isString()) {
+ } else if (value->isString()) {
QColor color = qt_color_from_string(value);
if (color.isValid() && r->context->state.fillStyle != QBrush(color)) {
r->context->state.fillStyle = QBrush(color);
@@ -1382,6 +1415,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::SimpleCallContex
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1391,16 +1426,18 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(QV4::SimpleCallContext
QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QV4::Value value = ctx->argument(0);
+ QV4::ScopedValue value(scope, ctx->argument(0));
- if ((value.isString() && value.toQStringNoThrow() == QStringLiteral("WindingFill"))
- || (value.isInt32() && value.integerValue() == Qt::WindingFill)) {
+ if ((value->isString() && value->toQString() == QStringLiteral("WindingFill"))
+ || (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
r->context->state.fillRule = Qt::WindingFill;
- } else if ((value.isString() && value.toQStringNoThrow() == QStringLiteral("OddEvenFill"))
- || (value.isInt32() && value.integerValue() == Qt::OddEvenFill)) {
+ } else if ((value->isString() && value->toQStringNoThrow() == QStringLiteral("OddEvenFill"))
+ || (value->isInt32() && value->integerValue() == Qt::OddEvenFill)) {
r->context->state.fillRule = Qt::OddEvenFill;
} else {
//error
@@ -1423,6 +1460,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::SimpleCallContext
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1443,20 +1482,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(QV4::SimpleCallCont
QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = ctx->engine->v8Engine;
- QV4::Value value = ctx->argument(0);
+ QV4::ScopedValue value(scope, ctx->argument(0));
- if (value.asObject()) {
+ if (value->asObject()) {
QColor color = engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->context->state.fillStyle = color;
r->context->buffer()->setStrokeStyle(color);
r->context->m_strokeStyle = value;
} else {
- QQuickContext2DStyle *style = value.as<QQuickContext2DStyle>();
+ QQuickContext2DStyle *style = value->as<QQuickContext2DStyle>();
if (style && style->brush != r->context->state.strokeStyle) {
r->context->state.strokeStyle = style->brush;
r->context->buffer()->setStrokeStyle(style->brush, style->patternRepeatX, style->patternRepeatY);
@@ -1466,7 +1507,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::SimpleCallCont
}
}
- } else if (value.isString()) {
+ } else if (value->isString()) {
QColor color = qt_color_from_string(value);
if (color.isValid() && r->context->state.strokeStyle != QBrush(color)) {
r->context->state.strokeStyle = QBrush(color);
@@ -1496,13 +1537,13 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::SimpleCallCont
QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
QV8Engine *engine = ctx->engine->v8Engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
if (ctx->argumentCount == 4) {
qreal x0 = ctx->arguments[0].toNumber();
@@ -1542,13 +1583,13 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
QV8Engine *engine = ctx->engine->v8Engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
if (ctx->argumentCount == 6) {
qreal x0 = ctx->arguments[0].toNumber();
@@ -1596,13 +1637,13 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
QV8Engine *engine = ctx->engine->v8Engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
if (ctx->argumentCount == 6) {
qreal x = ctx->arguments[0].toNumber();
@@ -1671,13 +1712,12 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallContext *ctx)
{
- QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
+ QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject);
CHECK_CONTEXT(r)
-
QV8Engine *engine = ctx->engine->v8Engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QV4::Scope scope(v4);
if (ctx->argumentCount == 2) {
QQuickContext2DStyle *pattern = new (v4->memoryManager) QQuickContext2DStyle(v4);
@@ -1743,6 +1783,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleC
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1760,10 +1802,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(QV4::SimpleCallContext
QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString lineCap = ctx->argument(0).toQStringNoThrow();
+ QString lineCap = ctx->arguments[0].toQString();
Qt::PenCapStyle cap;
if (lineCap == QStringLiteral("round"))
cap = Qt::RoundCap;
@@ -1797,6 +1841,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::SimpleCallContext
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1814,10 +1860,15 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(QV4::SimpleCallContext
QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString lineJoin = ctx->argument(0).toQStringNoThrow();
+ if (!ctx->argumentCount)
+ ctx->throwTypeError();
+
+ QString lineJoin = ctx->arguments[0].toQString();
Qt::PenJoinStyle join;
if (lineJoin == QStringLiteral("round"))
join = Qt::RoundJoin;
@@ -1841,6 +1892,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(QV4::SimpleCallContext
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1849,10 +1902,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(QV4::SimpleCallContex
QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- qreal w = ctx->argument(0).toNumber();
+ qreal w = ctx->argumentCount ? ctx->arguments[0].toNumber() : -1;
if (w > 0 && qIsFinite(w) && w != r->context->state.lineWidth) {
r->context->state.lineWidth = w;
@@ -1868,6 +1923,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(QV4::SimpleCallContex
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1876,10 +1933,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(QV4::SimpleCallConte
QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- qreal ml = ctx->argument(0).toNumber();
+ qreal ml = ctx->argumentCount ? ctx->arguments[0].toNumber() : -1;
if (ml > 0 && qIsFinite(ml) && ml != r->context->state.miterLimit) {
r->context->state.miterLimit = ml;
@@ -1895,6 +1954,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(QV4::SimpleCallConte
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1903,10 +1964,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(QV4::SimpleCallConte
QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- qreal blur = ctx->argument(0).toNumber();
+ qreal blur = ctx->argumentCount ? ctx->arguments[0].toNumber() : -1;
if (blur > 0 && qIsFinite(blur) && blur != r->context->state.shadowBlur) {
r->context->state.shadowBlur = blur;
@@ -1921,6 +1984,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(QV4::SimpleCallConte
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1929,10 +1994,14 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(QV4::SimpleCallCont
QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QColor color = qt_color_from_string(ctx->argument(0));
+ QColor color;
+ if (ctx->argumentCount)
+ color = qt_color_from_string(ctx->arguments[0]);
if (color.isValid() && color != r->context->state.shadowColor) {
r->context->state.shadowColor = color;
@@ -1950,6 +2019,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(QV4::SimpleCallCont
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1958,10 +2029,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(QV4::SimpleCallCo
QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- qreal offsetX = ctx->argument(0).toNumber();
+ qreal offsetX = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
if (qIsFinite(offsetX) && offsetX != r->context->state.shadowOffsetX) {
r->context->state.shadowOffsetX = offsetX;
r->context->buffer()->setShadowOffsetX(offsetX);
@@ -1976,6 +2049,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::SimpleCallCo
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1984,10 +2059,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(QV4::SimpleCallCo
QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- qreal offsetY = ctx->argument(0).toNumber();
+ qreal offsetY = ctx->argumentCount ? ctx->arguments[0].toNumber() : qSNaN();
if (qIsFinite(offsetY) && offsetY != r->context->state.shadowOffsetY) {
r->context->state.shadowOffsetY = offsetY;
r->context->buffer()->setShadowOffsetY(offsetY);
@@ -1997,6 +2074,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(QV4::SimpleCallCo
QV4::ReturnedValue QQuickJSContext2D::method_get_path(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2005,16 +2084,18 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_path(QV4::SimpleCallContext *ct
QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QV4::Value value = ctx->argument(0);
+ QV4::ScopedValue value(scope, ctx->argument(0));
r->context->beginPath();
- if (QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>()) {
+ if (QV4::QObjectWrapper *qobjectWrapper =value->as<QV4::QObjectWrapper>()) {
if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
r->context->m_path = path->path();
} else {
- QString path = value.toQStringNoThrow();
+ QString path =value->toQStringNoThrow();
QQuickSvgParser::parsePathDataFast(path, r->context->m_path);
}
r->context->m_v4path = value;
@@ -2028,6 +2109,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::SimpleCallContext *ct
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2048,6 +2131,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::SimpleCallC
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2068,6 +2153,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::SimpleCallCo
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2100,7 +2187,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::SimpleCall
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2151,7 +2239,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(QV4::SimpleCallContext
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2178,11 +2267,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::SimpleCallConte
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
-
r->context->beginPath();
return ctx->thisObject.asReturnedValue();
@@ -2209,7 +2298,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(QV4::SimpleCallC
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2257,7 +2347,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::SimpleC
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2274,7 +2365,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(QV4::SimpleCallContex
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2295,7 +2387,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(QV4::SimpleCallC
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(QV4::SimpleCallContext *ctx)
{
- QV4::Scope scope(ctx);
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r);
r->context->fill();
@@ -2487,6 +2580,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(QV4::SimpleCallCont
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(QV4::SimpleCallContext *ctx)
{
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2555,8 +2650,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_font(QV4::SimpleCallContext *ct
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString fs = ctx->argument(0).toQStringNoThrow();
- QFont font = qt_font_from_string(fs, r->context->state.font);
+ QV4::Scoped<QV4::String> s(scope, ctx->argument(0), QV4::Scoped<QV4::String>::Convert);
+ QFont font = qt_font_from_string(s->toQString(), r->context->state.font);
if (font != r->context->state.font) {
r->context->state.font = font;
}
@@ -2605,7 +2700,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::SimpleCallContex
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString textAlign = ctx->argument(0).toQStringNoThrow();
+ QV4::Scoped<QV4::String> s(scope, ctx->argument(0), QV4::Scoped<QV4::String>::Convert);
+ QString textAlign = s->toQString();
QQuickContext2D::TextAlignType ta;
if (textAlign == QStringLiteral("start"))
@@ -2669,7 +2765,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::SimpleCallCon
QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString textBaseline = ctx->argument(0).toQStringNoThrow();
+ QV4::Scoped<QV4::String> s(scope, ctx->argument(0), QV4::Scoped<QV4::String>::Convert);
+ QString textBaseline = s->toQString();
QQuickContext2D::TextBaseLineType tb;
if (textBaseline == QStringLiteral("alphabetic"))
@@ -2767,9 +2864,9 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::SimpleCal
if (ctx->argumentCount == 1) {
QFontMetrics fm(r->context->state.font);
uint width = fm.width(ctx->arguments[0].toQStringNoThrow());
- QV4::Object *tm = ctx->engine->newObject();
+ QV4::Scoped<QV4::Object> tm(scope, ctx->engine->newObject());
tm->put(ctx->engine->newIdentifier(QStringLiteral("width")), QV4::Value::fromDouble(width));
- return QV4::Value::fromObject(tm).asReturnedValue();
+ return tm.asReturnedValue();
}
return QV4::Encode::undefined();
}
@@ -2850,14 +2947,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallC
QQmlRefPointer<QQuickCanvasPixmap> pixmap;
- if (ctx->arguments[0].isString()) {
- QUrl url(ctx->arguments[0].toQStringNoThrow());
+ QV4::ScopedValue arg(scope, ctx->arguments[0]);
+ if (arg->isString()) {
+ QUrl url(arg->toQString());
if (!url.isValid())
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
pixmap = r->context->createPixmap(url);
- } else if (ctx->arguments[0].isObject()) {
- if (QV4::QObjectWrapper *qobjectWrapper = ctx->arguments[0].as<QV4::QObjectWrapper>()) {
+ } else if (arg->isObject()) {
+ if (QV4::QObjectWrapper *qobjectWrapper = arg->as<QV4::QObjectWrapper>()) {
if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
pixmap.take(r->context->createPixmap(imageItem->source()));
} else if (QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(qobjectWrapper->object())) {
@@ -2867,7 +2965,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallC
} else {
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
- } else if (QQuickJSContext2DImageData *imageData = ctx->arguments[0].as<QQuickJSContext2DImageData>()) {
+ } else if (QQuickJSContext2DImageData *imageData = arg->as<QQuickJSContext2DImageData>()) {
QQuickJSContext2DPixelData *pix = imageData->pixelData.as<QQuickJSContext2DPixelData>();
if (pix && !pix->image.isNull()) {
pixmap.take(new QQuickCanvasPixmap(pix->image, r->context->canvas()->window()));
@@ -2875,7 +2973,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallC
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
} else {
- QUrl url(ctx->arguments[0].toQStringNoThrow());
+ QUrl url(arg->toQStringNoThrow());
if (url.isValid())
pixmap = r->context->createPixmap(url);
else
@@ -3039,6 +3137,8 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(QV4::SimpleCallC
QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
{
+ QV4::ExecutionEngine *v4 = m->engine();
+ QV4::Scope scope(v4);
QQuickJSContext2DPixelData *r = m->as<QQuickJSContext2DPixelData>();
if (!m)
m->engine()->current->throwTypeError();
@@ -3069,6 +3169,8 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint
void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value)
{
+ QV4::ExecutionEngine *v4 = m->engine();
+ QV4::Scope scope(v4);
QQuickJSContext2DPixelData *r = m->as<QQuickJSContext2DPixelData>();
if (!r)
m->engine()->current->throwTypeError();
@@ -3127,15 +3229,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(QV4::Simpl
QV8Engine *engine = ctx->engine->v8Engine;
if (ctx->argumentCount == 1) {
- if (QQuickJSContext2DImageData *imgData = ctx->arguments[0].as<QQuickJSContext2DImageData>()) {
+ QV4::ScopedValue arg0(scope, ctx->arguments[0]);
+ if (QQuickJSContext2DImageData *imgData = arg0->as<QQuickJSContext2DImageData>()) {
QQuickJSContext2DPixelData *pa = imgData->pixelData.as<QQuickJSContext2DPixelData>();
if (pa) {
qreal w = pa->image.width();
qreal h = pa->image.height();
return qt_create_image_data(w, h, engine, QImage()).asReturnedValue();
}
- } else if (ctx->arguments[0].isString()) {
- QImage image = r->context->createPixmap(QUrl(ctx->arguments[0].toQStringNoThrow()))->image();
+ } else if (arg0->isString()) {
+ QImage image = r->context->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
return qt_create_image_data(image.width(), image.height(), engine, image).asReturnedValue();
}
} else if (ctx->argumentCount == 2) {
@@ -3195,7 +3298,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCa
if (ctx->argumentCount != 3 && ctx->argumentCount != 7)
return QV4::Encode::undefined();
- if (!ctx->arguments[0].isObject())
+ QV4::ScopedValue arg0(scope, ctx->arguments[0]);
+ if (!arg0->isObject())
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
qreal dx = ctx->arguments[1].toNumber();
@@ -3205,7 +3309,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCa
if (!qIsFinite(dx) || !qIsFinite(dy))
V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
- QQuickJSContext2DImageData *imageData = ctx->arguments[0].as<QQuickJSContext2DImageData>();
+ QQuickJSContext2DImageData *imageData = arg0->as<QQuickJSContext2DImageData>();
if (!imageData)
return ctx->thisObject.asReturnedValue();
@@ -4048,8 +4152,9 @@ QImage QQuickContext2D::toImage(const QRectF& bounds)
QQuickContext2DEngineData::QQuickContext2DEngineData(QV8Engine *engine)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
- QV4::Object *proto = new (v4->memoryManager) QQuickJSContext2DPrototype(v4);
+ QV4::Scoped<QV4::Object> proto(scope, new (v4->memoryManager) QQuickJSContext2DPrototype(v4));
proto->defineAccessorProperty(v4, QStringLiteral("strokeStyle"), QQuickJSContext2D::method_get_strokeStyle, QQuickJSContext2D::method_set_strokeStyle);
proto->defineAccessorProperty(v4, QStringLiteral("font"), QQuickJSContext2D::method_get_font, QQuickJSContext2D::method_set_font);
proto->defineAccessorProperty(v4, QStringLiteral("fillRule"), QQuickJSContext2D::method_get_fillRule, QQuickJSContext2D::method_set_fillRule);
@@ -4067,15 +4172,15 @@ QQuickContext2DEngineData::QQuickContext2DEngineData(QV8Engine *engine)
proto->defineAccessorProperty(v4, QStringLiteral("lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth);
proto->defineAccessorProperty(v4, QStringLiteral("textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign);
proto->defineAccessorProperty(v4, QStringLiteral("shadowBlur"), QQuickJSContext2D::method_get_shadowBlur, QQuickJSContext2D::method_set_shadowBlur);
- contextPrototype = QV4::Value::fromObject(proto);
+ contextPrototype = proto;
proto = v4->newObject();
proto->defineDefaultProperty(v4, QStringLiteral("addColorStop"), QQuickContext2DStyle::gradient_proto_addColorStop, 0);
- gradientProto = QV4::Value::fromObject(proto);
+ gradientProto = proto;
proto = v4->newObject();
proto->defineAccessorProperty(v4->id_length, QQuickJSContext2DPixelData::proto_get_length, 0);
- pixelArrayProto = QV4::Value::fromObject(proto);
+ pixelArrayProto = proto;
}
QQuickContext2DEngineData::~QQuickContext2DEngineData()
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 98a87a4bcf..341339e7b9 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3878,8 +3878,9 @@ void QQuickItem::mapFromItem(QQmlV4Function *args) const
}
QV4::ExecutionEngine *v4 = QV8Engine::getV4(args->engine());
- QV4::Object *rv = v4->newObject();
- args->setReturnValue(QV4::Value::fromObject(rv));
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> rv(scope, v4->newObject());
+ args->setReturnValue(rv.asValue());
qreal x = (args->length() > 1) ? (*args)[1].asDouble() : 0;
qreal y = (args->length() > 2) ? (*args)[2].asDouble() : 0;
@@ -3952,8 +3953,9 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const
}
QV4::ExecutionEngine *v4 = QV8Engine::getV4(args->engine());
- QV4::Object *rv = v4->newObject();
- args->setReturnValue(QV4::Value::fromObject(rv));
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> rv(scope, v4->newObject());
+ args->setReturnValue(rv.asValue());
qreal x = (args->length() > 1) ? (*args)[1].asDouble() : 0;
qreal y = (args->length() > 2) ? (*args)[2].asDouble() : 0;