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 ----- |
Free forum by Nabble | Edit this page |