Object subclass:#JavaClassReader
instanceVariableNames:'inStream msb constants majorVsn minorVsn constNeeds2Slots
constSlot'
classVariableNames:'Verbose Silent AbsolutelySilent LazyClassLoading
InvalidClassFormatSignal ClassLoaderQuerySignal'
poolDictionaries:''
category:'Java-Support'
!
!JavaClassReader class methodsFor:'initialization'!
initialize
InvalidClassFormatSignal := Signal new mayProceed:true.
InvalidClassFormatSignal notifierString:'class load failure'.
InvalidClassFormatSignal nameClass:self message:#invalidClassFormatSignal.
Verbose := false.
Silent := true.
AbsolutelySilent := false.
LazyClassLoading := false. "/ true.
ClassLoaderQuerySignal := QuerySignal new
"
JavaClassReader initialize
"
"Modified: / 27.1.1998 / 17:54:23 / cg"
! !
!JavaClassReader class methodsFor:'Signal constants'!
classLoaderQuerySignal
^ ClassLoaderQuerySignal
"Created: 14.8.1997 / 19:56:03 / cg"
!
invalidClassFormatSignal
^ InvalidClassFormatSignal
"Created: 3.8.1997 / 18:17:21 / cg"
! !
!JavaClassReader class methodsFor:'constants'!
fileMajorVersion
^ 45
"Modified: / 7.5.1998 / 13:14:27 / cg"
"Created: / 7.5.1998 / 13:16:35 / cg"
!
fileMinorVersion
^ 3
"Modified: / 7.5.1998 / 13:14:27 / cg"
"Created: / 7.5.1998 / 13:16:40 / cg"
!
magic_LSB
^ 16rBEBAFECA
"Modified: / 7.5.1998 / 13:14:27 / cg"
"Created: / 7.5.1998 / 13:15:05 / cg"
!
magic_MSB
^ 16rCAFEBABE
"Modified: / 7.5.1998 / 13:14:27 / 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 loader|
loader := ClassLoaderQuerySignal raise.
loader isNil ifTrue:[
^ self loadSystemClass:aClassName
].
^ loader loadClass:aClassName
"
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"
"Modified: / 20.10.1998 / 17:24:54 / 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 asString copyReplaceAll:$. with:$/
].
(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 zar entry zipFile|
p := path.
p asFilename isDirectory ifTrue:[
(p endsWith:Filename separator) ifFalse:[
p := p , (Filename separator asString)
].
(Array
with:clsName
with:clsName asLowercase
with:clsName asUppercase)
do:[:tryName |
(nm := p , tryName , '.class') asFilename exists ifTrue:[
(Java isExcludedFromClassPath:nm) ifFalse:[
rslt := self loadFileLazy:nm ignoring:loadedClass.
rslt notNil ifTrue:[^ rslt].
]
].
]
] ifFalse:[
((zipFile := p asFilename withSuffix:'jar') exists
or:[(zipFile := p asFilename withSuffix:'zip') exists]) ifTrue:[
zar := ZipArchive oldFileNamed:zipFile.
(Array
with:clsName
with:clsName asLowercase
with:clsName asUppercase)
do:[:tryName |
nm := tryName , '.class'.
entry := zar extract:nm.
entry notNil ifTrue:[
(Java isExcludedFromClassPath:nm) ifFalse:[
rslt := self loadStreamLazy:(entry readStream) ignoring:loadedClass.
rslt notNil ifTrue:[^ rslt].
]
]
]
]
]
].
('JAVA [info]: no file found for: ' , clsName) infoPrintCR.
^ nil
"Modified: / 14.8.1997 / 11:38:42 / stefan"
"Modified: / 17.9.1998 / 20:51:25 / 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."
|aClass pool|
aClass := self readFile:aFilename ignoring:classesBeingLoaded.
aClass notNil ifTrue:[
aClass isJavaClass ifTrue:[
"/ a java class
Java at:(aClass fullName asSymbol) put:aClass.
classesBeingLoaded remove:aClass fullName ifAbsent:nil.
JavaUnresolvedConstant resolveFor:aClass.
] ifFalse:[
"/ a smalltalk class
"/ self halt.
aClass inspect.
]
].
^ aClass
"
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"
"Modified: / 12.5.1998 / 22:06:52 / cg"
!
loadStreamLazy:aStream ignoring:classesBeingLoaded
"reads a class from aStream, installs and returns it.
Strings are fixed and classrefs are fixed,
but NO no class-init functions are called."
|javaClass pool|
javaClass := self readStream:aStream ignoring:classesBeingLoaded.
javaClass notNil ifTrue:[
Java at:(javaClass fullName asSymbol) put:javaClass.
classesBeingLoaded remove:javaClass fullName ifAbsent:nil.
JavaUnresolvedConstant resolveFor:javaClass.
].
^ javaClass
"Created: / 30.3.1998 / 17:59:02 / cg"
!
loadSystemClass:aClassName
"reads a class, installs and returns it.
The classes string constants are resolved & <clinit> is called,
if it implements it.
This only loads local classes (i.e. any Java classReader is not used)"
|rslt|
rslt := self loadClassLazy:aClassName ignoring:(Set new).
rslt notNil ifTrue:[self postLoadActions].
^ rslt
"
JavaClassReader loadSystemClass:'awt/Component'
JavaClassReader loadSystemClass:'awt/Button'
JavaClassReader loadSystemClass:'browser/AddButton'
JavaClassReader loadSystemClass:'java/lang/Object'
JavaClassReader loadSystemClass:'java/lang/AbstractMethodError'
JavaClassReader loadSystemClass:'java/lang/Thread'
"
"Modified: / 3.1.1998 / 22:36:13 / cg"
"Created: / 20.10.1998 / 17:24:40 / cg"
!
postLoadActions
"Resolve all classes' string constants.
Perform all class initialization functions (of those which are not
yet initialized)."
^ self postLoadActions:true
"Modified: 15.8.1997 / 01:02:17 / cg"
!
postLoadActions:loadUnresolved
"Resolve all classes' string constants.
Perform all class initialization functions
(of those which are not yet initialized)."
|classes prevUnresolved newUnresolved loader|
"/ 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:[
loader := ClassLoaderQuerySignal raise.
prevUnresolved := nil.
newUnresolved := JavaUnresolvedConstant unresolvedClassNames asArray.
loadUnresolved ifTrue:[
[prevUnresolved ~= newUnresolved] whileTrue:[
newUnresolved do:[:nextUnresolved |
|classURL|
(Java at:nextUnresolved) isNil ifTrue:[ "/ could have been loaded in the meantime
Silent ifFalse:[
'loading unresolved: ' print. nextUnresolved printCR.
].
loader isNil ifTrue:[
self
loadClassLazy:nextUnresolved
ignoring:(Set new).
] ifFalse:[
"/
"/ the aquired loader is a javaClassLoader
"/ which expects an URL as arg.
"/
"/ classURL := Java as_URL:('file:' , nextUnresolved asString , '.class').
"/ loader loadClass:classURL
loader
perform:#'loadClass(Ljava/lang/String;)Ljava/lang/Class;'
with:(Java as_String:(nextUnresolved asString)).
]
]
].
prevUnresolved := newUnresolved.
newUnresolved := JavaUnresolvedConstant unresolvedClassNames asArray.
].
].
false ifTrue:[
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
]
]
]
].
].
]
"Created: / 15.8.1997 / 01:01:44 / cg"
"Modified: / 21.10.1998 / 01:18:35 / 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:[
('JAVA [info]: no file: ' , aFilename) printCR.
self halt.
^ nil
].
javaClass := self new readStream:inStream ignoring:classesBeingLoaded.
(javaClass notNil and:[javaClass isJavaClass]) ifTrue:[
javaClass setBinaryFilePath:(inStream pathName).
].
inStream close.
AbsolutelySilent ifFalse:[
' ... loaded ' print. javaClass displayString printNL.
].
^ javaClass
"Created: / 15.4.1996 / 14:58:53 / cg"
"Modified: / 9.5.1998 / 01:44:24 / cg"
!
readStream:aStream
"reads a class from aStream and returns it.
The JavaClass is installed as global.
If new classes are required to be loaded, a new standard loader
is created."
^ self readStream:aStream loader:nil
"Modified: 14.8.1997 / 19:51:50 / cg"
!
readStream:aStream ignoring:classesBeingLoaded
"reads a class from aStream and returns it.
The JavaClass is not installed as global"
|javaClass|
javaClass := self new readStream:aStream ignoring:classesBeingLoaded.
AbsolutelySilent ifFalse:[
' ... loaded ' print. javaClass displayString printNL.
].
^ javaClass
"Modified: / 30.3.1998 / 18:14:40 / cg"
!
readStream:aStream loader:aClassLoader
"reads a class from aStream and returns it.
The JavaClass is installed as global.
If new classes are required to be loaded, aClassLoader is
asked to do it. If aClassLoader is nil, a new standard loader
is created."
^ self
readStream:aStream
loader:aClassLoader
loadUnresolved:true
"Modified: 15.8.1997 / 01:00:35 / cg"
!
readStream:aStream loader:aClassLoader loadUnresolved:loadUnresolved
"reads a class from aStream and returns it.
The JavaClass is installed as global.
If new classes are required to be loaded, aClassLoader is
asked to do it. If aClassLoader is nil, a new standard loader
is created."
|javaClass|
ClassLoaderQuerySignal answer:aClassLoader
do:[
javaClass := self readStream:aStream ignoring:(Set new).
javaClass notNil ifTrue:[
self postLoadActions:loadUnresolved.
Java at:(javaClass fullName asSymbol) put:javaClass.
JavaUnresolvedConstant resolveFor:javaClass.
].
].
^ javaClass
"Created: / 15.8.1997 / 00:59:24 / cg"
"Modified: / 23.1.1998 / 17:14:09 / cg"
!
resolveClass:aJavaClass
"Resolve a particular classes' constants.
Perform all class initialization functions
(of those which are not yet initialized)."
|loader classToLoad|
LazyClassLoading ifFalse:[
loader := (aJavaClass classLoader). "/ ? (ClassLoaderQuerySignal raise).
[
classToLoad := nil.
aJavaClass constantPool do:[:item |
|itemClass |
itemClass := item class.
itemClass == JavaUnresolvedClassConstant ifTrue:[
classToLoad := item className.
"/ ] ifFalse:[
"/ itemClass == JavaUnresolvedMethodrefConstant ifTrue:[
"/self halt.
"/ ] ifFalse:[
"/ itemClass == JavaUnresolvedInterfaceMethodrefConstant ifTrue:[
"/self halt.
"/ ]
"/ ]
].
].
classToLoad notNil ifTrue:[
loader isNil ifTrue:[
self
loadClassLazy:classToLoad
ignoring:(Set new).
] ifFalse:[
"/
"/ the aquired loader is a javaClassLoader
"/ which expects an URL as arg.
"/
"/ classURL := Java as_URL:('file:' , nextUnresolved asString , '.class').
"/ loader loadClass:classURL
loader
perform:#'loadClass(Ljava/lang/String;)Ljava/lang/Class;'
with:(Java as_String:(classToLoad asString)).
]
].
classToLoad notNil.
] whileTrue.
aJavaClass isInitialized ifFalse:[
Silent ifFalse:[
'performing class initialization of ' print. aJavaClass fullName printCR.
].
aJavaClass classInit
].
]
"Created: / 20.10.1998 / 17:53:22 / cg"
"Modified: / 20.10.1998 / 17:59:09 / 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
jSuperClass loader superClassName thisClassName existing_class
thisMetaClass|
"/
"/ read magic, determine byte order
"/
msb := true.
magic := inStream nextUnsignedLongMSB:true.
magic = (self class magic_MSB) ifFalse:[
magic = (self class magic_LSB) ifFalse:[
InvalidClassFormatSignal raiseErrorString:'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 ~~ (self class fileMajorVersion)
or:[minorVsn ~~ (self class fileMinorVersion)]) 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.
superClassName := super_class fullName.
"/ special for ST-classes
(superClassName startsWith:'smalltalk.') ifTrue:[
"/ a Smalltalk class
superClassName := superClassName copyFrom:11.
existingSuperClass := Smalltalk at:superClassName asSymbol.
existingSuperClass notNil ifTrue:[
super_class := existingSuperClass
] ifFalse:[
"/ self halt - must load superclass ...
]
] ifFalse:[
"/ a JAVA class
existingSuperClass := Java classNamed:superClassName.
existingSuperClass notNil ifTrue:[
super_class := existingSuperClass
] ifFalse:[
(super_class isMemberOf:JavaUnresolvedClassConstant) ifTrue:[
Silent ifFalse:[
'load superClass: ' print. superClassName printCR.
].
loader := ClassLoaderQuerySignal raise.
loader isNil ifTrue:[
existingSuperClass := self class
loadClassLazy:superClassName
ignoring:classesbeingLoaded.
] ifFalse:[
jSuperClass := loader
perform:#'loadClass(Ljava/lang/String;)Ljava/lang/Class;'
with:(Java as_String:superClassName).
existingSuperClass := JavaVM classForJavaClassObject:jSuperClass.
].
existingSuperClass isNil ifTrue:[
self halt:('cannot find superclass: ' , superClassName).
].
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.
thisClassName := this_class_ref fullName.
"/ care for smalltalk classes ...
(thisClassName startsWith:'smalltalk.') ifTrue:[
thisClassName := thisClassName copyFrom:11.
existing_class := Smalltalk at:thisClassName asSymbol.
existing_class notNil ifTrue:[
self halt:('overloading existing class: ', thisClassName).
thisClassName := (thisClassName , '_new') asSymbol.
].
thisMetaClass := Metaclass new.
thisMetaClass setSuperclass:super_class class.
thisMetaClass instSize:(super_class class instSize + nStatic).
this_class := thisMetaClass new.
this_class setSuperclass:super_class.
this_class setName:thisClassName asSymbol.
] ifFalse:[
"/ a java class
this_class := JavaClass fullName:thisClassName numStatic:nStatic.
nStatic ~~ 0 ifTrue:[
fields := fields select:[:f | f isStatic not].
JavaClass setInstanceVariableStringFromFields:staticFields in:this_class class.
this_class setStaticFields:staticFields.
this_class initializeStaticFields.
].
this_class setAccessFlags:access_flags.
this_class setSuperclass:super_class.
this_class setConstantPool:constants.
this_class setFields:fields.
this_class setInterfaces:interfaces.
constants owner:this_class.
].
"/
"/ get methods
"/
self readMethodsFor:this_class.
self readAttributesFor:this_class.
^ this_class
"
JavaClassReader loadFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader loadFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
JavaClassReader loadFile:'foo.cls'
JavaClassReader verbose:true.
JavaClassReader loadFile:'/phys/ibm3/hotjava/classes/java/lang/ArithmeticException.class'
JavaClassReader loadFile:'/phys/ibm3/java/lib/java/lang/ArithmeticException.class'
"
"Created: / 15.4.1996 / 15:02:47 / cg"
"Modified: / 13.5.1998 / 14:35:20 / 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
"/ implemented ST attributes
(attributeName = 'STLiterals') ifTrue:[
self readSTLiteralsAttributeFor:something.
^ self.
].
(attributeName = 'ClassRevision') ifTrue:[
self readSTClassRevisionAttributeFor:something.
^ self.
].
(attributeName = 'ClassPackage') ifTrue:[
self readSTClassPackageAttributeFor:something.
^ self.
].
(attributeName = 'ClassCategory') ifTrue:[
self readSTClassCategoryAttributeFor:something.
^ self.
].
(attributeName = 'ClassVarNames') ifTrue:[
self readSTClassVarNamesAttributeFor:something.
^ self.
].
(attributeName = 'ClassInstVarNames') ifTrue:[
self readSTClassInstVarNamesAttributeFor:something.
^ self.
].
(attributeName = 'InstVarNames') ifTrue:[
self readSTInstVarNamesAttributeFor:something.
^ self.
].
(attributeName = 'STCode') ifTrue:[
self readSTCodeAttributeFor:something.
^ self.
].
(attributeName = 'MethodCategory') ifTrue:[
self readSTMethodCategoryAttributeFor:something.
^ self.
].
"/ implemented JAVA attributes
(attributeName = 'Code') ifTrue:[
self readCodeAttributeFor:something.
^ self.
].
(attributeName = 'Exceptions') ifTrue:[
self readExceptionsAttributeFor:something.
^ self.
].
(attributeName = 'LineNumberTable') ifTrue:[
self readLineNumberTableAttributeFor:something.
^ self.
].
(attributeName = 'LocalVariableTable') ifTrue:[
self readLocalVariableTableAttributeFor:something.
^ self.
].
(attributeName = 'ConstantValue') ifTrue:[
self readConstantValueAttributeFor:something.
^ self.
].
(attributeName = 'SourceFile') ifTrue:[
self readSourceFileAttributeFor:something.
^ self.
].
"/ ignored JAVA attributes
(attributeName = 'Deprecated') ifTrue:[
"/ ('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
self skipAttribute:attributeName.
^ self.
].
(attributeName = 'AbsoluteSourcePath') ifTrue:[
('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
self skipAttribute:attributeName.
^ self.
].
(attributeName = 'Synthetic') ifTrue:[
('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
self skipAttribute:attributeName.
^ self.
].
(attributeName = 'InnerClasses') ifTrue:[
('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
self skipAttribute:attributeName.
^ self.
].
(attributeName startsWith:((Character value:13) asString , 'WARNING:')) ifTrue:[
"/ ('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
self skipAttribute:attributeName.
^ self.
].
"/ unknown attributes
('JAVA [warning]: unrecognized attribute: ' , attributeName) infoPrintCR.
self skipAttribute:attributeName.
"Modified: / 16.10.1998 / 12:51:59 / 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.
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: / 15.4.1996 / 15:40:17 / cg"
"Modified: / 9.4.1998 / 18:13:34 / 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"
!
readSourceFileAttributeFor:aClass
|attribute_length sourceFile_index sourceFile|
attribute_length := inStream nextUnsignedLongMSB:msb.
sourceFile_index := inStream nextUnsignedShortMSB:msb.
sourceFile := constants at:sourceFile_index.
aClass isJavaClass ifTrue:[
aClass setSourceFile:sourceFile.
] ifFalse:[
aClass setClassFilename:sourceFile
].
Verbose ifTrue:[Transcript show:'sourceFile: '; showCR:sourceFile].
^ true
"
JavaClassReader loadFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
JavaClassReader loadFile:'/phys/ibm3/hotjava/classes/browser/Alignable.class'
JavaClassReader loadFile:'foo.cls'
"
"Created: / 15.4.1996 / 15:40:17 / cg"
"Modified: / 12.5.1998 / 22:01:07 / cg"
!
skipAttribute:attributeName
"dont know about this attribute - skip it here"
|attribute_length attribute_info|
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:attributeName; showCR:'-attribute'].
"Created: / 9.4.1998 / 18:12:46 / cg"
"Modified: / 9.4.1998 / 18:13:20 / cg"
! !
!JavaClassReader methodsFor:'file reading - attributes-ST'!
readSTClassCategoryAttributeFor:aClass
|attribute_length categoryString_index categoryString|
attribute_length := inStream nextUnsignedLongMSB:msb.
categoryString_index := inStream nextUnsignedShortMSB:msb.
categoryString := constants at:categoryString_index.
aClass category:categoryString.
Verbose ifTrue:[Transcript show:'categoryString: '; showCR:categoryString].
^ true
"
JavaClassReader loadFile:'foo.cls'
"
"Created: / 9.5.1998 / 02:33:13 / cg"
"Modified: / 9.5.1998 / 02:36:55 / cg"
!
readSTClassInstVarNamesAttributeFor:aClass
|attribute_length nameString_index nameString|
attribute_length := inStream nextUnsignedLongMSB:msb.
nameString_index := inStream nextUnsignedShortMSB:msb.
nameString := constants at:nameString_index.
aClass class instanceVariableString:nameString.
Verbose ifTrue:[Transcript show:'nameString: '; showCR:nameString].
^ true
"
JavaClassReader loadFile:'foo.cls'
"
"Modified: / 12.5.1998 / 22:18:03 / cg"
"Created: / 12.5.1998 / 22:18:24 / cg"
!
readSTClassPackageAttributeFor:aClass
|attribute_length packageString_index packageString|
attribute_length := inStream nextUnsignedLongMSB:msb.
packageString_index := inStream nextUnsignedShortMSB:msb.
packageString := constants at:packageString_index.
aClass package:packageString asSymbol.
Verbose ifTrue:[Transcript show:'packageString: '; showCR:packageString].
^ true
"
JavaClassReader loadFile:'foo.cls'
"
"Modified: / 9.5.1998 / 02:32:38 / cg"
"Created: / 9.5.1998 / 02:33:44 / cg"
!
readSTClassRevisionAttributeFor:aClass
|attribute_length revisionString_index revisionString|
attribute_length := inStream nextUnsignedLongMSB:msb.
revisionString_index := inStream nextUnsignedShortMSB:msb.
revisionString := constants at:revisionString_index.
aClass setBinaryRevision:revisionString.
Verbose ifTrue:[Transcript show:'revisionString: '; showCR:revisionString].
^ true
"
JavaClassReader loadFile:'foo.cls'
"
"Created: / 9.5.1998 / 02:33:13 / cg"
"Modified: / 9.5.1998 / 02:35:01 / cg"
!
readSTClassVarNamesAttributeFor:aClass
|attribute_length nameString_index nameString|
attribute_length := inStream nextUnsignedLongMSB:msb.
nameString_index := inStream nextUnsignedShortMSB:msb.
nameString := constants at:nameString_index.
aClass classVariableString:nameString.
Verbose ifTrue:[Transcript show:'nameString: '; showCR:nameString].
^ true
"
JavaClassReader loadFile:'foo.cls'
"
"Created: / 9.5.1998 / 02:33:13 / cg"
"Modified: / 12.5.1998 / 22:18:03 / cg"
!
readSTInstVarNamesAttributeFor:aClass
|attribute_length nameString_index nameString|
attribute_length := inStream nextUnsignedLongMSB:msb.
nameString_index := inStream nextUnsignedShortMSB:msb.
nameString := constants at:nameString_index.
aClass setInstanceVariableString:nameString.
Verbose ifTrue:[Transcript show:'nameString: '; showCR:nameString].
^ true
"
JavaClassReader loadFile:'foo.cls'
"
"Created: / 12.5.1998 / 22:18:14 / cg"
"Modified: / 12.5.1998 / 22:21:10 / cg"
! !
!JavaClassReader methodsFor:'file reading - constants'!
readConstant
|tag constReader const|
constNeeds2Slots := false.
"/
"/ get tag
"/
tag := inStream nextByte.
Verbose ifTrue:[Transcript show:'tag = '; showCR:tag].
tag >= 250 ifTrue:[
constReader := #(
"/ ST types
readConstant_ST_Large "/ 249
readConstant_ST_Special "/ 250
readConstant_ST_Character "/ 251
readConstant_ST_ByteArray "/ 252
readConstant_ST_Array "/ 253
readConstant_ST_Symbol "/ 254
readConstant_ST_Reserved "/ 255
) at:tag-249+1.
] ifFalse:[
constReader := #(
"/ JAVA types
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: / 9.5.1998 / 01:26:05 / 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.
"/ long & double consts take 2 slots
"/ (only first is used)
constNeeds2Slots ifTrue:[
constSlot := constSlot + 2.
] ifFalse:[
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: / 7.5.1998 / 11:44:06 / 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:[
Verbose ifTrue:[Transcript showCR:'name in constant_class already resolved'].
"/ 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: / 8.5.1998 / 21:53:16 / cg"
!
readConstant_Double
|high low aFloat bytes|
"/ new code - to be tested
"/ bytes := ByteArray new:8.
"/
"/ inStream nextBytes:8 into:bytes startingAt:1.
"/ msb ~~ UninterpretedBytes isBigEndian ifTrue:[
"/ bytes reverse
"/ ].
"/ aFloat := bytes doubleAt:1.
"/ old code
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'
"
"Created: / 15.4.1996 / 16:34:42 / cg"
"Modified: / 8.5.1998 / 22:06:07 / 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
|b1 b2 b3 b4 aFloat bytes|
"/ new code - to be tested ...
"/
"/ bytes := ByteArray new:4.
"/ inStream nextBytes:4 into:bytes startingAt:1.
"/ msb ~~ UninterpretedBytes isBigEndian ifTrue:[
"/ bytes reverse
"/ ].
"/ aFloat := bytes floatAt:1.
"/ Verbose ifTrue:[Transcript show:'float; value= '; showCR:aFloat].
"/ ^ aFloat.
"/ old code
aFloat := ShortFloat basicNew.
b1 := inStream nextByte.
b2 := inStream nextByte.
b3 := inStream nextByte.
b4 := inStream nextByte.
UninterpretedBytes isBigEndian ifTrue:[
aFloat basicAt:1 put:b1.
aFloat basicAt:2 put:b2.
aFloat basicAt:3 put:b3.
aFloat basicAt:4 put:b4.
] ifFalse:[
aFloat basicAt:4 put:b1.
aFloat basicAt:3 put:b2.
aFloat basicAt:2 put:b3.
aFloat basicAt:1 put:b4.
].
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'
"
"Created: / 15.4.1996 / 16:34:42 / cg"
"Modified: / 10.11.1998 / 22:04:59 / 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 chars jString|
string_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'string; index= '; showCR:string_index].
"/ resolve here if possible
string_index < constSlot ifTrue:[
Java java_lang_String notNil ifTrue:[
chars := (constants at:string_index).
chars isString ifFalse:[
self halt:'should not happen'
].
jString := Java as_String:chars.
^ jString.
]
].
^ 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: / 7.5.1998 / 11:42:45 / cg"
! !
!JavaClassReader methodsFor:'file reading - constants-ST'!
readConstant_ST_Array
|aSize arr|
aSize := inStream nextUnsignedShortMSB:msb.
arr := Array new:aSize.
1 to:aSize do:[:i |
|element_index element|
element_index := inStream nextUnsignedShortMSB:msb.
arr at:i put:element_index.
].
Verbose ifTrue:[Transcript show:'array; size= '; showCR:aSize].
^ JavaUnresolvedSTArrayConstant
pool:constants
poolIndex:constSlot
array:arr
"Created: / 7.5.1998 / 11:47:01 / cg"
"Modified: / 9.5.1998 / 00:25:34 / cg"
!
readConstant_ST_ByteArray
|aSize arr|
aSize := inStream nextUnsignedShortMSB:msb.
arr := ByteArray new:aSize.
1 to:aSize do:[:i |
|element_index|
arr at:i put:(inStream nextByte).
].
Verbose ifTrue:[Transcript show:'byteArray; size= '; showCR:aSize].
^ arr
"Created: / 7.5.1998 / 11:47:12 / cg"
!
readConstant_ST_Character
|ascii|
ascii := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'char; ascii= '; showCR:ascii].
^ Character value:ascii
"Created: / 7.5.1998 / 11:48:12 / cg"
!
readConstant_ST_Special
|type|
type := inStream nextUnsignedShortMSB:msb.
^ #(
nil
true
false
) at:(type + 1)
"Created: / 8.5.1998 / 23:06:56 / cg"
"Modified: / 9.5.1998 / 00:40:14 / cg"
!
readConstant_ST_String
|tag string_index chars|
string_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'string; index= '; showCR:string_index].
"/ resolve here if possible
string_index < constSlot ifTrue:[
chars := (constants at:string_index).
^ chars
].
^ JavaUnresolvedSTStringConstant
pool:constants
poolIndex:constSlot
stringIndex:string_index
"Modified: / 7.5.1998 / 11:48:28 / cg"
"Created: / 7.5.1998 / 11:49:55 / cg"
!
readConstant_ST_Symbol
|tag string_index chars|
string_index := inStream nextUnsignedShortMSB:msb.
Verbose ifTrue:[Transcript show:'symbol; index= '; showCR:string_index].
"/ resolve here if possible
string_index < constSlot ifTrue:[
chars := (constants at:string_index).
chars isString ifFalse:[
self halt:'should not happen'
].
^ chars asSymbol
].
^ JavaUnresolvedSTSymbolConstant
pool:constants
poolIndex:constSlot
stringIndex:string_index
"Modified: / 7.5.1998 / 11:48:28 / 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) asSymbol.
field setSignature:(constants at:signature_index) asSymbol.
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'
"
"Created: / 15.4.1996 / 15:38:43 / cg"
"Modified: / 15.10.1998 / 10:38:01 / 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:'code_attribute_length: 0x'; showCR:(attribute_length printStringRadix:16)].
minorVsn > 2 ifTrue:[
"/ should be:
max_stack := inStream nextUnsignedShortMSB:msb.
max_locals := inStream nextUnsignedShortMSB:msb.
code_length := inStream nextUnsignedLongMSB:msb.
"/ unknown1 := inStream nextByte.
"/ max_stack := inStream nextByte.
"/ max_locals := inStream nextUnsignedShortMSB:msb.
"/ unknown2 := inStream nextUnsignedShortMSB:msb.
"/ code_length := 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).
Transcript show:'code at pos: '; showCR:inStream position
].
code_length ~~ 0 ifTrue:[
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'
"
"Created: / 15.4.1996 / 15:40:17 / cg"
"Modified: / 16.5.1998 / 01:39:42 / 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'
"
"Created: / 15.4.1996 / 15:40:17 / cg"
"Modified: / 7.4.1998 / 19:08:42 / 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:aClass
|m access_flags name_index name signature_index signature
tooManyArgs|
"/
"/ 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.
].
aClass isJavaClass ifTrue:[
m := JavaMethodWithHandler new.
m setAccessFlags:access_flags.
tooManyArgs := false.
Method argumentSignal handle:[:ex |
'JAVA: ***** java method has too many arguments - will fail to execute' infoPrintCR.
tooManyArgs := true.
ex proceed.
] do:[
m setName:name signature:signature.
].
m setJavaClass:aClass.
self readAttributesFor:m.
tooManyArgs ifTrue:[
m code:nil.
m byteCode:nil.
].
(m exceptionHandlerTable isNil) ifTrue:[
m exceptionTable isNil ifTrue:[
m := JavaMethod fromMethod:m
] ifFalse:[
m := JavaMethodWithException fromMethod:m
]
].
aClass addMethod:m name:name signature:signature.
] ifFalse:[
m := Method new.
self readAttributesFor:m.
(access_flags bitTest:JavaMethod A_STATIC) ifTrue:[
aClass class primAddSelector:name asSymbol withMethod:m.
] ifFalse:[
aClass primAddSelector:name asSymbol withMethod:m.
]
].
"
JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
"
"Created: / 15.4.1996 / 16:48:49 / cg"
"Modified: / 5.11.1998 / 20:01:43 / 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'
"
"Created: / 15.4.1996 / 16:46:30 / cg"
"Modified: / 8.5.1998 / 21:20:59 / cg"
! !
!JavaClassReader methodsFor:'file reading - methods-ST'!
readSTCodeAttributeFor:aSmalltalkMethod
|attribute_length max_stack max_locals code_length code
exception_table_length unknown1 unknown2|
attribute_length := inStream nextUnsignedLongMSB:msb.
Verbose ifTrue:[Transcript show:'attribute_length: 0x'; showCR:(attribute_length printStringRadix:16)].
max_stack := inStream nextUnsignedShortMSB:msb.
max_locals := inStream nextUnsignedShortMSB:msb.
code_length := inStream nextUnsignedLongMSB:msb.
Verbose ifTrue:[Transcript show:'code_length: '; showCR:(code_length printStringRadix:16)].
Verbose ifTrue:[Transcript show:'code at pos: '; showCR:inStream position].
code_length ~~ 0 ifTrue:[
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:[
self error:'unexpected exceptionTable length'.
"/ skip it.
1 to:exception_table_length do:[:i |
"start_pc :=" inStream nextUnsignedShortMSB:msb.
"end_pc :=" inStream nextUnsignedShortMSB:msb.
"handler_pc :=" inStream nextUnsignedShortMSB:msb.
"catch_type :=" inStream nextUnsignedShortMSB:msb.
].
].
aSmalltalkMethod byteCode:code.
aSmalltalkMethod stackSize:max_stack .
aSmalltalkMethod numberOfVars:max_locals.
self readAttributesFor:aSmalltalkMethod.
^ true
"Modified: / 16.5.1998 / 01:39:30 / cg"
!
readSTLiteralsAttributeFor:aSmalltalkMethod
|attribute_length literal_table_length literal_table litIndex literal|
attribute_length := inStream nextUnsignedLongMSB:msb.
literal_table_length := inStream nextUnsignedShortMSB:msb.
literal_table_length ~~ 0 ifTrue:[
literal_table := Array new:literal_table_length.
1 to:literal_table_length do:[:i |
litIndex := inStream nextUnsignedShortMSB:msb.
literal := (constants at:litIndex).
literal_table at:i put:literal.
].
].
Verbose ifTrue:[Transcript show:'literals: '; showCR:literal_table storeString.].
"Created: / 7.5.1998 / 11:52:28 / cg"
"Modified: / 16.5.1998 / 01:52:27 / cg"
!
readSTMethodCategoryAttributeFor:aSmalltalkMethod
|attribute_length name_index name|
attribute_length := inStream nextUnsignedLongMSB:msb.
name_index := inStream nextUnsignedShortMSB:msb.
name := (constants at:name_index).
aSmalltalkMethod category:name.
"Modified: / 8.5.1998 / 20:39:59 / cg"
"Created: / 16.5.1998 / 01:04:19 / cg"
! !
!JavaClassReader class methodsFor:'documentation'!
version
^ '$Header: /home/jv/Projects/SmalltalkX/repositories/cvs/stx/libjava/JavaClassReader.st,v 1.77 1998/11/11 15:02:49 cg Exp $'
! !
JavaClassReader initialize!