Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

GTK fails to precompile against master: ccall - type - typevar #573

Closed
colbec opened this issue May 31, 2021 · 6 comments
Closed

GTK fails to precompile against master: ccall - type - typevar #573

colbec opened this issue May 31, 2021 · 6 comments

Comments

@colbec
Copy link

colbec commented May 31, 2021

In

Commit b46df09eb6* (2021-05-31 02:08 UTC)
Platform Info:
  OS: Linux (x86_64-suse-linux)
  CPU: Intel(R) Core(TM) i5-4460  CPU @ 3.20GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.0 (ORCJIT, haswell)

precompile of GTK, GTKReactive and ImageView all fail. Problem started about 3 days ago. Precompile is fine in Julia 1.6.1.

Assuming that GTK is the most fundamental requirement, here is the relevant error output:

ERROR: LoadError: TypeError: in ccall method definition, expected Type, got a value of type TypeVar
Stacktrace:
  [1] top-level scope
    @ ~/.julia/packages/Gtk/3TfRG/src/GLib/signals.jl:331
  [2] include(mod::Module, _path::String)
    @ Base ./Base.jl:389
  [3] include(x::String)
    @ Gtk.GLib ~/.julia/packages/Gtk/3TfRG/src/GLib/GLib.jl:1
  [4] top-level scope
    @ ~/.julia/packages/Gtk/3TfRG/src/GLib/GLib.jl:62
  [5] include(mod::Module, _path::String)
    @ Base ./Base.jl:389
  [6] include(x::String)
    @ Gtk ~/.julia/packages/Gtk/3TfRG/src/Gtk.jl:2
  [7] top-level scope
    @ ~/.julia/packages/Gtk/3TfRG/src/Gtk.jl:17
  [8] include
    @ ./Base.jl:389 [inlined]
  [9] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt64}}, source::String)
    @ Base ./loading.jl:1232
 [10] top-level scope
    @ none:1
 [11] eval
    @ ./boot.jl:369 [inlined]
 [12] eval(x::Expr)
    @ Base.MainInclude ./client.jl:453
 [13] top-level scope
    @ none:1
in expression starting at /home/colin/.julia/packages/Gtk/3TfRG/src/GLib/signals.jl:331
in expression starting at /home/colin/.julia/packages/Gtk/3TfRG/src/GLib/GLib.jl:1
in expression starting at /home/colin/.julia/packages/Gtk/3TfRG/src/Gtk.jl:2
@gustaphe
Copy link

Can reproduce, in a fresh project with only Gtk.

julia 1.7.0-DEV.1244, Commit 8535b8c4d7
Gtk 1.1.7

@oscardssmith
Copy link

Confirming this. Any chance it can be fixed? It's breaking ProfileView.

@colbec
Copy link
Author

colbec commented Jun 18, 2021

I looked at this and found that a couple of functions are declared in signals.jl:

function uv_check(src::Ptr{Nothing})
    global expiration
    ex = expiration::UInt64
    if !_isempty_workqueue()
        return Int32(1)
    elseif !uv_loop_alive(Base.eventloop())
        return Int32(0)
    elseif ex == 0
        return Int32(1)
    elseif uv_pollfd.revents != 0
        return Int32(1)
    else
        now = ccall((:g_source_get_time, GLib.libglib), UInt64, (Ptr{Nothing},), src)
        return Int32(ex <= now)
    end
end
function uv_dispatch(src::Ptr{Nothing}, callback::Ptr{Nothing}, data::T) where T
    return ccall(callback, Cint, (T,), data)
end

The problem is in the uv_dispatch() function, the third argument to the ccall() function:
ccall(callback, Cint, (T,), data)
should be more like
ccall(callback, Cint, (Ptr{Nothing}), data)
and this actually works (as in passes syntax check) in the REPL, but I have no idea what that argument should really be, so cannot make a PR.

@giordano
Copy link
Contributor

See JuliaLang/julia#41278

@jonathanBieler
Copy link
Collaborator

jonathanBieler commented Jun 22, 2021

I'm not too sure but looking at Gtk's doc the data parameter is typed as gpointer which is an alias for void*, so I suspect Ptr{Cvoid} might be correct.

https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-set-callback

Tried it but it doesn't work, no method matching unsafe_convert(::Type{Ptr{Nothing}}, ::Int64).

@jonathanBieler
Copy link
Collaborator

jonathanBieler commented Jun 22, 2021

I tried to come up with a minimal example, as I understand callbacks can be any user defined function, and data can be anything as well so the situation is a bit like this :

test(x,y) = begin @show x, y ; true end

call_fun(f, data::T) where T  = ccall(f, Bool, (T,), data) # this is our uv_dispatch

funs = [@cfunction(test, Bool, (Int, Int)), @cfunction(test, Bool, (Float64, Float64))]
data = [(1,2), (1.0, 2.0)]

call_fun.(funs, data)

But this doesn't work (test prints gibberish instead of the correct values on v1.6), so something must be missing. That said if you define :

@generated function call_fun(f, data)
    :( ccall(f, Bool, ($(data),), data) )
end

Then it works (all Gtk's test pass in v1.8 with this solution). I find this a bit strange because in mind my mind the two call_fun should be equivalent. When I pass some data::T the compiler should compile a version of the function where T is the type of of data, which is what @generated does as well, but at a different stage. Obviously I don't understand everything here...

Edit : this explains why my example doesn't work : https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Type-Parameters

JeffBezanson added a commit that referenced this issue Jun 29, 2021
JeffBezanson added a commit that referenced this issue Jun 29, 2021
@tknopp tknopp closed this as completed in 51833fb Jun 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants