2012-01-12 16 views
7

Ho recentemente creato un decompilatore per AVM2/AS3 e ho notato che il compilatore Flash tende a emettere un sacco di codice inutile. Ad esempio, per una determinata applicazione ho rimosso circa il 10% del codice senza alcun danno alla funzionalità. Era solo un codice sicuramente non referenziato dagli opcode condizionali, né dai blocchi di gestione delle eccezioni.Perché il compilatore Flash ActionScript3 emette codice non necessario?

Inoltre, un'occhiata a questo frammento:

... 
    313  setproperty   y 
    315  getlocal   12 
317 returnvalue 318 jump L9 

    L3: 
    322  getlocal   8 
    324  returnvalue   

    L9: 
325 jump L10 ; L10 (opcode #331) does not ever exist. 
            ; Technically, it is a jump beyond 
            ; the end of function. This is invalid code! 

    L2: 
    329  pushnull    
    330  returnvalue   

Beh, naturalmente questo è il codice valido, che è anche morto e quindi non provoca effetti negativi (ad eccezione del codebase gonfiore). Ma perché emette mai quel codice? E perché il verificatore lo accetta?

+0

Non è stato fatto riferimento da una tabella di eccezioni (come non erano molti altri, molto più grandi - 10 di istruzioni - blocchi di codice morto) e, a giudicare dalle specifiche, è possibile trasferire il controllo tramite un opcode di salto o un'eccezione. Non ci sono nemmeno salti. – whitequark

+0

@wvxvw A proposito, i blocchi 'finally' sono fatti in AS3 con un trucco strano e subdolo, in cui il compilatore genera deliberatamente codici opzionali non validi per ingannare il verificatore e VM, di nuovo deliberatamente, li ignora. Flash è solo un enorme WTF. – whitequark

+0

@wvxvw, ho capito bene? se si esegue una determinata sequenza di codici opzionali, la VM consente al codice in esecuzione di esaminare il proprio flusso opcode in qualche modo, presumibilmente attraverso il loro invio allo stack di dati? +50 se trovi i riferimenti. – whitequark

risposta

7

ASC o compc non ottimizzano. Questo è un peccato, ma la teoria è che il JIT fa tutto il lavoro di ottimizzazione. Puoi trovare esempi ancora peggiori come aggiungere due costanti. Quindi la risposta è: mi dispiace, semplicemente non ottimizza. Potrebbe esserci un compilatore migliore in futuro. In questo momento devi fare affidamento sul JIT AS3 per eseguire il lavoro di ottimizzazione in fase di esecuzione (che fa un lavoro decente in!) O utilizzare un compilatore diverso.

+0

Sì, ovviamente ho visto aggiungere costanti e tali, per non dire coercizione inutile ovunque. Il peggior esempio di ciò è probabilmente il modo in cui 'lookupswitch' è codegen'd. Hai qualche riferimento sul perché è stato progettato in questo modo (come [LLVM] (http://blog.llvm.org/) ha)? La piegatura costante non è * quella * difficile da attuare, a meno che tu non sia completamente braindead. – whitequark

+1

whitequark: La teoria è che il "compilatore" è solo un parser glorificato e il JIT si prenderà cura di tutto il resto. Personalmente non penso che sia un buon design, ma come sia. Neanche io conosco alcun riferimento valido, mi dispiace. – starmole

Problemi correlati