Re: New LDC feature: dynamic compilation
On Monday, 13 November 2017 at 19:04:16 UTC, Ivan Butygin wrote: You need to explicitly compile `@dynamicCompile` functions before using any of them. Interesting feature. So is the executable linked to an installed instance of LDC/LLVM to make this happen, or is there some limited compiler embedded in the executable or Druntime? More details about the implementation please. Mike
Re: D as a Better C
On Wednesday, 30 August 2017 at 00:29:19 UTC, Parke wrote: But my original question was about what you (Kagamin) called "intermediate D". I was trying to understand what "intermediate D" is, and whether or not I could use "intermediate D" (whatever it is) to produce small(er) executables. "Intermediate D" probably refers to not use the -betterC switch, not linking in the official druntime, and instead implementing the features of D required by your program yourself. For example, the following is the most minimal "Hello World" I can make with D that does not require the -betterC switch, and does not use the official D runtime. Instead the runtime features required by this program are implemented in object.d. object.d module object; alias immutable(char)[] string; struct ModuleInfo { } class Object { } class TypeInfo { bool equals(in void* p1, in void* p2) const { return p1 == p2; } int compare(in void* p1, in void* p2) const { return _xopCmp(p1, p2); } } class TypeInfo_Class : TypeInfo { ubyte[136] ignore; } alias TypeInfo_Class ClassInfo; class TypeInfo_Struct : TypeInfo { ubyte[120] ignore; } extern (C) Object _d_newclass(const ClassInfo ci) { return null; } extern(C) void _d_throwc(Object h) { } class Throwable { } class Error : Throwable { this(string x) { } } extern(C) void _d_throwdwarf(Throwable o) { } extern(C) void _d_dso_registry(void* data) { } // The following code basically replaces the C runtime // extern extern(C) int main(int argc, char** argv); extern(C) void sys_exit(long arg1) { asm { mov RAX, 60; mov RDI, arg1; syscall; } } extern(C) void _start() { auto ret = main(0, null); sys_exit(ret); } private alias extern(C) int function(char[][] args) MainFunc; extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc) { // ignore args for now return mainFunc(null); } main.d -- module main; long sys_write(long arg1, in void* arg2, long arg3) { long result; asm { mov RAX, 1; mov RDI, arg1; mov RSI, arg2; mov RDX, arg3; syscall; } return result; } void write(in string text) { sys_write(2, text.ptr, text.length); } void main() { write("Hello\n"); } Building and executing -- On Linux 64-bit compile with: $ dmd -c -fPIC -release object.d main.d -of=main.o Link with: $ ld main.o -o main Report size: $ size main textdata bss dec hex filename 10701872 82950 b86 main Text execution: $ ./main Hello If you link with: $ ld main.o -o main --gc-sections You end up with: $ size main textdata bss dec hex filename 9501688 02638 a4e main This illustration does not require -betterC, but instead requires you to implement a "minimal D runtime" specific to your program, and the features of D that it employs. In this illustration that "minimal D runtime" is object.d. As you can see it is not a polished experience and gets much worse when you start employing more features of D. This could be improved, and in fact, with GDC you need even less useless boilerplate in object.d and may end up with an even smaller executable. (Maybe I'll follow up later with GDC illustration. Right now I don't have a computer with the latest GDC installed). If you try this experiment with LDC, you may end up with a multi-gigabyte file and crash your PC due to https://github.com/ldc-developers/ldc/issues/781 Hopefully we can improve the compiler/runtime implementation so doing this kind of programming won't require so many useless stubs, and users can implement just the features of D that they need for their program without having to rely on the on the blunt and heavy hand of -betterC. Mike
Re: D as a Better C
On Friday, 25 August 2017 at 23:13:53 UTC, Mengu wrote: On Friday, 25 August 2017 at 00:24:14 UTC, Michael V. Franklin wrote: On Thursday, 24 August 2017 at 19:21:31 UTC, Walter Bright wrote: [...] Great! I look forward to seeing improvements and hope to help. [...] i believe that should be an opt-out. what about newcomers? will they have to learn how to link std lib? No, because the dmd.conf that is delivered with the toolchain is already ready to go with reasonable defaults; and not hard-coded into the compiler. Advanced users can update dmd.conf or point the compiler to a different dmd.conf as they choose. Mike
Re: D as a Better C
On Thursday, 24 August 2017 at 19:21:31 UTC, Walter Bright wrote: On 8/24/2017 11:56 AM, Walter Bright wrote: I find -betterC to be somewhat of a copout for avoiding the hard work of improving D's implementation. On the contrary, I view it as providing motivation for dealing with those issues. The PR above is stalled for lack of motivation. -betterC also brings into sharp focus exactly what the issues are. Great! I look forward to seeing improvements and hope to help. Allow me to point out a recent pull request that should have resulted in an improvement in the full-featured D implementation rather than the -betterC implementation. https://github.com/dlang/dmd/pull/6918 DMD should never link in Phobos or druntime automatically. Rather, I think such dependencies should be specified on a platform-by-platform basis using a dmd.conf, linker script, or some other configuration file that is distributed with the toolchain's package. This puts the power in the hands of the user to avoid linking in Phobos and druntime without having to use the -betterC switch which is especially useful if the user is providing their own minimal runtime implementation to support features of D that are excluded with the heavy hand of -betterC. Mike
Re: D as a Better C
On Thursday, 24 August 2017 at 18:26:37 UTC, H. S. Teoh wrote: For instance, a D project targeting STM board, makes heavy use of classes and templates, resultant code segment is 3k. https://github.com/JinShil/stm32f42_discovery_demo#the-good To be fair, though, the above-mentioned project did have to create a stub druntime in order to get things to work. Not everyone may have the know-how required to construct a minimal druntime that works for their purposes. Those runtime stubs are needed precisely because of problems in D's implementation. If the implementation were fixed, none of those stubs would be required, and neither would the -betterC switch. Because the project above is not using any feature provided by those runtime stubs, those stubs should not be required, and neither should the -betterC switch. GDC has made some improvements here, and that is why the project above only compiles with GDC. LDC doesn't even display an error message when those stubs aren't created. Instead it enters a codegen loop generating a gargantuan multi-gigabyte file, ultimately crashing my VM (https://github.com/ldc-developers/ldc/issues/781). Sometimes, however, it is not known whether a runtime feature will be needed until link-time. In that case, it's OK for the compiler to emit TypeInfo, ModuleInfo, etc..., but it should do so in a way that the linker (with either LTO or --gc-sections) can determine what is needed and what isn't and discard that which isn't needed. Once unneeded object code is discarded, the linker errors disappear, and you get a functioning executable without linking in the runtime and without a -betterC switch. GDC recently implemented such an improvement (https://github.com/D-Programming-GDC/GDC/pull/505). It brought my binary size from 600kB to 6KB, so now I can get back to microcontroller programming in D. This is the kind of work that's needed. Mike
Re: D as a Better C
On Wednesday, 23 August 2017 at 17:44:31 UTC, Jonathan M Davis wrote: I confess that I tend to think of betterC as a waste of time. Clearly, there are folks who find it useful, but it loses so much that I see no point in using it for anything unless I have no choice. As long as attempts to improve it don't negatively impact normal D, then I don't really care what happens with it, but it's clearly not for me. And it _is_ possible to use full-featured D from C/C++ when D does not control main. It's just more of a pain. I'm somewhat in agreement here. I wouldn't call it a "waste of time", but I would prefer refactoring D's implementation to make using full-featured D from C/C++ less of a pain. I fear, however, that -betterC will be the favored excuse for not pursuing or prioritizing such improvements. Consider this: Rust doesn't need a special switch to make it interoperable with C. What's wrong with D's implementation that requires such things? Granted, D is not Rust, but D's implementation could be improved to make it more competitive with Rust in these use cases. For example, there is really no need for TypeInfo if you're not doing any dynanmic casts, but the current implementation generates it regardless. I find -betterC to be somewhat of a copout for avoiding the hard work of improving D's implementation. Mike