aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-11-02 18:48:18 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-25 22:04:42 +0100
commita41764cafbc85c271edde8d09eae46798ccdcb8d (patch)
treecb027ea57c6f764bdc277bf899caa3f8a866647b /src/qml
parent62c906059516bb829f05073096fd3e12f5103fba (diff)
IR Cleanup, resolve ID objects through array subscripts
...instead of a special MEMBER type. This allows removing the type member from V4IR::Member altogether (and thus unshadow from V4IR::Expr::type). By not requiring the base of a id lookup member expression to be a NAME, we can also speed up repeated id lookups by fetching the id object array wrapper only once per function. Change-Id: I3e9b8f498d32ace4a0cc2254f49e02ecc124f79c Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp12
-rw-r--r--src/qml/compiler/qqmlcodegenerator_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h7
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp4
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h2
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp5
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h2
-rw-r--r--src/qml/compiler/qv4isel_p.cpp12
-rw-r--r--src/qml/compiler/qv4isel_p.h2
-rw-r--r--src/qml/compiler/qv4jsir.cpp18
-rw-r--r--src/qml/compiler/qv4jsir_p.h30
-rw-r--r--src/qml/compiler/qv4regalloc.cpp3
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp5
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp6
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp58
-rw-r--r--src/qml/qml/qqmlcontextwrapper_p.h17
17 files changed, 114 insertions, 73 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 4e1d2ef9c8..b38e2670e6 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1213,6 +1213,7 @@ JSCodeGen::JSCodeGen(QQmlEnginePrivate *enginePrivate, const QString &fileName,
, _contextObjectTemp(-1)
, _scopeObjectTemp(-1)
, _importedScriptsTemp(-1)
+ , _idArrayTemp(-1)
{
_module = jsModule;
_module->setFileName(fileName);
@@ -1372,6 +1373,7 @@ void JSCodeGen::beginFunctionBodyHook()
_contextObjectTemp = _block->newTemp();
_scopeObjectTemp = _block->newTemp();
_importedScriptsTemp = _block->newTemp();
+ _idArrayTemp = _block->newTemp();
V4IR::Temp *temp = _block->TEMP(_contextObjectTemp);
initMetaObjectResolver(&temp->memberResolver, _contextObject);
@@ -1382,6 +1384,7 @@ void JSCodeGen::beginFunctionBodyHook()
move(temp, _block->NAME(V4IR::Name::builtin_qml_scope_object, 0, 0));
move(_block->TEMP(_importedScriptsTemp), _block->NAME(V4IR::Name::builtin_qml_imported_scripts_object, 0, 0));
+ move(_block->TEMP(_idArrayTemp), _block->NAME(V4IR::Name::builtin_qml_id_array, 0, 0));
}
V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col)
@@ -1403,8 +1406,13 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col
foreach (const IdMapping &mapping, _idObjects)
if (name == mapping.name) {
_function->idObjectDependencies.insert(mapping.idIndex);
- return _block->QML_CONTEXT_MEMBER(_block->NAME(V4IR::Name::builtin_qml_id_scope, line, col),
- _function->newString(mapping.name), mapping.idIndex);
+ V4IR::Expr *s = subscript(_block->TEMP(_idArrayTemp), _block->CONST(V4IR::SInt32Type, mapping.idIndex));
+ V4IR::Temp *result = _block->TEMP(_block->newTemp());
+ initMetaObjectResolver(&result->memberResolver, mapping.type);
+ _block->MOVE(result, s);
+ result = _block->TEMP(result->index);
+ result->isReadOnly = true; // don't allow use as lvalue
+ return result;
}
{
diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h
index 4f80a7f148..636f2827bb 100644
--- a/src/qml/compiler/qqmlcodegenerator_p.h
+++ b/src/qml/compiler/qqmlcodegenerator_p.h
@@ -381,7 +381,7 @@ private:
int _contextObjectTemp;
int _scopeObjectTemp;
int _importedScriptsTemp;
- int _idScopeTemp;
+ int _idArrayTemp;
};
} // namespace QtQml
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index a2b8c870a5..5c92439f0c 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -126,7 +126,7 @@ QT_BEGIN_NAMESPACE
F(MulNumberParams, mulNumberParams) \
F(SubNumberParams, subNumberParams) \
F(LoadThis, loadThis) \
- F(LoadQmlIdObject, loadQmlIdObject) \
+ F(LoadQmlIdArray, loadQmlIdArray) \
F(LoadQmlImportedScripts, loadQmlImportedScripts) \
F(LoadQmlContextObject, loadQmlContextObject) \
F(LoadQmlScopeObject, loadQmlScopeObject)
@@ -654,10 +654,9 @@ union Instr
MOTH_INSTR_HEADER
Param result;
};
- struct instr_loadQmlIdObject {
+ struct instr_loadQmlIdArray {
MOTH_INSTR_HEADER
Param result;
- int id;
};
struct instr_loadQmlImportedScripts {
MOTH_INSTR_HEADER
@@ -749,7 +748,7 @@ union Instr
instr_mulNumberParams mulNumberParams;
instr_subNumberParams subNumberParams;
instr_loadThis loadThis;
- instr_loadQmlIdObject loadQmlIdObject;
+ instr_loadQmlIdArray loadQmlIdArray;
instr_loadQmlImportedScripts loadQmlImportedScripts;
instr_loadQmlContextObject loadQmlContextObject;
instr_loadQmlScopeObject loadQmlScopeObject;
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 6f8bf13bd7..0854dd55ab 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -880,9 +880,9 @@ void InstructionSelection::loadThisObject(V4IR::Temp *temp)
#endif
}
-void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp)
+void InstructionSelection::loadQmlIdArray(V4IR::Temp *temp)
{
- generateFunctionCall(temp, __qmljs_get_id_object, Assembler::ContextRegister, Assembler::TrustedImm32(id));
+ generateFunctionCall(temp, __qmljs_get_id_array, Assembler::ContextRegister);
}
void InstructionSelection::loadQmlImportedScripts(V4IR::Temp *temp)
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index 0c2c994e32..5a02b62a73 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -1457,7 +1457,7 @@ protected:
virtual void callSubscript(V4IR::Expr *base, V4IR::Expr *index, V4IR::ExprList *args, V4IR::Temp *result);
virtual void convertType(V4IR::Temp *source, V4IR::Temp *target);
virtual void loadThisObject(V4IR::Temp *temp);
- virtual void loadQmlIdObject(int id, V4IR::Temp *temp);
+ virtual void loadQmlIdArray(V4IR::Temp *temp);
virtual void loadQmlImportedScripts(V4IR::Temp *temp);
virtual void loadQmlContextObject(V4IR::Temp *temp);
virtual void loadQmlScopeObject(V4IR::Temp *temp);
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 1b973b2359..c76c236de4 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -388,11 +388,10 @@ void InstructionSelection::loadThisObject(V4IR::Temp *temp)
addInstruction(load);
}
-void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp)
+void InstructionSelection::loadQmlIdArray(V4IR::Temp *temp)
{
- Instruction::LoadQmlIdObject load;
+ Instruction::LoadQmlIdArray load;
load.result = getResultParam(temp);
- load.id = id;
addInstruction(load);
}
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index ef26ba875d..bde7997c33 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -112,7 +112,7 @@ protected:
virtual void constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result);
virtual void constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result);
virtual void loadThisObject(V4IR::Temp *temp);
- virtual void loadQmlIdObject(int id, V4IR::Temp *temp);
+ virtual void loadQmlIdArray(V4IR::Temp *temp);
virtual void loadQmlImportedScripts(V4IR::Temp *temp);
virtual void loadQmlContextObject(V4IR::Temp *temp);
virtual void loadQmlScopeObject(V4IR::Temp *temp);
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index b3407867b4..a14a11c43e 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -103,6 +103,8 @@ void IRDecoder::visitMove(V4IR::Move *s)
if (V4IR::Name *n = s->source->asName()) {
if (n->id && *n->id == QStringLiteral("this")) // TODO: `this' should be a builtin.
loadThisObject(t);
+ else if (n->builtin == V4IR::Name::builtin_qml_id_array)
+ loadQmlIdArray(t);
else if (n->builtin == V4IR::Name::builtin_qml_context_object)
loadQmlContextObject(t);
else if (n->builtin == V4IR::Name::builtin_qml_scope_object)
@@ -142,15 +144,7 @@ void IRDecoder::visitMove(V4IR::Move *s)
return;
}
} else if (V4IR::Member *m = s->source->asMember()) {
- if (m->type == V4IR::Member::MemberOfQmlContext) {
- V4IR::Name *base = m->base->asName();
- Q_ASSERT(base);
-
- if (base->builtin == V4IR::Name::builtin_qml_id_scope) {
- loadQmlIdObject(m->memberIndex, t);
- return;
- }
- } else if (m->property) {
+ if (m->property) {
bool captureRequired = true;
if (_function) {
captureRequired = !_function->contextObjectDependencies.contains(m->property)
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index 647d85996d..6671ac1426 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -144,7 +144,7 @@ public: // to implement by subclasses:
virtual void constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result) = 0;
virtual void constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result) = 0;
virtual void loadThisObject(V4IR::Temp *temp) = 0;
- virtual void loadQmlIdObject(int id, V4IR::Temp *temp) = 0;
+ virtual void loadQmlIdArray(V4IR::Temp *temp) = 0;
virtual void loadQmlImportedScripts(V4IR::Temp *temp) = 0;
virtual void loadQmlContextObject(V4IR::Temp *temp) = 0;
virtual void loadQmlScopeObject(V4IR::Temp *temp) = 0;
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index 949a73432d..79b963f400 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -433,8 +433,8 @@ static const char *builtin_to_string(Name::Builtin b)
return "builtin_setup_argument_object";
case V4IR::Name::builtin_convert_this_to_object:
return "builtin_convert_this_to_object";
- case V4IR::Name::builtin_qml_id_scope:
- return "builtin_qml_id_scope";
+ case V4IR::Name::builtin_qml_id_array:
+ return "builtin_qml_id_array";
case V4IR::Name::builtin_qml_imported_scripts_object:
return "builtin_qml_imported_scripts_object";
case V4IR::Name::builtin_qml_scope_object:
@@ -841,13 +841,6 @@ Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *prop
return e;
}
-Expr *BasicBlock::QML_CONTEXT_MEMBER(Expr *base, const QString *id, int memberIndex)
-{
- Member*e = function->New<Member>();
- e->initQmlContextMember(base, id, memberIndex);
- return e;
-}
-
Stmt *BasicBlock::EXP(Expr *expr)
{
if (isTerminated())
@@ -1034,12 +1027,7 @@ void CloneExpr::visitSubscript(Subscript *e)
void CloneExpr::visitMember(Member *e)
{
- if (e->type == Member::MemberByName)
- cloned = block->MEMBER(clone(e->base), e->name, e->property);
- else if (e->type == Member::MemberOfQmlContext)
- cloned = block->QML_CONTEXT_MEMBER(clone(e->base), e->name, e->memberIndex);
- else
- Q_ASSERT(!"Unimplemented!");
+ cloned = block->MEMBER(clone(e->base), e->name, e->property);
}
} // end of namespace IR
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 5fd58acba4..fd54460b5c 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -343,7 +343,7 @@ struct Name: Expr {
builtin_define_object_literal,
builtin_setup_argument_object,
builtin_convert_this_to_object,
- builtin_qml_id_scope,
+ builtin_qml_id_array,
builtin_qml_imported_scripts_object,
builtin_qml_context_object,
builtin_qml_scope_object
@@ -378,9 +378,10 @@ struct Temp: Expr {
};
unsigned index;
- unsigned scope : 28; // how many scopes outside the current one?
+ unsigned scope : 27; // how many scopes outside the current one?
unsigned kind : 3;
unsigned isArgumentsOrEval : 1;
+ unsigned isReadOnly : 1;
// Used when temp is used as base in member expression
MemberExpressionResolver memberResolver;
@@ -394,10 +395,11 @@ struct Temp: Expr {
this->index = index;
this->scope = scope;
this->isArgumentsOrEval = false;
+ this->isReadOnly = false;
}
virtual void accept(ExprVisitor *v) { v->visitTemp(this); }
- virtual bool isLValue() { return true; }
+ virtual bool isLValue() { return !isReadOnly; }
virtual Temp *asTemp() { return this; }
virtual void dump(QTextStream &out) const;
@@ -538,38 +540,19 @@ struct Subscript: Expr {
};
struct Member: Expr {
- enum MemberType {
- MemberByName,
- // QML extensions
- MemberOfQmlContext // lookup in context's id values
- };
-
- MemberType type;
Expr *base;
const QString *name;
- int memberIndex; // used if type == MemberOfQmlContext
QQmlPropertyData *property;
void init(Expr *base, const QString *name, QQmlPropertyData *property = 0)
{
- this->type = MemberByName;
this->base = base;
this->name = name;
- this->memberIndex = -1;
this->property = property;
}
- void initQmlContextMember(Expr *base, const QString *name, int memberIndex)
- {
- this->type = MemberOfQmlContext;
- this->base = base;
- this->name = name;
- this->memberIndex = memberIndex;
- this->property = 0;
- }
-
virtual void accept(ExprVisitor *v) { v->visitMember(this); }
- virtual bool isLValue() { return type != MemberOfQmlContext; }
+ virtual bool isLValue() { return true; }
virtual Member *asMember() { return this; }
virtual void dump(QTextStream &out) const;
@@ -872,7 +855,6 @@ struct BasicBlock {
Expr *NEW(Expr *base, ExprList *args = 0);
Expr *SUBSCRIPT(Expr *base, Expr *index);
Expr *MEMBER(Expr *base, const QString *name, QQmlPropertyData *property = 0);
- Expr *QML_CONTEXT_MEMBER(Expr *base, const QString *id, int memberIndex);
Stmt *EXP(Expr *expr);
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index a0245c6808..a1594da82e 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -338,9 +338,8 @@ protected: // IRDecoder
addDef(temp);
}
- virtual void loadQmlIdObject(int id, V4IR::Temp *temp)
+ virtual void loadQmlIdArray(V4IR::Temp *temp)
{
- Q_UNUSED(id);
addDef(temp);
addCall();
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 4c0573ceaf..fbd4496875 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1242,10 +1242,9 @@ ReturnedValue __qmljs_lookup_runtime_regexp(ExecutionContext *ctx, int id)
return ctx->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
}
-ReturnedValue __qmljs_get_id_object(NoThrowContext *ctx, int id)
+ReturnedValue __qmljs_get_id_array(NoThrowContext *ctx)
{
- QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
- return QObjectWrapper::wrap(ctx->engine, context->idValues[id].data());
+ return ctx->engine->qmlContextObject()->getPointer()->as<QmlContextWrapper>()->idObjectsArray();
}
ReturnedValue __qmljs_get_context_object(NoThrowContext *ctx)
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 194523727f..935ccd2012 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -171,7 +171,7 @@ QV4::ReturnedValue __qmljs_construct_global_lookup(QV4::ExecutionContext *contex
QV4::ReturnedValue __qmljs_get_element(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::ValueRef index);
void __qmljs_set_element(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::ValueRef index, const QV4::ValueRef value);
-QV4::ReturnedValue __qmljs_get_id_object(NoThrowContext *ctx, int id);
+QV4::ReturnedValue __qmljs_get_id_array(NoThrowContext *ctx);
QV4::ReturnedValue __qmljs_get_imported_scripts(NoThrowContext *ctx);
QV4::ReturnedValue __qmljs_get_context_object(NoThrowContext *ctx);
QV4::ReturnedValue __qmljs_get_scope_object(NoThrowContext *ctx);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 98b446ef2e..944fe6e514 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -657,9 +657,9 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
VALUE(instr.result) = context->callData->thisObject;
MOTH_END_INSTR(LoadThis)
- MOTH_BEGIN_INSTR(LoadQmlIdObject)
- VALUE(instr.result) = __qmljs_get_id_object(static_cast<QV4::NoThrowContext*>(context), instr.id);
- MOTH_END_INSTR(LoadQmlIdObject)
+ MOTH_BEGIN_INSTR(LoadQmlIdArray)
+ VALUE(instr.result) = __qmljs_get_id_array(static_cast<QV4::NoThrowContext*>(context));
+ MOTH_END_INSTR(LoadQmlIdArray)
MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
VALUE(instr.result) = __qmljs_get_imported_scripts(static_cast<QV4::NoThrowContext*>(context));
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 406826a6f6..cbfc5468fe 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -63,7 +63,7 @@ DEFINE_MANAGED_VTABLE(QmlContextWrapper);
QmlContextWrapper::QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext)
: Object(QV8Engine::getV4(engine)),
v8(engine), readOnly(true), ownsContext(ownsContext), isNullWrapper(false),
- context(context), scopeObject(scopeObject)
+ context(context), scopeObject(scopeObject), idObjectsWrapper(0)
{
vtbl = &static_vtbl;
}
@@ -355,6 +355,14 @@ void QmlContextWrapper::destroy(Managed *that)
static_cast<QmlContextWrapper *>(that)->~QmlContextWrapper();
}
+void QmlContextWrapper::markObjects(Managed *m, ExecutionEngine *engine)
+{
+ QmlContextWrapper *This = static_cast<QmlContextWrapper*>(m);
+ if (This->idObjectsWrapper)
+ This->idObjectsWrapper->mark(engine);
+ Object::markObjects(m, engine);
+}
+
void QmlContextWrapper::registerQmlDependencies(ExecutionEngine *engine, const CompiledData::Function *compiledFunction)
{
// Let the caller check and avoid the function call :)
@@ -395,4 +403,52 @@ void QmlContextWrapper::registerQmlDependencies(ExecutionEngine *engine, const C
}
+ReturnedValue QmlContextWrapper::idObjectsArray()
+{
+ if (!idObjectsWrapper) {
+ ExecutionEngine *v4 = engine();
+ idObjectsWrapper = new (v4->memoryManager) QQmlIdObjectsArray(v4, this);
+ }
+ return idObjectsWrapper->asReturnedValue();
+}
+
+DEFINE_MANAGED_VTABLE(QQmlIdObjectsArray);
+
+QQmlIdObjectsArray::QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrapper *contextWrapper)
+ : Object(engine)
+ , contextWrapper(contextWrapper)
+{
+ vtbl = &static_vtbl;
+}
+
+ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasProperty)
+{
+ QQmlIdObjectsArray *This = static_cast<QQmlIdObjectsArray*>(m);
+ QQmlContextData *context = This->contextWrapper->getContext();
+ if (!context) {
+ if (hasProperty)
+ *hasProperty = false;
+ return Encode::undefined();
+ }
+ if (index >= (uint)context->idValueCount) {
+ if (hasProperty)
+ *hasProperty = false;
+ return Encode::undefined();
+ }
+
+ ExecutionEngine *v4 = m->engine();
+ QQmlEnginePrivate *ep = v4->v8Engine->engine() ? QQmlEnginePrivate::get(v4->v8Engine->engine()) : 0;
+ if (ep)
+ ep->captureProperty(&context->idValues[index].bindings);
+
+ return QObjectWrapper::wrap(This->engine(), context->idValues[index].data());
+}
+
+void QQmlIdObjectsArray::markObjects(Managed *that, ExecutionEngine *engine)
+{
+ QQmlIdObjectsArray *This = static_cast<QQmlIdObjectsArray*>(that);
+ This->contextWrapper->mark(engine);
+ Object::markObjects(that, engine);
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h
index d85f440b15..603a5af2fd 100644
--- a/src/qml/qml/qqmlcontextwrapper_p.h
+++ b/src/qml/qml/qqmlcontextwrapper_p.h
@@ -69,6 +69,8 @@ namespace CompiledData {
struct Function;
}
+struct QQmlIdObjectsArray;
+
struct Q_QML_EXPORT QmlContextWrapper : Object
{
Q_MANAGED
@@ -90,9 +92,11 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
static void put(Managed *m, const StringRef name, const ValueRef value);
static void destroy(Managed *that);
+ static void markObjects(Managed *m, ExecutionEngine *engine);
static void registerQmlDependencies(ExecutionEngine *context, const CompiledData::Function *compiledFunction);
+ ReturnedValue idObjectsArray();
QV8Engine *v8; // ### temporary, remove
bool readOnly;
@@ -101,6 +105,19 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
QQmlGuardedContextData context;
QPointer<QObject> scopeObject;
+private:
+ QQmlIdObjectsArray *idObjectsWrapper;
+};
+
+struct QQmlIdObjectsArray : public Object
+{
+ Q_MANAGED
+ QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrapper *contextWrapper);
+
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static void markObjects(Managed *that, ExecutionEngine *engine);
+
+ QmlContextWrapper *contextWrapper;
};
}