Pharo.image and the VM simulator

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

Pharo.image and the VM simulator

alistairgrant
 
Hi Everyone,

I'm trying to get a Pharo image running in the VM simulator (as part of
working towards writing a FileAttributesPluginSimulator).  My image
happens to use UnixOSProcessPlugin>>getCurrentWorkingDirectory during
startup, and this isn't yet supported in the simulator (there's no
UnixOSProcessPluginSimulator class).

For reference, the method is:


UnixIOProcessPlugin>>primitiveGetCurrentWorkingDirectory
"Answer a string containing the current working directory."

    | cwd cwdString bufferSize incrementBy maxSize buffer |
    <export: true>
    <var: 'buffer' type: #'char *'>
    <var: 'cwd' type: #'char *'>

    bufferSize := 100.
    incrementBy := 100.
    maxSize := 5000.

    [cwdString := interpreterProxy
        instantiateClass: interpreterProxy classString
       indexableSize: bufferSize.
    buffer := interpreterProxy arrayValueOf: cwdString.
    cwd := self get: buffer cwd: bufferSize. "getcwd(buffer, bufferSize)"
    (cwd = 0
    and: [bufferSize < maxSize])]
        whileTrue:
            [bufferSize := bufferSize + incrementBy].
        cwd = 0
            ifTrue:
                [interpreterProxy primitiveFail]
            ifFalse:
                [cwdString := self stringFromCString: cwd.
                interpreterProxy pop: 1 thenPush: cwdString]


In the simulator, cwdString and buffer are both SmallIntegers (the
Oop and begining of the string data respectively).

How can I write the contents of the string in to buffer as part of
the #get:cwd: simulation?

For reference I'd also like to have the answer given the oop
(cwdString).

From Clement's answer to Ben in
http://forum.world.st/Exploring-the-simulator-was-Re-REPL-image-for-simulation-td4896870.html
it seems like it may not be possible.  In that case I'd have to re-write
the primitive to avoid this type of code.

The only other similar code I could find used an uninitialised buffer on
the stack, so had something like:

self cCode: '' inSmalltalk:[ buffer := ByteArray new: 256 ].

and so passed the actual object to the function simulation.


Thanks,
Alistair
Reply | Threaded
Open this post in threaded view
|

Re: Pharo.image and the VM simulator

David T. Lewis
 
The primitive answers a Smalltalk String (cwdString). The rest of the
logic is there to instantiate the String and populate its data area with
the results of the getcwd() call.

For purposes of simulation, anything that answers a reasonable looking
String might be good enough. Possibly it could just end up being something
like this:

primitiveGetCurrentWorkingDirectory
    interpreterProxy pop: 1 thenPush: 'My Current Working Directory';



>
> Hi Everyone,
>
> I'm trying to get a Pharo image running in the VM simulator (as part of
> working towards writing a FileAttributesPluginSimulator).  My image
> happens to use UnixOSProcessPlugin>>getCurrentWorkingDirectory during
> startup, and this isn't yet supported in the simulator (there's no
> UnixOSProcessPluginSimulator class).
>
> For reference, the method is:
>
>
> UnixIOProcessPlugin>>primitiveGetCurrentWorkingDirectory
> "Answer a string containing the current working directory."
>
>     | cwd cwdString bufferSize incrementBy maxSize buffer |
>     <export: true>
>     <var: 'buffer' type: #'char *'>
>     <var: 'cwd' type: #'char *'>
>
>     bufferSize := 100.
>     incrementBy := 100.
>     maxSize := 5000.
>
>     [cwdString := interpreterProxy
>         instantiateClass: interpreterProxy classString
>        indexableSize: bufferSize.
>     buffer := interpreterProxy arrayValueOf: cwdString.
>     cwd := self get: buffer cwd: bufferSize. "getcwd(buffer, bufferSize)"
>     (cwd = 0
>     and: [bufferSize < maxSize])]
>         whileTrue:
>             [bufferSize := bufferSize + incrementBy].
>         cwd = 0
>             ifTrue:
>                 [interpreterProxy primitiveFail]
>             ifFalse:
>                 [cwdString := self stringFromCString: cwd.
>                 interpreterProxy pop: 1 thenPush: cwdString]
>
>
> In the simulator, cwdString and buffer are both SmallIntegers (the
> Oop and begining of the string data respectively).
>
> How can I write the contents of the string in to buffer as part of
> the #get:cwd: simulation?
>
> For reference I'd also like to have the answer given the oop
> (cwdString).
>
> From Clement's answer to Ben in
> http://forum.world.st/Exploring-the-simulator-was-Re-REPL-image-for-simulation-td4896870.html
> it seems like it may not be possible.  In that case I'd have to re-write
> the primitive to avoid this type of code.
>
> The only other similar code I could find used an uninitialised buffer on
> the stack, so had something like:
>
> self cCode: '' inSmalltalk:[ buffer := ByteArray new: 256 ].
>
> and so passed the actual object to the function simulation.
>
>
> Thanks,
> Alistair
>


