Commit 2f22f89e authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by Marius Wachtler

Don't use nodeName() from parent scope in created functions

When remapping generator expressions / set+dict comprehensions,
we create an explicit new function, which will later get run
through CFG again.  With the new changes, we can't use a nodeName()
that was generated in the parent scope, since that will end up clashing
when the generated scope generates its own names.

I think it's not too bad to fix since in these cases the arguments are only
ever used inside of the inner scope, so we just have to use names that aren't
used elsewhere.
parent b47e2421
...@@ -1655,7 +1655,12 @@ bool PrintVisitor::visit_return(AST_Return* node) { ...@@ -1655,7 +1655,12 @@ bool PrintVisitor::visit_return(AST_Return* node) {
} }
bool PrintVisitor::visit_set(AST_Set* node) { bool PrintVisitor::visit_set(AST_Set* node) {
assert(node->elts.size()); // An empty set literal is not writeable in Python (it's a dictionary),
// but we sometimes generate it (ex in set comprehension lowering).
// Just to make it clear when printing, print empty set literals as "SET{}".
if (!node->elts.size())
printf("SET");
printf("{"); printf("{");
bool first = true; bool first = true;
......
...@@ -867,7 +867,8 @@ private: ...@@ -867,7 +867,8 @@ private:
AST_FunctionDef* func = new AST_FunctionDef(); AST_FunctionDef* func = new AST_FunctionDef();
func->lineno = node->lineno; func->lineno = node->lineno;
func->col_offset = node->col_offset; func->col_offset = node->col_offset;
InternedString func_name = nodeName(func); // TODO this should be set off the type of the comprehension (ie <setcomp> or <dictcomp> or <genexpr>)
InternedString func_name = internString("<comprehension>");
func->name = func_name; func->name = func_name;
func->args = new AST_arguments(); func->args = new AST_arguments();
func->args->vararg = internString(""); func->args->vararg = internString("");
...@@ -913,20 +914,22 @@ private: ...@@ -913,20 +914,22 @@ private:
// argument to the function we create. See // argument to the function we create. See
// https://www.python.org/dev/peps/pep-0289/#early-binding-versus-late-binding // https://www.python.org/dev/peps/pep-0289/#early-binding-versus-late-binding
AST_expr* first = remapExpr(node->generators[0]->iter); AST_expr* first = remapExpr(node->generators[0]->iter);
InternedString first_generator_name = nodeName(node->generators[0]); InternedString arg_name = internString("#arg");
AST_MakeFunction* func = makeFunctionForScope(node); AST_MakeFunction* func = makeFunctionForScope(node);
func->function_def->args->args.push_back(makeName(first_generator_name, AST_TYPE::Param, node->lineno)); func->function_def->args->args.push_back(makeName(arg_name, AST_TYPE::Param, node->lineno));
emitComprehensionLoops(&func->function_def->body, node->generators, emitComprehensionLoops(&func->function_def->body, node->generators,
makeName(first_generator_name, AST_TYPE::Load, node->lineno), makeName(arg_name, AST_TYPE::Load, node->lineno),
[this, node](std::vector<AST_stmt*>* insert_point) { [this, node](std::vector<AST_stmt*>* insert_point) {
auto y = new AST_Yield(); auto y = new AST_Yield();
y->value = node->elt; y->value = node->elt;
insert_point->push_back(makeExpr(y)); insert_point->push_back(makeExpr(y));
}); });
pushAssign(func->function_def->name, func);
return makeCall(makeLoad(func->function_def->name, node), first); InternedString func_var_name = nodeName(func->function_def);
pushAssign(func_var_name, func);
return makeCall(makeLoad(func_var_name, node), first);
} }
void emitComprehensionYield(AST_DictComp* node, InternedString dict_name, std::vector<AST_stmt*>* insert_point) { void emitComprehensionYield(AST_DictComp* node, InternedString dict_name, std::vector<AST_stmt*>* insert_point) {
...@@ -945,12 +948,12 @@ private: ...@@ -945,12 +948,12 @@ private:
template <typename ResultType, typename CompType> AST_expr* remapScopedComprehension(CompType* node) { template <typename ResultType, typename CompType> AST_expr* remapScopedComprehension(CompType* node) {
// See comment in remapGeneratorExp re early vs. late binding. // See comment in remapGeneratorExp re early vs. late binding.
AST_expr* first = remapExpr(node->generators[0]->iter); AST_expr* first = remapExpr(node->generators[0]->iter);
InternedString first_generator_name = nodeName(node->generators[0]); InternedString arg_name = internString("#arg");
AST_MakeFunction* func = makeFunctionForScope(node); AST_MakeFunction* func = makeFunctionForScope(node);
func->function_def->args->args.push_back(makeName(first_generator_name, AST_TYPE::Param, node->lineno)); func->function_def->args->args.push_back(makeName(arg_name, AST_TYPE::Param, node->lineno));
InternedString rtn_name = nodeName(node); InternedString rtn_name = internString("#comp_rtn");
auto asgn = new AST_Assign(); auto asgn = new AST_Assign();
asgn->targets.push_back(makeName(rtn_name, AST_TYPE::Store, node->lineno)); asgn->targets.push_back(makeName(rtn_name, AST_TYPE::Store, node->lineno));
asgn->value = new ResultType(); asgn->value = new ResultType();
...@@ -958,16 +961,17 @@ private: ...@@ -958,16 +961,17 @@ private:
auto lambda = auto lambda =
[&](std::vector<AST_stmt*>* insert_point) { emitComprehensionYield(node, rtn_name, insert_point); }; [&](std::vector<AST_stmt*>* insert_point) { emitComprehensionYield(node, rtn_name, insert_point); };
AST_Name* first_name = makeName(first_generator_name, AST_TYPE::Load, node->lineno); AST_Name* first_name = makeName(internString("#arg"), AST_TYPE::Load, node->lineno);
emitComprehensionLoops(&func->function_def->body, node->generators, first_name, lambda); emitComprehensionLoops(&func->function_def->body, node->generators, first_name, lambda);
auto rtn = new AST_Return(); auto rtn = new AST_Return();
rtn->value = makeName(rtn_name, AST_TYPE::Load, node->lineno); rtn->value = makeName(rtn_name, AST_TYPE::Load, node->lineno);
func->function_def->body.push_back(rtn); func->function_def->body.push_back(rtn);
pushAssign(func->function_def->name, func); InternedString func_var_name = nodeName(func->function_def);
pushAssign(func_var_name, func);
return makeCall(makeName(func->function_def->name, AST_TYPE::Load, node->lineno), first); return makeCall(makeName(func_var_name, AST_TYPE::Load, node->lineno), first);
} }
AST_expr* remapIfExp(AST_IfExp* node) { AST_expr* remapIfExp(AST_IfExp* node) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment