[eliot.miranda@gmail.com: Re: VM Maker: VMMaker-dtl.189.mcz]

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

[eliot.miranda@gmail.com: Re: VM Maker: VMMaker-dtl.189.mcz]

David T. Lewis
 
Forwarding to the list with permission. Eliot provides some explanations
that may be of general interest.

Dave

----- Forwarded message from Eliot Miranda <[hidden email]> -----

Date: Wed, 6 Oct 2010 11:30:15 -0700
Subject: Re: VM Maker: VMMaker-dtl.189.mcz
From: Eliot Miranda <[hidden email]>
To: "David T. Lewis" <[hidden email]>

On Wed, Oct 6, 2010 at 5:35 AM, David T. Lewis <[hidden email]> wrote:

> On Tue, Oct 05, 2010 at 10:07:25PM -0700, Eliot Miranda wrote:
> > Hi David,
> >
> > On Tue, Oct 5, 2010 at 9:44 PM, David T. Lewis <[hidden email]>
> wrote:
> >
> > > Hi Eliot,
> > >
> > > Apologies if this is a duplicate message (a previous message seems to
> > > have disappeared), but attached are the changes for loading a Cog
> > > image into a standard VM.
> > >
> > > I can load a Cog image into a standard VM, save the image in old
> > > format, and load that saved image back into Cog. Float values
> > > are preserved throughout. This should open the possibility of
> > > developing images with Cog that may later need to be loaded into
> > > a standard VM.
> > >
> >
> > this is cool.  But why not adopt platform floats in the standard VM?
>  It's
> > faster.
> >
>
> I don't know actually, have not even looked at it. But if it's anything
> non-trivial, my time would be better spent on easing the transition
> to Cog, which will give much larger performance benefits ;)
>
> One thing I'd like to do is work through the list of plugins, getting
> everything as consistent and up to date as possible. There are plugins
> in oscog that are missing things from the main branch and vice versa,
> and a few cases where merging may be needed. I'll probably be bothering
> you with occasional emails on this topic.
>
> You had mentioned a couple of things related to primitive error return
> and function lookup that we need to add into the traditional VM. I'll
> probably be working on some of this on Friday, so if you can give me
> some pointers as to what needs to be done, I'll see if I can take care
> of it.
>

You could do it but so could I, and I've already done it.  Here's what to
do, without specifying who does it.

*Prim Fail Code*
Get an image with Lukas' latest rewrite engine from the refactoring browser
(AST-Core & AST-Semantic from squeaksource.com/rb).  Then rewrite

    successFlag => self successful
    successFlag := expr => self successful: expr

then eliminate successFlag and replace it with primFailCode.  Whereever
successFlag := true. is done to prepare for primitive invocation
(internalExecuteNewMethod et al) replace successFlag := true with self
initPrimCall and then use the following methods to test for success/failure

initPrimCall
"Set the failure code/success flag in preparation for calling a primitve.
 If primFailCode is non-zero a primitive has failed.  If primFailCode is
 greater than one then its value indicates the reason for failure. Override
 to disable the - for the jit - cumbersome stack balance checking code."
<inline: true>
primFailCode := 0

failed
<api>
^primFailCode ~= 0

primitiveFail
"Set general (unspecified) primitive failure.  Don't overwrite an error code
that has already been set."

"Use returnTypeC: #sqInt because that's the way it is defined in sq.h.
 Use no explicit return so that Slang doesn't fail an inlin ingtype-check
when
 a primitive with return type void uses ^self primitiveFail to exit."
<returnTypeC: #sqInt>
primFailCode == 0 ifTrue:
[primFailCode := 1]

primitiveFailFor: reasonCode
"Set specific primitive failure.
 N.B. primitiveFailFor: PrimNoErr is expected to clear the primFailCode."
<api>
^primFailCode := reasonCode

success: successBoolean
"Set the state of the primitive failure code/success flag, iff
successBoolean
 is false. If primFailCode is non-zero a primitive has failed.  If
