diff options
| author | Lars Knoll <lars.knoll@qt.io> | 2018-04-03 21:15:18 +0200 |
|---|---|---|
| committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-02 14:17:25 +0000 |
| commit | 9934514db7ec46f1c57d82e54e61c02b35bfd357 (patch) | |
| tree | 422d1db77b9c65b52e559a38a4cf3e84adc9613c /src/qml/compiler/qv4compilercontext.cpp | |
| parent | 851c28d140c398990513640047a20aab36ccc655 (diff) | |
Split out the generation of indices for locals and registers
Change-Id: I0e98ccba9ae3026cd8bfdc4cae100f280b5aa22c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compilercontext.cpp')
| -rw-r--r-- | src/qml/compiler/qv4compilercontext.cpp | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp index 1c583b5cf2..e2e978be7c 100644 --- a/src/qml/compiler/qv4compilercontext.cpp +++ b/src/qml/compiler/qv4compilercontext.cpp @@ -163,10 +163,12 @@ Context::ResolvedName Context::resolveName(const QString &name) void Context::emitHeaderBytecode(Codegen *codegen) { + using Instruction = Moth::Instruction; Moth::BytecodeGenerator *bytecodeGenerator = codegen->generator(); - bool allVarsEscape = hasWith || hasTry || hasDirectEval; + setupFunctionIndices(bytecodeGenerator); + if (requiresExecutionContext || type == ContextType::Binding) { // we don't really need this for bindings, but we do for signal handlers, and we don't know if the code is a signal handler or not. Instruction::CreateCallContext createContext; @@ -181,26 +183,14 @@ void Context::emitHeaderBytecode(Codegen *codegen) // variables in global code are properties of the global context object, not locals as with other functions. if (type == ContextType::Function || type == ContextType::Binding) { for (Context::MemberMap::iterator it = members.begin(), end = members.end(); it != end; ++it) { - const QString &local = it.key(); - if (allVarsEscape) - it->canEscape = true; - if (it->canEscape) { - it->index = locals.size(); - locals.append(local); - if (it->type == Context::ThisFunctionName) { - // move the name from the stack to the call context - Instruction::LoadReg load; - load.reg = CallData::Function; - bytecodeGenerator->addInstruction(load); - Instruction::StoreLocal store; - store.index = it->index; - bytecodeGenerator->addInstruction(store); - } - } else { - if (it->type == Context::ThisFunctionName) - it->index = CallData::Function; - else - it->index = bytecodeGenerator->newRegister(); + if (it->canEscape && it->type == Context::ThisFunctionName) { + // move the function from the stack to the call context + Instruction::LoadReg load; + load.reg = CallData::Function; + bytecodeGenerator->addInstruction(load); + Instruction::StoreLocal store; + store.index = it->index; + bytecodeGenerator->addInstruction(store); } } } else { @@ -226,4 +216,27 @@ void Context::emitHeaderBytecode(Codegen *codegen) } } +void Context::setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator) +{ + Q_ASSERT(locals.size() == 0); + Q_ASSERT(nRegisters == 0); + registerOffset = bytecodeGenerator->registerCount(); + + if (type == ContextType::Function || type == ContextType::Binding) { + for (Context::MemberMap::iterator it = members.begin(), end = members.end(); it != end; ++it) { + const QString &local = it.key(); + if (it->canEscape) { + it->index = locals.size(); + locals.append(local); + } else { + if (it->type == Context::ThisFunctionName) + it->index = CallData::Function; + else + it->index = bytecodeGenerator->newRegister(); + } + } + } + nRegisters = bytecodeGenerator->registerCount() - registerOffset; +} + QT_END_NAMESPACE |
