www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Where is TypeInfo_Class.m_init set

reply Hakan Aras <hakan.aras live.at> writes:
Sorry if this is the wrong category.

Where in the druntime is m_init of TypeInfo_Class set? I'm trying 
to use extern(C++) classes with -betterC and I would like to 
initialize their members properly.
Jul 30 2018
next sibling parent reply Mike Franklin <slavo5150 yahoo.com> writes:
On Monday, 30 July 2018 at 22:40:21 UTC, Hakan Aras wrote:
 Sorry if this is the wrong category.

 Where in the druntime is m_init of TypeInfo_Class set? I'm 
 trying to use extern(C++) classes with -betterC and I would 
 like to initialize their members properly.
I don't think it is set in druntime, but rather directly emitted to the binary by the compiler as part of the object code generation. I'm not sure if this is right, but check https://github.com/dlang/dmd/blob/792fe5379af310cbd9348eca910cd5f8889d57ac/ rc/dmd/toobj.d#L368 Afterall, the initializer is static data, so there's no need to expend resources setting it at runtime. Mike
Jul 30 2018
next sibling parent Mike Franklin <slavo5150 yahoo.com> writes:
On Tuesday, 31 July 2018 at 00:29:45 UTC, Mike Franklin wrote:

 I'm not sure if this is right, but check 
 https://github.com/dlang/dmd/blob/792fe5379af310cbd9348eca910cd5f8889d57ac/src/dmd/toobj.d#L368
Actually, this looks more like what you're looking for: https://github.com/dlang/dmd/blob/792fe5379af310cbd9348eca910cd5f8889d57ac/src/dmd/toobj.d#L1202 Mike
Jul 30 2018
prev sibling parent reply Hakan Aras <hakan.aras live.at> writes:
On Tuesday, 31 July 2018 at 00:29:45 UTC, Mike Franklin wrote:

 I don't think it is set in druntime, but rather directly 
 emitted to the binary by the compiler as part of the object 
 code generation.  I'm not sure if this is right, but check
 
That makes sense. I was hoping it would be possible without tinkering with the compiler, but it doesn't seem to be the case.
Jul 30 2018
next sibling parent Hakan Aras <hakan.aras live.at> writes:
If anyone stumbles upon this thread and wants to do the same 
thing, this article has some solutions: 
https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc.html

Not perfect, but at least it's a start.
Jul 30 2018
prev sibling parent reply kinke <kinke libero.it> writes:
On Tuesday, 31 July 2018 at 01:16:29 UTC, Hakan Aras wrote:
 I was hoping it would be possible without tinkering with the 
 compiler, but it doesn't seem to be the case.
