Re: spurious gc allocation

2013-11-09 Thread lomereiter
Indeed, disassembly reveals an allocation (with all three 
compilers = it's the front-end which generates this crap).


I guess the compiler incorrectly treats { node.value; } as a 
delegate and copies the node to GC heap.


void foo() {
int* node = null;
enum mutable = __traits(compiles, {node.value ;});
}

void main() {
foo();
}


Get variable symbol name that was passed to a paramater?

2013-11-09 Thread Rob T
I have a template function called inspect that takes two 
variables as arguments,


void inspect(T)( string symbol, T value )
{
   writeln(symbol,  = , value);
}

int y = 100;

inspect( y.stringof, y );

writes to console

y = 100

I am wondering if there's a way to pass only the variable and 
have the inspect function determine the variable's symbol name as 
passed rather than have to pass both the name and value 
separately?


void inspect(T)( T value )
{
   writeln( ? ,  = , value);
}


I've tried a template with alias parameter

void inspect(alias value)()
{
   writeln( value.stringof ,  = , value);
}

It works except when passing a variable contained inside a struct 
or class due to a missing this during evaluation, I'm also 
worried about template bloat.


I figure mixins may help, but not if it's same or less convenient 
to use as the double entry method.


Any suggestions, or is it just impossible or not worth trying?

--rt


Re: spurious gc allocation

2013-11-09 Thread bearophile

Ellery Newcomer:


can anyone confirm?


I only see the class instance allocation in the main(). I use two 
modules, with your code. I compile on Windows 32, using no 
compilation flags, and I see this asm, with obj2asm:



_D1a1C13_InsertAllButMFiZv:
pushEAX
pushEAX
mov [ESP],0
add ESP,8
ret 4

__Dmain:
L0: mov EAX,offset FLAT:_D1a1C7__ClassZ
pushEAX
callnear ptr __d_newclass
push1
mov ECX,[EAX]
calldword ptr 014h[ECX]
xor EAX,EAX
add ESP,4
ret

_main:
L0: mov EAX,offset FLAT:__Dmain
pushEAX
pushdword ptr 0Ch[ESP]
pushdword ptr 0Ch[ESP]
callnear ptr __d_run_main
add ESP,0Ch
ret

Bye,
bearophile


Re: Get variable symbol name that was passed to a paramater?

2013-11-09 Thread Dicebot

On Saturday, 9 November 2013 at 09:12:21 UTC, Rob T wrote:
It works except when passing a variable contained inside a 
struct or class due to a missing this during evaluation, I'm 
also worried about template bloat.


I figure mixins may help, but not if it's same or less 
convenient to use as the double entry method.


Any suggestions, or is it just impossible or not worth trying?


I have not found good workaround for this so far and consider it 
a main use case for template alias parameter enhancement.


Re: spurious gc allocation

2013-11-09 Thread Ellery Newcomer

On 11/09/2013 12:35 AM, lomereiter wrote:

Indeed, disassembly reveals an allocation (with all three compilers =
it's the front-end which generates this crap).


ouch.



I guess the compiler incorrectly treats { node.value; } as a delegate
and copies the node to GC heap.

void foo() {
 int* node = null;
 enum mutable = __traits(compiles, {node.value ;});
}

void main() {
 foo();
}


oh, I see, it's the delegate doing that. that's helpful.


https://d.puremagic.com/issues/show_bug.cgi?id=11483


Re: Question about function templates when parameter is void

2013-11-09 Thread Gary Willoughby

On Saturday, 9 November 2013 at 07:11:50 UTC, Uranuz wrote:
I have a question. In my code I want to make uniform template 
function to call JSON RPC methods (that are regular D functions 
of any type). So I need some way to call this function with no 
function params and with them in the same manner. There is a 
concrete example, because this description isn't obvious (I 
think that)


//
import std.stdio, std.json, std.conv, std.traits;


JSONValue getStdJSON(T)(T dValue)
{
static if( is( T == void ) )
{   
JSONValue result;
result.type = JSON_Type.NULL;
return result;
}
else
{
//
}

}

void f()
{
writeln(Hello!!);   
}

void main()
{
writeln(getStdJSON(f()));
}
//--
Compilation output:
/d661/f210.d(28): Error: template f210.getStdJSON does not 
match any function template declaration. Candidates are:

/d661/f210.d(6):f210.getStdJSON(T)(T dValue)
/d661/f210.d(28): Error: template f210.getStdJSON(T)(T dValue) 
cannot deduce template function from argument types !()(void)


//---

So my question is how can I implement something like this? 
Problem is that we don't really have value of type void, but I 
want uniform way to call this function when it has parameter 
with concrete type and not.


It seems odd to call a function as an argument which returns 
void. Surely you could just move that out and call it alone 
before the 'getStdJSON' call?


Anyway to answer you question, i'd probably overload the 
'getStdJSON' function.


Re: VC linker - unresolved external symbols - runtime

2013-11-09 Thread evilrat

On Saturday, 9 November 2013 at 15:30:55 UTC, deed wrote:
core.runtime's import path is specified in the sc.ini file, in 
DFLAGS
If I specify the core.runtime file in the build file everything 
works


Why is it so?


in short - it looks like phobos.lib not linked, try link it 
manually. i don't know why...


Re: VC linker - unresolved external symbols - runtime

2013-11-09 Thread deed

On Saturday, 9 November 2013 at 16:08:15 UTC, evilrat wrote:

On Saturday, 9 November 2013 at 15:59:02 UTC, deed wrote:


No, it doesn't work. Do I have to compile my own runtime 
library and pass it on the command line? (Have just grabbed 
the 3.064.2.zip file and not run any installer.)


The readme file in the runtime directory says it's compiled 
into phobos64.lib, which I presume is passed successfully, 
otherwise there would have been more unresolved symbols..


better use installer, or you can try to set correct linker, 
mspdb dll, and lib paths in sc.ini for your visual c++ and 
windows sdk.


phobos64.lib contains
_D4core7runtime7Runtime10initializeFDFC6object9ThrowableZvZb
but not
_D4core7runtime7Runtime10initializeFZb

Does this mean that the phobos64.lib is not aligned with current 
core.runtime module?


Re: is there a merge for associative arrays

2013-11-09 Thread Daniel Davidson

On Tuesday, 5 November 2013 at 17:47:16 UTC, bearophile wrote:

TV[TK] mergeAAs(TK, TV)(TV[TK] aas...) {

It seems even fit for Phobos.

Bye,
bearophile


I have something I would appreciate feedback/criticism on. My 
first stab at it worked, but had no support for passing in 
const/immutable.


AA mergeAAs(alias fun = a + b, AA)(AA[] aas...) 
if(isAssociativeArray!AA) {

  AA result;
  ...
}

Not sure if this is a good way or if there are better idiomatic 
ways, but here is what I have got. Any suggestions/improvements 
to make it more idiomatic would be appreciated. Is there already 
a DeepUnqual equivalent in phobos?


Thanks
Dan

import std.stdio;
import std.traits;
import std.algorithm;
import std.functional;

template DeepUnqual(T) {
  static if(isAssociativeArray!T) {
alias Unqual!(Unqual!(ValueType!T)[Unqual!(KeyType!T)]) 
DeepUnqual;

  } else static if(isDynamicArray!T) {
alias Unqual!(Unqual!(ArrayElementType!T)[]) DeepUnqual;
  } else static if(isPointer!T) {
alias Unqual!(PointerTarget!T) * DeepUnqual;
  } else {
alias Unqual!T DeepUnqual;
  }
}

DeepUnqual!AA
mergeAAs(alias fun = a + b, AA)(AA[] aas...) 
if(isAssociativeArray!AA) {

  DeepUnqual!AA result;
  if(aas.length) {
foreach( aa ; aas ) {
  foreach( k , v ; aa ) {
auto found = k in result;
if(found) {
  *found = binaryFun!fun(*found, v);
} else {
  result[k] = v;
}
  }
}
  }
  return result;
}

void main() {
  alias double[string] AA;
  AA a = [ foo:1.1, bar:2.2 ];
  AA b = [ foo:1.1, bard:2.2 ];
  writeln(mergeAAs(a, b));
  writeln(mergeAAs!q{a*b}(a, b));

  {
const AA ca = a.dup;
const AA cb = b.dup;
writeln(mergeAAs(ca,cb));
  }

  {
immutable AA ia = [ foo:1.1, bar:2.2 ];
immutable AA ib = [ foo:1.1, bard:2.2 ];
writeln(mergeAAs(ia,ib));
  }
}


Re: VC linker - unresolved external symbols - runtime

2013-11-09 Thread evilrat

On Saturday, 9 November 2013 at 16:22:07 UTC, deed wrote:

phobos64.lib contains
_D4core7runtime7Runtime10initializeFDFC6object9ThrowableZvZb
but not
_D4core7runtime7Runtime10initializeFZb

Does this mean that the phobos64.lib is not aligned with 
current core.runtime module?


i also have this problem on win 8.1 with visual studio 2013.

smells like a bug for me. file a bug on tracker.

for now i think manually calling rt_init() and rt_term() can be 
used to avoid it.


Re: Get variable symbol name that was passed to a paramater?

2013-11-09 Thread Rob T

On Saturday, 9 November 2013 at 11:07:08 UTC, Dicebot wrote:

On Saturday, 9 November 2013 at 09:12:21 UTC, Rob T wrote:
It works except when passing a variable contained inside a 
struct or class due to a missing this during evaluation, I'm 
also worried about template bloat.


I figure mixins may help, but not if it's same or less 
convenient to use as the double entry method.


Any suggestions, or is it just impossible or not worth trying?


I have not found good workaround for this so far and consider 
it a main use case for template alias parameter enhancement.


Do you know if there's already a enhancement request posted for 
this? I'll make one if not.


Re: How to compile and test samples under Windows?

2013-11-09 Thread Adam D. Ruppe
This reminded me to come back to this (I was commenting on stack 
overflow a few days ago too). Spun up an XP box and now I can 
reproduce your problem.


Strangely, the same exe and dll work on Vista computer still! But 
at least I can see the problem on XP so maybe I can help figure 
this out now


Re: How to compile and test samples under Windows?

2013-11-09 Thread Adam D. Ruppe
Aaaand figured it out: actually, the fact it worked on Vista but 
not on XP was the key clue and I'm ashamed I didn't realize this 
earlier.


This comment hints at it too in dserver.d
// Multiple threads not supported yet


Anyway, D's thread local storage doesn't quite work right on 
Windows XP, and does work beautifully on Vista and up. I don't 
really know why, but that's the way it is. It can cause invalid 
memory accesses...


And the GUIDs and a couple other variables in the sample are 
thread local! (Back when the sample was written, global variables 
were truly global, like in C. Since then, that's changed, the 
variables are now in thread local storage unless you mark them 
with __gshared, which breaks things...)


So here's the fix: add __gshared to a few places.

dserver.d, line 119 give or take, there's some globals g_cObj etc:

__gshared ULONG g_cObj =0;
__gshared ULONG g_cLock=0;

__gshared HINSTANCE g_hInst;

chello.d, about line 24:


__gshared GUID CLSID_Hello = { 0x30421140, 0, 0, [0xC0, 0, 0, 0, 
0, 0, 0, 0x46] };
__gshared GUID IID_IHello  = { 0x00421140, 0, 0, [0xC0, 0, 0, 0, 
0, 0, 0, 0x46] };



(Actually, those could probably be immutable too, but meh just 
making it work.)



Then recompile, remembering the libraries we talked about on 
stack overflow, and you get a new dll. On my computer, it 
actually came out 100KB smaller too, cool!



Now, chello.exe runs and successfully creates the object.

regsvr32.exe still fails though, on XP (works on Vista), I must 
still be missing something. But this is a lot closer already


Re: How to compile and test samples under Windows?

2013-11-09 Thread Adam D. Ruppe

On Saturday, 9 November 2013 at 23:37:38 UTC, Adam D. Ruppe wrote:
regsvr32.exe still fails though, on XP (works on Vista), I must 
still be missing something. But this is a lot closer already


I fixed this by commenting out the call to gc_init in 
dserver.d's DllMain (thereabouts line 140). I don't know why it 
would work in dclient but not regsvr, maybe it has to do with 
threads again. Regardless though, comment that out and it 
registers.


S yeah that's kinda messed up that this stuff doesn't just 
work, but at least you can make it work now, hopefully.


let me know if it works on your computer too.


Re: Get variable symbol name that was passed to a paramater?

2013-11-09 Thread Timothee Cour
can your 'inspect' method handle:
* multiple arguments?
* expressions?

I wrote a function that does both, it's one of those things that are very
useful for quick debugging:

import util.prettyprint;
void main(){
  int x=23;
  double y=2.4;
  writelnL(x,y,x*y);
}

//output:
file test.d:7 {
  x=int{23},
  y=double{2.4},
  x*y=double{55.2},
}

-
The way it works:
void writelnL(string file=__FILE__, Line_t line=__LINE__, T...)(T args){
...
auto argNames=getArgNamesFromFile(file,line);
...
}

This reads at runtime file/line and caches the information with memoize to
avoid re-reading the same file/line multiple times. I had also tried
reading the file/line at compile time using import(file)[line] but that
resulted in massive compile time slow-downs even when the actual writelnL
wasn't used at runtime. Then the code parses the line to extract each
argument names using a simplified D grammar.

However this still has some runtime penalty (reading a whole file just for
1 line) and is doing more work than necessary, as compiler has access to
this info.
I've already asked for this in the past (see email: feature request:
__ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___):

but Jacob pointed out that AST macros would make this un-necessary (like
wise with another proposal I made proposal: a new string litteral to embed
variables in a string ):

I don't think that __ARGS__ is a bad idea, I just think that there are
several features in D which could be replaced with a library solution using
AST macros (if those were available)

So let's either get a roadmap for introducing AST macros (preferred) or
let's allow this very simple __ARGS__ in the language.



On Sat, Nov 9, 2013 at 11:05 AM, Rob T al...@ucora.com wrote:

 On Saturday, 9 November 2013 at 11:07:08 UTC, Dicebot wrote:

 On Saturday, 9 November 2013 at 09:12:21 UTC, Rob T wrote:

 It works except when passing a variable contained inside a struct or
 class due to a missing this during evaluation, I'm also worried about
 template bloat.

 I figure mixins may help, but not if it's same or less convenient to use
 as the double entry method.

 Any suggestions, or is it just impossible or not worth trying?


 I have not found good workaround for this so far and consider it a main
 use case for template alias parameter enhancement.


 Do you know if there's already a enhancement request posted for this? I'll
 make one if not.



Re: Get variable symbol name that was passed to a paramater?

2013-11-09 Thread Timon Gehr

On 11/09/2013 10:12 AM, Rob T wrote:


I am wondering if there's a way to pass only the variable and have the
inspect function determine the variable's symbol name as passed rather
than have to pass both the name and value separately?
...


Well, yes, but the following does not scale that well, and it is 
somewhat fragile, since there is no way to get column information.


import std.stdio;
import std.string;
import std.algorithm;
import std.range;
import std.conv;

template LineCache(string f){ enum LineCache = 
import(__FILE__).splitLines(); }


void inspect(string f=__FILE__,int l=__LINE__,T)( T value ){
enum 
name=LineCache!__FILE__[l-1].find(inspect).drop(inspect.length).find(().drop(1).until!(a=a==')').to!string.strip;

writeln(name ~  = , value);
}

void main(){
int a;
int b=3;
inspect(a);
inspect(a+2);
inspect(a+b);
}


$ dmd -J. -run tt.d
a = 0
a+2 = 2
a+b = 3



Re: Get variable symbol name that was passed to a paramater?

2013-11-09 Thread Timon Gehr

On 11/10/2013 01:51 AM, Timon Gehr wrote:

On 11/09/2013 10:12 AM, Rob T wrote:


I am wondering if there's a way to pass only the variable and have the
inspect function determine the variable's symbol name as passed rather
than have to pass both the name and value separately?
...


Well, yes, but the following does not scale that well, and it is
somewhat fragile, since there is no way to get column information.

import std.stdio;
import std.string;
import std.algorithm;
import std.range;
import std.conv;

template LineCache(string f){ enum LineCache =
import(__FILE__).splitLines(); }

void inspect(string f=__FILE__,int l=__LINE__,T)( T value ){
 enum
name=LineCache!__FILE__[l-1].find(inspect).drop(inspect.length).find(().drop(1).until!(a=a==')').to!string.strip;
...


Oops. There's a typo. It should read LineCache!f, obviously.


 writeln(name ~  = , value);
}

void main(){
 int a;
 int b=3;
 inspect(a);
 inspect(a+2);
 inspect(a+b);
}


$ dmd -J. -run tt.d
a = 0
a+2 = 2
a+b = 3





Shared data concurrency with SDL

2013-11-09 Thread Tim Reinke
Newbie here.  I'm playing around with concurrency in D.  Being 
new to both, I have no idea what I'm doing and am seeking your 
guidance!


I'm using the D SDL wrapper (which is just a thin wrapper around 
the C library).


I have the following threads:
  - the main program thread; the `control  coordination` thread
  - SDL_Mixer has its own thread (which calls a callback I 
provide)

  - a thread to handle graphics

Questions I'm seeking answers to:
1) I'm doing a lot of casting to/from shared which doesn't feel 
right.  What should be I doing?  Some of this seems unavoidable, 
as in the SDL callback postMixCallback() where I'm bound by the 
SDL_mixer library to provide a specific type signature.


2) A specific instance of 1). In my main(), I declare 
GraphicsState to

