proper unregistration, when a classLib fails to load
authorClaus Gittinger <cg@exept.de>
Thu, 16 Sep 1999 20:28:44 +0200
changeset 966 0da15d671aef
parent 965 5f893e013e73
child 967 160ab002eed1
proper unregistration, when a classLib fails to load due to a missing superclass.
ObjectFileLoader.st
--- a/ObjectFileLoader.st	Thu Sep 16 20:27:32 1999 +0200
+++ b/ObjectFileLoader.st	Thu Sep 16 20:28:44 1999 +0200
@@ -840,13 +840,13 @@
 
     handle := self loadDynamicObject:aFileName.
     handle isNil ifTrue:[
-	Transcript showCR:('failed to load: ' , aFileName).
-	('ObjectFileLoader [warning]: '
-	 , aFileName
-	 , ' failed. ('
-	 , LinkErrorMessage
-	 , ')') errorPrintCR.
-	^ nil
+        Transcript showCR:('failed to load: ' , aFileName).
+        ('ObjectFileLoader [warning]: '
+         , aFileName
+         , ' failed. ('
+         , LinkErrorMessage
+         , ')') errorPrintCR.
+        ^ nil
     ].
 
     "
@@ -855,9 +855,9 @@
     symName := '_' , aClassName , '_Init'.
     initAddr := self getFunction:symName from:handle.
     initAddr isNil ifTrue:[
-	"try with added underscore"
-	symName := '__' , aClassName , '_Init'.
-	initAddr := self getFunction:symName from:handle.
+        "try with added underscore"
+        symName := '__' , aClassName , '_Init'.
+        initAddr := self getFunction:symName from:handle.
     ].
 
     knownToBeOk := true.
@@ -891,89 +891,92 @@
 "/    ].
 
     initAddr notNil ifTrue:[
-	Verbose ifTrue:[
-	    ('calling init at: ' , (initAddr printStringRadix:16)) infoPrintCR.
-	].
-	info := self performModuleInitAt:initAddr for:aClassName identifyAs:handle.
-	status := info at:1.
-	"
-	 if any classes are missing ...
-	"
-	(status == #missingClass) ifTrue:[
-	    "
-	     ... and we are loading a module ...
-	    "
-	    Transcript showCR:'try for missing class in same object ...'.
-	    Verbose ifTrue:[
-		'try for missing class:' infoPrint. (info at:2) infoPrintCR.
-	    ].
-	    otherClass := self loadClass:(info at:2) fromObjectFile:aFileName.
-	    otherClass notNil ifTrue:[
-		"
-		 try again ...
-		"
-		Transcript showCR:'missing class is here; try again ...'.
-		info := self performModuleInitAt:initAddr for:aClassName identifyAs:handle.
-		status := info at:1.
-	    ]
-	].
-
-	Verbose ifTrue:[
-	    'done init status=' infoPrint. info infoPrintCR.
-	].
-	(status == #unregisteredSuperclass) ifTrue:[
-	    Transcript showCR:'superclass is not registered'.
-	].
-
-	(Symbol hasInterned:aClassName) ifTrue:[
-	    newClass := Smalltalk at:aClassName asSymbol ifAbsent:[nil].
-	    Verbose ifTrue:[
-		'newClass is: ' infoPrint. newClass infoPrintCR
-	    ].
-	    newClass notNil ifTrue:[
-		Verbose ifTrue:[
-		    'initialize newClass ...' infoPrintCR
-		].
-		newClass initialize.
-		"force cache flush"
-		Smalltalk at:aClassName asSymbol put:newClass.
-		Smalltalk isInitialized ifTrue:[
-		    Smalltalk changed.
-		]
-	    ].
-	] ifFalse:[
-	    'ObjectFileLoader [warning]: class ' errorPrint. aClassName errorPrint.
-	    ' did not define itself' errorPrintCR
-	    "
-	     do not unload - could have installed other classes/methods ...
-	    "
-	].
-	Smalltalk flushCachedClasses.
-	^ newClass
+        Verbose ifTrue:[
+            ('calling init at: ' , (initAddr printStringRadix:16)) infoPrintCR.
+        ].
+        info := self performModuleInitAt:initAddr for:aClassName identifyAs:handle.
+        status := info at:1.
+        "
+         if any classes are missing ...
+        "
+        (status == #missingClass) ifTrue:[
+            "
+             ... and we are loading a module ...
+            "
+            Transcript showCR:'try for missing class in same object ...'.
+            Verbose ifTrue:[
+                'try for missing class:' infoPrint. (info at:2) infoPrintCR.
+            ].
+            otherClass := self loadClass:(info at:2) fromObjectFile:aFileName.
+            otherClass notNil ifTrue:[
+                "
+                 try again ...
+                "
+                Transcript showCR:'missing class is here; try again ...'.
+                info := self performModuleInitAt:initAddr for:aClassName identifyAs:handle.
+                status := info at:1.
+            ]
+        ].
+
+        Verbose ifTrue:[
+            'done init status=' infoPrint. info infoPrintCR.
+        ].
+        (status == #unregisteredSuperclass) ifTrue:[
+            Transcript showCR:'superclass is not registered'.
+        ].
+
+        (Symbol hasInterned:aClassName) ifTrue:[
+            newClass := Smalltalk at:aClassName asSymbol ifAbsent:[nil].
+            Verbose ifTrue:[
+                'newClass is: ' infoPrint. newClass infoPrintCR
+            ].
+            newClass notNil ifTrue:[
+                Smalltalk at:aClassName asSymbol put:newClass.
+
+                (newClass implements:#initialize) ifTrue:[
+                    Verbose ifTrue:[
+                        'initialize newClass ...' infoPrintCR
+                    ].
+                    newClass initialize.
+                ].
+                "force cache flush"
+                Smalltalk isInitialized ifTrue:[
+                    Smalltalk changed.
+                ]
+            ].
+        ] ifFalse:[
+            'ObjectFileLoader [warning]: class ' errorPrint. aClassName errorPrint.
+            ' did not define itself' errorPrintCR
+            "
+             do not unload - could have installed other classes/methods ...
+            "
+        ].
+        Smalltalk flushCachedClasses.
+        ^ newClass
     ].
 
     Verbose ifTrue:[
-	('no symbol: ', symName,' in ',aFileName) infoPrintCR.
+        ('no symbol: ', symName,' in ',aFileName) infoPrintCR.
     ].
 
     "
      unload
     "
     Verbose ifTrue:[
-	'unloading due to init failure:' infoPrint. handle pathName infoPrintCR.
+        'unloading due to init failure:' infoPrint. handle pathName infoPrintCR.
     ].
 
     moreHandles notNil ifTrue:[
-	moreHandles do:[:aHandle |
-	    Verbose ifTrue:[
-		('unloading: ', aHandle printString) infoPrintCR.
-	    ].
-	    self unloadDynamicObject:handle.
-	]
+        moreHandles do:[:aHandle |
+            Verbose ifTrue:[
+                ('unloading: ', aHandle printString) infoPrintCR.
+            ].
+            self unloadDynamicObject:handle.
+        ]
     ].
 
     Verbose ifTrue:[
-	('unloading: ', handle printString) infoPrintCR.
+        ('unloading: ', handle printString) infoPrintCR.
     ].
     self unloadDynamicObject:handle.
     ^ nil
