Jump to page: 1 2
Thread overview
February 08
How are static ctors actually implemented in D?  I was under the impression that there's some kind of table stored in the executable that the druntime startup code traverses. But apparently this is OS-dependent??  I'm trying to get static ctors to work in wasm, but can't find any way of making it work. The druntime code that I looked into all hook into stuff dependent on the executable format, and obviously there isn't anything for wasm (yet).

Is this even possible in wasm?  Or am I missing something obvious?


T

-- 
A program should be written to model the concepts of the task it performs rather than the physical world or a process because this maximizes the potential for it to be applied to tasks that are conceptually similar and, more important, to tasks that have not yet been conceived. -- Michael B. Allen
February 09

On Friday, 9 February 2024 at 00:02:12 UTC, H. S. Teoh wrote:

>

How are static ctors actually implemented in D? I was under the impression that there's some kind of table stored in the executable that the druntime startup code traverses. But apparently this is OS-dependent?? I'm trying to get static ctors to work in wasm, but can't find any way of making it work. The druntime code that I looked into all hook into stuff dependent on the executable format, and obviously there isn't anything for wasm (yet).

It primarily depends on the binary format, and is a cooperation between compiler and druntime. Usually, the compiler emits non-linker-strippable pointers to compiler-generated ModuleInfo structs into a special section (__minfo, .minfo or so), one for each .d module getting compiled into a specific object file. After linking to an executable/shared library, the ModuleInfo pointers of all .d modules of each linked object file are then stored consecutively in that named section of the data segment. This way, druntime can then reflect on all D modules/ModuleInfos linked into a binary, by getting that data range of ModuleInfo pointers (e.g., via linker-generated __{start,stop}___minfo bracketing symbols for ELF). And from there, module ctors, unittests etc. can be inferred.

>

Is this even possible in wasm? Or am I missing something obvious?

LDC has a fallback for exotic platforms, where it uses a linked list, and compiler-generated CRT-constructor functions which insert the ModuleInfo pointers at program initialization (in undefined order), invoked by the C runtime before C main(). So if wasm doesn't support named sections/data ranges, but would 'implicitly' support initializer functions (CRT constructors), that could be a potential route to take.

February 09

On Friday, 9 February 2024 at 00:48:47 UTC, kinke wrote:

>

So if wasm doesn't support named sections/data ranges

Oh well, looks like wasm-ld (i.e., lld) supports exactly the same magic __{start,stop}_* symbols as for ELF: https://github.com/llvm/llvm-project/issues/55839

February 09

On Friday, 9 February 2024 at 01:17:26 UTC, kinke wrote:

>

Oh well, looks like wasm-ld (i.e., lld) supports exactly the same magic __{start,stop}_* symbols as for ELF: https://github.com/llvm/llvm-project/issues/55839

Oh man, I've even added an LDC test for this, but almost 4 years ago and so forgot. :D

https://github.com/ldc-developers/ldc/blob/3c21924705aae83f0c16bfe54e673953671afe58/tests/codegen/wasi.d#L22-L39

February 09

On Friday, 9 February 2024 at 01:22:28 UTC, kinke wrote:

>

Oh man, I've even added an LDC test for this, but almost 4 years ago and so forgot. :D

https://github.com/ldc-developers/ldc/blob/3c21924705aae83f0c16bfe54e673953671afe58/tests/codegen/wasi.d#L22-L39

Yep, I remember asking you about for my druntime wasm port.

February 09
On Friday, 9 February 2024 at 00:02:12 UTC, H. S. Teoh wrote:
> Is this even possible in wasm?  Or am I missing something obvious?
>
>
> T

Might I direct you to my past efforts of a druntime port? This is a good entry point https://github.com/skoppe/ldc/tree/wasm as it contains the changes for LDC and submodules for Phobos and druntime.

I got everything working, except for things that aren't supported like exceptions and fibers.

Its just 3 year behind on master.

The other issue is the GC not seeing all pointers hence freeing too much. As mentioned in another thread this can be solved by spilling the pointers to the shadow stack, which involves either changes to LDC/llvm or doing a post build step. Nowadays there is binaryen which reimplemented the required pass. I haven't been able to test it but others have used it with a similar Böhm GC.
February 15
On Fri, Feb 09, 2024 at 01:22:28AM +0000, kinke via Digitalmars-d wrote:
> On Friday, 9 February 2024 at 01:17:26 UTC, kinke wrote:
> > Oh well, looks like wasm-ld (i.e., lld) supports exactly the same magic `__{start,stop}_*` symbols as for ELF: https://github.com/llvm/llvm-project/issues/55839
> 
> Oh man, I've even added an LDC test for this, but almost 4 years ago and so forgot. :D
> 
> https://github.com/ldc-developers/ldc/blob/3c21924705aae83f0c16bfe54e673953671afe58/tests/codegen/wasi.d#L22-L39

Hmm, I'm running into a problem here.  Following the above link I declared the symbols like this:

```d
extern(C) extern __gshared
{
    void* __start__minfo;
    void* __stop__minfo;
}
```

However, when I check their values at runtime:

```d
export void _wasm_start() // this is called from my JS bridge
{
    writefln("__start__minfo=0x%x", &__start__minfo);
    writefln("__end__minfo=0x%x", &__stop__minfo);
}
```

(I have a bare-bones version of writefln running for debugging purposes.)

The output says:

````
__start__minfo=0x0
__end__minfo=0x%0
````

What gives?

For reference, I'm using LDC 1.36.0 on x86_64--linux-gnu, with these compile flags:

	-mtriple=wasm32-unknown-unknown-wasm -Iplatform/wasm -O2 -L-allow-undefined -allinst -linkonce-templates --fvisibility=hidden

I had --fno-rtti before and it didn't work; I removed it but it still made no difference. I guess it's unrelated to RTTI.  Also, I tried removing --fvisibility-hidden but it also made no difference.

What am I doing wrong?


T

-- 
Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever.
February 15
On Thu, Feb 15, 2024 at 01:45:50PM -0800, H. S. Teoh via Digitalmars-d wrote: [...]
> The output says:
> 
> ````
> __start__minfo=0x0
> __end__minfo=0x%0
> ````
[...]

Ack, stray character got stuck in there somehow. Here's a pristine copy-n-paste from the output log:

````
__start__minfo=0x0
__end__minfo=0x0

````


T

-- 
We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
February 15
On 2/15/24 2:45 PM, H. S. Teoh wrote:
> On Fri, Feb 09, 2024 at 01:22:28AM +0000, kinke via Digitalmars-d wrote:
>> On Friday, 9 February 2024 at 01:17:26 UTC, kinke wrote:
>>> Oh well, looks like wasm-ld (i.e., lld) supports exactly the same
>>> magic `__{start,stop}_*` symbols as for ELF:
>>> https://github.com/llvm/llvm-project/issues/55839
>>
>> Oh man, I've even added an LDC test for this, but almost 4 years ago
>> and so forgot. :D
>>
>> https://github.com/ldc-developers/ldc/blob/3c21924705aae83f0c16bfe54e673953671afe58/tests/codegen/wasi.d#L22-L39
> 
> Hmm, I'm running into a problem here.  Following the above link I
> declared the symbols like this:
> 
> ```d
> extern(C) extern __gshared
> {
>      void* __start__minfo;
>      void* __stop__minfo;
> }
> ```
> 
> However, when I check their values at runtime:
> 
> ```d
> export void _wasm_start() // this is called from my JS bridge
> {
>      writefln("__start__minfo=0x%x", &__start__minfo);
>      writefln("__end__minfo=0x%x", &__stop__minfo);
> }
> ```
> 
> (I have a bare-bones version of writefln running for debugging purposes.)
> 
> The output says:
> 
> ````
> __start__minfo=0x0
> __end__minfo=0x%0
> ````
> 
> What gives?
> 
> For reference, I'm using LDC 1.36.0 on x86_64--linux-gnu, with these
> compile flags:
> 
> 	-mtriple=wasm32-unknown-unknown-wasm -Iplatform/wasm -O2 -L-allow-undefined -allinst -linkonce-templates --fvisibility=hidden
> 
> I had --fno-rtti before and it didn't work; I removed it but it still
> made no difference. I guess it's unrelated to RTTI.  Also, I tried
> removing --fvisibility-hidden but it also made no difference.
> 
> What am I doing wrong?

While I have zero knowledge of how LDC handles WASM, I did notice one difference between your code and the example in the link: the definition at the link has three underscores before the `minfo` whereas your code has only two.

February 15
On Thu, Feb 15, 2024 at 03:04:28PM -0700, David Gileadi via Digitalmars-d wrote:
> On 2/15/24 2:45 PM, H. S. Teoh wrote:
[...]
> > ```d
> > extern(C) extern __gshared
> > {
> >      void* __start__minfo;
> >      void* __stop__minfo;
> > }
> > ```
[...]
> While I have zero knowledge of how LDC handles WASM, I did notice one difference between your code and the example in the link: the definition at the link has three underscores before the `minfo` whereas your code has only two.

Whoa... I totally missed that! :-O

However, correcting it to 3 underscores still produced 0. :-(   What's going on??


T

-- 
I am not young enough to know everything. -- Oscar Wilde
« First   ‹ Prev
1 2