Skip to content

Commit

Permalink
make ccall fully statically compilable
Browse files Browse the repository at this point in the history
and remove the ducttape!
  • Loading branch information
vtjnash committed Oct 13, 2016
1 parent 22117b5 commit 39680e3
Show file tree
Hide file tree
Showing 23 changed files with 795 additions and 521 deletions.
4 changes: 2 additions & 2 deletions base/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ end
finalize(o::ANY) = ccall(:jl_finalize_th, Void, (Ptr{Void}, Any,),
Core.getptls(), o)

gc(full::Bool=true) = ccall(:jl_gc_collect, Void, (Cint,), full)
gc_enable(on::Bool) = ccall(:jl_gc_enable, Cint, (Cint,), on)!=0
gc(full::Bool=true) = ccall(:jl_gc_collect, Void, (Int32,), full)
gc_enable(on::Bool) = ccall(:jl_gc_enable, Int32, (Int32,), on) != 0

immutable Nullable{T}
hasvalue::Bool
Expand Down
3 changes: 3 additions & 0 deletions base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,21 @@ else
typealias Culong UInt
typealias Cwchar_t Int32
end

"""
Clong
Equivalent to the native `signed long` c-type.
"""
Clong

"""
Culong
Equivalent to the native `unsigned long` c-type.
"""
Culong

"""
Cwchar_t
Expand Down
26 changes: 26 additions & 0 deletions base/ctypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,78 +9,104 @@
Equivalent to the native `unsigned char` c-type (`UInt8`).
"""
typealias Cuchar UInt8


"""
Cshort
Equivalent to the native `signed short` c-type (`Int16`).
"""
typealias Cshort Int16


"""
Cushort
Equivalent to the native `unsigned short` c-type (`UInt16`).
"""
typealias Cushort UInt16


"""
Cint
Equivalent to the native `signed int` c-type (`Int32`).
"""
typealias Cint Int32


"""
Cuint
Equivalent to the native `unsigned int` c-type (`UInt32`).
"""
typealias Cuint UInt32


"""
Cptrdiff_t
Equivalent to the native `ptrdiff_t` c-type (`Int`).
"""
typealias Cptrdiff_t Int


"""
Csize_t
Equivalent to the native `size_t` c-type (`UInt`).
"""
typealias Csize_t UInt


"""
Cssize_t
Equivalent to the native `ssize_t` c-type.
"""
typealias Cssize_t Int


"""
Cintmax_t
Equivalent to the native `intmax_t` c-type (`Int64`).
"""
typealias Cintmax_t Int64


"""
Cuintmax_t
Equivalent to the native `uintmax_t` c-type (`UInt64`).
"""
typealias Cuintmax_t UInt64


"""
Clonglong
Equivalent to the native `signed long long` c-type (`Int64`).
"""
typealias Clonglong Int64


"""
Culonglong
Equivalent to the native `unsigned long long` c-type (`UInt64`).
"""
typealias Culonglong UInt64


"""
Cfloat
Equivalent to the native `float` c-type (`Float32`).
"""
typealias Cfloat Float32


"""
Cdouble
Expand Down
4 changes: 2 additions & 2 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ end
map(f::Function, a::Array{Any,1}) = Any[ f(a[i]) for i=1:length(a) ]

function precompile(f::ANY, args::Tuple)
ccall(:jl_compile_hint, Cint, (Any,), Tuple{Core.Typeof(f), args...}) != 0
ccall(:jl_compile_hint, Int32, (Any,), Tuple{Core.Typeof(f), args...}) != 0
end

function precompile(argt::Type)
ccall(:jl_compile_hint, Cint, (Any,), argt) != 0
ccall(:jl_compile_hint, Int32, (Any,), argt) != 0
end

"""
Expand Down
55 changes: 35 additions & 20 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1199,25 +1199,32 @@ function abstract_eval(e::ANY, vtypes::VarTable, sv::InferenceState)
abstract_eval(e.args[1], vtypes, sv)
t = Any
elseif is(e.head, :foreigncall)
rt = e.args[2]
if isdefined(sv.linfo, :def)
tvars = sv.linfo.def.tvars
if tvars !== svec()
env = data_pointer_from_objref(sv.linfo.sparam_vals) + sizeof(Ptr{Void})
rt = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), e.args[2], tvars, env)
end
end
abstract_eval(e.args[1], vtypes, sv)
rt = abstract_eval(e.args[2], vtypes, sv)
for i = 3:length(e.args)
for i = 4:length(e.args)
if abstract_eval(e.args[i], vtypes, sv) === Bottom
rt = Bottom
end
end
if rt === Bottom
t = Bottom
elseif !isType(rt)
t = Any
else
t = rt.parameters[1]
elseif isa(rt, Type)
t = rt
if isa(t, DataType) && is((t::DataType).name, Ref.name)
t = t.parameters[1]
if t === Any
t = Bottom # a return type of Box{Any} is invalid
end
end
else
t = Any
end
elseif is(e.head, :static_parameter)
n = e.args[1]
Expand Down Expand Up @@ -2212,7 +2219,7 @@ end

# replace slots 1:na with argexprs, static params with spvals, and increment
# other slots by offset.
function substitute!(e::ANY, na, argexprs, spvals, offset)
function substitute!(e::ANY, na::Int, argexprs::Vector{Any}, tvars::ANY, spvals::Vector{Any}, offset::Int)
if isa(e, Slot)
if 1 <= e.id <= na
ae = argexprs[e.id]
Expand All @@ -2227,17 +2234,25 @@ function substitute!(e::ANY, na, argexprs, spvals, offset)
return TypedSlot(e.id+offset, e.typ)
end
end
if isa(e,NewvarNode)
return NewvarNode(substitute!(e.slot, na, argexprs, spvals, offset))
if isa(e, NewvarNode)
return NewvarNode(substitute!(e.slot, na, argexprs, tvars, spvals, offset))
end
if isa(e,Expr)
if isa(e, Expr)
e = e::Expr
head = e.head
if head === :static_parameter
return spvals[e.args[1]]
elseif head === :foreigncall
for i = 1:length(e.args)
if i == 2 || i == 3
e.args[2] = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), e.args[2], tvars, spvals)
else
e.args[i] = substitute!(e.args[i], na, argexprs, tvars, spvals, offset)
end
end
elseif !is_meta_expr_head(head)
for i=1:length(e.args)
e.args[i] = substitute!(e.args[i], na, argexprs, spvals, offset)
for i = 1:length(e.args)
e.args[i] = substitute!(e.args[i], na, argexprs, tvars, spvals, offset)
end
end
end
Expand Down Expand Up @@ -2598,14 +2613,14 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
return invoke_NF()
end

na = method.nargs
na = Int(method.nargs)
# check for vararg function
isva = false
if na > 0 && method.isva
@assert length(argexprs) >= na-1
@assert length(argexprs) >= na - 1
# construct tuple-forming expression for argument tail
vararg = mk_tuplecall(argexprs[na:end], sv)
argexprs = Any[argexprs[1:(na-1)]..., vararg]
argexprs = Any[argexprs[1:(na - 1)]..., vararg]
isva = true
elseif na != length(argexprs)
# we have a method match only because an earlier
Expand Down Expand Up @@ -2709,7 +2724,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
prelude_stmts = Any[]
stmts_free = true # true = all entries of stmts are effect_free

for i=na:-1:1 # stmts_free needs to be calculated in reverse-argument order
for i = na:-1:1 # stmts_free needs to be calculated in reverse-argument order
#args_i = args[i]
aei = argexprs[i]
aeitype = argtype = widenconst(exprtype(aei, sv.src, sv.mod))
Expand Down Expand Up @@ -2758,10 +2773,10 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
end

# ok, substitute argument expressions for argument names in the body
body = substitute!(body, na, argexprs, spvals, length(sv.src.slotnames) - na)
append!(sv.src.slotnames, src.slotnames[na+1:end])
append!(sv.src.slottypes, src.slottypes[na+1:end])
append!(sv.src.slotflags, src.slotflags[na+1:end])
body = substitute!(body, na, argexprs, method.tvars, spvals, length(sv.src.slotnames) - na)
append!(sv.src.slotnames, src.slotnames[(na + 1):end])
append!(sv.src.slottypes, src.slottypes[(na + 1):end])
append!(sv.src.slotflags, src.slotflags[(na + 1):end])

