[Vm-dev] VM Maker: VMMaker-dtl.420.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Dec 21 02:24:04 UTC 2020


David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.420.mcz

==================== Summary ====================

Name: VMMaker-dtl.420
Author: dtl
Time: 20 December 2020, 9:10:42.452 pm
UUID: 25d351dc-3d71-45a5-adfe-95aa9f63e5bf
Ancestors: VMMaker-dtl.419

VMMaker 4.19.3
Let primitiveResumeFromSnapshot handle a changed image format for the resumed snapshot object.
Install and update an appropriate primitive table dynamically on entry to the interpreter loop.
Reset the image format number in the interpreter when resuming a snapshot object.
These changes enable e.g. a Squeak 4.6 image to resume into a Squeak 3.6 snapshot and vice versa.

=============== Diff against VMMaker-dtl.419 ===============

Item was changed:
  Interpreter subclass: #ContextInterpreter
+ 	instanceVariableNames: 'activeContext theHomeContext method receiver instructionPointer stackPointer localIP localSP localHomeContext localReturnContext localReturnValue messageSelector currentBytecode primitiveIndex primitiveFunctionPointer methodCache atCache lkupClass reclaimableContextCount nextPollTick nextWakeupTick lastTick interruptPending savedWindowSize deferDisplayUpdates pendingFinalizationSignals compilerInitialized compilerHooks newNativeMethod methodClass receiverClass interpreterVersion imageFormatVersionNumber interpreterProxy showSurfaceFn interruptCheckCounter interruptCheckCounterFeedBackReset interruptChecksEveryNms externalPrimitiveTable primitiveTableDefaults globalSessionID jmpBuf jmpDepth jmpMax suspendedCallbacks suspendedMethods imageFormatInitialVersion allowAccessBeyondSP'
- 	instanceVariableNames: 'activeContext theHomeContext method receiver instructionPointer stackPointer localIP localSP localHomeContext localReturnContext localReturnValue messageSelector currentBytecode primitiveIndex primitiveFunctionPointer methodCache atCache lkupClass reclaimableContextCount nextPollTick nextWakeupTick lastTick interruptPending savedWindowSize deferDisplayUpdates pendingFinalizationSignals compilerInitialized compilerHooks newNativeMethod methodClass receiverClass interpreterVersion imageFormatVersionNumber interpreterProxy showSurfaceFn interruptCheckCounter interruptCheckCounterFeedBackReset interruptChecksEveryNms externalPrimitiveTable globalSessionID jmpBuf jmpDepth jmpMax suspendedCallbacks suspendedMethods imageFormatInitialVersion allowAccessBeyondSP'
  	classVariableNames: 'BlockArgumentCountIndex BytecodeTable CacheProbeMax CallerIndex CompilerHooksSize DirBadPath DirEntryFound DirNoMoreEntries DoBalanceChecks HomeIndex InitialIPIndex MaxJumpBuf MessageDictionaryIndex MethodCacheNative TempFrameStart'
  	poolDictionaries: 'VMMethodCacheConstants VMSqueakV3BytecodeConstants'
  	category: 'VMMaker-Interpreter'!
  
  !ContextInterpreter commentStamp: '<historical>' prior: 0!
  This class is a complete implementation of the Smalltalk-80 virtual machine, derived originally from the Blue Book specification but quite different in some areas.
  
  It has been modernized with 32-bit pointers, better management of Contexts, and attention to variable use that allows the CCodeGenerator (qv) to keep, eg, the instruction pointer and stack pointer in registers as well as keeping most simple variables in a global array that seems to improve performance for most platforms.
  
  In addition to SmallInteger arithmetic and Floats, it supports logic on 32-bit PositiveLargeIntegers, thus allowing it to simulate itself much more effectively than would otherwise be the case.
  
  NOTE:  Here follows a list of things to be borne in mind when working on this code, or when making changes for the future.
  
  1.  There are a number of things that should be done the next time we plan to release a copletely incompatible image format.  These include unifying the instanceSize field of the class format word -- see instantiateClass:indexableSize:, and unifying the bits of the method primitive index (if we decide we need more than 512, after all) -- see primitiveIndexOf:.  Also, contexts should be given a special format code (see next item).
  
  2.  There are several fast checks for contexts (see isContextHeader: and isMethodContextHeader:) which will fail if the compact class indices of BlockContext or MethodContext change.  This is necessary because the oops may change during a compaction when the oops are being adjusted.  It's important to be aware of this when writing a new image using the systemTracer.  A better solution would be to reserve one of the format codes for Contexts only.
  
  3.  We have made normal files tolerant to size and positions up to 32 bits.  This has not been done for async files, since they are still experimental.  The code in size, at: and at:put: should work with sizes and indices up to 31 bits, although I have not tested it (di 12/98); it might or might not work with 32-bit sizes.
  
  4.  Note that 0 is used in a couple of places as an impossible oop.  This should be changed to a constant that really is impossible (or perhaps there is code somewhere that guarantees it --if so it should be put in this comment).  The places include the method cache and the at cache. !

