November 16, 2013
On 11/15/2013 08:32 AM, Walter Bright wrote:
>
> It's not that bad. Phobos can be built by specifying all the files on
> the command line.

That's the essential trade-off we have to make.
Either we come up with a clumsy way to list all DLL modules during compilation (separate compilation) or we add some compiler logic to auto-import exported data symbols. In the latter case compiled object files can be used for a DLL AND a static library.
We found the second approach to be more attractive.

The only issue is that most of the time one wants to strip exports when using objects for a static library.
November 16, 2013
On 11/12/2013 11:12 PM, Martin Nowak wrote:
> That's not an issue, you can't inline exported functions.
> This is because the actual implementation is only know at link-time
> (only at run-time on UNIX).

One might chose to ignore this possibly incorrect behaviour and still inline in favour of speed, but I don't think we need to worry about this now.
November 18, 2013
On 11/15/2013 7:31 AM, Benjamin Thaut wrote:
> Am 15/11/2013 08:27, schrieb Walter Bright:
>> On 11/14/2013 3:37 AM, Benjamin Thaut wrote:
>>> Am 14.11.2013 11:28, schrieb Walter Bright:
>>>> On 11/12/2013 2:23 PM, Martin Nowak wrote:
>>>>
>>>> One possibility is modules listed on the command line are regarded as
>>>> export==dllexport, and other modules as export==dllimport.
>>>>
>>>> This of course means that functions may wind up going through the
>>>> dllimport indirection even for calling functions in the same dll, but it
>>>> should work.
>>>
>>> That doesns't work for the case where a dll "A" uses a dll "B".
>>> In that case export has to mean "dllexport" for all modules of A but
>>> "dllimport"
>>> for all modules of B.
>>
>> I don't follow. If you're compiling A, you're specifying A modules on
>> the command line, and those will regard the B modules as dllimport.
>>
>
> Ok now I understand what you suggest. So basically you want to do the exact same
> as DIP 45 just giving the compiler parameter a different name.
>
> But you still didn't give a solution for the problem that the compiler does not
> know which modules are part of a shared library, which are part of a static
> library and which are part of the exeuctable.

I thought this did cover it. "export" in imported modules that are not listed on the compiler command line is regarded as "dllimport". "export" in modules listed on the commmand line is regarded as "dllexport".

> And please also consider single file compilation.

And yes, this would mean that a function may wind up calling a function in its own dll through the dll import thunk -- however -- this thunk is often provided by the import library, and so wouldn't be there for intra-dll calls.

November 18, 2013
On 11/15/2013 8:08 AM, Daniel Murphy wrote:
> "Walter Bright" <newshound2@digitalmars.com> wrote in message
> news:l64lji$2buh$1@digitalmars.com...
>> On 11/15/2013 12:00 AM, Daniel Murphy wrote:
>>> "Walter Bright" <newshound2@digitalmars.com> wrote in message
>>> news:l64imh$27na$1@digitalmars.com...
>>>>
>>>> Also, at least on Windows, you can call functions in a DLL without
>>>> saying
>>>> dllimport on them and suffering a layer of indirection. The magic
>>>> happens
>>>> in the import library, which provides the relevant thunk. It's about 15
>>>> years since I worked on this stuff, so I might be a bit fuzzy on the
>>>> details.
>>>
>>> The symbol in the import library just translates to an import table
>>> indirection.
>>
>> Yes, meaning the compiler doesn't have to do it if the import library is
>> set up correctly. (implib.exe should do it.)
>>
>
> Right, I was saying the indirection still exists.
>
>

No, not really, at least not on Windows. Try calling a function in the Windows API and disassemble it. You'll see a direct call.
November 18, 2013
On 11/15/2013 7:34 AM, Benjamin Thaut wrote:
> Am 15/11/2013 08:32, schrieb Walter Bright:
>> It's not that bad. Phobos can be built by specifying all the files on
>> the command line.
>>
>> Also, at least on Windows, you can call functions in a DLL without
>> saying dllimport on them and suffering a layer of indirection. The magic
>> happens in the import library, which provides the relevant thunk. It's
>> about 15 years since I worked on this stuff, so I might be a bit fuzzy
>> on the details.
>
> I know that. And we are using that fact in DIP 45. For data symbols we did
> suggest a similar behaviour that has to be implemented by us first. And yes we
> need data symbols, because of all the implicit data symbols the D programming
> language generates. TypeInfos, vtables etc.
>
> I suggest that you read all the links I gave for further reading in DIP 45 and
> DIP 45 again, because you are pretty close to what we suggested in DIP 45
> without actually realizing it.

I'm very much against the suggested rewriting of obj files to strip the export records :-)

November 18, 2013
On 11/16/2013 7:22 AM, Martin Nowak wrote:
> On 11/15/2013 08:32 AM, Walter Bright wrote:
>>
>> It's not that bad. Phobos can be built by specifying all the files on
>> the command line.
>
> That's the essential trade-off we have to make.
> Either we come up with a clumsy way to list all DLL modules during compilation
> (separate compilation) or we add some compiler logic to auto-import exported
> data symbols. In the latter case compiled object files can be used for a DLL AND
> a static library.
> We found the second approach to be more attractive.

Why? dmd is very fast at compiling. I'm not sure what is being saved here.


> The only issue is that most of the time one wants to strip exports when using
> objects for a static library.

That's a pretty big issue (to me, anyway).
November 18, 2013
"Walter Bright" <newshound2@digitalmars.com> wrote in message news:l6c7gt$27fc$1@digitalmars.com...
>>
>> Right, I was saying the indirection still exists.
>>
>>
>
> No, not really, at least not on Windows. Try calling a function in the Windows API and disassemble it. You'll see a direct call.

You sure about that?

src:

import core.sys.windows.windows;

void main()
{
    auto x = GetModuleHandleA(null);
}

obj:

__Dmain PROC NEAR
;  COMDEF __Dmain
        push    0                                       ; 0000 _ 6A, 00
        call    dword ptr [__imp__GetModuleHandleA@4]   ; 0002 _ FF. 15,
00000000(segrel)
        xor     eax, eax                                  ; 0008 _ 31. C0
        ret                                             ; 000A _ C3
__Dmain ENDP


exe:

?_0072  LABEL NEAR
        push    0                                       ; 00402010 _ 6A, 00
        call    dword ptr [?_0067]                      ; 00402012 _ FF. 15,
00401794(d)
        xor     eax, eax                                ; 00402018 _ 31. C0
        ret                                             ; 0040201A _ C3


November 18, 2013
On 11/17/2013 9:25 PM, Daniel Murphy wrote:
> "Walter Bright" <newshound2@digitalmars.com> wrote in message
> news:l6c7gt$27fc$1@digitalmars.com...
>>>
>>> Right, I was saying the indirection still exists.
>>>
>>>
>>
>> No, not really, at least not on Windows. Try calling a function in the
>> Windows API and disassemble it. You'll see a direct call.
>
> You sure about that?
>
> src:
>
> import core.sys.windows.windows;
>
> void main()
> {
>      auto x = GetModuleHandleA(null);
> }
>
> obj:
>
> __Dmain PROC NEAR
> ;  COMDEF __Dmain
>          push    0                                       ; 0000 _ 6A, 00
>          call    dword ptr [__imp__GetModuleHandleA@4]   ; 0002 _ FF. 15,
> 00000000(segrel)
>          xor     eax, eax                                  ; 0008 _ 31. C0
>          ret                                             ; 000A _ C3
> __Dmain ENDP
>
>
> exe:
>
> ?_0072  LABEL NEAR
>          push    0                                       ; 00402010 _ 6A, 00
>          call    dword ptr [?_0067]                      ; 00402012 _ FF. 15,
> 00401794(d)
>          xor     eax, eax                                ; 00402018 _ 31. C0
>          ret                                             ; 0040201A _ C3
>
>

Try this:

extern (Windows) int GetModuleHandleA(char*);

void main()
{
    auto x = GetModuleHandleA(null);
}