I've been playing around with LDC. There is an init symbol for classes, which is normally used as payload for the ClassInfo's m_init. I haven't been able to get its correct address though (I don't know enough about relocations), but it looks as if it could be gotten to work this way, see https://run.dlang.io/is/ZLDCpZ. Remove `-betterC` to see the address discrepancy causing the segfault, something like: init: 0x55dd229dc810 actual: 0x55dd229d3cf0
Jul 31 2018
parent reply kinke <noone nowhere.com> writes:
Sorry, scratch that, I forgot the `extern` before the dummy 
global. After fixing that, I didn't quickly find a solution for 
referencing the symbol in the .data.rel.ro section (LLVM asm, 
e.g., `void* getInit() { return __asm!(void*)("movq 
test.C.__init, %rax", "={rax}"); }` doesn't work either).

The compiler could emit the init symbol as regular global for 
`-betterC` though.

---

This issue could also be tackled in the D ctor of the extern(C++) 
class, by injecting the blit before the actual ctor body. C++ 
code wouldn't have to take care about that D-interop 
incompatibility anymore (independent of -betterC).
Jul 31 2018
parent reply Hakan Aras <hakan.aras live.at> writes:
On Tuesday, 31 July 2018 at 20:45:11 UTC, kinke wrote:
 Sorry, scratch that, I forgot the `extern` before the dummy 
 global. After fixing that, I didn't quickly find a solution for 
 referencing the symbol in the .data.rel.ro section (LLVM asm, 
 e.g., `void* getInit() { return __asm!(void*)("movq 
 test.C.__init, %rax", "={rax}"); }` doesn't work either).

 The compiler could emit the init symbol as regular global for 
 `-betterC` though.

 ---

 This issue could also be tackled in the D ctor of the 
 extern(C++) class, by injecting the blit before the actual ctor 
 body. C++ code wouldn't have to take care about that D-interop 
 incompatibility anymore (independent of -betterC).
I looked into that approach a little and it was pretty successful, at least for DMD: https://run.dlang.io/is/KDHoI9 LDC complains about the type of initializer though: onlineapp.d(22): Error: Global variable type does not match previous declaration with same mangled name: _D5bclib3Baz6__initZ onlineapp.d(22): Previous IR type: %bclib.Baz = type { [1 x i8*]*, i32 } onlineapp.d(22): New IR type: %bclib.BazInitializer = type { [1 x i8*]*, i32, [4 x i8] } Any ideas on how to match the type exactly? I don't quite understand why there are 4 bytes at the back of BazInitializer.
Aug 01 2018
parent reply kinke <kinke libero.it> writes:
On Thursday, 2 August 2018 at 02:52:44 UTC, Hakan Aras wrote:
 LDC complains about the type of initializer though:

 onlineapp.d(22): Error: Global variable type does not match 
 previous declaration with same mangled name: 
 _D5bclib3Baz6__initZ
 onlineapp.d(22):        Previous IR type: %bclib.Baz = type { 
 [1 x i8*]*, i32 }
 onlineapp.d(22):        New IR type:      %bclib.BazInitializer 
 = type { [1 x i8*]*, i32, [4 x i8] }


 Any ideas on how to match the type exactly? I don't quite 
 understand why there are 4 bytes at the back of BazInitializer.
Those 4 bytes for the struct is trailing padding, so that the struct is 16 bytes large, a multiple of its 8-bytes alignment (due to the pointer). Classes on the other hand aren't padded (they don't need to be, as there are no contiguous arrays of class instances, just class references). In this case, you could use `align(1) struct BazInitializer` to prevent the struct tail padding.
Aug 02 2018
parent Hakan Aras <hakan.aras live.at> writes:
On Thursday, 2 August 2018 at 10:54:17 UTC, kinke wrote:

 Those 4 bytes for the struct is trailing padding, so that the 
 struct is 16 bytes large, a multiple of its 8-bytes alignment 
 (due to the pointer). Classes on the other hand aren't padded 
 (they don't need to be, as there are no contiguous arrays of 
 class instances, just class references).
 In this case, you could use `align(1) struct BazInitializer` to 
 prevent the struct tail padding.
Oh yeah, forgot about alignment. It's no use though. Unless I can get my hands on the internal "struct" type of Baz somehow, LDC is not gonna let me declare it: https://github.com/ldc-developers/ldc/blob/69104bdbf94713431cbc67151c1b34a6a5e0df34/gen/llvmhelpers.cpp#L1759
Aug 02 2018
prev sibling parent reply Mike Franklin <slavo5150 yahoo.com> writes:
On Monday, 30 July 2018 at 22:40:21 UTC, Hakan Aras wrote:

 I'm trying to use extern(C++) classes with -betterC and I would 
 like to initialize their members properly.
I would also like to be able to use `extern(C++)` classes without the runtime, but I haven't been able to allocate any time to it yet. If you're trying to use `extern(C++)` classes with betterC, and the compiler is complaining about `TypeInfo` give me an example illustrating the problem, and I might be able to submit a fix to the compiler. Mike
Jul 30 2018
parent Hakan Aras <hakan.aras live.at> writes:
On Tuesday, 31 July 2018 at 03:42:15 UTC, Mike Franklin wrote:

 I would also like to be able to use `extern(C++)` classes 
 without the runtime, but I haven't been able to allocate any 
 time to it yet.

 If you're trying to use `extern(C++)` classes with betterC, and 
 the compiler is complaining about `TypeInfo` give me an example 
 illustrating the problem, and I might be able to submit a fix 
 to the compiler.

 Mike
It's working fine so far. Only problem is that the class needs to be compiletime constructible to get the initializer.
Jul 31 2018