Cesium icon indicating copy to clipboard operation
Cesium copied to clipboard

Strange approach to `ldind`

Open ForNeVeR opened this issue 7 months ago • 1 comments

Currently, PrimitiveType.cs has the following code:

    internal static readonly Dictionary<PrimitiveTypeKind, (OpCode load, OpCode store)> Opcodes = new()
    {
        { PrimitiveTypeKind.Char, (OpCodes.Ldind_I1, OpCodes.Stind_I1) },
        { PrimitiveTypeKind.SignedChar, (OpCodes.Ldind_I1, OpCodes.Stind_I1) },
        { PrimitiveTypeKind.UnsignedChar, (OpCodes.Ldind_U1, OpCodes.Stind_I1) },
        { PrimitiveTypeKind.Short, (OpCodes.Ldind_I2, OpCodes.Stind_I2) },
        { PrimitiveTypeKind.UnsignedShort, (OpCodes.Ldind_I2, OpCodes.Stind_I2) },
        { PrimitiveTypeKind.Int, (OpCodes.Ldind_I4, OpCodes.Stind_I4) },
        { PrimitiveTypeKind.UnsignedInt, (OpCodes.Ldind_I4, OpCodes.Stind_I4) },
        { PrimitiveTypeKind.Float, (OpCodes.Ldind_R4, OpCodes.Stind_R4) },
        { PrimitiveTypeKind.Long, (OpCodes.Ldind_I8, OpCodes.Stind_I8) },
        { PrimitiveTypeKind.UnsignedLong, (OpCodes.Ldind_I8, OpCodes.Stind_I8) },
        { PrimitiveTypeKind.Double, (OpCodes.Ldind_R8, OpCodes.Stind_R8) }
    };

Note how all the other unsigned types have same get operation as their signed counterparts, except UnsignedChar that has OpCodes.Ldind_U1.

In CIL, there are four unsigned ldind operations: ldind.u1, ldind.u2, and ldind.u4 (notably, ldind.u8 is absent). And we don't use them and use the signed versions.

Another interesting part is that there are no stind.u* operations: all the setters are always signed.

We should figure out if there's any visible difference between these operations, and either

  • use the signed ones consistently for all the unsigned types
  • or use the unsigned operations where available

ForNeVeR avatar Nov 12 '23 20:11 ForNeVeR

A possible test case (in C# for explanation's sake, so we'll of course need to convert to C):

sbyte[] x = new[] { -1 };
sbyte y = x[0]; // 2
int z = (int)y; // 3

My hypothesis is that the int cast in line 3 won't do anything actually, and thus its result will depend on whether the ldind operation in line 2 does sign-extension or zero-extension of the sbyte value in the array x.

ForNeVeR avatar Nov 12 '23 20:11 ForNeVeR