diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-10-15 10:22:47 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-11-05 21:15:39 +0000 |
commit | b1f07986c30978ed6636457e8d3f4a65c5db38a3 (patch) | |
tree | 6dd48a2901219b4268a95b9d5acd08a3c49988c0 /src/qml/compiler/qv4codegen.cpp | |
parent | 0fce92af2cab51d03f33230718ab5ae35149b9e1 (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.cpp | 78 |
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) |