"
COPYRIGHT (c) 1997 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
"{ Package: 'stx:libjava' }"
Object subclass:#JavaClassReader
instanceVariableNames:'inStream msb constants majorVsn minorVsn constNeeds2Slots
constSlot'
classVariableNames:'Verbose Silent AbsolutelySilent LazyClassLoading
InvalidClassFormatSignal ClassLoaderQuerySignal'
poolDictionaries:''
category:'Languages-Java-Support'
!
!JavaClassReader class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1997 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
! !
!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 query.
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|
Verbose == true ifTrue:[
Transcript showCR:'trying ' , path asFilename pathName, ' ...'.
].
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'.
Verbose == true ifTrue:[
Transcript showCR:'trying ' , nm, ' ...'.
].
nm asFilename exists ifTrue:[
(Java isExcludedFromClassPath:nm) ifFalse:[
rslt := self loadFileLazy:nm ignoring:loadedClass.
rslt notNil ifTrue:[^ rslt].
]
].
]
] ifFalse:[
Verbose == true ifTrue:[
Transcript showCR:'trying ' , (p asFilename withSuffix:'jar') pathName, ' ...'.
Transcript showCR:'and ' , (p asFilename withSuffix:'zip') pathName, ' ...'.
].
((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 query.
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. ' ...' printCR.
].
[
inStream := aFilename asFilename readStream.
] on:StreamError do:[:ex|
('JAVA [info]: no file: ' , aFilename asString) 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 query.
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:[
('JAVA: cannot find superclass: ' , superClassName) infoPrintCR.
"/ self halt:('cannot find superclass: ' , superClassName).
^ nil.
].
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: / 12.11.1998 / 21:14:45 / 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 = 'FastJavac1.0') 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: / 3.12.1998 / 13:13:42 / 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_Utf8 "/ 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"
!
readConstant_Unicode
|len string ascii|
len := inStream nextUnsignedShortMSB:msb.
string := TwoByteString new:len.
1 to:len do:[:idx |
ascii := inStream nextUnsignedShortMSB:msb.
string at:idx put:(Character value:ascii).
].
Verbose ifTrue:[Transcript show:'asciz; unicodeString= '; showCR:string].
^ string
!
readConstant_Utf8
|len bytes string|
len := inStream nextUnsignedShortMSB:msb.
bytes := ByteArray new:len.
inStream nextBytes:len into:bytes startingAt:1.
string := CharacterArray fromUTF8Bytes:bytes.
Verbose ifTrue:[Transcript show:'asciz; string= '; showCR:string].
^ string
! !
!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 := inStream nextUnsignedShortMSB:msb.
catch_type ~= 0 ifTrue:[
catch_type := constants at:catch_type.
].
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:[
(access_flags bitAnd:JavaMethod A_NATIVE) ~~ 0 ifTrue:[
m := JavaNativeMethod new.
] ifFalse:[
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 isNative ifFalse:[
m exceptionTable isNil ifTrue:[
m := JavaMethod fromMethod:m
] ifFalse:[
m := JavaMethodWithException fromMethod:m
]
]
] ifFalse:[
m setAccessFlags:(m accessFlags bitOr:JavaMethod A_HASHANDLER)
].
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: / 25.9.1999 / 23:16:25 / 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: /cvs/stx/stx/libjava/JavaClassReader.st,v 1.90 2004-02-06 17:58:26 stefan Exp $'
! !
JavaClassReader initialize!