Jump to page: 1 2
Thread overview
v0.123 borks the vTable
May 19, 2005
Kris
May 19, 2005
Kris
May 19, 2005
Walter
May 20, 2005
Kris
May 20, 2005
Walter
Re: v0.123 borks the vTable ~ Example
May 19, 2005
Kris
May 19, 2005
Walter
May 20, 2005
Walter
May 20, 2005
Kris
May 20, 2005
Walter
May 20, 2005
Kris
May 20, 2005
Kris
May 20, 2005
Walter
May 19, 2005
There's apparently been some notable changes in the way Interfaces are handled within both v0.122 and v0.123. Code that compiled and executed cleanly (and has done for ~10 months) breaks with both these builds.


dmd 0.121
-----------
# C:\D\mango\mango\io>dmd -c -I\d\mango Writer.d -v
# parse     Writer
# semantic  Writer
# semantic2 Writer
# semantic3 Writer
# code      Writer
# generating code for function 'this'
# generating code for function 'this'
# generating code for function 'error'
# generating code for function 'getBuffer'
# generating code for function 'setEncoder'
# generating code for function 'flush'
# generating code for function 'cr'
# generating code for function 'enableArrayPrefix'
# generating code for function 'length'
# generating code for function 'write'
# generating code for function 'encoder'
# generating code for function 'put'
# generating code for function 'put'
...
# generating code for function 'write'
# generating code for function '_staticCtor'



dmd 0.122
------------
# C:\D\mango\mango\io>dmd -c -I\d\mango Writer.d -v
# parse     Writer
# semantic  Writer
# Error: circular inheritance of interface



dmd 0.123
-----------
Same as 0.121, but tracing execution shows that calling through an interface now goes off into la la land (actually, instead of going to the vtable it went directly to the _printf C library routine!)


What happened, Walter?



May 19, 2005
DMD 0.124 has the same problem: compiles cleanly, but calls through interfaces are borked.


"Kris" <fu@bar.com> wrote in message news:d6il7f$2agd$1@digitaldaemon.com...
> There's apparently been some notable changes in the way Interfaces are handled within both v0.122 and v0.123. Code that compiled and executed cleanly (and has done for ~10 months) breaks with both these builds.
>
>
> dmd 0.121
> -----------
> # C:\D\mango\mango\io>dmd -c -I\d\mango Writer.d -v
> # parse     Writer
> # semantic  Writer
> # semantic2 Writer
> # semantic3 Writer
> # code      Writer
> # generating code for function 'this'
> # generating code for function 'this'
> # generating code for function 'error'
> # generating code for function 'getBuffer'
> # generating code for function 'setEncoder'
> # generating code for function 'flush'
> # generating code for function 'cr'
> # generating code for function 'enableArrayPrefix'
> # generating code for function 'length'
> # generating code for function 'write'
> # generating code for function 'encoder'
> # generating code for function 'put'
> # generating code for function 'put'
> ...
> # generating code for function 'write'
> # generating code for function '_staticCtor'
>
>
>
> dmd 0.122
> ------------
> # C:\D\mango\mango\io>dmd -c -I\d\mango Writer.d -v
> # parse     Writer
> # semantic  Writer
> # Error: circular inheritance of interface
>
>
>
> dmd 0.123
> -----------
> Same as 0.121, but tracing execution shows that calling through an
interface
> now goes off into la la land (actually, instead of going to the vtable it went directly to the _printf C library routine!)
>
>
> What happened, Walter?
>
>
>


May 19, 2005
"Kris" <fu@bar.com> wrote in message news:d6il7f$2agd$1@digitaldaemon.com...
> What happened, Walter?

I don't know. But if you can make a small example, I can fix it, it'll go into the test suite, and it'll never happen again.


May 19, 2005
Here's a contrived example that aborts:

interface IWritable
{
        void write (IWriter writer);
}

interface IWriter
{
        IWriter put (IWritable x);
}

interface IPhantom : IWritable {}

interface INewline : IPhantom {}

class Newline : INewline
{
        void write (IWriter writer)
        {
                printf ("OK\n");
        }
}



// implementation

class Writer : IWriter
{
        IWriter put (IWritable x)
        {
                x.write (this);
                return this;
        }
}

class DisplayWriter : Writer
{
        alias Writer.put put;
}

