Decompiler.st
author Claus Gittinger <cg@exept.de>
Thu, 08 Feb 1996 21:32:02 +0100
changeset 206 d4cd6769b983
parent 205 7554fe0b329d
child 217 eba0ee7232aa
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 1991 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

ByteCodeCompiler subclass:#Decompiler
       instanceVariableNames:'hasLineNo bytes literals index '
       classVariableNames:''
       poolDictionaries:''
       category:'System-Compiler'
!

!Decompiler class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1991 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

version
    ^ '$Header: /cvs/stx/stx/libcomp/Decompiler.st,v 1.9 1996-02-08 20:32:02 cg Exp $'
!

documentation
"
    only for stx-debugging. Not for public eyes.

    Decompiler decompile:(someClass compiledMethodAt:#someSelector)
"
! !

!Decompiler class methodsFor:'decompiling'!

decompile:aMethod
    ^ (self new) decompile:aMethod

    "Decompiler decompile:(FileBrowser compiledMethodAt:#initialize)"
! !

!Decompiler methodsFor:'decompiling'!

showOffset:byte
    |offs|

    index := index + 1.
    (byte > 127) ifTrue:[
	offs := byte - 256
    ] ifFalse:[
	offs := byte
    ].
    Transcript show:(offs printString).
    Transcript show:' ('.
    Transcript show:(index + offs) printString.
    Transcript show:')'
!

showLongOffset:byte
    |offs|

    index := index + 1.
    (byte > 127) ifTrue:[
	offs := byte - 256 - 128
    ] ifFalse:[
	offs := byte + 128
    ].
    Transcript show:offs printString.
    Transcript show:' ('.
    Transcript show:(index + offs) printString.
    Transcript show:')'
!

showVeryLongOffset:byte
    |offs|

    index := index + 1.
    (byte > 127) ifTrue:[
	offs := byte - 256 - 256
    ] ifFalse:[
	offs := byte + 256
    ].
    Transcript show:offs printString.
    Transcript show:' ('.
    Transcript show:(index + offs) printString.
    Transcript show:')'
!

showAbsOffset:byte
    |offs b2|

    index := index + 1.
    b2 := (bytes at:index).
    offs := byte + (b2 bitShift:8).
    index := index + 1.
    Transcript show:offs printString.
    Transcript show:' ('.
    Transcript show:offs printString.
    Transcript show:')'
!

showAbsOffsetLevel:byte
    |offs b2|

    index := index + 1.
    b2 := (bytes at:index).
    offs := byte + (b2 bitShift:8).
    index := index + 1.
    Transcript show:offs printString.
    Transcript show:' ('.
    Transcript show:offs printString.
    Transcript show:')'.
    self showNvarNargsAt:index.
    index := index + 2
!

showNvarNargsAt:index
    Transcript show:' nv='.
    Transcript show:(bytes at:index) printString.
    Transcript show:' na='.
    Transcript show:(bytes at:(index + 1)) printString
!

showLiteralAt:index
    |offs|

    offs := bytes at:index.
    self showLit:offs
!

showLiteral:byte
    index := index + 1.
    self showLit:byte
!

showLiteral16:byte
    |litIndex|

    litIndex := bytes wordAt:index MSB:false.
    self showLit:litIndex.
    index := index + 2
!

showLit:litIndex
    |lit|

    lit := literals at:litIndex.
    lit isBehavior ifTrue:[
	Transcript show:lit name
    ] ifFalse:[
	Transcript show:lit storeString
    ]
!

showLit1:ignored
    self showLit:1
!

showLit2:ignored
    self showLit:2
!

showLit3:ignored
    self showLit:3
!

showLit4:ignored
    self showLit:4
!

showLit5:ignored
    self showLit:5
!

showLit6:ignored
    self showLit:6
!

showLit7:ignored
    self showLit:7
!

showLit8:ignored
    self showLit:8
!

showLit9:ignored
    self showLit:9
!

showLiteralSkip6:byte
    index := index + 1.
    Transcript show:(literals at:byte) printString.
    index := index + 6
!

showLiteral16Skip6:byte
    |litIndex|

    litIndex := bytes wordAt:index MSB:false.
    index := index + 2.
    Transcript show:(literals at:litIndex) printString.
    index := index + 6
!

showOffsetLevel:byte
    self showOffset:byte.
    self showNvarNargsAt:index.
    index := index + 2
!

showLongOffsetLevel:byte
    self showLongOffset:byte.
    self showNvarNargsAt:index.
    index := index + 2
!

showVeryLongOffsetLevel:byte
    self showVeryLongOffset:byte.
    self showNvarNargsAt:index.
    index := index + 2
!

showSendArgs:byte
    Transcript show:byte printString.
    Transcript show:' '.
    index := index + 1.
    self showLiteralAt:index.
    index := index + 1
!

showLsendArgs:byte
    |litIndex|

    Transcript show:byte printString.
    Transcript show:' '.
    index := index + 1.
    litIndex := bytes wordAt:index MSB:false.
    Transcript show:(literals at:litIndex) printString.
    index := index + 2
!

showSpecialSend:byte
    |specialIndex|

    specialIndex := bytes at:index.
    index := index + 1.
"/    Transcript show:specialIndex printString.
    Transcript show:'#'.
    Transcript show:(#(top bottom left right) at:specialIndex + 1)
!

showSuperSendArgs:byte
    Transcript show:byte printString.
    Transcript show:' '.
    index := index + 1.
    self showLiteralAt:index.
    index := index + 1.
    Transcript show:' '.
    self showLiteralAt:index.
    index := index + 1
!

showLineNo:byte
    Transcript show:' line:' , byte printString.
    index := index + 1
!

showIndex:byte
    Transcript show:byte printString.
    index := index + 1
!

showInstvarIndex:byte
    Transcript show:byte printString.
    classToCompileFor notNil ifTrue:[
        Transcript show:'('.
        Transcript show:(classToCompileFor allInstVarNames at:(byte + 1)).
        Transcript show:')'.
    ].
    index := index + 1
!

showLevelIndex:byte
    self showIndex:byte.
    Transcript show:' lvl:'; show:(bytes at:index).
    index := index + 1.
!

showIndexLevel:byte
    self showIndex:byte.
    self showNvarNargsAt:index.
    index := index + 2
!

showNumber:byte
    Transcript show:byte printString.
    index := index + 1
!

showNumber16:byte
    Transcript show:(bytes signedWordAt:index MSB:false) printString.
    index := index + 2
!

showPC
    Transcript show:(index printStringRadix:10 size:3 fill:(Character space)).
    Transcript show:': '.
    Transcript show:((bytes at:index) printStringRadix:16 size:2 fill:$0).
    Transcript show:' '.
!

decompile:aMethod
    |nBytes offs byte sym sel lineNr who|

    aMethod isNil ifTrue:[
	Transcript showCr:'nil method'.
	^ self
    ].   

    who := aMethod who.
    who notNil ifTrue:[
        classToCompileFor := who first.
        Transcript cr.
        Transcript showCr:'decompiling ' , classToCompileFor name , '>>' , (who at:2) , ':'.
        Transcript cr.
    ].

    bytes := aMethod byteCode.
    bytes isNil ifTrue:[
	Transcript showCr:'no bytecode'.
	^ self
    ].
    literals := aMethod literals.
    index := 1.
    nBytes := bytes size.
    [index <= nBytes] whileTrue:[
	self showPC.
	sym := self symbolicCodeFor:(bytes at:index).
	Transcript show:sym.
"
	extra notNil ifTrue:[Transcript show:(extra printString)].
"
	hasLineNo ifTrue:[
	    index := index + 1.
	    lineNr := bytes at:index.
	] ifFalse:[
	    lineNr := nil
	].
	index := index + 1.
	extra notNil ifTrue:[
	    Transcript show:' '.
	    byte := bytes at:index.

	    "compute argument showXXX selector from extra ..."

	    sel := 'show' , extra , ':'.
	    sel at:5 put:(sel at:5) asUppercase.
	    self perform:sel asSymbol with:byte
	].
	lineNr notNil ifTrue:[
	    Transcript show:'['; show:lineNr; show:']'
	].
	Transcript showCr:''
    ]
!

symbolicCodeFor:aByte
    |syms extras lnos|

    syms := #(  retTop         " 0  "
		retNil
		retTrue
		retFalse
		ret0
		retSelf         " 5  "
		blockRetTop
		nil
		LINE
		nil
		pushNil         " 10 "
		pushTrue
		pushFalse
		sendSelf
		pushLit
		pushSelf        " 15 "
		pushNum
		pushNum16
		drop
		send
		superSend       " 20 "
		send0
		send1
		send2
		send3
		sendDrop        " 25 "
		sendDrop0
		sendDrop1
		sendDrop2
		sendDrop3
		pushMethodArg   " 30 "
		pushMethodVar
		pushBlockArg
		pushBlockVar
		pushInstVar
		pushClassVar    " 35 "
		pushGlobal
		storeMethodVar
		storeBlockVar
		storeInstVar
		storeClassVar   " 40 "
		storeGlobal
		pushOuterBlockArg
		pushOuter1BlockArg
		pushOuter2BlockArg
		equal           " 45 "
		notEqual
		dup
		equal0
		notEqual0
		falseJump       " 50 "
		trueJump
		nilJump
		notNilJump
		jump
		makeBlock       " 55 "
		zeroJump
		notZeroJump
		eqJump
		notEqJump
		falseJump       " 60 "
		trueJump
		nilJump
		notNilJump
		jump
		makeBlock       " 65 "
		zeroJump
		notZeroJump
		eqJump
		notEqJump
		falseJump       " 70 "
		trueJump
		nilJump
		notNilJump
		jump
		makeBlock       " 75 "
		zeroJump
		notZeroJump
		eqJump
		notEqJump
		pushMethodVar1  " 80 "
		pushMethodVar2
		pushMethodVar3
		pushMethodVar4
		pushMethodVar5
		pushMethodVar6  " 85 "
		pushMethodArg1
		pushMethodArg2
		pushMethodArg3
		pushMethodArg4
		pushInstVar1    " 90 "
		pushInstVar2
		pushInstVar3
		pushInstVar4
		pushInstVar5
		pushInstVar6    " 95 "
		pushInstVar7
		pushInstVar8
		pushInstVar9
		pushInstVar10
		storeMethodVar1 " 100 "
		storeMethodVar2
		storeMethodVar3
		storeMethodVar4
		storeMethodVar5
		storeMethodVar6 " 105 "
		sendY
		sendX
		sendWidth
		sendHeight
		storeInstVar1   " 110 "
		storeInstVar2
		storeInstVar3
		storeInstVar4
		storeInstVar5
		storeInstVar6  " 115 "
		storeInstVar7
		storeInstVar8
		storeInstVar9
		storeInstVar10
		push0           " 120 "
		push1
		pushMinus1
		sendPlus1
		sendMinus1
		incMethodVar    " 125 "
		decMethodVar
		retNum
		pushOuterBlockVar       "16r80"
		storeOuterBlockVar
		sendEQ          " 130 "
		sendPLUS
		sendNE
		sendMINUS
		sendCLASS
		sendAT          " 135 "
		sendATPUT
		sendBitAnd
		sendBitOr
		push2
		pushBlockArg1   " 140 "
		pushBlockArg2
		pushBlockArg3
		pushBlockArg4
		pushContext             "16r90"
		sendGT          " 145 "
		sendGE
		sendLT
		sendLE
		sendNEXT
		sendPEEK        " 150 "
		sendVALUE
		sendVALUE1
		sendSIZE
		sendORIGIN
		sendEXTENT      " 155 "
		make0Block             
		makeNILBlock
		sendASINTEGER   " 158 "
		sendROUNDED     " 159 "
		retMvar1        " 160 " "16rA0"
		retMvar2        
		retMvar3        
		retMvar4        
		retMvar5        
		retMvar6        " 165 "
		retIvar1        
		retIvar2        
		retIvar3        
		retIvar4        
		retIvar5        " 170 "
		retIvar6        
		retIvar7        
		retIvar8        
		retMarg1        
		retMarg2        " 175 "
		pushClassInstVar
		storeClassInstVar
		nil
		not
		sendSelf0       " 180 "
		sendSelf1
		sendSelf2
		sendSelf3
		sendSelfDrop0   
		sendSelfDrop1   " 185 "
		sendSelfDrop2
		sendSelfDrop3
		isNil
		notNil
		falseJumpAbs    " 190 "
		trueJumpAbs     
		nilJumpAbs     
		notNilJumpAbs   
		jumpAbs        
		makeBlockAbs    " 195 "
		zeroJumpAbs
		notZeroJumpAbs
		eqJumpAbs
		notEqJumpAbs    " 199 "
		pushArray       " 200 "
		pushLLit
		jmpFalseL
		jmpTrueL
		nil
		lsend           "   205 " 
		lsuperSend
		lsendSelf         
		pushGT0
		nil
		sendArrayNew    "   210 " 
		sendBasicNew      
		sendGT0
		sendNew
		sendBasicNewN
		sendNewN        "   215 " 
		sendLogAnd
		sendLogOr
		pushGlobL
		storeGlobL
		nil              "  220 " 
		nil                  
		pushLit1             
		pushLit2              
		pushLit3             
		pushLit4             
		pushLit5             
		pushLit6             
		pushLit7            
		pushLit8            
		sendMUL          "   230 "
		sendSpecial      "   231 "
	      ).

    lnos := #(  false          " 0  "
		false   
		false   
		false   
		false
		false          " 5  "
		false
		false
		true
		false
		false          " 10 "
		false
		false
		true
		false
		false          " 15 "
		false
		false
		false
		true
		true           " 20 "
		true 
		true 
		true 
		true 
		true           " 25 "
		true 
		true 
		true 
		true 
		false          " 30 "
		false
		false
		false
		false
		false          " 35 "
		false
		false
		false
		false
		false           " 40 "
		false
		false
		false
		false
		false           " 45 "
		false
		false
		false
		false
		false       " 50 "
		false
		false
		false
		false
		false       " 55 "
		false
		false
		false
		false
		false       " 60 "
		false
		false
		false
		false
		false       " 65 "
		false
		false
		false
		false
		false       " 70 "
		false
		false
		false
		false
		false       " 75 "
		false
		false
		false
		false 
		false  " 80 "
		false
		false
		false
		false
		false  " 85 "
		false
		false
		false
		false
		false    " 90 "
		false
		false
		false
		false
		false    " 95 "
		false
		false
		false
		false
		false " 100 "
		false
		false
		false
		false
		false " 105 "
		false
		false
		false
		false
		false   " 110 "
		false
		false
		false
		false
		false  " 115 "
		false
		false
		false
		false
		false           " 120 "
		false
		false
		true
		true
		true    " 125 "
		true
		false
		false
		false
		true          " 130 "
		true
		true
		true
		false
		true          " 135 "
		true
		true
		true
		false
		false   " 140 "
		false
		false
		false
		false
		true          " 145 "
		true
		true
		true
		true
		true        " 150 "
		true
		true
		true
		true
		true             " 155 "
		false
		false
		true
		true
		false        " 160 "
		false
		false
		false
		false
		false        " 165 "
		false
		false
		false
		false
		false        " 170 "
		false
		false
		false
		false
		false        " 175 "
		false
		false
		false
		true
		true         " 180 "
		true
		true
		true
		true
		true         " 185 "
		true
		true
		false
		false
		false         " 190 "
		false
		false
		false
		false
		false         " 195 "
		false
		false
		false
		false         " 199 "
		false         " 200 "
		false
		false
		false
		false
		true            " 205 " 
		true
		false
		true
		false
		false           " 210 "      " arrayNew "
		true                         " basicNew "
		true                         " > 0 "
		true                         " new "
		true                         " basicNew: "
		true            " 215 "      " new: "
		true
		true
		false
		false
		false           " 220 " 
		false
		false
		false
		false
		false           " 225 " 
		false
		false
		false
		false           " 229 " 
		true            " 230 "
		true            " 231 "
	      ).

    extras := #(nil             " 0  "
		nil
		nil
		nil
		nil
		nil             " 5  "
		nil
		nil
		nil
		nil
		nil             " 10 "
		nil
		nil
		sendArgs
		literal
		nil             " 15 "
		number
		number16
		nil
		sendArgs
		superSendArgs   " 20 "
		literal
		literal
		literal
		literal
		sendArgs        " 25 "
		literal
		literal
		literal
		literal
		index           " 30 "
		index
		index
		index
		instvarIndex
		literalSkip6    " 35 "
		literalSkip6
		index
		index
		instvarIndex
		literalSkip6    " 40 "
		literalSkip6
		indexLevel
		index
		index
		nil             " 45 "
		nil
		nil
		nil
		nil
		offset          " 50 "
		offset
		offset
		offset
		offset
		offsetLevel     " 55 "
		offset
		offset
		offset
		offset
		longOffset      " 60 "
		longOffset
		longOffset
		longOffset
		longOffset
		longOffsetLevel " 65 "
		longOffset
		longOffset
		longOffset
		longOffset
		veryLongOffset  " 70 "
		veryLongOffset
		veryLongOffset
		veryLongOffset
		veryLongOffset
		veryLongOffsetLevel  " 75 "
		veryLongOffset
		veryLongOffset
		veryLongOffset
		veryLongOffset
		nil             " 80 "
		nil
		nil
		nil
		nil
		nil             " 85 "
		nil
		nil
		nil
		nil
		nil             " 90 "
		nil
		nil
		nil
		nil
		nil             " 95 "
		nil
		nil
		nil
		nil
		nil             " 100 "
		nil
		nil
		nil
		nil
		nil             " 105 "
		nil
		nil
		nil
		nil
		nil             " 110 "
		nil
		nil
		nil
		nil
		nil             " 115 "
		nil
		nil
		nil
		nil
		nil             " 120 "
		nil
		nil
		nil
		nil
		index           " 125 "
		index
		number
		levelIndex "/ indexLevel
		indexLevel
		nil             " 130 "
		nil
		nil
		nil
		nil
		nil             " 135 "
		nil
		nil
		nil
		nil
		nil             " 140 "
		nil
		nil
		nil
		nil
		nil             " 145 "
		nil
		nil
		nil
		nil
		nil             " 150 "
		nil
		nil
		nil
		nil
		nil             " 155 "
		nil
		nil
		nil
		nil
		nil             " 160 "
		nil
		nil
		nil
		nil
		nil             " 165 "
		nil
		nil
		nil
		nil
		nil             " 170 "
		nil
		nil
		nil
		nil
		nil             " 175 "
		index
		index
		nil
		nil
		literal         " 180 "
		literal
		literal
		literal
		literal         
		literal         " 185 "
		literal
		literal
		nil
		nil
		absOffset       " 190 "
		absOffset
		absOffset
		absOffset
		absOffset
		absOffsetLevel
		absOffset
		absOffset
		absOffset
		absOffset       " 199 "
		nil             " 200 "
		literal16
		nil
		nil
		nil
		lsendArgs       " 205 "
		lsuperSendArgs
		lsendSelfArgs
		nil
		nil
		nil             " 210 "
		nil
		nil
		nil
		nil
		nil             " 215 "
		nil
		nil
		literal16Skip6   
		literal16Skip6
		nil             " 220 "
		nil
		lit1
		lit2
		lit3
		lit4            " 225 "
		lit5
		lit6
		lit7
		lit8
		nil             " 230 "
		specialSend     " 231 "

	     ).

    extra := extras at:(aByte + 1).
    hasLineNo := lnos at:(aByte + 1).
    ^ syms at:(aByte + 1)

    "Modified: 2.9.1995 / 00:12:11 / claus"
! !