VM Maker: VMMaker.oscog-akg.2473.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-akg.2473.mcz

commits-2
 
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!