1. Double Trouble with Phix (bug)(solved)

The code below will run on Euphoria or Phix without change. However, the results are different.

--/* 
include std/dll.e  
--*/ 
 
constant GTK = open_dll("libgtk-3.so.0") 
constant 
 init = define_c_func(GTK,"gtk_init_check",{C_POINTER,C_POINTER},C_POINTER),   
 show_all = define_c_proc(GTK,"gtk_widget_show_all",{C_POINTER}), 
 main = define_c_proc(GTK,"gtk_main",{}), 
 add = define_c_proc(GTK,"gtk_container_add",{C_POINTER,C_POINTER}), 
 new_win = define_c_func(GTK,"gtk_window_new",{C_INT},C_POINTER), 
 new_spin = define_c_func(GTK,"gtk_spin_button_new_with_range",{C_DOUBLE,C_DOUBLE,C_DOUBLE},C_POINTER), 
 set_range = define_c_proc(GTK,"gtk_spin_button_set_range",{C_POINTER,C_DOUBLE,C_DOUBLE}) 
 
if init < 1 or c_func(init,{0,0})=0 then abort(1) end if  
atom win = c_func(new_win,{0}) 
atom spin = c_func(new_spin,{1,100,1}) -- range is 1..100, try it! 
 
c_proc(add,{win,spin})                                       --------------- 
c_proc(set_range,{spin,25,75}) -- range is now 25..75 on EU, 0..25 with phix 
                                                             --------------- 
c_proc(show_all,{win}) 
c_proc(main,{}) 

Something shifty going on here. blink

new topic     » topic index » view message » categorize

2. Re: Double Trouble with Phix (bug)

OK, it works on windows, but does not work on linux.

I've got some idea what the problem is but not a proper solution yet.

First, I changed the newspin line and tested that without the set_range:

atom spin = c_func(new_spin,{1,100,10}) -- range is 1..100, try it!  

Then, in builtins\VM\pcfunc.e I changed the first set of these

                        if i=1 then 
                            #ilASM{ 
                                    [64] 
                                        movsd xmm0,qword[rsp] 
                                    [] 
                                  } 
                        elsif i=2 then 
                            #ilASM{ 
                                    [64] 
                                        movsd xmm0,qword[rsp] 
--                                      movsd xmm1,qword[rsp] 
                                    [] 
                                  } 
                        elsif i=3 then 
                            #ilASM{ 
                                    [64] 
                                        movsd xmm1,qword[rsp] 
                                        movsd xmm2,qword[rsp] 
                                    [] 
                                  } 

and (after p -c p, obviously) the set_range 25,75 now works. Since the first arg is a pointer, the i=1 part is not executed and we left xmm0/1/2 as 25,75,75.

But of course if you comment out the set_range, the original new_spin is now faulty, with a range of 1..10 step 10, which makes sense as we left xmm0/1/2 as 1,10,10.

So my theory is that windows puts the third arg, if floating point, in xmm2, no matter what types the first and second args are.
However I think (I've never seen this written down) that linux puts the third arg in xmm0 if 1st & 2nd args don't blag any xmm registers, up to xmm2 if they both do.

I'm thinking the fix will be entirely in pcfunc.e, and in fact we've got all the right assembly instructions we need, just the wrong controlling hll code. Maybe it will be something like this:

sequence xmmi = tagset(la) -- (used as-is under windows) 
... 
if platform()=LINUX then 
  for i=1 to la do //set xmmi[i] correctly// end for 
end if 
 
-- and in the main for i=la to 1 by -1 loop: 
  integer xi = xmmi[i] 
 
--    if i=1 then     \  times 
      if xi=1 then    /  40ish 

Of course you have to have a separate forward pass to allocate registers, then a backward one to shove them on the stack.

If you're up for it, you might want to have a go at that yourself....?

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

3. Re: Double Trouble with Phix (bug)

petelomax said...

OK, it works on windows, but does not work on linux.

I've got some idea what the problem is but not a proper solution yet.

Of course you have to have a separate forward pass to allocate registers, then a backward one to shove them on the stack.

If you're up for it, you might want to have a go at that yourself....?

I'd better not try, since I have no idea what you just wrote.

And I never was any good at football....

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

4. Re: Double Trouble with Phix (bug)

Wise man. Anyway, my first stab was alot easier than I first feared and seems ok: https://github.com/petelomax/Phix/blob/master/builtins/VM/pcfunc.e

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

5. Re: Double Trouble with Phix (bug)

petelomax said...

Wise man. Anyway, my first stab was alot easier than I first feared and seems ok: https://github.com/petelomax/Phix/blob/master/builtins/VM/pcfunc.e

Success!

Now works like it should.

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

6. Re: Double Trouble with Phix (bug)

I am (of course) happy you all fixed this, but it smells like a problem the next "upgrade" of the OS (any of Windoze, *nix, etc) will break. It's like 50 different versions of win32lib which are variously in/compatable in ways unknown to the average user who just wants a window to open or a process to run. As it's clear the maintainers of the OS aren't going to notify Pete, Derek, Matt, Greg, etc about the next rescrambling of the OS's variable handlers, praps a way of testing the situation in Phix/OE at compile time, and then applying the appropriate code, beats hard-coding the fix for the problem as it stands today.

I am not diss'ing this fix, i am only looking at the worst-case scene that might pop up in six months. This snuck up on you this time, it may sneak up again. Or i may be clueless.

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

7. Re: Double Trouble with Phix (bug)

katsmeow said...

smells like a problem the next "upgrade" of the OS will break.

It was always a problem, passing C_DOUBLE to 64-bit .so on linux only ever worked when all args were C_DOUBLE. It won't come back.
There was an earlier problem with some kernels being compiled with "-allignstacktosixteenbytes" (or whatever its really called) and some not, but again, now it's fixed it won't come back.

katsmeow said...

praps a way of testing Phix

That's what "p -test" is for.

To be honest, neither of the above have made it into that yet, and they'll probably be tricker than most, but I'll give 'em a bash.
One thing I can promise (while I still have all my marbles) is anything that bites twice will end up being properly tested by p -test.

Things will always break, I suppose. I will also just say that irv is currently on a completely untrodden path.

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

8. Re: Double Trouble with Phix (bug)

petelomax said...

Things will always break, I suppose. I will also just say that irv is currently on a completely untrodden path.

I figure that GTK is complex enough that it's likely to test a lot of the more obscure operations.

The good news is it turns out that it is very easy to "wrap" calls to libgtk-3, most take only 3 or 4 lines of code. The whole class thing works well, also.

The thing that is taking longest is trying to work out the best syntax. I've had some success duplicating EuGTK syntax style.

Q: what, exactly, happens in a new() call, e.g. GtkWindow win = new(). And what can go inside those parens? I've read the docs, and only got a headache.

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

9. Re: Double Trouble with Phix (bug)

irv said...

Q: what, exactly, happens in a new() call, e.g. GtkWindow win = new(). And what can go inside those parens? I've read the docs, and only got a headache.

aside: new() actually takes up to two parameters, but here the first is deduced[1] from the opening GtkWindow part of that statement [aka context], so we'll concentrate on the second.

The other parameter (optional, can be first/only) is a sequence of values, assigned in numerical order. For example:

class GtkWindow 
 public: 
  integer one 
  string two 
  atom three 
  sequence four 
  function getw() return {one,two,three,four} end function 
end class 
 
GtkWindow win = new({1,"two",3.3,{4}}), 
          win2 = new() 
win2.one = 1 
win2.two = "two" 
win2.three = 3.3 
win2.four = {4} 
?win.getw() 
?win2.getw() 

Obviously win and win2 are initialised identically. Should you move string two above integer one in the definition, you'll get a typecheck error on the (unmodified) inline declaration of the first win.

Note that if you have any functions/procedures in the class definition, they are treated as integers/routine_ids, but for now I'd recommend moving them below anything you want to initialise.
(I can talk a bit more about initialising/replacing/playing with any such integers/routine_ids, when you're ready.)

[1] The hardest part of the docs is that the first parameter is NOT optional, but in most cases the compiler automatically inserts it, so it feels like it is.
Were you to code something like my_create_instance(new({defaults})), then the compiler would demand you insert GtkWindow, making {defaults} the second parameter.

UPDATE: (This was never documented either) If you have a constructor function, that puts further constraints on the min/max number of {defaults} you must provide. Also, if you added

  function GtkWindow(object arg1=0,arg2=0,arg3=0,arg4=0) 
    ?{arg1,arg2,arg3,arg4} 
    return this 
  end function 

to the above, it would in fact effectively discard the inline defaults, since it's leaving your constructor routine to deal with them.
Note that to permit new({1,"two",3.3,{4}}), I needed the constructor to have at least four parameters,
and that to permit new(), they all had to be optional.

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

Search



Quick Links

User menu

Not signed in.

Misc Menu