digitalmars.D - minimal object.d implementation that allows classes
- =?UTF-8?B?THXDrXM=?= Marques (3/3) Dec 06 2017 Is there a small druntime/object.d implementation that allows
- Eugene Wissner (2/5) Dec 06 2017 http://arsdnet.net/dcode/minimal.zip ?
- =?UTF-8?B?THXDrXM=?= Marques (5/6) Dec 06 2017 I tried that one, but I was having trouble getting it to work (it
- Adam D. Ruppe (20/26) Dec 07 2017 Yeah, minimal.zip is getting a bit old, but most the changes
- Timo Sintonen (8/11) Dec 06 2017 https://bitbucket.org/timosi/minlibd
- Wild (10/13) Dec 07 2017 You could modify the one I use for PowerNex[1]. It is a hacked
- =?UTF-8?B?THXDrXM=?= Marques (12/16) Dec 07 2017 This one seems to be the one for me. For instance,
- Jean-Louis Leroy (23/39) Dec 07 2017 I am currently trying to understand how the compiler and the
- Steven Schveighoffer (14/59) Dec 07 2017 The object is constructed here:
- Jean-Louis Leroy (6/9) Dec 07 2017 Thanks for the pointers, you've saved me a lot of time :)
- Jean-Louis Leroy (24/34) Dec 07 2017 Cool:
- Steven Schveighoffer (3/4) Dec 07 2017 This is a buffer overflow, why are you doing this specifically?
- Jean-Louis Leroy (5/10) Dec 07 2017 It's not an overflow because of the call to `reserve`. It is part
- Steven Schveighoffer (5/17) Dec 07 2017 Ah, ok.
- Jacob Carlborg (4/7) Dec 08 2017 Modifying the vtable can be useful for mocking and stubbing methods as w...
- Jean-Louis Leroy (3/10) Dec 08 2017 Indeed. The initial vtable is in read only memory, but the
- Mike Franklin (10/13) Dec 07 2017 I can get away with just this
Is there a small druntime/object.d implementation that allows basic support for classes, without bringing the whole druntime implementation with it?
Dec 06 2017
On Wednesday, 6 December 2017 at 17:17:40 UTC, Luís Marques wrote:Is there a small druntime/object.d implementation that allows basic support for classes, without bringing the whole druntime implementation with it?http://arsdnet.net/dcode/minimal.zip ?
Dec 06 2017
On Wednesday, 6 December 2017 at 17:52:16 UTC, Eugene Wissner wrote:http://arsdnet.net/dcode/minimal.zip ?I tried that one, but I was having trouble getting it to work (it seems to have bit rotten), and it does much more than I need, which probably is adding to the work to fix it.
Dec 06 2017
On Wednesday, 6 December 2017 at 18:32:11 UTC, Luís Marques wrote:On Wednesday, 6 December 2017 at 17:52:16 UTC, Eugene Wissner wrote:Yeah, minimal.zip is getting a bit old, but most the changes should be fairly small - adjusting sizes mainly. I just haven't done that for a year or two. The basic process is compile and link, if something doesn't work, copy/paste enough in to make the error go away. Sizes can be gotten from real druntime with __traits(classInstanceSize) and such, then you put in a dummy buffer to pad to it (remembering the vptr and monitor already get tou part of the way there). minimal.zip does a bit more than the bare minimum, but polymorphic classes DO require a fair chunk of code - various typeinfo and cast functions, some kind of memory function - and some of that code requires other code like struct typeinfo too (ugh, but the compiler insists). minimal.zip also includes exceptions and some startup stuff but that's mostly just because such were easy after polymorphism worked so I did because I can. Of course, if targetting webassembly, you can prolly cut all that out and rely on the javascript plumbing instead (i think). Certainly the asm functions will need to be cut there.http://arsdnet.net/dcode/minimal.zip ?I tried that one, but I was having trouble getting it to work (it seems to have bit rotten), and it does much more than I need, which probably is adding to the work to fix it.
Dec 07 2017
On Wednesday, 6 December 2017 at 17:17:40 UTC, Luís Marques wrote:Is there a small druntime/object.d implementation that allows basic support for classes, without bringing the whole druntime implementation with it?https://bitbucket.org/timosi/minlibd This is mainly targeted to microcontrollers which do not have any operating system. If this is not suitable for you, at least there are lists of needed files and required changes. It might be possible to reduce this further but I have not yet had need for that. Feel free to ask more info if you are interested.
Dec 06 2017
On Wednesday, 6 December 2017 at 17:17:40 UTC, Luís Marques wrote:Is there a small druntime/object.d implementation that allows basic support for classes, without bringing the whole druntime implementation with it?You could modify the one I use for PowerNex[1]. It is a hacked version of Adam D. Ruppes minimal.zip. There are only a few imports for strlen, mem{set,move,cpy}, etc. You probably need to add some sort of entrypoint and maybe implement a few more runtime functions. - Dan [1] https://github.com/PowerNex/PowerNex/blob/master/loader/src/object.d
Dec 07 2017
On Thursday, 7 December 2017 at 08:59:08 UTC, Wild wrote:You could modify the one I use for PowerNex[1]. It is a hacked version of Adam D. Ruppes minimal.zip. There are only a few imports for strlen, mem{set,move,cpy}, etc.This one seems to be the one for me. For instance, typeid(ClassName) seems to work, which I need. For completeness, I had looked into minlibd but it didn't seemed compatible with LDC and difficult for me to fix, IIRC. Regarding Mike's question of what my use case is, I wanted my program to run in webassembly/asmjs. Since druntime/phobos haven't been ported to that target, I was being careful with my design to not depend on the runtime, but then I found out I love the openmethods package. So I decided to check if I could implement just enough of druntime to allow a forked version of openmethods to work. As far as I can tell that's feasible.
Dec 07 2017
On Thursday, 7 December 2017 at 13:08:09 UTC, Luís Marques wrote:On Thursday, 7 December 2017 at 08:59:08 UTC, Wild wrote:I am currently trying to understand how the compiler and the runtime interact. ClassInfo contains a vtbl array whose ptr property is the same as the vptr found in an instance of that class. However, when I modify that pointer (e.g. by reserving 1000 more entries) and create a new instance, it still contains the old pointer. So it looks like the compiler sets the vptr without consulting the ClassInfo but somehow reflects it there. I'd appreciate if anybody can explain how it works, or sends me links to relevant info. Example: import std.stdio; class Foo { void foo() {} } void main() { auto oldPtr = Foo.classinfo.vtbl.ptr; Foo.classinfo.vtbl.reserve(1000); writeln(oldPtr != Foo.classinfo.vtbl.ptr); // true Object foo = new Foo(); writeln(oldPtr == *cast(void***)foo); // true, alas } ...at least that's what I get with dmd.You could modify the one I use for PowerNex[1]. It is a hacked version of Adam D. Ruppes minimal.zip. There are only a few imports for strlen, mem{set,move,cpy}, etc.This one seems to be the one for me. For instance, typeid(ClassName) seems to work, which I need. For completeness, I had looked into minlibd but it didn't seemed compatible with LDC and difficult for me to fix, IIRC. Regarding Mike's question of what my use case is, I wanted my program to run in webassembly/asmjs. Since druntime/phobos haven't been ported to that target, I was being careful with my design to not depend on the runtime, but then I found out I love the openmethods package. So I decided to check if I could implement just enough of druntime to allow a forked version of openmethods to work. As far as I can tell that's feasible.
Dec 07 2017
On 12/7/17 9:45 AM, Jean-Louis Leroy wrote:On Thursday, 7 December 2017 at 13:08:09 UTC, Luís Marques wrote:The object is constructed here: https://github.com/dlang/druntime/blob/master/src/rt/lifetime.d#L71 specifically, the vtbl is set when you blit the initializer array (another piece of the TypeInfo) into the class object here: https://github.com/dlang/druntime/blob/master/src/rt/lifetime.d#L115 So basically, the reason why it happens is because the pointer you are changing is not the piece that actually is used to intialize the block. On a side note however, you really shouldn't change data in a ClassInfo at all, and probably the compiler shouldn't let you! This is static readonly data, and changing this is I think even disallowed on some OSes. Relevant source of how vtbls in D work: https://dlang.org/spec/abi.html#classes -SteveOn Thursday, 7 December 2017 at 08:59:08 UTC, Wild wrote:I am currently trying to understand how the compiler and the runtime interact. ClassInfo contains a vtbl array whose ptr property is the same as the vptr found in an instance of that class. However, when I modify that pointer (e.g. by reserving 1000 more entries) and create a new instance, it still contains the old pointer. So it looks like the compiler sets the vptr without consulting the ClassInfo but somehow reflects it there. I'd appreciate if anybody can explain how it works, or sends me links to relevant info. Example: import std.stdio; class Foo { void foo() {} } void main() { auto oldPtr = Foo.classinfo.vtbl.ptr; Foo.classinfo.vtbl.reserve(1000); writeln(oldPtr != Foo.classinfo.vtbl.ptr); // true Object foo = new Foo(); writeln(oldPtr == *cast(void***)foo); // true, alas }You could modify the one I use for PowerNex[1]. It is a hacked version of Adam D. Ruppes minimal.zip. There are only a few imports for strlen, mem{set,move,cpy}, etc.This one seems to be the one for me. For instance, typeid(ClassName) seems to work, which I need. For completeness, I had looked into minlibd but it didn't seemed compatible with LDC and difficult for me to fix, IIRC. Regarding Mike's question of what my use case is, I wanted my program to run in webassembly/asmjs. Since druntime/phobos haven't been ported to that target, I was being careful with my design to not depend on the runtime, but then I found out I love the openmethods package. So I decided to check if I could implement just enough of druntime to allow a forked version of openmethods to work. As far as I can tell that's feasible.
Dec 07 2017
On Thursday, 7 December 2017 at 14:59:57 UTC, Steven Schveighoffer wrote:The object is constructed here: [...]Thanks for the pointers, you've saved me a lot of time :)On a side note however, you really shouldn't change data in a ClassInfo at all, and probably the compiler shouldn't let you!This experiment is related to an ongoing discussion with Walter, Andrei and Ali on extending D with general mechanisms to better support libraries like openmethods. I will post in Studies soon.
Dec 07 2017
On Thursday, 7 December 2017 at 15:09:45 UTC, Jean-Louis Leroy wrote:On Thursday, 7 December 2017 at 14:59:57 UTC, Steven Schveighoffer wrote:Cool: import std.stdio; class Foo { abstract void report(); } class Bar : Foo { override void report() { writeln("I'm fine!"); } } void main() { auto oldPtr = Bar.classinfo.vtbl.ptr; Bar.classinfo.vtbl.reserve(1000); Bar.classinfo.vtbl.ptr[Bar.classinfo.vtbl.length] = cast(void*) 0x123456; writeln(oldPtr != Bar.classinfo.vtbl.ptr); // true *cast(void***) Bar.classinfo.m_init.ptr = Bar.classinfo.vtbl.ptr; Foo foo = new Bar(); writeln(oldPtr == *cast(void***)foo); // false foo.report(); // I'm fine! writeln((*cast(void***)foo)[Bar.classinfo.vtbl.length]); // 123456 }The object is constructed here: [...]Thanks for the pointers, you've saved me a lot of time :)On a side note however, you really shouldn't change data in a ClassInfo at all, and probably the compiler shouldn't let you!This experiment is related to an ongoing discussion with Walter, Andrei and Ali on extending D with general mechanisms to better support libraries like openmethods. I will post in Studies soon.
Dec 07 2017
On 12/7/17 10:21 AM, Jean-Louis Leroy wrote:Bar.classinfo.vtbl.ptr[Bar.classinfo.vtbl.length] = cast(void*) 0x123456;This is a buffer overflow, why are you doing this specifically? -Steve
Dec 07 2017
On Thursday, 7 December 2017 at 15:34:09 UTC, Steven Schveighoffer wrote:On 12/7/17 10:21 AM, Jean-Louis Leroy wrote:It's not an overflow because of the call to `reserve`. It is part of an experiment related to supporting user-defined per-class metadata by extending the vtable.Bar.classinfo.vtbl.ptr[Bar.classinfo.vtbl.length] = cast(void*) 0x123456;This is a buffer overflow, why are you doing this specifically? -Steve
Dec 07 2017
On 12/7/17 10:45 AM, Jean-Louis Leroy wrote:On Thursday, 7 December 2017 at 15:34:09 UTC, Steven Schveighoffer wrote:Ah, ok. Take care, I'm not sure that the classinfo instances are scanned by the GC. Might be better to use C malloc. -SteveOn 12/7/17 10:21 AM, Jean-Louis Leroy wrote:It's not an overflow because of the call to `reserve`. It is part of an experiment related to supporting user-defined per-class metadata by extending the vtable.Bar.classinfo.vtbl.ptr[Bar.classinfo.vtbl.length] = cast(void*) 0x123456;This is a buffer overflow, why are you doing this specifically? -Steve
Dec 07 2017
On 2017-12-07 16:09, Jean-Louis Leroy wrote:This experiment is related to an ongoing discussion with Walter, Andrei and Ali on extending D with general mechanisms to better support libraries like openmethods. I will post in Studies soon.Modifying the vtable can be useful for mocking and stubbing methods as well. -- /Jacob Carlborg
Dec 08 2017
On Friday, 8 December 2017 at 14:59:12 UTC, Jacob Carlborg wrote:On 2017-12-07 16:09, Jean-Louis Leroy wrote:Indeed. The initial vtable is in read only memory, but the re-allocated one is writeable.This experiment is related to an ongoing discussion with Walter, Andrei and Ali on extending D with general mechanisms to better support libraries like openmethods. I will post in Studies soon.Modifying the vtable can be useful for mocking and stubbing methods as well.
Dec 08 2017
On Wednesday, 6 December 2017 at 17:17:40 UTC, Luís Marques wrote:Is there a small druntime/object.d implementation that allows basic support for classes, without bringing the whole druntime implementation with it?I can get away with just this (https://github.com/JinShil/stm32f42_discovery_demo/blob/master/sour e/runtime/object.d) in GDC. It will likely cause LDC to crash (See https://github.com/ldc-developers/ldc/issues/781, https://github.com/ldc-developers/ldc/issues/552). I haven't tested it with DMD. But, I'm not really using classes in the typical way. Instead, I'm more-or-less using them as namespaces with static polymorphism. For an example, see https://github.com/JinShil/stm32f42_discovery_demo/blob/master/source/stm32f42/pwr.d What you need in object.d will likely depend on how you intend to use your classes. What's your use case? Mike
Dec 07 2017