[Vm-dev] Primitives return what?

Stuart Cassoff aa72 at bell.net
Mon Apr 9 22:34:04 UTC 2018


> ---------- Original Message ----------
> From: Eliot Miranda <eliot.miranda at gmail.com>
> Date: April 9, 2018 at 10:54 AM
> 
> 
> Hi Stewart,
> 

Hi Elliott,

> 
> > On Apr 8, 2018, at 3:52 PM, Stuart Cassoff <aa72 at bell.net> wrote:
> > 
> > 
> > Apologies in advance for not doing enough homework.
> > 
> > From what I can understand so far:
> > - Primitive function signatures specify returning an sqInt but the returned value is never used.
> 
> Right.  This is historical.  It used to be that all functions generated by Slang returned sqInt.
> 
> > - Primitives generally don't themselves return values, they often just drop off the end of the function.
> 
> They always return values but never by the C 
> route.  Primitives fetch their arguments from the Smalltalk stack through stackPointer and argumentCount.  They then validate these arguments.  If validation, of subsequent processing fails, they leave their arguments in place, set primFailCode appropriately and return.  If not, they pop the receiver and arguments from the stack and push the result, leaving primFailCode set to 0, and return.
> 
> There are convenience functions for accessing arguments (e.g. stackIntegerValue:) and for returning results (e.g. methodFloatValue:).  The advantage this interface has is varargs primitives.  See for example primitiveVMParameter.
> 
> Clément and I have added a C signature primitive that works as he describes, receiving its arguments as function arguments, answering the result on success,   setting primFailCode and answering 0 on failure.  We shall use this form more as things progress. We use this form only  for C code that has very shallow stack depth because we call them directly from jitted code where it runs on a Smalltalk stack page, and hence avoids the expensive stack switch involved in normal primitive invocation, but must keep within the bounds of a stack page.
> 
> Finally, the JIT generates machine code primitives that access their arguments either from the register arguments or the stack (messages with two or fewer arguments are passed in registers, those with more on the stack), and return their result directly.
> 
> > - Most (all?) primitive code is generated by VMMaker.
> 
> That's right.  For plugin primitives the generated code is often no more than a wrapper around platform C code.  The interface between the two is defined in platforms/Cross/plugins/XXXPlugin/XXXPlugin.h.  See for example platforms/Cross/plugins/FilePlugin/FilePlugin.h
> 
> > Compiling results in warnings: "non-void function should return a value".
> 
> Not necessarily.  Slang has been modified to type primitives as returning void if possible.  The problem is the interface to functions in sqVirtualMachine.h which types some functions as sqInt even though they don't return a result.  This is historical.

I think the generated interpreter code yields a lot of "non-void function should return a value" type warnings.
I don't remember exactly; I'll see when I get back to work on this project. So far I'm still wading through compiler warnings.
Differences in how compilers are configured/built on different systems may also have an effect here.

> 
> > 
> > So I'm wondering if  the code generator could add "return 0;" (return 1; ?) where needed,
> > or could the functions be generated with a void signature instead of sqInt.
> 
> I believe it does so in some circumstances.  Look at a specific case to see what the issue is.  You may find it does not fit a simple category ;-). I have tried to eliminate warnings in the Interpreter and cogit (e.g. spursrc/vm/{gcc3x-cointerpreter.c,cogitIA32.c}.  I have not tried to eliminate warnings from plugin primitives.
> 
> > That is, iiuc, if the returned values from primitives are ignored.
> > If they are, I think that's a bit of a bummer because that's a wasted communications channel.
> 
> Agreed.  I like the C signature approach above, but this
> - does not work for varargs
> - cannot handle stack changing primitives like perform and block value
> - if called directly from machine code, cannot be used for primitives that call library code (the stack depth limitation)
> So we only use it for new primitives that fits these constraints.
> 
> 
> > Any clarification appreciated,
> 
> Has this helped? 

Yes! Thanks very much for your response.
And I'm pleased to note that at this point I've already gained prior understanding of some of these things and knew what you were talking about (like in para 1). :)

Still learnin'

Stu


> 
> > Stu
> 
> Cheers, Eliot
> _,,,^..^,,,_ (phone)


More information about the Vm-dev mailing list