and it compiles and links and runs. No indirection (in the object file, the indirection is supplied by linker, triggered by an impdef record in kernel32.lib). The "export" isn't actually needed.
November 18, 2013
"Walter Bright" <newshound2@digitalmars.com> wrote in message news:l6cm9d$2uq8$1@digitalmars.com...
> On 11/17/2013 9:25 PM, Daniel Murphy wrote:
>> "Walter Bright" <newshound2@digitalmars.com> wrote in message news:l6c7gt$27fc$1@digitalmars.com...
>>>>
>>>> Right, I was saying the indirection still exists.
>>>>
>>>>
>>>
>>> No, not really, at least not on Windows. Try calling a function in the Windows API and disassemble it. You'll see a direct call.
>>
>> You sure about that?
>>
>> src:
>>
>> import core.sys.windows.windows;
>>
>> void main()
>> {
>>      auto x = GetModuleHandleA(null);
>> }
>>
>> obj:
>>
>> __Dmain PROC NEAR
>> ;  COMDEF __Dmain
>>          push    0                                       ; 0000 _ 6A, 00
>>          call    dword ptr [__imp__GetModuleHandleA@4]   ; 0002 _ FF. 15,
>> 00000000(segrel)
>>          xor     eax, eax                                  ; 0008 _ 31.
>> C0
>>          ret                                             ; 000A _ C3
>> __Dmain ENDP
>>
>>
>> exe:
>>
>> ?_0072  LABEL NEAR
>>          push    0                                       ; 00402010 _ 6A,
>> 00
>>          call    dword ptr [?_0067]                      ; 00402012 _ FF.
>> 15,
>> 00401794(d)
>>          xor     eax, eax                                ; 00402018 _ 31.
>> C0
>>          ret                                             ; 0040201A _ C3
>>
>>
>
> Try this:
>
> extern (Windows) int GetModuleHandleA(char*);
>
> void main()
> {
>     auto x = GetModuleHandleA(null);
> }
>
> and it compiles and links and runs. No indirection (in the object file, the indirection is supplied by linker, triggered by an impdef record in kernel32.lib). The "export" isn't actually needed.

So now we get:

?_0072  LABEL NEAR
        push    0                                       ; 00402010 _ 6A, 00
        call    Unnamed_2_1A0DC                         ; 00402012 _ E8,
0001A0C5
        xor     eax, eax                                ; 00402017 _ 31. C0
        ret                                             ; 00402019 _ C3

Where Unnamed_2_1A0DC is a thunk in the import table:

Unnamed_2_1A0DC LABEL NEAR
        jmp     dword ptr [?_0067]                      ; 0041C0DC _ FF. 25,
00401794(d)

That still appears to be a layer of indirection to me...

So the difference is the compiler is unaware the function may be called through the import table?  Why would it ever _want_ to use the first version, are there any cases that can't simply be rewritten as the second?


November 20, 2013
Am 18.11.2013 06:12, schrieb Walter Bright:
> On 11/15/2013 7:34 AM, Benjamin Thaut wrote:
>> Am 15/11/2013 08:32, schrieb Walter Bright:
>>> It's not that bad. Phobos can be built by specifying all the files on
>>> the command line.
>>>
>>> Also, at least on Windows, you can call functions in a DLL without
>>> saying dllimport on them and suffering a layer of indirection. The magic
>>> happens in the import library, which provides the relevant thunk. It's
>>> about 15 years since I worked on this stuff, so I might be a bit fuzzy
>>> on the details.
>>
>> I know that. And we are using that fact in DIP 45. For data symbols we
>> did
>> suggest a similar behaviour that has to be implemented by us first.
>> And yes we
>> need data symbols, because of all the implicit data symbols the D
>> programming
>> language generates. TypeInfos, vtables etc.
>>
>> I suggest that you read all the links I gave for further reading in
>> DIP 45 and
>> DIP 45 again, because you are pretty close to what we suggested in DIP 45
>> without actually realizing it.
>
> I'm very much against the suggested rewriting of obj files to strip the
> export records :-)
>

That can easily be avoided by suppling a compiler switch which either actives exporting (if it is off by default) or deactivating export (if it is on by default).

-- 
Kind Regards
Benjamin Thaut