be unshared.  GraphicsState just holds on to a bunch of pointers
returned by SDL initialization routines (which won't work on 
shared
pointers).  Then, in order to communicate with the graphics 
thread via
send(), I cast the address of to a shared pointer.  On the other 
end,

I receive this shared pointer then cast to an unshared pointer and
dereference.  I do this because the pointer values in 
GraphicsState
are passed pretty much exclusively to C functions which won't 
accept

shared types.  Seems awkward, no?

My code (also at http://pastebin.com/SMC2e9Bx )

// Holds data the graphics thread needs
// This is initialized in the main
// thread then sent to the graphics thread
// Cleanup is done by the main thread after
// the graphics thread exits
struct GraphicsState {
  SDL_Window* window;
  SDL_Renderer* renderer;
  SDL_Texture* texture;
  ImageSurface cairoSurface;
  ubyte* pixels;
}

// a simple ring buffer
struct RingBuffer {
  ulong pos;
  short[] buffer;
}


void main()
{
  // ...
  GraphicsState graphicsState;
  gfxInit(graphicsState);

  shared RingBuffer ringBuffer;
  ringBuffer.pos = 0;
  ringBuffer.buffer.length = audioConf.sample_f * 
audioConf.chunkSize;


  Mix_SetPostMix(finished, cast(void*)ringBuffer);

  Tid tid = spawn(doGfx);
  shared GraphicsState* sharedGfx = cast(shared 
GraphicsState*)graphicsState;

  send(tid, sharedGfx, cast(shared(RingBuffer*))ringBuffer);
  // ...
}

extern(C) void postMixCallback(void* udata, ubyte *stream, int 
len)

{
  shared RingBuffer* buffer = cast(shared RingBuffer*)udata;
  short *samples = cast(short*)stream;

  // naive copy
  for (int i = 0; i  len / short.sizeof; i += 2)
  {
buffer.buffer[buffer.pos] = *(samples + i);
auto nextPos = buffer.pos + 1;
if (nextPos == buffer.buffer.length)
{
  nextPos = 0;
}
buffer.pos = nextPos;
  }
}

void doGfx(AudioConf audioConf)
{
  GraphicsState graphicsState;
  Mix_Chunk* beat;
  shared RingBuffer* ringBuffer;
  auto msg = receiveOnly!(shared(GraphicsState*), 
shared(RingBuffer*));


  graphicsState = *(cast(GraphicsState*)msg[0]);
  ringBuffer = msg[1];

  while (true) {
// read from ring buffer
// render
  }
}