[M3devel] M3CG loophole operator is not LOOPHOLE (but what?)

Rodney M. Bates rodney_bates at lcwb.coop
Thu Dec 10 19:15:48 CET 2015


I have just discovered the hard way that the following comment, from M3CG_Ops.i3:

   loophole (from, two: ZType);
   (* s0.two := LOOPHOLE(s0.from, two) *)

is not true.

The front end can produce M3CG loophole ops in which the two types do not have
the same size.  For example, the front end passes a small exception argument
to RaiseEx by value as CGType.Addr, whose size is native word size, and if
the argument has a different stack size (e.g. REAL is 32-bit, even on a native
64-bit machine), then it first converts it using the M3CG loophole operator.

Almost the same thing can happen for an explicit LOOPHOLE in M3 source code.  On a
64-bit machine, compiling libm3/src/geometry/Transform.m3, M3 source code
equivalent to:

   LOOPHOLE (REALvariable, BITS BITSIZE(REAL) FOR [-16_7fffffff-1 .. 16_7fffffff])

(translated by CastExpr.m3:286) produces almost the same M3CG loophole operator,
because the stack size of the subrange is 64-bit, even though its memory size is
32.  So the loophole comes out converting REAL to Int64.  (Note that BITS has no
effect, since the type is not used as a field or array element).

Since loophole takes its operand off the abstract stack and puts its result back
there, the stack size is the right one to use here, for both from-type and to-type.

But what are the complete rules about loophole?   Apparently some combinations
really are bitcasts, but which ones?  Exactly those where the sizes match?  What
is the actual conversion for other combinations?  32-bit REAL to 64-bit integer
or address is particularly unclear.

If anybody has any knowledge about this, it would be helpful.  There is quite a
bit of code to vet, otherwise.  15 different places in the front end generate
loophole.

-- 
Rodney Bates
rodney.m.bates at acm.org



More information about the M3devel mailing list