Jump to page: 1 2
Thread overview
Several questions (about inline assembly, ddoc for templates, and foreach)
Aug 19, 2006
Marcio
Aug 19, 2006
Marcio
Aug 19, 2006
Thomas Kuehne
Aug 20, 2006
Sean Kelly
Aug 20, 2006
Thomas Kuehne
Aug 20, 2006
Sean Kelly
Aug 19, 2006
Marcio
Aug 19, 2006
Thomas Kuehne
Aug 19, 2006
Marcio
August 19, 2006
Hi all,

I have several questions I cannot find elsewhere:

1 - Using inline assembly, how can I access the "ptr" attribute of an array? For example:
void main() {
  int[] array;
  asm {
    mov EAX, array.ptr;
  }
}
The compiler says: "identifier expected".

2 - Is Ddoc working for templates? If it is, I can't make it generate the documentation for some template functions...

3 - Is there a way to manually increment the index of a foreach loop? I ask this because the index cannot be made inout, only the value.

Thanks,
August 19, 2006
Marcio wrote:
> Hi all,
> 
> I have several questions I cannot find elsewhere:
> 
> 1 - Using inline assembly, how can I access the "ptr" attribute of an array? For example:
> void main() {
>   int[] array;
>   asm {
>     mov EAX, array.ptr;
>   }
> }
> The compiler says: "identifier expected".

I'm not sure.  Of course, pending a real solution from someone who knows better, you could do this:

# void main () {
#   int[] array             ;
#   auto  ptr   = array.ptr ;
#
#   asm {
#     mov  EAX , ptr ;
#   }
# }

> 2 - Is Ddoc working for templates? If it is, I can't make it generate the documentation for some template functions...
> 
> 3 - Is there a way to manually increment the index of a foreach loop? I ask this because the index cannot be made inout,
> only the value.

Any reason why you can't make the index inout?  I've done it often enough myself to this very effect.  Of course, I'm sure its undefined behavior with associative arrays, but with fixed/variable-length arrays it works just fine.

# int[] arr = someBigFunction();
#
# /* skip any values preceded by 0 ... for some reason */
# foreach (inout i, inout x; arr) {
#   if (i == 0) {
#     i++;
#     continue;
#   }
#   /* do stuff with x */
# }

> Thanks,
August 19, 2006
Chris Nicholson-Sauls wrote:
> (...)
> I'm not sure.  Of course, pending a real solution from someone who knows better,
you could
> do this:
>
> # void main () {
> #   int[] array             ;
> #   auto  ptr   = array.ptr ;
> #
> #   asm {
> #     mov  EAX , ptr ;
> #   }
> # }

Yes, that's what I'm doing currently.

> > 3 - Is there a way to manually increment the index of a foreach loop? I ask
this because the index cannot be made inout,
> > only the value.
>
> Any reason why you can't make the index inout?  I've done it often enough myself
to this
> very effect.  Of course, I'm sure its undefined behavior with associative
arrays, but with
> fixed/variable-length arrays it works just fine.
>
> # int[] arr = someBigFunction();
> #
> # /* skip any values preceded by 0 ... for some reason */
> # foreach (inout i, inout x; arr) {
> #   if (i == 0) {
> #     i++;
> #     continue;
> #   }
> #   /* do stuff with x */
> # }

Are you sure that works?
I've just tested the following code with DMD v0.164 (in Linux):

void main()
{
  char[] arr = "test";

  foreach (inout i, inout c; arr) {
    if (i == 0) {
      i++;
      continue;
    }
  }
}

And the compiler says: "foreach: key cannot be out".
Did you use the last version?
August 19, 2006
Marcio schrieb am 2006-08-19:
> Chris Nicholson-Sauls wrote:
>> (...)
>> I'm not sure.  Of course, pending a real solution from someone who knows better,
> you could
>> do this:
>>
>> # void main () {
>> #   int[] array             ;
>> #   auto  ptr   = array.ptr ;
>> #
>> #   asm {
>> #     mov  EAX , ptr ;
>> #   }
>> # }
>
> Yes, that's what I'm doing currently.

It's implemntation dependent. Phobos, GPhobos and Ares currently use

# struct Array{
#    size_t len;
#    void* ptr;
# }

Thus you could write(32-bit systems only):

# asm {
#    mov EAX, [array + 4]
# }

Thomas


August 19, 2006
Marcio wrote:
> Are you sure that works?
> I've just tested the following code with DMD v0.164 (in Linux):
> 
> void main()
> {
>   char[] arr = "test";
> 
>   foreach (inout i, inout c; arr) {
>     if (i == 0) {
>       i++;
>       continue;
>     }
>   }
> }
> 
> And the compiler says: "foreach: key cannot be out".
> Did you use the last version?

Huh.  I could've sworn it used to work that way... but no matter, I just wrote the following and it worked fine (DMD 0.164):

# import std.stdio : writefln ;
#
# T[] array (T) (T[] args ...) { return args.dup; }
#
# void main () {
#   int[] arr = array!(int)(1, 2, 0, 3, 4, 5, 0, 6, 7, 8, 0, 9, 10);
#
#   foreach (i, inout x; arr) {
#     if (x == 0) {
#       i++;
#       continue;
#     }
#     writefln("[%2d] %2d", i, x);
#   }
# }

Turns out the 'inout' isn't neccessary anyhow.  This prints, as I expected:
[ 0]  1
[ 1]  2
[ 4]  4
[ 5]  5
[ 8]  7
[ 9]  8
[12] 10


-- Chris Nicholson-Sauls
August 19, 2006
Chris Nicholson-Sauls wrote:
> Huh.  I could've sworn it used to work that way... but no matter, I just wrote the
> following and it worked fine (DMD 0.164):
> (...)
> Turns out the 'inout' isn't neccessary anyhow.  This prints, as I expected:
> (...)

Thanks! It must've been my fault, perhaps I was doing something wrong and I couldn't get it to work.


Thomas Kuehne wrote:
> It's implemntation dependent. Phobos, GPhobos and Ares currently use
>
> # struct Array{
> #    size_t len;
> #    void* ptr;
> # }
>
> Thus you could write(32-bit systems only):
>
> # asm {
> #    mov EAX, [array + 4]
> # }

Just tested the following code, using DMD v0.164 (in Linux), and it didn't work:

//----------------------------------------------------
void main() {
  static uint[3] array = [0xC0DE, 0xBEEF, 0xF00D];
  uint* a = null;

  asm {
    mov EAX, [array + 4];
    mov a, EAX;
  }

  writefln(a);        // Prints: BEEF
}
//----------------------------------------------------

Any ideas?
August 19, 2006
Marcio schrieb am 2006-08-19:
> Thomas Kuehne wrote:
>> It's implemntation dependent. Phobos, GPhobos and Ares currently use
>>
>> # struct Array{
>> #    size_t len;
>> #    void* ptr;
>> # }
>>
>> Thus you could write(32-bit systems only):
>>
>> # asm {
>> #    mov EAX, [array + 4]
>> # }
>
> Just tested the following code, using DMD v0.164 (in Linux), and it didn't work:
>
> //----------------------------------------------------
> void main() {
>   static uint[3] array = [0xC0DE, 0xBEEF, 0xF00D];
>   uint* a = null;
>
>   asm {
>     mov EAX, [array + 4];
>     mov a, EAX;
>   }
>
>   writefln(a);        // Prints: BEEF
> }
> //----------------------------------------------------
>
> Any ideas?

Static arrays are special :X

Try
#	uint[] array = new uint[3];
#	array[0] = 0xC0DE;
#	array[1] = 0xBEEF;
#	array[2] = 0xF00D;

And replace
#
# writefln(a);
#

with something like
#
# writefln("%X", *a);
#

Thomas

August 19, 2006
Thomas Kuehne wrote:
> Static arrays are special :X
>
> Try
> # uint[] array = new uint[3];
> # array[0] = 0xC0DE;
> # array[1] = 0xBEEF;
> # array[2] = 0xF00D;
>
> And replace
> #
> # writefln(a);
> #
>
> with something like
> #
> # writefln("%X", *a);
> #

That only works for dynamically created arrays, but thanks anyway!
So there's really no way to do something like that with a static array?
August 20, 2006
Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Marcio schrieb am 2006-08-19:
>> Chris Nicholson-Sauls wrote:
>>> (...)
>>> I'm not sure.  Of course, pending a real solution from someone who knows better,
>> you could
>>> do this:
>>>
>>> # void main () {
>>> #   int[] array             ;
>>> #   auto  ptr   = array.ptr ;
>>> #
>>> #   asm {
>>> #     mov  EAX , ptr ;
>>> #   }
>>> # }
>> Yes, that's what I'm doing currently.
> 
> It's implemntation dependent. Phobos, GPhobos and Ares currently use
> 
> # struct Array{
> #    size_t len;
> #    void* ptr;
> # }

I think this is actually required.  According to the ABI (http://www.digitalmars.com/d/abi.html):

    Arrays
    A dynamic array consists of:

    offset   contents
    0        array dimension
    4        pointer to array data


Sean
August 20, 2006
Sean Kelly schrieb am 2006-08-20:
> Thomas Kuehne wrote:
>> It's implementation dependent. Phobos, GPhobos and Ares currently use
>> 
>> # struct Array{
>> #    size_t len;
>> #    void* ptr;
>> # }
>
> I think this is actually required.  According to the ABI (http://www.digitalmars.com/d/abi.html):
>
>      Arrays
>      A dynamic array consists of:
>
>      offset   contents
>      0        array dimension
>      4        pointer to array data

Thus on a 64bit system, an array may only contain (2^32 - 1) elements and every access suffers from a bad alignment of the data pointer?

Walter's ABI and Phobos are going to require quite a bit of a makeover if they are ported to a non-32bit system. A sample:

Phobos: dmd/src/phobos/internal/aaA.d:454
long _aaValues(AA aa, size_t keysize, size_t valuesize)

GPhobos(from gdc): d/phobos/internal/aaA.d:456
Array _aaValues(AA aa, size_t keysize, size_t valuesize)

Thomas

« First   ‹ Prev
1 2