Reply | Threaded
Open this post in threaded view
|

Re: Pharo.image and the VM simulator

alistairgrant
 
Hi David,

Thanks for your reply.  I could do something like that, but it would
reduce the value of the simulator since it would mean that simulator
specific code is used rather than the code that will ultimately be
translated to C.

However your reply did prompt me to try something similar and I
(eventually) figured out how to address the buffer directly:
interpreterProxy>>byteAt:put:.

So now the simulator gets past this point and the original plugin code
is unmodified.

Thanks!
Alistair


On Mon, 8 Oct 2018 at 19:01, David T. Lewis <[hidden email]> wrote:

>
>
> The primitive answers a Smalltalk String (cwdString). The rest of the
> logic is there to instantiate the String and populate its data area with
> the results of the getcwd() call.
>
> For purposes of simulation, anything that answers a reasonable looking
> String might be good enough. Possibly it could just end up being something
> like this:
>
> primitiveGetCurrentWorkingDirectory
>     interpreterProxy pop: 1 thenPush: 'My Current Working Directory';
>
>
>
> >
> > Hi Everyone,
> >
> > I'm trying to get a Pharo image running in the VM simulator (as part of
> > working towards writing a FileAttributesPluginSimulator).  My image
> > happens to use UnixOSProcessPlugin>>getCurrentWorkingDirectory during
> > startup, and this isn't yet supported in the simulator (there's no
> > UnixOSProcessPluginSimulator class).
> >
> > For reference, the method is:
> >
> >
> > UnixIOProcessPlugin>>primitiveGetCurrentWorkingDirectory
> > "Answer a string containing the current working directory."
> >
> >     | cwd cwdString bufferSize incrementBy maxSize buffer |
> >     <export: true>
> >     <var: 'buffer' type: #'char *'>
> >     <var: 'cwd' type: #'char *'>
> >
> >     bufferSize := 100.
> >     incrementBy := 100.
> >     maxSize := 5000.
> >
> >     [cwdString := interpreterProxy
> >         instantiateClass: interpreterProxy classString
> >        indexableSize: bufferSize.
> >     buffer := interpreterProxy arrayValueOf: cwdString.
> >     cwd := self get: buffer cwd: bufferSize. "getcwd(buffer, bufferSize)"
> >     (cwd = 0
> >     and: [bufferSize < maxSize])]
> >         whileTrue:
> >             [bufferSize := bufferSize + incrementBy].
> >         cwd = 0
> >             ifTrue:
> >                 [interpreterProxy primitiveFail]
> >             ifFalse:
> >                 [cwdString := self stringFromCString: cwd.
> >                 interpreterProxy pop: 1 thenPush: cwdString]
> >
> >
> > In the simulator, cwdString and buffer are both SmallIntegers (the
> > Oop and begining of the string data respectively).
> >
> > How can I write the contents of the string in to buffer as part of
> > the #get:cwd: simulation?
> >
> > For reference I'd also like to have the answer given the oop
> > (cwdString).
> >
> > From Clement's answer to Ben in
> > http://forum.world.st/Exploring-the-simulator-was-Re-REPL-image-for-simulation-td4896870.html
> > it seems like it may not be possible.  In that case I'd have to re-write
> > the primitive to avoid this type of code.
> >
> > The only other similar code I could find used an uninitialised buffer on
> > the stack, so had something like:
> >
> > self cCode: '' inSmalltalk:[ buffer := ByteArray new: 256 ].
> >
> > and so passed the actual object to the function simulation.
> >
> >
> > Thanks,
> > Alistair
> >
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Pharo.image and the VM simulator