@@ -1274,22 +1277,31 @@
                 Transcript showCR:'LOADER: incompatible object (recompile without commonSymbols ?)'
             ].
             status ~~ #initFailed ifTrue:[
-                self listUndefinedSymbolsIn:handle.
+                status ~~ #missingClass ifTrue:[
+                    self listUndefinedSymbolsIn:handle.
+                ]
             ].
 
             Verbose ifTrue:[
                 'unloading, since init failed ...' infoPrintCR.
             ].
             self unloadDynamicObject:handle.
+            Verbose ifTrue:[
+                'unloaded.' infoPrintCR.
+            ].
             handle := nil.
 
             status == #initFailed ifTrue:[
                 msg := 'LOADER: module not loaded (init function signalled failure).'
             ] ifFalse:[
-                (self namesMatching:'*__sepInitCode__*' segment:'[tT?]' in:aFileName) notNil ifTrue:[
-                    msg := 'LOADER: module not loaded (no _Init entry - looks like an incomplete sepInitCode object).'
+                status == #missingClass ifTrue:[
+                    msg := 'LOADER: module not loaded (superclass missing: ' , (info at:2) , ').'
                 ] ifFalse:[
-                    msg := 'LOADER: module not loaded (no _Init entry in object file ?).'
+                    (self namesMatching:'*__sepInitCode__*' segment:'[tT?]' in:aFileName) notNil ifTrue:[
+                        msg := 'LOADER: module not loaded (no _Init entry - looks like an incomplete sepInitCode object).'
+                    ] ifFalse:[
+                        msg := 'LOADER: module not loaded (no _Init entry in object file ?).'
+                    ].
                 ].
             ].
         ].
