[Mono-devel-list] Bug in mini

Paolo Molaro lupus at ximian.com
Sat May 3 11:46:18 EDT 2003

On 05/02/03 Don Roberts wrote:
> Let me preface this by saying that I'm not a mono developer, I'm in the
> process of trying to get #Smalltalk to run under it, though. We ran into a
> problem running our calculator example under mono. After many hours and
> brain cells, I know why it doesn't work. Mini can't handle MSIL with the
> following pattern:
>                  ...some code...
>                  br    LOOP_TEST
> LOOP:            dup
>                  ...code using stack value...
> LOOP_TEST:       ldloc.0
>                  ldc.i4 0xff
>                  ble   LOOP
> What happens is that mini creates the basic block for LOOP before it has
> processed any of the in-edges (since the only in-edge comes from the ble
> instruction). Therefore, it doesn't know how many arguments are on the
> stack when it translates the DUP instruction and CHECK_STACK(1) fails.

I tryed running the sst.exe compiler and it seems to die in the same
way. The complete function that triggers it is:

    .method public static  specialname 
           default void GenerateCharacterLiterals$()  cil managed 
        // Method begins at RVA 0x8f7c
        // Code size 55 (0x37)
        .maxstack 6
        .locals init (
                int32   V_0)
        IL_0000: ldc.i4 256
        IL_0005: newarr Smalltalk.Classes.Character
        IL_000a: stsfld  class Smalltalk.Classes.Character[] Smalltalk.Pools.Smalltalk::Character-literals$
        IL_000f: ldsfld  class Smalltalk.Classes.Character[] Smalltalk.Pools.Smalltalk::Character-literals$
        IL_0014: ldc.i4.s 0x00
        IL_0016: stloc.0 
        IL_0017: br IL_002a

        IL_001c: dup 
        IL_001d: ldloc.0 
        IL_001e: dup 
        IL_001f: newobj instance void class Smalltalk.Classes.Character::.ctor(char)
        IL_0024: stelem.ref 
        IL_0025: ldloc.0 
        IL_0026: ldc.i4.s 0x01
        IL_0028: add 
        IL_0029: stloc.0 
        IL_002a: ldloc.0 
        IL_002b: ldc.i4 255
        IL_0030: ble IL_001c

        IL_0035: pop 
        IL_0036: ret 
    } // end of method Root$::default void GenerateCharacterLiterals$() 

The problem with this method is that it is not valid if I understand the
following paragraph of the spec correctly:

1.7.5      Backward Branch Constraints
      It must be possible, with a single forward-pass through the CIL
      instruction stream for any method, to infer the exact state of
      the evaluation stack at every instruction (where by "state" we
      mean the number and type of each item on the evaluation stack).
      In particular, if that single-pass analysis arrives at an
      instruction, call it location X, that immediately follows an
      unconditional branch, and where X is not the target of an earlier
      branch instruction, then the state of the evaluation stack at X,
      clearly, cannot be derived from existing information. In this case,
      the CLI demands that the evaluation stack at X be empty.

In this method, location X is at label IL_001c, the dup is preceded by
an unconditional branch and there is no previous branch to IL_001c
itself, so the evaluation stack at that point is assumed to be empty
and since dup has no element to duplicate, we bail out and report an
Sigh. The sad part is that peverify doesn't report the issue and the ms
jit obviously executes the code, so we'll have to make it work, too.
Is it possible to change the #smalltalk compiler to not generate that
kind of code? It may be that sometime in the future the MS people will
follow the spec and report an error for it, too...

Should bring the issue up with the MS and ECMA people :-(


lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better

More information about the Mono-devel-list mailing list