Eliot Miranda-2
In reply to this post by alistairgrant
 
Hi Alistair,

> On Oct 7, 2018, at 11:18 PM, Alistair Grant <[hidden email]> wrote:
>
>
> Hi Everyone,
>
> I'm trying to get a Pharo image running in the VM simulator (as part of
> working towards writing a FileAttributesPluginSimulator).  My image
> happens to use UnixOSProcessPlugin>>getCurrentWorkingDirectory during
> startup, and this isn't yet supported in the simulator (there's no
> UnixOSProcessPluginSimulator class).
>
> For reference, the method is:
>
>
> UnixIOProcessPlugin>>primitiveGetCurrentWorkingDirectory
> "Answer a string containing the current working directory."
>
>  | cwd cwdString bufferSize incrementBy maxSize buffer |
>  <export: true>
>  <var: 'buffer' type: #'char *'>
>  <var: 'cwd' type: #'char *'>
>
>  bufferSize := 100.
>  incrementBy := 100.
>  maxSize := 5000.
>
>  [cwdString := interpreterProxy
>      instantiateClass: interpreterProxy classString
>     indexableSize: bufferSize.
>  buffer := interpreterProxy arrayValueOf: cwdString.
>  cwd := self get: buffer cwd: bufferSize. "getcwd(buffer, bufferSize)"
>  (cwd = 0
>  and: [bufferSize < maxSize])]
>      whileTrue:
>          [bufferSize := bufferSize + incrementBy].
>      cwd = 0
>          ifTrue:
>              [interpreterProxy primitiveFail]
>          ifFalse:
>              [cwdString := self stringFromCString: cwd.
>              interpreterProxy pop: 1 thenPush: cwdString]
>
>
> In the simulator, cwdString and buffer are both SmallIntegers (the
> Oop and begining of the string data respectively).
>
> How can I write the contents of the string in to buffer as part of
> the #get:cwd: simulation?

Look at VMClass>>#strncpy:_:_: et al.  All the machinery for string copying is already there.  cwdString and buffer are integer indices into memory, the LittleEndianBitmap that holds the entire state of the simulation’s heap. In the JIT memory also holds the stack zone and the method zone.

>
> For reference I'd also like to have the answer given the oop
> (cwdString).
>
> From Clement's answer to Ben in
> http://forum.world.st/Exploring-the-simulator-was-Re-REPL-image-for-simulation-td4896870.html
> it seems like it may not be possible.  In that case I'd have to re-write
> the primitive to avoid this type of code.

You can either use the style I’m trying to use more and more, which is to write C calls using a Smalltalk message send, and then implement the body, eg see dir_EntryLookup:_:_:_:_:_:_:_:_:_:_:_:, or you can add an override of the entire primitive in a simulation subclass.  Clearly the former is better, but one needs to use some idioms to mimic C conventions, eg addressOf:put:.  Slang translates self addressOf: foo put: ... into &foo, put in the simulation passes foo and evaluates the block argument to put: with the value put so one can simulate pointer passing.  dir_EntryLookup:_:_:_:_:_:_:_:_:_:_:_: provides a relevant example.

>
> The only other similar code I could find used an uninitialised buffer on
> the stack, so had something like:
>
> self cCode: '' inSmalltalk:[ buffer := ByteArray new: 256 ].
>
> and so passed the actual object to the function simulation.
>
>
> Thanks,
> Alistair
Reply | Threaded
Open this post in threaded view
|

Re: Pharo.image and the VM simulator

alistairgrant
 
Hi Eliot,

On Mon, 8 Oct 2018 at 23:21, Eliot Miranda <[hidden email]> wrote:

>
>
> Hi Alistair,
>
> > On Oct 7, 2018, at 11:18 PM, Alistair Grant <[hidden email]> wrote:
> >
> >
> > Hi Everyone,
> >
> > I'm trying to get a Pharo image running in the VM simulator (as part of
> > working towards writing a FileAttributesPluginSimulator).  My image
> > happens to use UnixOSProcessPlugin>>getCurrentWorkingDirectory during
> > startup, and this isn't yet supported in the simulator (there's no
> > UnixOSProcessPluginSimulator class).
> >
> > For reference, the method is:
> >
> >
> > UnixIOProcessPlugin>>primitiveGetCurrentWorkingDirectory
> > "Answer a string containing the current working directory."
> >
> >  | cwd cwdString bufferSize incrementBy maxSize buffer |
> >  <export: true>
> >  <var: 'buffer' type: #'char *'>
> >  <var: 'cwd' type: #'char *'>
> >
> >  bufferSize := 100.
> >  incrementBy := 100.
> >  maxSize := 5000.
> >
> >  [cwdString := interpreterProxy
> >      instantiateClass: interpreterProxy classString
> >     indexableSize: bufferSize.
> >  buffer := interpreterProxy arrayValueOf: cwdString.
> >  cwd := self get: buffer cwd: bufferSize. "getcwd(buffer, bufferSize)"
> >  (cwd = 0
> >  and: [bufferSize < maxSize])]
> >      whileTrue:
> >          [bufferSize := bufferSize + incrementBy].
> >      cwd = 0
> >          ifTrue:
> >              [interpreterProxy primitiveFail]
> >          ifFalse:
> >              [cwdString := self stringFromCString: cwd.
> >              interpreterProxy pop: 1 thenPush: cwdString]
> >
> >
> > In the simulator, cwdString and buffer are both SmallIntegers (the
> > Oop and begining of the string data respectively).
> >
> > How can I write the contents of the string in to buffer as part of
> > the #get:cwd: simulation?
>
> Look at VMClass>>#strncpy:_:_: et al.  All the machinery for string copying is already there.  cwdString and buffer are integer indices into memory, the LittleEndianBitmap that holds the entire state of the simulation’s heap. In the JIT memory also holds the stack zone and the method zone.

Yep, I found this one after replying to David.  Thanks.


> > For reference I'd also like to have the answer given the oop
> > (cwdString).
> >
> > From Clement's answer to Ben in
> > http://forum.world.st/Exploring-the-simulator-was-Re-REPL-image-for-simulation-td4896870.html
> > it seems like it may not be possible.  In that case I'd have to re-write
> > the primitive to avoid this type of code.
>
> You can either use the style I’m trying to use more and more, which is to write C calls using a Smalltalk message send, and then implement the body, eg see dir_EntryLookup:_:_:_:_:_:_:_:_:_:_:_:, or you can add an override of the entire primitive in a simulation subclass.  Clearly the former is better, but one needs to use some idioms to mimic C conventions, eg addressOf:put:.  Slang translates self addressOf: foo put: ... into &foo, put in the simulation passes foo and evaluates the block argument to put: with the value put so one can simulate pointer passing.  dir_EntryLookup:_:_:_:_:_:_:_:_:_:_:_: provides a relevant example.

Right, I'm following the pattern from dir_EntryLookup:...  So far I've
got UnixIOProcessPlugin>>primitiveGetCurrentWorkingDirectory simulated
without any changes to the original primitive definition (by writing
#get:cwd: in the simulator class).  Although I think the original
primitive also needs some tidy up - e.g. it isn't checking that the
memory allocation succeeded.

I'm now working on FileAttributesPlugin.  #primitiveFileMasks is
working and I'm currently working on #primitiveFileExists (but slow
going due to limited time :-)).

Thanks again,
Alistair



> > The only other similar code I could find used an uninitialised buffer on
> > the stack, so had something like:
> >
> > self cCode: '' inSmalltalk:[ buffer := ByteArray new: 256 ].
> >
> > and so passed the actual object to the function simulation.
> >
> >
> > Thanks,
> > Alistair