[Vm-dev] VM Maker: VMMaker.oscog-akg.2473.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Oct 24 06:25:58 UTC 2018


Alistair Grant uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-akg.2473.mcz

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

Name: VMMaker.oscog-akg.2473
Author: akg
Time: 24 October 2018, 8:21:56.15293 am
UUID: 62d7a8e5-56fb-4b35-9b4c-17096a668194
Ancestors: VMMaker.oscog-eem.2472

VM simulation fixes:

- #isCArray is true if the receiver provides the interface.
- FilePluginSimulator>>sqFileDeleteName:Size: handles UTF8 character names
-- TODO: Method to be renamed.
- Add InterpreterPlugin>>memcpy:_:_: to delegate to the interpreter proxy
- Remove SpurMemoryManager>>memcpy:_:_: this looks like it was created before VMClass>>memcpy:_:_:, but doesn't handle different argument types.
- Add InterpreterPlugin>>memmove:_:_: to delegate to the interpreter proxy.
- InterpreterPrimitives>>getenv: handle CArrayAccessor.
- InterpreterPrimitives>>primitiveGetenv remove #cCode:inSmalltalk:.
- Add VMClass>>asByteArray: to handle UTF8 strings (which shouldn't be a String)
- VMClass>>memcpy:_:_: handle different parameter types
- VMClass>>strlen: handle CArray(Accessor)s
- VMClass>>strncpy:_:_: handle CArrayAccessors

=============== Diff against VMMaker.oscog-eem.2472 ===============

Item was changed:
  ----- Method: CArray>>isCArray (in category 'testing') -----
  isCArray
+ 	"Answer a boolean indicating whether the receiver responds to the CArray interface"
+ 
  	^true!

Item was added:
+ ----- Method: CObjectAccessor>>isCArray (in category 'testing') -----
+ isCArray
+ 	"Answer a boolean indicating whether the receiver responds to the CArray interface"
+ 
+ 	^true!

Item was changed:
  ----- Method: FilePluginSimulator>>sqFileDeleteName:Size: (in category 'simulation') -----
  sqFileDeleteName: nameIndex Size: nameSize
  	| path |
+ 
+ 	path := (interpreterProxy asString: nameIndex size: nameSize) asByteArray utf8Decoded.
- 	path := interpreterProxy asString: nameIndex size: nameSize.
  	(StandardFileStream isAFileNamed: path) ifFalse:
  		[^interpreterProxy primitiveFail].
  	[FileDirectory deleteFilePath: path]
  		on: Error
  		do: [:ex| interpreterProxy primitiveFail]!

Item was added:
+ ----- Method: InterpreterPlugin>>memcpy:_:_: (in category 'simulation support') -----
+ memcpy: dest _: src _: bytes
+ 	<doNotGenerate>
+ 	"implementation of memcpy(3). N.B. If ranges overlap, must use memmove."
+ 
+ 	^interpreterProxy memcpy: dest _: src _: bytes
+ !

Item was added:
+ ----- Method: InterpreterPlugin>>memmove:_:_: (in category 'simulation support') -----
+ memmove: destAddress _: sourceAddress _: bytes
+ 	<doNotGenerate>
+ 	"implementation of memcpy(3). N.B. If ranges overlap, must use memmove."
+ 
+ 	^interpreterProxy memmove: destAddress _: sourceAddress _: bytes!

Item was changed:
  ----- Method: InterpreterPrimitives>>getenv: (in category 'simulation support') -----
  getenv: aByteStringOrByteArray
  	<doNotGenerate>
  	"The primitiveGetenv: primitive answers nil for undefined variables.
  	 The primitiveGetenv implementation is written to expect getenv: to
  	 answer 0, not nil,  for undefined variables.  Map nil to 0 for simulation."
+ 
+ 	"aByteStringOrByteArray is probably null terminated, convert to non-null-terminated"
+ 	^(self primitiveGetenv: (self asString: aByteStringOrByteArray)) ifNil: [0]!
- 	^(self primitiveGetenv: aByteStringOrByteArray) ifNil: [0]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveGetenv (in category 'other primitives') -----
  primitiveGetenv
  	"Access to environment variables via getenv.  No putenv or setenv as yet."
  	| key var result |
  	<export: true>
  	<var: #key type: #'char *'>
  	<var: #var type: #'char *'>
  	sHEAFn ~= 0 ifTrue: "secHasEnvironmentAccess"
  		[self sHEAFn ifFalse: [^self primitiveFailFor: PrimErrInappropriate]].
  	key := self cStringOrNullFor: self stackTop.
  	key = 0 ifTrue:
  		[self successful ifTrue:
  			[^self primitiveFailFor: PrimErrBadArgument].
  		 ^self primitiveFailFor: primFailCode].
+ 	var := self getenv: key.
- 	var := self getenv: (self cCode: [key] inSmalltalk: [key allButLast]).
  	self free: key.
  	var ~= 0 ifTrue:
  		[result := objectMemory stringForCString: var.
  		 result ifNil:
  			[^self primitiveFailFor: PrimErrNoMemory]].
  	self assert: primFailCode = 0.
  	self pop: 2 thenPush: (var = 0 ifTrue: [objectMemory nilObject] ifFalse: [result])!

Item was changed:
  ----- Method: Object>>isCArray (in category '*VMMaker-testing') -----
  isCArray
+ 	"Answer a boolean indicating whether the receiver responds to the CArray interface"
+ 
  	^false!

Item was removed:
- ----- Method: SpurMemoryManager>>memcpy:_:_: (in category 'simulation') -----
- memcpy: destAddress _: sourceAddress _: bytes
- 	"For SpurGenerationScavenger>>copyToFutureSpace:bytes:. N.B. If ranges overlap, must use memmove."
- 	<doNotGenerate>
- 	self deny: ((destAddress <= sourceAddress and: [destAddress asInteger + bytes > sourceAddress])
- 				or: [sourceAddress <= destAddress and: [sourceAddress asInteger + bytes > destAddress]]).
- 	^self memmove: destAddress _: sourceAddress _: bytes!

Item was added:
+ ----- Method: VMClass>>asByteArray: (in category 'C library extensions') -----
+ asByteArray: aStringOrStringIndex
+ 	"aStringOrStringIndex is either a string or an address in the heap.
+ 	 Create a ByteArray of the requested length form the bytes in the
+ 	 heap starting at stringIndex."
+ 	<doNotGenerate>
+ 	| sz |
+ 	aStringOrStringIndex isString ifTrue:
+ 		[^aStringOrStringIndex asByteArray].
+ 	sz := self strlen: aStringOrStringIndex.
+ 	^self strncpy: (ByteArray new: sz) _: aStringOrStringIndex _: sz!

Item was changed:
  ----- Method: VMClass>>memcpy:_:_: (in category 'C library simulation') -----
+ memcpy: dest _: src _: bytes
- memcpy: dString _: sString _: bytes
  	<doNotGenerate>
  	"implementation of memcpy(3). N.B. If ranges overlap, must use memmove."
+ 	| getBlock setBlock |
+ 
+ 	(src isInteger and: [dest isInteger]) ifTrue:
+ 		[ self deny: ((dest <= src and: [dest + bytes > src])
+ 					or: [src <= dest and: [src + bytes > dest]])].
+ 
+ 	"Determine the source and destination access blocks based on the parameter type"
+ 	getBlock := src isCollection ifTrue: 
+ 		[src isString ifTrue: 
+ 			"basicAt: answers integers"
+ 			[[ :idx | src basicAt: idx]]
+ 		ifFalse: 
+ 			[src class == ByteArray ifTrue: 
+ 				[[ :idx | src at: idx]]]]
+ 	ifFalse: 
+ 		[src isInteger ifTrue: 
+ 			[[ :idx | self byteAt: src + idx - 1]]
+ 		ifFalse: 
+ 			[src isCArray ifTrue:
+ 				[[ :idx | src at: idx - 1]]]].
+ 	getBlock ifNil: [self error: 'unhandled type of source string'].
+ 	setBlock := dest isCollection ifTrue: 
+ 		[dest isString ifTrue:
+ 			"basicAt:put: stores integers"
+ 			[[ :idx | dest basicAt: idx put: (getBlock value: idx)]] 
+ 		ifFalse: 
+ 			[dest class == ByteArray ifTrue: 
+ 				[[ :idx | dest at: idx put: (getBlock value: idx)]]]]
+ 	ifFalse: 
+ 		[dest isInteger ifTrue:
+ 			[[ :idx | self byteAt: dest + idx - 1 put: (getBlock value: idx)]]
- 	(dString isCollection or: [sString isCollection]) ifFalse:
- 		[| destAddress sourceAddress |
- 		 destAddress := dString asInteger.
- 		 sourceAddress := sString asInteger.
- 		 self deny: ((destAddress <= sourceAddress and: [destAddress + bytes > sourceAddress])
- 					or: [sourceAddress <= destAddress and: [sourceAddress + bytes > destAddress]])].
- 	dString isInteger
- 		ifTrue:
- 			[1 to: bytes do:
- 				[:i| | v |
- 				v := sString isString
- 						ifTrue: [sString basicAt: i]
- 						ifFalse: [self byteAt: sString + i - 1].
- 				self byteAt: dString + i - 1 put: v]]
  		ifFalse:
+ 			[dest isCArray ifTrue:
+ 				[[ :idx | dest at: idx - 1 put: (getBlock value: idx)]]]].
+ 	setBlock ifNil: [self error: 'unhandled type of destination string'].
+ 	1 to: bytes do: setBlock.
+ 
+ 	^dest!
- 			[1 to: bytes do:
- 				[:i| | v |
- 				v := sString isString
- 						ifTrue: [sString basicAt: i]
- 						ifFalse: [self byteAt: sString + i - 1].
- 				dString basicAt: i put: v]].
- 	^dString!

Item was changed:
  ----- Method: VMClass>>strlen: (in category 'C library simulation') -----
  strlen: aCString
  	"Simulate strlen(3)"
  	<doNotGenerate>
  	| len |
+ 
+ 	aCString isCArray ifTrue:
+ 		["CArrays may be 0 terminated or the correct length (in the simulator)"
- 	aCString isString ifTrue:
- 		[^aCString size].
- 	aCString class == ByteArray ifTrue: [
- 		"ByteArrays may be 0 terminated or the correct length (in the simulator)"
  		len := 0.
+ 		[(len = aCString size or: [(aCString at: len) = 0]) ifTrue: [^len].
+ 		len := len + 1] repeat]
+ 	ifFalse:
+ 		[aCString isString ifTrue: 
+ 			[^aCString size]
+ 		ifFalse:
+ 			[aCString class == ByteArray ifTrue: [
+ 				"ByteArrays may be 0 terminated or the correct length (in the simulator)"
+ 				len := 0.
+ 				[(len = aCString size or: [(aCString at: len+1) = 0]) ifTrue: [^len].
+ 				len := len + 1] repeat]]].
- 		[(len = aCString size or: [(aCString at: len+1) = 0]) ifTrue: [^len].
- 		len := len + 1] repeat].
  	"Must be an address"
  	len := 0.
  	[(self byteAt: aCString + len) = 0 ifTrue: [^len].
  	len := len + 1] repeat!

Item was changed:
  ----- Method: VMClass>>strncpy:_:_: (in category 'C library simulation') -----
  strncpy: dest _: src _: n
  	<doNotGenerate>
  	"implementation of strncpy(3).
  	 See e.g. https://manpages.debian.org/stretch/manpages-dev/strncpy.3.en.html
  	 The C version always takes an address; the simulation allows a String, ByteArray,
  	 CArray or address within the simulation object memory (Positive Integer)"
  	| getBlock setBlock count |
  	count := n.
  	"Determine the source and destination access blocks based on the parameter type"
  	getBlock := src isCollection
  					ifTrue:
  						[count := count min: src size.
  						 src isString
  							ifTrue: [[ :idx | src basicAt: idx]] "basicAt: answers integers"
  							ifFalse:
  								[src class == ByteArray ifTrue:
  									[[ :idx | src at: idx]]]]
  					ifFalse:
  						[src isInteger
  							ifTrue: [[ :idx | self byteAt: src + idx - 1]]
  							ifFalse:
+ 								[src isCArray ifTrue:
- 								[src class == CArray ifTrue:
  									[[ :idx | src at: idx - 1]]]].
  	getBlock ifNil: [self error: 'unhandled type of source string'].
  	setBlock := dest isCollection
  					ifTrue:
  						[dest isString
  							ifTrue: [[ :idx | dest basicAt: idx put: (getBlock value: idx)]] "basicAt:put: stores integers"
  							ifFalse:
  								[dest class == ByteArray ifTrue:
  									[[ :idx | dest at: idx put: (getBlock value: idx)]]]]
  					ifFalse:
  						[dest isInteger ifTrue: 
  							[[ :idx | self byteAt: dest + idx - 1 put: (getBlock value: idx)]]].
  	setBlock ifNil: [self error: 'unhandled type of destination string'].
  	1 to: count do: setBlock.
  	"SVr4, 4.3BSD, C89, C99 require the remainder of the buffer be filled with nulls"
  	getBlock := [:idx| 0].
  	count + 1 to: n do: setBlock.
  	^dest!



More information about the Vm-dev mailing list