1. detecting if an atom is a pointer

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

new topic     » topic index » view message » categorize

2. Re: detecting if an atom is a pointer

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."

new topic     » goto parent     » topic index » view message » categorize

3. Re: detecting if an atom is a pointer

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: detecting if an atom is a pointer

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu