Boo

BCE0055 fired during compilation starting from rev 2393 (generics generators)

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 0.7.7
  • Component/s: Compiler
  • Labels:
    None
  • Environment:
    Linux/Mono 1.2&SVN
  • Number of attachments :
    2

Description

Here's the follow-up from the mailing-list :

"""
There is a regression brought by revision 2393 (generics generators)
that I don't achieve to locate/fix.
Also, I'm not sure the same error occurs when building with MS .NET or
only occurs when building with Mono.

I can build successfully revision 2392 but with rev 2393 and later I'm
getting this error during
Boo.Lang.Useful compilation :

Boo.Lang.Useful:
[booc] Compiling 27 files to
'/home/cedric/dev/workspace/boo-svn/boo/build/Boo.Lang.Useful.dll'.
(...)
[booc] 7 warning(s). /* unused local variables warnings. */
[booc] /home/cedric/dev/workspace/boo-svn/boo/src/Boo.Lang.Useful/Collections/Cache.boo(105,13):
BCE0055: Internal compiler error: field not found.
[booc] 1 error(s).
"""

Attached output of "booc -t:library -vvv /src/
Boo.Lang.Useful/Collections/Cache.boo" to reply to Avishay's request.

  1. cache.fail.txt
    06/Feb/07 3:54 PM
    107 kB
    Cedric Vivier
  2. MonoType.patch
    09/Feb/07 4:49 PM
    2 kB
    Cedric Vivier

Issue Links

Activity

Hide
Avishay Lavie added a comment -

Marked for 0.7.7.

Show
Avishay Lavie added a comment - Marked for 0.7.7.
Hide
Avishay Lavie added a comment -

I can't reproduce this on Microsoft .NET-1.1 or 2.0. Can anyone test this on generic/non-generic Mono?

Show
Avishay Lavie added a comment - I can't reproduce this on Microsoft .NET-1.1 or 2.0. Can anyone test this on generic/non-generic Mono?
Hide
Cedric Vivier added a comment -

I downgraded to mono 1.1.17.1 just in case it was some recent
regression in mono svn but the same problem occurs.

I continued my investigations and found something really weird :

$ booc -v -t:library src/Boo.Lang.Useful/Collections/Cache.boo
Boo Compiler version 0.7.6.2389 (CLR v2.0.50727.42)
1 module(s) processed in 929,023ms after 181,419ms of environment setup.

It works! Cache.dll generated and looks ok.

$ booc -vv -t:library src/Boo.Lang.Useful/Collections/Cache.boo
Same BCE0055 error as usual (the same as with -vvv).

So it seems the error is related to some verbose/tracing option used
both by "-vv*" argumenet and nant ?

Show
Cedric Vivier added a comment - I downgraded to mono 1.1.17.1 just in case it was some recent regression in mono svn but the same problem occurs. I continued my investigations and found something really weird : $ booc -v -t:library src/Boo.Lang.Useful/Collections/Cache.boo Boo Compiler version 0.7.6.2389 (CLR v2.0.50727.42) 1 module(s) processed in 929,023ms after 181,419ms of environment setup. It works! Cache.dll generated and looks ok. $ booc -vv -t:library src/Boo.Lang.Useful/Collections/Cache.boo Same BCE0055 error as usual (the same as with -vvv). So it seems the error is related to some verbose/tracing option used both by "-vv*" argumenet and nant ?
Hide
Cedric Vivier added a comment -

Good news

I achieved to locate the problem precisely and a workaround.
A "field not found" exception was fired by
System.Reflection.Emit.TypeBuilder.GetField() during booc EmitAssembly
step in the method MapGenericField().

For some reason the mono implementation of GetField() cannot find the
protected field "_state" of the new AbstractGeneratorEnumerator class
added in rev 2393.

A quick workaround for boo mono users is to change the _state field to
public, I guess this wouldn't be correct to change this longterm as
this is clearly a mono bug.

Show
Cedric Vivier added a comment - Good news I achieved to locate the problem precisely and a workaround. A "field not found" exception was fired by System.Reflection.Emit.TypeBuilder.GetField() during booc EmitAssembly step in the method MapGenericField(). For some reason the mono implementation of GetField() cannot find the protected field "_state" of the new AbstractGeneratorEnumerator class added in rev 2393. A quick workaround for boo mono users is to change the _state field to public, I guess this wouldn't be correct to change this longterm as this is clearly a mono bug.
Hide
Cedric Vivier added a comment -
Show
Cedric Vivier added a comment - Posted patch to mono devel list : http://lists.ximian.com/pipermail/mono-devel-list/2007-February/022431.html
Hide
Cedric Vivier added a comment -

