2017-06-04 6 views
1

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

Antwort

1

Im Folgenden finden Sie uncompyle6 Deparse der oben ist. Ich bin mir nicht ganz sicher, ob es korrekt ist, dass das erste Argument von mkfunc_annotate zu Recht als pos_arg bezeichnet wird und nicht als Standardwert arg.

Einer der feinen Punkte in der obigen Anordnung ist, dass die LOAD_CONST ein Tupels ist (mit einem Argumente), und das ist wichtig, in einer deparser clueing (oder Person), daß die Funktion bezeichnet ist.

stmts 
    sstmt 
     stmt 
      funcdef_annotate (2) 
       0. mkfunc_annotate (7) 
        0. pos_arg 
         expr 
          L. 1  0 LOAD_CONST   5 5 
        1. annotate_arg 
         expr 
             3 LOAD_CONST    'an argument that defaults to 5' 
        2. annotate_tuple 
            6 LOAD_CONST    ('x',) 
        3.    9 LOAD_CONST    '<code_object foo>' 
        4.    12 LOAD_CONST    'foo' 
        5.    15 EXTENDED_ARG  131074 '131072' 
        6.    18 MAKE_FUNCTION_A_2_1  '1 positional, 0 keyword pair, 2 annotated' 
       1. designator 
           21 STORE_NAME    'foo' 
Verwandte Themen