1. Phix: 64bit (-1) equal #ffffffffffffffff ?!

Hallo

To make it more clear i have put togheter this small codefile.

The function scan_com_ports() should return a list of available serial ports.
The function serial_open()
should open a serial port and return the handle or INVALID_HANDLE_VALUE(-1) if it fails

C:\TDM-GCC-64\x86_64-w64-mingw32\include>grep -i INVALID_HANDLE_VALUE *.* 
pdh.h:#define INVALID_HANDLE_VALUE ((HANDLE)((LONG_PTR)-1)) 
handleapi.h:#define INVALID_HANDLE_VALUE ((HANDLE) (LONG_PTR)-1) 
This works nice with Phix 32bit:
The result on my Computer: (yes, (COM7: and COM8: is what i expected)
196 
11000100 
11111111111111111111111111111111 
 
224 
11100000 
11111111111111111111111111111111 
 
{"COM7:","COM8:"} 

But works not so nice with Phix 64bit:
If it fails,the function returns #ffffffffffffffff instead of (-1), isn't it the same?
The result on my Computer:

18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
152 
10011000 
1111111111111111111111111111111111111111111111111111111111111111 
 
156 
10011100 
1111111111111111111111111111111111111111111111111111111111111111 
 
18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
{"COM5:","COM6:","COM7:","COM8:","COM9:","COM10:"} 

include cffi.e 
 
constant kernel=open_dll("kernel32.dll") 
--REF: http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx 
--constant iCreateFile = define_c_func(kernel,"CreateFileA",{C_INT,C_INT,C_INT,C_INT,C_INT,C_INT,C_INT},C_INT) 
sequence tStr=""" 

HANDLE CreateFileA( 
  _in_           LPCSTR                lpFileName, 
  _in_           DWORD                 dwDesiredAccess, 
  _in_           DWORD                 dwShareMode, 
  _in_           LPVOID                lpSecurityAttributes, 
  _in_           DWORD                 dwCreationDisposition, 
  _in_           DWORD                 dwFlagsAndAttributes, 
  _in_           HANDLE                hTemplateFile 
); 
""" 

 
set_unicode(0) 
constant iCreateFile=define_cffi_func(kernel,tStr) 
 
constant 
     GENERIC_READ    = #80000000, 
     GENERIC_WRITE   = #40000000, 
     OPEN_EXISTING   = 3 
                                    
-- open a serial port and return the handle or INVALID_HANDLE_VALUE(-1) if it fails 
global function serial_open(integer com) 
atom fn_val, pComm 
   pComm = allocate_string(sprintf("\\\\.\\com%d",com)) 
   fn_val = c_func(iCreateFile,{pComm, 
                    GENERIC_READ+GENERIC_WRITE, 
                    0, 
                    0, 
                    OPEN_EXISTING, 
                    0, 
                    0 
                    }) 
   free(pComm) 
    if equal(fn_val,#ffffffffffffffff) then 
--      fn_val=-1 --This helps with Phix 64bit, but i think it is an ugly hack,  
    end if 
   return fn_val                 
end function 
 
--REF: http://msdn.microsoft.com/en-us/library/ms724211.aspx 
--constant iCloseHandle = define_c_func(kernel,"CloseHandle",{C_UINT},C_INT) 
tStr=""" 

BOOL CloseHandle( 
  _in_ HANDLE hObject 
); 
""" 

set_unicode(0) 
constant iCloseHandle=define_cffi_func(kernel,tStr) 
 
global procedure serial_close(atom hCom) 
atom fn_val 
  fn_val = c_func(iCloseHandle,{hCom})    
end procedure 
 
function scan_com_ports() 
atom hcom 
sequence retval={} 
for i=5 to 10 do 
    hcom=serial_open(i) 
    if hcom>0  then 
        puts(1,sprintf("%d\n",hcom)) 
        puts(1,sprintf("%b\n",hcom)) 
        puts(1,sprintf("%b\n\n",-1)) --just to make sure I'am not completly confused 
        serial_close(i) 
        retval=append(retval,(sprintf("COM%d:",i))) 
    end if 
    end for 
return retval 
end function 
?scan_com_ports() 
wait_key() 

Maybe someone can enlighten me.

Maybe I should just continue with 32bit. For my small programs there is not really a need to support 64bit. This is not the first time I have come across such oddities. I just forgot about it.
Andreas

new topic     » topic index » view message » categorize

2. Re: Phix: 64bit (-1) equal #ffffffffffffffff ?!

andreasWagner said...

should open a serial port and return the handle or INVALID_HANDLE_VALUE(-1) if it fails

C:\TDM-GCC-64\x86_64-w64-mingw32\include>grep -i INVALID_HANDLE_VALUE *.* 
pdh.h:#define INVALID_HANDLE_VALUE ((HANDLE)((LONG_PTR)-1)) 
handleapi.h:#define INVALID_HANDLE_VALUE ((HANDLE) (LONG_PTR)-1) 
This works nice with Phix 32bit:

But works not so nice with Phix 64bit:
If it fails,the function returns #ffffffffffffffff instead of (-1), isn't it the same?
The result on my Computer:

18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
152 
10011000 
1111111111111111111111111111111111111111111111111111111111111111 
 
156 
10011100 
1111111111111111111111111111111111111111111111111111111111111111 
 
18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
18446744073709551615 
1111111111111111111111111111111111111111111111111111111111111111 
1111111111111111111111111111111111111111111111111111111111111111 
 
{"COM5:","COM6:","COM7:","COM8:","COM9:","COM10:"} 

Maybe someone can enlighten me.

Not sure, but seems like it's returning a 32bit int sometimes rather than the 64bit long that's needed to get to -1 on a 64bit system. (This bug is not noticible on 32bits since sizeof(long) == sizeof(int) == 32bits, but on 64bit intel/amd systems sizeof(long) is twice sizeof(int) and this was a major headache in getting OE ported to 64bits due to all the assumptions made between sizeof(void*) and sizeof(long) and sizeof(int).)

andreasWagner said...

Maybe I should just continue with 32bit. For my small programs there is not really a need to support 64bit.

Of course, no harm in sticking to what works or what you need.

andreasWagner said...

This is not the first time I have come across such oddities. I just forgot about it.
Andreas

Thanks for reporting it though - even if there's no immediate response, having the report can be helpful to someone else in realizing that a bug exists and in figuring out the issue and solving it.

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

3. Re: Phix: 64bit (-1) equal #ffffffffffffffff ?!

andreasWagner said...
    if equal(fn_val,#ffffffffffffffff) then 
--      fn_val=-1 --This helps with Phix 64bit, but i think it is an ugly hack,  
    end if 

I'll agree with you that is not pretty, but it is probably the best/safest way, and (esp with an "or #FFFFFFFF") protects you against the sign of c_func() results possibly getting flipped one day.
Of course, having got it to work at all, I am going to be exceeding cautious of making the slightest change to anything in that area, for fear of it all coming crashing down like a ton of bricks.
Should you think I have some special knowledge of whether INVALID_FILE_HANDLE is -1, #FFFFFFFF, #FFFFFFFFFFFFFFFF, (HANDLE)-1, (HANDLE)(LONG_PTR)-1, (1 << FFI::Platform::ADDRESS_SIZE) - 1, or something else entirely, you would be quite wrong. Even Raymond Chen, the oracle of all microsoft-related knowledge, has some disparaging words to say on the matter, NULL would have been better, but "it is what it is, and we cannot change history": https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443

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

4. Re: Phix: 64bit (-1) equal #ffffffffffffffff ?!

petelomax said...

I'll agree with you that is not pretty, but it is probably the best/safest way, and (esp with an "or #FFFFFFFF") protects you against the sign of c_func() results possibly getting flipped one day.
Of course, having got it to work at all, I am going to be exceeding cautious of making the slightest change to anything in that area, for fear of it all coming crashing down like a ton of bricks.
Should you think I have some special knowledge of whether INVALID_FILE_HANDLE is -1, #FFFFFFFF, #FFFFFFFFFFFFFFFF, (HANDLE)-1, (HANDLE)(LONG_PTR)-1, (1 << FFI::Platform::ADDRESS_SIZE) - 1, or something else entirely, you would be quite wrong. Even Raymond Chen, the oracle of all microsoft-related knowledge, has some disparaging words to say on the matter, NULL would have been better, but "it is what it is, and we cannot change history": https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443

thanks for the answer, now at least i feel a little better and no longer doubt my sanity so much. And I can understand that you don't want to change anything. But with Raymond Chen on your side, who is to say that the solution is worse than any other? The ("or #FFFFFFFFFF") is a very good idea before the next surprise comes.

Thank you

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

Search



Quick Links

User menu

Not signed in.

Misc Menu