Skip to content

[mypyc] Refactor IR building for generator functions #19008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
May 2, 2025

Conversation

JukkaL
Copy link
Collaborator

@JukkaL JukkaL commented May 1, 2025

The code was pretty hard to follow, since there were many conditional code paths in a very long function that handles both normal functions, nested functions and generators.

Move much of the generator-specific code to a helper function. This required moving some functionality to helper functions to avoid code duplication. Also pass a function as an argument to avoid a dependency cycle.

This is quite a big refactoring, and it's easier to follow by looking at the individual commits in this PR.

@@ -191,6 +191,41 @@ def add_args_to_env(
builder.add_var_to_env_class(arg.variable, rtype, base, reassign=reassign)


def add_vars_to_env(builder: IRBuilder) -> None:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this code here since this is used for both regular and generator functions.


# Add all variables and functions that are declared/defined within this
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following code was moved to add_vars_to_env.

Comment on lines 264 to 269
# Re-enter the FuncItem and visit the body of the function this time.
builder.enter(fn_info)
setup_env_for_generator_class(builder)
symtable = gen_generator_func_body(builder, fn_info, sig)

load_outer_envs(builder, builder.fn_info.generator_class)
top_level = builder.top_level_fn_info()
if (
builder.fn_info.is_nested
and isinstance(fitem, FuncDef)
and top_level
and top_level.add_nested_funcs_to_env
):
setup_func_for_recursive_call(builder, fitem, builder.fn_info.generator_class)
create_switch_for_generator_class(builder)
add_raise_exception_blocks_to_generator_class(builder, fitem.line)
# Evaluate argument defaults in the surrounding scope, since we
# calculate them *once* when the function definition is evaluated.
calculate_arg_defaults(builder, fn_info, func_reg, symtable)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this to gen_generator_func to make it consistent with gen_func_body?
We could technically take it out of the is_generator switch. It's just the symtable that differs if I am reading the code correctly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason I didn't do it is that we'd need find a new module for calculate_arg_defaults to avoid a cyclic dependency. I'll think about it.

@JukkaL JukkaL merged commit c0218a4 into master May 2, 2025
12 checks passed
@JukkaL JukkaL deleted the mypyc-generator-refactor branch May 2, 2025 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants