Decompiler.st
author Stefan Vogel <sv@exept.de>
Sat, 10 Aug 1996 00:55:35 +0200
changeset 327 38119b9c1623
parent 326 d2858404a4a4
child 331 92f5214d6de2
permissions -rw-r--r--
More specialGlobals.

"
 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 listStream'
	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.
"
!

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

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

!Decompiler  class methodsFor:'decompiling'!

decompile:aMethod
    ^ (self new) decompile:aMethod to:Transcript

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

    "Modified: 16.4.1996 / 20:26:01 / cg"
!

decompile:aMethod to:aStream
    ^ (self new) decompile:aMethod to:aStream

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

    "Created: 16.4.1996 / 20:25:55 / cg"
! !

!Decompiler methodsFor:'decompiling'!

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

    listStream := aStream.

    aMethod isNil ifTrue:[
        aStream showCR:'nil method'.
        ^ self
    ].   

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

    bytes := aMethod byteCode.
    bytes isNil ifTrue:[
        aStream showCR:'no bytecode'.
        ^ self
    ].
    literals := aMethod literals.
    index := 1.
    nBytes := bytes size.
    [index <= nBytes] whileTrue:[
        self showPC.
        sym := self symbolicCodeFor:(bytes at:index).
        aStream 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:[
            aStream 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:[
            aStream show:'['; show:lineNr; show:']'
        ].
        aStream showCR:''
    ]

    "Created: 16.4.1996 / 20:27:18 / cg"
    "Modified: 16.4.1996 / 20:27:40 / cg"
!

showAbsOffset:byte
    |offs b2|

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

    "Modified: 16.4.1996 / 20:27:53 / cg"
!

showAbsOffsetLevel:byte
    |offs b2|

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

    "Modified: 16.4.1996 / 20:27:57 / cg"
!

showIndex:byte
    listStream show:byte printString.
    index := index + 1

    "Modified: 16.4.1996 / 20:27:59 / cg"
!

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

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

    "Modified: 16.4.1996 / 20:28:06 / cg"
!

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

    "Modified: 16.4.1996 / 20:28:08 / cg"
!

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

    "Modified: 16.4.1996 / 20:28:10 / cg"
!

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
!

showLit:litIndex
    |lit|

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

    "Modified: 16.4.1996 / 20:28:19 / cg"
!

showLiteral16:byte
    |litIndex|

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

showLiteral16Skip6:byte
    |litIndex|

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

    "Modified: 16.4.1996 / 20:28:23 / cg"
!

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

showLiteralAt:index
    |offs|

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

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

    "Modified: 16.4.1996 / 20:28:27 / cg"
!

showLongOffset:byte
    |offs|

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

    "Modified: 16.4.1996 / 20:28:30 / cg"
!

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

showLsendArgs:byte
    |litIndex|

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

    "Modified: 16.4.1996 / 20:28:35 / cg"
!

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

    "Modified: 16.4.1996 / 20:28:37 / cg"
!

showNumber:byte
    listStream show:byte printString.
    index := index + 1

    "Modified: 16.4.1996 / 20:28:38 / cg"
!

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

    "Modified: 16.4.1996 / 20:28:40 / cg"
!

showOffset:byte
    |offs|

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

    "Modified: 16.4.1996 / 20:28:43 / cg"
!

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

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

    "Modified: 16.4.1996 / 20:28:47 / cg"
!

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

    "Modified: 16.4.1996 / 20:28:50 / cg"
!

showSpecialGlobal:byte
    |specialIndex|

    specialIndex := bytes at:index.
    index := index + 1.
"/    listStream show:specialIndex printString.
    listStream show:(#(Array String FloatArray DoubleArray
                       Point Symbol Smalltalk Processor 
                       SmallInteger Character Float Process
                       Set IdentitySet Dictionary IdentityDictionary
                       Semaphore OrderedCollection) at:specialIndex + 1)

    "Modified: 16.4.1996 / 20:28:53 / cg"
    "Modified: 9.8.1996 / 23:59:36 / stefan"
!

showSpecialSend:byte
    |specialIndex|

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

    "Modified: 16.4.1996 / 20:28:55 / cg"
!

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

    "Modified: 16.4.1996 / 20:28:58 / cg"
!

showVeryLongOffset:byte
    |offs|

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

    "Modified: 16.4.1996 / 20:29:00 / cg"
!

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

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 "
		pushGlobal      " 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 "
		pushBlockVar1
		pushBlockVar2
		pushBlockVar3
		storeBlockVar1
		storeBlockVar2
		storeBlockVar3
		refCheck
		pushLocal
		storeLocal      " 240 "
	      ).

    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 "
		false
		false
		false
		false
		false
		false
		false
		false
		false           " 240 "
	      ).

    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 "
		specialGlobal   " 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 "
		nil
		nil
		nil
		nil
		nil
		nil
		index
		index           " 240 "
	     ).

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

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

ttt
        Set new

    "Created: 9.8.1996 / 23:49:00 / stefan"
! !

!Decompiler  class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libcomp/Decompiler.st,v 1.16 1996-08-09 22:55:35 stefan Exp $'
! !