@@ -1345,7 +1357,7 @@
 	handle := LoadedObjects at:aFileName ifAbsent:nil
     ].
     handle isNil ifTrue:[
-	'OBJFLOADER: oops file to be unloaded was not loaded dynamically (', aFileName , ')'.
+	('OBJFLOADER: oops file to be unloaded was not loaded dynamically (', aFileName , ')') infoPrintCR.
 	^ self
     ].
 
@@ -1370,7 +1382,7 @@
         handle := LoadedObjects at:aFileName ifAbsent:nil
     ].
     handle isNil ifTrue:[
-        'OBJFLOADER: oops file to be unloaded was not loaded dynamically (', (aFileName ? 'unknown-file') , ')'.
+        ('OBJFLOADER: oops file to be unloaded was not loaded dynamically (', (aFileName ? 'unknown-file') , ')') infoPrintCR.
         ^ self
     ].
     handle isClassLibHandle ifFalse:[
@@ -3383,42 +3395,68 @@
         'unload module name=' infoPrint. handle pathName infoPrintCR.
     ].
 
-    "/
-    "/ fixup 
-    "/
-
-    handle isFunctionObjectHandle ifTrue:[
-        handle functions do:[:f |
-                                f notNil ifTrue:[
-                                    f code:0
-                                ]
-                            ].
-    ].
-
-    handle isClassLibHandle ifTrue:[
-        self deinitializeClassesFromModule:handle.
+    handle isUnknownHandle ifTrue:[
+	Verbose ifTrue:[
+	    'module type is not known - assume uninitialized classLib'
+	].
         self unregisterModule:handle.
-    ] ifFalse:[    
-        handle isMethodHandle ifTrue:[
+	handle makeClassLibHandle.
+    ] ifFalse:[
+        handle isClassLibHandle ifTrue:[
+            Verbose ifTrue:[
+                'a classLib - deinit classes' infoPrintCR.
+            ].
+            self deinitializeClassesFromModule:handle.
+            Verbose ifTrue:[
+                'unregister' infoPrintCR.
+            ].
             self unregisterModule:handle.
-        ] ifFalse:[
-            "/
-            "/ call its deInit function (if present)
-            "/
-            fileName := handle pathName asFilename baseName.
-            functionName := self initFunctionBasenameForFile:fileName.
-
-            deInitAddr := self findFunction:functionName suffix:'__deInit' in:handle.
-            deInitAddr notNil ifTrue:[
-                self callInitFunctionAt:deInitAddr 
-                     specialInit:false 
-                     forceOld:true 
-                     interruptable:false
-                     argument:0
-                     identifyAs:handle
-                     returnsObject:false.
+        ] ifFalse:[    
+            handle isMethodHandle ifTrue:[
+                Verbose ifTrue:[
+                    'a methodHandle - unregister' infoPrintCR.
+                ].
+                self unregisterModule:handle.
+            ] ifFalse:[
+                handle isFunctionObjectHandle ifTrue:[
+                    Verbose ifTrue:[
+                        'a functionObject - fixup functionRefs' infoPrintCR.
+                    ].
+                    handle functions do:[:f |
+                                    f notNil ifTrue:[
+                                        f code:0
+                                    ]
+                                ].
+                ].
+
+                "/
+                "/ call its deInit function (if present)
+                "/
+                Verbose ifTrue:[
+                    'search for deInit function...' infoPrintCR.
+                ].
+                fileName := handle pathName asFilename baseName.
+                functionName := self initFunctionBasenameForFile:fileName.
+    
+                deInitAddr := self findFunction:functionName suffix:'__deInit' in:handle.
+                deInitAddr notNil ifTrue:[
+                    Verbose ifTrue:[
+                        'invoke deInit function...' infoPrintCR.
+                    ].
+                    self callInitFunctionAt:deInitAddr 
+                         specialInit:false 
+                         forceOld:true 
+                         interruptable:false
+                         argument:0
+                         identifyAs:handle
+                         returnsObject:false.
+                ]
             ]
-        ]
+        ].
+    ].
+
+    Verbose ifTrue:[
+        'cleanup done - now unload...' infoPrintCR.
     ].
 
     "/
@@ -3428,6 +3466,10 @@
         ^ self error:'unloadDynamic failed' mayProceed:true
     ].
 
+    Verbose ifTrue:[
+        'unload done ...' infoPrintCR.
+    ].
+
     "/
     "/ remove from loaded objects
     "/
@@ -3960,6 +4002,6 @@
 !ObjectFileLoader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libcomp/ObjectFileLoader.st,v 1.206 1999-09-13 14:19:04 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libcomp/ObjectFileLoader.st,v 1.207 1999-09-16 18:28:44 cg Exp $'
 ! !
 ObjectFileLoader initialize!