class FlushWriter : DisplayWriter
{
        override IWriter put (IWritable x)
        {
               // have superclass handle the IWritable
                super.put (x);

                // flush output when we see a newline
                if (cast(Newline) x)
                   {
                   }

                return this;
        }
}


// a static instance
public static INewline NL;

static this ()
{
        NL = new Newline;
}


void test (IWriter w)
{
        // this works
        //w.put (new Newline);

        // this fails
        w.put (NL);
}


void main()
{
        test (new FlushWriter);
}

######################

C:\D\mango\mango\test>test
Object
Error: Access Violation

######################

This example actually calls _printf() directly instead of w.put(), which is
where the console output "Object" comes from.

There seems to be an issue with the use of a statically constructed NL. Further, if the depth of interface inheritance is changed for NL (e.g. derive directly from IWritable instead of IPhantom) then it doesn't break. Nor does it break if you construct and pass a new Newline instance. BTW; I recall this same bug appeared and was fixed in the 0.8x timeframe. I couldn't reproduce an example at that time.

Any chance of an interim release to fix this, please?  Mango is completely broken by this.


Finally, just an FYI: I noticed the codegen for interfaces has (recently) become a bit bloated ~ here's a listing from the above code: there are tests made on the Interface that used to occur, but were fixed sometime in the middle of last year (they used to be performed when returning an Interface, but that was cleaned up nicely). Now they appear to be back again?

Compiler flags are -release -g  (-O makes no real difference)

This first listing is converting an Interface to its superInterface
(INewline to IWritable):

67:   void test (IWriter w)
004020B8   enter       4,0
004020BC   mov         dword ptr [ebp-4],eax
68:   {
69:           // this works
70:           //w.put (new Newline);
71:
72:           // this fails
73:           w.put (NL);
004020BF   cmp         dword ptr [_D3bar2NLC3bar8INewline (00415760)],0
004020C6   je          _D3bar4testFC3bar7IWriterZv+1Ah (004020d2)
004020C8   mov         eax,[_D3bar2NLC3bar8INewline (00415760)]
004020CD   lea         ecx,[eax+8]
004020D0   jmp         _D3bar4testFC3bar7IWriterZv+1Ch (004020d4)
004020D2   xor         ecx,ecx
004020D4   push        ecx
004020D5   mov         eax,dword ptr [w]
004020D8   mov         edx,dword ptr [eax]
004020DA   call        dword ptr [edx+4]
74:   }
004020DD   leave
004020DE   ret

And this one is converting from an object into an implemented interface
(FlushWriter to IWriter):

78:   void main()
004020E0   enter       4,0
79:   {
80:           test (new FlushWriter);
004020E4   push        offset __Class_3bar11FlushWriter (00411354)
004020E9   call        __d_newclass (00402330)
004020EE   add         esp,4
004020F1   mov         dword ptr [_TMP5],eax
004020F4   test        eax,eax
004020F6   je          _Dmain+1Dh (004020fd)
004020F8   lea         eax,[eax+8]
004020FB   jmp         _Dmain+1Fh (004020ff)
004020FD   xor         eax,eax
004020FF   call        _D3bar4testFC3bar7IWriterZv (004020b8)
81:   }
00402104   leave
00402105   ret


This kind of thing used to be performed much more efficiently, and still is when returning an Object as an Interface; as this partial listing from the FlushWriter method shows:

53:                   return this;
00402084   mov         eax,dword ptr [this]
00402087   add         eax,8
54:           }
0040208A   leave
0040208B   ret         4

Back last year, this kind of return statement had the same odd tests as seen in the other listings. Thankfully, those were cleaned up nicely. Can you clean up these ones too, please?






"Kris" <fu@bar.com> wrote in message news:d6il7f$2agd$1@digitaldaemon.com...
> There's apparently been some notable changes in the way Interfaces are handled within both v0.122 and v0.123. Code that compiled and executed cleanly (and has done for ~10 months) breaks with both these builds.
>
>
> dmd 0.121
> -----------
> # C:\D\mango\mango\io>dmd -c -I\d\mango Writer.d -v
> # parse     Writer
> # semantic  Writer
> # semantic2 Writer
> # semantic3 Writer
> # code      Writer
> # generating code for function 'this'
> # generating code for function 'this'
> # generating code for function 'error'
> # generating code for function 'getBuffer'
> # generating code for function 'setEncoder'
> # generating code for function 'flush'
> # generating code for function 'cr'
> # generating code for function 'enableArrayPrefix'
> # generating code for function 'length'
> # generating code for function 'write'
> # generating code for function 'encoder'
> # generating code for function 'put'
> # generating code for function 'put'
> ...
> # generating code for function 'write'
> # generating code for function '_staticCtor'
>
>
>
> dmd 0.122
> ------------
> # C:\D\mango\mango\io>dmd -c -I\d\mango Writer.d -v
> # parse     Writer
> # semantic  Writer
> # Error: circular inheritance of interface
>
>
>
> dmd 0.123
> -----------
> Same as 0.121, but tracing execution shows that calling through an
interface
> now goes off into la la land (actually, instead of going to the vtable it went directly to the _printf C library routine!)
>
>
> What happened, Walter?
>
>
>


May 19, 2005
Thanks. I'll have a look.


May 20, 2005
There's a second related segfault that I have an example for ~ there's four layers of inheritance, with an embedded diamond.

Do you have an email I can send it to?



"Walter" <newshound@digitalmars.com> wrote in message news:d6ivqe$2jt9$1@digitaldaemon.com...
>
> "Kris" <fu@bar.com> wrote in message
news:d6il7f$2agd$1@digitaldaemon.com...
> > What happened, Walter?
>
> I don't know. But if you can make a small example, I can fix it, it'll go into the test suite, and it'll never happen again.
>
>


May 20, 2005
"Kris" <fu@bar.com> wrote in message news:d6jdrj$2tca$1@digitaldaemon.com...
> There's a second related segfault that I have an example for ~ there's
four
> layers of inheritance, with an embedded diamond.
>
> Do you have an email I can send it to?

www.digitalmars.com/contact.html


May 20, 2005
"Kris" <fu@bar.com> wrote in message news:d6j1tk$2lbr$1@digitaldaemon.com...
> Here's a contrived example that aborts:

I've found the problem and fixed it.

> Finally, just an FYI: I noticed the codegen for interfaces has (recently) become a bit bloated ~ here's a listing from the above code: there are
tests
> made on the Interface that used to occur, but were fixed sometime in the middle of last year (they used to be performed when returning an
Interface,
> but that was cleaned up nicely). Now they appear to be back again?

Those tests are needed when an offset needs to be added to the 'this' pointer to get a pointer to the right vtbl[]. If the 'this' is null, it shouldn't get an offset added.


May 20, 2005
Right; but isn't that trying to salvage a use-case that's already broken? I mean, you're working with a invalid null instance at that point - yes?


"Walter" <newshound@digitalmars.com> wrote in message news:d6lacb$1fbd$2@digitaldaemon.com...
>
> "Kris" <fu@bar.com> wrote in message
news:d6j1tk$2lbr$1@digitaldaemon.com...
> > Here's a contrived example that aborts:
>
> I've found the problem and fixed it.
>
> > Finally, just an FYI: I noticed the codegen for interfaces has
(recently)
> > become a bit bloated ~ here's a listing from the above code: there are
> tests
> > made on the Interface that used to occur, but were fixed sometime in the middle of last year (they used to be performed when returning an
> Interface,
> > but that was cleaned up nicely). Now they appear to be back again?
>
> Those tests are needed when an offset needs to be added to the 'this' pointer to get a pointer to the right vtbl[]. If the 'this' is null, it shouldn't get an offset added.
>
>


May 20, 2005
Shall I test it against Mango?

(I just sent an email that has a return address)


"Walter" <newshound@digitalmars.com> wrote in message news:d6lacb$1fbd$2@digitaldaemon.com...
>
> "Kris" <fu@bar.com> wrote in message
news:d6j1tk$2lbr$1@digitaldaemon.com...
> > Here's a contrived example that aborts:
>
> I've found the problem and fixed it.
>
> > Finally, just an FYI: I noticed the codegen for interfaces has
(recently)
> > become a bit bloated ~ here's a listing from the above code: there are
> tests
> > made on the Interface that used to occur, but were fixed sometime in the middle of last year (they used to be performed when returning an
> Interface,
> > but that was cleaned up nicely). Now they appear to be back again?
>
> Those tests are needed when an offset needs to be added to the 'this' pointer to get a pointer to the right vtbl[]. If the 'this' is null, it shouldn't get an offset added.
>
>


« First   ‹ Prev
1 2