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>
This commit is contained in:
parent
a0f8be4021
commit
e441692b0b
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
@ -225,6 +219,16 @@ struct Scoped
|
|||
++scope.size;
|
||||
#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)
|
||||
{
|
||||
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue