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);
79 if (scope != VariableScope::Var || (*it).scope != VariableScope::Var)
81 if ((*it).type <= type) {
83 (*it).function = function;
91 if (contextType == ContextType::Block && (scope == VariableScope::Var && type != MemberType::FunctionDefinition))
92 return parent->addLocalVar(name, type, scope, function, declarationLocation);
96 m.function = function;
98 m.declarationLocation = declarationLocation;
218 codegen->module()->blocks.append(
this);
219 blockIndex = codegen->module()->blocks.size() - 1;
223 Instruction::PushScriptContext scriptContext;
225 bytecodeGenerator->addInstruction(scriptContext);
228 Instruction::PushCatchContext catchContext;
230 catchContext.name = codegen->registerString(caughtVariable);
231 bytecodeGenerator->addInstruction(catchContext);
233 Instruction::PushBlockContext blockContext;
235 bytecodeGenerator->addInstruction(blockContext);
238 Instruction::CreateCallContext createContext;
239 bytecodeGenerator->addInstruction(createContext);
244 Instruction::InitializeBlockDeadTemporalZone tdzInit;
247 bytecodeGenerator->addInstruction(tdzInit);
253 Instruction::ConvertThisToObject convert;
254 bytecodeGenerator->addInstruction(convert);
257 Instruction::LoadReg load;
258 load.reg = CallData::This;
259 bytecodeGenerator->addInstruction(load);
260 Codegen::Reference r = codegen->referenceForName(QStringLiteral(
"this"),
true);
261 r.storeConsumeAccumulator();
264 Instruction::LoadReg load;
265 load.reg = CallData::NewTarget;
266 bytecodeGenerator->addInstruction(load);
267 Codegen::Reference r = codegen->referenceForName(QStringLiteral(
"new.target"),
true);
268 r.storeConsumeAccumulator();
273 for (Context::MemberMap::const_iterator it =
members.constBegin(), cend = members.constEnd(); it != cend; ++it) {
274 if (it->isLexicallyScoped())
276 const QString &local = it.key();
278 Instruction::DeclareVar declareVar;
279 declareVar.isDeletable = (contextType == ContextType::Eval);
280 declareVar.varName = codegen->registerString(local);
281 bytecodeGenerator->addInstruction(declareVar);
286 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
287 if (it->canEscape && it->type == Context::ThisFunctionName) {
289 Instruction::LoadReg load;
290 load.reg = CallData::Function;
291 bytecodeGenerator->addInstruction(load);
292 Instruction::StoreLocal store;
293 store.index = it->index;
294 bytecodeGenerator->addInstruction(store);
301 if (isStrict || (formals && !formals->isSimpleParameterList())) {
302 Instruction::CreateUnmappedArgumentsObject setup;
303 bytecodeGenerator->addInstruction(setup);
305 Instruction::CreateMappedArgumentsObject setup;
306 bytecodeGenerator->addInstruction(setup);
308 codegen->referenceForName(QStringLiteral(
"arguments"),
false).storeConsumeAccumulator();
311 for (
const Context::Member &member : std::as_const(members)) {
312 if (member.function) {
313 const int function = codegen->defineFunction(member.function->name.toString(), member.function, member.function->formals, member.function->body);
314 codegen->loadClosure(function);
315 Codegen::Reference r = codegen->referenceForName(member.function->name.toString(),
true);
316 r.storeConsumeAccumulator();
346 Q_ASSERT(locals.size() == 0);
350 QList<Context::MemberMap::Iterator> localsInTDZ;
351 const auto registerLocal = [
this, &localsInTDZ](Context::MemberMap::iterator member) {
352 if (member->isLexicallyScoped()) {
353 localsInTDZ << member;
355 member->index = locals.size();
356 locals.append(member.key());
360 QList<Context::MemberMap::Iterator> registersInTDZ;
361 const auto allocateRegister = [bytecodeGenerator, ®istersInTDZ](Context::MemberMap::iterator member) {
362 if (member->isLexicallyScoped())
363 registersInTDZ << member;
373 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
377 if (it->type == Context::ThisFunctionName)
378 it->index = CallData::Function;
380 allocateRegister(it);
388 for (Context::MemberMap::iterator it =
members.begin(), end = members.end(); it != end; ++it) {
389 if (!it->isLexicallyScoped() && (contextType == ContextType::Global || contextType == ContextType::ScriptImportedByQML || !isStrict))
394 allocateRegister(it);
400 for (
auto &member: std::as_const(localsInTDZ)) {
401 member->index = locals.size();
402 locals.append(member.key());
405 if (contextType == ContextType::ESModule && !localNameForDefaultExport.isEmpty()) {
406 if (!
members.contains(localNameForDefaultExport)) {
409 locals.append(localNameForDefaultExport);
416 for (
auto &member: std::as_const(registersInTDZ))
417 member->index = bytecodeGenerator->newRegister();
void emitBlockFooter(Compiler::Codegen *codegen)
void emitBlockHeader(Compiler::Codegen *codegen)
UsesArgumentsObject usesArgumentsObject
void setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)