17Context *Module::newContext(Node *node, Context *parent, ContextType contextType)
19 Q_ASSERT(!contextMap.contains(node));
21 Context *c =
new Context(parent, contextType);
23 SourceLocation loc = node->firstSourceLocation();
24 c->line = loc.startLine;
25 c->column = loc.startColumn;
28 contextMap.insert(node, c);
33 parent->nestedContexts.append(c);
34 c->isStrict = parent->isStrict;
64 if (formals && formals->containsName(name))
65 return (scope == VariableScope::Var);
67 if (!isCatchBlock || name != caughtVariable) {
68 MemberMap::iterator it =
members.find(name);
70 if (scope != VariableScope::Var || (*it).scope != VariableScope::Var)
72 if ((*it).type <= type) {
74 (*it).function = function;
81 if (contextType == ContextType::Block && (scope == VariableScope::Var && type != MemberType::FunctionDefinition))
82 return parent->addLocalVar(name, type, scope, function, declarationLocation);
86 m.function = function;
88 m.declarationLocation = declarationLocation;
184 codegen->module()->blocks.append(
this);
185 blockIndex = codegen->module()->blocks.size() - 1;
189 Instruction::PushScriptContext scriptContext;
191 bytecodeGenerator->addInstruction(scriptContext);
194 Instruction::PushCatchContext catchContext;
196 catchContext.name = codegen->registerString(caughtVariable);
197 bytecodeGenerator->addInstruction(catchContext);
199 Instruction::PushBlockContext blockContext;
201 bytecodeGenerator->addInstruction(blockContext);
204 Instruction::CreateCallContext createContext;
205 bytecodeGenerator->addInstruction(createContext);
210 Instruction::InitializeBlockDeadTemporalZone tdzInit;
213 bytecodeGenerator->addInstruction(tdzInit);
219 Instruction::ConvertThisToObject convert;
220 bytecodeGenerator->addInstruction(convert);
223 Instruction::LoadReg load;
224 load.reg = CallData::This;
225 bytecodeGenerator->addInstruction(load);
226 Codegen::Reference r = codegen->referenceForName(QStringLiteral(
"this"),
true);
227 r.storeConsumeAccumulator();
230 Instruction::LoadReg load;
231 load.reg = CallData::NewTarget;
232 bytecodeGenerator->addInstruction(load);
233 Codegen::Reference r = codegen->referenceForName(QStringLiteral(
"new.target"),
true);
234 r.storeConsumeAccumulator();
239 for (Context::MemberMap::const_iterator it =
members.constBegin(), cend = members.constEnd(); it != cend; ++it) {
240 if (it->isLexicallyScoped())
242 const QString &local = it.key();
244 Instruction::DeclareVar declareVar;
245 declareVar.isDeletable = (contextType == ContextType::Eval);
246 declareVar.varName = codegen->registerString(local);
247 bytecodeGenerator->addInstruction(declareVar);
252 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
253 if (it->canEscape && it->type == Context::ThisFunctionName) {
255 Instruction::LoadReg load;
256 load.reg = CallData::Function;
257 bytecodeGenerator->addInstruction(load);
258 Instruction::StoreLocal store;
259 store.index = it->index;
260 bytecodeGenerator->addInstruction(store);
267 if (isStrict || (formals && !formals->isSimpleParameterList())) {
268 Instruction::CreateUnmappedArgumentsObject setup;
269 bytecodeGenerator->addInstruction(setup);
271 Instruction::CreateMappedArgumentsObject setup;
272 bytecodeGenerator->addInstruction(setup);
274 codegen->referenceForName(QStringLiteral(
"arguments"),
false).storeConsumeAccumulator();
277 for (
const Context::Member &member : std::as_const(members)) {
278 if (member.function) {
279 const int function = codegen->defineFunction(member.function->name.toString(), member.function, member.function->formals, member.function->body);
280 codegen->loadClosure(function);
281 Codegen::Reference r = codegen->referenceForName(member.function->name.toString(),
true);
282 r.storeConsumeAccumulator();
312 Q_ASSERT(locals.size() == 0);
316 QVector<Context::MemberMap::Iterator> localsInTDZ;
317 const auto registerLocal = [
this, &localsInTDZ](Context::MemberMap::iterator member) {
318 if (member->isLexicallyScoped()) {
319 localsInTDZ << member;
321 member->index = locals.size();
322 locals.append(member.key());
326 QVector<Context::MemberMap::Iterator> registersInTDZ;
327 const auto allocateRegister = [bytecodeGenerator, ®istersInTDZ](Context::MemberMap::iterator member) {
328 if (member->isLexicallyScoped())
329 registersInTDZ << member;
339 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
343 if (it->type == Context::ThisFunctionName)
344 it->index = CallData::Function;
346 allocateRegister(it);
354 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
355 if (!it->isLexicallyScoped() && (contextType == ContextType::Global || contextType == ContextType::ScriptImportedByQML || !isStrict))
360 allocateRegister(it);
366 for (
auto &member: std::as_const(localsInTDZ)) {
367 member->index = locals.size();
368 locals.append(member.key());
371 if (contextType == ContextType::ESModule && !localNameForDefaultExport.isEmpty()) {
372 if (!members.contains(localNameForDefaultExport)) {
375 locals.append(localNameForDefaultExport);
382 for (
auto &member: std::as_const(registersInTDZ))
383 member->index = bytecodeGenerator->newRegister();
void emitBlockFooter(Compiler::Codegen *codegen)
void emitBlockHeader(Compiler::Codegen *codegen)
UsesArgumentsObject usesArgumentsObject
void setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)