Comments on JDK-8198408 please ?

John Rose john.r.rose at oracle.com
Tue Feb 27 00:36:07 UTC 2018


On Feb 26, 2018, at 4:00 PM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
> 
> ...We should have a lowering step before getting to the backend which prepares the AST to a form which is more amenable to the withfield treatment. So if you have
> 
> a.b.c = x
> 
> this should be translated as:
> 
> __WithField(a.b, __WithField(b.c, x))

More precisely:

a = __WithField(a.b, __WithField(a.b.c, x))

The first __WithField returns an updated version of a (with b updated).
The second returns an updated version of a.b (with c updated).
And the whole thing needs to be written back to a.

And, I'd prefer if the programmer were forced to write the __WithFields
explicitly, since it's closer to the virtual machine.

> and the backend should then have an easier life. Incidentally, this form is also similar to what John suggested to use as a prototype - so perhaps a new experimental keyword and a new experimental AST node could be a good start here.

+1

> Once we have a new AST node - e.g.
> 
> class JCWithField extends JCExpression {
>    JCExpression lvalue;
>    JCExpression rvalue;
> }
> 
> We have to decide what kind of 'lvalue' are admissible in such a construct. How many levels can the lvalue have? Can the lvalue contain complex expressions, as in:
> 
> __WithField(foo(x -> ...).g, 12)

I don't think complex LHSs are a problem for __WithField.  The only "magic" structure
in the LHS is the trailing ".g".  The stuff before ".g" is just a pointer expression.
It gets code generated like this:

   …stuff before ".g" compiled to TOS
   invokestatic foo(Function)Foo
   bipush 12
   withfield Foo.g:int
   …result is at TOS
   

> I think for now it's better to start simple - only one level allowed and no complex expressions in the selector allowed.

I don't think there is really a technical reason for this; but of course is there is one,
make it simpler by restricting the construct.

> That means that lvalue should be restricted to a JCFieldAccess node, whose 'selected' part must be a JCIdent. This form should be close enough to what the bytecode can handle.

I think, the reason you are suggesting this is you are envisioning a "magic"
write-back of the JCIdent variable, under the hood.  I am not, which is why
I corrected your formula above to include an explicit write-back.

The __WithField op should be exactly a withfield bytecode, no more and
no less.  If the user wants a writeback, then write back the new value.
Otherwise, send it somewhere else (field write, method arg, etc.).

Oh, and __WithField is an expression operator, but *not* a statement
expression operator.  It's like +-*/&|^ (and I mean that in the nicest way).

> This means that some 'manual' desugaring would need to take place - but I think it's an acceptable trade off for now.

Asking the user to do the write-back is the best manual desugaring!

— John


More information about the valhalla-dev mailing list