Well, it would have been too simple... there is another problem now

We can build boo rev 2393 on mono but the runtime says it cannot load the Boo.Lang.AbstractGenerator class when using a exe or dll consuming it (say Boo.Lang.Useful for instance).
Worse, the generated IL makes monodis crash...

This is not a regression because of the above patch since changing _state to public with unmodified mono does compile too but the generated dll are also incorrect.

My guess is there is another mono bug in TypeBuilder or other Reflection.Emit.* method used within booc's EmitAssembly step.
Maybe also it would be interesting too see how gmcs do this? (Avish? Rodrigo?)

Show
Cedric Vivier added a comment - Well, it would have been too simple... there is another problem now We can build boo rev 2393 on mono but the runtime says it cannot load the Boo.Lang.AbstractGenerator class when using a exe or dll consuming it (say Boo.Lang.Useful for instance). Worse, the generated IL makes monodis crash... This is not a regression because of the above patch since changing _state to public with unmodified mono does compile too but the generated dll are also incorrect. My guess is there is another mono bug in TypeBuilder or other Reflection.Emit.* method used within booc's EmitAssembly step. Maybe also it would be interesting too see how gmcs do this? (Avish? Rodrigo?)
Hide
Avishay Lavie added a comment -

The Boo.Lang.AbstractGenerator class that it's trying to use is a generic class (that's why it gets into the hassle of MixedGenericType.MapMember). For that to work, Boo.Lang.Compiler must be compiled with gmcs and not mcs, and it must use the generics-enabled System.Reflection.Emit if such a thing exists. I don't know how to do this (I was sure that's how it was in the first place!)
When using (and not gmcs), the NET_2_0 compilation flag shouldn't be set.

Show
Avishay Lavie added a comment - The Boo.Lang.AbstractGenerator class that it's trying to use is a generic class (that's why it gets into the hassle of MixedGenericType.MapMember). For that to work, Boo.Lang.Compiler must be compiled with gmcs and not mcs, and it must use the generics-enabled System.Reflection.Emit if such a thing exists. I don't know how to do this (I was sure that's how it was in the first place!) When using (and not gmcs), the NET_2_0 compilation flag shouldn't be set.
Hide
Cedric Vivier added a comment -

1) monodis output of trunk Boo.Lang.Useful.dll (generated by MS.NET) :
===

