Object subclass:#JavaClassReader
instanceVariableNames:'inStream msb constants majorVsn minorVsn constNeeds2Slots
constSlot'
classVariableNames:'Verbose Silent AbsolutelySilent LazyClassLoading'
poolDictionaries:''
category:'Java-Support'
!
!JavaClassReader class methodsFor:'initialization'!
initialize
Verbose := false.
Silent := true.
AbsolutelySilent := false.
LazyClassLoading := false. "/ true.
"
JavaClassReader initialize
"
"Modified: 7.2.1997 / 19:25:23 / cg"
! !
!JavaClassReader class methodsFor:'debugging'!
verbose:aBoolean
Verbose := aBoolean
"
Java flushClasses.
JavaClassReader verbose:true
JavaClassReader verbose:false
"
! !
!JavaClassReader class methodsFor:'file reading'!
loadClass:aClassName
"reads a class, installs and returns it.
The classes string constants are resolved & <clinit> is called,
if it implements it."
|rslt|
rslt := self loadClassLazy:aClassName ignoring:Set new.
rslt notNil ifTrue:[self postLoadActions].
^ rslt
"
JavaClassReader loadClass:'awt/Component'
JavaClassReader loadClass:'awt/Button'
JavaClassReader loadClass:'browser/AddButton'
JavaClassReader loadClass:'java/lang/Object'
JavaClassReader loadClass:'java/lang/AbstractMethodError'
JavaClassReader loadClass:'java/lang/Thread'
"
"Created: 15.4.1996 / 14:58:53 / cg"
!
loadClassLazy:aClassName ignoring:classesBeingLoaded
"private helper:
reads a class, installs and returns it.
The class is searched along the ClassPath.
This is a partial load (to load other classes):
- The classes stringConstants are not fixed to be JavaStrings
(i.e they are still ST-Strings).
- The class is not initialized."
|rslt clsName cls loadedClass|
(aClassName endsWith:';') ifTrue:[
('oops - loading of ' , aClassName , ' attempted') printNL.
self halt:'should not happen'.
^ nil
].
(aClassName endsWith:'[]') ifTrue:[
('oops - loading of ' , aClassName , ' attempted') printNL.
self halt:'should not happen'.
^ nil
].
clsName := aClassName.
(clsName includes:$.) ifTrue:[
clsName := clsName copy replaceAll:$. by:$/
].
(classesBeingLoaded notNil and:[classesBeingLoaded includes:clsName]) ifTrue:[
('oops - recursive load of ' , clsName , ' attempted') printNL.
self halt:'should not happen'.
^ JavaUnresolvedClassConstant fullName:clsName
].
(cls := Java at:clsName) notNil ifTrue:[
('oops - ' , clsName , ' is already loaded') printNL.
self halt:clsName , ' is already loaded - should not happen'.
^ cls
].
classesBeingLoaded isNil ifTrue:[
loadedClass := Set with:clsName
] ifFalse:[
loadedClass := Set withAll:classesBeingLoaded.
loadedClass add:clsName.
].
Java classPath do:[:path |
|nm p|
p := path.
(p endsWith:Filename separator) ifFalse:[
p := p , (Filename separator asString)
].
(nm := p , clsName , '.class') asFilename exists ifTrue:[
rslt := self loadFileLazy:nm ignoring:loadedClass.
rslt notNil ifTrue:[^ rslt].
]
].
('JAVA: no file found for: ' , clsName) infoPrintCR.
^ nil
"Modified: 30.7.1997 / 16:58:30 / cg"
!
loadFile:aFilename
"reads a class from aFilename, installs and returns it.
The classes strings are fixed and its class-init function is called."
self loadFileLazy:aFilename ignoring:(Set new).
self postLoadActions
!
loadFileLazy:aFilename ignoring:classesBeingLoaded
"reads a class from aFilename, installs and returns it.
Strings are fixed and classrefs are fixed,
but NO no class-init functions are called."
|javaClass pool|
javaClass := self readFile:aFilename ignoring:classesBeingLoaded.
javaClass notNil ifTrue:[
Java at:(javaClass fullName asSymbol) put:javaClass.
classesBeingLoaded remove:javaClass fullName ifAbsent:nil.
JavaUnresolvedConstant resolveFor:javaClass.
].
^ javaClass
"
JavaClassReader loadFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
'/phys/ibm3/java/lib/java/lang' asFilename
directoryContents do:[:nm |
(nm endsWith:'.class') ifTrue:[
('/phys/ibm3/java/lib/java/lang/' , nm) printNL.
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/lang/' , nm
]
].
'/phys/ibm3/java/lib/java/io' asFilename
directoryContents do:[:nm |
(nm endsWith:'.class') ifTrue:[
('/phys/ibm3/java/lib/java/io/' , nm) printNL.
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/io/' , nm
]
].
'/phys/ibm3/java/lib/java/net' asFilename
directoryContents do:[:nm |
(nm endsWith:'.class') ifTrue:[
('/phys/ibm3/java/lib/java/net/' , nm) printNL.
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/net/' , nm
]
].
'/phys/ibm3/java/lib/java/util' asFilename
directoryContents do:[:nm |
(nm endsWith:'.class') ifTrue:[
('/phys/ibm3/java/lib/java/util/' , nm) printNL.
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/util/' , nm
]
].
'/phys/ibm3/java/lib/java/awt' asFilename
directoryContents do:[:nm |
(nm endsWith:'.class') ifTrue:[
('/phys/ibm3/java/lib/java/awt/' , nm) printNL.
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/awt/' , nm
]
].
'/phys/ibm3/java/lib/java/applet' asFilename
directoryContents do:[:nm |
(nm endsWith:'.class') ifTrue:[
('/phys/ibm3/java/lib/java/applet/' , nm) printNL.
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/applet/' , nm
]
].
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/lang/AbstractMethodError.class'
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/lang/Thread.class'
"
"Created: 15.4.1996 / 14:58:53 / cg"
!
postLoadActions
"Resolve all classes' string constants.
Perform all class initialization functions (of those which are not
yet initialized)."
|classes prevUnresolved newUnresolved|
"/ need at least java.lang.String, for valid constants
Java java_lang_String isNil ifTrue:[
self loadClassLazy:'java.lang.String' ignoring:Set new.
].
LazyClassLoading ifFalse:[
prevUnresolved := nil.
newUnresolved := JavaUnresolvedConstant unresolvedClassNames asArray.
[prevUnresolved ~= newUnresolved] whileTrue:[
newUnresolved do:[:nextUnresolved |
(Java at:nextUnresolved) isNil ifTrue:[ "/ could have been loaded in the meantime
Silent ifFalse:[
'loading unresolved: ' print. nextUnresolved printCR.
].
self
loadClassLazy:nextUnresolved
ignoring:Set new.
]
].
prevUnresolved := newUnresolved.
newUnresolved := JavaUnresolvedConstant unresolvedClassNames asArray.
].
newUnresolved size == 0 ifTrue:[
"/ nothing unresolved
(classes := Java allClasses) notNil ifTrue:[
"/ init all new classes
"/ fetch again - there could be new ones ...
classes := Java allClasses.
classes do:[:aJavaClass |
aJavaClass isInitialized ifFalse:[
Silent ifFalse:[
'performing class initialization of ' print. aJavaClass fullName printCR.
].
aJavaClass classInit
]
]
]
].
]
"Modified: 26.3.1997 / 13:43:45 / cg"
!
readFile:aFilename ignoring:classesBeingLoaded
"reads a class from aFilename and returns it.
The JavaClass is NOT installed as global and unresolved
refs are NOT patched."
|inStream javaClass|
Silent ifFalse:[
'reading ' print. aFilename print. ' ...' printNL.
].
inStream := aFilename asFilename readStream.
inStream isNil ifTrue:[
('no file: ' , aFilename) printCR.
self halt.
^ nil
].
javaClass := self new readStream:inStream ignoring:classesBeingLoaded.
javaClass notNil ifTrue:[
javaClass setBinaryFilePath:(inStream pathName).
].
inStream close.
AbsolutelySilent ifFalse:[
' ... loaded ' print. javaClass displayString printNL.
].
^ javaClass
"Created: 15.4.1996 / 14:58:53 / cg"
!
readStream:aStream ignoring:classesBeingLoaded
"reads a class from aStream and returns it.
The JavaClass is not installed as global"
^ self new readStream:aStream ignoring:classesBeingLoaded
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Modified: 15.4.1996 / 15:01:30 / cg"
! !
!JavaClassReader methodsFor:'file reading'!
readClassFileIgnoring:classesbeingLoaded
"reads a class from inStream and returns it.
The JavaClass is not installed as global and its constants
(especially strings) may not be fully resolved."
|magic
access_flags this_class this_class_index super_class super_class_index
realSuperClass this_class_ref existingSuperClass
fields interfaces staticFields nStatic|
"/
"/ read magic, determine byte order
"/
msb := true.
magic := inStream nextUnsignedLongMSB:msb.
magic = 16rCAFEBABE ifFalse:[
magic = 16rBEBAFECA ifFalse:[
self error:'not a java class file'.
^ nil
].
msb := false.
Verbose ifTrue:[Transcript showCR:'file is lsb'].
] ifTrue:[
Verbose ifTrue:[Transcript showCR:'file is msb'].
].
"/
"/ get version
"/
minorVsn := inStream nextUnsignedShortMSB:msb.
majorVsn := inStream nextUnsignedShortMSB:msb.
(majorVsn ~~ 45 or:[minorVsn ~~ 3]) ifTrue:[
Transcript show:'warning this file has version '; show:majorVsn; show:'.'; showCR:minorVsn.
].
Verbose ifTrue:[
Transcript show:'version = ';
show:(majorVsn printString);
show:'.';
showCR:(minorVsn printString).
].
"/
"/ get constant pool
"/
self readConstantPool.
"/
"/ access flags
"/
access_flags := inStream nextUnsignedShortMSB:msb.
this_class_index := inStream nextUnsignedShortMSB:msb.
super_class_index := inStream nextUnsignedShortMSB:msb.
super_class_index == 0 ifTrue:[
super_class := nil
] ifFalse:[
super_class := constants at:super_class_index.
existingSuperClass := Java classNamed:super_class fullName.
existingSuperClass notNil ifTrue:[
super_class := existingSuperClass
] ifFalse:[
(super_class isMemberOf:JavaUnresolvedClassConstant) ifTrue:[
Silent ifFalse:[
'load superClass: ' print. super_class fullName printCR.
].
existingSuperClass := self class
loadClassLazy:(super_class fullName)
ignoring:classesbeingLoaded.
existingSuperClass isNil ifTrue:[
self halt:('cannot find superclass: ' , super_class fullName).
].
super_class := existingSuperClass
] ifFalse:[
self halt:'oops - superclass ?'
]
].
].
"/
"/ get interfaces
"/
interfaces := self readInterfaces.
"/
"/ get fields
"/
fields := self readFieldInfofields.
"/
"/ create the fields as instVars
"/ static fields are created as class-InstVars
"/
staticFields := fields select:[:f | f isStatic].
nStatic := staticFields size.
this_class_ref := constants at:this_class_index.
nStatic ~~ 0 ifTrue:[
fields := fields select:[:f | f isStatic not].
this_class := JavaClass fullName:(this_class_ref fullName) numStatic:nStatic.
JavaClass setInstanceVariableStringFromFields:staticFields in:this_class class.
this_class setStaticFields:staticFields.
this_class initializeStaticFields.
] ifFalse:[
this_class := JavaClass fullName:(this_class_ref fullName) numStatic:0.
].
this_class setAccessFlags:access_flags.
this_class setSuperclass:super_class.
this_class setConstantPool:constants.
this_class setFields:fields.
this_class setInterfaces:interfaces.
"/
"/ get methods
"/
self readMethodsFor:this_class.
self readAttributesFor:this_class.
constants owner:this_class.
^ this_class
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
JavaClassReader verbose:true.
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/java/lang/ArithmeticException.class'
JavaClassReader readFile:'/phys/ibm3/java/lib/java/lang/ArithmeticException.class'
"
"Created: 15.4.1996 / 15:02:47 / cg"
"Modified: 15.4.1996 / 16:51:48 / cg"
!
readSourceFileAttributeFor:aJavaClass
|attribute_length sourceFile_index sourceFile|
attribute_length := inStream nextUnsignedLongMSB:msb.
sourceFile_index := inStream nextUnsignedShortMSB:msb.
sourceFile := constants at:sourceFile_index.
aJavaClass setSourceFile:sourceFile.
Verbose ifTrue:[Transcript show:'sourceFile: '; showCR:sourceFile].
^ true
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readStream:aStream ignoring:classesBeingLoaded
"reads a class from aStream and returns it.
The JavaClass is not installed as global"
inStream := aStream.
inStream binary.
^ self readClassFileIgnoring:classesBeingLoaded
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:00:55 / cg"
"Modified: 15.4.1996 / 15:06:18 / cg"
! !
!JavaClassReader methodsFor:'file reading - attributes'!
readAttribute:attributeName for:something
(attributeName = 'Code') ifTrue:[
self readCodeAttributeFor:something.
^ true.
].
(attributeName = 'Exceptions') ifTrue:[
self readExceptionsAttributeFor:something.
^ true.
].
(attributeName = 'LineNumberTable') ifTrue:[
self readLineNumberTableAttributeFor:something.
^ true.
].
(attributeName = 'LocalVariableTable') ifTrue:[
self readLocalVariableTableAttributeFor:something.
^ true.
].
(attributeName = 'ConstantValue') ifTrue:[
self readConstantValueAttributeFor:something.
^ true.
].
(attributeName = 'SourceFile') ifTrue:[
self readSourceFileAttributeFor:something.
^ true.
].
('JAVA: unrecognized attribute: ' , attributeName) infoPrintCR.
^ false
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readAttributeFor:something
|attribute_name_index attribute_name attribute_length attribute_info|
Verbose ifTrue:[Transcript show:'attrib at pos: '; showCR:inStream position].
attribute_name_index := inStream nextUnsignedShortMSB:msb.
"/
"/ UNDOC feature ?
"/
attribute_name_index > constants size ifTrue:[
attribute_name_index == 16rb700 ifTrue:[
self halt.
]
].
attribute_name := constants at:attribute_name_index.
Verbose ifTrue:[Transcript show:'attrib name: '; showCR:attribute_name].
(self readAttribute:attribute_name for:something) ifFalse:[
attribute_length := inStream nextUnsignedLongMSB:msb.
attribute_info := ByteArray new:(attribute_length).
inStream nextBytes:attribute_length into:attribute_info startingAt:1.
Verbose ifTrue:[Transcript show:'skipped '; show:attribute_name; showCR:'-attribute'].
].
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readAttributesFor:something
|attributes_count|
attributes_count := inStream nextUnsignedShortMSB:msb.
1 to:attributes_count do:[:i |
self readAttributeFor:something.
].
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
! !
!JavaClassReader methodsFor:'file reading - constants'!
readConstant
|tag constReader const|
constNeeds2Slots := false.
"/
"/ get tag
"/
tag := inStream nextByte.
Verbose ifTrue:[Transcript show:'tag = '; showCR:tag].
constReader := #(
readConstant_Asciz "/ 1 - now called Utf8
readConstant_Unicode "/ 2
readConstant_Integer "/ 3
readConstant_Float "/ 4
readConstant_Long "/ 5
readConstant_Double "/ 6
readConstant_Class "/ 7
readConstant_String "/ 8
readConstant_Fieldref "/ 9
readConstant_Methodref "/ 10
readConstant_InterfaceMethodref "/ 11
readConstant_NameAndType "/ 12
) at:tag ifAbsent:[#readConstant_Undef].
^ self perform:constReader.
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:46:32 / cg"
"Modified: 15.4.1996 / 15:47:00 / cg"
!
readConstantPool
|constantPoolCount const i|
"/
"/ get constant pool
"/
constantPoolCount := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'constantPoolCount = '; showCR:constantPoolCount].
constants := JavaConstantPool "Array" new:constantPoolCount-1.
constSlot := 1.
[constSlot < constantPoolCount] whileTrue:[
Verbose ifTrue:[Transcript show:'const: '; showCR:constSlot].
const := self readConstant.
constants at:constSlot put:const.
constNeeds2Slots ifTrue:[
constSlot := constSlot + 1.
].
constSlot := constSlot + 1.
].
constSlot := -1.
"/ preresolve what can be (especially, strings are resolved here)
1 to:constantPoolCount-1 do:[:i |
|const value|
const := constants at:i.
const notNil ifTrue:[ "/ kludge for 2-slot constants (which only take 1 slot in ST/X)
(const isKindOf:JavaUnresolvedConstant) ifTrue:[
value := const preResolve.
value ~~ const ifTrue:[
constants at:i put:value.
]
]
]
].
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Created: 15.4.1996 / 15:14:11 / cg"
"Modified: 15.4.1996 / 16:41:57 / cg"
!
readConstant_Asciz
|len string|
len := inStream nextUnsignedShortMSB:msb.
string := String new:len.
inStream nextBytes:len into:string startingAt:1.
Verbose ifTrue:[Transcript show:'asciz; string= '; showCR:string].
^ string
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Created: 15.4.1996 / 15:15:35 / cg"
"Modified: 15.4.1996 / 16:33:45 / cg"
!
readConstant_Class
|name_index name|
name_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'class; index= '; showCR:name_index].
name := constants at:name_index.
name notNil ifTrue:[
self halt
].
^ JavaUnresolvedClassConstant
pool:constants
poolIndex:constSlot
nameIndex:name_index
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:21:13 / cg"
"Modified: 15.4.1996 / 15:49:32 / cg"
!
readConstant_Double
|high low aFloat|
high := inStream nextUnsignedLongMSB:msb.
low := inStream nextUnsignedLongMSB:msb.
aFloat := Float new.
UninterpretedBytes isBigEndian ifTrue:[
aFloat basicAt:1 put:((high bitShift:-24) bitAnd:16rFF).
aFloat basicAt:2 put:((high bitShift:-16) bitAnd:16rFF).
aFloat basicAt:3 put:((high bitShift:-8) bitAnd:16rFF).
aFloat basicAt:4 put:(high bitAnd:16rFF).
aFloat basicAt:5 put:((low bitShift:-24) bitAnd:16rFF).
aFloat basicAt:6 put:((low bitShift:-16) bitAnd:16rFF).
aFloat basicAt:7 put:((low bitShift:-8) bitAnd:16rFF).
aFloat basicAt:8 put:(low bitAnd:16rFF).
] ifFalse:[
aFloat basicAt:1 put:(low bitAnd:16rFF).
aFloat basicAt:2 put:((low bitShift:-8) bitAnd:16rFF).
aFloat basicAt:3 put:((low bitShift:-16) bitAnd:16rFF).
aFloat basicAt:4 put:((low bitShift:-24) bitAnd:16rFF).
aFloat basicAt:5 put:(high bitAnd:16rFF).
aFloat basicAt:6 put:((high bitShift:-8) bitAnd:16rFF).
aFloat basicAt:7 put:((high bitShift:-16) bitAnd:16rFF).
aFloat basicAt:8 put:((high bitShift:-24) bitAnd:16rFF).
].
constNeeds2Slots := true.
Verbose ifTrue:[Transcript show:'double; value= '; showCR:aFloat].
^ aFloat
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Modified: 15.4.1996 / 15:42:16 / cg"
"Created: 15.4.1996 / 16:34:42 / cg"
!
readConstant_Fieldref
|class_index name_and_type_index|
class_index := inStream nextUnsignedShortMSB:msb.
name_and_type_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'fieldref; classindex= '; showCR:class_index].
Verbose ifTrue:[Transcript show:'fieldref; name&typeindex= '; showCR:name_and_type_index].
^ JavaUnresolvedFieldrefConstant
pool:constants
poolIndex:constSlot
classIndex:class_index
nameandTypeIndex:name_and_type_index
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:22:18 / cg"
"Modified: 15.4.1996 / 16:07:01 / cg"
!
readConstant_Float
|high aFloat|
high := inStream nextUnsignedLongMSB:msb.
aFloat := ShortFloat basicNew.
UninterpretedBytes isBigEndian ifTrue:[
aFloat basicAt:1 put:((high bitShift:-24) bitAnd:16rFF).
aFloat basicAt:2 put:((high bitShift:-16) bitAnd:16rFF).
aFloat basicAt:3 put:((high bitShift:-8) bitAnd:16rFF).
aFloat basicAt:4 put:(high bitAnd:16rFF).
] ifFalse:[
aFloat basicAt:1 put:(high bitAnd:16rFF).
aFloat basicAt:2 put:((high bitShift:-8) bitAnd:16rFF).
aFloat basicAt:3 put:((high bitShift:-16) bitAnd:16rFF).
aFloat basicAt:4 put:((high bitShift:-24) bitAnd:16rFF).
].
Verbose ifTrue:[Transcript show:'float; value= '; showCR:aFloat].
^ aFloat
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Modified: 15.4.1996 / 15:42:16 / cg"
"Created: 15.4.1996 / 16:34:42 / cg"
!
readConstant_Integer
|value|
value := inStream nextLongMSB:msb.
Verbose ifTrue:[Transcript show:'integer; value= '; showCR:value].
^ value
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Modified: 15.4.1996 / 15:42:16 / cg"
"Created: 15.4.1996 / 16:34:42 / cg"
!
readConstant_InterfaceMethodref
|class_index name_and_type_index|
class_index := inStream nextUnsignedShortMSB:msb.
name_and_type_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'methodref; classindex= '; showCR:class_index].
Verbose ifTrue:[Transcript show:'methodref; name&typeindex= '; showCR:name_and_type_index].
^ JavaUnresolvedInterfaceMethodrefConstant
pool:constants
poolIndex:constSlot
classIndex:class_index
nameandTypeIndex:name_and_type_index
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:22:37 / cg"
"Modified: 15.4.1996 / 16:07:19 / cg"
!
readConstant_Long
|high low value|
high := inStream nextUnsignedLongMSB:msb.
low := inStream nextUnsignedLongMSB:msb.
value := (high bitShift:32) bitOr:low.
(high bitTest:16r80000000) ifTrue:[
value := value - 16r10000000000000000.
].
constNeeds2Slots := true.
Verbose ifTrue:[Transcript show:'long; value= '; showCR:value].
^ value
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Modified: 15.4.1996 / 15:42:16 / cg"
"Created: 15.4.1996 / 16:34:42 / cg"
!
readConstant_Methodref
|class_index name_and_type_index|
class_index := inStream nextUnsignedShortMSB:msb.
name_and_type_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'methodref; classindex= '; showCR:class_index].
Verbose ifTrue:[Transcript show:'methodref; name&typeindex= '; showCR:name_and_type_index].
^ JavaUnresolvedMethodrefConstant
pool:constants
poolIndex:constSlot
classIndex:class_index
nameandTypeIndex:name_and_type_index
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:22:37 / cg"
"Modified: 15.4.1996 / 16:07:19 / cg"
!
readConstant_NameAndType
|name_index signature_index|
name_index := inStream nextUnsignedShortMSB:msb.
signature_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'methodref; nameindex= '; showCR:name_index].
Verbose ifTrue:[Transcript show:'methodref; signatureindex= '; showCR:signature_index].
^ JavaUnresolvedNameandTypeConstant
pool:constants
poolIndex:constSlot
nameIndex:name_index
signatureIndex:signature_index
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:23:43 / cg"
"Modified: 15.4.1996 / 16:17:16 / cg"
!
readConstant_String
|tag string_index|
string_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'string; index= '; showCR:string_index].
^ JavaUnresolvedStringConstant
pool:constants
poolIndex:constSlot
stringIndex:string_index
"
Verbose := true.
JavaClassReader readFile:'/phys/ibm3/java/lib/java/lang/System.class'
"
"Created: 15.4.1996 / 15:20:33 / cg"
"Modified: 15.4.1996 / 16:01:37 / cg"
! !
!JavaClassReader methodsFor:'file reading - fields'!
readConstantValueAttributeFor:aField
|attribute_length constantvalue_index constantValue|
attribute_length := inStream nextUnsignedLongMSB:msb.
constantvalue_index := inStream nextUnsignedShortMSB:msb.
constantValue := constants at:constantvalue_index.
aField constantValue:constantValue.
Verbose ifTrue:[Transcript show:'constantValue: '; showCR:constantValue].
^ true
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readFieldInfofield
|access_flags name_index signature_index attributes_count field|
access_flags := inStream nextUnsignedShortMSB:msb.
name_index := inStream nextUnsignedShortMSB:msb.
signature_index := inStream nextUnsignedShortMSB:msb.
field := JavaField new.
field setAccessFlags:access_flags.
field setName:(constants at:name_index).
field setSignature:(constants at:signature_index).
attributes_count := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:' field name: '; show:(constants at:name_index);
show:' access: '; show:access_flags;
show:' attrib_cnt: '; showCR:attributes_count].
1 to:attributes_count do:[:i |
self readAttributeFor:field.
].
^ field
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:38:43 / cg"
!
readFieldInfofields
|nFields fields|
"/
"/ get fieldInfos
"/
nFields := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'fieldsCount = '; showCR:nFields].
fields := Array new:nFields.
1 to:nFields do:[:i |
Verbose ifTrue:[Transcript show:'field: '; showCR:i].
fields at:i put:(self readFieldInfofield)
].
^ fields
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:34:41 / cg"
"Modified: 15.4.1996 / 15:35:28 / cg"
! !
!JavaClassReader methodsFor:'file reading - interfaces'!
readInterfaces
|interfacesCount interface_index interface interfaces|
"/
"/ get interfaces
"/
interfacesCount := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'interfacesCount = '; showCR:interfacesCount].
interfaces := Array new:interfacesCount.
1 to:interfacesCount do:[:i |
Verbose ifTrue:[Transcript show:'interface: '; showCR:i].
interface_index := inStream nextUnsignedShortMSB:msb.
interface := constants at:interface_index.
interfaces at:i put:interface.
].
^ interfaces
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: 15.4.1996 / 15:31:59 / cg"
"Modified: 15.4.1996 / 15:33:28 / cg"
! !
!JavaClassReader methodsFor:'file reading - methods'!
readCodeAttributeFor:aJavaMethod
|attribute_length max_stack max_locals code_length code
exception_table_length exception_table unknown1 unknown2|
attribute_length := inStream nextUnsignedLongMSB:msb.
Verbose ifTrue:[Transcript show:'attribute_length: 0x'; showCR:(attribute_length printStringRadix:16)].
minorVsn > 2 ifTrue:[
unknown1 := inStream nextByte.
max_stack := inStream nextByte.
max_locals := inStream nextUnsignedShortMSB:msb.
unknown2 := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'?1: '; showCR:unknown1].
Verbose ifTrue:[Transcript show:'?2: '; showCR:unknown2].
] ifFalse:[
max_stack := inStream nextByte.
max_locals := inStream nextByte.
].
code_length := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'code_length: '; showCR:(code_length printStringRadix:16)].
Verbose ifTrue:[Transcript show:'code at pos: '; showCR:inStream position].
code := ByteArray new:code_length.
inStream nextBytes:code_length into:code startingAt:1.
Verbose ifTrue:[Transcript show:'method code:'; showCR:code.].
exception_table_length := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'exception_table_length: '; showCR:(exception_table_length printStringRadix:16)].
exception_table_length ~~ 0 ifTrue:[
Verbose ifTrue:[Transcript show:'exceptionTable length:'; showCR:exception_table_length.].
exception_table := Array new:exception_table_length.
1 to:exception_table_length do:[:i |
|start_pc end_pc handler_pc catch_type|
start_pc := inStream nextUnsignedShortMSB:msb.
end_pc := inStream nextUnsignedShortMSB:msb.
handler_pc := inStream nextUnsignedShortMSB:msb.
catch_type := constants at:(inStream nextUnsignedShortMSB:msb).
exception_table at:i put:(JavaExceptionTableEntry
startPC:start_pc
endPC:end_pc
handlerPC:handler_pc
catchType:catch_type).
].
aJavaMethod setExceptionHandlerTable:exception_table.
].
aJavaMethod
setCode:code
maxStack:max_stack
maxLocals:max_locals
u1:unknown1
u2:unknown2.
self readAttributesFor:aJavaMethod.
^ true
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readExceptionsAttributeFor:aJavaMethod
|attribute_length exception_table_length exception_table|
attribute_length := inStream nextUnsignedLongMSB:msb.
exception_table_length := inStream nextUnsignedShortMSB:msb.
exception_table_length ~~ 0 ifTrue:[
exception_table := Array new:exception_table_length.
1 to:exception_table_length do:[:i |
|idx ex|
idx := inStream nextUnsignedShortMSB:msb.
ex := constants at:idx.
exception_table at:i put:ex.
].
].
Verbose ifTrue:[Transcript showCR:'method has an exceptionTable'].
aJavaMethod setExceptionTable:exception_table.
^ true
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readLineNumberTableAttributeFor:aJavaMethod
|attribute_length line_number_table_length line_number_table|
attribute_length := inStream nextUnsignedLongMSB:msb.
line_number_table_length := inStream nextUnsignedShortMSB:msb.
line_number_table_length ~~ 0 ifTrue:[
line_number_table := Array new:line_number_table_length.
1 to:line_number_table_length do:[:i |
|start_pc line_number|
start_pc := inStream nextUnsignedShortMSB:msb.
line_number := inStream nextUnsignedShortMSB:msb.
line_number_table at:i put:(start_pc -> line_number).
].
].
Verbose ifTrue:[Transcript showCR:'method has a lineNumberTable'].
aJavaMethod setLineNumberTable:line_number_table.
^ true
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/java/lang/Boolean.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readLocalVariableTableAttributeFor:aJavaMethod
|attribute_length local_variable_table_length local_variable_table|
attribute_length := inStream nextUnsignedLongMSB:msb.
local_variable_table_length := inStream nextUnsignedShortMSB:msb.
local_variable_table_length ~~ 0 ifTrue:[
local_variable_table := JavaLocalVariableTable new:local_variable_table_length.
1 to:local_variable_table_length do:[:i |
|start_pc length name_index sig_index slot name signature|
start_pc := inStream nextUnsignedShortMSB:msb.
length := inStream nextUnsignedShortMSB:msb.
name_index := inStream nextUnsignedShortMSB:msb.
name := constants at:name_index.
sig_index := inStream nextUnsignedShortMSB:msb.
signature := constants at:sig_index.
slot := inStream nextUnsignedShortMSB:msb.
local_variable_table at:i put:(JavaLocalVariableTableEntry new
startPC:start_pc
length:length
name:name
signature:signature
slot:slot)
].
].
Verbose ifTrue:[Transcript showCR:'method has a localvariableTable'].
aJavaMethod setLocalVariableTable:local_variable_table.
^ true
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/java/lang/Boolean.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 15:40:17 / cg"
!
readMethodFor:aJavaClass
|m access_flags name_index name signature_index signature|
"/
"/ get a method
"/
access_flags := inStream nextUnsignedShortMSB:msb.
name_index := inStream nextUnsignedShortMSB:msb.
signature_index := inStream nextUnsignedShortMSB:msb.
name := constants at:name_index.
signature := constants at:signature_index.
Verbose ifTrue:[Transcript show:'method name:'; showCR:name.
Transcript show:'signature:'; showCR:signature.].
m := JavaMethod new.
m setAccessFlags:access_flags.
m setSignature:signature.
m setName:name.
m setJavaClass:aJavaClass.
self readAttributesFor:m.
aJavaClass addMethod:m name:name signature:signature.
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 16:48:49 / cg"
!
readMethodsFor:aJavaClass
|methodsCount method|
"/
"/ get methods
"/
methodsCount := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'methodsCount = '; showCR:methodsCount].
1 to:methodsCount do:[:i |
Verbose ifTrue:[Transcript show:'method: '; showCR:i].
method := self readMethodFor:aJavaClass
].
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Modified: 15.4.1996 / 15:33:28 / cg"
"Created: 15.4.1996 / 16:46:30 / cg"
! !
!JavaClassReader class methodsFor:'documentation'!
version
^ '$Header: /home/jv/Projects/SmalltalkX/repositories/cvs/stx/libjava/JavaClassReader.st,v 1.40 1997/07/30 16:11:21 cg Exp $'
! !
JavaClassReader initialize!