Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cfunction tuple of types deprecation #23066

Merged
merged 3 commits into from
Aug 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ Deprecated or removed

* `Base.SparseArrays.SpDiagIterator` has been removed ([#23261]).

* The tuple-of-types form of `cfunction`, `cfunction(f, returntype, (types...))`, has been deprecated
in favor of the tuple-type form `cfunction(f, returntype, Tuple{types...})` ([#23066]).

* `diagm(A::SparseMatrixCSC)` has been deprecated in favor of
`spdiagm(sparsevec(A))` ([#23341]).

Expand Down
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,9 @@ export hex2num
# issue #17886
# deprecations for filter[!] with 2-arg functions are in associative.jl

# PR #23066
@deprecate cfunction(f, r, a::Tuple) cfunction(f, r, Tuple{a...})

# PR 23341
@deprecate diagm(A::SparseMatrixCSC) spdiagm(sparsevec(A))

Expand Down
6 changes: 3 additions & 3 deletions doc/src/manual/calling-c-and-fortran-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ Julia function. Arguments to [`cfunction()`](@ref) are as follows:
1. A Julia Function
2. Return type
3. A tuple of input types
3. A tuple type of input types
Only platform-default C calling convention is supported. `cfunction`-generated pointers cannot
be used in calls where WINAPI expects `stdcall` function on 32-bit windows, but can be used on WIN64
Expand Down Expand Up @@ -192,11 +192,11 @@ a C `int`, so we must be sure to return `Cint` via a call to `convert` and a `ty
In order to pass this function to C, we obtain its address using the function `cfunction`:

```jldoctest mycompare
julia> const mycompare_c = cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble}));
julia> const mycompare_c = cfunction(mycompare, Cint, Tuple{Ref{Cdouble}, Ref{Cdouble}});
```

[`cfunction()`](@ref) accepts three arguments: the Julia function (`mycompare`), the return type
(`Cint`), and a tuple of the argument types, in this case to sort an array of `Cdouble`
(`Cint`), and a tuple type of the input argument types, in this case to sort an array of `Cdouble`
([`Float64`](@ref)) elements.

The final call to `qsort` looks like this:
Expand Down
2 changes: 1 addition & 1 deletion examples/embedding/embedding.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ int main()
" nothing\n"
"end");
typedef void (*Func_VOID__VOID)(void);
jl_value_t *pbar = jl_eval_string("cfunction(bar_from_c, Void, ())");
jl_value_t *pbar = jl_eval_string("cfunction(bar_from_c, Void, Tuple{})");
Func_VOID__VOID bar = (Func_VOID__VOID)jl_unbox_voidpointer(pbar);
bar();
checked_eval_string("bar() = println(\"calling new bar\")");
Expand Down
4 changes: 0 additions & 4 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1422,10 +1422,6 @@ extern "C" JL_DLLEXPORT
void *jl_function_ptr(jl_function_t *f, jl_value_t *rt, jl_value_t *argt)
{
JL_GC_PUSH1(&argt);
if (jl_is_tuple(argt)) {
// TODO: maybe deprecation warning, better checking
argt = (jl_value_t*)jl_apply_tuple_type_v((jl_value_t**)jl_data_ptr(argt), jl_nfields(argt));
}
JL_LOCK(&codegen_lock);
Function *llvmf = jl_cfunction_object(f, rt, (jl_tupletype_t*)argt);
JL_GC_POP();
Expand Down
4 changes: 2 additions & 2 deletions test/ambiguous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ end
# Test that non-ambiguous cases work
io = IOBuffer()
@test precompile(ambig, (Int, Int)) == true
cfunction(ambig, Int, (Int, Int))
cfunction(ambig, Int, Tuple{Int, Int})
@test length(code_lowered(ambig, (Int, Int))) == 1
@test length(code_typed(ambig, (Int, Int))) == 1
code_llvm(io, ambig, (Int, Int))
code_native(io, ambig, (Int, Int))

# Test that ambiguous cases fail appropriately
@test precompile(ambig, (UInt8, Int)) == false
cfunction(ambig, Int, (UInt8, Int)) # test for a crash (doesn't throw an error)
cfunction(ambig, Int, Tuple{UInt8, Int}) # test for a crash (doesn't throw an error)
@test_throws ErrorException which(ambig, (UInt8, Int))
@test_throws ErrorException code_llvm(io, ambig, (UInt8, Int))
@test_throws ErrorException code_native(io, ambig, (UInt8, Int))
Expand Down
24 changes: 12 additions & 12 deletions test/ccall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -791,57 +791,57 @@ for (t,v) in ((Complex{Int32},:ci32),(Complex{Int64},:ci64),
function $fname(s)
@assert false
end
b = ccall(cfunction($fname1,Ref{$t},(Ref{$t},)),Ref{$t},(Ref{$t},),a)
b = ccall(cfunction($fname1, Ref{$t}, Tuple{Ref{$t}}), Ref{$t}, (Ref{$t},), a)
verbose && println("C: ",b)
@test b == $v
@test b === a
@test b === c
b = ccall(cfunction($fname,$t,($t,)),$t,($t,),a)
b = ccall(cfunction($fname, $t, Tuple{$t}), $t, ($t,), a)
verbose && println("C: ",b)
@test b == $v
if ($(t).mutable)
@test !(b === c)
@test !(b === a)
end
b = ccall(cfunction($fname1,$t,(Ref{$t},)),$t,(Ref{$t},),a)
b = ccall(cfunction($fname1, $t, Tuple{Ref{$t}}), $t, (Ref{$t},), a)
verbose && println("C: ",b)
@test b == $v
if ($(t).mutable)
@test !(b === c)
@test !(b === a)
end
b = ccall(cfunction($fname,Ref{$t},($t,)),Ref{$t},($t,),a)
b = ccall(cfunction($fname, Ref{$t}, Tuple{$t}), Ref{$t}, ($t,), a)
verbose && println("C: ",b)
@test b == $v
@test b === c
if ($(t).mutable)
@test !(b === a)
end
b = ccall(cfunction($fname,Any,(Ref{$t},)),Any,(Ref{$t},),$v)
b = ccall(cfunction($fname, Any, Tuple{Ref{$t}}), Any, (Ref{$t},), $v)
verbose && println("C: ",b)
@test b == $v
@test b === c
if ($(t).mutable)
@test !(b === a)
end
b = ccall(cfunction($fname,Any,(Ref{Any},)),Any,(Ref{Any},),$v)
b = ccall(cfunction($fname, Any, Tuple{Ref{Any}}), Any, (Ref{Any},), $v)
@test b == $v
@test b === c
if ($(t).mutable)
@test !(b === a)
end
@test_throws TypeError ccall(cfunction($fname,Ref{AbstractString},(Ref{Any},)),Any,(Ref{Any},),$v)
@test_throws TypeError ccall(cfunction($fname,AbstractString,(Ref{Any},)),Any,(Ref{Any},),$v)
@test_throws TypeError ccall(cfunction($fname, Ref{AbstractString}, Tuple{Ref{Any}}), Any, (Ref{Any},), $v)
@test_throws TypeError ccall(cfunction($fname, AbstractString, Tuple{Ref{Any}}), Any, (Ref{Any},), $v)
end
end

# issue 13031
foo13031(x) = Cint(1)
foo13031p = cfunction(foo13031, Cint, (Ref{Tuple{}},))
foo13031p = cfunction(foo13031, Cint, Tuple{Ref{Tuple{}}})
ccall(foo13031p, Cint, (Ref{Tuple{}},), ())

foo13031(x,y,z) = z
foo13031p = cfunction(foo13031, Cint, (Ref{Tuple{}},Ref{Tuple{}},Cint))
foo13031p = cfunction(foo13031, Cint, Tuple{Ref{Tuple{}}, Ref{Tuple{}}, Cint})
ccall(foo13031p, Cint, (Ref{Tuple{}},Ref{Tuple{}},Cint), (), (), 8)

# issue 17219
Expand Down Expand Up @@ -993,7 +993,7 @@ if Sys.ARCH === :x86_64
T = NTuple{4, VecElement{s}}
@eval function rt_sse(a1::$T, a2::$T, a3::$T, a4::$T)
return ccall(
cfunction(foo_ams, $T, ($T, $T, $T, $T)),
cfunction(foo_ams, $T, Tuple{$T, $T, $T, $T}),
$T,
($T, $T, $T, $T),
a1, a2, a3, a4)
Expand Down Expand Up @@ -1281,7 +1281,7 @@ end
evalf_callback_19805(ci::callinfos_19805{FUNC_FT}) where {FUNC_FT} = ci.f(0.5)::Float64

evalf_callback_c_19805(ci::callinfos_19805{FUNC_FT}) where {FUNC_FT} = cfunction(
evalf_callback_19805, Float64, (callinfos_19805{FUNC_FT},))
evalf_callback_19805, Float64, Tuple{callinfos_19805{FUNC_FT}})

@test_throws(ErrorException("ccall: the type of argument 1 doesn't correspond to a C type"),
evalf_callback_c_19805( callinfos_19805(sin) ))
Expand Down
2 changes: 1 addition & 1 deletion test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4404,7 +4404,7 @@ end
function f18054()
return Cint(0)
end
cfunction(f18054, Cint, ())
cfunction(f18054, Cint, Tuple{})

# issue #18986: the ccall optimization of cfunction leaves JL_TRY stack in bad state
dummy18996() = return nothing
Expand Down
2 changes: 1 addition & 1 deletion test/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ if Sys.iswindows()
x+y
end

let addr = cfunction(WeVirtualProtectThisToRWX, UInt64, (UInt64, UInt64))
let addr = cfunction(WeVirtualProtectThisToRWX, UInt64, Tuple{UInt64, UInt64})
addr = addr-(UInt64(addr)%4096)
PAGE_EXECUTE_READWRITE = 0x40
oldPerm = Ref{UInt32}()
Expand Down
4 changes: 2 additions & 2 deletions test/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ end
tracefoo(x, y) = x+y
didtrace = false
tracer(x::Ptr{Void}) = (@test isa(unsafe_pointer_to_objref(x), Core.MethodInstance); global didtrace = true; nothing)
ccall(:jl_register_method_tracer, Void, (Ptr{Void},), cfunction(tracer, Void, (Ptr{Void},)))
ccall(:jl_register_method_tracer, Void, (Ptr{Void},), cfunction(tracer, Void, Tuple{Ptr{Void}}))
meth = which(tracefoo,Tuple{Any,Any})
ccall(:jl_trace_method, Void, (Any,), meth)
@test tracefoo(1, 2) == 3
Expand All @@ -508,7 +508,7 @@ ccall(:jl_register_method_tracer, Void, (Ptr{Void},), C_NULL)

# Method Tracing test
methtracer(x::Ptr{Void}) = (@test isa(unsafe_pointer_to_objref(x), Method); global didtrace = true; nothing)
ccall(:jl_register_newmeth_tracer, Void, (Ptr{Void},), cfunction(methtracer, Void, (Ptr{Void},)))
ccall(:jl_register_newmeth_tracer, Void, (Ptr{Void},), cfunction(methtracer, Void, Tuple{Ptr{Void}}))
tracefoo2(x, y) = x*y
@test didtrace
didtrace = false
Expand Down
2 changes: 1 addition & 1 deletion test/spawn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ let fname = tempname()
oldhandle = OLD_STDERR.handle
OLD_STDERR.status = Base.StatusClosing
OLD_STDERR.handle = C_NULL
ccall(:uv_close, Void, (Ptr{Void}, Ptr{Void}), oldhandle, cfunction(thrash, Void, (Ptr{Void},)))
ccall(:uv_close, Void, (Ptr{Void}, Ptr{Void}), oldhandle, cfunction(thrash, Void, Tuple{Ptr{Void}}))
sleep(1)
import Base.zzzInvalidIdentifier
"""
Expand Down
2 changes: 1 addition & 1 deletion test/staged.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ module TestGeneratedThrow
foo() = (bar(rand() > 0.5 ? 1 : 1.0); error("foo"))
function __init__()
code_typed(foo,(); optimize = false)
cfunction(foo,Void,())
cfunction(foo,Void,Tuple{})
end
end

Expand Down