primFailCode
 is greater than one then its value indicates the reason for failure."

"Use returnTypeC: #sqInt because that's the way it is defined in sq.h.
 Use no explicit return so that Slang doesn't fail an inlin ingtype-check
when
 a primitive with return type void uses ^self success: false to exit."
<returnTypeC: #sqInt>
<inline: true>
successBoolean ifFalse:
["Don't overwrite an error code that has already been set."
 primFailCode == 0 ifTrue:
[primFailCode := 1]]

successful
"Answer the state of the primitive failure code/success flag.  If
 primFailCode is non-zero a primitive has failed.  If primFailCode
 is greater than one then its value indicates the reason for failure."
<inline: true>
^primFailCode == 0


Object Memory => objectMemory refactoring
Look at the division of labour in the Cog VMMaker between ObjectMemory,
NewObjectMemory et al and StackInterpreter CoInterpreter et al for
object-emory related selectors.  Basically we want to replicate the movement
of methods between the two.  I've been tweaking this for a whole so its best
to copy what I've done in Cog rather than try and come up with the division
anew.  Then once methods have been moved to the right place use the rewrite
engine to replace 'self `@method: ``@args' with 'objectMemory `@method:
``@args' (the rewrite engine is soooo cool) for all methods in Interpreter
that are implemented by ObjectMemory.

You'll need to use the Cog Slang to get objectMemory elided in translation,
which you address here:

I'm also really interested in what you have done for the code generator
> to support object memory as an instance variable. I wonder if I can
> do something similar to mix class MemoryAccess (slang version of
> sqMemoryAccess.h) into an object memory (this is personal interest,
> I have no intention of adding it to the VMMaker package per se).
>

So in the Cog VMMaker look at senders/implementors
of isNonArgumentImplicitReceiverVariableName:
and shouldExcludeReceiverAsFirstArgument:.  There are a couple of things
going on here  One is that when objectMemory is in an inst var sends to
objectMemory need to have objectMemory elided just as sends to self or
interpreterProxy have the receiver elided (or replaced by
interpreterProxy->foo).  The other is that struct types such
as CogAbstractInstruction need to keep self so that e.g.

CogAbstractInstruction>>addDependent: anInstruction
<var: #anInstruction type: #'AbstractInstruction *'>
<returnTypeC: #'AbstractInstruction *'>
dependent notNil ifTrue:
[anInstruction dependent: dependent].
^dependent := anInstruction

is translated as

static AbstractInstruction *
addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction
*anInstruction) {
    if (((self_in_addDependent->dependent)) != null) {
        (anInstruction->dependent = (self_in_addDependent->dependent));
    }
    return (self_in_addDependent->dependent) = anInstruction;
}

There's other machinery to support these struct types (subclasses
of VMStructType); primarily see senders/implementors of isAccessor:
isStructAccessor and transformToStructClassMethodFor:.

BTW, I think mixing class MemoryAccess into ObjectMemory is an excellent
thing to do, and you should absolutely think of adding it to VMMaker.

One of the things I don't like about thr Cog structure right now is that
there is no sharing between the simulators.  Basically Interpreter,
StackInterpreter, CoInterpreter, NewObjectMemory *and* NewCoObjectMemory all
have simulator subclasses even though there is huge commonality between the
three interpreter simulators and between the two ObjectMemory simualtors
(note that once we refactor Interpreter to use the objectMemory inst var
then ObjectMemory will also need a simulator).

One alternative would be to push the simulation code up into superclasses of
ObjectMemory and InterpreterPrimitives, e.g. into VMClass.  I've already
done that with things like oop:isGreaterThan:.  Another alternative is to
put it into the classes itself and use the <doNotGenerate> pragma to avid
its generation, but that can get quite cluttered.  But neither of these
approaches copes with LSB vs MSB issues, for which we either use an
VMBIGENDIAN ifTrue:ifFalse: or subclasses.

best
Eliot


> Dave
>
>

----- End forwarded message -----