aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compileddata.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-10-15 10:22:47 +0200
committerLars Knoll <lars.knoll@qt.io>2018-11-05 21:15:39 +0000
commitb1f07986c30978ed6636457e8d3f4a65c5db38a3 (patch)
tree6dd48a2901219b4268a95b9d5acd08a3c49988c0 /src/qml/compiler/qv4compileddata.cpp
parent0fce92af2cab51d03f33230718ab5ae35149b9e1 (diff)
Create proper template objects for tagged templates
If a tagged template gets evaluated multiple times, the underlying template object is shared. Change-Id: Ie2f476fbc93d5991322ce1087c42719a8d8333ae Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compileddata.cpp')
-rw-r--r--src/qml/compiler/qv4compileddata.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 244e762faf..3b2d6e0a48 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -225,6 +225,36 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
return nullptr;
}
+Heap::Object *CompilationUnit::templateObjectAt(int index) const
+{
+ Q_ASSERT(index < int(data->templateObjectTableSize));
+ if (!templateObjects.size())
+ templateObjects.resize(data->templateObjectTableSize);
+ Heap::Object *o = templateObjects.at(index);
+ if (o)
+ return o;
+
+ // create the template object
+ Scope scope(engine);
+ const CompiledData::TemplateObject *t = data->templateObjectAt(index);
+ Scoped<ArrayObject> a(scope, engine->newArrayObject(t->size));
+ Scoped<ArrayObject> raw(scope, engine->newArrayObject(t->size));
+ ScopedValue s(scope);
+ for (uint i = 0; i < t->size; ++i) {
+ s = runtimeStrings[t->stringIndexAt(i)];
+ a->arraySet(i, s);
+ s = runtimeStrings[t->rawStringIndexAt(i)];
+ raw->arraySet(i, s);
+ }
+
+ ObjectPrototype::method_freeze(engine->functionCtor(), nullptr, raw, 1);
+ a->defineReadonlyProperty(QStringLiteral("raw"), raw);
+ ObjectPrototype::method_freeze(engine->functionCtor(), nullptr, a, 1);
+
+ templateObjects[index] = a->objectValue()->d();
+ return templateObjects.at(index);
+}
+
void CompilationUnit::unlink()
{
if (engine)
@@ -284,6 +314,10 @@ void CompilationUnit::markObjects(QV4::MarkStack *markStack)
if (c)
c->mark(markStack);
+ for (QV4::Heap::Object *o : qAsConst(templateObjects))
+ if (o)
+ o->mark(markStack);
+
if (runtimeLookups) {
for (uint i = 0; i < data->lookupTableSize; ++i)
runtimeLookups[i].markObjects(markStack);