Object subclass:#JavaDecompiler
instanceVariableNames:'code pc javaMethod outStream classToCompileFor'
classVariableNames:'DecoderTable'
poolDictionaries:''
category:'Java-Support'
!
!JavaDecompiler class methodsFor:'initialization'!
initialize
DecoderTable := #(
(nop) "/ 0
(aconst_null) "/ 1
(iconst_m1) "/ 2
(iconst_0) "/ 3
(iconst_1) "/ 4
(iconst_2) "/ 5
(iconst_3) "/ 6
(iconst_4) "/ 7
(iconst_5) "/ 8
(lconst_0) "/ 9
(lconst_1) "/ 10
(fconst_0) "/ 11
(fconst_1) "/ 12
(fconst_2) "/ 13
(dconst_0) "/ 14
(dconst_1) "/ 15
(bipush signedByte) "/ 16
(sipush signedShort) "/ 17
(ldc1 constIndexByte) "/ 18
(ldc2 constIndexShort) "/ 19
(ldc2w constIndexShort) "/ 20
(iload localIndexByte) "/ 21
(lload localIndexByte) "/ 22
(fload localIndexByte) "/ 23
(dload localIndexByte) "/ 24
(aload localIndexByte) "/ 25
(iload_0) "/ 26
(iload_1) "/ 27
(iload_2) "/ 28
(iload_3) "/ 29
(lload_0) "/ 30
(lload_1) "/ 31
(lload_2) "/ 32
(lload_3) "/ 33
(fload_0) "/ 34
(fload_1) "/ 35
(fload_2) "/ 36
(fload_3) "/ 37
(dload_0) "/ 38
(dload_1) "/ 39
(dload_2) "/ 40
(dload_3) "/ 41
(aload_0) "/ 42
(aload_1) "/ 43
(aload_2) "/ 44
(aload_3) "/ 45
(iaload) "/ 46
(laload) "/ 47
(faload) "/ 48
(daload) "/ 49
(aaload) "/ 50
(baload) "/ 51
(caload) "/ 52
(saload) "/ 53
(istore localIndexByte) "/ 54
(lstore localIndexByte) "/ 55
(fstore localIndexByte) "/ 56
(dstore localIndexByte) "/ 57
(astore localIndexByte) "/ 58
(istore_0) "/ 59
(istore_1) "/ 60
(istore_2) "/ 61
(istore_3) "/ 62
(lstore_0) "/ 63
(lstore_1) "/ 64
(lstore_2) "/ 65
(lstore_3) "/ 66
(fstore_0) "/ 67
(fstore_1) "/ 68
(fstore_2) "/ 69
(fstore_3) "/ 70
(dstore_0) "/ 71
(dstore_1) "/ 72
(dstore_2) "/ 73
(dstore_3) "/ 74
(astore_0) "/ 75
(astore_1) "/ 76
(astore_2) "/ 77
(astore_3) "/ 78
(iastore) "/ 79
(lastore) "/ 80
(fastore) "/ 81
(dastore) "/ 82
(aastore) "/ 83
(bastore) "/ 84
(castore) "/ 85
(sastore) "/ 86
(pop) "/ 87
(pop2) "/ 88
(dup) "/ 89
(dup_x1) "/ 90
(dup_x2) "/ 91
(dup2) "/ 92
(dup2_x1) "/ 93
(dup2_x2) "/ 94
(swap) "/ 95
(iadd) "/ 96
(ladd) "/ 97
(fadd) "/ 98
(dadd) "/ 99
(isub) "/ 100
(lsub) "/ 101
(fsub) "/ 102
(dsub) "/ 103
(imul) "/ 104
(lmul) "/ 105
(fmul) "/ 106
(dmul) "/ 107
(idiv) "/ 108
(ldiv) "/ 109
(fdiv) "/ 110
(ddiv) "/ 111
"/ (imod) "/ 112 "/ obsolete
(irem) "/ 112
"/ (lmod) "/ 113 "/ obsolete
(lrem) "/ 113
"/ (fmod) "/ 114 "/ obsolete
(frem) "/ 114
"/ (dmod) "/ 115 "/ obsolete
(drem) "/ 115
(ineg) "/ 116
(lneg) "/ 117
(fneg) "/ 118
(dneg) "/ 119
(ishl) "/ 120
(lshl) "/ 121
(ishr) "/ 122
(lshr) "/ 123
(iushr) "/ 124
(lushr) "/ 125
(iand) "/ 126
(land) "/ 127
(ior) "/ 128
(lor) "/ 129
(ixor) "/ 130
(lxor) "/ 131
(iinc localIndexByte signedByte) "/ 132
(i2l) "/ 133
(i2f) "/ 134
(i2d) "/ 135
(l2i) "/ 136
(l2f) "/ 137
(l2d) "/ 138
(f2i) "/ 139
(f2l) "/ 140
(f2d) "/ 141
(d2i) "/ 142
(d2l) "/ 143
(d2f) "/ 144
(int2byte) "/ 145
(int2char) "/ 146
(int2short) "/ 147
(lcmp) "/ 148
(fcmpl) "/ 149
(fcmpg) "/ 150
(dcmpl) "/ 151
(dcmpg) "/ 152
(ifeq signedBranchShort) "/ 153
(ifne signedBranchShort) "/ 154
(iflt signedBranchShort) "/ 155
(ifge signedBranchShort) "/ 156
(ifgt signedBranchShort) "/ 157
(ifle signedBranchShort) "/ 158
(if_icmpeq signedBranchShort) "/ 159
(if_icmpne signedBranchShort) "/ 160
(if_icmplt signedBranchShort) "/ 161
(if_icmpge signedBranchShort) "/ 162
(if_icmpgt signedBranchShort) "/ 163
(if_icmple signedBranchShort) "/ 164
(if_acmpeq signedBranchShort) "/ 165
(if_acmpne signedBranchShort) "/ 166
(goto signedBranchShort) "/ 167
(jsr signedBranchShort) "/ 168
(ret localIndexByte) "/ 169
(tableswitch tableSwitchBytes) "/ 170
(lookupswitch lookupSwitchBytes) "/ 171
(ireturn) "/ 172
(lreturn) "/ 173
(freturn) "/ 174
(dreturn) "/ 175
(areturn) "/ 176
(return) "/ 177
(getstatic constIndexShort) "/ 178
(putstatic constIndexShort) "/ 179
(getfield constIndexShort) "/ 180
(putfield constIndexShort) "/ 181
(invokevirtual constIndexShort) "/ 182
(invokenonvirtual constIndexShort) "/ 183
(invokestatic constIndexShort) "/ 184
(invokeinterface constIndexShort nargsByte reservedByte) "/ 185
(newfromname) "/ 186
(new constIndexShort) "/ 187
(newarray arrayTypeByte) "/ 188
(anewarray constIndexShort) "/ 189
(arraylength) "/ 190
(athrow) "/ 191
(checkcast constIndexShort) "/ 192
(instanceof constIndexShort) "/ 193
(monitorenter) "/ 194
(monitorexit) "/ 195
"/ (verifystack) "/ 196 obsolete (Alpha release)
(wide localIndexByte) "/ 196
(multianewarray constIndexShort dimensionsByte) "/ 197
(ifnull signedBranchShort) "/ 198
(ifnonnull signedBranchShort) "/ 199
(#'goto_w' signedBranchLong) "/ 200
(#'jsr_w' signedBranchShort) "/ 201
(breakpoint) "/ 202
nil "/ 203
nil "/ 204
nil "/ 205
nil "/ 206
nil "/ 207
nil "/ 208
(#'ret_w' signedBranchShort) "/ 209
nil "/ 210
nil "/ 211
nil "/ 212
nil "/ 213
nil "/ 214
nil "/ 215
nil "/ 216
nil "/ 217
nil "/ 218
nil "/ 219
nil "/ 220
nil "/ 221
nil "/ 222
nil "/ 223
nil "/ 224
nil "/ 225
nil "/ 226
nil "/ 227
nil "/ 228
nil "/ 229
nil "/ 230
nil "/ 231
nil "/ 232
nil "/ 233
nil "/ 234
nil "/ 235
nil "/ 236
nil "/ 237
nil "/ 238
nil "/ 239
nil "/ 240
nil "/ 241
nil "/ 242
nil "/ 243
nil "/ 244
nil "/ 245
nil "/ 246
nil "/ 247
nil "/ 248
nil "/ 249
nil "/ 250
nil "/ 251
nil "/ 252
nil "/ 253
nil "/ 254
(invokenonvirtual_d constIndexShort) "/ 255 special - dummy invokenonvirtual
)
"
JavaDecompiler initialize
"
"Modified: 16.4.1996 / 14:56:13 / cg"
! !
!JavaDecompiler class methodsFor:'accessing'!
instructionTable
^ DecoderTable
! !
!JavaDecompiler class methodsFor:'decompiling'!
decompile:aJavaMethod
self decompile:aJavaMethod to:Transcript
!
decompile:aJavaMethod to:aStream
self new decompile:aJavaMethod to:aStream
! !
!JavaDecompiler methodsFor:'decompiling'!
decompile:aJavaMethod to:aStream
|who endPC insn spec op|
outStream := aStream.
who := aJavaMethod who.
who notNil ifTrue:[
classToCompileFor := who methodClass.
aStream cr.
"/ aStream showCR:'decompiling ' , classToCompileFor name , '>>' , (who methodSelector) , ':'.
aStream showCR:'decompiling ' , aJavaMethod displayString , ':'.
aJavaMethod isStatic ifTrue:[
aStream show:'static method'.
].
aStream cr.
aStream cr.
].
javaMethod := aJavaMethod.
code := aJavaMethod javaByteCode.
endPC := code size.
endPC == 0 ifTrue:[
javaMethod isNative ifTrue:[
outStream nextPutAll:'implemented in C'; cr
] ifFalse:[
outStream nextPutAll:'no bytecode'; cr
].
^ self
].
pc := 1.
[pc <= endPC] whileTrue:[
insn := code at:pc.
pc := pc + 1.
spec := DecoderTable at:(insn + 1).
spec isNil ifTrue:[
op := '** invalid opcode: ',insn printString, ' **'
] ifFalse:[
op := spec at:1
].
outStream
show:((pc - 1) printStringPaddedTo:4);
show:' ';
show:op;
show:' '.
spec notNil ifTrue:[
spec from:2 to:spec size do:[:what |
self perform:what
].
].
outStream cr.
]
"Created: 16.4.1996 / 14:59:29 / cg"
"Modified: 16.4.1996 / 15:27:05 / cg"
! !
!JavaDecompiler methodsFor:'operand decoding'!
arrayTypeByte
|hi low index type|
index := code at:pc.
pc := pc + 1.
type := #('T_ARRAY' 'invalid' 'invalid' 'T_BOOLEAN'
'T_CHAR' 'T_FLOAT' 'T_DOUBLE' 'T_BYTE'
'T_INT' 'T_LONG' ) at:index ifAbsent:'invalid'.
outStream
show:index;
show:' [';
show:type;
show:']'
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
constIndexByte
|index|
index := code at:pc.
pc := pc + 1.
outStream
show:index;
show:' [';
show:(javaMethod constantPool at:index ifAbsent:['??']) displayString;
show:'] '
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
constIndexShort
|index|
index := code wordAt:pc MSB:true.
pc := pc + 2.
outStream
show:index;
show:' [';
show:(javaMethod constantPool at:index ifAbsent:'???') displayString;
show:'] '
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
dimensionsByte
outStream show:' dims= '.
self unsignedByte
!
localIndexByte
|hi low index constants|
index := code at:pc.
pc := pc + 1.
outStream
show:index;
show:' '
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
lookupSwitchBytes
|defaultOffset delta nPairs match pc0|
pc0 := pc-1. "/ i.e. the pc of the tableSwitch op
[(pc-1) \\ 4 ~~ 0] whileTrue:[
pc := pc + 1
].
defaultOffset := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
nPairs := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
outStream show:'n='; show:nPairs; cr.
nPairs timesRepeat:[
match := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
delta := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
outStream show:' ';
show:match;
show:' -> ';
show:delta;
show:' [';
show:(pc0 + delta);
show:']';
cr.
].
outStream show:' ';
show:'default';
show:' -> ';
show:defaultOffset;
show:' [';
show:(pc0 + defaultOffset);
show:']'.
!
nargsByte
|byte constants|
byte := code byteAt:pc.
pc := pc + 1.
outStream
show:byte
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
reservedByte
|byte constants|
byte := code byteAt:pc.
pc := pc + 1.
outStream
show:byte
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
signedBranchShort
|index constants|
index := code signedWordAt:pc MSB:true.
outStream
show:index;
show:' [';
show:(pc + index - 1);
show:']'.
pc := pc + 2.
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
signedByte
|byte constants|
byte := code signedByteAt:pc.
pc := pc + 1.
outStream
show:byte
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
signedShort
|word constants|
word := code signedWordAt:pc MSB:true.
pc := pc + 2.
outStream
show:word
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
!
tableSwitchBytes
|defaultOffset delta low high pc0|
pc0 := pc-1. "/ i.e. the pc of the tableSwitch op
[(pc-1) \\ 4 ~~ 0] whileTrue:[
pc := pc + 1
].
defaultOffset := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
low := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
high := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
outStream cr.
low to:high do:[:switchValue |
delta := code signedDoubleWordAt:pc MSB:true.
pc := pc + 4.
outStream show:' ';
show:switchValue;
show:' -> ';
show:delta;
show:' [';
show:(pc0 + delta);
show:']';
cr.
].
outStream show:' ';
show:'default';
show:' -> ';
show:defaultOffset;
show:' [';
show:(pc0 + defaultOffset);
show:']'.
!
unsignedByte
|byte constants|
byte := code byteAt:pc.
pc := pc + 1.
outStream
show:byte
"Created: 16.4.1996 / 15:00:04 / cg"
"Modified: 16.4.1996 / 15:30:55 / cg"
! !
!JavaDecompiler class methodsFor:'documentation'!
version
^ '$Header: /home/jv/Projects/SmalltalkX/repositories/cvs/stx/libjava/JavaDecompiler.st,v 1.22 1996/12/07 12:54:07 cg Exp $'
! !
JavaDecompiler initialize!