Skip to content
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

bpo-45152: refactor the dis module to make handling of hasconst opcod… #28258

Merged
merged 1 commit into from
Sep 15, 2021

Conversation

iritkatriel
Copy link
Member

@iritkatriel iritkatriel commented Sep 9, 2021

…es more generic. Rename constants to co_consts to make it clear which constants this is.

https://bugs.python.org/issue45152

…es more generic. Rename constants to co_consts to make it clear which constants this is.
if op == LOAD_CONST:
if co_consts is not None:
argval = co_consts[arg]
return argval
Copy link
Member Author

Choose a reason for hiding this comment

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

I have a patch that exposes the get_const_value function from compile.c in the _opcode module, but I'm on the fence whether it's worth the complication it adds. Let me know if you'd like to see it.

Copy link
Member

Choose a reason for hiding this comment

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

Why would you do that? Surely it's easier to replicate its functionality in pure Python, even if we add some new ways to represent constants. It doesn't even take a code object currently. And TBH, should e.g. LOAD_NONE even be counted as having a constant? I'd expect HAS_CONST(LOAD_NONE) might well be False.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think LOAD_NONE should be HAS_CONST, because the peephole optimiser treats it the same as a LOAD_CONST, for things like folding const tuples and conditional jumps that depend on const.

So far I don't think opcode.hasconst is used for anything (it contains only LOAD_CONST). So I thought we would make it include all the splits of LOAD_CONST, and then HAS_CONST is a C macro generated from that (it's new, I just added it).

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see. Currently we take (not the exact notation)

LOAD_CONST None
LOAD_CONST 42
BUILD_TUPLE 2

and transform it to

LOAD_CONST (None, 42)

adding (None, 42) as a new constant to co_consts. We want to still do that even when the first instruction is replaced by LOAD_NONE. That makes sense!

We still have the issue that we might end up with unused constants in co_consts due to this folding. Inada just fixed this for trailing unused constants in GH-28109 (bpo-45056) but for orphaned constants in the middle we have no solution (we'd have to renumber all the LOAD_CONST opargs). Fortunately I think it's not worth it, this is rare.

So you've convinced me that LOAD_NONE should be in opcode.hasconst, but not that it's worth exposing that C function.

Copy link
Member Author

Choose a reason for hiding this comment

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

but not that it's worth exposing that C function.

Yeah, I agree it's OTT in this case. We'll just have to implement it twice.

if op == IMPORT_NAME and i >= 2:
from_op = opargs[i-1]
level_op = opargs[i-2]
if (from_op[0] in hasconst and level_op[0] in hasconst):
Copy link
Member Author

Choose a reason for hiding this comment

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

even this needs hasconst to have LOAD_NONE - the fromlist can be None.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

When you commit, please make sure the commit title is whole again (GitHub did its annoying thing where it truncates the title in the middle of a word and puts the rest in the description).

else:
return UNKNOWN, ''
argval = _get_const_value(op, arg, co_consts)
argrepr = repr(argval) if argval is not UNKNOWN else ''
Copy link
Member

Choose a reason for hiding this comment

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

Wondering if repr(UNKNOWN) should just return ''...

Copy link
Member Author

Choose a reason for hiding this comment

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

I ruled that out when I thought that the sentinel will be part of the external API, because it could be confusing.
Now it seems more reasonable, because it's only an internal thing, but I still think the sentinel doesn't need to know so much about how it's going to be used/displayed.

@iritkatriel iritkatriel merged commit 40d2ac9 into python:main Sep 15, 2021
@iritkatriel iritkatriel deleted the bpo-45152a branch November 5, 2021 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants