Bei der Arbeit über uncompyle6 Dekompilierungsprozeß Bugs Ich habe über Problem kommt versuchen CPython Montag Ausgang mit dem, was der Python docs beschreibt für MAKE_FUNCTION
in Einklang zu bringen.Codegenerierung für Python 3 Annotation mit Standardwert
Python Quelle:
def foo(x: 'an argument that defaults to 5' = 5):
return
Disassemby (xdis-Version):
# Argument count: 1
# Kw-only arguments: 0
# Number of locals: 1
# Stack size: 1
# Flags: 0x00000043 (NOFREE | NEWLOCALS | OPTIMIZED)
# First Line: 1
# Constants:
# 0: 5
# 1: 'an argument that defaults to 5'
# 2: ('x',)
# 3: <code object foo at 0x7f49115938a0, file "exec", line 1>
# 4: 'foo'
# 5: None
# Names:
# 0: foo
1 0 LOAD_CONST 0 (5)
3 LOAD_CONST 1 ('an argument that defaults to 5')
6 LOAD_CONST 2 (('x',))
9 LOAD_CONST 3 (<code object foo at 0x7f49115938a0, file "exec", line 1>)
12 LOAD_CONST 4 ('foo')
15 EXTENDED_ARG 2 (131072)
18 MAKE_FUNCTION 131073 (1 positional, 0 name and default, 2 annotations)
21 STORE_NAME 0 (foo)
24 LOAD_CONST 5 (None)
27 RETURN_VALUE
Beachten Sie, dass in 18 der Offset-Wert ist im Grunde der Wert arg bei 19 Offset (1) plus den erweiterten arg Wert .
Die Interpretation in Klammern ist xdis und möglicherweise nicht korrekt.
Edit: Es ist nicht nur richtig, aber das zusätzliche Paar in Offset 6, um ein Tupel anzuzeigen, ist von wesentlicher Bedeutung.
In https://docs.python.org/3.4/library/dis.html#opcode-MAKE_FUNCTION heißt es:
Schiebt eine neue Funktion Objekt auf dem Stapel. Von unten nach oben muss der verbrauchten Stapel besteht aus
- argc & 0xFF Standardargument Objekten in Positionsordnung
- (argc >> 8) & 0xFF Paare von Namen und Standardargument, mit dem Namen nur unter der Objekt auf dem Stapel, für die Keyword-only Parameter
- (argc >> 16) & 0x7FFF Parameter Annotation Objekte
- ein Tupel für die Annotationen die Parameternamen Listing (nur, wenn es irgendwelche Annotation Objekte)
Es sieht für mich so aus, als ob es ein Annotationsobjekt gibt, nicht zwei. Und ein Standardargument und kein Positionsargument. Auch bei Offset 24 sehen wir eine Erwähnung von 5, aber das ist, nachdem wir MAKE_FUNCTION
haben. Die Verknüpfung eines Default-Wertes mit dem Parameter x
ist im Code nicht möglich. Eine Art Optimierung hier?
Wie soll ich die Assembly als genaue Darstellung der Python-Quelle verstehen?
Hinweis: Ich sehe diesen Code in mindestens Python erzeugt 3,1-3,5