Re: alloca without runtime?

2017-05-10 Thread via Digitalmars-d-learn

On Wednesday, 10 May 2017 at 20:25:45 UTC, aberba wrote:

On Thursday, 4 May 2017 at 14:54:58 UTC, 岩倉 澪 wrote:

On Thursday, 4 May 2017 at 12:50:02 UTC, Kagamin wrote:

You can try ldc and llvm intrinsics
http://llvm.org/docs/LangRef.html#alloca-instruction
http://llvm.org/docs/LangRef.html#llvm-stacksave-intrinsic


Ah, yep!

pragma(LDC_alloca) void* alloca(size_t);

This appears to work with ldc. It would be nice if there was a 
way to do this with dmd/other compilers as well though. If it 
were up to me I'd have alloca defined by the language standard 
and every compiler would have to provide an implementation 
like this. At the very least I'd like to have an alloca that 
works with dmd, as I want to do debug builds with dmd and 
release builds with ldc.


embedded platform?


An embedded platform would be a good use-case for this, but I'm 
just trying to do this on Linux x86_64 personally. It's a fun 
experiment to see how far I can push D to give me low-level 
control without dependencies


Re: alloca without runtime?

2017-05-04 Thread via Digitalmars-d-learn

On Thursday, 4 May 2017 at 12:50:02 UTC, Kagamin wrote:

You can try ldc and llvm intrinsics
http://llvm.org/docs/LangRef.html#alloca-instruction
http://llvm.org/docs/LangRef.html#llvm-stacksave-intrinsic


Ah, yep!

pragma(LDC_alloca) void* alloca(size_t);

This appears to work with ldc. It would be nice if there was a 
way to do this with dmd/other compilers as well though. If it 
were up to me I'd have alloca defined by the language standard 
and every compiler would have to provide an implementation like 
this. At the very least I'd like to have an alloca that works 
with dmd, as I want to do debug builds with dmd and release 
builds with ldc.


Re: alloca without runtime?

2017-05-04 Thread via Digitalmars-d-learn

On Sunday, 30 April 2017 at 05:07:31 UTC, 岩倉 澪 wrote:
I've been playing around with using D with no runtime on Linux, 
but recently I was thinking it would be nice to have an alloca 
implementation. I was thinking I could just bump the stack 
pointer (with alignment considerations) but from what I 
understand compilers sometimes generate code that references 
variables relative to RSP instead of RBP? I've seen people 
saying that a proper alloca can't be implemented without help 
from the compiler...


I took a peek in druntime and found rt.alloca which has 
__alloca implemented with inline asm. I tried throwing that in 
my project and calling it but it segfaults on rep movsq. The 
comments in the code suggest it is trying to copy temps on the 
stack but I seem to get a really large garbage RCX, I don't 
fully follow what is going on yet.


Is there any way I can get a working alloca without using 
druntime, c runtime, etc?


As a follow-up, here is a simple example of what I mean:

first, let's create a main.d, we'll define our own entry point 
and make a call to alloca in main:


extern (C):
void _start()
{
asm nothrow @nogc
{
naked;
xor RBP, RBP;
pop RDI;
mov RSI, RSP;
and RSP, -16;
call main;
mov RDI, RAX;
mov RAX, 60;
syscall;
ret;
}
}
pragma(startaddress, _start);
int main(int argc, char** argv)
{
import rt.alloca;
void* a = __alloca(42);
return 0;
}

Next, let's make an rt directory and copy the source of 
druntime's rt.alloca into rt/alloca.d


Now let's compile these:

dmd -betterC -debuglib= -defaultlib= -boundscheck=off -vgc -vtls 
-c -gc main.d rt/alloca.d


Great, now we need to strip symbols out to make this work, like 
so:


objcopy -R '.data.*[0-9]TypeInfo_*' -R '.[cd]tors.*' -R .eh_frame 
-R minfo -R .group.d_dso -R .data.d_dso_rec -R .text.d_dso_init 
-R .dtors.d_dso_dtor -R .ctors.d_dso_ctor -N __start_minfo -N 
__stop_minfo main.o
objcopy -R '.data.*[0-9]TypeInfo_*' -R '.[cd]tors.*' -R .eh_frame 
-R minfo -R .group.d_dso -R .data.d_dso_rec -R .text.d_dso_init 
-R .dtors.d_dso_dtor -R .ctors.d_dso_ctor -N __start_minfo -N 
__stop_minfo alloca.o


With that out of the way, we are ready to link:

ld main.o alloca.o

And when we try to run ./a.out we get a segfault.

What I want is a way to allocate on the stack (size of allocation 
not necessarily known at compile-time) and for the compiler to be 
aware that it can't generate code that refers to variables on the 
stack relative to rsp, or anything else that might break the 
naive implementation of alloca as simply bumping rsp with inline 
asm. Apparently this "magic" __alloca can't be used outside of 
the compiler, or is there a way to make it work?


alloca without runtime?

2017-04-29 Thread via Digitalmars-d-learn
I've been playing around with using D with no runtime on Linux, 
but recently I was thinking it would be nice to have an alloca 
implementation. I was thinking I could just bump the stack 
pointer (with alignment considerations) but from what I 
understand compilers sometimes generate code that references 
variables relative to RSP instead of RBP? I've seen people saying 
that a proper alloca can't be implemented without help from the 
compiler...


I took a peek in druntime and found rt.alloca which has __alloca 
implemented with inline asm. I tried throwing that in my project 
and calling it but it segfaults on rep movsq. The comments in the 
code suggest it is trying to copy temps on the stack but I seem 
to get a really large garbage RCX, I don't fully follow what is 
going on yet.


Is there any way I can get a working alloca without using 
druntime, c runtime, etc?


Re: The Mystery of the Misbehaved Malloc

2016-07-29 Thread via Digitalmars-d-learn

On Saturday, 30 July 2016 at 05:21:26 UTC, ag0aep6g wrote:

On 07/30/2016 07:00 AM, 岩倉 澪 wrote:

auto mem = malloc(2^^31);


2^^31 is negative. 2^^31-1 is the maximum positive value of an 
int, so 2^^31 wraps around to int.min.


Try 2u^^31.


bah, I'm an idiot! CASE CLOSED. Thanks for the help :P


The Mystery of the Misbehaved Malloc

2016-07-29 Thread via Digitalmars-d-learn
So I ran into a problem earlier - trying to allocate 2GB or more 
on Windows would fail even if there was enough room. Mentioned it 
in the D irc channel and a few fine folks pointed out that 
Windows only allows 2GB for 32-bit applications unless you pass a 
special flag which may or may not be a good idea.


I think to myself, "Easy solution, I'll just compile as 64-bit!"

But alas, my 64-bit executable suffers the same problem.

I boiled it down to a simple test:

void main()
{
import core.stdc.stdlib : malloc;
auto mem = malloc(2^^31);
assert(mem);
import core.stdc.stdio : getchar;
getchar();
}

I wrote this test with the C functions so that I can do a direct 
comparison with a C program compiled with VS 2015:


#include 
#include 
#include 
#include 
int main(int argc, char *argv[])
{
void *ptr = malloc((size_t)pow(2, 31));
assert(ptr);
getchar();
return 0;
}

I compile the D test with: `ldc2 -m64 -test.d`
I compile the C test with: `CL test.c`

`file` reports "PE32+ executable (console) x86-64, for MS 
Windows" for both executables.


When the C executable runs, I see the allocation under "commit 
change" in the Resource Monitor. When the D executable runs, the 
assertion fails!


The D program is able to allocate up to 2^31 - 1 before failing. 
And yes, I do have enough available memory to make a larger 
allocation.


Can you help me solve this mystery?


Re: Create Windows "shortcut" (.lnk) with D?

2016-03-06 Thread via Digitalmars-d-learn

On Sunday, 6 March 2016 at 11:00:35 UTC, John wrote:

On Sunday, 6 March 2016 at 03:13:23 UTC, 岩倉 澪 wrote:

IShellLinkA* shellLink;
IPersistFile* linkFile;

Any help would be highly appreciated as I'm new to Windows 
programming in D and have no idea what I'm doing wrong!


In D, interfaces are references, so it should be:

  IShellLinkA shellLink;
  IPersistFile linkFile;


That's exactly what the problem was, thank you!!


Re: Create Windows "shortcut" (.lnk) with D?

2016-03-05 Thread via Digitalmars-d-learn

On Sunday, 6 March 2016 at 05:00:55 UTC, BBasile wrote:
If you don't want to mess with the Windows API then you can 
dynamically create a script (I do this in CE installer):


This might be an option but I'd prefer to use the Windows API 
directly. I don't know vb script and maintaining such a script 
inline would just add cognitive overhead I think.


If I can't get it working with the Windows API; I'll probably 
have to do it this way though. Thanks for the suggestion!





Create Windows "shortcut" (.lnk) with D?

2016-03-05 Thread via Digitalmars-d-learn
I'm creating a small installation script in D, but I've been 
having trouble getting shortcut creation to work! I'm a linux 
guy, so I don't know much about Windows programming...


Here are the relevant bits of code I have:

import core.sys.windows.basetyps, core.sys.windows.com, 
core.sys.windows.objbase, core.sys.windows.objidl, 
core.sys.windows.shlobj, core.sys.windows.windef;
import std.conv, std.exception, std.file, std.format, std.path, 
std.stdio, std.string, std.utf, std.zip;


//Couldn't find these in core.sys.windows
extern(C) const GUID CLSID_ShellLink = {0x00021401, 0x, 
0x,

  [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};

extern(C) const IID IID_IShellLinkA  = {0x000214EE, 0x, 
0x,

  [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};

extern(C) const IID IID_IPersistFile = {0x010B, 0x, 
0x,

  [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};

void main()
{
string programFolder, dataFolder, desktopFolder;
{
char[MAX_PATH] _programFolder, _dataFolder, 
_desktopFolder;
SHGetFolderPathA(null, CSIDL_PROGRAM_FILESX86, null, 0, 
_programFolder.ptr);
SHGetFolderPathA(null, CSIDL_LOCAL_APPDATA, null, 0, 
_dataFolder.ptr);
SHGetFolderPathA(null, CSIDL_DESKTOPDIRECTORY, null, 0, 
_desktopFolder.ptr);
programFolder = 
_programFolder.assumeUnique().ptr.fromStringz();

dataFolder = _dataFolder.assumeUnique().ptr.fromStringz();
desktopFolder = 
_desktopFolder.assumeUnique().ptr.fromStringz();

}
auto inputFolder = buildNormalizedPath(dataFolder, 
"Aker/agtoolbox/input");
auto outputFolder = buildNormalizedPath(dataFolder, 
"Aker/agtoolbox/output");

CoInitialize(null);
scope(exit)
CoUninitialize();
IShellLinkA* shellLink;
IPersistFile* linkFile;
CoCreateInstance(_ShellLink, null, 
CLSCTX_INPROC_SERVER, _IShellLinkA, cast(void**));
auto exePath = buildNormalizedPath(programFolder, 
"Aker/agtoolbox/agtoolbox.exe").toStringz();

shellLink.SetPath(exePath);
auto arguments = format("-i %s -o %s", inputFolder, 
outputFolder).toStringz();

shellLink.SetArguments(arguments);
auto workingDirectory = programFolder.toStringz();
shellLink.SetWorkingDirectory(workingDirectory);
shellLink.QueryInterface(_IPersistFile, 
cast(void**));
auto linkPath = buildNormalizedPath(desktopFolder, 
"agtoolbox.lnk").toUTF16z();

linkFile.Save(linkPath, TRUE);
}

I tried sprinkling it with print statements and it crashes on 
shellLink.setPath(exePath);


This is the full script: 
https://gist.github.com/miotatsu/1cc55fe29d8a8dcccab5
I found the values for the missing windows api bits from this: 
http://www.dsource.org/projects/tutorials/wiki/CreateLinkUsingCom


I compile with: dmd agtoolbox-installer.d ole32.lib
I got the ole32.lib from the dmd install

Any help would be highly appreciated as I'm new to Windows 
programming in D and have no idea what I'm doing wrong!