'From Squeak 1.1 of September 21, 1996 on 21 October 1996 at 12:52:42 am'! FileDirectory subclass: #UnixFileDirectory instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'System-Files'! !BitBltSimulation methodsFor: 'inner loop'! copyLoop | prevWord thisWord skewWord halftoneWord mergeWord hInc y i word unskew skewMask notSkewMask | "This version of the inner loop assumes noSource = false." hInc _ hDir*4. "Byte delta" "degenerate skew fixed for Sparc. 10/20/96 ikp" skew == -32 ifTrue: [skew _ unskew _ skewMask _ 0] ifFalse: [skew < 0 ifTrue: [unskew _ skew+32. skewMask _ AllOnes << (0-skew)] ifFalse: [skew == 0 ifTrue: [unskew _ 0. skewMask _ AllOnes] ifFalse: [unskew _ skew-32. skewMask _ AllOnes >> skew]]]. notSkewMask _ skewMask bitInvert32. noHalftone ifTrue: [halftoneWord _ AllOnes. halftoneHeight _ 0] ifFalse: [halftoneWord _ interpreterProxy longAt: halftoneBase]. y _ dy. 1 to: bbH do: "here is the vertical loop" [ :i | halftoneHeight > 1 ifTrue: "Otherwise, its always the same" [halftoneWord _ interpreterProxy longAt: (halftoneBase + (y \\ halftoneHeight * 4)). y _ y + vDir]. preload ifTrue: ["load the 64-bit shifter" prevWord _ interpreterProxy longAt: sourceIndex. sourceIndex _ sourceIndex + hInc] ifFalse: [prevWord _ 0]. "Note: the horizontal loop has been expanded into three parts for speed:" "This first section requires masking of the destination store..." thisWord _ interpreterProxy longAt: sourceIndex. "pick up next word" skewWord _ ((prevWord bitAnd: notSkewMask) bitShift: unskew) bitOr: "32-bit rotate" ((thisWord bitAnd: skewMask) bitShift: skew). prevWord _ thisWord. sourceIndex _ sourceIndex + hInc. mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (interpreterProxy longAt: destIndex). interpreterProxy longAt: destIndex put: ((mask1 bitAnd: mergeWord) bitOr: (mask1 bitInvert32 bitAnd: (interpreterProxy longAt: destIndex))). destIndex _ destIndex + hInc. "This central horizontal loop requires no store masking" combinationRule = 3 ifTrue: [2 to: nWords-1 do: "Special inner loop for STORE" [ :word | thisWord _ interpreterProxy longAt: sourceIndex. "pick up next word" skewWord _ ((prevWord bitAnd: notSkewMask) bitShift: unskew) bitOr: "32-bit rotate" ((thisWord bitAnd: skewMask) bitShift: skew). prevWord _ thisWord. sourceIndex _ sourceIndex + hInc. interpreterProxy longAt: destIndex put: (skewWord bitAnd: halftoneWord). destIndex _ destIndex + hInc] ] ifFalse: [2 to: nWords-1 do: "Normal inner loop does merge:" [ :word | thisWord _ interpreterProxy longAt: sourceIndex. "pick up next word" skewWord _ ((prevWord bitAnd: notSkewMask) bitShift: unskew) bitOr: "32-bit rotate" ((thisWord bitAnd: skewMask) bitShift: skew). prevWord _ thisWord. sourceIndex _ sourceIndex + hInc. mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (interpreterProxy longAt: destIndex). interpreterProxy longAt: destIndex put: mergeWord. destIndex _ destIndex + hInc] ]. "This last section, if used, requires masking of the destination store..." nWords > 1 ifTrue: [thisWord _ interpreterProxy longAt: sourceIndex. "pick up next word" skewWord _ ((prevWord bitAnd: notSkewMask) bitShift: unskew) bitOr: "32-bit rotate" ((thisWord bitAnd: skewMask) bitShift: skew). prevWord _ thisWord. sourceIndex _ sourceIndex + hInc. mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: (interpreterProxy longAt: destIndex). interpreterProxy longAt: destIndex put: ((mask2 bitAnd: mergeWord) bitOr: (mask2 bitInvert32 bitAnd: (interpreterProxy longAt: destIndex))). destIndex _ destIndex + hInc]. sourceIndex _ sourceIndex + sourceDelta. destIndex _ destIndex + destDelta]! ! CCodeGenerator comment: 'This class oversees the translation of a subset of Smalltalk to C, allowing the comforts of Smalltalk during development and the efficiency and portability of C for the resulting interpreter. Executing Interpreter translate: ''InterpTestInline.c'' doInlining: true. (with single quotes) will cause all the methods of Interpreter, ObjectMemory and BitBltSimulation to be translated to C, and stored in the named file. This file together with the files emitted by InterpreterSupportCode (qv) should be adequate to produce a complete interpreter for the Macintosh environment.'! !CCodeGenerator methodsFor: 'C code generator'! emitCHeaderForPrimitivesOn: aStream "Write a C file header for compiled primitives onto the given stream." aStream nextPutAll: '/* Automatically generated from Squeak on '. aStream nextPutAll: Time dateAndTimeNow printString. aStream nextPutAll: '*/'; cr; cr. aStream nextPutAll: '#include "sq.h"'; cr; cr. aStream nextPutAll: '#define true 1'; cr. aStream nextPutAll: '#define false 0'; cr. "Note: Using 'null' because nil is predefined in Think C" aStream nextPutAll: '#define null 0'; cr. aStream nextPutAll: ' /* Memory Access Macros */ #define byteAt(i) (*((unsigned char *) (i))) #define byteAtput(i, val) (*((unsigned char *) (i)) = val) /* #define floatAt(i) (*((double *) (i))) */ /* #define floatAtput(i, val) (*((double *) (i)) = val) */ typedef union { double value; struct { int first, second; } words; } floatWords; double floatAt(int i) { floatWords conv; conv.words.first= *((int *)i); conv.words.second= *(((int *)i)+1); return conv.value; } double floatAtput(int i, double val) { *((int *)i)= ((floatWords *)&val)->words.first; *(((int *)i)+1)= ((floatWords *)&val)->words.second; return val; } #define longAt(i) (*((int *) (i))) #define longAtput(i, val) (*((int *) (i)) = val) /*** Imported Variables ***/ extern int stackPointer; extern int successFlag; '. aStream cr.! 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; cr. aStream nextPutAll: '#include "sq.h"'; cr; cr. aStream nextPutAll: '#define true 1'; cr. aStream nextPutAll: '#define false 0'; cr. "Note: Using 'null' because nil is predefined in Think C" aStream nextPutAll: '#define null 0'; cr. aStream nextPutAll: ' /* memory access macros */ #define byteAt(i) (*((unsigned char *) (i))) #define byteAtput(i, val) (*((unsigned char *) (i)) = val) /* #define floatAt(i) (*((double *) (i))) */ /* #define floatAtput(i, val) (*((double *) (i)) = val) */ typedef union { double value; struct { int first, second; } words; } floatWords; double floatAt(int i) { floatWords conv; conv.words.first= *((int *)i); conv.words.second= *(((int *)i)+1); return conv.value; } double floatAtput(int i, double val) { *((int *)i)= ((floatWords *)&val)->words.first; *(((int *)i)+1)= ((floatWords *)&val)->words.second; return val; } #define longAt(i) (*((int *) (i))) #define longAtput(i, val) (*((int *) (i)) = val) int printCallStack(void); void error(char *s); void error(char *s) { /* Print an error message and exit. */ static int printingStack = false; printf("\n%s\n\n", s); if (!!printingStack) { /* flag prevents recursive error when trying to print a broken stack */ printingStack = true; printCallStack(); } exit(-1); } '. aStream cr.! ! !FileDirectory methodsFor: 'path name'! topDirectoryPath "the path to the root of the filesystem. 10/20/96 ikp" ^''! ! !FileDirectory methodsFor: 'file names'! topDirectoryName "Answer the file list's name for the top (root) directory. 10/18/96 ikp" ^''! ! !FileList methodsFor: 'initialization'! directory: dir "Set the path of the volume to be displayed." sortMode == nil ifTrue: [sortMode _ #name]. self okToChange ifFalse: [^ self]. directory _ dir. volList _ (Array with: directory topDirectoryName) , directory pathParts. self changed: #relabel. self changed: #list. self newListAndPattern: (pattern == nil ifTrue: ['*'] ifFalse: [pattern]). ! ! !FileList methodsFor: 'list access'! toggleListIndex: index "Select the volume name in the receiver's list whose index is the argument." | delim name | volListIndex _ index. delim _ directory pathNameDelimiter. name _ volList at: index. self directory: (FileDirectory newOnPath: (String streamContents: [:strm | strm nextPutAll: directory topDirectoryPath. 2 to: index do: [:i | strm nextPutAll: (volList at: i). i < index ifTrue: [strm nextPut: delim]]])).! ! !Interpreter methodsFor: 'float primitives'! primitiveTimesTwoPower | rcvr arg | self var: #rcvr declareC: 'double rcvr'. arg _ self popInteger. rcvr _ self popFloat. successFlag ifTrue: [ self pushFloat: (self cCode: 'ldexp(rcvr, arg)') ] ifFalse: [ self unPop: 2 ].! ! !MacFileDirectory methodsFor: 'name service'! topDirectoryName "Answer the file list's name for the top (root) directory. 10/18/96 ikp" ^'Desk Top'! ! !UnixFileDirectory methodsFor: 'name service'! topDirectoryName "Answer the file list's name for the top (root) directory. 10/18/96 ikp" ^'/'! topDirectoryPath "Answer the path to the top (root) directory. 10/18/96 ikp" ^'/'! ! !UnixFileDirectory methodsFor: 'file creation'! fileClass ^ StandardFileStream! ! !UnixFileDirectory class methodsFor: 'initialization'! pathNameDelimiter ^ $/! setMacFileNamed: fileName type: typeString creator: creatorString "Mac specific; noop on other platforms."! ! FileDirectory class removeSelector: #topDirectoryName! UnixFileDirectory class removeSelector: #topDirectoryName!