1. Double Trouble with Phix (bug)(solved)
- Posted by irv Dec 20, 2020
- 1124 views
- Last edited Dec 25, 2020
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.
2. Re: Double Trouble with Phix (bug)
- Posted by petelomax Dec 22, 2020
- 1066 views
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....?
3. Re: Double Trouble with Phix (bug)
- Posted by irv Dec 22, 2020
- 1034 views
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....
4. Re: Double Trouble with Phix (bug)
- Posted by petelomax Dec 22, 2020
- 1122 views
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
5. Re: Double Trouble with Phix (bug)
- Posted by irv Dec 22, 2020
- 1039 views
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.
6. Re: Double Trouble with Phix (bug)
- Posted by katsmeow Dec 23, 2020
- 1038 views
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.
7. Re: Double Trouble with Phix (bug)
- Posted by petelomax Dec 23, 2020
- 992 views
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.
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.
8. Re: Double Trouble with Phix (bug)
- Posted by irv Dec 23, 2020
- 991 views
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.
9. Re: Double Trouble with Phix (bug)
- Posted by petelomax Dec 23, 2020
- 1083 views
- Last edited Dec 24, 2020
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.