.method private virtual hidebysig newslot
instance default class [mscorlib]System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator () cil managed
{ // Method begins at RVA 0x353c .override class [mscorlib]System.Collections.IDictionary::GetEnumerator // Code size 25 (0x19) .maxstack 3 .locals init ( class [mscorlib]System.Collections.IDictionaryEnumerator V_0) IL_0000: ldarg.0 IL_0001: ldfld class Boo.Lang.Useful.Collections.Cache/LruItem Boo.Lang.Useful.Collections.Cache::_head IL_0006: callvirt instance class CompilerGenerated.Generator___generator16 class Boo.Lang.Useful.Collections.Cache/LruItem::Generator() IL_000b: newobj instance void class Boo.Lang.Useful.Collections.Cache/CacheEnumerator::.ctor(class [mscorlib]System.Collections.IEnumerable) IL_0010: stloc.0 IL_0011: br IL_0017 IL_0016: nop IL_0017: ldloc.0 IL_0018: ret } // end of method Cache::System.Collections.IDictionary.GetEnumerator

2) monodis output of Boo.Lang.Useful.dll (generated by mono) :
====
.method private virtual hidebysig newslot
instance default class [mscorlib]System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator () cil managed
{
// Method begins at RVA 0x34ac
.override class [mscorlib]System.Collections.IDictionary::GetEnumerator
// Code size 25 (0x19)
.maxstack 4
.locals init (
class [mscorlib]System.Collections.IDictionaryEnumerator V_0)
IL_0000: ldarg.0
IL_0001: ldfld class Boo.Lang.Useful.Collections.Cache/LruItem Boo.Lang.Useful.Collections.Cache::_head

    • (process:16769): WARNING **: The class Boo.Lang.AbstractGenerator`1 could not be loaded, used in Boo.Lang, Version=1.0.0.0, Culture=neutral, PublicKeyToken=32c39770e9a21a67
      Erreur de segmentation (core dumped)

3) monodis output of trunk Boo.Lang.dll (generated by MS.NET):
===
//method AbstractGenerator::GetEnumerator
.method public virtual hidebysig newslot abstract
instance default class [mscorlib]System.Collections.IEnumerator GetEnumerator () cil managed
{ // Method begins at RVA 0x0 } // end of method AbstractGenerator::GetEnumerator



4) monodis output of Boo.Lang.dll (generated by mono gmcs) :
===

// method AbstractGenerator`1::System.Collections.IEnumerable.GetEnumerator
.method private final virtual hidebysig newslot
instance default class [mscorlib]System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () cil managed
{ // Method begins at RVA 0x4ccc .override class [mscorlib]System.Collections.IEnumerable::GetEnumerator // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class Boo.Lang.AbstractGenerator`1<!0>::GetEnumerator() IL_0006: ret } // end of method AbstractGenerator`1::System.Collections.IEnumerable.GetEnumerator

// method line 147
.method public virtual hidebysig newslot abstract
instance default class [mscorlib]System.Collections.Generic.IEnumerator`1<!T> GetEnumerator () cil managed
{ // Method begins at RVA 0x0 } } // end of method AbstractGenerator`1::GetEnumerator

The big difference between (3) and (4) is surprising, maybe the problem is coming from here?

Show
Cedric Vivier added a comment - 1) monodis output of trunk Boo.Lang.Useful.dll (generated by MS.NET) : === .method private virtual hidebysig newslot instance default class [mscorlib]System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator () cil managed { // Method begins at RVA 0x353c .override class [mscorlib]System.Collections.IDictionary::GetEnumerator // Code size 25 (0x19) .maxstack 3 .locals init ( class [mscorlib]System.Collections.IDictionaryEnumerator V_0) IL_0000: ldarg.0 IL_0001: ldfld class Boo.Lang.Useful.Collections.Cache/LruItem Boo.Lang.Useful.Collections.Cache::_head IL_0006: callvirt instance class CompilerGenerated.Generator___generator16 class Boo.Lang.Useful.Collections.Cache/LruItem::Generator() IL_000b: newobj instance void class Boo.Lang.Useful.Collections.Cache/CacheEnumerator::.ctor(class [mscorlib]System.Collections.IEnumerable) IL_0010: stloc.0 IL_0011: br IL_0017 IL_0016: nop IL_0017: ldloc.0 IL_0018: ret } // end of method Cache::System.Collections.IDictionary.GetEnumerator 2) monodis output of Boo.Lang.Useful.dll (generated by mono) : ==== .method private virtual hidebysig newslot instance default class [mscorlib]System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator () cil managed { // Method begins at RVA 0x34ac .override class [mscorlib]System.Collections.IDictionary::GetEnumerator // Code size 25 (0x19) .maxstack 4 .locals init ( class [mscorlib]System.Collections.IDictionaryEnumerator V_0) IL_0000: ldarg.0 IL_0001: ldfld class Boo.Lang.Useful.Collections.Cache/LruItem Boo.Lang.Useful.Collections.Cache::_head
    • (process:16769): WARNING **: The class Boo.Lang.AbstractGenerator`1 could not be loaded, used in Boo.Lang, Version=1.0.0.0, Culture=neutral, PublicKeyToken=32c39770e9a21a67 Erreur de segmentation (core dumped)
3) monodis output of trunk Boo.Lang.dll (generated by MS.NET): === //method AbstractGenerator::GetEnumerator .method public virtual hidebysig newslot abstract instance default class [mscorlib]System.Collections.IEnumerator GetEnumerator () cil managed { // Method begins at RVA 0x0 } // end of method AbstractGenerator::GetEnumerator 4) monodis output of Boo.Lang.dll (generated by mono gmcs) : === // method AbstractGenerator`1::System.Collections.IEnumerable.GetEnumerator .method private final virtual hidebysig newslot instance default class [mscorlib]System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () cil managed { // Method begins at RVA 0x4ccc .override class [mscorlib]System.Collections.IEnumerable::GetEnumerator // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class Boo.Lang.AbstractGenerator`1<!0>::GetEnumerator() IL_0006: ret } // end of method AbstractGenerator`1::System.Collections.IEnumerable.GetEnumerator // method line 147 .method public virtual hidebysig newslot abstract instance default class [mscorlib]System.Collections.Generic.IEnumerator`1<!T> GetEnumerator () cil managed { // Method begins at RVA 0x0 } } // end of method AbstractGenerator`1::GetEnumerator The big difference between (3) and (4) is surprising, maybe the problem is coming from here?
Hide
Cedric Vivier added a comment -

Hey Avish! You replied while I was posting the monodis dumps

So you mean Boo.Lang should not be compiled with NET_2_0 profile when building NET_2_0 boo?

Show
Cedric Vivier added a comment - Hey Avish! You replied while I was posting the monodis dumps So you mean Boo.Lang should not be compiled with NET_2_0 profile when building NET_2_0 boo?
Hide
Avishay Lavie added a comment -

Yes, of course.
Also, the difference between (3) and (4) seems to be because (3) was generated by MS.NET 1.1 and not 2.0, or by MS.NET 2.0 without setting the compilation flag NET_2_0 when compiling Boo.Lang.dll.

To make it clear:
To compile boo for generics, we must use the .NET Framework v2.0 or gmcs, and include the NET_2_0 flag when compiling Boo.Lang and Boo.Lang.Compiler. Nant is supposed to do both of these.
To compile boo without generics support, we should NOT set the NET_2_0 flag for neither Boo.Lang.Compiler nor Boo.Lang.
If we have a Boo.Lang.Compiler compiled with NET_2_0 support but our Boo.Lang.dll was not compiled with NET_2_0 support, we're in a lot of trouble.

I'll try to dig more into this tomorrow, now that I have a shiny new Kubuntu distro all set up.

Show
Avishay Lavie added a comment - Yes, of course. Also, the difference between (3) and (4) seems to be because (3) was generated by MS.NET 1.1 and not 2.0, or by MS.NET 2.0 without setting the compilation flag NET_2_0 when compiling Boo.Lang.dll. To make it clear: To compile boo for generics, we must use the .NET Framework v2.0 or gmcs, and include the NET_2_0 flag when compiling Boo.Lang and Boo.Lang.Compiler. Nant is supposed to do both of these. To compile boo without generics support, we should NOT set the NET_2_0 flag for neither Boo.Lang.Compiler nor Boo.Lang. If we have a Boo.Lang.Compiler compiled with NET_2_0 support but our Boo.Lang.dll was not compiled with NET_2_0 support, we're in a lot of trouble. I'll try to dig more into this tomorrow, now that I have a shiny new Kubuntu distro all set up.
Hide
Cedric Vivier added a comment -

Ok, sorry if I was a little confused of your previous reply... and I actually forgot trunk's Boo.Lang.dll has not been "bin updated" after rev.2393 so my comparison was pretty pointless

So yeah, of course Nant is doing the job here, this means we are left with some another bug in mono's TypeBuilder/Reflection.Emit during EmitAssembly, right?

PS: welcome to the shiny world of (k)ubuntu

Show
Cedric Vivier added a comment - Ok, sorry if I was a little confused of your previous reply... and I actually forgot trunk's Boo.Lang.dll has not been "bin updated" after rev.2393 so my comparison was pretty pointless So yeah, of course Nant is doing the job here, this means we are left with some another bug in mono's TypeBuilder/Reflection.Emit during EmitAssembly, right? PS: welcome to the shiny world of (k)ubuntu
Hide
Cedric Vivier added a comment -

I tried on another machine and it works nice (with MonoType.patch applied of course)

Sorry for the false report about the class loading problem, it was a weird packaging conflict on my machine.

I believe we can close the bug now if anyone can confirm.

Show
Cedric Vivier added a comment - I tried on another machine and it works nice (with MonoType.patch applied of course) Sorry for the false report about the class loading problem, it was a weird packaging conflict on my machine. I believe we can close the bug now if anyone can confirm.
Hide
Avishay Lavie added a comment -

I want to make sure Boo builds ok on all 5 platform (.NET-1, .NET-2, mcs-1,mcs-2, gmcs-2) before we close this one. Also, I'm not happy with the transition of _state to public - it should be protected.
Have you received any response from the Mono guys?

Show
Avishay Lavie added a comment - I want to make sure Boo builds ok on all 5 platform (.NET-1, .NET-2, mcs-1,mcs-2, gmcs-2) before we close this one. Also, I'm not happy with the transition of _state to public - it should be protected. Have you received any response from the Mono guys?
Hide
Avishay Lavie added a comment -

I looked inside your patch and only now I fully understand the problem. Until the bug gets fixed upstream, marking _state public is the best thing we can do. Let's close this baby. Cedric, do you want to commit it or should I?

Show
Avishay Lavie added a comment - I looked inside your patch and only now I fully understand the problem. Until the bug gets fixed upstream, marking _state public is the best thing we can do. Let's close this baby. Cedric, do you want to commit it or should I?
Hide
Cedric Vivier added a comment -

No response from the mono guys yet.
I'd love to commit but it seems I do not have commit rights, so please do

Show
Cedric Vivier added a comment - No response from the mono guys yet. I'd love to commit but it seems I do not have commit rights, so please do
Hide
Avishay Lavie added a comment -

Cedric's hack applied.

Show
Avishay Lavie added a comment - Cedric's hack applied.
Hide
Cedric Vivier added a comment -

Time to close this one.

Show
Cedric Vivier added a comment - Time to close this one.

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: