www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Several questions (about inline assembly, ddoc for templates, and foreach)

reply Marcio <m.faustino gmail.com> writes:
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,
Aug 19 2006
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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,

Aug 19 2006
parent reply Marcio <m.faustino gmail.com> writes:
Chris Nicholson-Sauls wrote:
 (...)
 I'm not sure.  Of course, pending a real solution from someone who knows
better,

 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


 only the value.

Any reason why you can't make the index inout? I've done it often enough myself

 very effect.  Of course, I'm sure its undefined behavior with associative

 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?
Aug 19 2006
next sibling parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----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,

 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 -----BEGIN PGP SIGNATURE----- iD8DBQFE527pLK5blCcjpWoRAm6eAJ44HPK1AmaPJ6Zdair6dTd7rnbaGwCfT6oR AgavCz0umlrBm+skjkL7H7I= =7N6c -----END PGP SIGNATURE-----
Aug 19 2006
parent reply Sean Kelly <sean f4.ca> writes:
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,

 do this:

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


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
Aug 20 2006
parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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 -----BEGIN PGP SIGNATURE----- iD8DBQFE6NYlLK5blCcjpWoRArjhAJ9EcyU1PZPbjLyIhdV8dwGMlC4uLgCghW82 6f8fgglEHaIwkLc9HBbGklk= =5i4c -----END PGP SIGNATURE-----
Aug 20 2006
parent Sean Kelly <sean f4.ca> writes:
Thomas Kuehne wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
 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;
 # }

(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?

The whole ABI needs a rewrite in terms of pointer size rather than fixed offset.
 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)

Yup. Fortunately, most of the pointer size-related diffs between Phobos and GPhobos are in this file, so the changes shouldn't be too onerous. Particularly since they can all be revealed by a diff between the two. Sean
Aug 20 2006
prev sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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
Aug 19 2006
parent reply Marcio <m.faustino gmail.com> writes:
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?
Aug 19 2006
parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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 -----BEGIN PGP SIGNATURE----- iD8DBQFE55u3LK5blCcjpWoRAvqHAJ4jCwdfq4eiMY3Q9nRZShIbhR7q5wCgk/rL PmehAwIRT8emFAesQwWU2Vs= =0uiF -----END PGP SIGNATURE-----
Aug 19 2006
parent Marcio <m.faustino gmail.com> writes:
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?
Aug 19 2006