18Context *Module::newContext(Node *node, Context *parent, ContextType contextType)
20 Q_ASSERT(!contextMap.contains(node));
22 Context *c =
new Context(parent, contextType);
24 SourceLocation loc = node->firstSourceLocation();
25 c->line = loc.startLine;
26 c->column = loc.startColumn;
29 contextMap.insert(node, c);
34 parent->nestedContexts.append(c);
35 c->isStrict = parent->isStrict;
65 if (formals && formals->containsName(name))
66 return (scope == VariableScope::Var);
68 if (!isCatchBlock || name != caughtVariable) {
69 MemberMap::iterator it =
members.find(name);
71 if (scope != VariableScope::Var || (*it).scope != VariableScope::Var)
73 if ((*it).type <= type) {
75 (*it).function = function;
82 if (contextType == ContextType::Block && (scope == VariableScope::Var && type != MemberType::FunctionDefinition))
83 return parent->addLocalVar(name, type, scope, function, declarationLocation);
87 m.function = function;
89 m.declarationLocation = declarationLocation;
185 codegen->module()->blocks.append(
this);
186 blockIndex = codegen->module()->blocks.size() - 1;
190 Instruction::PushScriptContext scriptContext;
192 bytecodeGenerator->addInstruction(scriptContext);
195 Instruction::PushCatchContext catchContext;
197 catchContext.name = codegen->registerString(caughtVariable);
198 bytecodeGenerator->addInstruction(catchContext);
200 Instruction::PushBlockContext blockContext;
202 bytecodeGenerator->addInstruction(blockContext);
205 Instruction::CreateCallContext createContext;
206 bytecodeGenerator->addInstruction(createContext);
211 Instruction::InitializeBlockDeadTemporalZone tdzInit;
214 bytecodeGenerator->addInstruction(tdzInit);
220 Instruction::ConvertThisToObject convert;
221 bytecodeGenerator->addInstruction(convert);
224 Instruction::LoadReg load;
225 load.reg = CallData::This;
226 bytecodeGenerator->addInstruction(load);
227 Codegen::Reference r = codegen->referenceForName(QStringLiteral(
"this"),
true);
228 r.storeConsumeAccumulator();
231 Instruction::LoadReg load;
232 load.reg = CallData::NewTarget;
233 bytecodeGenerator->addInstruction(load);
234 Codegen::Reference r = codegen->referenceForName(QStringLiteral(
"new.target"),
true);
235 r.storeConsumeAccumulator();
240 for (Context::MemberMap::const_iterator it =
members.constBegin(), cend = members.constEnd(); it != cend; ++it) {
241 if (it->isLexicallyScoped())
243 const QString &local = it.key();
245 Instruction::DeclareVar declareVar;
246 declareVar.isDeletable = (contextType == ContextType::Eval);
247 declareVar.varName = codegen->registerString(local);
248 bytecodeGenerator->addInstruction(declareVar);
253 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
254 if (it->canEscape && it->type == Context::ThisFunctionName) {
256 Instruction::LoadReg load;
257 load.reg = CallData::Function;
258 bytecodeGenerator->addInstruction(load);
259 Instruction::StoreLocal store;
260 store.index = it->index;
261 bytecodeGenerator->addInstruction(store);
268 if (isStrict || (formals && !formals->isSimpleParameterList())) {
269 Instruction::CreateUnmappedArgumentsObject setup;
270 bytecodeGenerator->addInstruction(setup);
272 Instruction::CreateMappedArgumentsObject setup;
273 bytecodeGenerator->addInstruction(setup);
275 codegen->referenceForName(QStringLiteral(
"arguments"),
false).storeConsumeAccumulator();
278 for (
const Context::Member &member : std::as_const(members)) {
279 if (member.function) {
280 const int function = codegen->defineFunction(member.function->name.toString(), member.function, member.function->formals, member.function->body);
281 codegen->loadClosure(function);
282 Codegen::Reference r = codegen->referenceForName(member.function->name.toString(),
true);
283 r.storeConsumeAccumulator();
313 Q_ASSERT(locals.size() == 0);
317 QList<Context::MemberMap::Iterator> localsInTDZ;
318 const auto registerLocal = [
this, &localsInTDZ](Context::MemberMap::iterator member) {
319 if (member->isLexicallyScoped()) {
320 localsInTDZ << member;
322 member->index = locals.size();
323 locals.append(member.key());
327 QList<Context::MemberMap::Iterator> registersInTDZ;
328 const auto allocateRegister = [bytecodeGenerator, ®istersInTDZ](Context::MemberMap::iterator member) {
329 if (member->isLexicallyScoped())
330 registersInTDZ << member;
340 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
344 if (it->type == Context::ThisFunctionName)
345 it->index = CallData::Function;
347 allocateRegister(it);
355 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
356 if (!it->isLexicallyScoped() && (contextType == ContextType::Global || contextType == ContextType::ScriptImportedByQML || !isStrict))
361 allocateRegister(it);
367 for (
auto &member: std::as_const(localsInTDZ)) {
368 member->index = locals.size();
369 locals.append(member.key());
372 if (contextType == ContextType::ESModule && !localNameForDefaultExport.isEmpty()) {
373 if (!
members.contains(localNameForDefaultExport)) {
376 locals.append(localNameForDefaultExport);
383 for (
auto &member: std::as_const(registersInTDZ))
384 member->index = bytecodeGenerator->newRegister();
void emitBlockFooter(Compiler::Codegen *codegen)
void emitBlockHeader(Compiler::Codegen *codegen)
UsesArgumentsObject usesArgumentsObject
void setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)