[Vm-dev] VM Maker: VMMaker.oscog-eem.2162.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Mar 17 21:34:51 UTC 2017
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2162.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.2162
Author: eem
Time: 17 March 2017, 2:33:43.955084 pm
UUID: 62e528cf-ac80-421c-9bd3-eb7f843200b6
Ancestors: VMMaker.oscog-eem.2161
InterpreterPrimitives:
Add a proper getenv: primitive, with full control for disabling from the SecurityPlugin. Actual security plugin support required, which will be provided soon. Clean up some of the SecurityPlugin accessors to avoid cCode:. Fix mem:cp:y: for ByteArrays.
InterpreterProxy
Add stringForCString: to the API, now providing the cStringOrNullFor:/stringForCString: pair.
Fix primitiveDirectoryEntry simulation for PharoVM in the CogVMSimulator.
=============== Diff against VMMaker.oscog-eem.2161 ===============
Item was added:
+ ----- Method: CogVMSimulator>>makeDirEntryName:size:createDate:modDate:isDir:fileSize:posixPermissions:isSymlink: (in category 'as yet unclassified') -----
+ makeDirEntryName: entryName size: entryNameSize createDate: createDate modDate: modifiedDate isDir: dirFlag fileSize: fileSize posixPermissions: posixPermissions isSymlink: symlinkFlag
+ <option: #PharoVM>
+ <var: 'entryName' type: 'char *'>
+
+ | modDateOop createDateOop nameString results |
+
+ results := objectMemory instantiateClass: (objectMemory splObj: ClassArray) indexableSize: 7.
+ nameString := objectMemory instantiateClass: (objectMemory splObj: ClassString) indexableSize: entryNameSize.
+ createDateOop := self positive32BitIntegerFor: createDate.
+ modDateOop := self positive32BitIntegerFor: modifiedDate.
+
+ 1 to: entryNameSize do:
+ [ :i |
+ objectMemory storeByte: i-1 ofObject: nameString withValue: (entryName at: i) asciiValue].
+
+ objectMemory storePointerUnchecked: 0 ofObject: results withValue: nameString.
+ objectMemory storePointerUnchecked: 1 ofObject: results withValue: createDateOop.
+ objectMemory storePointerUnchecked: 2 ofObject: results withValue: modDateOop.
+ dirFlag
+ ifTrue: [ objectMemory storePointerUnchecked: 3 ofObject: results withValue: objectMemory trueObject ]
+ ifFalse: [ objectMemory storePointerUnchecked: 3 ofObject: results withValue: objectMemory falseObject ].
+ objectMemory storePointerUnchecked: 4 ofObject: results withValue: (objectMemory integerObjectOf: fileSize).
+ objectMemory storePointerUnchecked: 5 ofObject: results withValue: (objectMemory integerObjectOf: posixPermissions).
+ symlinkFlag
+ ifTrue: [ objectMemory storePointerUnchecked: 6 ofObject: results withValue: objectMemory trueObject ]
+ ifFalse: [ objectMemory storePointerUnchecked: 6 ofObject: results withValue: objectMemory falseObject ].
+
+ ^ results!
Item was changed:
----- Method: CogVMSimulator>>primitiveDirectoryEntry (in category 'file primitives') -----
primitiveDirectoryEntry
| name pathName arrayNilOrSymbol result |
name := self stringOf: self stackTop.
pathName := self stringOf: (self stackValue: 1).
- "temporary work-around to make it work in Pharo..."
- self cppIf: PharoVM ifTrue: [ pathName := Smalltalk imagePath ].
-
self successful ifFalse:
[^self primitiveFail].
arrayNilOrSymbol := FileDirectory default primLookupEntryIn: pathName name: name.
arrayNilOrSymbol ifNil:
[self pop: 3 thenPush: objectMemory nilObject.
^self].
arrayNilOrSymbol isArray ifFalse:
["arrayNilOrSymbol ~~ #primFailed ifTrue:
[self halt]. "
self transcript show: name, ' NOT FOUND'.
^self primitiveFail].
result := PharoVM
ifTrue:
[self makeDirEntryName: (arrayNilOrSymbol at: 1) size: (arrayNilOrSymbol at: 1) size
createDate: (arrayNilOrSymbol at: 2) modDate: (arrayNilOrSymbol at: 3)
isDir: (arrayNilOrSymbol at: 4) fileSize: (arrayNilOrSymbol at: 5)
+ posixPermissions: (arrayNilOrSymbol at: 6 ifAbsent: [8r644]) isSymlink: (arrayNilOrSymbol at: 7 ifAbsent: [false])]
- posixPermissions: (arrayNilOrSymbol at: 6) isSymlink: (arrayNilOrSymbol at: 7) ]
ifFalse:
[self makeDirEntryName: (arrayNilOrSymbol at: 1) size: (arrayNilOrSymbol at: 1) size
createDate: (arrayNilOrSymbol at: 2) modDate: (arrayNilOrSymbol at: 3)
isDir: (arrayNilOrSymbol at: 4) fileSize: (arrayNilOrSymbol at: 5) ].
self pop: 3 thenPush: result!
Item was changed:
VMClass subclass: #InterpreterPrimitives
+ instanceVariableNames: 'objectMemory messageSelector argumentCount newMethod primFailCode profileMethod profileProcess profileSemaphore nextProfileTick preemptionYields newFinalization sHEAFn'
- instanceVariableNames: 'objectMemory messageSelector argumentCount newMethod primFailCode profileMethod profileProcess profileSemaphore nextProfileTick preemptionYields newFinalization'
classVariableNames: 'CrossedX EndOfRun MillisecondClockMask'
poolDictionaries: 'VMBasicConstants VMBytecodeConstants VMMethodCacheConstants VMObjectIndices VMSqueakClassIndices VMStackFrameOffsets'
category: 'VMMaker-Interpreter'!
!InterpreterPrimitives commentStamp: 'eem 12/11/2012 17:11' prior: 0!
InterpreterPrimitives implements most of the VM's core primitives. It is the root of the interpreter hierarchy so as to share the core primitives amongst the varioius interpreters.
Instance Variables
argumentCount: <Integer>
messageSelector: <Integer>
newMethod: <Integer>
nextProfileTick: <Integer>
objectMemory: <ObjectMemory> (simulation only)
preemptionYields: <Boolean>
primFailCode: <Integer>
profileMethod: <Integer>
profileProcess: <Integer>
profileSemaphore: <Integer>
argumentCount
- the number of arguments of the current message
messageSelector
- the oop of the selector of the current message
newMethod
- the oop of the result of looking up the current message
nextProfileTick
- the millisecond clock value of the next profile tick (if profiling is in effect)
objectMemory
- the memory manager and garbage collector that manages the heap
preemptionYields
- a boolean controlling the process primitives. If true (old, incorrect, blue-book semantics) a preempted process is sent to the back of its run-queue. If false, a process preempted by a higher-priority process is put back at the head of its run queue, hence preserving cooperative scheduling within priorities.
primFailCode
- primtiive success/failure flag, 0 for success, otherwise the reason code for failure
profileMethod
- the oop of the method at the time nextProfileTick was reached
profileProcess
- the oop of the activeProcess at the time nextProfileTick was reached
profileSemaphore
- the oop of the semaphore to signal when nextProfileTick is reached
!
Item was added:
+ ----- Method: InterpreterPrimitives class>>declareCVarsIn: (in category 'C translation') -----
+ declareCVarsIn: aCCodeGen
+ aCCodeGen var: 'sHEAFn' declareC: 'int (*sHEAFn)() = 0' "the hasEnvironmentAccess function"!
Item was changed:
----- Method: InterpreterPrimitives>>cStringOrNullFor: (in category 'primitive support') -----
cStringOrNullFor: oop
"Answer either a malloced string with the null-terminated contents of oop if oop is a string,
or the null pointer if oop is nil, or fail. It is the client's responsibility to free the string later."
<api>
<returnTypeC: #'char *'>
+ <inline: false>
| isString len cString |
<var: 'cString' type: #'char *'>
isString := self isInstanceOfClassByteString: oop.
isString ifFalse:
[oop ~= objectMemory nilObject ifTrue:
[self primitiveFailFor: PrimErrBadArgument].
^0].
len := objectMemory lengthOf: oop.
len = 0 ifTrue:
[^0].
cString := self malloc: len + 1.
cString ifNil:
[self primitiveFailFor: PrimErrNoCMemory.
^0].
self mem: cString cp: (objectMemory firstIndexableField: oop) y: len.
+ cString at: (self cCode: [len] inSmalltalk: [len + 1]) put: 0.
- cString at: len put: 0.
^cString!
Item was added:
+ ----- Method: InterpreterPrimitives>>getenv: (in category 'simulation support') -----
+ getenv: aByteStringOrByteArray
+ <doNotGenerate>
+ <primitive: 'primitiveGetenv' module: '' error: ec>
+ ec == #'bad argument' ifTrue:
+ [aByteStringOrByteArray isString ifFalse:
+ [^self getenv: aByteStringOrByteArray asString]].
+ self primitiveFail!
Item was added:
+ ----- Method: InterpreterPrimitives>>initializeInterpreter: (in category 'initialization') -----
+ initializeInterpreter: bytesToShift
+ sHEAFn := self ioLoadFunction: 'secHasEnvironmentAccess' From: 'SecurityPlugin'!
Item was added:
+ ----- Method: InterpreterPrimitives>>primitiveGetenv (in category 'other primitives') -----
+ primitiveGetenv
+ "Access to environment variables via getenv. No putenv or setenv as yet."
+ | var result |
+ <export: true>
+ <var: #var type: #'char *'>
+ <var: #result type: #'char *'>
+ sHEAFn ~= 0 ifTrue: "secHasEnvironmentAccess"
+ [self sHEAFn ifFalse: [^self primitiveFailFor: PrimErrInappropriate]].
+ var := self cStringOrNullFor: self stackTop.
+ var = 0 ifTrue:
+ [self successful ifTrue:
+ [^self primitiveFailFor: PrimErrBadArgument].
+ ^self].
+ result := self getenv: (self cCode: [var] inSmalltalk: [var allButLast]).
+ self free: var.
+ result ~= 0 ifTrue:
+ [result := objectMemory stringForCString: result.
+ result ifNil:
+ [^self primitiveFailFor: PrimErrNoMemory]].
+ self assert: primFailCode = 0.
+ self pop: 2 thenPush: (result = 0 ifTrue: [objectMemory nilObject] ifFalse: [result])!
Item was added:
+ ----- Method: InterpreterPrimitives>>sHEAFn (in category 'simulation support') -----
+ sHEAFn
+ <doNotGenerate>
+ self break.
+ ^true!
Item was added:
+ ----- Method: InterpreterProxy>>cStringOrNullFor: (in category 'testing') -----
+ cStringOrNullFor: oop
+ "Answer either a malloced string with the null-terminated contents of oop if oop is a string,
+ or the null pointer if oop is nil, or fail. It is the client's responsibility to free the string later."
+ <returnTypeC: #'char *'>
+ oop isString ifTrue: [^oop] ifFalse: [self primitiveFail. ^0]!
Item was added:
+ ----- Method: InterpreterProxy>>stringForCString: (in category 'testing') -----
+ stringForCString: aCString
+ "Answer a ByteString object containing the bytes (possibly UTF-8?) in the null-terminated C string aCString."
+ <var: #aCString type: #'char *'>
+ self notYetImplemented!
Item was changed:
----- Method: SecurityPlugin>>secCanRenameImage (in category 'exported functions') -----
secCanRenameImage
<export: true>
+ ^self ioCanRenameImage!
- ^self cCode: [self ioCanRenameImage] inSmalltalk: [true]!
Item was changed:
----- Method: SecurityPlugin>>secCanWriteImage (in category 'exported functions') -----
secCanWriteImage
<export: true>
+ ^self ioCanWriteImage!
- ^self cCode: 'ioCanWriteImage()'!
Item was changed:
----- Method: SecurityPlugin>>secDisableFileAccess (in category 'exported functions') -----
secDisableFileAccess
<export: true>
+ ^self ioDisableFileAccess!
- ^self cCode: 'ioDisableFileAccess()'!
Item was changed:
----- Method: SecurityPlugin>>secDisableSocketAccess (in category 'exported functions') -----
secDisableSocketAccess
<export: true>
+ ^self ioDisableSocketAccess!
- ^self cCode: 'ioDisableSocketAccess()'!
Item was added:
+ ----- Method: SecurityPlugin>>secHasEnvironmentAccess (in category 'exported functions') -----
+ secHasEnvironmentAccess
+ <export: true>
+ ^self ioHasEnvironmentAccess!
Item was changed:
----- Method: SecurityPlugin>>secHasFileAccess (in category 'exported functions') -----
secHasFileAccess
<export: true>
+ ^self ioHasFileAccess!
- ^self cCode: 'ioHasFileAccess()'!
Item was changed:
----- Method: SecurityPlugin>>secHasSocketAccess (in category 'exported functions') -----
secHasSocketAccess
<export: true>
+ ^self ioHasSocketAccess!
- ^self cCode: 'ioHasSocketAccess()'!
Item was changed:
----- Method: StackInterpreter>>initializeInterpreter: (in category 'initialization') -----
initializeInterpreter: bytesToShift
"Initialize Interpreter state before starting execution of a new image."
interpreterProxy := self sqGetInterpreterProxy.
self dummyReferToProxy.
objectMemory initializeObjectMemory: bytesToShift.
self checkAssumedCompactClasses.
self initializeExtraClassInstVarIndices.
method := newMethod := objectMemory nilObject.
self cCode: '' inSmalltalk:
[breakSelectorLength ifNil:
[breakSelectorLength := objectMemory minSmallInteger]].
methodDictLinearSearchLimit := 8.
self initialCleanup.
LowcodeVM ifTrue: [ self setupNativeStack ].
profileSemaphore := profileProcess := profileMethod := objectMemory nilObject.
interruptKeycode := 2094. "cmd-. as used for Mac but no other OS"
[globalSessionID = 0] whileTrue:
[globalSessionID := self
cCode: [(self time: #NULL) + self ioMSecs]
+ inSmalltalk: [(Random new next * SmallInteger maxVal) asInteger]].
+ super initializeInterpreter: bytesToShift.!
- inSmalltalk: [(Random new next * SmallInteger maxVal) asInteger]]!
Item was changed:
----- Method: VMClass>>mem:cp:y: (in category 'C library simulation') -----
mem: dString cp: sString y: bytes
<doNotGenerate>
"implementation of memcpy(3). N.B. If ranges overlap, must use memmove."
(dString isString or: [sString isString]) ifFalse:
[| destAddress sourceAddress |
+ dString class == ByteArray ifTrue:
+ [ByteString adoptInstance: dString.
+ ^[self mem: dString cp: sString y: bytes] ensure:
+ [ByteArray adoptInstance: dString]].
destAddress := dString asInteger.
sourceAddress := sString asInteger.
self deny: ((destAddress <= sourceAddress and: [destAddress + bytes > sourceAddress])
or: [sourceAddress <= destAddress and: [sourceAddress + bytes > destAddress]])].
dString isString
ifTrue:
[1 to: bytes do:
[:i| | v |
v := sString isString
ifTrue: [sString at: i]
ifFalse: [Character value: (self byteAt: sString + i - 1)].
dString at: i put: v]]
ifFalse:
[1 to: bytes do:
[:i| | v |
v := sString isString
ifTrue: [(sString at: i) asInteger]
ifFalse: [self byteAt: sString + i - 1].
self byteAt: dString + i - 1 put: v]].
^dString!
More information about the Vm-dev
mailing list