1. detecting if an atom is a pointer
- Posted by Chris Bensler <bensler at nt.net> Nov 15, 2006
- 564 views
The problem: A set of routines that accept an atom as a parameter, which could be a pointer or a type identifier. The type identifiers are Eu's C type definitions.. C_INT, C_FLOAT, etc.. All the Eu definitions are in the format #0F00000F where #0F000000 represents the type modifier and #0000000F represents the atomic size. I've expanded the definitions to support compound C types. (structs, unions, arrays and bitfields) The mask format for the expanded identifiers is #CFFFFFFF As you can see, the expanded identifiers use pretty much all the bits of the atom. (bits 27 and 28 are not used) My first thought was to use the pointer alignment to detect the difference, since an identifier will always use at least 1 of the aligned bits for the type size. This is flawed however because the type size could be 8, which would use 4 bits and the 3 aligned bits would be 0. Additionally, it would be preferable if it will handle third party allocations as well as Eu pointers, and AFAIK there is no guarantee that third party pointers will be aligned at all. So the question: is there a way that I can determine if an atom is a pointer or an identifier? In my testing it appears that the pointers never use all the high bits. Is this because Eu's heaps? or OS heaps? Would it be safe to use those bits to detect identifiers? Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria
2. Re: detecting if an atom is a pointer
- Posted by Al Getz <Xaxo at aol.com> Nov 15, 2006
- 539 views
Chris Bensler wrote: > > The problem: > A set of routines that accept an atom as a parameter, which could be a > pointer > or a type identifier. > > The type identifiers are Eu's C type definitions.. > C_INT, C_FLOAT, etc.. > All the Eu definitions are in the format #0F00000F > where #0F000000 represents the type modifier and #0000000F represents the > atomic > size. > I've expanded the definitions to support compound C types. (structs, unions, > arrays and bitfields) > The mask format for the expanded identifiers is #CFFFFFFF > As you can see, the expanded identifiers use pretty much all the bits of the > atom. (bits 27 and 28 are not used) > > My first thought was to use the pointer alignment to detect the difference, > since an identifier will always use at least 1 of the aligned bits for the > type > size. This is flawed however because the type size could be 8, which would use > 4 bits and the 3 aligned bits would be 0. Additionally, it would be preferable > if it will handle third party allocations as well as Eu pointers, and AFAIK > there is no guarantee that third party pointers will be aligned at all. > > So the question: is there a way that I can determine if an atom is a pointer > or an identifier? > > In my testing it appears that the pointers never use all the high bits. Is > this > because Eu's heaps? or OS heaps? Would it be safe to use those bits to detect > identifiers? > > Chris Bensler > ~ The difference between ordinary and extraordinary is that little extra ~ > <a href="http://empire.iwireweb.com">http://empire.iwireweb.com</a> - Empire > for Euphoria Hi Chris, Welcome to the world of trying to tell the difference between a pointer and an integer. There's only three ways: Identify the pointer by name, ie "Pointer1", etc, and id normal integers by other types of names, "myvalue" etc. or By making it part of a sequence: {TYPE_POINTER, value} or Make the least bit always a 'zero' for pointers, and make it always a 'one' for non-pointers. This of course also means that you might have to change your type identifier integers, to make them always odd...ie if you have #80 you'll have to change it to #81 and make a cross ref table or possibly just adapt that to your program or some other idea. This way you know if it's a pointer by checking the LSB of the value. Take care, Al E boa sorte com sua programacao Euphoria! My bumper sticker: "I brake for LED's" From "Black Knight": "I can live with losing the good fight, but i can not live without fighting it". "Well on second thought, maybe not."
3. Re: detecting if an atom is a pointer
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Nov 16, 2006
- 571 views
- Last edited Nov 17, 2006
On Wed, 15 Nov 2006 15:45:06 -0800, Chris Bensler <guest at RapidEuphoria.com> wrote: >In my testing it appears that the pointers never use all the high >bits. Is this because Eu's heaps? or OS heaps? Would it be safe to use >those bits to detect identifiers? The windows api GlobalAlloc is documented somewhere as always returning 8-byte aligned addresses, but occasionally it does not. On a 32-bit machine, all native allocation methods will be 32-bit aligned. However:
atom ptr ptr = allocate(10) ?ptr poke(ptr,"0123456789") while peek(ptr)<'3' do ptr+=1 end while ?ptr
clearly results in a non-4-byte-aligned pointer, and likewise any pointer returned from a c function is probably 4-byte-aligned but in no way guaranteed to be. GetLogicalDriveStrings springs to mind as a c/winapi function which packs strings back-to-back, leading to code like the above. So the answer is that you probably could get something working by mangling/mapping C_INT etc to always have one or both of the two least significant bits set, but one day it will break. I also remember once assuming that allocate (or api) won't return memory addresses below something like #00100000 because that is where the OS or something similar lives on win98. Of course it went belly up the first time anyone ran it on XP. My advice: pass an extra boolean flag to indicate what it is. Regards, Pete
4. Re: detecting if an atom is a pointer
- Posted by Chris Bensler <bensler at nt.net> Nov 16, 2006
- 551 views
- Last edited Nov 17, 2006
Pete Lomax wrote: > > On Wed, 15 Nov 2006 15:45:06 -0800, Chris Bensler > <guest at RapidEuphoria.com> wrote: > > >In my testing it appears that the pointers never use all the high > >bits. Is this because Eu's heaps? or OS heaps? Would it be safe to use > >those bits to detect identifiers? > The windows api GlobalAlloc is documented somewhere as always > returning 8-byte aligned addresses, but occasionally it does not. > On a 32-bit machine, all native allocation methods will be 32-bit > aligned. However: > }}} <eucode> > atom ptr > ptr = allocate(10) > ?ptr > poke(ptr,"0123456789") > while peek(ptr)<'3' do > ptr+=1 > end while > ?ptr > </eucode> {{{ > clearly results in a non-4-byte-aligned pointer, and likewise any > pointer returned from a c function is probably 4-byte-aligned but in > no way guaranteed to be. GetLogicalDriveStrings springs to mind as a > c/winapi function which packs strings back-to-back, leading to code > like the above. > > So the answer is that you probably could get something working by > mangling/mapping C_INT etc to always have one or both of the two least > significant bits set, but one day it will break. > > I also remember once assuming that allocate (or api) won't return > memory addresses below something like #00100000 because that is where > the OS or something similar lives on win98. Of course it went belly up > the first time anyone ran it on XP. > > My advice: pass an extra boolean flag to indicate what it is. > > Regards, > Pete Thanks Pete. I've worked around it. Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria