'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 24 August 2008 at 10:51:05 am'! ObjectMemory subclass: #Interpreter instanceVariableNames: 'activeContext theHomeContext method receiver instructionPointer stackPointer localIP localSP localHomeContext localReturnContext localReturnValue messageSelector argumentCount newMethod currentBytecode successFlag primitiveIndex primitiveFunctionPointer methodCache atCache lkupClass reclaimableContextCount nextPollTick nextWakeupTick lastTick interruptKeycode interruptPending semaphoresToSignalA semaphoresUseBufferA semaphoresToSignalCountA semaphoresToSignalB semaphoresToSignalCountB processSignalingLowSpace savedWindowSize fullScreenFlag deferDisplayUpdates pendingFinalizationSignals compilerInitialized compilerHooks extraVMMemory newNativeMethod methodClass receiverClass interpreterVersion interpreterProxy showSurfaceFn interruptCheckCounterFeedBackReset interruptChecksEveryNms externalPrimitiveTable primitiveTable globalSessionID jmpBuf jmpDepth jmpMax suspendedCallbacks suspendedMethods profileProcess profileMethod profileSemaphore nextProfileTick metaclassSizeBytes' classVariableNames: 'ActiveProcessIndex AtCacheEntries AtCacheFixedFields AtCacheFmt AtCacheMask AtCacheOop AtCacheSize AtCacheTotalSize AtPutBase BlockArgumentCountIndex BlockMethodIndex BytecodeTable CacheProbeMax CallerIndex CharacterValueIndex ClosureCopiedValuesIndex ClosureIndex ClosureMethodIndex ClosureNumArgsIndex ClosureOuterContextIndex ClosureStartPCIndex CompilerHooksSize CrossedX DirBadPath DirEntryFound DirNoMoreEntries EndOfRun ExcessSignalsIndex FirstLinkIndex HeaderIndex HomeIndex InitialIPIndex InstanceSpecificationIndex InstructionPointerIndex JitterTable LastLinkIndex LiteralStart MaxExternalPrimitiveTableSize MaxJumpBuf MaxPrimitiveIndex MessageArgumentsIndex MessageDictionaryIndex MessageLookupClassIndex MessageSelectorIndex MethodArrayIndex MethodCacheClass MethodCacheEntries MethodCacheEntrySize MethodCacheMask MethodCacheMethod MethodCachePrim MethodCachePrimFunction MethodCacheSelector MethodCacheSize MethodIndex MillisecondClockMask MyListIndex NextLinkIndex PrimitiveExternalCallIndex PrimitiveTable PriorityIndex ProcessListsIndex ReceiverIndex SelectorStart SemaphoresToSignalSize SenderIndex StackPointerIndex StreamArrayIndex StreamIndexIndex StreamReadLimitIndex StreamWriteLimitIndex SuperclassIndex SuspendedContextIndex TempFrameStart ValueIndex XIndex YIndex' poolDictionaries: '' category: 'VMMaker-Interpreter'! !Interpreter methodsFor: 'contexts' stamp: 'eem 6/20/2008 21:49'! argumentCountOfClosure: closurePointer ^self quickFetchInteger: ClosureNumArgsIndex ofObject: closurePointer! ! !Interpreter methodsFor: 'contexts' stamp: 'eem 5/29/2008 11:53'! isContext: oop self inline: true. ^(self isNonIntegerObject: oop) and: [self isContextHeader: (self baseHeader: oop)]! ! !Interpreter methodsFor: 'stack bytecodes' stamp: 'eem 5/24/2008 11:00'! storeRemoteTemp: index inVectorAt: tempVectorIndex | tempVector | tempVector := self temporary: tempVectorIndex. self storePointer: index ofObject: tempVector withValue: self internalStackTop.! ! !Interpreter methodsFor: 'control primitives' stamp: 'eem 7/24/2008 17:54'! closureIn: context numArgs: numArgs instructionPointer: initialIP | newClosure | self inline: true. newClosure := self instantiateSmallClass: (self splObj: ClassBlockClosure) sizeInBytes: (BytesPerWord * 4) + BaseHeaderSize. "Assume: have just allocated a new closure; it must be young. Thus, can use unchecked stores." "N.B. It is up to the caller to store the copiedValues!!" self storePointerUnchecked: ClosureOuterContextIndex ofObject: newClosure withValue: activeContext. self storePointerUnchecked: ClosureStartPCIndex ofObject: newClosure withValue: (self integerObjectOf: initialIP). self storePointerUnchecked: ClosureNumArgsIndex ofObject: newClosure withValue: (self integerObjectOf: numArgs). ^newClosure! ! !Interpreter methodsFor: 'image save/restore' stamp: 'eem 6/23/2008 16:26'! imageFormatCompatibilityVersion "This VM is backward-compatible with the immediately preceeding non-closure version." BytesPerWord == 4 ifTrue: [^6502] ifFalse: [^68000]! ! !Interpreter methodsFor: 'image save/restore' stamp: 'eem 6/23/2008 16:24'! imageFormatVersion "Return a magic constant that changes when the image format changes. Since the image reading code uses this to detect byte ordering, one must avoid version numbers that are invariant under byte reversal." BytesPerWord == 4 ifTrue: [^6503] ifFalse: [^68001]! ! !Interpreter methodsFor: 'image save/restore' stamp: 'eem 6/23/2008 16:27'! readableFormat: imageVersion "Anwer true if images of the given format are readable by this interpreter. Allows a virtual machine to accept selected older image formats." ^ imageVersion = self imageFormatVersion or: [imageVersion = self imageFormatCompatibilityVersion] " Example of multiple formats: ^ (imageVersion = self imageFormatVersion) or: [imageVersion = 6504] "! ! !Interpreter methodsFor: 'message sending' stamp: 'eem 5/27/2008 18:51'! activateNewMethod | newContext methodHeader initialIP tempCount nilOop where | methodHeader := self headerOf: newMethod. newContext := self allocateOrRecycleContext: (methodHeader bitAnd: LargeContextBit). initialIP := ((LiteralStart + (self literalCountOfHeader: methodHeader)) * BytesPerWord) + 1. tempCount := (methodHeader >> 19) bitAnd: 16r3F. "Assume: newContext will be recorded as a root if necessary by the call to newActiveContext: below, so we can use unchecked stores." where := newContext + BaseHeaderSize. self longAt: where + (SenderIndex << ShiftForWord) put: activeContext. self longAt: where + (InstructionPointerIndex << ShiftForWord) put: (self integerObjectOf: initialIP). self longAt: where + (StackPointerIndex << ShiftForWord) put: (self integerObjectOf: tempCount). self longAt: where + (MethodIndex << ShiftForWord) put: newMethod. self longAt: where + (ClosureIndex << ShiftForWord) put: nilObj. "Copy the reciever and arguments..." 0 to: argumentCount do: [:i | self longAt: where + ((ReceiverIndex+i) << ShiftForWord) put: (self stackValue: argumentCount-i)]. "clear remaining temps to nil in case it has been recycled" nilOop := nilObj. argumentCount+1+ReceiverIndex to: tempCount+ReceiverIndex do: [:i | self longAt: where + (i << ShiftForWord) put: nilOop]. self pop: argumentCount + 1. reclaimableContextCount := reclaimableContextCount + 1. self newActiveContext: newContext.! ! !Interpreter methodsFor: 'message sending' stamp: 'eem 5/27/2008 18:52'! internalActivateNewMethod | methodHeader newContext tempCount argCount2 needsLarge where | self inline: true. methodHeader := self headerOf: newMethod. needsLarge := methodHeader bitAnd: LargeContextBit. (needsLarge = 0 and: [freeContexts ~= NilContext]) ifTrue: [newContext := freeContexts. freeContexts := self fetchPointer: 0 ofObject: newContext] ifFalse: ["Slower call for large contexts or empty free list" self externalizeIPandSP. newContext := self allocateOrRecycleContext: needsLarge. self internalizeIPandSP]. tempCount := (methodHeader >> 19) bitAnd: 16r3F. "Assume: newContext will be recorded as a root if necessary by the call to newActiveContext: below, so we can use unchecked stores." where := newContext + BaseHeaderSize. self longAt: where + (SenderIndex << ShiftForWord) put: activeContext. self longAt: where + (InstructionPointerIndex << ShiftForWord) put: (self integerObjectOf: (((LiteralStart + (self literalCountOfHeader: methodHeader)) * BytesPerWord) + 1)). self longAt: where + (StackPointerIndex << ShiftForWord) put: (self integerObjectOf: tempCount). self longAt: where + (MethodIndex << ShiftForWord) put: newMethod. self longAt: where + (ClosureIndex << ShiftForWord) put: nilObj. "Copy the reciever and arguments..." argCount2 := argumentCount. 0 to: argCount2 do: [:i | self longAt: where + ((ReceiverIndex+i) << ShiftForWord) put: (self internalStackValue: argCount2-i)]. "clear remaining temps to nil in case it has been recycled" methodHeader := nilObj. "methodHeader here used just as faster (register?) temp" argCount2+1+ReceiverIndex to: tempCount+ReceiverIndex do: [:i | self longAt: where + (i << ShiftForWord) put: methodHeader]. self internalPop: argCount2 + 1. reclaimableContextCount := reclaimableContextCount + 1. self internalNewActiveContext: newContext. ! ! !Interpreter methodsFor: 'contexts' stamp: 'eem 5/23/2008 14:53'! sender | context closureOrNil | context := localHomeContext. [(closureOrNil := self fetchPointer: ClosureIndex ofObject: context) ~~ nilObj] whileTrue: [context := self fetchPointer: ClosureOuterContextIndex ofObject: closureOrNil]. ^self fetchPointer: SenderIndex ofObject: context! ! !Interpreter methodsFor: 'compiled methods' stamp: 'eem 7/24/2008 17:15'! primitiveNewMethod | header bytecodeCount class size theMethod literalCount | header := self popStack. bytecodeCount := self popInteger. self success: (self isIntegerObject: header). successFlag ifFalse: [self unPop: 2. ^nil]. class := self popStack. size := (self literalCountOfHeader: header) + 1 * BytesPerWord + bytecodeCount. theMethod := self instantiateClass: class indexableSize: size. self storePointerUnchecked: HeaderIndex ofObject: theMethod withValue: header. literalCount := self literalCountOfHeader: header. 1 to: literalCount do: [:i | self storePointer: i ofObject: theMethod withValue: nilObj]. self push: theMethod! ! !Interpreter methodsFor: 'stack bytecodes' stamp: 'eem 7/24/2008 17:56'! pushClosureCopyCopiedValuesBytecode "The compiler has pushed the values to be copied, if any. Find numArgs and numCopied in the byte following. Pop numCopied values off the stack int an Array (or use nil if none). Create a Closure with the copiedValues and numArgs so specified, starting at the pc following the block size and jump over that code." | newClosure numArgsNumCopied numArgs numCopied copiedValues offset | numArgsNumCopied := self fetchByte. numArgs := numArgsNumCopied bitAnd: 16rF. numCopied := numArgsNumCopied bitShift: -4. numCopied > 0 ifTrue: ["self assert: numCopied * BytesPerWord <= 252." self externalizeIPandSP. "This is a pain." copiedValues := self instantiateSmallClass: (self splObj: ClassArray) sizeInBytes: (numCopied * BytesPerWord) + BaseHeaderSize. self internalizeIPandSP. 0 to: numCopied - 1 do: [:i| "Assume: have just allocated a new Array; it must be young. Thus, can use unchecked stores." self storePointerUnchecked: i ofObject: copiedValues withValue: (self internalStackValue: numCopied - i - 1)]. self internalPop: numCopied. self pushRemappableOop: copiedValues]. "Split offset := (self fetchByte * 256) + self fetchByte. into two because evaluation order in C is undefined." offset := self fetchByte * 256. offset := offset + self fetchByte. self externalizeIPandSP. "This is a pain." newClosure := self closureIn: activeContext numArgs: numArgs instructionPointer: ((self cCoerce: localIP to: 'sqInt') + 2 - (method+BaseHeaderSize)). reclaimableContextCount := 0. "The closure refers to thisContext so it can't be reclaimed." numCopied > 0 ifTrue: [copiedValues := self popRemappableOop] ifFalse: [copiedValues := nilObj]. self storePointerUnchecked: ClosureCopiedValuesIndex ofObject: newClosure withValue: copiedValues. self internalizeIPandSP. localIP := localIP + offset. self fetchNextBytecode. self internalPush: newClosure! ! !Interpreter methodsFor: 'stack bytecodes' stamp: 'eem 7/22/2008 16:46'! pushNewArrayBytecode | size popValues array | size := self fetchByte. popValues := size > 127. size := size bitAnd: 127. self fetchNextBytecode. self externalizeIPandSP. array := self instantiateClass: (self splObj: ClassArray) indexableSize: size. self internalizeIPandSP. popValues ifTrue: [0 to: size - 1 do: [:i| "Assume: have just allocated a new Array; it must be young. Thus, can use unchecked stores." self storePointerUnchecked: i ofObject: array withValue: (self internalStackValue: size - i - 1)]. self internalPop: size]. self internalPush: array! ! !Interpreter methodsFor: 'stack bytecodes' stamp: 'eem 5/27/2008 13:28'! pushRemoteTempLongBytecode | remoteTempIndex tempVectorIndex | remoteTempIndex := self fetchByte. tempVectorIndex := self fetchByte. self fetchNextBytecode. self pushRemoteTemp: remoteTempIndex inVectorAt: tempVectorIndex! ! !Interpreter methodsFor: 'stack bytecodes' stamp: 'eem 5/27/2008 15:12'! pushRemoteTemp: index inVectorAt: tempVectorIndex | tempVector | tempVector := self temporary: tempVectorIndex. self internalPush: (self fetchPointer: index ofObject: tempVector)! ! !Interpreter methodsFor: 'stack bytecodes' stamp: 'eem 5/24/2008 11:01'! storeAndPopRemoteTempLongBytecode self storeRemoteTempLongBytecode. self internalPop: 1! ! !Interpreter methodsFor: 'stack bytecodes' stamp: 'eem 5/27/2008 13:29'! storeRemoteTempLongBytecode | remoteTempIndex tempVectorIndex | remoteTempIndex := self fetchByte. tempVectorIndex := self fetchByte. self fetchNextBytecode. self storeRemoteTemp: remoteTempIndex inVectorAt: tempVectorIndex! ! !Interpreter methodsFor: 'common selector sends' stamp: 'eem 8/22/2008 15:20'! bytecodePrimValue "In-line value for BlockClosure and BlockContext" | maybeBlock rcvrClass | maybeBlock := self internalStackTop. argumentCount := 0. successFlag := true. (self isNonIntegerObject: maybeBlock) ifTrue: [rcvrClass := self fetchClassOfNonInt: maybeBlock. rcvrClass = (self splObj: ClassBlockClosure) ifTrue: [self externalizeIPandSP. self primitiveClosureValue. self internalizeIPandSP] ifFalse: [rcvrClass = (self splObj: ClassBlockContext) ifTrue: [self externalizeIPandSP. self primitiveValue. self internalizeIPandSP] ifFalse: [successFlag := false]]]. successFlag ifFalse: [messageSelector := self specialSelector: 25. ^self normalSend]. self fetchNextBytecode! ! !Interpreter methodsFor: 'common selector sends' stamp: 'eem 8/22/2008 15:37'! bytecodePrimValueWithArg "In-line value: for BlockClosure and BlockContext" | maybeBlock rcvrClass | maybeBlock := self internalStackValue: 1. argumentCount := 1. successFlag := true. (self isNonIntegerObject: maybeBlock) ifTrue: [rcvrClass := self fetchClassOfNonInt: maybeBlock. rcvrClass = (self splObj: ClassBlockClosure) ifTrue: [self externalizeIPandSP. self primitiveClosureValue. self internalizeIPandSP] ifFalse: [rcvrClass = (self splObj: ClassBlockContext) ifTrue: [self externalizeIPandSP. self primitiveValue. self internalizeIPandSP] ifFalse: [successFlag := false]]]. successFlag ifFalse: [messageSelector := self specialSelector: 26. ^self normalSend]. self fetchNextBytecode! ! !Interpreter methodsFor: 'control primitives' stamp: 'eem 6/9/2008 16:43'! activateNewClosureMethod: blockClosure "Similar to activateNewMethod but for Closure and newMethod." | theBlockClosure closureMethod newContext methodHeader copiedValues numCopied where outerContext | DoAssertionChecks ifTrue: [self okayOop: blockClosure]. outerContext := self fetchPointer: ClosureOuterContextIndex ofObject: blockClosure. DoAssertionChecks ifTrue: [self okayOop: outerContext]. closureMethod := self fetchPointer: MethodIndex ofObject: outerContext. methodHeader := self headerOf: closureMethod. self pushRemappableOop: blockClosure. newContext := self allocateOrRecycleContext: (methodHeader bitAnd: LargeContextBit). "All for one, and one for all!!" "allocateOrRecycleContext: may cayse a GC; restore blockClosure and refetch outerContext et al" theBlockClosure := self popRemappableOop. outerContext := self fetchPointer: ClosureOuterContextIndex ofObject: theBlockClosure. copiedValues := self fetchPointer: ClosureCopiedValuesIndex ofObject: theBlockClosure. "Should evaluate to 0 for nilObj" numCopied := self fetchWordLengthOf: copiedValues. "Assume: newContext will be recorded as a root if necessary by the call to newActiveContext: below, so we can use unchecked stores." where := newContext + BaseHeaderSize. self longAt: where + (SenderIndex << ShiftForWord) put: activeContext. self longAt: where + (InstructionPointerIndex << ShiftForWord) put: (self fetchPointer: ClosureStartPCIndex ofObject: theBlockClosure). self longAt: where + (StackPointerIndex << ShiftForWord) put: (self integerObjectOf: argumentCount + numCopied). self longAt: where + (MethodIndex << ShiftForWord) put: (self fetchPointer: MethodIndex ofObject: outerContext). self longAt: where + (ClosureIndex << ShiftForWord) put: theBlockClosure. self longAt: where + (ReceiverIndex << ShiftForWord) put: (self fetchPointer: ReceiverIndex ofObject: outerContext). "Copy the arguments..." 1 to: argumentCount do: [:i | self longAt: where + ((ReceiverIndex+i) << ShiftForWord) put: (self stackValue: argumentCount-i)]. "Copy the copied values..." where := newContext + BaseHeaderSize + ((ReceiverIndex + 1 + argumentCount) << ShiftForWord). 0 to: numCopied - 1 do: [:i| self longAt: where + (i << ShiftForWord) put: (self fetchPointer: i ofObject: copiedValues)]. "The initial instructions in the block nil-out remaining temps." self pop: argumentCount + 1. self newActiveContext: newContext! ! !Interpreter methodsFor: 'control primitives' stamp: 'eem 7/24/2008 17:55'! primitiveClosureCopyWithCopiedValues | newClosure numArgs | numArgs := self stackIntegerValue: 1. successFlag ifFalse: [^self primitiveFail]. newClosure := self closureIn: (self stackValue: 2) numArgs: numArgs "greater by 1 due to preIncrement of localIP" instructionPointer: instructionPointer + 2 - (method+BaseHeaderSize). self storePointerUnchecked: ClosureCopiedValuesIndex ofObject: newClosure withValue: self stackTop. self pop: 3 thenPush: newClosure! ! !Interpreter methodsFor: 'control primitives' stamp: 'eem 8/22/2008 15:09'! primitiveClosureValue | blockClosure blockArgumentCount closureMethod copiedValues outerContext | blockClosure := self stackValue: argumentCount. blockArgumentCount := self argumentCountOfClosure: blockClosure. argumentCount = blockArgumentCount ifFalse: [^self primitiveFail]. "Somewhat paranoiac checks we need while debugging that we may be able to discard in a robust system." outerContext := self fetchPointer: ClosureOuterContextIndex ofObject: blockClosure. (self isContext: outerContext) ifFalse: [^self primitiveFail]. closureMethod := self fetchPointer: MethodIndex ofObject: outerContext. "Check if the closure's method is actually a CompiledMethod." ((self isNonIntegerObject: closureMethod) and: [self isCompiledMethod: closureMethod]) ifFalse: [^self primitiveFail]. "Check if copiedValues is either nil or anArray." copiedValues := self fetchPointer: ClosureCopiedValuesIndex ofObject: blockClosure. (copiedValues == nilObj or: [(self fetchClassOf: copiedValues) = (self splObj: ClassArray)]) ifFalse: [^self primitiveFail]. self activateNewClosureMethod: blockClosure. self quickCheckForInterrupts! ! !Interpreter methodsFor: 'control primitives' stamp: 'eem 8/22/2008 15:08'! primitiveClosureValueNoContextSwitch "An exact clone of primitiveClosureValue except that this version will not check for interrupts on stack overflow." | blockClosure blockArgumentCount closureMethod copiedValues outerContext | blockClosure := self stackValue: argumentCount. blockArgumentCount := self argumentCountOfClosure: blockClosure. argumentCount = blockArgumentCount ifFalse: [^self primitiveFail]. "Somewhat paranoiac checks we need while debugging that we may be able to discard in a robust system." outerContext := self fetchPointer: ClosureOuterContextIndex ofObject: blockClosure. (self isContext: outerContext) ifFalse: [^self primitiveFail]. closureMethod := self fetchPointer: MethodIndex ofObject: outerContext. "Check if the closure's method is actually a CompiledMethod." ((self isNonIntegerObject: closureMethod) and: [self isCompiledMethod: closureMethod]) ifFalse: [^self primitiveFail]. "Check if copiedValues is either nil or anArray." copiedValues := self fetchPointer: ClosureCopiedValuesIndex ofObject: blockClosure. (copiedValues == nilObj or: [(self fetchClassOf: copiedValues) = (self splObj: ClassArray)]) ifFalse: [^self primitiveFail]. self activateNewClosureMethod: blockClosure! ! !Interpreter methodsFor: 'control primitives' stamp: 'eem 8/22/2008 15:36'! primitiveClosureValueWithArgs | argumentArray arraySize cntxSize blockClosure blockArgumentCount closureMethod index copiedValues outerContext | argumentArray := self stackTop. (self isArray: argumentArray) ifFalse: [^self primitiveFail]. "Check for enough space in thisContext to push all args" arraySize := self fetchWordLengthOf: argumentArray. cntxSize := self fetchWordLengthOf: activeContext. (self stackPointerIndex + arraySize) < cntxSize ifFalse: [^self primitiveFail]. blockClosure := self stackValue: argumentCount. blockArgumentCount := self argumentCountOfClosure: blockClosure. arraySize = blockArgumentCount ifFalse: [^self primitiveFail]. "Somewhat paranoiac checks we need while debugging that we may be able to discard in a robust system." outerContext := self fetchPointer: ClosureOuterContextIndex ofObject: blockClosure. (self isContext: outerContext) ifFalse: [^self primitiveFail]. closureMethod := self fetchPointer: MethodIndex ofObject: outerContext. "Check if the closure's method is actually a CompiledMethod." ((self isNonIntegerObject: closureMethod) and: [self isCompiledMethod: closureMethod]) ifFalse: [^self primitiveFail]. "Check if copiedValues is either nil or anArray." copiedValues := self fetchPointer: ClosureCopiedValuesIndex ofObject: blockClosure. (copiedValues == nilObj or: [(self fetchClassOf: copiedValues) = (self splObj: ClassArray)]) ifFalse: [^self primitiveFail]. self popStack. "Copy the arguments to the stack, and activate" index := 1. [index <= arraySize] whileTrue: [self push: (self fetchPointer: index - 1 ofObject: argumentArray). index := index + 1]. argumentCount := arraySize. self activateNewClosureMethod: blockClosure. self quickCheckForInterrupts! ! !Interpreter methodsFor: 'control primitives' stamp: 'eem 5/27/2008 15:40'! primitiveExecuteMethodArgsArray "receiver, argsArray, then method are on top of stack. Execute method against receiver and args" | methodArgument argCnt argumentArray | methodArgument := self popStack. argumentArray := self popStack. ((self isNonIntegerObject: methodArgument) and: [(self isCompiledMethod: newMethod) and: [self isArray: argumentArray]]) ifFalse: [self unPop: 2. ^self primitiveFail]. argCnt := self argumentCountOf: methodArgument. argCnt = (self fetchWordLengthOf: argumentArray) ifFalse: [self unPop: 2. ^self primitiveFail]. self transfer: argCnt from: argumentArray + BaseHeaderSize to: stackPointer + BytesPerWord. self unPop: argCnt. newMethod := methodArgument. primitiveIndex := self primitiveIndexOf: newMethod. argumentCount := argCnt. self executeNewMethod! ! !ObjectMemory class methodsFor: 'initialization' stamp: 'eem 5/23/2008 16:47'! initializeSpecialObjectIndices "Initialize indices into specialObjects array." NilObject := 0. FalseObject := 1. TrueObject := 2. SchedulerAssociation := 3. ClassBitmap := 4. ClassInteger := 5. ClassString := 6. ClassArray := 7. "SmalltalkDictionary := 8." "Do not delete!!" ClassFloat := 9. ClassMethodContext := 10. ClassBlockContext := 11. ClassPoint := 12. ClassLargePositiveInteger := 13. TheDisplay := 14. ClassMessage := 15. ClassCompiledMethod := 16. TheLowSpaceSemaphore := 17. ClassSemaphore := 18. ClassCharacter := 19. SelectorDoesNotUnderstand := 20. SelectorCannotReturn := 21. ProcessSignalingLowSpace := 22. "was TheInputSemaphore" SpecialSelectors := 23. CharacterTable := 24. SelectorMustBeBoolean := 25. ClassByteArray := 26. ClassProcess := 27. CompactClasses := 28. TheTimerSemaphore := 29. TheInterruptSemaphore := 30. SelectorCannotInterpret := 34. "Was MethodContextProto := 35." ClassBlockClosure := 36. "Was BlockContextProto := 37." ExternalObjectsArray := 38. ClassPseudoContext := 39. ClassTranslatedMethod := 40. TheFinalizationSemaphore := 41. ClassLargeNegativeInteger := 42. ClassExternalAddress := 43. ClassExternalStructure := 44. ClassExternalData := 45. ClassExternalFunction := 46. ClassExternalLibrary := 47. SelectorAboutToReturn := 48. SelectorRunWithIn := 49. ! ! !Interpreter class methodsFor: 'initialization' stamp: 'eem 6/16/2008 10:07'! initializeBytecodeTable "Interpreter initializeBytecodeTable" "Note: This table will be used to generate a C switch statement." BytecodeTable := Array new: 256. self table: BytecodeTable from: #( ( 0 15 pushReceiverVariableBytecode) ( 16 31 pushTemporaryVariableBytecode) ( 32 63 pushLiteralConstantBytecode) ( 64 95 pushLiteralVariableBytecode) ( 96 103 storeAndPopReceiverVariableBytecode) (104 111 storeAndPopTemporaryVariableBytecode) (112 pushReceiverBytecode) (113 pushConstantTrueBytecode) (114 pushConstantFalseBytecode) (115 pushConstantNilBytecode) (116 pushConstantMinusOneBytecode) (117 pushConstantZeroBytecode) (118 pushConstantOneBytecode) (119 pushConstantTwoBytecode) (120 returnReceiver) (121 returnTrue) (122 returnFalse) (123 returnNil) (124 returnTopFromMethod) (125 returnTopFromBlock) (126 127 unknownBytecode) (128 extendedPushBytecode) (129 extendedStoreBytecode) (130 extendedStoreAndPopBytecode) (131 singleExtendedSendBytecode) (132 doubleExtendedDoAnythingBytecode) (133 singleExtendedSuperBytecode) (134 secondExtendedSendBytecode) (135 popStackBytecode) (136 duplicateTopBytecode) (137 pushActiveContextBytecode) (138 pushNewArrayBytecode) (139 unknownBytecode) (140 pushRemoteTempLongBytecode) (141 storeRemoteTempLongBytecode) (142 storeAndPopRemoteTempLongBytecode) (143 pushClosureCopyCopiedValuesBytecode) (144 151 shortUnconditionalJump) (152 159 shortConditionalJump) (160 167 longUnconditionalJump) (168 171 longJumpIfTrue) (172 175 longJumpIfFalse) "176-191 were sendArithmeticSelectorBytecode" (176 bytecodePrimAdd) (177 bytecodePrimSubtract) (178 bytecodePrimLessThan) (179 bytecodePrimGreaterThan) (180 bytecodePrimLessOrEqual) (181 bytecodePrimGreaterOrEqual) (182 bytecodePrimEqual) (183 bytecodePrimNotEqual) (184 bytecodePrimMultiply) (185 bytecodePrimDivide) (186 bytecodePrimMod) (187 bytecodePrimMakePoint) (188 bytecodePrimBitShift) (189 bytecodePrimDiv) (190 bytecodePrimBitAnd) (191 bytecodePrimBitOr) "192-207 were sendCommonSelectorBytecode" (192 bytecodePrimAt) (193 bytecodePrimAtPut) (194 bytecodePrimSize) (195 bytecodePrimNext) (196 bytecodePrimNextPut) (197 bytecodePrimAtEnd) (198 bytecodePrimEquivalent) (199 bytecodePrimClass) (200 bytecodePrimBlockCopy) (201 bytecodePrimValue) (202 bytecodePrimValueWithArg) (203 bytecodePrimDo) (204 bytecodePrimNew) (205 bytecodePrimNewWithArg) (206 bytecodePrimPointX) (207 bytecodePrimPointY) (208 255 sendLiteralSelectorBytecode) ).! ! !Interpreter class methodsFor: 'initialization' stamp: 'eem 5/29/2008 12:18'! initializeContextIndices "Class MethodContext" SenderIndex := 0. InstructionPointerIndex := 1. StackPointerIndex := 2. MethodIndex := 3. ClosureIndex := 4. "N.B. Called receiverMap in the image." ReceiverIndex := 5. TempFrameStart := 6. "Note this is in two places!!" "Class BlockContext" CallerIndex := 0. BlockArgumentCountIndex := 3. InitialIPIndex := 4. HomeIndex := 5. "Class BlockClosure" ClosureOuterContextIndex := 0. ClosureStartPCIndex := 1. ClosureNumArgsIndex := 2. ClosureCopiedValuesIndex := 3! ! !Interpreter class methodsFor: 'initialization' stamp: 'eem 8/22/2008 15:09'! initializePrimitiveTable "This table generates a C function address table use in primitiveResponse along with dispatchFunctionPointerOn:in:" "NOTE: The real limit here is 2047 because of the method header layout but there is no point in going over the needed size" MaxPrimitiveIndex := 575. PrimitiveTable := Array new: MaxPrimitiveIndex + 1. self table: PrimitiveTable from: #( "Integer Primitives (0-19)" (0 primitiveFail) (1 primitiveAdd) (2 primitiveSubtract) (3 primitiveLessThan) (4 primitiveGreaterThan) (5 primitiveLessOrEqual) (6 primitiveGreaterOrEqual) (7 primitiveEqual) (8 primitiveNotEqual) (9 primitiveMultiply) (10 primitiveDivide) (11 primitiveMod) (12 primitiveDiv) (13 primitiveQuo) (14 primitiveBitAnd) (15 primitiveBitOr) (16 primitiveBitXor) (17 primitiveBitShift) (18 primitiveMakePoint) (19 primitiveFail) "Guard primitive for simulation -- *must* fail" "LargeInteger Primitives (20-39)" (20 primitiveFail) (21 primitiveAddLargeIntegers) (22 primitiveSubtractLargeIntegers) (23 primitiveLessThanLargeIntegers) (24 primitiveGreaterThanLargeIntegers) (25 primitiveLessOrEqualLargeIntegers) (26 primitiveGreaterOrEqualLargeIntegers) (27 primitiveEqualLargeIntegers) (28 primitiveNotEqualLargeIntegers) (29 primitiveMultiplyLargeIntegers) (30 primitiveDivideLargeIntegers) (31 primitiveModLargeIntegers) (32 primitiveDivLargeIntegers) (33 primitiveQuoLargeIntegers) (34 primitiveBitAndLargeIntegers) (35 primitiveBitOrLargeIntegers) (36 primitiveBitXorLargeIntegers) (37 primitiveBitShiftLargeIntegers) (38 primitiveFail) (39 primitiveFail) "Float Primitives (40-59)" (40 primitiveAsFloat) (41 primitiveFloatAdd) (42 primitiveFloatSubtract) (43 primitiveFloatLessThan) (44 primitiveFloatGreaterThan) (45 primitiveFloatLessOrEqual) (46 primitiveFloatGreaterOrEqual) (47 primitiveFloatEqual) (48 primitiveFloatNotEqual) (49 primitiveFloatMultiply) (50 primitiveFloatDivide) (51 primitiveTruncated) (52 primitiveFractionalPart) (53 primitiveExponent) (54 primitiveTimesTwoPower) (55 primitiveSquareRoot) (56 primitiveSine) (57 primitiveArctan) (58 primitiveLogN) (59 primitiveExp) "Subscript and Stream Primitives (60-67)" (60 primitiveAt) (61 primitiveAtPut) (62 primitiveSize) (63 primitiveStringAt) (64 primitiveStringAtPut) (65 primitiveFail) "was primitiveNext which no longer pays its way (normal Smalltalk code is faster)" (66 primitiveFail) "was primitiveNextPut which no longer pays its way (normal Smalltalk code is faster)" (67 primitiveFail) "was primitiveAtEnd which no longer pays its way (normal Smalltalk code is faster)" "StorageManagement Primitives (68-79)" (68 primitiveObjectAt) (69 primitiveObjectAtPut) (70 primitiveNew) (71 primitiveNewWithArg) (72 primitiveArrayBecomeOneWay) "Blue Book: primitiveBecome" (73 primitiveInstVarAt) (74 primitiveInstVarAtPut) (75 primitiveAsOop) (76 primitiveStoreStackp) "Blue Book: primitiveAsObject" (77 primitiveSomeInstance) (78 primitiveNextInstance) (79 primitiveNewMethod) "Control Primitives (80-89)" (80 primitiveBlockCopy) (81 primitiveValue) (82 primitiveValueWithArgs) (83 primitivePerform) (84 primitivePerformWithArgs) (85 primitiveSignal) (86 primitiveWait) (87 primitiveResume) (88 primitiveSuspend) (89 primitiveFlushCache) "Input/Output Primitives (90-109)" (90 primitiveMousePoint) (91 primitiveTestDisplayDepth) "Blue Book: primitiveCursorLocPut" (92 primitiveSetDisplayMode) "Blue Book: primitiveCursorLink" (93 primitiveInputSemaphore) (94 primitiveGetNextEvent) "Blue Book: primitiveSampleInterval" (95 primitiveInputWord) (96 primitiveFail) "primitiveCopyBits" (97 primitiveSnapshot) (98 primitiveStoreImageSegment) (99 primitiveLoadImageSegment) (100 primitivePerformInSuperclass) "Blue Book: primitiveSignalAtTick" (101 primitiveBeCursor) (102 primitiveBeDisplay) (103 primitiveScanCharacters) (104 primitiveFail) "primitiveDrawLoop" (105 primitiveStringReplace) (106 primitiveScreenSize) (107 primitiveMouseButtons) (108 primitiveKbdNext) (109 primitiveKbdPeek) "System Primitives (110-119)" (110 primitiveEquivalent) (111 primitiveClass) (112 primitiveBytesLeft) (113 primitiveQuit) (114 primitiveExitToDebugger) (115 primitiveChangeClass) "Blue Book: primitiveOopsLeft" (116 primitiveFlushCacheByMethod) (117 primitiveExternalCall) (118 primitiveDoPrimitiveWithArgs) (119 primitiveFlushCacheSelective) "Squeak 2.2 and earlier use 119. Squeak 2.3 and later use 116. Both are supported for backward compatibility." "Miscellaneous Primitives (120-127)" (120 primitiveCalloutToFFI) (121 primitiveImageName) (122 primitiveNoop) "Blue Book: primitiveImageVolume" (123 primitiveValueUninterruptably) "@@@: Remove this when all VMs have support" (124 primitiveLowSpaceSemaphore) (125 primitiveSignalAtBytesLeft) "Squeak Primitives Start Here" "Squeak Miscellaneous Primitives (128-149)" (126 primitiveDeferDisplayUpdates) (127 primitiveShowDisplayRect) (128 primitiveArrayBecome) (129 primitiveSpecialObjectsOop) (130 primitiveFullGC) (131 primitiveIncrementalGC) (132 primitiveObjectPointsTo) (133 primitiveSetInterruptKey) (134 primitiveInterruptSemaphore) (135 primitiveMillisecondClock) (136 primitiveSignalAtMilliseconds) (137 primitiveSecondsClock) (138 primitiveSomeObject) (139 primitiveNextObject) (140 primitiveBeep) (141 primitiveClipboardText) (142 primitiveVMPath) (143 primitiveShortAt) (144 primitiveShortAtPut) (145 primitiveConstantFill) "NOTE: When removing the obsolete indexed primitives, the following two should go become #primitiveIntegerAt / atPut" (146 primitiveFail) "primitiveReadJoystick" (147 primitiveFail) "primitiveWarpBits" (148 primitiveClone) (149 primitiveGetAttribute) "File Primitives (150-169) - NO LONGER INDEXED" (150 164 primitiveFail) (165 primitiveIntegerAt) "hacked in here for now" (166 primitiveIntegerAtPut) (167 primitiveYield) (168 primitiveCopyObject) (169 primitiveFail) "Sound Primitives (170-199) - NO LONGER INDEXED" (170 185 primitiveFail) "Old closure primitives" (186 primitiveFail) "was primitiveClosureValue" (187 primitiveFail) "was primitiveClosureValueWithArgs" "Perform method directly" (188 primitiveExecuteMethodArgsArray) (189 primitiveExecuteMethod) "Sound Primitives (continued) - NO LONGER INDEXED" (190 194 primitiveFail) "Unwind primitives" (195 primitiveFindNextUnwindContext) (196 primitiveTerminateTo) (197 primitiveFindHandlerContext) (198 primitiveMarkUnwindMethod) (199 primitiveMarkHandlerMethod) "new closure primitives (were Networking primitives)" (200 primitiveClosureCopyWithCopiedValues) (201 primitiveClosureValue) "value" (202 primitiveClosureValue) "value:" (203 primitiveClosureValue) "value:value:" (204 primitiveClosureValue) "value:value:value:" (205 primitiveClosureValue) "value:value:value:value:" (206 primitiveClosureValueWithArgs) "valueWithArguments:" (207 209 primitiveFail) "reserved for Cog primitives" (210 primitiveAt) "Compatibility with Cog StackInterpreter Context primitives" (211 primitiveAtPut) "Compatibility with Cog StackInterpreter Context primitives" (212 primitiveSize) "Compatibility with Cog StackInterpreter Context primitives" (213 219 primitiveFail) "reserved for Cog primitives" (220 primitiveFail) "reserved for Cog primitives" (221 primitiveClosureValueNoContextSwitch) "valueNoContextSwitch" (222 primitiveClosureValueNoContextSwitch) "valueNoContextSwitch:" (223 229 primitiveFail) "reserved for Cog primitives" (230 primitiveRelinquishProcessor) (231 primitiveForceDisplayUpdate) (232 primitiveFormPrint) (233 primitiveSetFullScreen) (234 primitiveFail) "primBitmapdecompressfromByteArrayat" (235 primitiveFail) "primStringcomparewithcollated" (236 primitiveFail) "primSampledSoundconvert8bitSignedFromto16Bit" (237 primitiveFail) "primBitmapcompresstoByteArray" (238 241 primitiveFail) "serial port primitives" (242 primitiveFail) (243 primitiveFail) "primStringtranslatefromtotable" (244 primitiveFail) "primStringfindFirstInStringinSetstartingAt" (245 primitiveFail) "primStringindexOfAsciiinStringstartingAt" (246 primitiveFail) "primStringfindSubstringinstartingAtmatchTable" (247 primitiveSnapshotEmbedded) (248 primitiveInvokeObjectAsMethod) (249 primitiveArrayBecomeOneWayCopyHash) "VM Implementor Primitives (250-255)" (250 clearProfile) (251 dumpProfile) (252 startProfiling) (253 stopProfiling) (254 primitiveVMParameter) (255 primitiveInstVarsPutFromStack) "Never used except in Disney tests. Remove after 2.3 release." "Quick Push Const Methods" (256 primitivePushSelf) (257 primitivePushTrue) (258 primitivePushFalse) (259 primitivePushNil) (260 primitivePushMinusOne) (261 primitivePushZero) (262 primitivePushOne) (263 primitivePushTwo) "Quick Push Const Methods" (264 519 primitiveLoadInstVar) "These ranges used to be used by obsiolete indexed primitives." (520 529 primitiveFail) (530 539 primitiveFail) (540 549 primitiveFail) (550 559 primitiveFail) (560 569 primitiveFail) "External primitive support primitives" (570 primitiveFlushExternalPrimitives) (571 primitiveUnloadModule) (572 primitiveListBuiltinModule) (573 primitiveListExternalModule) (574 primitiveFail) "reserved for addl. external support prims" "Unassigned Primitives" (575 primitiveFail)). ! ! !SystemDictionary methodsFor: 'special objects' stamp: 'eem 7/22/2008 18:37'! recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "The Special Objects Array is an array of object pointers used by the Squeak virtual machine. Its contents are critical and unchecked, so don't even think of playing here unless you know what you are doing." | newArray | newArray := Array new: 50. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self associationAt: #Processor). "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. newArray at: 10 put: Float. newArray at: 11 put: MethodContext. newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. newArray at: 18 put: (self specialObjectsArray at: 18). "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order." newArray at: 25 put: ((0 to: 255) collect: [:ascii | Character value: ascii]). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Prototype instances that can be copied for fast initialization" newArray at: 32 put: (Float new: 2). newArray at: 33 put: (LargePositiveInteger new: 4). newArray at: 34 put: Point new. newArray at: 35 put: #cannotInterpret:. "Note: This must be fixed once we start using context prototypes (yeah, right)" "(MethodContext new: CompiledMethod fullFrameSize)." newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. "(BlockContext new: CompiledMethod fullFrameSize)." newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" "array of objects referred to by external code" newArray at: 40 put: PseudoContext. newArray at: 41 put: TranslatedMethod. "finalization Semaphore" newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "Now replace the interpreter's reference in one atomic operation" self specialObjectsArray become: newArray! ! Interpreter removeSelector: #closureCopyNumArgs:instructionPointer:! Interpreter removeSelector: #closure:copiedValues:NumArgs:instructionPointer:! Interpreter removeSelector: #closure:copiedValues:numArgs:instructionPointer:! Interpreter removeSelector: #experimentalBytecode! Interpreter removeSelector: #isContext:header:! !Interpreter reorganize! ('initialization' dummyReferToProxy initialCleanup initializeInterpreter: loadInitialContext moduleUnloaded:) ('interpreter shell' fetchByte fetchNextBytecode getCurrentBytecode interpret unknownBytecode) ('message sending' activateNewMethod argCount commonSend createActualMessageTo: dispatchFunctionPointerOn:in: dispatchFunctionPointer: executeNewMethod executeNewMethodFromCache findNewMethodInClass: internalActivateNewMethod internalExecuteNewMethod internalFindNewMethod lookupMethodInClass: lookupMethodInDictionary: normalSend primitiveCalloutToFFI specialSelector: superclassOf: superclassSend) ('method lookup cache' addNewMethodToCache flushMethodCache flushMethodCacheFrom:to: functionPointerFor:inClass: lookupInMethodCacheSel:class: rewriteMethodCacheSel:class:primIndex: rewriteMethodCacheSel:class:primIndex:primFunction:) ('contexts' allocateOrRecycleContext: argumentCountOfBlock: argumentCountOfClosure: caller context:hasSender: fetchContextRegisters: fetchStackPointerOf: internalFetchContextRegisters: internalNewActiveContext: internalPop: internalPop:thenPush: internalPush: internalStackTop internalStackValue: internalStoreContextRegisters: isContextHeader: isContextNonInt: isContext: isMethodContextHeader: newActiveContext: pop2AndPushIntegerIfOK: popInteger popPos32BitInteger popStack pop: pop:thenPushBool: pop:thenPushInteger: pop:thenPush: pushBool: pushInteger: push: recycleContextIfPossible: sender stackArgvFloat: stackArgvInteger: stackArgvObject: stackFloatValue: stackIntegerValue: stackObjectValue: stackPointerIndex stackTop stackValue: storeContextRegisters: storeStackPointerValue:inContext: temporary: unPop:) ('compiled methods' argumentCountOf: headerOf: isHandlerMarked: isUnwindMarked: literalCountOfHeader: literalCountOf: literal: literal:ofMethod: methodClassOf: primitiveIndexOf: primitiveNewMethod tempCountOf:) ('jump bytecodes' jumplfFalseBy: jumplfTrueBy: jump: longJumpIfFalse longJumpIfTrue longUnconditionalJump shortConditionalJump shortUnconditionalJump) ('return bytecodes' commonReturn internalAboutToReturn:through: internalCannotReturn: returnFalse returnNil returnReceiver returnTopFromBlock returnTopFromMethod returnTrue) ('stack bytecodes' duplicateTopBytecode extendedPushBytecode extendedStoreAndPopBytecode extendedStoreBytecode popFloat popStackBytecode pushActiveContextBytecode pushClosureCopyCopiedValuesBytecode pushConstantFalseBytecode pushConstantMinusOneBytecode pushConstantNilBytecode pushConstantOneBytecode pushConstantTrueBytecode pushConstantTwoBytecode pushConstantZeroBytecode pushFloat: pushLiteralConstantBytecode pushLiteralConstant: pushLiteralVariableBytecode pushLiteralVariable: pushNewArrayBytecode pushReceiverBytecode pushReceiverVariableBytecode pushReceiverVariable: pushRemoteTempLongBytecode pushRemoteTemp:inVectorAt: pushTemporaryVariableBytecode pushTemporaryVariable: storeAndPopReceiverVariableBytecode storeAndPopRemoteTempLongBytecode storeAndPopTemporaryVariableBytecode storeRemoteTempLongBytecode storeRemoteTemp:inVectorAt:) ('send bytecodes' doubleExtendedDoAnythingBytecode secondExtendedSendBytecode sendLiteralSelectorBytecode singleExtendedSendBytecode singleExtendedSuperBytecode) ('common selector sends' bytecodePrimAdd bytecodePrimAt bytecodePrimAtEnd bytecodePrimAtPut bytecodePrimBitAnd bytecodePrimBitOr bytecodePrimBitShift bytecodePrimBlockCopy bytecodePrimClass bytecodePrimDiv bytecodePrimDivide bytecodePrimDo bytecodePrimEqual bytecodePrimEquivalent bytecodePrimGreaterOrEqual bytecodePrimGreaterThan bytecodePrimLessOrEqual bytecodePrimLessThan bytecodePrimMakePoint bytecodePrimMod bytecodePrimMultiply bytecodePrimNew bytecodePrimNewWithArg bytecodePrimNext bytecodePrimNextPut bytecodePrimNotEqual bytecodePrimPointX bytecodePrimPointY bytecodePrimSize bytecodePrimSubtract bytecodePrimValue bytecodePrimValueWithArg) ('primitive support' failed internalPrimitiveResponse positive32BitIntegerFor: positive32BitValueOf: positive64BitIntegerFor: positive64BitValueOf: primitiveFail primitiveResponse signed32BitIntegerFor: signed32BitValueOf: signed64BitIntegerFor: signed64BitValueOf: success:) ('arithmetic integer primitives' primitiveAdd primitiveBitAnd primitiveBitOr primitiveBitShift primitiveBitXor primitiveDiv primitiveDivide primitiveEqual primitiveGreaterOrEqual primitiveGreaterThan primitiveLessOrEqual primitiveLessThan primitiveMakePoint primitiveMod primitiveMultiply primitiveNotEqual primitiveQuo primitiveSubtract) ('arithmetic largeint primitives' primitiveAddLargeIntegers primitiveBitAndLargeIntegers primitiveBitOrLargeIntegers primitiveBitShiftLargeIntegers primitiveBitXorLargeIntegers primitiveDivideLargeIntegers primitiveDivLargeIntegers primitiveEqualLargeIntegers primitiveGreaterOrEqualLargeIntegers primitiveGreaterThanLargeIntegers primitiveLessOrEqualLargeIntegers primitiveLessThanLargeIntegers primitiveModLargeIntegers primitiveMultiplyLargeIntegers primitiveNotEqualLargeIntegers primitiveQuoLargeIntegers primitiveSubtractLargeIntegers) ('arithmetic float primitives' primitiveArctan primitiveAsFloat primitiveExp primitiveExponent primitiveFloatAdd primitiveFloatAdd:toArg: primitiveFloatDivide primitiveFloatDivide:byArg: primitiveFloatEqual primitiveFloatEqual:toArg: primitiveFloatGreaterOrEqual primitiveFloatGreaterThan primitiveFloatGreater:thanArg: primitiveFloatLessOrEqual primitiveFloatLessThan primitiveFloatLess:thanArg: primitiveFloatMultiply primitiveFloatMultiply:byArg: primitiveFloatNotEqual primitiveFloatSubtract primitiveFloatSubtract:fromArg: primitiveFractionalPart primitiveLogN primitiveSine primitiveSquareRoot primitiveTimesTwoPower primitiveTruncated) ('arithmetic primitive support' checkBooleanResult: checkIntegerResult: compare31or32Bits:equal: doPrimitiveDiv:by: doPrimitiveMod:by:) ('array primitives' install:inAtCache:at:string: primitiveAt primitiveAtPut primitiveCompareBytes primitiveSize primitiveStringAt primitiveStringAtPut primitiveStringReplace) ('array primitive support' asciiOfCharacter: byteLengthOf: characterForAscii: commonAtPut: commonAt: commonVariableInternal:at:cacheIndex: commonVariable:at:cacheIndex: commonVariable:at:put:cacheIndex: lengthOf: lengthOf:baseHeader:format: stObject:at: stObject:at:put: stSizeOf: subscript:with:format: subscript:with:storing:format:) ('control primitives' activateNewClosureMethod: closureIn:numArgs:instructionPointer: internalPrimitiveValue primitiveBlockCopy primitiveClosureCopyWithCopiedValues primitiveClosureValue primitiveClosureValueNoContextSwitch primitiveClosureValueWithArgs primitiveDoPrimitiveWithArgs primitiveExecuteMethod primitiveExecuteMethodArgsArray primitiveInvokeObjectAsMethod primitivePerform primitivePerformAt: primitivePerformInSuperclass primitivePerformWithArgs primitiveValue primitiveValueUninterruptably primitiveValueWithArgs) ('I/O primitives' displayBitsOf:Left:Top:Right:Bottom: primitiveBeCursor primitiveBeDisplay primitiveBeep primitiveClipboardText primitiveDeferDisplayUpdates primitiveForceDisplayUpdate primitiveForceTenure primitiveFormPrint primitiveGetLogDirectory primitiveGetNextEvent primitiveGetWindowLabel primitiveGetWindowSize primitiveInputSemaphore primitiveInputWord primitiveInterruptSemaphore primitiveKbdNext primitiveKbdPeek primitiveMouseButtons primitiveMousePoint primitiveRelinquishProcessor primitiveScanCharacters primitiveScreenDepth primitiveScreenSize primitiveSetDisplayMode primitiveSetFullScreen primitiveSetInterruptKey primitiveSetLogDirectory primitiveSetWindowLabel primitiveSetWindowSize primitiveShowDisplayRect primitiveTestDisplayDepth) ('I/O primitive support' fullDisplayUpdate reverseDisplayFrom:to: showDisplayBits:Left:Top:Right:Bottom:) ('bitblt support' copyBits copyBitsFrom:to:at: loadBitBltFrom:) ('image segment in/out' copyObj:toSegment:addr:stopAt:saveOopAt:headerAt: forward:to:savingOopAt:andHeaderAt: imageSegmentVersion oopHasAcceptableClass: primitiveFailAfterCleanup: primitiveLoadImageSegment primitiveStoreImageSegment restoreHeadersFrom:to:from:and:to:from:) ('memory space primitives' primitiveBytesLeft primitiveFullGC primitiveIncrementalGC primitiveIsRoot primitiveIsYoung primitiveLowSpaceSemaphore primitiveRootTable primitiveRootTableAt primitiveSetGCBiasToGrow primitiveSetGCBiasToGrowGCLimit primitiveSetGCSemaphore primitiveSignalAtBytesLeft) ('object memory support' mapInterpreterOops markAndTraceInterpreterOops postGCAction preGCAction: storePointerUnchecked:ofObject:withValue:) ('object access primitives' changeClassOf:to: primitiveArrayBecome primitiveArrayBecomeOneWay primitiveArrayBecomeOneWayCopyHash primitiveAsOop primitiveChangeClass primitiveClass primitiveClone primitiveCopyObject primitiveEquivalent primitiveInstVarAt primitiveInstVarAtPut primitiveNew primitiveNewWithArg primitiveNextInstance primitiveNextObject primitiveObjectAt primitiveObjectAtPut primitiveObjectPointsTo primitivePointX primitivePointY primitiveSomeInstance primitiveSomeObject primitiveStoreStackp sufficientSpaceToInstantiate:indexableSize:) ('object format' byteSizeOf: fixedFieldsOf:format:length: floatObjectOf: formatOfClass: isIndexable: nonWeakFieldsOf: slotSizeOf:) ('other primitives' primitiveIdentityDictionaryLookup primitiveImageName) ('plugin primitives' primitiveExternalCall primitiveFlushExternalPrimitives primitiveListBuiltinModule primitiveListExternalModule primitiveUnloadModule) ('plugin primitive support' callExternalPrimitive: classNameOf:Is: flushExternalPrimitiveOf: flushExternalPrimitives flushExternalPrimitiveTable getFullScreenFlag getInterruptCheckCounter getInterruptKeycode getInterruptPending getNextWakeupTick getSavedWindowSize includesBehavior:ThatOf: isFloatObject: is:KindOf: is:MemberOf: methodArgumentCount methodPrimitiveIndex primitiveMethod setFullScreenFlag: setInterruptCheckCounter: setInterruptKeycode: setInterruptPending: setNextWakeupTick: setSavedWindowSize:) ('plugin support' addToExternalPrimitiveTable: firstFixedField: firstIndexableField: getThisSessionID ioFilename:fromString:ofLength:resolveAliases: isBigEnder vmEndianness) ('process primitives' primitiveClearVMProfile primitiveFindHandlerContext primitiveFindNextUnwindContext primitiveInterruptChecksPerMSec primitiveMarkHandlerMethod primitiveMarkUnwindMethod primitiveProfilePrimitive primitiveProfileSample primitiveProfileSemaphore primitiveProfileStart primitiveResume primitiveSignal primitiveStartVMProfiling primitiveStopVMProfiling primitiveSuspend primitiveTerminateTo primitiveVMProfileInfoInto primitiveWait primitiveYield) ('process primitive support' addLastLink:toList: adjustInterruptCheckCounterFeedback checkForInterrupts forceInterruptCheck internalQuickCheckForInterrupts interruptCheckForced isEmptyList: putToSleep: quickCheckForInterrupts removeFirstLinkOfList: removeProcess:fromList: resume: saveProcessSignalingLowSpace schedulerPointer signalExternalSemaphores signalFinalization: signalSemaphoreWithIndex: synchronousSignal: transferTo: wakeHighestPriority) ('quick primitives' primitiveInstVarsPutFromStack primitiveLoadInstVar primitivePushFalse primitivePushMinusOne primitivePushNil primitivePushOne primitivePushSelf primitivePushTrue primitivePushTwo primitivePushZero) ('sound primitives' primitiveConstantFill primitiveIntegerAt primitiveIntegerAtPut primitiveShortAt primitiveShortAtPut) ('system control primitives' primitiveDisablePowerManager primitiveExitToDebugger primitiveFlushCache primitiveFlushCacheByMethod primitiveFlushCacheSelective primitiveGetAttribute primitiveHighResClock primitiveMillisecondClock primitiveNoop primitiveQuit primitiveSecondsClock primitiveSignalAtMilliseconds primitiveSnapshot primitiveSnapshotEmbedded primitiveSpecialObjectsOop primitiveVMParameter primitiveVMPath) ('image save/restore' byteSwapByteObjects byteSwapByteObjectsFrom:to: byteSwapped: checkImageVersionFrom:startingAt: dumpImage: getLongFromFile:swap: imageFormatCompatibilityVersion imageFormatVersion putLong:toFile: readableFormat: readImageFromFile:HeapSize:StartingAt: reverseBytesFrom:to: reverseBytesInImage reverseWordsFrom:to: snapshotCleanUp snapshot: wordSwapped: writeImageFileIO: writeImageFile:) ('callback support' callbackEnter: callbackLeave:) ('compiler support' compilerCreateActualMessage:storingArgs: compilerFlushCacheHook: compilerFlushCache: compilerMapFrom:to: compilerMapHookFrom:to: compilerMark compilerMarkHook compilerPostGC compilerPostGCHook compilerPostSnapshot compilerPostSnapshotHook compilerPreGCHook: compilerPreGC: compilerPreSnapshot compilerPreSnapshotHook compilerProcessChange compilerProcessChangeHook compilerProcessChange:to: compilerTranslateMethod compilerTranslateMethodHook disableCompiler enableCompiler initCompilerHooks nullCompilerHook setCompilerInitialized:) ('debug printing' cr printAllStacks printCallStack printCallStackOf: printChar: printNameOfClass:count: printNum: printOop: printStringOf: printUnbalancedStackFromNamedPrimitive printUnbalancedStack: print:) ('debug support' allAccessibleObjectsOkay balancedStack:afterPrimitive:withArgs: capturePendingFinalizationSignals findClassOfMethod:forReceiver: findSelectorOfMethod:forReceiver: okayActiveProcessStack okayFields: okayInterpreterObjects okayOop: oopHasOkayClass: verifyCleanHeaders) ('utilities' areIntegers:and: arrayValueOf: assertClassOf:is: booleanCheat: booleanValueOf: checkedIntegerValueOf: externalizeIPandSP fetchArray:ofObject: fetchFloat:ofObject: fetchIntegerOrTruncFloat:ofObject: fetchInteger:ofObject: floatValueOf: internalizeIPandSP loadFloatOrIntFrom: makePointwithxValue:yValue: quickFetchInteger:ofObject: signExtend16: sizeOfSTArrayFromCPrimitive: storeInteger:ofObject:withValue: transfer:fromIndex:ofObject:toIndex:ofObject: transfer:from:to:) ('translation support' expandCases) !