Item was changed:
  ----- Method: ContextInterpreter class>>declareCVarsIn: (in category 'translation') -----
  declareCVarsIn: aCCodeGenerator 
  	aCCodeGenerator addHeaderFile: '<setjmp.h>'.
  	aCCodeGenerator var: #interpreterProxy type: #'struct VirtualMachine*'.
  	"declare primitiveTable as an array of pointers to a function returning void, taking no arguments"
  	aCCodeGenerator var: #primitiveFunctionPointer declareC: 'void (*primitiveFunctionPointer)(void)'.
  	aCCodeGenerator var: #methodCache declareC: 'long methodCache[' , (MethodCacheSize + 1) printString , ']'.
  	aCCodeGenerator var: #atCache declareC: 'sqInt atCache[' , (AtCacheTotalSize + 1) printString , ']'.
  	aCCodeGenerator var: #statGCTime type: #sqLong.
  	aCCodeGenerator var: #statFullGCMSecs type: #sqLong.
  	aCCodeGenerator var: #statIGCDeltaTime type: #sqLong.
  	aCCodeGenerator var: #statIncrGCMSecs type: #sqLong.
  	aCCodeGenerator var: #localIP type: #'char*'.
  	aCCodeGenerator var: #localSP type: #'char*'.
  	aCCodeGenerator var: #showSurfaceFn type: #'void*'.
  	aCCodeGenerator var: #compilerHooks declareC: 'sqInt (*compilerHooks[' , (CompilerHooksSize + 1) printString , '])()'.
  	aCCodeGenerator var: #interpreterVersion declareC: 'const char *interpreterVersion = "' , SmalltalkImage current datedVersion , ' [' , SmalltalkImage current lastUpdateString , ']"'.
  	self declareCAsOop: {#instructionPointer. #method. #newMethod. #activeContext. #theHomeContext. #stackPointer} in: aCCodeGenerator.
  	aCCodeGenerator var: #jmpBuf declareC: 'jmp_buf jmpBuf[' , (MaxJumpBuf + 1) printString , ']'.
  	aCCodeGenerator var: #suspendedCallbacks declareC: 'sqInt suspendedCallbacks[' , (MaxJumpBuf + 1) printString , ']'.
  	aCCodeGenerator var: #suspendedMethods declareC: 'sqInt suspendedMethods[' , (MaxJumpBuf + 1) printString , ']'.
  	"Reinitialized at interpreter entry by #initializeImageFormatVersion"
  	aCCodeGenerator var: #imageFormatVersionNumber declareC: 'sqInt imageFormatVersionNumber = 0'.
  	"Declared here to prevent inclusion in foo struct by
  	CCodeGeneratorGlobalStructure"
  	aCCodeGenerator var: #imageFormatInitialVersion declareC: 'sqInt imageFormatInitialVersion = 0'.
+ 	aCCodeGenerator var: #primitiveTable declareC: 'void (*primitiveTable[', MaxPrimitiveIndex asString, '])(void)'.
+ 	aCCodeGenerator var: #primitiveTableDefaults declareC: 'void (*primitiveTableDefaults[' , (MaxPrimitiveIndex + 2) printString , '] )(void)= ' , self primitiveTableString.
- 	aCCodeGenerator var: #primitiveTable declareC: 'void (*primitiveTable[' , (MaxPrimitiveIndex + 2) printString , '] )(void)= ' , self primitiveTableString.
  	aCCodeGenerator var: #externalPrimitiveTable declareC: 'void (*externalPrimitiveTable[' , (MaxExternalPrimitiveTableSize + 1) printString , '])(void)'.
  !

Item was added:
+ ----- Method: ContextInterpreter>>installPrimitiveTable (in category 'primitive table') -----
+ installPrimitiveTable
+ 	<inline: false>
+ 	0 to: MaxPrimitiveIndex do: [ :i |
+ 		primitiveTable at: i put: (primitiveTableDefaults at: i) ].
+ 	self updatePrimitiveTable.
+ !

Item was changed:
  ----- Method: ContextInterpreter>>interpret (in category 'interpreter shell') -----
  interpret
  	"This is the main interpreter loop. It normally loops forever, fetching and executing bytecodes. When running in the context of a browser plugin VM, however, it must return control to the browser periodically. This should done only when the state of the currently running Squeak thread is safely stored in the object heap. Since this is the case at the moment that a check for interrupts is performed, that is when we return to the browser if it is time to do so. Interrupt checks happen quite frequently."
  
  	<inline: false> "should not be inlined into any senders"
  	self initializeImageFormatVersion.
+ 	self installPrimitiveTable.
- 	self updatePrimitiveTable..
  	allowAccessBeyondSP := self useOldPrimitives. "some old images must disable stack bounds check"
  	self browserPluginInitialiseIfNeeded. "record entry time when running as a browser plug-in"
  	self internalizeIPandSP.
  	self fetchNextBytecode.
  	[true] whileTrue: [self dispatchOn: currentBytecode in: BytecodeTable].
  	localIP := localIP - 1.  "undo the pre-increment of IP before returning"
  	self externalizeIPandSP.
  !

Item was changed:
  ----- Method: ContextInterpreter>>primitiveResumeFromSnapshot (in category 'snapshot utility primitives') -----
  primitiveResumeFromSnapshot
  	"Discard the current object memory and resume interpreter execution
  	in the provided snapshot."
  
  	| expectedArraySize snapshotValues size newMemoryBytesOrBitmap bigEndian snapshotImageFormat snapshotStartOfMemory snapshotSpecialObjectsOop snapshotLastHash screenSizePoint headerSize imageBytes imageHeaderFlags snapshotExtraVMMemory swapBytes snapshotFullScreen defaultHeapSize desiredHeapSize |
  	<export: true>
  	expectedArraySize := 11. "ImageSnapshot new asValues size => 11"
  	argumentCount == 1
  		ifFalse: [ ^self primitiveFailFor: PrimErrBadNumArgs].
  	snapshotValues := self stackObjectValue: 0.
  	self assertClassOf: snapshotValues is: (objectMemory splObj: ClassArray).
  	self successful
  		ifFalse: [ ^self primitiveFailFor: PrimErrBadArgument].
  	size := objectMemory numSlotsOf: snapshotValues.
  	size < expectedArraySize ifTrue: [ ^self primitiveFailFor: PrimErrBadArgument].
  	newMemoryBytesOrBitmap := objectMemory fetchPointer: 0 ofObject: snapshotValues.
  	bigEndian := (objectMemory fetchPointer: 1 ofObject: snapshotValues) = objectMemory trueObject.
  	snapshotImageFormat := objectMemory integerValueOf: (objectMemory fetchPointer: 2 ofObject: snapshotValues)..
  	(self readableFormat: snapshotImageFormat)
  		ifFalse: [ ^self primitiveFailFor: PrimErrInappropriate ].
  	headerSize := objectMemory integerValueOf: (objectMemory fetchPointer: 3 ofObject: snapshotValues)..
  	imageBytes := self positive32BitValueOf: (objectMemory fetchPointer: 4 ofObject: snapshotValues).. "good for up to 2GB image"
  	snapshotStartOfMemory := objectMemory integerValueOf: (objectMemory fetchPointer: 5 ofObject: snapshotValues)..
  	snapshotSpecialObjectsOop := objectMemory integerValueOf: (objectMemory fetchPointer: 6 ofObject: snapshotValues)..
  	snapshotLastHash := objectMemory integerValueOf: (objectMemory fetchPointer: 7 ofObject: snapshotValues)..
  	screenSizePoint := objectMemory fetchPointer: 8 ofObject: snapshotValues..
  	self assertClassOf: screenSizePoint is: (objectMemory splObj: ClassPoint).
  	self successful
  		ifFalse: [ ^self primitiveFailFor: PrimErrBadArgument].
  	imageHeaderFlags := objectMemory integerValueOf: (objectMemory fetchPointer: 9 ofObject: snapshotValues)..
  	snapshotExtraVMMemory := objectMemory integerValueOf: (objectMemory fetchPointer: 10 ofObject: snapshotValues)..
+ 	imageFormatVersionNumber := 0.
+ 	imageFormatInitialVersion := snapshotImageFormat.
  
  	swapBytes := bigEndian ~= self isBigEnder.
  	snapshotFullScreen := false. "FIXME"
  
  	"From sqUnixMain.c
  	#define DefaultHeapSize           20
  		megabytes BEYOND actual image size"
  	defaultHeapSize := 20 * 1000 * 1000.
  	desiredHeapSize := defaultHeapSize + imageBytes.
  
  	self
  		snapshotResume: newMemoryBytesOrBitmap
  		heapSize: desiredHeapSize
  		swapBytes: swapBytes
  		oldBaseAddr: snapshotStartOfMemory
  		specialObjectsOop: snapshotSpecialObjectsOop
  		lastHash: snapshotLastHash
  		savedWindowSize: screenSizePoint
  		fullScreenFlag: snapshotFullScreen
  		extraVMMemory: snapshotExtraVMMemory.
  
  	self pop: 1 thenPush: newMemoryBytesOrBitmap.
  
  !

Item was added:
+ ----- Method: ContextInterpreter>>updatePrimitiveTable (in category 'primitive table') -----
+ updatePrimitiveTable
+ 	"Make any run time updates to the primitive table that may be required for supporting
+ 	the current running image. May be called by an interpreter that determines at run time
+ 	that it needs to provide support for an older image.
+ 
+ 	References: The SqueakJS dispatch table, which is known to run the full range of Squeak
+ 	images, is used as a reference, along with comparison to the Squeak VM table as of
+ 	January 2005 from VMMaker-tpr.22, which was the last version prior to converting
+ 	images to support full closures  (dtl Dec 2016)"
+ 
+ 	<inline: false>
+ 	self useOldPrimitives ifTrue: [
+ 		self installPrimitive: #primitiveNext at: 65.
+ 		self installPrimitive: #primitiveNextPut at: 66.
+ 		self installPrimitive: #primitiveAtEnd at: 67.
+ 
+ 		self installPrimitive: #primitiveBlockCopy at: 80.
+ 		self installPrimitive: #primitiveValue at: 81.
+ 		self installPrimitive: #primitiveValueWithArgs at: 82.
+ 
+ 		self installPrimitive: 'primitiveCopyBits' from: 'BitBltPlugin' at: 96.
+ 
+ 		self installPrimitive: #primitiveValueUninterruptably at: 123.
+ 
+ 		self installPrimitive: 'primitiveReadJoystick' from: 'JoystickTabletPlugin' at: 146.
+ 
+ 		self installPrimitive: 'primitiveWarpBits' from: 'BitBltPlugin' at: 147.
+ 
+ 		self installPrimitive: 'primitiveFileAtEnd' from: 'FilePlugin' at: 150.
+ 		self installPrimitive: 'primitiveFileClose' from: 'FilePlugin'  at: 151.
+ 		self installPrimitive: 'primitiveFileGetPosition' from: 'FilePlugin' at: 152.
+ 		self installPrimitive: 'primitiveFileOpen' from: 'FilePlugin' at: 153.
+ 		self installPrimitive: 'primitiveFileRead' from: 'FilePlugin' at: 154.
+ 		self installPrimitive: 'primitiveFileSetPosition' from: 'FilePlugin' at: 155.
+ 		self installPrimitive: 'primitiveFileDelete' from: 'FilePlugin' at: 156.
+ 		self installPrimitive: 'primitiveFileSize' from: 'FilePlugin' at: 157.
+ 		self installPrimitive: 'primitiveFileWrite' from: 'FilePlugin' at: 158.
+ 		self installPrimitive: 'primitiveFileRename' from: 'FilePlugin' at: 159.
+ 		self installPrimitive: 'primitiveDirectoryCreate' from: 'FilePlugin' at: 160.
+ 		self installPrimitive: 'primitiveDirectoryDelimitor' from: 'FilePlugin'at: 161.
+ 		self installPrimitive: 'primitiveDirectoryLookup' from: 'FilePlugin' at: 162.
+ 		self installPrimitive: 'primitiveDirectoryDelete' from: 'FilePlugin' at: 163.
+ 		self installPrimitive: 'primitiveDirectorySetMacTypeAndCreator' from: 'FilePlugin' at: 169.
+ 
+ 		self installPrimitive: 'primitiveSoundStart' from: 'SoundPlugin' at: 170.
+ 		self installPrimitive: 'primitiveSoundStartWithSemaphore' from: 'SoundPlugin' at: 171.
+ 		self installPrimitive: 'primitiveSoundStop' from: 'SoundPlugin' at: 172.
+ 		self installPrimitive: 'primitiveSoundAvailableSpace' from: 'SoundPlugin' at: 173.
+ 		self installPrimitive: 'primitiveSoundPlaySamples' from: 'SoundPlugin' at: 174.
+ 		self installPrimitive: 'primitiveSoundPlaySilence' from: 'SoundPlugin' at: 175.
+ 		self installPrimitive: 'primWaveTableSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 176.
+ 		self installPrimitive: 'primFMSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 177.
+ 		self installPrimitive: 'primPluckedSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 178.
+ 		self installPrimitive: 'primSampledSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 179.
+ 		self installPrimitive: 'primitiveMixFMSound' from: 'SoundGenerationPlugin' at: 180.
+ 		self installPrimitive: 'primitiveMixPluckedSound' from: 'SoundGenerationPlugin' at: 181.
+ 		self installPrimitive: 'oldprimSampledSoundmixSampleCountintostartingAtleftVolrightVol' from: 'SoundGenerationPlugin' at: 182.
+ 		self installPrimitive: 'primitiveApplyReverb' from: 'SoundGenerationPlugin' at: 183.
+ 		self installPrimitive: 'primitiveMixLoopedSampledSound' from: 'SoundGenerationPlugin' at: 184.
+ 		self installPrimitive: 'primitiveMixSampledSound' from: 'SoundGenerationPlugin' at: 185.
+ 
+ 		self installPrimitive: 'primitiveSoundInsertSamples' from: 'SoundPlugin' at: 189.
+ 
+ 		self installPrimitive: 'primitiveSoundStopRecording' from: 'SoundPlugin' at: 191.
+ 		self installPrimitive: 'primitiveSoundGetRecordingSampleRate' from: 'SoundPlugin' at: 192.
+ 		self installPrimitive: 'primitiveSoundRecordSamples' from: 'SoundPlugin' at: 193.
+ 		self installPrimitive: 'primitiveSoundSetRecordLevel' from: 'SoundPlugin' at: 194.
+ 
+ 		self installPrimitive: 'primitiveInitializeNetwork' from: 'SocketPlugin' at: 200.
+ 		self installPrimitive: 'primitiveResolverStartNameLookup' from: 'SocketPlugin' at: 201.
+ 		self installPrimitive: 'primitiveResolverNameLookupResult' from: 'SocketPlugin' at: 202.
+ 		self installPrimitive: 'primitiveResolverStartAddressLookup' from: 'SocketPlugin' at: 203.
+ 		self installPrimitive: 'primitiveResolverAddressLookupResult' from: 'SocketPlugin' at: 204.
+ 		self installPrimitive: 'primitiveResolverAbortLookup' from: 'SocketPlugin' at: 205.
+ 		self installPrimitive: 'primitiveResolverLocalAddress' from: 'SocketPlugin' at: 206.
+ 		self installPrimitive: 'primitiveResolverStatus' from: 'SocketPlugin' at: 207.
+ 		self installPrimitive: 'primitiveResolverError' from: 'SocketPlugin' at: 208.
+ 		self installPrimitive: 'primitiveSocketCreate' from: 'SocketPlugin' at: 209.
+ 		self installPrimitive: 'primitiveSocketDestroy' from: 'SocketPlugin' at: 210.
+ 		self installPrimitive: 'primitiveSocketConnectionStatus' from: 'SocketPlugin' at: 211.
+ 		self installPrimitive: 'primitiveSocketError' from: 'SocketPlugin' at: 212.
+ 		self installPrimitive: 'primitiveSocketLocalAddress' from: 'SocketPlugin' at: 213.
+ 		self installPrimitive: 'primitiveSocketLocalPort' from: 'SocketPlugin' at: 214.
+ 		self installPrimitive: 'primitiveSocketRemoteAddress' from: 'SocketPlugin' at: 215.
+ 		self installPrimitive: 'primitiveSocketRemotePort' from: 'SocketPlugin' at: 216.
+ 		self installPrimitive: 'primitiveSocketConnectToPort' from: 'SocketPlugin' at: 217.
+ 		self installPrimitive: 'primitiveSocketListenOnPort' from: 'SocketPlugin' at: 218.
+ 		self installPrimitive: 'primitiveSocketCloseConnection' from: 'SocketPlugin' at: 219.
+ 		self installPrimitive: 'primitiveSocketAbortConnection' from: 'SocketPlugin' at: 220.
+ 		self installPrimitive: 'primitiveSocketReceiveDataBufCount' from: 'SocketPlugin' at: 221.
+ 		self installPrimitive: 'primitiveSocketReceiveDataAvailable' from: 'SocketPlugin' at: 222.
+ 		self installPrimitive: 'primitiveSocketSendDataBufCount' from: 'SocketPlugin' at: 223.
+ 		self installPrimitive: 'primitiveSocketSendDone' from: 'SocketPlugin' at: 224.
+ 
+ 		self installPrimitive: 'primitiveDecompressFromByteArray' from: 'MiscPrimitivePlugin' at: 234.
+ 		self installPrimitive: 'primitiveCompareString' from: 'MiscPrimitivePlugin' at: 235.
+ 		self installPrimitive: 'primitiveConvert8BitSigned' from: 'MiscPrimitivePlugin' at: 236.
+ 		self installPrimitive: 'primitiveCompressToByteArray' from: 'MiscPrimitivePlugin' at: 237.
+ 
+ 		self installPrimitive: 'primitiveSerialPortOpen' from: 'SerialPlugin' at: 238.
+ 		self installPrimitive: 'primitiveSerialPortClose' from: 'SerialPlugin' at: 239.
+ 		self installPrimitive: 'primitiveSerialPortWrite' from: 'SerialPlugin' at: 240.
+ 		self installPrimitive: 'primitiveSerialPortRead' from: 'SerialPlugin' at: 241.
+ 
+ 		self installPrimitive: 'primitiveTranslateStringWithTable' from: 'MiscPrimitivePlugin' at: 243.
+ 		self installPrimitive: 'primitiveFindFirstInString' from: 'MiscPrimitivePlugin' at: 244.
+ 		self installPrimitive: 'primitiveIndexOfAsciiInString' from: 'MiscPrimitivePlugin' at: 245.
+ 		self installPrimitive: 'primitiveFindSubstring' from: 'MiscPrimitivePlugin' at: 246.
+ 	]
+ !

Item was removed:
- ----- Method: InterpreterPrimitives>>updatePrimitiveTable (in category 'primitive table') -----
- updatePrimitiveTable
- 	"Make any run time updates to the primitive table that may be required for supporting
- 	the current running image. May be called by an interpreter that determines at run time
- 	that it needs to provide support for an older image.
- 
- 	References: The SqueakJS dispatch table, which is known to run the full range of Squeak
- 	images, is used as a reference, along with comparison to the Squeak VM table as of
- 	January 2005 from VMMaker-tpr.22, which was the last version prior to converting
- 	images to support full closures  (dtl Dec 2016)"
- 
- 	| primitiveTableUpdated |
- 	<inline: false>
- 	<var: #primitiveTableUpdated type: 'static int'>
- 	primitiveTableUpdated == true ifFalse: [
- 		primitiveTableUpdated := true.
- 		self useOldPrimitives ifTrue: [
- 			self installPrimitive: #primitiveNext at: 65.
- 			self installPrimitive: #primitiveNextPut at: 66.
- 			self installPrimitive: #primitiveAtEnd at: 67.
- 
- 			self installPrimitive: #primitiveBlockCopy at: 80.
- 			self installPrimitive: #primitiveValue at: 81.
- 			self installPrimitive: #primitiveValueWithArgs at: 82.
- 
- 			self installPrimitive: 'primitiveCopyBits' from: 'BitBltPlugin' at: 96.
- 
- 			self installPrimitive: #primitiveValueUninterruptably at: 123.
- 
- 			self installPrimitive: 'primitiveReadJoystick' from: 'JoystickTabletPlugin' at: 146.
- 
- 			self installPrimitive: 'primitiveWarpBits' from: 'BitBltPlugin' at: 147.
- 
- 			self installPrimitive: 'primitiveFileAtEnd' from: 'FilePlugin' at: 150.
- 			self installPrimitive: 'primitiveFileClose' from: 'FilePlugin'  at: 151.
- 			self installPrimitive: 'primitiveFileGetPosition' from: 'FilePlugin' at: 152.
- 			self installPrimitive: 'primitiveFileOpen' from: 'FilePlugin' at: 153.
- 			self installPrimitive: 'primitiveFileRead' from: 'FilePlugin' at: 154.
- 			self installPrimitive: 'primitiveFileSetPosition' from: 'FilePlugin' at: 155.
- 			self installPrimitive: 'primitiveFileDelete' from: 'FilePlugin' at: 156.
- 			self installPrimitive: 'primitiveFileSize' from: 'FilePlugin' at: 157.
- 			self installPrimitive: 'primitiveFileWrite' from: 'FilePlugin' at: 158.
- 			self installPrimitive: 'primitiveFileRename' from: 'FilePlugin' at: 159.
- 			self installPrimitive: 'primitiveDirectoryCreate' from: 'FilePlugin' at: 160.
- 			self installPrimitive: 'primitiveDirectoryDelimitor' from: 'FilePlugin'at: 161.
- 			self installPrimitive: 'primitiveDirectoryLookup' from: 'FilePlugin' at: 162.
- 			self installPrimitive: 'primitiveDirectoryDelete' from: 'FilePlugin' at: 163.
- 			self installPrimitive: 'primitiveDirectorySetMacTypeAndCreator' from: 'FilePlugin' at: 169.
- 
- 			self installPrimitive: 'primitiveSoundStart' from: 'SoundPlugin' at: 170.
- 			self installPrimitive: 'primitiveSoundStartWithSemaphore' from: 'SoundPlugin' at: 171.
- 			self installPrimitive: 'primitiveSoundStop' from: 'SoundPlugin' at: 172.
- 			self installPrimitive: 'primitiveSoundAvailableSpace' from: 'SoundPlugin' at: 173.
- 			self installPrimitive: 'primitiveSoundPlaySamples' from: 'SoundPlugin' at: 174.
- 			self installPrimitive: 'primitiveSoundPlaySilence' from: 'SoundPlugin' at: 175.
- 			self installPrimitive: 'primWaveTableSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 176.
- 			self installPrimitive: 'primFMSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 177.
- 			self installPrimitive: 'primPluckedSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 178.
- 			self installPrimitive: 'primSampledSoundmixSampleCountintostartingAtpan' from: 'SoundGenerationPlugin' at: 179.
- 			self installPrimitive: 'primitiveMixFMSound' from: 'SoundGenerationPlugin' at: 180.
- 			self installPrimitive: 'primitiveMixPluckedSound' from: 'SoundGenerationPlugin' at: 181.
- 			self installPrimitive: 'oldprimSampledSoundmixSampleCountintostartingAtleftVolrightVol' from: 'SoundGenerationPlugin' at: 182.
- 			self installPrimitive: 'primitiveApplyReverb' from: 'SoundGenerationPlugin' at: 183.
- 			self installPrimitive: 'primitiveMixLoopedSampledSound' from: 'SoundGenerationPlugin' at: 184.
- 			self installPrimitive: 'primitiveMixSampledSound' from: 'SoundGenerationPlugin' at: 185.
- 
- 			self installPrimitive: 'primitiveSoundInsertSamples' from: 'SoundPlugin' at: 189.
- 
- 			self installPrimitive: 'primitiveSoundStopRecording' from: 'SoundPlugin' at: 191.
- 			self installPrimitive: 'primitiveSoundGetRecordingSampleRate' from: 'SoundPlugin' at: 192.
- 			self installPrimitive: 'primitiveSoundRecordSamples' from: 'SoundPlugin' at: 193.
- 			self installPrimitive: 'primitiveSoundSetRecordLevel' from: 'SoundPlugin' at: 194.
- 
- 			self installPrimitive: 'primitiveInitializeNetwork' from: 'SocketPlugin' at: 200.
- 			self installPrimitive: 'primitiveResolverStartNameLookup' from: 'SocketPlugin' at: 201.
- 			self installPrimitive: 'primitiveResolverNameLookupResult' from: 'SocketPlugin' at: 202.
- 			self installPrimitive: 'primitiveResolverStartAddressLookup' from: 'SocketPlugin' at: 203.
- 			self installPrimitive: 'primitiveResolverAddressLookupResult' from: 'SocketPlugin' at: 204.
- 			self installPrimitive: 'primitiveResolverAbortLookup' from: 'SocketPlugin' at: 205.
- 			self installPrimitive: 'primitiveResolverLocalAddress' from: 'SocketPlugin' at: 206.
- 			self installPrimitive: 'primitiveResolverStatus' from: 'SocketPlugin' at: 207.
- 			self installPrimitive: 'primitiveResolverError' from: 'SocketPlugin' at: 208.
- 			self installPrimitive: 'primitiveSocketCreate' from: 'SocketPlugin' at: 209.
- 			self installPrimitive: 'primitiveSocketDestroy' from: 'SocketPlugin' at: 210.
- 			self installPrimitive: 'primitiveSocketConnectionStatus' from: 'SocketPlugin' at: 211.
- 			self installPrimitive: 'primitiveSocketError' from: 'SocketPlugin' at: 212.
- 			self installPrimitive: 'primitiveSocketLocalAddress' from: 'SocketPlugin' at: 213.
- 			self installPrimitive: 'primitiveSocketLocalPort' from: 'SocketPlugin' at: 214.
- 			self installPrimitive: 'primitiveSocketRemoteAddress' from: 'SocketPlugin' at: 215.
- 			self installPrimitive: 'primitiveSocketRemotePort' from: 'SocketPlugin' at: 216.
- 			self installPrimitive: 'primitiveSocketConnectToPort' from: 'SocketPlugin' at: 217.
- 			self installPrimitive: 'primitiveSocketListenOnPort' from: 'SocketPlugin' at: 218.
- 			self installPrimitive: 'primitiveSocketCloseConnection' from: 'SocketPlugin' at: 219.
- 			self installPrimitive: 'primitiveSocketAbortConnection' from: 'SocketPlugin' at: 220.
- 			self installPrimitive: 'primitiveSocketReceiveDataBufCount' from: 'SocketPlugin' at: 221.
- 			self installPrimitive: 'primitiveSocketReceiveDataAvailable' from: 'SocketPlugin' at: 222.
- 			self installPrimitive: 'primitiveSocketSendDataBufCount' from: 'SocketPlugin' at: 223.
- 			self installPrimitive: 'primitiveSocketSendDone' from: 'SocketPlugin' at: 224.
- 
- 			self installPrimitive: 'primitiveDecompressFromByteArray' from: 'MiscPrimitivePlugin' at: 234.
- 			self installPrimitive: 'primitiveCompareString' from: 'MiscPrimitivePlugin' at: 235.
- 			self installPrimitive: 'primitiveConvert8BitSigned' from: 'MiscPrimitivePlugin' at: 236.
- 			self installPrimitive: 'primitiveCompressToByteArray' from: 'MiscPrimitivePlugin' at: 237.
- 
- 			self installPrimitive: 'primitiveSerialPortOpen' from: 'SerialPlugin' at: 238.
- 			self installPrimitive: 'primitiveSerialPortClose' from: 'SerialPlugin' at: 239.
- 			self installPrimitive: 'primitiveSerialPortWrite' from: 'SerialPlugin' at: 240.
- 			self installPrimitive: 'primitiveSerialPortRead' from: 'SerialPlugin' at: 241.
- 
- 			self installPrimitive: 'primitiveTranslateStringWithTable' from: 'MiscPrimitivePlugin' at: 243.
- 			self installPrimitive: 'primitiveFindFirstInString' from: 'MiscPrimitivePlugin' at: 244.
- 			self installPrimitive: 'primitiveIndexOfAsciiInString' from: 'MiscPrimitivePlugin' at: 245.
- 			self installPrimitive: 'primitiveFindSubstring' from: 'MiscPrimitivePlugin' at: 246.
- 		]
- 	]
- !

Item was changed:
  ----- Method: VMMaker class>>versionString (in category 'version testing') -----
  versionString
  
  	"VMMaker versionString"
  
+ 	^'4.19.3'!
- 	^'4.19.2'!



More information about the Vm-dev mailing list