aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4codegen.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/qv4codegen.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/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp78
1 files changed, 14 insertions, 64 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index ac596e2b5b..09c0e60f4d 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2243,85 +2243,35 @@ bool Codegen::visit(TaggedTemplate *ast)
break;
}
- int arrayTemp = createTemplateArray(ast->templateLiteral);
- Q_UNUSED(arrayTemp);
+ createTemplateObject(ast->templateLiteral);
+ int templateObjectTemp = Reference::fromAccumulator(this).storeOnStack().stackSlot();
+ Q_UNUSED(templateObjectTemp);
auto calldata = pushTemplateArgs(ast->templateLiteral);
if (hasError)
return false;
++calldata.argc;
- Q_ASSERT(calldata.argv == arrayTemp + 1);
+ Q_ASSERT(calldata.argv == templateObjectTemp + 1);
--calldata.argv;
handleCall(base, calldata, functionObject, thisObject);
return false;
}
-int Codegen::createTemplateArray(TemplateLiteral *t)
+void Codegen::createTemplateObject(TemplateLiteral *t)
{
- int arrayTemp = bytecodeGenerator->newRegister();
+ TemplateObject obj;
- int argc = 0;
- int args = -1;
- auto push = [this, &argc, &args](const QStringRef &arg) {
- int temp = bytecodeGenerator->newRegister();
- if (args == -1)
- args = temp;
- Instruction::LoadRuntimeString instr;
- instr.stringId = registerString(arg.toString());
- bytecodeGenerator->addInstruction(instr);
- Instruction::StoreReg store;
- store.reg = temp;
- bytecodeGenerator->addInstruction(store);
-
- ++argc;
- };
-
- {
- RegisterScope scope(this);
-
- for (TemplateLiteral *it = t; it; it = it->next)
- push(it->value);
-
- if (args == -1) {
- Q_ASSERT(argc == 0);
- args = 0;
- }
-
- Instruction::DefineArray call;
- call.argc = argc;
- call.args = Moth::StackSlot::createRegister(args);
- bytecodeGenerator->addInstruction(call);
-
- Instruction::StoreReg store;
- store.reg = arrayTemp;
- bytecodeGenerator->addInstruction(store);
+ for (TemplateLiteral *it = t; it; it = it->next) {
+ obj.strings.append(registerString(it->value.toString()));
+ obj.rawStrings.append(registerString(it->rawValue.toString()));
}
- {
- RegisterScope scope(this);
-
- argc = 0;
- args = -1;
-
- for (TemplateLiteral *it = t; it; it = it->next)
- push(it->rawValue);
-
- if (args == -1) {
- Q_ASSERT(argc == 0);
- args = 0;
- }
-
- Instruction::DefineArray call;
- call.argc = argc;
- call.args = Moth::StackSlot::createRegister(args);
- bytecodeGenerator->addInstruction(call);
-
- Reference a = Reference::fromStackSlot(this, arrayTemp);
- Reference m = Reference::fromMember(a, QStringLiteral("raw"));
- m.storeConsumeAccumulator();
- }
+ int index = _module->templateObjects.size();
+ _module->templateObjects.append(obj);
- return arrayTemp;
+ Instruction::GetTemplateObject getTemplateObject;
+ getTemplateObject.index = index;
+ bytecodeGenerator->addInstruction(getTemplateObject);
}
bool Codegen::visit(FunctionExpression *ast)