'From Squeak3.3alpha of 24 January 2002 [latest update: #4862] on 11 May 2002 at 8:11:49 pm'! "Change Set: VMMaker32-7part2 Date: 7 May 2002 Author: tim@sumeru.stanford.edu Part 2 of 2 of the latest VMMaker; it has to be in two parts because of two bugs relating to fileouts. Filein part 1 first, then part 2. Do not filein part 2 and then part 1. Nor should you file part three, since part three does not exist. Latest phase of a decent VM source code builder, this version being intended for a 3.2 image of approx update level 4811. This version is a first merge of the version6 changeset with Andreas' variations to support his favoured code layout for Windows. The platforms file tree you need can be downloaded via cvs from squeak.Sourceforge.net. See the VMMaker & VMMakerTool class commnets for details"! TestInterpreterPlugin subclass: #AsynchFilePlugin instanceVariableNames: 'sCOAFfn ' classVariableNames: '' module: #(Squeak VMConstruction Plugins IO)! Object subclass: #CCodeGenerator instanceVariableNames: 'translationDict inlineList constants variables variableDeclarations methods variablesSetCache headerFiles pluginPrefix extraDefs postProcesses isCPP pluginName ' classVariableNames: 'UseRightShiftForDivide ' module: #(Squeak VMConstruction TranslationToC)! FileStreamException subclass: #CannotDeleteFileException instanceVariableNames: '' classVariableNames: '' module: #(Squeak Language Exceptions Core)! TestInterpreterPlugin subclass: #FileCopyPlugin instanceVariableNames: '' classVariableNames: '' module: #(Squeak VMConstruction Plugins IO)! !FileCopyPlugin commentStamp: '' prior: 0! This plugin is a simple workaround for the lamentable state of the Squeak file handling system; it provides a primitive to copy a file or tree via the OS facility and thus preserve all the OS attributes in the most trivial possible manner. Not intended for a long life and should be replaced by better code as soon as possible! InterpreterPlugin subclass: #FilePlugin instanceVariableNames: 'sCGFTfn sCDPfn sCSFTfn sDFAfn sCRFfn sCCPfn sHFAfn sCOFfn sCLPfn sCDFfn ' classVariableNames: 'DirBadPath DirEntryFound DirNoMoreEntries ' module: #(Squeak VMConstruction Plugins IO)! ObjectMemory class instanceVariableNames: 'timeStamp '! TestInterpreterPlugin subclass: #SocketPlugin instanceVariableNames: 'sCCSOTfn sHSAfn sDSAfn sCCTPfn sCCLOPfn ' classVariableNames: '' module: #(Squeak VMConstruction Plugins IO)! Object subclass: #VMMaker instanceVariableNames: 'inline forBrowser allPlugins internalPlugins externalPlugins platformName sourceDirName platformRootDirName logger allFilesList ' classVariableNames: 'DirNames ' module: #(Squeak VMConstruction Building)! !VMMaker commentStamp: '' prior: 0! This class builds a VM codebase from the in-image and on-file code. The platforms file tree you need can be downloaded via cvs from http://squeak.Sourceforge.net. See also the swiki (http://minnow.cc.gatech.edu/squeak/2106) for instructions. It is fairly configurable as to where directories live and can handle multiple platform's source trees at once. It's main purpose is to allow easy building of source trees with any combination of internal/external/unused plugins to suit your platform needs and capabilities. For example, the Acorn has no need of Sound or AsynchFile plugins since I haven't written any platform code for them. There is a simple UI tool for this VMMakerTool openInWorld will open a reasonably self explanatory tool with balloon help to explain all the fields - and a help window on top of that. There are some simple workspace & inspector commands, allowing scripted building: VMMaker default initializeAllExternal generateEntire for example will build sources for a system with all the plugins external whereas VMMaker default initializeAllInternal generateEntire would build all applicable plugins for internal compilation. (VMMaker forPlatform: 'Mac OS') initializeAllExternal generateEntire would build a source tree for a Mac even on a Windows machine (err, ignoring for now the irritation of lineends). If you have a slightly more complex configuration you want to use, perhaps with Socket and Serial support external (because for your case they are rarely used and saving the space has some value) then you could try (VMMaker default initializeAllInternalBut: #(SocketPlugin SerialPlugin) generateEntire More complex still would be (VMMaker default initializeInternal: #(BitBltPlugin MiscPrimsPlugin FilePlugin) external: #(SocketPlugin ZipPlugin B2DPlugin) which allows you to precisely list all the plugins to use. WARNING If you miss out a plugin you need, it won't be there. This message is really best suited to use by a UI like VMMakerTool. To save a configuration for later use, you need to send #saveConfiguration to an active instance of VMMaker. Obviously you could simply use (VMMaker default initializeAllInternalBut: #(SocketPlugin SerialPlugin) saveConfiguration but inspecting VMMaker default and altering the internalPlugins and externalPlugins or the boolean flags for inline or forBrowser followed by saving the configuration allows ultimate power for now. To load a saved configuration file, use #loadConfigurationFrom: aFilename whilst inspecting a VMMaker. The loaded state will completely override any pre-existing state, so take care. You can generate only parts of the source tree if you wish; as shown above #generateEntire will create the whole collection of internal and external plugins as well as the core VM. To create only the external plugins use #generateExternalPlugins, or create a single plugin with #generateExternalPlugin: name. To assemble the main VM including the internal plugins, use #generateMainVM. The interpreter 'interp.c' file is made with #generateInterpreterFile. You can generate a single internal plugin with #generateInternalPlugin: only if it has already been generated before; this interlocking is intended to make sure the named primitive table in the vm is correct. There are some rules to observe in order to use this:- - under the working directory (by default - you can configure it) you need a directory called 'platforms' (also configurable) with subdirectories named as the platform names returned by Smalltalk platformName (ie unix, RiscOS, Mac OS, etc - this isn't configurable). At the very least you need the one for your own platform and the pseudo-platform called 'Cross'. By adding a 'DirNames' entry for #machineType you can cross 'compile' for some other platform. Now all we need is a cross-compiler for the C code :-) - under this directory you must have a simple structure of directories for each generated plugin that you support on the platform, plus 'vm'. In each directory you place any/all platform specific files (and subdirectories) for that plugin. In 'misc' you can place any miscellaneous files such as makefiles, resources etc. For example, for unix you have platforms/ unix/ plugins/ AsynchFilePlugin / sqUnixAsynchfile.c vm/ sqGnu.h Profile/ misc/ makefile.in util/ ...etc Any plugins requiring platform files that you don't support shouldn't appear in the resulting code tree. If you try to include an unsupported plugin in the list to be made external, the VMMaker simply ignores it. However, if you include it in the list to be made internal you will get an error since that seems like a potentially serious source of confusion. There are three lists of plugins maintained herein:- 1) the list of all known generatable plugins. We scan this list and compare with the supported plugins as indicated by the file tree. 2) the list of chosen internal plugins. 3) the list of chosen external plugins. See initializeAllPlugins, initialiseAllExternal etc for fairly obvious usage. There is also a short list of directory names in the class variable 'DirNames' that you can alter if needed. Known problems:- a) since Squeak has really poor filename handling, you can't simply change the directory names to '/foo/bar/myEvilCodeBase' and expect it to work. You fix file names and I'll fix VMMaker :-) b) Squeak copying of a file loses the assorted permissions, filetype info and other useful bits. To workaround this problem, see the FileCopyPlugin, which provides the platform independent part of a simple access for the OS filecopy capability. So far there are functional plugins for unix, Mac and Acorn. DOS machines appear not to need one. This is less of a problem in practise now that unix & Mac no longer copy files from /platforms to /src. inline - is the generated code to be inlined or not forBrowser - is this to be a build for in-Browser use? Only relevent to Macs allPlugins - all the known possible plugins internalPlugins - the plugins chosen to be generated for internal linking externalPlugins - the plugins intended to be external plugins exportList - a list of function names exported from plugins intended to be internal platformName - the name of the platform for which we are building a source tree. It is possible to do 'cross-compiles' sourceDirName, platformRootDirName - the name of the directory into which we write the generated sources and the name of the directory where we should find the platforms tree.! ]style[(184 39 6394)f1,f1Rhttp://minnow.cc.gatech.edu/squeak/2106;,f1! VMMaker subclass: #MacOSPowerPCOS9VMMaker instanceVariableNames: '' classVariableNames: '' module: #(Squeak VMConstruction Building)! !MacOSPowerPCOS9VMMaker commentStamp: '' prior: 0! (VMMaker default initializeAllInternalBut: #(IntegerPokerPlugin Mpeg3Plugin FFIPlugin TestOSAPlugin)) generateMainVM.! MacOSPowerPCOS9VMMaker subclass: #MacOSPowerPCOS9BrowserVMMaker instanceVariableNames: '' classVariableNames: '' module: #(Squeak VMConstruction Building)! !MacOSPowerPCOS9BrowserVMMaker commentStamp: '' prior: 0! (MacOSPowerPCOS9BrowserVMMaker new initialize initializeAllInternalBut: #(IntegerPokerPlugin Mpeg3Plugin FFIPlugin TestOSAPlugin)) generateInterpreterFile.! VMMaker subclass: #RiscOSVMMaker instanceVariableNames: '' classVariableNames: '' module: #(Squeak VMConstruction Building)! !RiscOSVMMaker commentStamp: '' prior: 0! Special VMMaker class for Acorn RiscOS - add generation of a configuration file for each plugin, required by the dynamic loading libraries! Error subclass: #VMMakerException instanceVariableNames: '' classVariableNames: '' module: #(Squeak VMConstruction Building)! Model subclass: #VMMakerTool instanceVariableNames: 'vmMaker allPluginsList allPluginsSelection allPluginsSelectionsArray internalPluginsList internalPluginsSelection internalPluginsSelectionsArray externalPluginsList externalPluginsSelection externalPluginsSelectionsArray logger platformPathMorph platformNameMorph generatedPathMorph ' classVariableNames: '' module: #(Squeak VMConstruction Building)! !VMMakerTool commentStamp: '' prior: 0! VMMakerTool help information ------------------------------------ If you really get stuck, send mail to the Squeak mailing list, squeak-dev@lists.squeakfoundation.org VMMakerTool openInWorld What this is -------------- This tool is a simple interactive interface to VMMaker. You can change the directory paths for where the system looks for the platform files (those C files that are handwritten for each platform) and where it will put the assembled sources (the appropriate platform files and generated files) ready for you to compile into a new vm. You can change the platform for which it will generate files. You can choose which plugins are built and whether they are built for internal or external use. How to use it --------------- To build a configuration, drag plugins from the leftmost 'Plugins not built' list to either the 'Internal Plugins' list or the 'External Plugins' list. Plugins that cannot be built on your machine due to missing files will not be draggable. Once you have a configuration, you can save it for later retrieval by pressing the 'Save Configuration' button. Unsurprisingly you can reload a saved configuration with the 'Load Configuration' button. To generate an entire code tree, press the 'Generate All' button. This will process all the vm and plugin files needed for your configuration. To generate only the files for the vm and any internal plugins, use the 'Generate Core VM' button. This will be most useful if you are experimenting with the design of the vm internals or new object memory layouts etc. The 'Generate External Plugins' button will regenerate all the plugins in the External Plugins list. Note that 'excess' directories will be deleted each time you generate the vm in order to reduce potential confusion if you move a plugin from internal to external etc. If you repeatedly generate the vm only the files that appear to be out of date will be recreated; this drastically reduces the time taken if you have only changed a single plugin class for example. You can also generate internal or external plugins singly, using the menus in the lists but be warned - internal plugins are tightly related to the generated file 'vm/sqNamedPrims.h' and adding or removing an internal plugin without regenerating this (via 'Generate Core VM' or 'Generate All') will cause much grief. The application attempts to prevent this, but there are surely ways to confuse both yourself and the code. In general when writing experimental plugins it is much simpler to build them as external during the development cycle. If the default path for the platforms code is not correct for your machine you can use the 'Find Path' button to search for a plausible directory. Note that this could take an arbitrarily long time on a machine with connections to other machines since you may end up searching all their disc space as well. You can choose from a menu of all known platforms (at least, all those known in the set of files on your machine) by using the 'Find platform' button. This is useful if you want to generate files for some other platform and feel uncertain of the exact spelling. By default the platform will be set to that upon which you are running. If you feel the need to delete all the generated files you can press the 'Clean out' button - this will recursively delete everything below the path for the generated sources. Details ------- You really ought to read the class comment for VMMaker. Really. Go on, do it now. Errors ------- A number of errors are possible, mostly relating to the two directory paths and the platform name. As much as possible these are trapped and you will see 'inform' menus to let you know. Inevitably, if you put in the effort, you will be able to confuse the tool and break it. ! ]style[(28 141 23 1921 90 1247 7 319)f1b,f1,f1dVMMakerTool openInWorld;;,f1,bif1,f1,f1LVMMaker Comment;,f1! VMMaker subclass: #VMMakerWithFileCopying instanceVariableNames: '' classVariableNames: '' module: #(Squeak VMConstruction Building)! !VMMakerWithFileCopying commentStamp: '' prior: 0! This subclass of VMMaker is a hopefully temporary way to provide the copying of files from platforms/{Cross|foo} to src/ until all platforms are able to do their compiling with the platforms tree in place. The default class will NOT do the file copies and gradually the platform specific classes can be removed as they all catch up.! VMMakerWithFileCopying subclass: #Win32VMMaker instanceVariableNames: '' classVariableNames: '' module: #(Squeak VMConstruction Building)! !AsynchFilePlugin methodsFor: 'initialize-release' stamp: 'JMM 1/20/2002 22:00'! initialiseModule "Initialise the module" self export: true. sCOAFfn _ interpreterProxy ioLoadFunction: 'secCanOpenAsyncFileOfSizeWritable' From: 'SecurityPlugin'. ^self cCode: 'asyncFileInit()' inSmalltalk:[true]! ! !AsynchFilePlugin methodsFor: 'initialize-release' stamp: 'JMM 1/20/2002 22:06'! moduleUnloaded: aModuleName "The module with the given name was just unloaded. Make sure we have no dangling references." self export: true. self var: #aModuleName type: 'char *'. (aModuleName strcmp: 'SecurityPlugin') = 0 ifTrue:[ "The security plugin just shut down. How odd." sCOAFfn _ 0. ].! ! !AsynchFilePlugin methodsFor: 'primitives' stamp: 'JMM 1/20/2002 22:00'! primitiveAsyncFileOpen: fileName forWrite: writeFlag semaIndex: semaIndex | fileNameSize fOop f okToOpen | self var: #f declareC: 'AsyncFile *f'. self primitive: 'primitiveAsyncFileOpen' parameters: #(#String #Boolean #SmallInteger ). fileNameSize _ interpreterProxy slotSizeOf: (fileName asOop: String). "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCOAFfn ~= 0 ifTrue: [okToOpen _ self cCode: ' ((int (*) (char *, int, int)) sCOAFfn)(fileName, fileNameSize, writeFlag)'. okToOpen ifFalse: [^ interpreterProxy primitiveFail]]. fOop _ interpreterProxy instantiateClass: interpreterProxy classByteArray indexableSize: (self cCode: 'sizeof(AsyncFile)'). f _ self asyncFileValueOf: fOop. interpreterProxy failed ifFalse: [self cCode: 'asyncFileOpen(f, (int)fileName, fileNameSize, writeFlag, semaIndex)']. ^ fOop! ! !CCodeGenerator methodsFor: 'public' stamp: 'ar 3/16/2002 18:00'! declareModuleName: nameString "add the declaration of a module name, version and local/external tag" self var: #moduleName declareC:'const char *moduleName = #ifdef SQUEAK_BUILTIN_PLUGIN "', nameString,' (i)" #else "', nameString,' (e)" #endif '.! ! !CCodeGenerator methodsFor: 'public' stamp: 'ar 3/16/2002 15:50'! generateCodeStringForPrimitives | s methodList | s _ ReadWriteStream on: (String new: 1000). methodList _ methods asSortedCollection: [:m1 :m2 | m1 selector < m2 selector]. self emitCHeaderForPrimitivesOn: s. self emitCVariablesOn: s. self emitCFunctionPrototypes: methodList on: s. methodList do: [:m | m emitCCodeOn: s generator: self]. self emitExportsOn: s. ^ s contents ! ! !CCodeGenerator methodsFor: 'public' stamp: 'ar 3/16/2002 15:30'! pluginName "Return the plugin prefix when generating local plugins. Local plugins are plugins compiled with the main interpreter source but are not included (nor inlined into) interp.c" ^pluginName! ! !CCodeGenerator methodsFor: 'public' stamp: 'ar 3/16/2002 15:29'! pluginName: aString "Set the plugin name when generating plugins." pluginName _ aString.! ! !CCodeGenerator methodsFor: 'public' stamp: 'tpr 9/26/2001 07:28'! storeCodeOnFile: fileName doInlining: inlineFlag doAssertions: assertionFlag "Store C code for this code base on the given file." | stream | stream _ CrLfFileStream forceNewFileNamed: fileName. stream ifNil: [Error signal: 'Could not open C code file: ', fileName]. self emitCCodeOn: stream doInlining: inlineFlag doAssertions: assertionFlag. stream close! ! !CCodeGenerator methodsFor: 'C code generator' stamp: 'ar 3/16/2002 15:33'! cFunctionNameFor: aSelector "Create a C function name from the given selector by omitting colons and prefixing with the plugin name if the method is exported." ^aSelector copyWithout: $:! ! !CCodeGenerator methodsFor: 'C code generator' stamp: 'ar 3/16/2002 14:20'! emitCCodeOn: aStream doInlining: inlineFlag doAssertions: assertionFlag "Emit C code for all methods in the code base onto the given stream. All inlined method calls should already have been expanded." | verbose methodList | "method preparation" verbose _ false. self prepareMethods. verbose ifTrue: [ self printUnboundCallWarnings. self printUnboundVariableReferenceWarnings. Transcript cr. ]. assertionFlag ifFalse: [ self removeAssertions ]. self doInlining: inlineFlag. "code generation" methodList _ methods asSortedCollection: [ :m1 :m2 | m1 selector < m2 selector ]. self emitCHeaderOn: aStream. self emitCVariablesOn: aStream. self emitCFunctionPrototypes: methodList on: aStream. 'Writing Translated Code...' displayProgressAt: Sensor cursorPoint from: 0 to: methods size during: [:bar | methodList doWithIndex: [ :m :i | bar value: i. m emitCCodeOn: aStream generator: self. ]]. self emitExportsOn: aStream. ! ! !CCodeGenerator methodsFor: 'C code generator' stamp: 'ar 4/7/2002 18:25'! emitCVariablesOn: aStream "Store the global variable declarations on the given stream." | varString | aStream nextPutAll: '/*** Variables ***/'; cr. variables asSortedCollection do: [ :var | varString _ var asString. (self isGeneratingPluginCode) ifTrue:[ varString = 'interpreterProxy' ifTrue:[ "quite special..." aStream cr; nextPutAll: '#ifdef SQUEAK_BUILTIN_PLUGIN'. aStream cr; nextPutAll: 'extern'. aStream cr; nextPutAll: '#endif'; cr. ] ifFalse:[aStream nextPutAll:'static ']. ]. (variableDeclarations includesKey: varString) ifTrue: [ aStream nextPutAll: (variableDeclarations at: varString), ';'; cr. ] ifFalse: [ "default variable declaration" aStream nextPutAll: 'int ', varString, ';'; cr. ]. ]. aStream cr.! ! !CCodeGenerator methodsFor: 'C code generator' stamp: 'tpr 4/9/2002 19:13'! emitExportsOn: aStream "Store all the exported primitives in a form to be used by internal plugins" | prefix | pluginName ifNotNil:[aStream nextPutAll:' #ifdef SQUEAK_BUILTIN_PLUGIN';cr]. aStream nextPutAll:' void* ', (pluginName ifNil:['vm']),'_exports[][3] = {'. prefix := pluginName ifNil:['""'] ifNotNil:['"', pluginName,'"']. self exportedPrimitiveNames do:[:primName| aStream cr; nextPutAll:' {'; nextPutAll: prefix; nextPutAll:', "'; nextPutAll: primName; nextPutAll:'", (void*)'; nextPutAll: primName; nextPutAll:'},'. ]. aStream nextPutAll:' {NULL, NULL, NULL} }; '. pluginName ifNotNil:[aStream nextPutAll:' #endif /* ifdef SQ_BUILTIN_PLUGIN */ '].! ! !DropPlugin methodsFor: 'primitives' stamp: 'JMM 9/15/2001 21:14'! setFileAccessCallback: address self export: true. self var: #address type: 'int'. ^self cCode: 'sqSecFileAccessCallback((void *) address)'.! ! !FileCopyPlugin methodsFor: 'system primitives' stamp: 'tpr 4/10/2002 19:34'! primitiveFile: srcName copyTo: dstName |srcSz dstSz ok | self primitive: 'primitiveFileCopyNamedTo' parameters: #(String String). srcSz _ interpreterProxy slotSizeOf: srcName cPtrAsOop. dstSz _ interpreterProxy slotSizeOf: dstName cPtrAsOop. ok _ self sqCopyFile: srcName size: srcSz to: dstName size: dstSz. ok ifFalse:[interpreterProxy primitiveFail]. ! ! !FileDirectory methodsFor: 'enumeration' stamp: 'tpr 4/9/2002 17:24'! directoryEntryFor: filenameOrPath "Answer the directory entry for the given file or path. Sorta like a poor man's stat()." | fName dir | FileDirectory splitName: filenameOrPath to:[:filePath :name | fName _ name. filePath isEmpty ifTrue: [dir _ self] ifFalse: [dir _ FileDirectory on: filePath]]. self isCaseSensitive ifTrue:[^dir entries detect:[:entry| entry name = fName] ifNone:[nil]] ifFalse:[^dir entries detect:[:entry| entry name sameAs: fName] ifNone:[nil]]! ! !FileDirectory methodsFor: 'file operations' stamp: 'tpr 3/26/2002 16:48'! deleteLocalFiles "Delete the local files in this directory." self fileNames do:[:fn| self deleteFileNamed: fn ifAbsent: [(CannotDeleteFileException new messageText: 'Could not delete the old version of file ' , (self fullNameFor: fn)) signal]] ! ! !FileDirectory methodsFor: 'file operations' stamp: 'tpr 3/26/2002 18:09'! recursiveDelete "Delete the this directory, recursing down its tree." self directoryNames do: [:dn | (self directoryNamed: dn) recursiveDelete]. self deleteLocalFiles. "should really be some exception handling for directory deletion, but no support for it yet" self containingDirectory deleteDirectory: self localName! ! !FileDirectory class methodsFor: 'name utilities' stamp: 'ar 4/7/2002 15:47'! directoryEntryFor: filenameOrPath ^self default directoryEntryFor: filenameOrPath! ! !FilePlugin methodsFor: 'initialize-release' stamp: 'JMM 1/21/2002 11:02'! initialiseModule self export: true. sCCPfn _ interpreterProxy ioLoadFunction: 'secCanCreatePathOfSize' From: 'SecurityPlugin'. sCDPfn _ interpreterProxy ioLoadFunction: 'secCanDeletePathOfSize' From: 'SecurityPlugin'. sCGFTfn _ interpreterProxy ioLoadFunction: 'secCanGetFileTypeOfSize' From: 'SecurityPlugin'. sCLPfn _ interpreterProxy ioLoadFunction: 'secCanListPathOfSize' From: 'SecurityPlugin'. sCSFTfn _ interpreterProxy ioLoadFunction: 'secCanSetFileTypeOfSize' From: 'SecurityPlugin'. sDFAfn _ interpreterProxy ioLoadFunction: 'secDisableFileAccess' From: 'SecurityPlugin'. sCDFfn _ interpreterProxy ioLoadFunction: 'secCanDeleteFileOfSize' From: 'SecurityPlugin'. sCOFfn _ interpreterProxy ioLoadFunction: 'secCanOpenFileOfSizeWritable' From: 'SecurityPlugin'. sCRFfn _ interpreterProxy ioLoadFunction: 'secCanRenameFileOfSize' From: 'SecurityPlugin'. sHFAfn _ interpreterProxy ioLoadFunction: 'secHasFileAccess' From: 'SecurityPlugin'. ^self cCode: 'sqFileInit()' inSmalltalk:[true]! ! !FilePlugin methodsFor: 'initialize-release' stamp: 'JMM 1/21/2002 11:03'! moduleUnloaded: aModuleName "The module with the given name was just unloaded. Make sure we have no dangling references." self export: true. self var: #aModuleName type: 'char *'. (aModuleName strcmp: 'SecurityPlugin') = 0 ifTrue:[ "The security plugin just shut down. How odd." sCCPfn _ sCDPfn _ sCGFTfn _ sCLPfn _ sCSFTfn _ sDFAfn _ sCDFfn _ sCOFfn _ sCRFfn _ sHFAfn _ 0. ].! ! !FilePlugin methodsFor: 'file primitives' stamp: 'tpr 4/24/2002 13:53'! fileOpenName: nameIndex size: nameSize write: writeFlag secure: secureFlag "Open the named file, possibly checking security. Answer the file oop." | file fileOop okToOpen | self var: #file type: 'SQFile *'. self var: 'nameIndex' type: 'char *'. self export: true. fileOop _ interpreterProxy instantiateClass: interpreterProxy classByteArray indexableSize: self fileRecordSize. file _ self fileValueOf: fileOop. interpreterProxy failed ifFalse: [ secureFlag ifTrue: [ "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCOFfn ~= 0 ifTrue: [okToOpen _ self cCode: '((int (*) (char *, int, int)) sCOFfn)(nameIndex, nameSize, writeFlag)'. okToOpen ifFalse: [interpreterProxy primitiveFail]]]]. interpreterProxy failed ifFalse: [self cCode: 'sqFileOpen(file, (int)nameIndex, nameSize, writeFlag)' inSmalltalk: [file]]. ^ fileOop! ! !FilePlugin methodsFor: 'file primitives' stamp: 'JMM 8/18/2001 23:22'! getThisSession "Exported entry point for the VM." self export: true. ^self cCode: 'sqFileThisSession()'.! ! !FilePlugin methodsFor: 'file primitives' stamp: 'JMM 1/21/2002 10:59'! primitiveFileDelete | namePointer nameIndex nameSize okToDelete | self var: 'nameIndex' type: 'char *'. self export: true. namePointer _ interpreterProxy stackValue: 0. (interpreterProxy isBytes: namePointer) ifFalse: [^ interpreterProxy primitiveFail]. nameIndex _ interpreterProxy firstIndexableField: namePointer. nameSize _ interpreterProxy byteSizeOf: namePointer. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCDFfn ~= 0 ifTrue: [okToDelete _ self cCode: ' ((int (*) (char *, int)) sCDFfn)(nameIndex, nameSize)'. okToDelete ifFalse: [^ interpreterProxy primitiveFail]]. self sqFileDeleteName: (self cCoerce: nameIndex to: 'int') Size: nameSize. interpreterProxy failed ifFalse: [interpreterProxy pop: 1]! ! !FilePlugin methodsFor: 'file primitives' stamp: 'JMM 1/20/2002 21:35'! primitiveFileGetPosition | file position | self var: 'file' declareC: 'SQFile *file'. self var: 'position' type: 'squeakFileOffsetType'. self export: true. file _ self fileValueOf: (interpreterProxy stackValue: 0). interpreterProxy failed ifFalse: [position _ self sqFileGetPosition: file]. interpreterProxy failed ifFalse: [ interpreterProxy pop: 2. interpreterProxy push: (interpreterProxy positive64BitIntegerFor: position)].! ! !FilePlugin methodsFor: 'file primitives' stamp: 'tpr 4/24/2002 13:53'! primitiveFileOpen | writeFlag namePointer filePointer nameIndex nameSize | self var: 'nameIndex' type: 'char *'. self export: true. writeFlag _ interpreterProxy booleanValueOf: (interpreterProxy stackValue: 0). namePointer _ interpreterProxy stackValue: 1. (interpreterProxy isBytes: namePointer) ifFalse: [^ interpreterProxy primitiveFail]. nameIndex _ interpreterProxy firstIndexableField: namePointer. nameSize _ interpreterProxy byteSizeOf: namePointer. filePointer _ self fileOpenName: nameIndex size: nameSize write: writeFlag secure: true. interpreterProxy failed ifFalse: [interpreterProxy pop: 3. "rcvr, name, writeFlag" interpreterProxy push: filePointer] ! ! !FilePlugin methodsFor: 'file primitives' stamp: 'JMM 1/21/2002 11:01'! primitiveFileRename | oldNamePointer newNamePointer oldNameIndex oldNameSize newNameIndex newNameSize okToRename | self var: 'oldNameIndex' type: 'char *'. self var: 'newNameIndex' type: 'char *'. self export: true. newNamePointer _ interpreterProxy stackValue: 0. oldNamePointer _ interpreterProxy stackValue: 1. ((interpreterProxy isBytes: newNamePointer) and: [interpreterProxy isBytes: oldNamePointer]) ifFalse: [^ interpreterProxy primitiveFail]. newNameIndex _ interpreterProxy firstIndexableField: newNamePointer. newNameSize _ interpreterProxy byteSizeOf: newNamePointer. oldNameIndex _ interpreterProxy firstIndexableField: oldNamePointer. oldNameSize _ interpreterProxy byteSizeOf: oldNamePointer. "If the security plugin can be loaded, use it to check for rename permission. If not, assume it's ok" sCRFfn ~= 0 ifTrue: [okToRename _ self cCode: ' ((int (*) (char *, int)) sCRFfn)(oldNameIndex, oldNameSize)'. okToRename ifFalse: [^ interpreterProxy primitiveFail]]. self sqFileRenameOld: (self cCoerce: oldNameIndex to: 'int') Size: oldNameSize New: (self cCoerce: newNameIndex to: 'int') Size: newNameSize. interpreterProxy failed ifFalse: [interpreterProxy pop: 2]! ! !FilePlugin methodsFor: 'file primitives' stamp: 'JMM 1/21/2002 20:38'! primitiveFileSetPosition | newPosition file sz | self var: 'file' declareC: 'SQFile *file'. self var: 'newPosition' type: 'squeakFileOffsetType'. self export: true. (self isIntegerObject: (interpreterProxy stackValue: 0)) ifFalse: [sz _ self cCode: 'sizeof(squeakFileOffsetType)'. (interpreterProxy byteSizeOf: (interpreterProxy stackValue: 0)) > sz ifTrue: [^interpreterProxy primitiveFail]]. newPosition _ interpreterProxy positive64BitValueOf: (interpreterProxy stackValue: 0). file _ self fileValueOf: (interpreterProxy stackValue: 1). interpreterProxy failed ifFalse:[ self sqFile: file SetPosition: newPosition ]. interpreterProxy failed ifFalse:[ interpreterProxy pop: 2 "pop position, file; leave rcvr on stack" ].! ! !FilePlugin methodsFor: 'file primitives' stamp: 'JMM 1/20/2002 21:35'! primitiveFileSize | file size | self var: 'file' declareC: 'SQFile *file'. self var: 'size' type: 'squeakFileOffsetType'. self export: true. file _ self fileValueOf: (interpreterProxy stackValue: 0). interpreterProxy failed ifFalse:[size _ self sqFileSize: file]. interpreterProxy failed ifFalse: [ interpreterProxy pop: 2. interpreterProxy push: (interpreterProxy positive64BitIntegerFor: size)].! ! !FilePlugin methodsFor: 'file primitives' stamp: 'JMM 1/21/2002 20:38'! primitiveFileTruncate | truncatePosition file sz | self var: 'file' declareC: 'SQFile *file'. self var: 'truncatePosition' type: 'squeakFileOffsetType'. self export: true. (self isIntegerObject: (interpreterProxy stackValue: 0)) ifFalse: [sz _ self cCode: 'sizeof(squeakFileOffsetType)'. (interpreterProxy byteSizeOf: (interpreterProxy stackValue: 0)) > sz ifTrue: [^interpreterProxy primitiveFail]]. truncatePosition _ interpreterProxy positive64BitValueOf: (interpreterProxy stackValue: 0). file _ self fileValueOf: (interpreterProxy stackValue: 1). interpreterProxy failed ifFalse:[ self sqFile: file Truncate: truncatePosition ]. interpreterProxy failed ifFalse:[ interpreterProxy pop: 2 "pop position, file; leave rcvr on stack" ].! ! !FilePlugin methodsFor: 'directory primitives' stamp: 'JMM 1/20/2002 21:34'! makeDirEntryName: entryName size: entryNameSize createDate: createDate modDate: modifiedDate isDir: dirFlag fileSize: fileSize | modDateOop createDateOop nameString results stringPtr fileSizeOop | self var: 'entryName' declareC: 'char *entryName'. self var: 'stringPtr' declareC:'char *stringPtr'. self var: 'fileSize' declareC:'squeakFileOffsetType fileSize'. "allocate storage for results, remapping newly allocated oops in case GC happens during allocation" interpreterProxy pushRemappableOop: (interpreterProxy instantiateClass: (interpreterProxy classArray) indexableSize: 5). interpreterProxy pushRemappableOop: (interpreterProxy instantiateClass: (interpreterProxy classString) indexableSize: entryNameSize).. interpreterProxy pushRemappableOop: (interpreterProxy positive32BitIntegerFor: createDate). interpreterProxy pushRemappableOop: (interpreterProxy positive32BitIntegerFor: modifiedDate). interpreterProxy pushRemappableOop: (interpreterProxy positive64BitIntegerFor: fileSize). fileSizeOop _ interpreterProxy popRemappableOop. modDateOop _ interpreterProxy popRemappableOop. createDateOop _ interpreterProxy popRemappableOop. nameString _ interpreterProxy popRemappableOop. results _ interpreterProxy popRemappableOop. "copy name into Smalltalk string" stringPtr _ interpreterProxy firstIndexableField: nameString. 0 to: entryNameSize - 1 do: [ :i | stringPtr at: i put: (entryName at: i). ]. interpreterProxy storePointer: 0 ofObject: results withValue: nameString. interpreterProxy storePointer: 1 ofObject: results withValue: createDateOop. interpreterProxy storePointer: 2 ofObject: results withValue: modDateOop. dirFlag ifTrue: [ interpreterProxy storePointer: 3 ofObject: results withValue: interpreterProxy trueObject ] ifFalse: [ interpreterProxy storePointer: 3 ofObject: results withValue: interpreterProxy falseObject ]. interpreterProxy storePointer: 4 ofObject: results withValue: fileSizeOop. ^ results! ! !FilePlugin methodsFor: 'directory primitives' stamp: 'JMM 1/20/2002 22:08'! primitiveDirectoryCreate | dirName dirNameIndex dirNameSize okToCreate | self var: #dirNameIndex type: 'char *'. self export: true. dirName _ interpreterProxy stackValue: 0. (interpreterProxy isBytes: dirName) ifFalse: [^ interpreterProxy primitiveFail]. dirNameIndex _ interpreterProxy firstIndexableField: dirName. dirNameSize _ interpreterProxy byteSizeOf: dirName. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCCPfn ~= 0 ifTrue: [okToCreate _ self cCode: ' ((int (*) (char *, int)) sCCPfn)(dirNameIndex, dirNameSize)'. okToCreate ifFalse: [^ interpreterProxy primitiveFail]]. (self cCode: 'dir_Create((char *) dirNameIndex, dirNameSize)' inSmalltalk: [false]) ifFalse: [^ interpreterProxy primitiveFail]. interpreterProxy pop: 1! ! !FilePlugin methodsFor: 'directory primitives' stamp: 'JMM 1/21/2002 10:38'! primitiveDirectoryDelete | dirName dirNameIndex dirNameSize okToDelete | self var: #dirNameIndex type: 'char *'. self export: true. dirName _ interpreterProxy stackValue: 0. (interpreterProxy isBytes: dirName) ifFalse: [^ interpreterProxy primitiveFail]. dirNameIndex _ interpreterProxy firstIndexableField: dirName. dirNameSize _ interpreterProxy byteSizeOf: dirName. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCDPfn ~= 0 ifTrue: [okToDelete _ self cCode: ' ((int (*) (char *, int)) sCDPfn)(dirNameIndex, dirNameSize)'. okToDelete ifFalse: [^ interpreterProxy primitiveFail]]. (self cCode: 'dir_Delete((char *) dirNameIndex, dirNameSize)' inSmalltalk: [false]) ifFalse: [^ interpreterProxy primitiveFail]. interpreterProxy pop: 1! ! !FilePlugin methodsFor: 'directory primitives' stamp: 'JMM 1/21/2002 10:40'! primitiveDirectoryGetMacTypeAndCreator | creatorString typeString fileName creatorStringIndex typeStringIndex fileNameIndex fileNameSize okToGet | self var: 'creatorStringIndex' type: 'char *'. self var: 'typeStringIndex' type: 'char *'. self var: 'fileNameIndex' type: 'char *'. self export: true. creatorString _ interpreterProxy stackValue: 0. typeString _ interpreterProxy stackValue: 1. fileName _ interpreterProxy stackValue: 2. ((interpreterProxy isBytes: creatorString) and: [(interpreterProxy byteSizeOf: creatorString) = 4]) ifFalse: [^ interpreterProxy primitiveFail]. ((interpreterProxy isBytes: typeString) and: [(interpreterProxy byteSizeOf: typeString) = 4]) ifFalse: [^ interpreterProxy primitiveFail]. (interpreterProxy isBytes: fileName) ifFalse: [^ interpreterProxy primitiveFail]. creatorStringIndex _ interpreterProxy firstIndexableField: creatorString. typeStringIndex _ interpreterProxy firstIndexableField: typeString. fileNameIndex _ interpreterProxy firstIndexableField: fileName. fileNameSize _ interpreterProxy byteSizeOf: fileName. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCGFTfn ~= 0 ifTrue: [okToGet _ self cCode: ' ((int (*) (char *, int)) sCGFTfn)(fileNameIndex, fileNameSize)'. okToGet ifFalse: [^ interpreterProxy primitiveFail]]. (self cCode: 'dir_GetMacFileTypeAndCreator( (char *) fileNameIndex, fileNameSize, (char *) typeStringIndex, (char *) creatorStringIndex)' inSmalltalk: [true]) ifFalse: [^ interpreterProxy primitiveFail]. interpreterProxy pop: 3! ! !FilePlugin methodsFor: 'directory primitives' stamp: 'JMM 1/21/2002 10:43'! primitiveDirectoryLookup | index pathName pathNameIndex pathNameSize status entryName entryNameSize createDate modifiedDate dirFlag fileSize okToList | self var: 'entryName' declareC: 'char entryName[256]'. self var: 'pathNameIndex' type: 'char *'. self var: 'fileSize' type: 'squeakFileOffsetType'. self export: true. index _ interpreterProxy stackIntegerValue: 0. pathName _ interpreterProxy stackValue: 1. (interpreterProxy isBytes: pathName) ifFalse: [^ interpreterProxy primitiveFail]. pathNameIndex _ interpreterProxy firstIndexableField: pathName. pathNameSize _ interpreterProxy byteSizeOf: pathName. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCLPfn ~= 0 ifTrue: [okToList _ self cCode: ' ((int (*) (char *, int)) sCLPfn)(pathNameIndex, pathNameSize)'] ifFalse: [okToList _ true]. okToList ifTrue: [status _ self cCode: 'dir_Lookup( (char *) pathNameIndex, pathNameSize, index, entryName, &entryNameSize, &createDate, &modifiedDate, &dirFlag, &fileSize)'] ifFalse: [status _ DirNoMoreEntries]. interpreterProxy failed ifTrue: [^ nil]. status = DirNoMoreEntries ifTrue: ["no more entries; return nil" interpreterProxy pop: 3. "pop pathName, index, rcvr" interpreterProxy push: interpreterProxy nilObject. ^ nil]. status = DirBadPath ifTrue: [^ interpreterProxy primitiveFail]. "bad path" interpreterProxy pop: 3. "pop pathName, index, rcvr" interpreterProxy push: (self makeDirEntryName: entryName size: entryNameSize createDate: createDate modDate: modifiedDate isDir: dirFlag fileSize: fileSize)! ! !FilePlugin methodsFor: 'directory primitives' stamp: 'JMM 1/21/2002 10:45'! primitiveDirectorySetMacTypeAndCreator | creatorString typeString fileName creatorStringIndex typeStringIndex fileNameIndex fileNameSize okToSet | self var: 'creatorStringIndex' type: 'char *'. self var: 'typeStringIndex' type: 'char *'. self var: 'fileNameIndex' type: 'char *'. self export: true. creatorString _ interpreterProxy stackValue: 0. typeString _ interpreterProxy stackValue: 1. fileName _ interpreterProxy stackValue: 2. ((interpreterProxy isBytes: creatorString) and: [(interpreterProxy byteSizeOf: creatorString) = 4]) ifFalse: [^ interpreterProxy primitiveFail]. ((interpreterProxy isBytes: typeString) and: [(interpreterProxy byteSizeOf: typeString) = 4]) ifFalse: [^ interpreterProxy primitiveFail]. (interpreterProxy isBytes: fileName) ifFalse: [^ interpreterProxy primitiveFail]. creatorStringIndex _ interpreterProxy firstIndexableField: creatorString. typeStringIndex _ interpreterProxy firstIndexableField: typeString. fileNameIndex _ interpreterProxy firstIndexableField: fileName. fileNameSize _ interpreterProxy byteSizeOf: fileName. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCSFTfn ~= 0 ifTrue: [okToSet _ self cCode: ' ((int (*) (char *, int)) sCSFTfn)(fileNameIndex, fileNameSize)'. okToSet ifFalse: [^ interpreterProxy primitiveFail]]. (self cCode: 'dir_SetMacFileTypeAndCreator( (char *) fileNameIndex, fileNameSize, (char *) typeStringIndex, (char *) creatorStringIndex)' inSmalltalk: [true]) ifFalse: [^ interpreterProxy primitiveFail]. interpreterProxy pop: 3! ! !FilePlugin methodsFor: 'security primitives' stamp: 'tpr 4/18/2002 15:50'! primitiveDisableFileAccess self export: true. "If the security plugin can be loaded, use it to turn off file access If not, assume it's ok" sDFAfn ~= 0 ifTrue: [self cCode: ' ((int (*) (void)) sDFAfn)()']. interpreterProxy failed ifFalse: [interpreterProxy pop: 1]! ! !FilePlugin methodsFor: 'security primitives' stamp: 'JMM 1/21/2002 11:02'! primitiveHasFileAccess | hasAccess | self export: true. "If the security plugin can be loaded, use it to check . If not, assume it's ok" sHFAfn ~= 0 ifTrue: [hasAccess _ self cCode: ' ((int (*) (void)) sHFAfn)()'] ifFalse: [hasAccess _ true]. interpreterProxy pop: 1. interpreterProxy pushBool: hasAccess! ! !FileStream class methodsFor: 'instance creation' stamp: 'tpr 10/16/2001 12:49'! forceNewFileNamed: fileName "Create a new file with the given name, and answer a stream opened for writing on that file. If the file already exists, delete it without asking before creating the new file." ^self concreteStream forceNewFileNamed: fileName! ! !Interpreter methodsFor: 'message sending' stamp: 'sac 10/5/2001 02:56'! normalSend "Send a message, starting lookup with the receiver's class." "Assume: messageSelector and argumentCount have been set, and that the receiver and arguments have been pushed onto the stack," "Note: This method is inlined into the interpreter dispatch loop." | rcvr | self inline: true. self sharedCodeNamed: 'commonSend' inCase: 131. rcvr _ self internalStackValue: argumentCount. lkupClass _ self fetchClassOf: rcvr. receiverClass _ lkupClass. self internalFindNewMethod. self internalExecuteNewMethod. self fetchNextBytecode! ! !Interpreter methodsFor: 'primitive support' stamp: 'JMM 1/29/2002 20:06'! positive64BitIntegerFor: integerValue | newLargeInteger value check | "Note - integerValue is interpreted as POSITIVE, eg, as the result of Bitmap>at:, or integer>bitAnd:." self var: 'integerValue' type: 'squeakInt64'. (self sizeof: integerValue) = 4 ifTrue: [^self positive32BitIntegerFor: integerValue]. self cCode: 'check = integerValue >> 32'. check = 0 ifTrue: [^self positive32BitIntegerFor: integerValue]. newLargeInteger _ self instantiateSmallClass: (self splObj: ClassLargePositiveInteger) sizeInBytes: 12 fill: 0. 0 to: 7 do: [:i | self cCode: 'value = ( integerValue >> (i * 8)) & 255'. self storeByte: i ofObject: newLargeInteger withValue: value]. ^ newLargeInteger! ! !Interpreter methodsFor: 'primitive support' stamp: 'JMM 1/21/2002 11:17'! positive64BitValueOf: oop "Convert the given object into an integer value. The object may be either a positive ST integer or a eight-byte LargePositiveInteger." | sz szsqueakInt64 value | self returnTypeC: 'squeakInt64'. self var: 'value' type: 'squeakInt64'. (self isIntegerObject: oop) ifTrue: [ value _ self integerValueOf: oop. value < 0 ifTrue: [^ self primitiveFail]. ^ value]. self assertClassOf: oop is: (self splObj: ClassLargePositiveInteger). successFlag ifFalse: [^ self primitiveFail]. szsqueakInt64 _ self cCode: 'sizeof(squeakInt64)'. sz _ self lengthOf: oop. sz > szsqueakInt64 ifTrue: [^ self primitiveFail]. value _ 0. 0 to: sz - 1 do: [:i | value _ value + ((self cCoerce: (self fetchByte: i ofObject: oop) to: 'squeakInt64') << (i*8))]. ^value.! ! !Interpreter methodsFor: 'primitive support' stamp: 'JMM 1/29/2002 20:05'! signed64BitIntegerFor: integerValue "Return a Large Integer object for the given integer value" | newLargeInteger value largeClass intValue check | self inline: false. self var: 'integerValue' type: 'squeakInt64'. self var: 'value' type: 'squeakInt64'. integerValue < 0 ifTrue:[ largeClass _ self classLargeNegativeInteger. value _ 0 - integerValue] ifFalse:[ largeClass _ self classLargePositiveInteger. value _ integerValue]. (self sizeof: value) = 4 ifTrue: [^self signed32BitIntegerFor: integerValue]. self cCode: 'check = value >> 32'. check = 0 ifTrue: [^self signed32BitIntegerFor: integerValue]. newLargeInteger _ self instantiateSmallClass: largeClass sizeInBytes: 12 fill: 0. 0 to: 7 do: [:i | self cCode: 'intValue = ( value >> (i * 8)) & 255'. self storeByte: i ofObject: newLargeInteger withValue: intValue]. ^ newLargeInteger! ! !Interpreter methodsFor: 'primitive support' stamp: 'JMM 1/21/2002 11:18'! signed64BitValueOf: oop "Convert the given object into an integer value. The object may be either a positive ST integer or a eight-byte LargeInteger." | sz value largeClass negative szsqueakInt64 | self inline: false. self returnTypeC: 'squeakInt64'. self var: 'value' type: 'squeakInt64'. (self isIntegerObject: oop) ifTrue: [^self cCoerce: (self integerValueOf: oop) to: 'squeakInt64']. largeClass _ self fetchClassOf: oop. largeClass = self classLargePositiveInteger ifTrue:[negative _ false] ifFalse:[largeClass = self classLargeNegativeInteger ifTrue:[negative _ true] ifFalse:[^self primitiveFail]]. szsqueakInt64 _ self cCode: 'sizeof(squeakInt64)'. sz _ self lengthOf: oop. sz > szsqueakInt64 ifTrue: [^ self primitiveFail]. value _ 0. 0 to: sz - 1 do: [:i | value _ value + ((self cCoerce: (self fetchByte: i ofObject: oop) to: 'squeakInt64') << (i*8))]. negative ifTrue:[^0 - value] ifFalse:[^value]! ! !Interpreter methodsFor: 'other primitives'! primitiveImageName "When called with a single string argument, record the string as the current image file name. When called with zero arguments, return a string containing the current image file name." | s sz sCRIfn okToRename| argumentCount = 1 ifTrue: [ "If the security plugin can be loaded, use it to check for rename permission. If not, assume it's ok" sCRIfn _ self ioLoadFunction: 'secCanRenameImage' From: 'SecurityPlugin'. sCRIfn ~= 0 ifTrue:[okToRename _ self cCode:' ((int (*) (void)) sCRIfn)()'. okToRename ifFalse:[^self primitiveFail]]. s _ self stackTop. self assertClassOf: s is: (self splObj: ClassString). successFlag ifTrue: [ sz _ self stSizeOf: s. self imageNamePut: (s + BaseHeaderSize) Length: sz. self pop: 1. "pop s, leave rcvr on stack" ]. ] ifFalse: [ sz _ self imageNameSize. s _ self instantiateClass: (self splObj: ClassString) indexableSize: sz. self imageNameGet: (s + BaseHeaderSize) Length: sz. self pop: 1. "rcvr" self push: s. ]. ! ! !Interpreter methodsFor: 'image save/restore' stamp: 'JMM 1/20/2002 21:34'! checkImageVersionFrom: f startingAt: imageOffset "Read and verify the image file version number and return true if the the given image file needs to be byte-swapped. As a side effect, position the file stream just after the version number of the image header. This code prints a warning and does a hard-exit if it cannot find a valid version number." "This code is based on C code by Ian Piumarta." | version firstVersion | self var: #f declareC: 'sqImageFile f'. self var: #imageOffset declareC: 'squeakFileOffsetType imageOffset'. "check the version number" self sqImageFile: f Seek: imageOffset. version _ firstVersion _ self getLongFromFile: f swap: false. (self readableFormat: version) ifTrue: [^ false]. "try with bytes reversed" self sqImageFile: f Seek: imageOffset. version _ self getLongFromFile: f swap: true. (self readableFormat: version) ifTrue: [^ true]. "Note: The following is only meaningful if not reading an embedded image" imageOffset = 0 ifTrue:[ "try skipping the first 512 bytes (prepended by certain Mac file transfer utilities)" self sqImageFile: f Seek: 512. version _ self getLongFromFile: f swap: false. (self readableFormat: version) ifTrue: [^ false]. "try skipping the first 512 bytes with bytes reversed" self sqImageFile: f Seek: 512. version _ self getLongFromFile: f swap: true. (self readableFormat: version) ifTrue: [^ true]]. "hard failure; abort" self print: 'This interpreter (vers. '. self printNum: self imageFormatVersion. self print: ' cannot read image file (vers. '. self printNum: firstVersion. self cr. self print: 'Hit CR to quit'. self getchar. self ioExit. ! ! !Interpreter methodsFor: 'image save/restore' stamp: 'JMM 1/20/2002 21:34'! readImageFromFile: f HeapSize: desiredHeapSize StartingAt: imageOffset "Read an image from the given file stream, allocating the given amount of memory to its object heap. Fail if the image has an unknown format or requires more than the given amount of memory." "Details: This method detects when the image was stored on a machine with the opposite byte ordering from this machine and swaps the bytes automatically. Furthermore, it allows the header information to start 512 bytes into the file, since some file transfer programs for the Macintosh apparently prepend a Mac-specific header of this size. Note that this same 512 bytes of prefix area could also be used to store an exec command on Unix systems, allowing one to launch Smalltalk by invoking the image name as a command." "This code is based on C code by Ian Piumarta and Smalltalk code by Tim Rowledge. Many thanks to both of you!!!!" | swapBytes headerStart headerSize dataSize oldBaseAddr minimumMemory memStart bytesRead bytesToShift heapSize | self var: #f declareC: 'sqImageFile f'. self var: #headerStart declareC: 'squeakFileOffsetType headerStart'. self var: #dataSize declareC: 'size_t dataSize'. self var: #imageOffset declareC: 'squeakFileOffsetType imageOffset'. swapBytes _ self checkImageVersionFrom: f startingAt: imageOffset. headerStart _ (self sqImageFilePosition: f) - 4. "record header start position" headerSize _ self getLongFromFile: f swap: swapBytes. dataSize _ self getLongFromFile: f swap: swapBytes. oldBaseAddr _ self getLongFromFile: f swap: swapBytes. specialObjectsOop _ self getLongFromFile: f swap: swapBytes. lastHash _ self getLongFromFile: f swap: swapBytes. savedWindowSize _ self getLongFromFile: f swap: swapBytes. fullScreenFlag _ self getLongFromFile: f swap: swapBytes. extraVMMemory _ self getLongFromFile: f swap: swapBytes. lastHash = 0 ifTrue: [ "lastHash wasn't stored (e.g. by the cloner); use 999 as the seed" lastHash _ 999]. "decrease Squeak object heap to leave extra memory for the VM" heapSize _ self cCode: 'reserveExtraCHeapBytes(desiredHeapSize, extraVMMemory)'. "compare memory requirements with availability". minimumMemory _ dataSize + 100000. "need at least 100K of breathing room" heapSize < minimumMemory ifTrue: [ GenerateBrowserPlugin ifTrue: [ self plugInNotifyUser: 'The amount of memory specified by the ''memory'' EMBED tag is not enough for the installed Squeak image file.'. ^ nil] ifFalse: [self error: 'Insufficient memory for this image']]. "allocate a contiguous block of memory for the Squeak heap" memory _ self cCode: '(unsigned char *) sqAllocateMemory(minimumMemory, heapSize)'. memory = nil ifTrue: [ GenerateBrowserPlugin ifTrue: [ self plugInNotifyUser: 'There is not enough memory to give Squeak the amount specified by the ''memory'' EMBED tag.'. ^ nil] ifFalse: [self error: 'Failed to allocate memory for the heap']]. memStart _ self startOfMemory. memoryLimit _ (memStart + heapSize) - 24. "decrease memoryLimit a tad for safety" endOfMemory _ memStart + dataSize. "position file after the header" self sqImageFile: f Seek: headerStart + headerSize. "read in the image in bulk, then swap the bytes if necessary" bytesRead _ self cCode: 'sqImageFileRead(memory, sizeof(unsigned char), dataSize, f)'. bytesRead ~= dataSize ifTrue: [ GenerateBrowserPlugin ifTrue: [ self plugInNotifyUser: 'Squeak had problems reading its image file.'. self plugInShutdown. ^ nil] ifFalse: [self error: 'Read failed or premature end of image file']]. swapBytes ifTrue: [self reverseBytesInImage]. "compute difference between old and new memory base addresses" bytesToShift _ memStart - oldBaseAddr. self initializeInterpreter: bytesToShift. "adjusts all oops to new location" ^ dataSize ! ! !Interpreter methodsFor: 'image save/restore' stamp: 'tpr 4/23/2002 16:51'! writeImageFileIO: imageBytes | headerStart headerSize f bytesWritten sCWIfn okToWrite | self var: #f declareC: 'sqImageFile f'. self var: #headerStart declareC: 'squeakFileOffsetType headerStart'. "If the security plugin can be loaded, use it to check for write permission. If not, assume it's ok" sCWIfn _ self ioLoadFunction: 'secCanWriteImage' From: 'SecurityPlugin'. sCWIfn ~= 0 ifTrue:[okToWrite _ self cCode:' ((int (*) (void)) sCWIfn)()'. okToWrite ifFalse:[^self primitiveFail]]. "local constants" headerStart _ 0. headerSize _ 64. "header size in bytes; do not change!!" f _ self cCode: 'sqImageFileOpen(imageName, "wb")'. f = nil ifTrue: [ "could not open the image file for writing" self success: false. ^ nil]. headerStart _ self cCode: 'sqImageFileStartLocation(f,imageName,headerSize+imageBytes)'. self cCode: '/* Note: on Unix systems one could put an exec command here, padded to 512 bytes */'. "position file to start of header" self sqImageFile: f Seek: headerStart. self putLong: (self imageFormatVersion) toFile: f. self putLong: headerSize toFile: f. self putLong: imageBytes toFile: f. self putLong: (self startOfMemory) toFile: f. self putLong: specialObjectsOop toFile: f. self putLong: lastHash toFile: f. self putLong: (self ioScreenSize) toFile: f. self putLong: fullScreenFlag toFile: f. self putLong: extraVMMemory toFile: f. 1 to: 7 do: [:i | self putLong: 0 toFile: f]. "fill remaining header words with zeros" successFlag ifFalse: [ "file write or seek failure" self cCode: 'sqImageFileClose(f)'. ^ nil]. "position file after the header" self sqImageFile: f Seek: headerStart + headerSize. "write the image data" bytesWritten _ self cCode: 'sqImageFileWrite(memory, sizeof(unsigned char), imageBytes, f)'. self success: bytesWritten = imageBytes. self cCode: 'sqImageFileClose(f)'. ! ! !InterpreterPlugin class methodsFor: 'compiling' stamp: 'tpr 3/26/2002 15:21'! noteCompilationOf: aSelector meta: isMeta "note the recompiliation by resetting the timeStamp " self touch. ^super noteCompilationOf: aSelector meta: isMeta! ! !ADPCMCodecPlugin class methodsFor: 'translation' stamp: 'tpr 4/9/2002 16:14'! translateInDirectory: directory doInlining: inlineFlag "handle a special case code string rather than generated code" "Not currently hooked into the timeStamp mechanism for VMMaker since this would mean replicating code from InterpreterPlugin; waiting for a more elegant solution to appear. In the meantime this means that this plugin will always get regenerated even if the file is uptodate" | cg | self initialize. cg _ self buildCodeGeneratorUpTo: InterpreterPlugin. cg addMethodsForPrimitives: ADPCMCodec translatedPrimitives. inlineFlag ifTrue:[ "now remove a few which will be inlined but not pruned" cg pruneMethods: #(indexForDeltaFrom:to: nextBits: nextBits:put:)]. self storeString: cg generateCodeStringForPrimitives onFileNamed: (directory fullNameFor: self moduleName, '.c'). ^cg exportedPrimitiveNames asArray ! ! !B3DAcceleratorPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:08'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !B3DAcceleratorPlugin class methodsFor: 'translation' stamp: 'tpr 7/4/2001 15:12'! requiresCrossPlatformFiles "default is ok for most, any plugin needing platform specific files must say so" ^true! ! !B3DAcceleratorPlugin class methodsFor: 'translation' stamp: 'tpr 3/20/2001 12:16'! requiresPlatformFiles "default is ok for most, any plugin needing platform specific files must say so" ^true! ! !B3DEnginePlugin class methodsFor: 'translation' stamp: 'tpr 7/4/2001 15:10'! requiresCrossPlatformFiles "If there cross platform files to be associated with the plugin, here is where you want to flag" ^true! ! !B3DEnginePlugin class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:08'! shouldBeTranslated "B3DEnginePlugin should be translated but its subclasses should not since they are incorporated within this class's translation process" ^self == B3DEnginePlugin! ! !B3DEnginePlugin class methodsFor: 'translation' stamp: 'tpr 4/9/2002 16:14'! translateInDirectory: directory doInlining: inlineFlag "Special case for the 3D code. Check all the classes' timestamps, not just one" | cg fname fstat tStamp| fname _ self moduleName, '.c'. tStamp _ 0. tStamp _ { B3DEnginePlugin. B3DTransformerPlugin. B3DVertexBufferPlugin. B3DShaderPlugin. B3DClipperPlugin. B3DPickerPlugin. B3DRasterizerPlugin} inject: 0 into: [:tS :cl| tS _ tS max: cl timeStamp]. "don't translate if the file is newer than my timeStamp" fstat _ directory entryAt: fname ifAbsent:[nil]. fstat ifNotNil:[tStamp < fstat modificationTime ifTrue:[^nil]]. self initialize. cg _ self buildCodeGeneratorUpTo: InterpreterPlugin. { B3DEnginePlugin. B3DTransformerPlugin. B3DVertexBufferPlugin. B3DShaderPlugin. B3DClipperPlugin. B3DPickerPlugin. B3DRasterizerPlugin} do: [:theClass | theClass initialize. cg addClass: theClass. theClass declareCVarsIn: cg]. cg storeCodeOnFile: (directory fullNameFor: fname) doInlining: inlineFlag. ^cg exportedPrimitiveNames asArray! ! !BalloonEngineBase class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:14'! shouldBeTranslated "BalloonEnginePlugin should be translated but its superclasse should not since it is incorporated within this class's translation process. Nor should the simulation subclass be translated" ^self == BalloonEnginePlugin! ! !BitBltSimulator class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:19'! shouldBeTranslated "This class should not be translated " ^false! ! !DropPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:09'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !DropPlugin class methodsFor: 'translation' stamp: 'tpr 3/20/2001 12:15'! requiresPlatformFiles "default is ok for most, any plugin needing platform specific files must say so" ^true! ! !FFIPlugin class methodsFor: 'C support code' stamp: 'tpr 5/23/2001 17:09'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !FFIPlugin class methodsFor: 'translation' stamp: 'tpr 11/29/2000 22:40'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !FXBltSimulation class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:24'! shouldBeTranslated "This class should not be translated" ^false! ! !FilePlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:09'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !FilePlugin class methodsFor: 'translation' stamp: 'tpr 7/4/2001 15:12'! requiresCrossPlatformFiles "this plugin requires cross platform files in order to work" ^true! ! !FilePlugin class methodsFor: 'translation' stamp: 'tpr 11/29/2000 22:37'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !FilePluginSimulator class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:34'! shouldBeTranslated "This class should not be translated" ^false! ! !InflatePlugin class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:27'! shouldBeTranslated "InflatePlugin should not be translated but its subclass should since it is incorporated within that class's translation process" ^self ~= InflatePlugin! ! !JPEGReadWriter2Plugin methodsFor: 'primitives' stamp: 'tpr 4/29/2002 17:17'! primJPEGWriteImage: aJPEGCompressStruct onByteArray: destination form: form quality: quality progressiveJPEG: progressiveFlag errorMgr: aJPEGErrorMgr2Struct | pcinfo pjerr buffer rowStride formBits formWidth formHeight formDepth i j formPix destinationSize pixPerWord formPitch formBitsSize formBitsAsInt | self export: true. self primitive: 'primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgr' parameters: #(ByteArray ByteArray Form SmallInteger Boolean ByteArray). self var: #pcinfo declareC: 'j_compress_ptr pcinfo'. self var: #pjerr declareC: 'error_ptr2 pjerr'. self var: #buffer declareC: 'JSAMPARRAY buffer'. self var: #formBits declareC: 'unsigned * formBits'. self var: #destinationSize type: 'unsigned int'. "Avoid warnings when saving method" self cCode: '' inSmalltalk: [ pcinfo _ nil. pjerr _ nil. buffer _nil. rowStride _ nil. formBits _ nil. formWidth _ nil. formHeight _ nil. formDepth _ nil. i _ nil. j _ nil. formPix _ nil. destinationSize _ nil. pcinfo. pjerr. buffer. rowStride. formBits. formWidth. formHeight. formDepth. i. j. formPix. destinationSize. ]. formBits _self cCoerce: (interpreterProxy fetchPointer: 0 ofObject: form) to: 'unsigned *'. formBitsAsInt _ interpreterProxy fetchPointer: 0 ofObject: form. formWidth _ interpreterProxy fetchInteger: 1 ofObject: form. formHeight _ interpreterProxy fetchInteger: 2 ofObject: form. formDepth _ interpreterProxy fetchInteger: 3 ofObject: form. "Various parameter checks" self cCode: ' interpreterProxy->success ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(5))) >= (sizeof(struct jpeg_compress_struct))); interpreterProxy->success ((interpreterProxy->stSizeOf(interpreterProxy->stackValue(0))) >= (sizeof(struct error_mgr2))); if (interpreterProxy->failed()) return null; ' inSmalltalk: []. pixPerWord _ 32 // formDepth. formPitch _ formWidth + (pixPerWord-1) // pixPerWord * 4. formBitsSize _ interpreterProxy byteSizeOf: formBitsAsInt. interpreterProxy success: ((interpreterProxy isWordsOrBytes: formBitsAsInt) and: [formBitsSize = (formPitch * formHeight)]). interpreterProxy failed ifTrue: [^ nil]. self cCode: ' destinationSize = interpreterProxy->stSizeOf(interpreterProxy->stackValue(4)); pcinfo = (j_compress_ptr)aJPEGCompressStruct; pjerr = (error_ptr2)aJPEGErrorMgr2Struct; if (destinationSize) { pcinfo->err = jpeg_std_error(&pjerr->pub); pjerr->pub.error_exit = error_exit; if (setjmp(pjerr->setjmp_buffer)) { jpeg_destroy_compress(pcinfo); destinationSize = 0; } if (destinationSize) { jpeg_create_compress(pcinfo); jpeg_mem_dest(pcinfo, destination, &destinationSize); pcinfo->image_width = formWidth; pcinfo->image_height = formHeight; pcinfo->input_components = 3; pcinfo->in_color_space = JCS_RGB; jpeg_set_defaults(pcinfo); if (quality > 0) jpeg_set_quality (pcinfo, quality, 1); if (progressiveFlag) jpeg_simple_progression(pcinfo); jpeg_start_compress(pcinfo, TRUE); rowStride = formWidth * 3; /* Make a one-row-high sample array that will go away when done with image */ buffer = (*(pcinfo->mem)->alloc_sarray) ((j_common_ptr) pcinfo, JPOOL_IMAGE, rowStride, 1); while (pcinfo->next_scanline < pcinfo->image_height) { switch (formDepth) { case 32: for(i = 0, j = 1; i < rowStride; i +=3, j++) { formPix = formBits [ ((pcinfo->next_scanline) * formWidth) + j ]; buffer[0][i] = (formPix >> 16) & 255; buffer[0][i+1] = (formPix >> 8) & 255; buffer[0][i+2] = formPix & 255; } break; case 16: for(i = 0, j = 1; i < rowStride; i +=6, j++) { formPix = formBits [ ((pcinfo->next_scanline) * formWidth) / 2 + j ]; buffer[0][i] = (formPix >> 23) & 248; buffer[0][i+1] = (formPix >> 18) & 248; buffer[0][i+2] = (formPix >> 13) & 248; buffer[0][i+3] = (formPix >> 7) & 248; buffer[0][i+4] = (formPix >> 2) & 248; buffer[0][i+5] = (formPix << 3) & 248; } break; } (void) jpeg_write_scanlines(pcinfo, buffer, 1); } jpeg_finish_compress(pcinfo); jpeg_destroy_compress(pcinfo); } } ' inSmalltalk: []. ^(self cCode: 'destinationSize' inSmalltalk: [0]) asOop: SmallInteger! ! !JoystickTabletPlugin methodsFor: 'initialize-release' stamp: 'tpr 3/26/2002 15:22'! shutdownModule self export: true. ^self cCode: 'joystickShutdown()' inSmalltalk:[true]! ! !MiscPrimitivePlugin class methodsFor: 'translation' stamp: 'tpr 4/9/2002 16:15'! translateInDirectory: directory doInlining: inlineFlag "handle a special case code string rather than normal generated code." | cg fname fstat | fname _ self moduleName, '.c'. "don't translate if the file is newer than my timeStamp" fstat _ directory entryAt: fname ifAbsent:[nil]. fstat ifNotNil:[self timeStamp < fstat modificationTime ifTrue:[^nil]]. self initialize. cg _ self buildCodeGeneratorUpTo: InterpreterPlugin. cg addMethodsForPrimitives: self translatedPrimitives. self storeString: cg generateCodeStringForPrimitives onFileNamed: (directory fullNameFor: fname). ^cg exportedPrimitiveNames asArray ! ! !ObjectMemory class methodsFor: 'translation' stamp: 'tpr 3/27/2002 12:53'! noteCompilationOf: aSelector meta: isMeta "note the recompiliation by resetting the timeStamp " self touch. ^super noteCompilationOf: aSelector meta: isMeta! ! !Interpreter class methodsFor: 'translation' stamp: 'tpr 4/9/2002 16:17'! translateInDirectory: directory doInlining: inlineFlag forBrowserPlugin: pluginFlag "Translate the Smalltalk description of the virtual machine into C. If inlineFlag is true, small method bodies are inlined to reduce procedure call overhead. On the PPC, this results in a factor of three speedup with only 30% increase in code size. If pluginFlag is true, generate code for an interpreter that runs as a browser plugin (Netscape or IE)." "Note: The pluginFlag is meaningless on Windows and Unix. On these platforms Squeak runs as it's own process and doesn't need any special attention from the VMs point of view. Meaning that NONE of the required additional functions will be supported. In other words, the pluginFlag is not needed and not supported." | doInlining cg fileName tStamp fstat | tStamp _ { Interpreter. ObjectMemory} inject: 0 into: [:tS :cl| tS _ tS max: cl timeStamp]. "don't translate if the file is newer than my timeStamp" fileName _ 'interp.c'. fstat _ directory entryAt: fileName ifAbsent:[nil]. fstat ifNotNil:[tStamp < fstat modificationTime ifTrue:[^nil]]. doInlining _ inlineFlag. pluginFlag ifTrue: [doInlining _ true]. "must inline when generating browser plugin" Interpreter initialize. ObjectMemory initialize. GenerateBrowserPlugin _ pluginFlag. cg _ CCodeGenerator new initialize. cg addClass: Interpreter. cg addClass: ObjectMemory. Interpreter declareCVarsIn: cg. ObjectMemory declareCVarsIn: cg. cg storeCodeOnFile: (directory fullNameFor: fileName) doInlining: doInlining! ! !PluggableCodeGenerator methodsFor: 'C code generator' stamp: 'tpr 4/10/2002 18:28'! emitCHeaderForPrimitivesOn: aStream "Write a C file header for compiled primitives onto the given stream." self emitCHeaderOn: aStream. aStream nextPutAll: ' /*** Proxy Functions ***/ #define stackValue(i) (interpreterProxy->stackValue(i)) #define stackIntegerValue(i) (interpreterProxy->stackIntegerValue(i)) #define successFlag (!!interpreterProxy->failed()) #define success(bool) (interpreterProxy->success(bool)) #define arrayValueOf(oop) (interpreterProxy->arrayValueOf(oop)) #define checkedIntegerValueOf(oop) (interpreterProxy->checkedIntegerValueOf(oop)) #define fetchArrayofObject(idx,oop) (interpreterProxy->fetchArrayofObject(idx,oop)) #define fetchFloatofObject(idx,oop) (interpreterProxy->fetchFloatofObject(idx,oop)) #define fetchIntegerofObject(idx,oop) (interpreterProxy->fetchIntegerofObject(idx,oop)) #define floatValueOf(oop) (interpreterProxy->floatValueOf(oop)) #define pop(n) (interpreterProxy->pop(n)) #define pushInteger(n) (interpreterProxy->pushInteger(n)) #define sizeOfSTArrayFromCPrimitive(cPtr) (interpreterProxy->sizeOfSTArrayFromCPrimitive(cPtr)) #define storeIntegerofObjectwithValue(idx,oop,value) (interpreterProxy->storeIntegerofObjectwithValue(idx,oop,value)) #define primitiveFail() interpreterProxy->primitiveFail() /* allows accessing Strings in both C and Smalltalk */ #define asciiValue(c) c '. aStream cr.! ! !PluggableCodeGenerator methodsFor: 'C code generator' stamp: 'tpr 4/10/2002 18:27'! emitCHeaderOn: aStream "Write a C file header onto the given stream." aStream nextPutAll: '/* Automatically generated from Squeak on '. aStream nextPutAll: Time dateAndTimeNow printString. aStream nextPutAll: ' */';cr. aStream nextPutAll:' #include #include #include #include #include /* Default EXPORT macro that does nothing (see comment in sq.h): */ #define EXPORT(returnType) returnType /* Do not include the entire sq.h file but just those parts needed. */ /* The virtual machine proxy definition */ #include "sqVirtualMachine.h" /* Configuration options */ #include "sqConfig.h" /* Platform specific definitions */ #include "sqPlatformSpecific.h" #define true 1 #define false 0 #define null 0 /* using ''null'' because nil is predefined in Think C */ #ifdef SQUEAK_BUILTIN_PLUGIN #undef EXPORT // was #undef EXPORT(returnType) but screws NorCroft cc #define EXPORT(returnType) static returnType #endif '. "Additional header files" headerFiles do:[:hdr| aStream nextPutAll:'#include '; nextPutAll: hdr; cr]. aStream nextPutAll: ' /* memory access macros */ #define byteAt(i) (*((unsigned char *) (i))) #define byteAtput(i, val) (*((unsigned char *) (i)) = val) #define longAt(i) (*((int *) (i))) #define longAtput(i, val) (*((int *) (i)) = val) '. aStream cr.! ! !SecurityPlugin methodsFor: 'exported functions'! secCan: socket ListenOnPort: port self export: true. ^self cCode: 'ioCanListenOnPort(socket, port)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanConnect: addr ToPort: port self export: true. ^self cCode: 'ioCanConnectToPort(addr, port)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanCreate: netType SocketOfType: socketType self export: true. ^self cCode: 'ioCanCreateSocketOfType(netType, socketType)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanCreatePath: dirName OfSize: dirNameSize self export: true. self var: #dirName type: 'char *'. ^self cCode: 'ioCanCreatePathOfSize(dirName, dirNameSize)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanDeleteFile: fileName OfSize: fileNameSize self export: true. self var: #fileName type: 'char *'. ^self cCode: 'ioCanDeleteFileOfSize(fileName, fileNameSize)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanDeletePath: dirName OfSize: dirNameSize self export: true. self var: #dirName type: 'char *'. ^self cCode: 'ioCanDeletePathOfSize(dirName, dirNameSize)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanGetFileType: fileName OfSize: fileNameSize self export: true. self var: #fileName type: 'char *'. ^self cCode: 'ioCanGetFileTypeOfSize(fileName, fileNameSize)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanListPath: pathName OfSize: pathNameSize self export: true. self var: #pathName type: 'char *'. ^self cCode: 'ioCanListPathOfSize(pathName, pathNameSize)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanOpenAsyncFile: fileName OfSize: fileNameSize Writable: writeFlag self export: true. self var: #fileName type: 'char *'. ^self cCode: 'ioCanOpenAsyncFileOfSizeWritable(fileName, fileNameSize, writeFlag)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanOpenFile: fileName OfSize: fileNameSize Writable: writeFlag self export: true. self var: #fileName type: 'char *'. ^self cCode: 'ioCanOpenFileOfSizeWritable(fileName, fileNameSize, writeFlag)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanRenameFile: fileName OfSize: fileNameSize self export: true. self var: #fileName type: 'char *'. ^self cCode: 'ioCanRenameFileOfSize(fileName, fileNameSize)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanRenameImage self export: true. ^self cCode: 'ioCanRenameImage()'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanSetFileType: fileName OfSize: fileNameSize self export: true. self var: #fileName type: 'char *'. ^self cCode: 'ioCanSetFileTypeOfSize(fileName, fileNameSize)'! ! !SecurityPlugin methodsFor: 'exported functions'! secCanWriteImage self export: true. ^self cCode: 'ioCanWriteImage()'! ! !SecurityPlugin methodsFor: 'exported functions'! secDisableFileAccess self export: true. ^self cCode: 'ioDisableFileAccess()'! ! !SecurityPlugin methodsFor: 'exported functions'! secDisableSocketAccess self export: true. ^self cCode: 'ioDisableSocketAccess()'! ! !SecurityPlugin methodsFor: 'exported functions'! secHasFileAccess self export: true. ^self cCode: 'ioHasFileAccess()'! ! !SecurityPlugin methodsFor: 'exported functions'! secHasSocketAccess self export: true. ^self cCode: 'ioHasSocketAccess()'! ! !SecurityPlugin methodsFor: 'initialize' stamp: 'JMM 8/15/2001 11:59'! initialiseModule self export: true. ^self cCode: 'ioInitSecurity()' inSmalltalk:[true]! ! !SecurityPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:10'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !SecurityPlugin class methodsFor: 'translation' stamp: 'tpr 3/20/2001 12:33'! requiresPlatformFiles "default is ok for most, any plugin needing platform specific files must say so" ^true! ! !SerialPlugin methodsFor: 'primitives' stamp: 'TPR 2/11/2000 16:08'! primitiveSerialPortOpen: portNum baudRate: baudRate stopBitsType: stopBitsType parityType: parityType dataBits: dataBits inFlowControlType: inFlowControl outFlowControlType: outFlowControl xOnByte: xOnChar xOffByte: xOffChar self primitive: 'primitiveSerialPortOpen' parameters: #(SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger SmallInteger ). self cCode: 'serialPortOpen( portNum, baudRate, stopBitsType, parityType, dataBits, inFlowControl, outFlowControl, xOnChar, xOffChar)'! ! !SerialPlugin methodsFor: 'primitives' stamp: 'TPR 3/21/2000 17:00'! primitiveSerialPortRead: portNum into: array startingAt: startIndex count: count | bytesRead arrayPtr | self primitive: 'primitiveSerialPortRead' parameters: #(SmallInteger ByteArray SmallInteger SmallInteger ). interpreterProxy success: (startIndex >= 1 and: [startIndex + count - 1 <= (interpreterProxy byteSizeOf: array cPtrAsOop)]). arrayPtr _ array asInteger + startIndex - 1. bytesRead _ self cCode: 'serialPortReadInto( portNum, count, arrayPtr)'. "adjust for zero-origin indexing" ^ bytesRead asSmallIntegerObj! ! !SerialPlugin methodsFor: 'primitives' stamp: 'TPR 3/21/2000 17:00'! primitiveSerialPortWrite: portNum from: array startingAt: startIndex count: count | bytesWritten arrayPtr | self primitive: 'primitiveSerialPortWrite' parameters: #(SmallInteger ByteArray SmallInteger SmallInteger ). interpreterProxy success: (startIndex >= 1 and: [startIndex + count - 1 <= (interpreterProxy byteSizeOf: array cPtrAsOop)]). interpreterProxy failed ifFalse: [arrayPtr _ array asInteger + startIndex - 1. bytesWritten _ self serialPort: portNum Write: count From: arrayPtr]. ^ bytesWritten asSmallIntegerObj! ! !SocketPlugin methodsFor: 'initialize-release' stamp: 'JMM 1/21/2002 11:09'! initialiseModule self export: true. sDSAfn _ interpreterProxy ioLoadFunction: 'secDisableSocketAccess' From: 'SecurityPlugin'. sHSAfn _ interpreterProxy ioLoadFunction: 'secHasSocketAccess' From: 'SecurityPlugin'. sCCTPfn _ interpreterProxy ioLoadFunction: 'secCanConnectToPort' From: 'SecurityPlugin'. sCCLOPfn _ interpreterProxy ioLoadFunction: 'secCanListenOnPort' From: 'SecurityPlugin'. sCCSOTfn _ interpreterProxy ioLoadFunction: 'secCanCreateSocketOfType' From: 'SecurityPlugin'. ^self cCode: 'socketInit()' inSmalltalk:[true]! ! !SocketPlugin methodsFor: 'initialize-release' stamp: 'JMM 1/21/2002 11:10'! moduleUnloaded: aModuleName "The module with the given name was just unloaded. Make sure we have no dangling references." self export: true. self var: #aModuleName type: 'char *'. (aModuleName strcmp: 'SecurityPlugin') = 0 ifTrue:[ "The security plugin just shut down. How odd." sDSAfn _ sHSAfn _ sCCTPfn _ sCCLOPfn _ sCCSOTfn _ 0. ].! ! !SocketPlugin methodsFor: 'primitives' stamp: 'JMM 1/21/2002 11:07'! primitiveSocket: socket connectTo: address port: port | addr s okToConnect | self var: #s declareC: 'SocketPtr s'. self primitive: 'primitiveSocketConnectToPort' parameters: #(#Oop #ByteArray #SmallInteger ). addr _ self netAddressToInt: (self cCoerce: address to: 'unsigned char *'). "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCCTPfn ~= 0 ifTrue: [okToConnect _ self cCode: ' ((int (*) (int, int)) sCCTPfn)(addr, port)'. okToConnect ifFalse: [^ interpreterProxy primitiveFail]]. s _ self socketValueOf: socket. interpreterProxy failed ifFalse: [self sqSocket: s ConnectTo: addr Port: port]! ! !SocketPlugin methodsFor: 'primitives' stamp: 'JMM 1/21/2002 11:07'! primitiveSocket: socket listenOnPort: port "one part of the wierdass dual prim primitiveSocketListenOnPort which was warped by some demented evil person determined to twist the very nature of reality" | s okToListen | self var: #s declareC: 'SocketPtr s'. self primitive: 'primitiveSocketListenOnPort' parameters: #(#Oop #SmallInteger ). s _ self socketValueOf: socket. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCCLOPfn ~= 0 ifTrue: [okToListen _ self cCode: ' ((int (*) (SocketPtr, int)) sCCLOPfn)(s, port)'. okToListen ifFalse: [^ interpreterProxy primitiveFail]]. self sqSocket: s ListenOnPort: port! ! !SocketPlugin methodsFor: 'primitives' stamp: 'JMM 1/21/2002 11:08'! primitiveSocket: socket listenOnPort: port backlogSize: backlog "second part of the wierdass dual prim primitiveSocketListenOnPort which was warped by some demented evil person determined to twist the very nature of reality" | s okToListen | self var: #s declareC: 'SocketPtr s'. self primitive: 'primitiveSocketListenOnPortBacklog' parameters: #(#Oop #SmallInteger #SmallInteger ). s _ self socketValueOf: socket. "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCCLOPfn ~= 0 ifTrue: [okToListen _ self cCode: ' ((int (*) (SocketPtr, int)) sCCLOPfn)(s, port)'. okToListen ifFalse: [^ interpreterProxy primitiveFail]]. self sqSocket: s ListenOnPort: port BacklogSize: backlog! ! !SocketPlugin methodsFor: 'primitives' stamp: 'JMM 1/21/2002 11:09'! primitiveSocketCreateNetwork: netType type: socketType receiveBufferSize: recvBufSize sendBufSize: sendBufSize semaIndex: semaIndex | socketOop s okToCreate | self var: #s declareC: 'SocketPtr s'. self primitive: 'primitiveSocketCreate' parameters: #(#SmallInteger #SmallInteger #SmallInteger #SmallInteger #SmallInteger ). "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCCSOTfn ~= 0 ifTrue: [okToCreate _ self cCode: ' ((int (*) (int, int)) sCCSOTfn)(netType, socketType)'. okToCreate ifFalse: [^ interpreterProxy primitiveFail]]. socketOop _ interpreterProxy instantiateClass: interpreterProxy classByteArray indexableSize: self socketRecordSize. s _ self socketValueOf: socketOop. self sqSocket: s CreateNetType: netType SocketType: socketType RecvBytes: recvBufSize SendBytes: sendBufSize SemaID: semaIndex. ^ socketOop! ! !SocketPlugin methodsFor: 'primitives' stamp: 'JMM 1/21/2002 11:10'! primitiveSocketCreateNetwork: netType type: socketType receiveBufferSize: recvBufSize sendBufSize: sendBufSize semaIndex: semaIndex readSemaIndex: aReadSema writeSemaIndex: aWriteSema | socketOop s okToCreate | self var: #s declareC: 'SocketPtr s'. self primitive: 'primitiveSocketCreate3Semaphores' parameters: #(#SmallInteger #SmallInteger #SmallInteger #SmallInteger #SmallInteger #SmallInteger #SmallInteger ). "If the security plugin can be loaded, use it to check for permission. If not, assume it's ok" sCCSOTfn ~= 0 ifTrue: [okToCreate _ self cCode: ' ((int (*) (int, int)) sCCSOTfn)(netType, socketType)'. okToCreate ifFalse: [^ interpreterProxy primitiveFail]]. socketOop _ interpreterProxy instantiateClass: interpreterProxy classByteArray indexableSize: self socketRecordSize. s _ self socketValueOf: socketOop. self sqSocket: s CreateNetType: netType SocketType: socketType RecvBytes: recvBufSize SendBytes: sendBufSize SemaID: semaIndex ReadSemaID: aReadSema WriteSemaID: aWriteSema. ^ socketOop! ! !SocketPlugin methodsFor: 'security primitives' stamp: 'tpr 4/18/2002 15:56'! primitiveDisableSocketAccess self export: true. "If the security plugin can be loaded, use it to turn off socket access If not, assume it's ok" sDSAfn ~= 0 ifTrue: [self cCode: ' ((int (*) (void)) sDSAfn)()']. interpreterProxy failed ifFalse: [interpreterProxy pop: 1]! ! !SocketPlugin methodsFor: 'security primitives' stamp: 'JMM 1/21/2002 11:06'! primitiveHasSocketAccess | hasAccess | self export: true. interpreterProxy pop: 1. "If the security plugin can be loaded, use it to check . If not, assume it's ok" sHSAfn ~= 0 ifTrue: [hasAccess _ self cCode: ' ((int (*) (void)) sHSAfn)()'] ifFalse: [hasAccess _ true]. interpreterProxy pop: 1. interpreterProxy pushBool: hasAccess! ! !SoundCodecPlugin class methodsFor: 'accessing' stamp: 'tpr 5/23/2001 17:11'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !SoundCodecPlugin class methodsFor: 'accessing' stamp: 'tpr 4/18/2002 15:56'! moduleName ^ 'SoundCodecPrims' "Needs to be the name used for module specification..." ! ! !SoundCodecPlugin class methodsFor: 'accessing' stamp: 'tpr 7/2/2001 16:34'! requiresCrossPlatformFiles "If there cross platform files to be associated with the plugin, here is where you want to flag" ^true! ! !SoundGenerationPlugin class methodsFor: 'accessing' stamp: 'tpr 5/23/2001 17:11'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !SoundGenerationPlugin class methodsFor: 'accessing' stamp: 'tpr 4/9/2002 16:15'! translateInDirectory: directory doInlining: inlineFlag "handle a special case code string rather than generated code. NB sqOldSoundsPrims IS NOT FULLY INTEGRATED - it still isn't included in the exports list" | cg | self initialize. cg _ self buildCodeGeneratorUpTo: InterpreterPlugin. cg addMethodsForPrimitives: AbstractSound translatedPrimitives. self storeString: cg generateCodeStringForPrimitives onFileNamed: (directory fullNameFor: self moduleName, '.c'). "What we need here is some way to derive the prim names from sqOldSoundPrims - or dump it entirely. Perhaps add this class (without then generating the file again) using fake entry points like SurfacePlugin does" ^cg exportedPrimitiveNames asArray ! ! !StandardFileMenu methodsFor: 'private' stamp: 'rww 9/23/2001 09:54'! newFileFrom: aDirectory withPattern: aPattern canTypeFileName _ true. pattern _ aPattern. ^self makeFileMenuFor: aDirectory! ! !StandardFileMenu class methodsFor: 'instance creation' stamp: 'rww 9/23/2001 09:56'! newFileMenu: aDirectory withPattern: aPattern Smalltalk isMorphic ifFalse: [^ PluggableFileList newFileMenu: aDirectory]. ^ super new newFileFrom: aDirectory withPattern: aPattern! ! !StandardFileStream class methodsFor: 'file creation' stamp: 'tpr 10/21/2001 11:11'! forceNewFileNamed: fileName "Create a new file with the given name, and answer a stream opened for writing on that file. If the file already exists, delete it without asking before creating the new file." | dir localName fullName f | fullName _ self fullName: fileName. (self isAFileNamed: fullName) ifFalse: [f _ self new open: fullName forWrite: true. ^ f isNil ifTrue: ["Failed to open the file" (FileDoesNotExistException fileName: fullName) signal] ifFalse: [f]]. dir _ FileDirectory forFileName: fullName. localName _ FileDirectory localNameFor: fullName. dir deleteFileNamed: localName ifAbsent: [(CannotDeleteFileException new messageText: 'Could not delete the old version of file ' , fullName) signal]. f _ self new open: fullName forWrite: true. ^ f isNil ifTrue: ["Failed to open the file" (FileDoesNotExistException fileName: fullName) signal] ifFalse: [f]! ! !StandardFileStream class methodsFor: 'error handling' stamp: 'tpr 10/18/2001 19:08'! readOnlyFileDoesNotExistUserHandling: fullFileName | dir files choices selection newName fileName | dir _ FileDirectory forFileName: fullFileName. files _ dir fileNames. fileName _ FileDirectory localNameFor: fullFileName. choices _ fileName correctAgainst: files. choices add: 'Choose another name'. choices add: 'Cancel'. selection _ (PopUpMenu labelArray: choices lines: (Array with: 5) ) startUpWithCaption: (FileDirectory localNameFor: fullFileName), ' does not exist.'. selection = choices size ifTrue:["cancel" ^ nil "should we raise another exception here?"]. selection < (choices size - 1) ifTrue: [ newName _ (dir pathName , FileDirectory slash , (choices at: selection))]. selection = (choices size - 1) ifTrue: [ newName _ FillInTheBlank request: 'Enter a new file name' initialAnswer: fileName]. newName = '' ifFalse: [^ self readOnlyFileNamed: (self fullName: newName)]. ^ self error: 'Could not open a file'! ! !SurfacePlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:12'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !SurfacePlugin class methodsFor: 'translation' stamp: 'tpr 7/4/2001 15:15'! requiresCrossPlatformFiles "If there cross platform files to be associated with the plugin, here is where you want to flag" ^true! ! !SurfacePlugin class methodsFor: 'translation' stamp: 'tpr 4/9/2002 16:15'! translateInDirectory: directory doInlining: inlineFlag "handle a special case external file rather than normal generated code." | cg | self initialize. cg _ self buildCodeGeneratorUpTo: self. "We rely on the fake entry points implemented on the instance side to allow the export list to be accurate. Please update them if you change the code" ^cg exportedPrimitiveNames asArray! ! !SystemDictionary methodsFor: 'miscellaneous' stamp: 'JMM 5/29/2001 11:55'! osVersion "Return the version number string of the platform we're running on" ^(self getSystemAttribute: 1002) asString! ! !SystemDictionary methodsFor: 'miscellaneous' stamp: 'JMM 5/29/2001 11:56'! platformSubtype "Return the subType of the platform we're running on" ^self getSystemAttribute: 1003! ! !TestInterpreterPlugin class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:20'! shouldBeTranslated "TestInterpreterPlugin should not be translated but its subclasses should" ^self ~= TestInterpreterPlugin! ! !AsynchFilePlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:04'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !AsynchFilePlugin class methodsFor: 'translation' stamp: 'tpr 11/29/2000 22:37'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !FileCopyPlugin class methodsFor: 'translation' stamp: 'tpr 4/27/2001 11:02'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !FlippyArrayPlugin2 class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:32'! shouldBeTranslated "This class should not be translated" ^false! ! !FooPlugin2 class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:10'! shouldBeTranslated "This class should not be translated" ^false! ! !JPEGReadWriter2Plugin class methodsFor: 'translation' stamp: 'tpr 3/1/2002 17:03'! requiresCrossPlatformFiles "default is ok for most, any plugin needing cross platform files must say so" ^true! ! !JPEGReadWriter2Plugin class methodsFor: 'translation' stamp: 'JMM 10/3/2001 11:48'! requiresPlatformFiles "default is ok for most, any plugin needing platform specific files must say so" ^true! ! !JoystickTabletPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:08'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !JoystickTabletPlugin class methodsFor: 'translation' stamp: 'tpr 3/26/2002 15:22'! requiresPlatformFiles " this plugin requires platform specific files in order to work" ^true! ! !MIDIPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:10'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !MIDIPlugin class methodsFor: 'translation' stamp: 'tpr 11/29/2000 22:38'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !Mpeg3Plugin class methodsFor: 'initialize-release' stamp: 'tpr 5/23/2001 17:10'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !Mpeg3Plugin class methodsFor: 'initialize-release' stamp: 'tpr 7/4/2001 15:13'! requiresCrossPlatformFiles "If there cross platform files to be associated with the plugin, here is where you want to flag" ^true! ! !Mpeg3Plugin class methodsFor: 'initialize-release' stamp: 'tpr 3/13/2002 18:05'! requiresPlatformFiles "If there platform files to be associated with the plugin, here is where you want to flag" ^true! ! !SerialPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:11'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !SerialPlugin class methodsFor: 'translation' stamp: 'tpr 11/29/2000 22:38'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !SocketPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:11'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !SocketPlugin class methodsFor: 'translation' stamp: 'tpr 11/29/2000 22:38'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !SoundPlugin class methodsFor: 'translation' stamp: 'tpr 5/23/2001 17:12'! hasHeaderFile "If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag" ^true! ! !SoundPlugin class methodsFor: 'translation' stamp: 'tpr 11/29/2000 22:38'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !TIPTestPlugin class methodsFor: 'translation' stamp: 'tpr 5/14/2001 12:16'! shouldBeTranslated "This should not be translated" ^false! ! !TestOSAPlugin class methodsFor: 'translation' stamp: 'JMM 5/30/2001 19:43'! requiresPlatformFiles "this plugin requires platform specific files in order to work" ^true! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 4/1/2002 12:13'! initialize logger := Transcript. inline _ true. forBrowser _ false. internalPlugins _ SortedCollection new. externalPlugins _ SortedCollection new. platformName _ self class machinesDirName. allFilesList _ Dictionary new! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/16/2001 09:54'! initializeAllExternal "add all the plugins to the external list and make sure the internal list is empty" self initializeInternal: #() external: self availablePlugins ! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/16/2001 09:54'! initializeAllExternalBut: arrayOfInternalPluginNames "add all the plugins to the external list except for those listed, which should be added to the internal list" self initializeInternal: arrayOfInternalPluginNames external: (self availablePlugins copyWithoutAll: arrayOfInternalPluginNames )! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/16/2001 09:54'! initializeAllInternal "add all the plugins to the internal list and make sure the external list is empty" self initializeInternal: self availablePlugins external: #()! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/16/2001 09:54'! initializeAllInternalBut: arrayOfExternalPluginNames "add all the plugins to the internal list except for those listed, which should be added to the external list" self initializeInternal: (self availablePlugins copyWithoutAll: arrayOfExternalPluginNames) external: arrayOfExternalPluginNames! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/11/2001 13:00'! initializeAllPlugins allPlugins _ self providedPlugins! ! !VMMaker methodsFor: 'initialize'! initializeInternal: arrayOfInternalPluginNames external: arrayOfExternalPluginNames "try to set up with the listed internal and external plugins." self initialize. self internal: arrayOfInternalPluginNames external: arrayOfExternalPluginNames! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/16/2001 12:05'! internal: arrayOfInternalPluginNames external: arrayOfExternalPluginNames "try to set up with the listed internal and external plugins. Check that they are supportable plugins, reject those that are not - remember that this depends on the platform etc " "since we went to some trouble to drop plugins we cannot handle, don't add them now" internalPlugins _ (allPlugins intersection: arrayOfInternalPluginNames) select: [:pl | self canSupportPlugin: pl]. allPlugins _ allPlugins copyWithoutAll: internalPlugins. externalPlugins _ (allPlugins intersection: arrayOfExternalPluginNames) select: [:pl | self canSupportPlugin: pl ]. allPlugins _ allPlugins copyWithoutAll: externalPlugins. ! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/12/2001 15:40'! providedPlugins "generate the list by asking the InterpreterPlugins" ^ ((InterpreterPlugin allSubclasses select: [:cl | cl shouldBeTranslated]) collect: [:cl | cl name]) asSortedCollection! ! !VMMaker methodsFor: 'initialize' stamp: 'tpr 10/11/2001 12:53'! setPlatName: aString "private - just set the platform name string, nothing else. Go away...." platformName _ aString! ! !VMMaker methodsFor: 'plugin lists' stamp: 'ar 4/7/2002 13:09'! allModuleNames "return the list of all the all plugins' moduleNames" ^Array streamContents:[:strm| self allPluginsDo:[:pl| strm nextPut: pl moduleName ]]! ! !VMMaker methodsFor: 'plugin lists' stamp: 'ar 4/7/2002 13:10'! allPluginsDo: aBlock "for each class that should be an external plugin, evaluate aBlock" self externalPluginsDo: aBlock. self internalPluginsDo: aBlock.! ! !VMMaker methodsFor: 'plugin lists' stamp: 'tpr 3/13/2002 15:56'! canSupportPlugin: pluginClassName "see if this plugin needs any external files and if so, check to see if they seem to exist." [self validatePlugin: pluginClassName in: allPlugins , internalPlugins , externalPlugins] on: VMMakerException do: [^ false]. ^ true! ! !VMMaker methodsFor: 'plugin lists' stamp: 'tpr 7/2/2001 16:29'! externalFilesRequiredFor: plugin ^plugin requiresCrossPlatformFiles or:[plugin requiresPlatformFiles]! ! !VMMaker methodsFor: 'plugin lists' stamp: 'tpr 3/26/2002 18:34'! externalModuleNames "return the list of all the external plugins' moduleNames" ^Array streamContents:[:strm| self externalPluginsDo:[:pl| strm nextPut: pl moduleName ]]! ! !VMMaker methodsFor: 'plugin lists' stamp: 'tpr 1/24/2001 12:53'! externalPluginsDo: aBlock "for each class that should be an external plugin, evaluate aBlock" self plugins: externalPlugins do: aBlock! ! !VMMaker methodsFor: 'plugin lists' stamp: 'tpr 3/26/2002 18:36'! internalModuleNames "return the list of all the internal plugins' moduleNames" ^Array streamContents:[:strm| self internalPluginsDo:[:pl| strm nextPut: pl moduleName ]]! ! !VMMaker methodsFor: 'plugin lists' stamp: 'tpr 1/24/2001 12:53'! internalPluginsDo: aBlock "for each class that should be an internal plugin, evaluate aBlock" self plugins: internalPlugins do: aBlock! ! !VMMaker methodsFor: 'plugin lists' stamp: 'tpr 1/24/2001 11:57'! plugins: aCollection do: aBlock "for each class in aCollection that should be a plugin, evaluate aBlock" aCollection do: [:sym | (Smalltalk hasClassNamed: sym) ifTrue: [aBlock value: (Smalltalk classNamed: sym)] ifFalse:["Another place to raise a sensible error to the UI" ^self couldNotFindPluginClass: sym]]! ! !VMMaker methodsFor: 'private - copying files' stamp: 'ar 4/7/2002 15:59'! copyFileNamed: srcName to: dstName | dstEntry srcEntry | dstEntry _ FileDirectory directoryEntryFor: dstName. dstEntry ifNotNil:[ srcEntry _ FileDirectory directoryEntryFor: srcName. srcEntry ifNil:[^self couldNotOpenFile: srcName]. dstEntry modificationTime >= srcEntry modificationTime ifTrue:[^self]. ]. logger show:'==> ', dstName; cr. ^self primitiveCopyFileNamed: srcName to: dstName ! ! !VMMaker methodsFor: 'private - copying files' stamp: 'tpr 2/11/2002 15:11'! copyFilesFrom: srcDir to: dstDir "This really ought to be a facility in file system. The major annoyance here is that file types and permissions are not handled by current Squeak code" [srcDir fileNames do: [:filenm | self copyFileNamed: (srcDir fullNameFor: filenm) to: (dstDir fullNameFor: filenm)]] on: InvalidDirectoryError do:["do nothing if the directory is invalid"] ! ! !VMMaker methodsFor: 'private - copying files' stamp: 'tpr 2/11/2002 15:10'! copyFilesFromSourceDirectory: srcDir toTargetDirectory: dstDir "copy all the files and directories from srcDir to dstDir, recursively" self copyFilesFromSourceDirectory: srcDir toTargetDirectory: dstDir recursively: true! ! !VMMaker methodsFor: 'private - copying files' stamp: 'ar 3/10/2002 15:02'! copyFilesFromSourceDirectory: srcDir toTargetDirectory: dstDir recursively: recurseBoolean "copy all files and subdirectories from srcDir to dstDir, optionally recursing down the tree. It is assumed that both directories already exist and have appropriate permissions - proper error handling ought to be provided sometime. Note how nice it would be if the file system classes already did this; why, they could even defer to an improved file plugin for some of these things." "copy all the files" | dirList | srcDir localName = 'CVS' ifTrue:[logger show: 'CVS files NOT copied by VMMaker'; cr. ^self]. self copyFilesFrom: srcDir to: dstDir. recurseBoolean ifFalse:[^self]. "If we are recursing create the subdirectories of srcDir in dstDir, and then copy that subtree " dirList _ srcDir directoryNames copyWithout: 'CVS'. dirList do: [:newDstDir | (dstDir directoryExists: newDstDir) ifFalse: [dstDir createDirectory: newDstDir]. self copyFilesFromSourceDirectory: (srcDir directoryNamed: newDstDir) toTargetDirectory: (dstDir directoryNamed: newDstDir) recursively: true]! ! !VMMaker methodsFor: 'private - copying files' stamp: 'tpr 4/10/2002 19:38'! primitiveCopyFileNamed: srcName to: dstName "This really ought to be a facility in file system. The major annoyance here is that file types and permissions are not handled by current Squeak code" | buffer src dst | "primitiveExternalCall" "If the plugin doesn't do it, go the slow way and lose the filetype info" "This method may signal FileDoesNotExistException if either the source or dest files cannnot be opened; possibly permissions or bad name problems" [[src _ FileStream readOnlyFileNamed: srcName] on: FileDoesNotExistException do: [^ self couldNotOpenFile: srcName]. [dst _ FileStream forceNewFileNamed: dstName] on: FileDoesNotExistException do: [^ self couldNotOpenFile: dstName]. buffer _ String new: 50000. [src atEnd] whileFalse: [dst nextPutAll: (src nextInto: buffer)]] ensure: [src ifNotNil: [src close]. dst ifNotNil: [dst close]]! ! !VMMaker methodsFor: 'copying files' stamp: 'tpr 2/11/2002 14:50'! copyAssortedFiles "copy any miscellaneous files/dirs from the cross-platformDirectory/misc/ToCopy - general readme files etc, then from the platform specific directory/misc/ToCopy - makefiles, utils etc that have to be copied." | srcDir | "Is there a crossPlatformDirectory subdirectory called 'misc'?" (self crossPlatformDirectory directoryExists: 'misc') ifTrue: [srcDir _ self crossPlatformDirectory directoryNamed: 'misc'. "Is there a subdirectory called 'ToCopy' ?" (srcDir directoryExists: 'ToCopy') ifTrue:[ srcDir _ srcDir directoryNamed: 'ToCopy'. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: self sourceDirectory]]. "Is there a platformDirectory subdirectory called 'misc'?" (self platformDirectory directoryExists: 'misc') ifTrue: [srcDir _ self platformDirectory directoryNamed: 'misc'. "Is there a subdirectory called 'ToCopy' ?" (srcDir directoryExists: 'ToCopy') ifTrue:[ srcDir _ srcDir directoryNamed: 'ToCopy'. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: self sourceDirectory]]! ! !VMMaker methodsFor: 'generate sources' stamp: 'ar 4/7/2002 15:54'! generateEntire "generate the interp, internal plugins and exports as well as the external plugins" self generateMainVM. self generateExternalPlugins. ! ! !VMMaker methodsFor: 'generate sources' stamp: 'tpr 4/9/2002 16:15'! generateExternalPlugin: pluginName "generate the named external plugin" | exports plugin | "Refuse to translate this plugin if it requires platform specific files and they are not present." [plugin _ self validateExternalPlugin: pluginName] on: VMMakerException do:[^self]. exports _ plugin translateInDirectory: (self externalPluginsDirectoryFor: plugin) doInlining: inline. logger show: 'external plugin ' , plugin name , ' generated as ' , plugin moduleName; cr. exports ifNotNil: ["if exp is nil we skip this since the plugin was already up to date" self export: exports forExternalPlugin: plugin]. self processFilesForExternalPlugin: plugin! ! !VMMaker methodsFor: 'generate sources' stamp: 'ar 4/7/2002 13:05'! generateExternalPlugins "generate the external plugins" self deleteUnwantedExternalPluginDirectories. self externalPluginsDo: [:plugin | self generateExternalPlugin: plugin]. self storeExternalPluginList.! ! !VMMaker methodsFor: 'generate sources' stamp: 'tpr 3/27/2002 15:01'! generateInternalPlugin: pluginName "generate the named internal plugin. Make sure the exports list is actually correct and write it out" self deleteUnwantedInternalPluginDirectories. self privateGenerateInternalPlugin: pluginName. self generateExportsFile! ! !VMMaker methodsFor: 'generate sources' stamp: 'ar 4/7/2002 13:06'! generateInternalPlugins "generate the internal plugins and add their exports to the main list. te exports list is NOT written to file by this method" self deleteUnwantedInternalPluginDirectories. self internalPluginsDo: [:plugin | self privateGenerateInternalPlugin: plugin]. self storeInternalPluginList.! ! !VMMaker methodsFor: 'generate sources' stamp: 'ar 4/7/2002 12:49'! generateInterpreterFile "generate the main 'interp.c' file for the interpreter and the list of export statments" Interpreter translateInDirectory: self coreVMDirectory doInlining: inline forBrowserPlugin: forBrowser.! ! !VMMaker methodsFor: 'generate sources' stamp: 'tpr 3/4/2002 10:38'! generateMainVM "generate the interp, internal plugins and exports" self generateInterpreterFile; processFilesForCoreVM; processAssortedFiles; generateInternalPlugins; generateExportsFile! ! !VMMaker methodsFor: 'generate sources' stamp: 'tpr 4/9/2002 16:15'! privateGenerateInternalPlugin: pluginName "generate the named internal plugin" | plugin | "Refuse translate this plugin if it requires platform specific files and they are not present." plugin _ self validateInternalPlugin: pluginName. plugin ifNil: [^ self couldNotFindPluginClass: pluginName]. plugin translateInDirectory: (self internalPluginsDirectoryFor: plugin) doInlining: inline. logger show: 'internal plugin ' , plugin name , ' generated as ' , plugin moduleName; cr. self processFilesForInternalPlugin: plugin. ! ! !VMMaker methodsFor: 'generate sources' stamp: 'tpr 10/17/2001 13:15'! validateExternalPlugin: plName ^self validatePlugin: plName in: externalPlugins! ! !VMMaker methodsFor: 'generate sources' stamp: 'tpr 10/17/2001 13:15'! validateInternalPlugin: plName ^self validatePlugin: plName in: internalPlugins! ! !VMMaker methodsFor: 'generate sources' stamp: 'tpr 3/13/2002 15:29'! validatePlugin: plName in: listOfPlugins "check that the plName is either an actual plugin class or a plugin class name. Return the plugin class or raise an error if nil" | plugin | plName isString ifTrue: [(listOfPlugins includes: plName) ifTrue: [plugin _ Smalltalk classNamed: plName]] ifFalse: [((plName isBehavior and: [plName inheritsFrom: InterpreterPlugin]) and: [listOfPlugins includes: plName name]) ifTrue: [plugin _ plName]]. plugin ifNil: [^ self couldNotFindPluginClass: plName]. "Is there a cross-platform or platform files directory of the same name as this plugin?" plugin requiresPlatformFiles ifTrue: [(self platformPluginsDirectory directoryExists: plugin moduleName) ifFalse: [logger show: 'No platform specific files found for ' , plugin moduleName printString; cr. ^ self couldNotFindPlatformFilesFor: plugin]]. plugin requiresCrossPlatformFiles ifTrue: [(self crossPlatformPluginsDirectory directoryExists: plugin moduleName) ifFalse: [logger show: 'No cross platform files found for ' , plugin moduleName printString; cr. ^ self couldNotFindPlatformFilesFor: plugin]]. ^plugin! ! !VMMaker methodsFor: 'source directories' stamp: 'tpr 1/9/2002 20:35'! crossPlatformDirectory "return the directory where we should find the cross-platform literal sources - etc" | fd machDirNm | fd _ self platformRootDirectory. (fd directoryExists: (machDirNm _ 'Cross')) ifFalse: ["The supposed directory for the actual cross-platform code does not exist." ^ self couldNotFindPlatformDirectoryFor: 'cross-platform ']. ^ fd directoryNamed: machDirNm! ! !VMMaker methodsFor: 'source directories' stamp: 'tpr 10/18/2001 19:43'! crossPlatformPluginsDirectory "return the directory where we should find the cross-platform plugin specific sources" (self crossPlatformDirectory directoryExists: self class pluginsDirName) ifFalse: ["The supposed directory for the plugins code does not exist. We need to raise a suitable exception, but cant think of one right now." ^self couldNotFindPlatformDirectoryFor: 'any plugins needing cross-platform']. ^self crossPlatformDirectory directoryNamed: self class pluginsDirName! ! !VMMaker methodsFor: 'source directories' stamp: 'tpr 1/9/2002 20:35'! platformDirectory "return the directory where we should find the platform specific sources" | fd platNm | fd _ self platformRootDirectory. (fd directoryExists: (platNm _ self platformName)) ifFalse: ["The supposed directory for the actual platform code does not exist." ^ self couldNotFindPlatformDirectoryFor: platNm]. ^ fd directoryNamed: platNm! ! !VMMaker methodsFor: 'source directories' stamp: 'tpr 10/18/2001 19:46'! platformPluginsDirectory "return the directory where we should find the platform plugin specific sources" (self platformDirectory directoryExists: self class pluginsDirName) ifFalse: ["The supposed directory for the plugins code does not exist. We need to raise a suitable exception, but cant think of one right now." ^self couldNotFindPlatformDirectoryFor: 'any plugins needing ', self platformName]. ^self platformDirectory directoryNamed: self class pluginsDirName! ! !VMMaker methodsFor: 'source directories' stamp: 'tpr 1/9/2002 20:33'! platformRootDirectory "return the directory where we should find all platform's sources" (FileDirectory default directoryExists: (platformRootDirName ifNil: [self class platformsDirName])) ifFalse: ["The supposed directory for the platforms code does not exist." ^ self couldNotFindDirectory: 'the platform code tree']. ^ FileDirectory default directoryNamed: (platformRootDirName ifNil: [self class platformsDirName])! ! !VMMaker methodsFor: 'source directories' stamp: 'tpr 1/9/2002 20:28'! platformRootDirectoryName: aString "set the directory where we should find all platform's sources There really ought to be plausible sanity checks done here" platformRootDirName _ aString. (FileDirectory default directoryExists: aString) ifFalse:[self couldNotFindDirectory: aString. ^false]. self reinitializePluginsLists. ^true! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 2/14/2002 14:27'! coreVMDirectory "return the target directory for the main VM sources, interp.c etc" | fd | fd _ self sourceDirectory directoryNamed: self class coreVMDirName. fd assureExistence. ^ fd! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 3/27/2002 15:19'! deleteEntireGeneratedTree "remove all the files - all of them I say" self sourceDirectory recursiveDelete! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 3/26/2002 18:34'! deleteUnwantedExternalPluginDirectories "delete directories in the external plugins tree with names not in the list of external plugins. This will make sure that only wanted plugins are left after generating external plugins - no previous ones will get left there like unwanted porridge" (self externalPluginsDirectory directoryNames copyWithoutAll: self externalModuleNames) do: [:nm | (self externalPluginsDirectory directoryNamed: nm) recursiveDelete]! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 3/26/2002 18:37'! deleteUnwantedInternalPluginDirectories "delete directories in the internal plugins tree with names not in the list of internal plugins. This will make sure that only wanted plugins are left after generating internal plugins - no previous ones will get left there like unwanted porridge" (self internalPluginsDirectory directoryNames copyWithoutAll: self internalModuleNames) do: [:nm | (self internalPluginsDirectory directoryNamed: nm) recursiveDelete]! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 2/14/2002 14:27'! externalPluginsDirectory "return the target directory for the external plugins sources" | fd | fd _ self sourceDirectory directoryNamed: self class pluginsDirName. fd assureExistence. ^fd! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 2/14/2002 14:27'! externalPluginsDirectoryFor: plugin "return the directory for the external plugin sources" |fd| fd _ self externalPluginsDirectory directoryNamed: plugin moduleName. fd assureExistence. ^fd! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 2/14/2002 14:27'! internalPluginsDirectory "return the directory for the internal plugins sources" |fd| fd _ self coreVMDirectory directoryNamed: 'intplugins'. fd assureExistence. ^fd! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 2/14/2002 14:27'! internalPluginsDirectoryFor: plugin "return the directory for the internal plugin sources" |fd| fd _ self internalPluginsDirectory directoryNamed: plugin moduleName. fd assureExistence. ^fd! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 4/9/2002 17:34'! makefileDirectory "where to put generated makefile related files" ^self sourceDirectory! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 2/14/2002 14:17'! sourceDirectory | fd | fd _ FileDirectory default directoryNamed: (sourceDirName ifNil: [self class sourceDirName]). fd assureExistence. ^ fd! ! !VMMaker methodsFor: 'target directories' stamp: 'tpr 2/14/2002 14:27'! sourceDirectoryName: aString "Sanity check really ought to be added, This is the root directory for where the sources will be WRITTEN" sourceDirName _ aString. (FileDirectory on: aString) assureExistence. self changed: #sourceDirectory. ^true! ! !VMMaker methodsFor: 'exports' stamp: 'tpr 4/20/2001 16:35'! export: exportList forExternalPlugin: aPlugin "it may be useful on certain platforms to do something with the export list of external plugins, just as the internal plugins' exports get added to the VM list. Default is to do nothing though."! ! !VMMaker methodsFor: 'exports' stamp: 'ar 4/7/2002 12:48'! generateExportsFile ^self storeExportsOn:(self coreVMDirectory fullNameFor: 'sqNamedPrims.h'). ! ! !VMMaker methodsFor: 'exports' stamp: 'ar 4/7/2002 12:48'! storeExportsOn: aFilename "Store the exports on the given file" | s | [s _ CrLfFileStream forceNewFileNamed: aFilename] on: FileDoesNotExistException do:[^self couldNotOpenFile: aFilename]. s nextPutAll:'/* This is an automatically generated table of all builtin modules in the VM */'; cr. s cr; nextPutAll:'extern sqExport vm_exports[];'. s cr; nextPutAll: 'extern sqExport os_exports[];'. self internalPluginsDo:[:cls| s cr; nextPutAll: 'extern sqExport '; nextPutAll: cls moduleName; nextPutAll:'_exports[];'. ]. s cr. s cr; nextPutAll:'sqExport *pluginExports[] = {'. s crtab; nextPutAll:'vm_exports,'. s crtab; nextPutAll: 'os_exports,'. self internalPluginsDo:[:cls| s crtab; nextPutAll: cls moduleName; nextPutAll:'_exports,' ]. s crtab; nextPutAll:'NULL'. s cr; nextPutAll:'};'; cr. s close! ! !VMMaker methodsFor: 'exports' stamp: 'tpr 4/9/2002 17:47'! storeExternalPluginList | s fileName | fileName _ self makefileDirectory fullNameFor: 'plugins.ext'. [s _ CrLfFileStream forceNewFileNamed: fileName] on: FileDoesNotExistException do:[^self couldNotOpenFile: fileName]. s nextPutAll:'# Automatically generated makefile include for external plugins'. s cr; nextPutAll:'EXTERNAL_PLUGINS ='. self externalPluginsDo:[:cls| s space; nextPutAll: cls moduleName. ]. s cr; close! ! !VMMaker methodsFor: 'exports' stamp: 'tpr 4/9/2002 17:35'! storeInternalPluginList | s fileName | fileName _ self makefileDirectory fullNameFor: 'plugins.int'. [s _ CrLfFileStream forceNewFileNamed: fileName] on: FileDoesNotExistException do:[^self couldNotOpenFile: fileName]. s nextPutAll:'# Automatically generated makefile include for internal plugins'. s cr; nextPutAll:'INTERNAL_PLUGINS ='. self internalPluginsDo:[:cls| s space; nextPutAll: cls moduleName. ]. s cr; close! ! !VMMaker methodsFor: 'objects from disk' stamp: 'tpr 10/11/2001 13:20'! configurationInfo "build a simple Array of the configuration information that would be usefully saved for later reloading:- the list of internal & external plugins, the flags, the platform name, and the two major directory names" ^ Array new writeStream nextPut: internalPlugins; nextPut: externalPlugins; nextPut: inline; nextPut: forBrowser; nextPut: platformName; nextPut: self sourceDirectory pathName; nextPut: self platformRootDirectory pathName; contents! ! !VMMaker methodsFor: 'objects from disk' stamp: 'tpr 10/12/2001 16:33'! loadConfiguration: aConfigArray "load the configuration but ignore the platformName - the platform name must have been handled during the creation of this vmmaker in order for it to work correctly" inline _ aConfigArray at:3. forBrowser _ aConfigArray at: 4. "This part must be ignored --> self setPlatName: (aConfigArray at: 5)." self sourceDirectoryName: (aConfigArray at: 6). self platformRootDirectoryName: ( aConfigArray at:7). self initializeAllPlugins. self internal: (aConfigArray at:1) external:(aConfigArray at:2). self changed: #reinitialize ! ! !VMMaker methodsFor: 'objects from disk' stamp: 'tpr 5/14/2001 15:07'! readConfigurationFrom: aFileName "read info about the current configuration from a file. Return the array that would have been made by #configurationInfo" | fileStream | fileStream _ FileStream oldFileNamed: aFileName. ^fileStream fileInObjectAndCode! ! !VMMaker methodsFor: 'objects from disk' stamp: 'rww 9/23/2001 09:49'! saveConfigurationTo: aFile "write info about the current configuration to a file." | fileStream | fileStream _ FileStream newFileNamed: aFile. fileStream fileOutClass: nil andObject: self configurationInfo! ! !VMMaker methodsFor: 'private - errors' stamp: 'tpr 10/21/2001 11:13'! couldNotFindDirectory: dirName "This should raise a nice exception to a UI" (VMMakerException new messageText: self class name, ' could not find directory ', dirName) signal! ! !VMMaker methodsFor: 'private - errors' stamp: 'tpr 10/18/2001 19:41'! couldNotFindPlatformDirectoryFor: platName "This should raise a nice exception to a UI" self couldNotFindDirectory: 'for: ', platName, ' specific files; is the platform root path set correctly?'! ! !VMMaker methodsFor: 'private - errors' stamp: 'tpr 10/21/2001 11:14'! couldNotFindPlatformFilesFor: plugin "This should raise a nice exception to a UI" (VMMakerException new messageText: self class name, ' could not find platform specific files for: ', plugin moduleName) signal! ! !VMMaker methodsFor: 'private - errors' stamp: 'tpr 10/21/2001 11:15'! couldNotFindPluginClass: pluginSymbol "This should raise a nice exception to a UI" (VMMakerException new messageText: self class name, ' could not find the class for: ', pluginSymbol) signal! ! !VMMaker methodsFor: 'private - errors' stamp: 'tpr 10/21/2001 11:12'! couldNotOpenFile: fileName "This should raise a nice exception to a UI" (VMMakerException new messageText: self class name, ' could not open file: ', fileName) signal! ! !VMMaker methodsFor: 'UI access'! availablePlugins allPlugins ifNil:[self initializeAllPlugins]. ^allPlugins! ! !VMMaker methodsFor: 'UI access'! externalModules ^externalPlugins! ! !VMMaker methodsFor: 'UI access'! internalModules ^internalPlugins! ! !VMMaker methodsFor: 'UI access' stamp: 'tpr 10/12/2001 15:34'! listOfName: aSymbol "work out which list is the one associated with this symbol" #availableModules = aSymbol ifTrue:[^allPlugins]. #internalModules = aSymbol ifTrue:[^internalPlugins]. #externalModules =aSymbol ifTrue:[^externalPlugins]. ^nil! ! !VMMaker methodsFor: 'UI access' stamp: 'ar 3/10/2002 15:02'! logger ^logger! ! !VMMaker methodsFor: 'UI access' stamp: 'ar 3/10/2002 15:02'! logger: aStream logger := aStream.! ! !VMMaker methodsFor: 'UI access' stamp: 'tpr 10/16/2001 09:56'! makeAllModulesAvailable self internal: #() external: #(). self reinitializePluginsLists! ! !VMMaker methodsFor: 'UI access' stamp: 'tpr 10/16/2001 12:10'! makeAllModulesExternal self initializeAllPlugins. self internal: #() external: self availablePlugins. self changed: #reinitialize ! ! !VMMaker methodsFor: 'UI access' stamp: 'tpr 10/16/2001 12:10'! makeAllModulesInternal self initializeAllPlugins. self internal: self availablePlugins external: #(). self changed: #reinitialize ! ! !VMMaker methodsFor: 'UI access' stamp: 'tpr 10/12/2001 15:35'! movePlugin: pluginName from: srcListName to: dstListName "the VMMakerTool UI has been used to drag a plugin from one list to another " "we need to do some tests - are the lists actually ours? is the plugin ours? is the destination list one where we must check the plugin for acceptability? return true if all is ok, false otherwise" | dstList srcList | dstList _ self listOfName: dstListName. srcList _ self listOfName: srcListName. dstList == allPlugins ifTrue: [dstList add: (srcList remove: pluginName)] ifFalse: ["the dest must be internal or external, so check the plugin for acceptability " (self canSupportPlugin: pluginName) ifTrue: [dstList add: (srcList remove: pluginName)]]! ! !VMMaker methodsFor: 'UI access'! platformName ^platformName! ! !VMMaker methodsFor: 'UI access' stamp: 'tpr 10/11/2001 13:06'! reinitializePluginsLists "something has changed that affects the validity of the plugin lists. Recalculate them as best we can. It is probably possible to check on the current lists and keep the configuration as close as possible the same; but for the moment just try to use the same lists " self initializeAllPlugins. self internal: internalPlugins external: externalPlugins. self changed: #reinitialize ! ! !VMMaker methodsFor: 'processing external files' stamp: 'tpr 3/13/2002 14:25'! processAssortedFiles "Here is where we get a chance to process any files needed as part of the make process; instructions, makefile fragments, resources etc. The default is to copy any miscellaneous files/dirs from the cross-platformDirectory/misc/ToCopy, then from the platform specific directory/misc/ToCopy. You can put any tree structure you like under misc/ToCopy, should that be important to you." | srcDir | "Is there a crossPlatformDirectory subdirectory called 'misc'?" (self crossPlatformDirectory directoryExists: 'misc') ifTrue: [srcDir _ self crossPlatformDirectory directoryNamed: 'misc'. "Is there a subdirectory called 'ToCopy' ?" (srcDir directoryExists: 'ToCopy') ifTrue:[ srcDir _ srcDir directoryNamed: 'ToCopy'. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: self sourceDirectory]]. "Is there a platformDirectory subdirectory called 'misc'?" (self platformDirectory directoryExists: 'misc') ifTrue: [srcDir _ self platformDirectory directoryNamed: 'misc'. "Is there a subdirectory called 'ToCopy' ?" (srcDir directoryExists: 'ToCopy') ifTrue:[ srcDir _ srcDir directoryNamed: 'ToCopy'. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: self sourceDirectory]]! ! !VMMaker methodsFor: 'processing external files' stamp: 'tpr 4/1/2002 12:12'! processFilesForCoreVM "process any cross-platform files from the crossPlatformDir and then any files relating to the core vm from the platformDirectory's vm subdirectory." "This is a stub ready for collecting all the filenames etc that might be needed to write a makefile. No details are yet certain." | vmDirName fList | vmDirName _ self class coreVMDirName. fList _ OrderedCollection new. {self crossPlatformDirectory directoryNamed: vmDirName. self platformDirectory directoryNamed: vmDirName. self coreVMDirectory} do:[:dir| fList addAll: (dir fullNamesOfAllFilesInSubtree reject:[:el| (el findString: 'CVS' startingAt: 1) ~= 0])]. allFilesList at: 'vm' put: fList ! ! !VMMaker methodsFor: 'processing external files' stamp: 'tpr 4/1/2002 12:09'! processFilesForExternalPlugin: plugin "process any files relating to the external plugin. This also provides a stub ready for collecting all the filenames etc that might be needed to write a makefile, carefully weeding out any CVS related files. No details are yet certain." |fList| fList _ OrderedCollection new. {self crossPlatformPluginsDirectory directoryNamed: plugin moduleName. self platformPluginsDirectory directoryNamed: plugin moduleName. self externalPluginsDirectoryFor: plugin} do:[:dir| fList addAll: (dir fullNamesOfAllFilesInSubtree reject:[:el| (el findString: 'CVS' startingAt: 1) ~= 0])]. allFilesList at: plugin moduleName put: fList! ! !VMMaker methodsFor: 'processing external files' stamp: 'tpr 4/1/2002 12:10'! processFilesForInternalPlugin: plugin "process any files relating to the internal plugin. This also provides a stub ready for collecting all the filenames etc that might be needed to write a makefile, carefully weeding out any CVS related files. No details are yet certain." |fList| fList _ OrderedCollection new. {self crossPlatformPluginsDirectory directoryNamed: plugin moduleName. self platformPluginsDirectory directoryNamed: plugin moduleName. self internalPluginsDirectoryFor: plugin} do:[:dir| fList addAll: (dir fullNamesOfAllFilesInSubtree reject:[:el| (el findString: 'CVS' startingAt: 1) ~= 0])]. allFilesList at: plugin moduleName put: fList! ! !MacOSPowerPCOS9BrowserVMMaker methodsFor: 'initialize' stamp: 'JMM 5/30/2001 18:12'! initialize super initialize. forBrowser _ true! ! !RiscOSVMMaker methodsFor: 'generate sources' stamp: 'tpr 2/14/2002 14:27'! export: exportList forExternalPlugin: aPlugin "it may be useful on certain platforms to do something with the export list of external plugins, just as the internal plugins' exports get added to the VM list. Default is to do nothing though." "For RiscOS using the 'rink' external linker each plugin needs a 'dsc' file that looks like id:SqueakSO main_version:100 code_version:001 entries: // named_entries: getModuleName // with all the exported names in the list. We also need a '/o' directory for the object files" "open a file called plugindir/pluginname.dsc and write into it" | f fd| fd _ self externalPluginsDirectoryFor: aPlugin. "If we get an error to do with opening the .dsc file, we need to raise an application error to suit" [f _ CrLfFileStream forceNewFileNamed: (fd fullNameFor: aPlugin moduleName, '.dsc')] on: FileStreamException do:[^self couldNotOpenFile: (fd fullNameFor: aPlugin moduleName, '.dsc')]. f nextPutAll: 'id:SqueakSO main_version:100 code_version:001 entries: // named_entries: '. exportList do:[:el| f nextPutAll: el. f cr]. f nextPutAll: '//'; cr. f close. (fd directoryNamed: 'o') assureExistence ! ! !VMMaker class methodsFor: 'initialisation'! activeVMMakerClassFor: platformName "Return the concrete VMMaker subclass for the platform on which we are currently running." VMMaker allSubclasses do: [:class | (class isActiveVMMakerClassFor: platformName) ifTrue: [^ class]]. "no responding subclass; use VMMaker" ^ VMMaker ! ! !VMMaker class methodsFor: 'initialisation'! default "return a VMMaker initialised to build a default no-internal-plugins, no-external-plugins vm codebase" ^self forPlatform: Smalltalk platformName! ! !VMMaker class methodsFor: 'initialisation' stamp: 'tpr 10/12/2001 17:59'! forConfigurationFile: aFileName | config fileStream vmMaker | fileStream _ FileStream oldFileNamed: aFileName. config _ fileStream fileInObjectAndCode. vmMaker _ self forPlatform: (config at: 5). vmMaker loadConfiguration: config. ^vmMaker! ! !VMMaker class methodsFor: 'initialisation'! forPlatform: platformName "return a VMMaker initialised to build a default no-internal-plugins, no-external-plugins vm codebase" ^(self activeVMMakerClassFor: platformName) new initialize setPlatName: platformName! ! !VMMaker class methodsFor: 'initialisation' stamp: 'tpr 10/21/2001 11:28'! initialize "VMMaker initialize" DirNames _ Dictionary new. DirNames at: #coreVMDir put: 'vm'; at: #platformsDir put: 'platforms'; at: #pluginsDir put: 'plugins'; at: #sourceDir put: 'src'! ! !VMMaker class methodsFor: 'initialisation' stamp: 'tpr 2/4/2002 19:18'! isActiveVMMakerClassFor: platformName "Does this class claim to be that properly active subclass of VMMaker for this platform? Subclasses are welcome to override this default" ^ platformName , '*' match: self name! ! !VMMaker class methodsFor: 'accessing' stamp: 'tpr 12/1/2000 15:58'! coreVMDirName ^DirNames at: #coreVMDir! ! !VMMaker class methodsFor: 'accessing' stamp: 'tpr 1/24/2001 15:03'! machinesDirName ^DirNames at: #machineType ifAbsent:[Smalltalk platformName]! ! !VMMaker class methodsFor: 'accessing' stamp: 'tpr 12/1/2000 16:03'! platformsDirName ^DirNames at: #platformsDir! ! !VMMaker class methodsFor: 'accessing' stamp: 'tpr 12/1/2000 16:12'! pluginsDirName ^DirNames at: #pluginsDir! ! !VMMaker class methodsFor: 'accessing' stamp: 'tpr 12/1/2000 16:14'! sourceDirName ^DirNames at: #sourceDir! ! !MacOSPowerPCOS9VMMaker class methodsFor: 'initialisation'! isActiveVMMakerClassFor: platformName "Does this class claim to be that properly active subclass of VMMaker for this platform?" ^platformName = 'Mac OS'" and: [Smalltalk platformSubtype = 'PowerPC'] <- this used to be used but prevents any attempt to do the crossplatform generation thang. How can we handle that bit properly?"! ! !MacOSPowerPCOS9BrowserVMMaker class methodsFor: 'initialisation'! isActiveVMMakerClassFor: platformName ^false! ! !VMMakerTool methodsFor: 'list access' stamp: 'tpr 10/10/2001 12:36'! availableListSelectionAt: index "return the boolean to say if the available plugin at index is selected" ^allPluginsSelectionsArray at: index! ! !VMMakerTool methodsFor: 'list access' stamp: 'tpr 10/10/2001 12:37'! availableListSelectionAt: index put: bool "set the boolean to say if the available plugin at index is selected" ^allPluginsSelectionsArray at: index put: bool! ! !VMMakerTool methodsFor: 'list access'! availableModules ^vmMaker availablePlugins! ! !VMMakerTool methodsFor: 'list access'! currentAvailableModuleIndex allPluginsSelection ifNil:[^0]. ^allPluginsSelection! ! !VMMakerTool methodsFor: 'list access'! currentAvailableModuleIndex: anInteger allPluginsSelection _ anInteger. self changed: #availableModules! ! !VMMakerTool methodsFor: 'list access'! currentExternalModuleIndex externalPluginsSelection ifNil:[^0]. ^externalPluginsSelection! ! !VMMakerTool methodsFor: 'list access'! currentExternalModuleIndex: anInteger externalPluginsSelection _ anInteger. self changed: #externalModules! ! !VMMakerTool methodsFor: 'list access'! currentInternalModuleIndex internalPluginsSelection ifNil:[^0]. ^internalPluginsSelection! ! !VMMakerTool methodsFor: 'list access'! currentInternalModuleIndex: anInteger internalPluginsSelection _ anInteger. self changed: #internalModules! ! !VMMakerTool methodsFor: 'list access' stamp: 'tpr 10/10/2001 12:36'! externalListSelectionAt: index "return the boolean to say if the external plugin at index is selected" ^externalPluginsSelectionsArray at: index! ! !VMMakerTool methodsFor: 'list access' stamp: 'tpr 10/10/2001 12:37'! externalListSelectionAt: index put: bool "set the boolean to say if the external plugin at index is selected" ^externalPluginsSelectionsArray at: index put: bool! ! !VMMakerTool methodsFor: 'list access'! externalModules ^vmMaker externalModules! ! !VMMakerTool methodsFor: 'list access'! initialModules ^vmMaker availableModules! ! !VMMakerTool methodsFor: 'list access' stamp: 'tpr 10/10/2001 12:36'! internalListSelectionAt: index "return the boolean to say if the internal plugin at index is selected" ^internalPluginsSelectionsArray at: index! ! !VMMakerTool methodsFor: 'list access' stamp: 'tpr 10/10/2001 12:37'! internalListSelectionAt: index put: bool "set the boolean to say if the internal plugin at index is selected" ^internalPluginsSelectionsArray at: index put: bool! ! !VMMakerTool methodsFor: 'list access'! internalModules ^vmMaker internalModules! ! !VMMakerTool methodsFor: 'list access' stamp: 'tpr 10/12/2001 15:29'! listForMorph: aMorph "work out which list is the one associated with this morph" allPluginsList = aMorph ifTrue:[^allPluginsList getListSelector]. internalPluginsList = aMorph ifTrue:[^internalPluginsList getListSelector]. externalPluginsList =aMorph ifTrue:[^externalPluginsList getListSelector]. ^nil! ! !VMMakerTool methodsFor: 'list access'! listMorphs ^Array with: allPluginsList with: internalPluginsList with: externalPluginsList! ! !VMMakerTool methodsFor: 'drag and drop'! acceptDroppingMorph: transferMorph event: evt inMorph: aMorph "Here we are fetching information from the dropped transferMorph and performing the correct action for this drop. As long as the source is part of this tool, move the dragged item from the source list to the destination list" transferMorph source model = self ifFalse:[^false]. ^self moveItem: transferMorph passenger from: transferMorph source to: aMorph! ! !VMMakerTool methodsFor: 'drag and drop' stamp: 'tpr 10/12/2001 15:27'! dragPassengerFor: item inMorph: dragSource (dragSource isKindOf: PluggableListMorph) ifFalse: [^item]. ^item contents! ! !VMMakerTool methodsFor: 'drag and drop'! dragTransferTypeForMorph: dragSource ^(dragSource isKindOf: PluggableListMorph) ifTrue: [dragSource getListSelector]! ! !VMMakerTool methodsFor: 'drag and drop' stamp: 'tpr 10/21/2001 11:19'! moveItem: transferedMorph from: sourceListMorph to: destListMorph "As part of a drag operation we have to move the item carried by the transfer morph from a source list to a destination list" "work out which list is involved and add the item to it" | destlist srclist | "no need to do anything if we drop on the same place from which we dragged" sourceListMorph = destListMorph ifTrue: [^ false]. (destlist _ self listForMorph: destListMorph) ifNil: [^ false]. (srclist _ self listForMorph: sourceListMorph) ifNil: [^ false]. vmMaker movePlugin: transferedMorph contents from: srclist to: destlist. self changed: sourceListMorph getListSelector. self changed: destListMorph getListSelector. ^ true! ! !VMMakerTool methodsFor: 'drag and drop'! wantsDroppedMorph: transferMorph event: anEvent inMorph: destinationLM "We are only interested in TransferMorphs as wrappers for information. If their content is really interesting for us, will determined later in >>acceptDroppingMorph:event:." "only want drops on the lists" ^self listMorphs includes: destinationLM! ! !VMMakerTool methodsFor: 'initialisation' stamp: 'tpr 5/7/2002 18:00'! buildWindow "VMMakerTool openInWorld" | sysWin box verticalOffset | sysWin _ (SystemWindow labelled: 'VMMaker') model: self. verticalOffset _ 0. "add a row of buttons to start up various actions" box _ AlignmentMorph new vResizing: #shrinkWrap. box addMorphBack: (SimpleButtonMorph new target: self; label: 'Generate All'; actionSelector: #generateAll; hResizing: #spaceFill; setBalloonText: 'Generate the sources for the core VM and all chosen plugins'). box addMorphBack: (SimpleButtonMorph new target: self; label: 'Generate Core VM'; actionSelector: #generateCore; hResizing: #spaceFill; setBalloonText: 'Generate the sources for the core vm and any internal plugins'). box addMorphBack: (SimpleButtonMorph new target: self; label: 'Generate External Plugins'; actionSelector: #generateExternal; hResizing: #spaceFill; setBalloonText: 'Generate the sources for all external plugins'). sysWin addMorph: box fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 0) offsets: (0 @ verticalOffset corner: 0 @ (verticalOffset _ verticalOffset + box height - 1))). "add a row of buttons to start up various actions" box _ AlignmentMorph new vResizing: #shrinkWrap. box addMorphBack: (SimpleButtonMorph new target: self; label: 'Load Configuration'; actionSelector: #loadConfig; hResizing: #spaceFill; setBalloonText: 'Load a previously saved configuration'). box addMorphBack: (SimpleButtonMorph new target: self; label: 'Save Configuration'; actionSelector: #saveConfig; hResizing: #spaceFill; setBalloonText: 'Save the current configuration'). box addMorphBack: (SimpleButtonMorph new target: self; label: 'Help'; actionSelector: #helpText; hResizing: #spaceFill; setBalloonText: 'Open the help window'). sysWin addMorph: box fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 0) offsets: (0 @ verticalOffset corner: 0 @ (verticalOffset _ verticalOffset + box height - 1))). "add the labelled text field for the path to the platform sources - typically {current dir}/platforms" box _ AlignmentMorph new. box addMorph: (TextMorph new contents: 'Path to platforms code:' asText allBold) lock; setBalloonText: 'The directory where the platform source tree is found; can be edited in text field to the right. Default of {working directory}/src is strongly recommended'. sysWin addMorph: box fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 0.3 @ 0) offsets: (0 @ verticalOffset corner: 0 @ (verticalOffset + box height - 1))). box _ AlignmentMorph new. box addMorphBack: (SimpleButtonMorph new target: self; label: 'Find Path'; actionSelector: #findPlatformsPath; hResizing: #spaceFill; setBalloonText: 'Search for the path to your platforms directory if it is not the default. May take a very long time on machines with large discs attached'). sysWin addMorph: box fullFrame: (LayoutFrame fractions: (1 @ 0 corner: 1 @ 0) offsets: (-100 @ verticalOffset corner: 0 @ (verticalOffset + box height - 1))). sysWin addMorph: ((platformPathMorph _ PluggableTextMorph on: self text: #platformsPathText accept: #platformsPathText:) acceptOnCR: true) fullFrame: (LayoutFrame fractions: (0.3 @ 0 corner: 1 @ 0) offsets: (0 @ verticalOffset corner: -100 @ (verticalOffset _ verticalOffset + box height - 1))). "add the labelled text field for the name of the platform - typically the current platform" box _ AlignmentMorph new. box addMorph: (TextMorph new contents: 'Platform name:' asText allBold) lock; setBalloonText: 'The platform name (as returned by Smalltalk platformName - unix, Mac OS, RISCOS, win32 etc); can be edited (in text field to the right) to cross generate'. sysWin addMorph: box fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 0.3 @ 0) offsets: (0 @ verticalOffset corner: 0 @ (verticalOffset + box height - 1))). box _ AlignmentMorph new. box addMorphBack: (SimpleButtonMorph new target: self; label: 'Find platform'; actionSelector: #platformsListMenu; hResizing: #spaceFill; setBalloonText: 'Choose from a list of known platforms. The default is this current platform.'). sysWin addMorph: box fullFrame: (LayoutFrame fractions: (1 @ 0 corner: 1 @ 0) offsets: (-100 @ verticalOffset corner: 0 @ (verticalOffset + box height - 1))). sysWin addMorph: ((platformNameMorph _ PluggableTextMorph on: self text: #platformNameText accept: #platformNameText:) acceptOnCR: true) fullFrame: (LayoutFrame fractions: (0.3 @ 0 corner: 1 @ 0) offsets: (0 @ verticalOffset corner: -100 @ (verticalOffset _ verticalOffset + box height - 1))). "Add the labelled text field to specify where the generated code should go; typically {current dir}/sources" box _ AlignmentMorph new. box addMorph: (TextMorph new contents: 'Path to generated sources' asText allBold; lock); setBalloonText: 'The directory where the built sources will be placed; can be edited in text field to the right. The default is strongly recommended; makefile alterations may be needed if you use a different path.'. sysWin addMorph: box fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 0.3 @ 0) offsets: (0 @ verticalOffset corner: 0 @ (verticalOffset + box height - 1))). box _ AlignmentMorph new. box addMorphBack: (SimpleButtonMorph new target: self; label: 'Clean out'; actionSelector: #cleanoutSrcDir; hResizing: #spaceFill; setBalloonText: 'Clean out all the files in the target directory, ready for a clean build'). sysWin addMorph: box fullFrame: (LayoutFrame fractions: (1 @ 0 corner: 1 @ 0) offsets: (-100 @ verticalOffset corner: 0 @ (verticalOffset + box height - 1))). sysWin addMorph: ((generatedPathMorph _ PluggableTextMorph on: self text: #sourcePathText accept: #sourcePathText:) acceptOnCR: true) fullFrame: (LayoutFrame fractions: (0.3 @ 0 corner: 1 @ 0) offsets: (0 @ verticalOffset corner: -100 @ (verticalOffset _ verticalOffset + box height - 1))). "Add the list of plugins that are available to build" allPluginsList _ (PluggableListMorph on: self list: #availableModules selected: #currentAvailableModuleIndex changeSelected: #currentAvailableModuleIndex: menu: #availableListMenu: keystroke: nil) enableDragNDrop. allPluginsList hResizing: #spaceFill; vResizing: #spaceFill; borderWidth: 0. box _ AlignmentMorph newColumn. box addMorphBack: (TextMorph new contents: 'Plugins not built' asText allBold; lock); setBalloonText: 'List of plugins that are available to build but not yet chosen. Drag to either other list or use menu option to move in bulk'. box addMorphBack: allPluginsList. sysWin addMorph: box fullFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 / 3 @ 1) offsets: (0 @ verticalOffset corner: 0 @ -100)). "make the list for plugins that will be built for internal linking" internalPluginsList _ (PluggableListMorph on: self list: #internalModules selected: #currentInternalModuleIndex changeSelected: #currentInternalModuleIndex: menu: #internalListMenu: keystroke: nil) enableDragNDrop. internalPluginsList hResizing: #spaceFill; vResizing: #spaceFill; borderWidth: 0. box _ AlignmentMorph newColumn. box addMorphBack: (TextMorph new contents: 'Internal Plugins' asText allBold; lock); setBalloonText: 'List of plugins chosen to be built internally'. box addMorphBack: internalPluginsList. sysWin addMorph: box fullFrame: (LayoutFrame fractions: (1 / 3 @ 0 corner: 2 / 3 @ 1) offsets: (0 @ verticalOffset corner: 0 @ -100)). "make the list for plugins to be built externally (ie as DLLs, SO or whatever suits the platform" externalPluginsList _ (PluggableListMorph on: self list: #externalModules selected: #currentExternalModuleIndex changeSelected: #currentExternalModuleIndex: menu: #externalListMenu: keystroke: nil) enableDragNDrop. externalPluginsList hResizing: #spaceFill; vResizing: #spaceFill; borderWidth: 0. box _ AlignmentMorph newColumn. box addMorphBack: (TextMorph new contents: 'External Plugins' asText allBold; lock); setBalloonText: 'List of plugins chosen to be built externally'. box addMorphBack: externalPluginsList. sysWin addMorph: box fullFrame: (LayoutFrame fractions: (2 / 3 @ 0 corner: 1 @ 1) offsets: (0 @ verticalOffset corner: 0 @ -100)). sysWin addMorph: (PluggableTextMorph on: logger text: nil accept: nil readSelection: nil menu: nil) fullFrame: (LayoutFrame fractions: (0 @ 1 corner: 1 @ 1) offsets: (0 @ -100 corner: 0 @ 0)). ^ sysWin! ! !VMMakerTool methodsFor: 'initialisation' stamp: 'ar 3/10/2002 15:09'! initialExtent ^600@450! ! !VMMakerTool methodsFor: 'initialisation' stamp: 'ar 3/10/2002 15:06'! initialize logger := TranscriptStream new. vmMaker _ VMMaker default. vmMaker logger: logger. vmMaker addDependent: self. allPluginsSelectionsArray _ Array new: self availableModules size withAll: false. internalPluginsSelectionsArray _ Array new. externalPluginsSelectionsArray _ Array new.! ! !VMMakerTool methodsFor: 'initialisation' stamp: 'tpr 10/12/2001 18:06'! update: anObject "some related object has changed. Try to handle it" anObject == #reinitialize ifTrue: [self updateAllViews]! ! !VMMakerTool methodsFor: 'initialisation' stamp: 'tpr 10/12/2001 18:06'! updateAllViews self changed: #platformsPathText; changed: #platformNameText; changed: #sourcePathText; changed: #availableModules; changed: #internalModules; changed: #externalModules! ! !VMMakerTool methodsFor: 'path access' stamp: 'tpr 3/27/2002 15:19'! cleanoutSrcDir "remove the entire generated src tree, ready for a nice clean build" vmMaker deleteEntireGeneratedTree! ! !VMMakerTool methodsFor: 'path access' stamp: 'tpr 3/12/2002 14:07'! findPlatformsPath | path | path _ self findPlatformsPathFrom: FileDirectory default. path ifNil: [(self confirm: 'No path found. Try searching from the root directory? (May take sometime)') ifTrue: [path _ self findPlatformsPathFrom: FileDirectory root. path ifNil: [^ self inform: 'No path found. Did you download the appropriate support code?']] ifFalse: [^ nil]]. self platformsPathText: path! ! !VMMakerTool methodsFor: 'path access' stamp: 'tpr 3/12/2002 14:10'! findPlatformsPathFrom: fd | path | Utilities informUserDuring:[:bar| path := self findPlatformsPathFrom: fd informing: bar. ]. ^path! ! !VMMakerTool methodsFor: 'path access' stamp: 'ar 3/10/2002 14:54'! findPlatformsPathFrom: fd informing: bar | dirNames possiblePath | bar value: 'Searching in ', fd pathName. dirNames := fd directoryNames. (dirNames includes: 'platforms') ifTrue:[ possiblePath := fd pathName, fd pathNameDelimiter asString, 'platforms'. (self confirm: 'Found a platforms directory at ', possiblePath,' Do you want me to use it?') ifTrue:[^possiblePath]. ]. dirNames do:[:dd| possiblePath := self findPlatformsPathFrom: (fd directoryNamed: dd) informing: bar. possiblePath ifNotNil:[^possiblePath]. ]. ^nil! ! !VMMakerTool methodsFor: 'path access'! platformNameText "return a Text for the platform name" ^vmMaker platformName asText! ! !VMMakerTool methodsFor: 'path access' stamp: 'tpr 10/21/2001 11:24'! platformsPathText "return a Text for the path to the platform sources" [^vmMaker platformRootDirectory fullName asText] on: VMMakerException do:[^'Problem with directory name for platform code: enter correct path or consult help text' asText]! ! !VMMakerTool methodsFor: 'path access' stamp: 'tpr 3/27/2002 15:47'! platformsPathText: aText "set the path to the platform sources" [^vmMaker platformRootDirectoryName: aText asString] on: VMMakerException do:[:ex| self inform:'problem with this directory name; check the path settings, permissions or spelling?'. ex return: false]! ! !VMMakerTool methodsFor: 'path access' stamp: 'ar 5/4/2002 21:06'! sourcePathText "return a Text for the path to the generated sources" ^[vmMaker sourceDirectory fullName asText] on: VMMakerException do:[:ex| ex return:''].! ! !VMMakerTool methodsFor: 'path access'! sourcePathText: aText "set the path to the generated sources" ^vmMaker sourceDirectoryName: aText asString! ! !VMMakerTool methodsFor: 'generate sources' stamp: 'tpr 10/21/2001 11:00'! generateAll "tell the vmMaker to build all the sources" self checkOK ifTrue: [[vmMaker generateEntire] on: VMMakerException do: [:ex| self inform: ex messageText]]! ! !VMMakerTool methodsFor: 'generate sources' stamp: 'tpr 10/21/2001 11:01'! generateCore "tell the vmMaker to build all the core vm sources" self checkOK ifTrue: [[vmMaker generateMainVM] on: VMMakerException do: [:ex| self inform: ex messageText]]! ! !VMMakerTool methodsFor: 'generate sources' stamp: 'tpr 10/21/2001 11:02'! generateExternal "tell the vmMaker to build all the externally linked plugin sources" self checkOK ifTrue: [[vmMaker generateExternalPlugins] on: VMMakerException do: [:ex | self inform: ex messageText]]! ! !VMMakerTool methodsFor: 'generate sources' stamp: 'tpr 10/21/2001 11:03'! generateSelectedExternalPlugin | plugin | plugin := self externalModules at: self currentExternalModuleIndex ifAbsent: [^self]. self checkOK ifTrue: [[vmMaker generateExternalPlugin: plugin] on: VMMakerException do: [:ex| self inform: ex messageText]] ! ! !VMMakerTool methodsFor: 'generate sources' stamp: 'tpr 10/21/2001 11:03'! generateSelectedInternalPlugin | plugin | plugin := self internalModules at: self currentInternalModuleIndex ifAbsent: [^self]. self checkOK ifTrue: [[vmMaker generateInternalPlugin: plugin] on: VMMakerException do: [:ex| self inform: ex messageText]] ! ! !VMMakerTool methodsFor: 'menus' stamp: 'rww 9/25/2001 01:17'! availableListMenu: aMenu aMenu addList:#( ('make all external' makeAllPluginsExternal) ('make all internal' makeAllPluginsInternal) ('make all available' makeAllPluginsAvailable) - ('browse plugin' browseSelectedAvailablePlugin)). ^ aMenu! ! !VMMakerTool methodsFor: 'menus' stamp: 'rww 9/25/2001 02:00'! browseSelectedAvailablePlugin | plugin | plugin := self availableModules at: self currentAvailableModuleIndex ifAbsent: [^self]. (Smalltalk classNamed: plugin) browseHierarchy! ! !VMMakerTool methodsFor: 'menus' stamp: 'rww 9/25/2001 02:00'! browseSelectedExternalPlugin | plugin | plugin := self externalModules at: self currentExternalModuleIndex ifAbsent: [^self]. (Smalltalk classNamed: plugin) browseHierarchy! ! !VMMakerTool methodsFor: 'menus' stamp: 'rww 9/25/2001 02:01'! browseSelectedInternalPlugin | plugin | plugin := self internalModules at: self currentInternalModuleIndex ifAbsent: [^self]. (Smalltalk classNamed: plugin) browseHierarchy! ! !VMMakerTool methodsFor: 'menus' stamp: 'rww 9/25/2001 01:17'! externalListMenu: aMenu aMenu addList:#( ('make all external' makeAllPluginsExternal) ('make all internal' makeAllPluginsInternal) ('make all available' makeAllPluginsAvailable) - ('browse plugin' browseSelectedExternalPlugin) - ('generate plugin' generateSelectedExternalPlugin)). ^ aMenu! ! !VMMakerTool methodsFor: 'menus' stamp: 'tpr 10/14/2001 20:11'! helpText (StringHolder new contents: self class comment) openLabel: 'VMMakerTool help' ! ! !VMMakerTool methodsFor: 'menus' stamp: 'rww 9/25/2001 01:17'! internalListMenu: aMenu aMenu addList:#( ('make all external' makeAllPluginsExternal) ('make all internal' makeAllPluginsInternal) ('make all available' makeAllPluginsAvailable) - ('browse plugin' browseSelectedInternalPlugin) - ('generate plugin' generateSelectedInternalPlugin)). ^ aMenu! ! !VMMakerTool methodsFor: 'menus' stamp: 'tpr 10/16/2001 09:58'! makeAllPluginsAvailable vmMaker makeAllModulesAvailable! ! !VMMakerTool methodsFor: 'menus' stamp: 'tpr 10/16/2001 09:58'! makeAllPluginsExternal vmMaker makeAllModulesExternal! ! !VMMakerTool methodsFor: 'menus' stamp: 'tpr 10/16/2001 09:58'! makeAllPluginsInternal vmMaker makeAllModulesInternal! ! !VMMakerTool methodsFor: 'menus' stamp: 'rww 9/25/2001 01:02'! perform: selector orSendTo: otherTarget "Selector was just chosen from a menu by a user. If can respond, then perform it on myself. If not, send it to otherTarget, presumably the editPane from which the menu was invoked." (self respondsTo: selector) ifTrue: [^ self perform: selector] ifFalse: [^ otherTarget perform: selector]! ! !VMMakerTool methodsFor: 'menus' stamp: 'ar 3/10/2002 15:05'! platformNameText: aText "set the platform name - this will almost certainly mean replacing the vmMaker with one suited to the platform so we do it anyway." | prevVMMaker | prevVMMaker _ vmMaker. "make a new vmmaker and ensure I depend on it correctly" vmMaker _ VMMaker forPlatform: aText string. vmMaker logger: logger. vmMaker addDependent: self. prevVMMaker removeDependent: self. "configure the new vmmaker to match the old one" [vmMaker loadConfiguration: prevVMMaker configurationInfo. vmMaker platformDirectory] on: VMMakerException do: [self inform: 'Possible problem with path settings or platform name? Check path, permissions or spellings'. ^ false]. ^ true! ! !VMMakerTool methodsFor: 'menus' stamp: 'tpr 5/7/2002 17:51'! platformsListMenu "create a menu of all known platforms" |choice platnames| platnames _ vmMaker platformRootDirectory directoryNames copyWithoutAll: #('Cross' 'CVS'). choice _ (PopUpMenu labelArray: platnames lines: #()) startUp. choice = 0 ifTrue:[^self]. self platformNameText: (platnames at: choice) asText! ! !VMMakerTool methodsFor: 'configurations' stamp: 'ar 3/10/2002 15:05'! loadConfig | fileResult file | fileResult _ (StandardFileMenu oldFileMenu: FileDirectory default withPattern: '*.config') startUpWithCaption: 'Select VMMaker configuration...'. fileResult ifNotNil: [file _ fileResult directory fullNameFor: fileResult name. [vmMaker _ VMMaker forConfigurationFile: file. vmMaker logger: logger. vmMaker platformDirectory] on: Error do: [self inform: 'Possible problem with path settings or platform name?']. self updateAllViews]! ! !VMMakerTool methodsFor: 'configurations' stamp: 'rww 9/23/2001 14:17'! saveConfig "write info about the current configuration to a file." | fileResult file | fileResult := (StandardFileMenu newFileMenu: FileDirectory default withPattern: '*.config') startUpWithCaption: 'Save VMMaker configuration...'. fileResult ifNotNil: [ ('*.config' match: fileResult name) ifFalse: [fileResult name: (fileResult name, '.config')]. file := fileResult directory fullNameFor: fileResult name. vmMaker saveConfigurationTo: file]. ! ! !VMMakerTool methodsFor: '-- all --' stamp: 'tpr 4/1/2002 15:38'! checkOK "check as many settings as we can and report true if all seems ok" (platformPathMorph accept; hasUnacceptedEdits) ifTrue:[^false]. (platformNameMorph accept; hasUnacceptedEdits) ifTrue:[^false]. (generatedPathMorph accept; hasUnacceptedEdits) ifTrue:[^false]. [vmMaker platformPluginsDirectory; crossPlatformPluginsDirectory] on: VMMakerException do: [:ex| self inform: ex messageText. ^ false]. ^ true! ! !VMMakerTool class methodsFor: 'instance creation'! new ^super new initialize! ! !VMMakerTool class methodsFor: 'instance creation'! openInWorld "Build a VMMakerTool and open it" "VMMakerTool openInWorld" ^self new buildWindow openInWorld! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 4/9/2002 18:51'! copyCrossPlatformFilesFor: plugin internal: aBoolean | srcDir targetDir | [srcDir _ self crossPlatformPluginsDirectory directoryNamed: plugin moduleName. targetDir _ aBoolean ifTrue:[self internalPluginsDirectoryFor: plugin] ifFalse:[self externalPluginsDirectoryFor: plugin]. logger show: 'Copy any cross platform files from: ' , srcDir printString , ' to ' , targetDir printString; cr. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: targetDir] on: FileStreamException do: ["If any file related exceptions get here, we've had some problem, probably path of permissions. Raise the general exception" ^ self couldNotFindPlatformFilesFor: plugin]! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 4/17/2002 16:23'! copyCrossPlatformVMFiles | srcDir targetDir vmDirName | vmDirName _ self class coreVMDirName. "Is there a crossPlatformDirectory subdirectory called 'vmDirName'?" (self crossPlatformDirectory directoryExists: vmDirName) ifTrue: [srcDir _ self crossPlatformDirectory directoryNamed: vmDirName. targetDir _ self coreVMDirectory. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: targetDir]! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 4/9/2002 18:51'! copyPlatformFilesFor: plugin internal: aBoolean | srcDir targetDir | [srcDir _ self platformPluginsDirectory directoryNamed: plugin moduleName. targetDir _ aBoolean ifTrue:[self internalPluginsDirectoryFor: plugin] ifFalse:[self externalPluginsDirectoryFor: plugin]. logger show: 'Copy any platform files from: ' , srcDir printString , ' to ' , targetDir printString; cr. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: targetDir] on: FileStreamException do: ["If any file related exceptions get here, we've had some problem, probably path of permissions. Raise the general exception" ^ self couldNotFindPlatformFilesFor: plugin]! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 4/17/2002 16:23'! copyPlatformVMFiles | srcDir targetDir vmDirName | vmDirName _ self class coreVMDirName. "Is there a platformDirectory subdirectory called 'vmDirName'?" (self platformDirectory directoryExists: vmDirName) ifTrue: [srcDir _ self platformDirectory directoryNamed: vmDirName. targetDir _ self coreVMDirectory. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: targetDir]! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 3/4/2002 10:34'! processAssortedFiles "See the comment in VMMaker> processAssortedFiles first. This version of the method will copy any miscellaneous files/dirs from the cross-platformDirectory - readme files etc, then from the platform specific directory - makefiles, utils etc. " | srcDir | "Is there a crossPlatformDirectory subdirectory called 'misc'?" (self crossPlatformDirectory directoryExists: 'misc') ifTrue: [srcDir _ self crossPlatformDirectory directoryNamed: 'misc'. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: self sourceDirectory]. "Is there a platformDirectory subdirectory called 'misc'?" (self platformDirectory directoryExists: 'misc') ifTrue: [srcDir _ self platformDirectory directoryNamed: 'misc'. self copyFilesFromSourceDirectory: srcDir toTargetDirectory: self sourceDirectory]. "Now copy any files that are always copied for all platforms" super processAssortedFiles ! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 4/17/2002 16:24'! processFilesForCoreVM "When using a copying version of VMMaker, copy any cross-platform files from the crossPlatformDir and then copy any files relating to the core vm from the platformDirectory's vm subdirectory." super processFilesForCoreVM. "Is there a crossPlatformDirectory subdirectory called 'vmDirName'?" self copyCrossPlatformVMFiles. "Is there a platformDirectory subdirectory called 'vmDirName'?" self copyPlatformVMFiles ! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 4/9/2002 18:51'! processFilesForExternalPlugin: plugin "See comment in VMMaker>processFileForExternalPlugin: first. When using a copying version of VMMaker, copy any files relating to the external plugin from the crossPlatform & platformDirectory subdir 'plugins'" super processFilesForExternalPlugin: plugin. "This version of the method has to actually copy files around" self copyCrossPlatformFilesFor: plugin internal: false; copyPlatformFilesFor: plugin internal: false! ! !VMMakerWithFileCopying methodsFor: 'copying files' stamp: 'tpr 4/9/2002 18:52'! processFilesForInternalPlugin: plugin "See comment in VMMaker>processFileForInternalPlugin: first. When using a copying version of VMMaker, copy any files relating to the internal plugin from the crossPlatform & platformDirectory subdir 'plugins'" super processFilesForInternalPlugin: plugin. "This version of the method has to actually copy files around" self copyCrossPlatformFilesFor: plugin internal: true; copyPlatformFilesFor: plugin internal: true! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/9/2002 18:52'! copyPlatformFilesFor: plugin internal: aBoolean "do nothing for Windows - code is generated into the platform tree so the files are already there"! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/17/2002 16:25'! copyPlatformVMFiles "Windows builds the sources in the platforms tree, so do nothing here"! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/17/2002 16:31'! deleteEntireGeneratedTree "remove all the files - but on Windows we can't easily tell which ones. So do nothing for now"! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/17/2002 15:31'! deleteUnwantedExternalPluginDirectories "delete directories in the external plugins tree with names not in the list of external plugins. This will make sure that only wanted plugins are left after generating external plugins - no previous ones will get left there like unwanted porridge" "On windows, we are keeping all the plugins in one place, the platforms tree, so don't delete - we can't easily tell which ones need to be kept"! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/17/2002 16:30'! deleteUnwantedInternalPluginDirectories "delete directories in the internal plugins tree with names not in the list of internal plugins. This will make sure that only wanted plugins are left after generating inernal plugins - no previous ones will get left there like unwanted porridge" "On windows, we are keeping all the plugins in one place, the platforms tree, so don't delete - we can't easily tell which ones need to be kept"! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/9/2002 15:19'! externalPluginsDirectory "return the target directory for the external plugins sources" ^self pluginsDirectory! ! !Win32VMMaker methodsFor: 'target directories'! internalPluginsDirectory ^self pluginsDirectory! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/9/2002 17:34'! makefileDirectory "where to put generated makefile related files" ^self pluginsDirectory! ! !Win32VMMaker methodsFor: 'target directories' stamp: 'tpr 4/9/2002 15:20'! pluginsDirectory "return the target directory for the plugins sources - for Windows this is the platforms source directory for the plugin" | fd | fd _ self sourceDirectory directoryNamed: self class pluginsDirName. fd assureExistence. ^fd! ! !Win32VMMaker methodsFor: 'target directories'! sourceDirectory "For Andreas... " ^self platformDirectory! ! VMMaker initialize! !VMMaker reorganize! ('initialize' initialize initializeAllExternal initializeAllExternalBut: initializeAllInternal initializeAllInternalBut: initializeAllPlugins initializeInternal:external: internal:external: providedPlugins setPlatName:) ('plugin lists' allModuleNames allPluginsDo: canSupportPlugin: externalFilesRequiredFor: externalModuleNames externalPluginsDo: internalModuleNames internalPluginsDo: plugins:do:) ('private - copying files' copyFileNamed:to: copyFilesFrom:to: copyFilesFromSourceDirectory:toTargetDirectory: copyFilesFromSourceDirectory:toTargetDirectory:recursively: primitiveCopyFileNamed:to:) ('copying files' copyAssortedFiles) ('generate sources' generateEntire generateExternalPlugin: generateExternalPlugins generateInternalPlugin: generateInternalPlugins generateInterpreterFile generateMainVM privateGenerateInternalPlugin: validateExternalPlugin: validateInternalPlugin: validatePlugin:in:) ('source directories' crossPlatformDirectory crossPlatformPluginsDirectory platformDirectory platformPluginsDirectory platformRootDirectory platformRootDirectoryName:) ('target directories' coreVMDirectory deleteEntireGeneratedTree deleteUnwantedExternalPluginDirectories deleteUnwantedInternalPluginDirectories externalPluginsDirectory externalPluginsDirectoryFor: internalPluginsDirectory internalPluginsDirectoryFor: makefileDirectory sourceDirectory sourceDirectoryName:) ('exports' export:forExternalPlugin: generateExportsFile storeExportsOn: storeExternalPluginList storeInternalPluginList) ('objects from disk' configurationInfo loadConfiguration: readConfigurationFrom: saveConfigurationTo:) ('private - errors' couldNotFindDirectory: couldNotFindPlatformDirectoryFor: couldNotFindPlatformFilesFor: couldNotFindPluginClass: couldNotOpenFile:) ('UI access' availablePlugins externalModules internalModules listOfName: logger logger: makeAllModulesAvailable makeAllModulesExternal makeAllModulesInternal movePlugin:from:to: platformName reinitializePluginsLists) ('processing external files' processAssortedFiles processFilesForCoreVM processFilesForExternalPlugin: processFilesForInternalPlugin:) ! UUIDPlugin class removeSelector: #headerFile! SoundPlugin class removeSelector: #headerFile! SocketPlugin class removeSelector: #headerFile! SerialPlugin class removeSelector: #headerFile! Mpeg3Plugin class removeSelector: #headerFile! MIDIPlugin class removeSelector: #headerFile! JoystickTabletPlugin class removeSelector: #headerFile! JPEGReadWriter2Plugin class removeSelector: #errorFile! JPEGReadWriter2Plugin class removeSelector: #headerFile! JPEGReadWriter2Plugin class removeSelector: #jConfigFile! JPEGReadWriter2Plugin class removeSelector: #jmemdatadstFile! JPEGReadWriter2Plugin class removeSelector: #jmemdatasrcFile! JPEGReadWriter2Plugin class removeSelector: #translateOn:inlining:to:local:! JPEGReadWriter2Plugin class removeSelector: #writeSupportFiles! AsynchFilePlugin class removeSelector: #headerFile! TestInterpreterPlugin class removeSelector: #translate:doInlining:debug:! TestInterpreterPlugin class removeSelector: #translate:doInlining:locally:debug:! TestInterpreterPlugin class removeSelector: #translateDoInlining:debug:! SurfacePlugin class removeSelector: #headerFile! SurfacePlugin class removeSelector: #sourceCode! SurfacePlugin class removeSelector: #translateOn:inlining:to:local:! SoundGenerationPlugin class removeSelector: #headerFile! SoundGenerationPlugin class removeSelector: #oldSourceFile! SoundGenerationPlugin class removeSelector: #translateOn:inlining:to:local:! SoundCodecPlugin class removeSelector: #headerFile! SoundCodecPlugin class removeSelector: #sourceFile! SoundCodecPlugin class removeSelector: #translateOn:inlining:to:local:! TestInterpreterPlugin subclass: #SocketPlugin instanceVariableNames: 'sDSAfn sHSAfn sCCTPfn sCCLOPfn sCCSOTfn ' classVariableNames: '' module: #(Squeak VMConstruction Plugins IO)! SecurityPlugin class removeSelector: #headerFile! Interpreter class removeSelector: #storeExports:on:! Interpreter class removeSelector: #translate:doInlining:! Interpreter class removeSelector: #translate:doInlining:forBrowserPlugin:! Interpreter class removeSelector: #translateForBrowserPlugin:! MiscPrimitivePlugin class removeSelector: #translateOn:inlining:to:local:! InterpreterSupportCode class removeSelector: #cCodeForMiscPrimitives! InterpreterSupportCode class removeSelector: #compareWithFilesInFolder:! InterpreterSupportCode class removeSelector: #macAddressXlationFile! InterpreterSupportCode class removeSelector: #macArchiveBinaryFile! InterpreterSupportCode class removeSelector: #macAsyncFilePrimsFile! InterpreterSupportCode class removeSelector: #macBrowserPluginFile! InterpreterSupportCode class removeSelector: #macDNRFile! InterpreterSupportCode class removeSelector: #macDirectoryFile! InterpreterSupportCode class removeSelector: #macDragDropFile! InterpreterSupportCode class removeSelector: #macJoystickAndTabletFile! InterpreterSupportCode class removeSelector: #macMinimal! InterpreterSupportCode class removeSelector: #macNetworkFile! InterpreterSupportCode class removeSelector: #macSecurityFile! InterpreterSupportCode class removeSelector: #macSerialAndMIDIPortFile! InterpreterSupportCode class removeSelector: #macSoundFile! InterpreterSupportCode class removeSelector: #macTCPFile! InterpreterSupportCode class removeSelector: #macWindowFile! InterpreterSupportCode class removeSelector: #readmeFile! InterpreterSupportCode class removeSelector: #squeakConfigFile! InterpreterSupportCode class removeSelector: #squeakFilePrimsFile! InterpreterSupportCode class removeSelector: #squeakHeaderFile! InterpreterSupportCode class removeSelector: #squeakNamedPrimsFile! InterpreterSupportCode class removeSelector: #squeakPlatSpecFile! InterpreterSupportCode class removeSelector: #squeakPlatformExportsFile! InterpreterSupportCode class removeSelector: #squeakVirtualMachineFile! InterpreterSupportCode class removeSelector: #squeakVirtualMachineHeaderFile! InterpreterSupportCode class removeSelector: #storeString:onFileNamed:! InterpreterSupportCode class removeSelector: #storeStuffitArchive:onFileNamed:! InterpreterSupportCode class removeSelector: #writeMacSourceFiles! InterpreterSupportCode class removeSelector: #writePluginSupportFiles! InterpreterSupportCode class removeSelector: #writeSupportFiles! FilePlugin class removeSelector: #headerFile! FXBltSimulator class removeSelector: #translate:doInlining:! FFIPlugin class removeSelector: #sqFFIHeaderFile! FFIPlugin class removeSelector: #sqUnixFFIFile! FFIPlugin class removeSelector: #sqWin32FFIFile! FFIPlugin class removeSelector: #writeSupportFiles! DropPlugin class removeSelector: #headerFile! B3DRasterizerPlugin class removeSelector: #b3dAllocC! B3DRasterizerPlugin class removeSelector: #b3dAllocH! B3DRasterizerPlugin class removeSelector: #b3dDrawC! B3DRasterizerPlugin class removeSelector: #b3dHeaderH! B3DRasterizerPlugin class removeSelector: #b3dInitC! B3DRasterizerPlugin class removeSelector: #b3dMainC! B3DRasterizerPlugin class removeSelector: #b3dRemapC! B3DRasterizerPlugin class removeSelector: #b3dTypesH! B3DRasterizerPlugin class removeSelector: #translateSupportCode:inlining:! B3DRasterizerPlugin class removeSelector: #writeSupportCode:! B3DEnginePlugin class removeSelector: #translateB3D! B3DEnginePlugin class removeSelector: #translateOn:inlining:to:local:! B3DAcceleratorPlugin class removeSelector: #headerFile! B3DAcceleratorPlugin class removeSelector: #sqMacOpenGLFile! B3DAcceleratorPlugin class removeSelector: #sqMacOpenGLHeaderFile! B3DAcceleratorPlugin class removeSelector: #sqMacOpenGLInfoFile! B3DAcceleratorPlugin class removeSelector: #sqOpenGLRendererFile! B3DAcceleratorPlugin class removeSelector: #sqOpenGLRendererHeaderFile! B3DAcceleratorPlugin class removeSelector: #translateOn:inlining:to:local:! ADPCMCodecPlugin class removeSelector: #translateOn:inlining:to:local:! InterpreterPlugin subclass: #FilePlugin instanceVariableNames: 'sCCPfn sCDPfn sCGFTfn sCLPfn sCSFTfn sDFAfn sCDFfn sCOFfn sCRFfn sHFAfn ' classVariableNames: 'DirBadPath DirEntryFound DirNoMoreEntries ' module: #(Squeak VMConstruction Plugins IO)! CCodeGenerator removeSelector: #declareModuleName:local:! CCodeGenerator removeSelector: #isTranslatingLocally! CCodeGenerator removeSelector: #pluginPrefix! CCodeGenerator removeSelector: #pluginPrefix:! Object subclass: #CCodeGenerator instanceVariableNames: 'translationDict inlineList constants variables variableDeclarations methods variablesSetCache headerFiles pluginName extraDefs postProcesses isCPP ' classVariableNames: 'UseRightShiftForDivide ' module: #(Squeak VMConstruction TranslationToC)!