# make labels / goto statements unique
# relocate inlining information
Expand Down
6 changes: 3 additions & 3 deletions base/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function unsafe_wrap{T,N}(::Union{Type{Array},Type{Array{T}},Type{Array{T,N}}},
end
function unsafe_wrap{T}(::Union{Type{Array},Type{Array{T}},Type{Array{T,1}}},
p::Ptr{T}, d::Integer, own::Bool=false)
ccall(:jl_ptr_to_array_1d, Vector{T},
ccall(:jl_ptr_to_array_1d, Array{T,1},
(Any, Ptr{Void}, Csize_t, Cint), Array{T,1}, p, d, own)
end
unsafe_wrap{N,I<:Integer}(Atype::Type, p::Ptr, dims::NTuple{N,I}, own::Bool=false) =
Expand Down Expand Up @@ -93,8 +93,8 @@ and makes a copy of the data.
"""
unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, len::Integer, own::Bool=false) =
ccall(:jl_array_to_string, Ref{String}, (Any,),
ccall(:jl_ptr_to_array_1d, Vector{UInt8}, (Any, Ptr{UInt8}, Csize_t, Cint),
Vector{UInt8}, p, len, own))
ccall(:jl_ptr_to_array_1d, Array{UInt8,1}, (Any, Ptr{UInt8}, Csize_t, Cint),
Array{UInt8,1}, p, len, own))
unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, own::Bool=false) =
unsafe_wrap(String, p, ccall(:strlen, Csize_t, (Ptr{UInt8},), p), own)

Expand Down
10 changes: 5 additions & 5 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ end
Get an array of the names exported by a `Module`, with optionally more `Module` globals
according to the additional parameters.
"""
names(m::Module, all::Bool=false, imported::Bool=false) = sort!(ccall(:jl_module_names, Array{Symbol,1}, (Any,Cint,Cint), m, all, imported))
names(m::Module, all::Bool=false, imported::Bool=false) = sort!(ccall(:jl_module_names, Array{Symbol,1}, (Any, Cint, Cint), m, all, imported))

isexported(m::Module, s::Symbol) = ccall(:jl_module_exports_p, Cint, (Any, Any), m, s) != 0
isdeprecated(m::Module, s::Symbol) = ccall(:jl_is_binding_deprecated, Cint, (Any, Any), m, s) != 0
Expand Down Expand Up @@ -364,12 +364,12 @@ function _methods_by_ftype(t::ANY, lim)
return _methods(Any[tp...], length(tp), lim, [])
end
# XXX: the following can return incorrect answers that the above branch would have corrected
return ccall(:jl_matching_methods, Any, (Any,Cint,Cint), t, lim, 0)
return ccall(:jl_matching_methods, Any, (Any, Cint, Cint), t, lim, 0)
end

function _methods(t::Array,i,lim::Integer,matching::Array{Any,1})
if i == 0
new = ccall(:jl_matching_methods, Any, (Any,Cint,Cint), Tuple{t...}, lim, 0)
new = ccall(:jl_matching_methods, Any, (Any, Cint, Cint), Tuple{t...}, lim, 0)
new === false && return false
append!(matching, new::Array{Any,1})
else
Expand Down Expand Up @@ -432,7 +432,7 @@ methods(f::Core.Builtin) = MethodList(Method[], typeof(f).name.mt)
function methods_including_ambiguous(f::ANY, t::ANY)
ft = isa(f,Type) ? Type{f} : typeof(f)
tt = isa(t,Type) ? Tuple{ft, t.parameters...} : Tuple{ft, t...}
ms = ccall(:jl_matching_methods, Any, (Any,Cint,Cint), tt, -1, 1)::Array{Any,1}
ms = ccall(:jl_matching_methods, Any, (Any, Cint, Cint), tt, -1, 1)::Array{Any,1}
return MethodList(Method[m[3] for m in ms], typeof(f).name.mt)
end
function methods(f::ANY)
Expand Down Expand Up @@ -521,7 +521,7 @@ function _dump_function(linfo::Core.MethodInstance, native::Bool, wrapper::Bool,

if native
str = ccall(:jl_dump_function_asm, Ref{String},
(Ptr{Void}, Cint, Cstring), llvmf, 0, syntax)
(Ptr{Void}, Cint, Ptr{UInt8}), llvmf, 0, syntax)
else
str = ccall(:jl_dump_function_ir, Ref{String},
(Ptr{Void}, Bool, Bool), llvmf, strip_ir_metadata, dump_module)
Expand Down
Loading

0 comments on commit 39680e3

Please sign in to comment.