Skip to content

Commit 7aaef28

Browse files
committed
Finish effects implementation for ccall
1 parent 0a49a5f commit 7aaef28

File tree

4 files changed

+27
-11
lines changed

4 files changed

+27
-11
lines changed

base/c.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ function ccall_macro_parse(expr::Expr)
639639
end
640640

641641

642-
function ccall_macro_lower(convention, func, rettype, types, args, nreq)
642+
function ccall_macro_lower(convention, effects, func, rettype, types, args, nreq)
643643
lowering = []
644644
realargs = []
645645
gcroots = []
@@ -676,7 +676,7 @@ function ccall_macro_lower(convention, func, rettype, types, args, nreq)
676676
esc(etypes),
677677
nreq,
678678
QuoteNode(convention),
679-
nothing,
679+
effects,
680680
realargs..., gcroots...)
681681
push!(lowering, exp)
682682

@@ -732,5 +732,9 @@ The string literal could also be used directly before the function
732732
name, if desired `"libglib-2.0".g_uri_escape_string(...`
733733
"""
734734
macro ccall(expr)
735-
return ccall_macro_lower(:ccall, ccall_macro_parse(expr)...)
735+
return ccall_macro_lower(:ccall, nothing, ccall_macro_parse(expr)...)
736+
end
737+
738+
macro ccall_effects(effects, expr)
739+
return ccall_macro_lower(:ccall, effects, ccall_macro_parse(expr)...)
736740
end

base/compiler/types.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ function encode_effects_override(eo::EffectsOverride)
6868
e = 0x00
6969
eo.consistent && (e |= 0x01)
7070
eo.effect_free && (e |= 0x02)
71-
eo.nothrow && (e |= 0x02)
72-
eo.terminates && (e |= 0x04)
73-
eo.terminates_locally && (e |= 0x08)
71+
eo.nothrow && (e |= 0x04)
72+
eo.terminates && (e |= 0x08)
73+
eo.terminates_locally && (e |= 0x10)
7474
e
7575
end
7676

@@ -82,7 +82,6 @@ decode_effects_override(e::UInt8) =
8282
(e >> 3) & 0x01 != 0x00,
8383
(e >> 4) & 0x01 != 0x00)
8484

85-
8685
"""
8786
InferenceResult
8887

base/expr.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,14 @@ macro assume_effects(args...)
520520
end
521521
end
522522
ex = args[end]
523-
isa(ex, Expr) || ArgumentError("Bad expression `$ex` in @constprop [settings] ex")
523+
isa(ex, Expr) || throw(ArgumentError("Bad expression `$ex` in @constprop [settings] ex"))
524+
if ex.head === :macrocall && ex.args[1] == Symbol("@ccall")
525+
ex.args[1] = GlobalRef(Base, Symbol("@ccall_effects"))
526+
insert!(ex.args, 3, Core.Compiler.encode_effects_override(Core.Compiler.EffectsOverride(
527+
consistent, effect_free, nothrow, terminates_globally, terminates_locally
528+
)))
529+
return esc(ex)
530+
end
524531
return pushmeta!(ex, :purity, consistent, effect_free, nothrow, terminates_globally, terminates_locally)
525532
end
526533

test/ccall.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ end
3636
Core.svec(Ptr{Ptr{Cchar}}, Cstring,
3737
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
3838
Cfloat, Cfloat, Cfloat, Cfloat, Cfloat, Cfloat, Cfloat, Cfloat, Cfloat),
39-
2, :(:cdecl),
39+
2, :(:cdecl), nothing,
4040
:(Base.unsafe_convert(Ptr{Ptr{Cchar}}, strp)), :(Base.unsafe_convert(Cstring, fmt)),
4141
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
4242
Cfloat(1.1), Cfloat(2.2), Cfloat(3.3), Cfloat(4.4), Cfloat(5.5), Cfloat(6.6), Cfloat(7.7), Cfloat(8.8), Cfloat(9.9),
@@ -1676,7 +1676,7 @@ using Base: ccall_macro_parse, ccall_macro_lower
16761676
end
16771677

16781678
@testset "ensure the base-case of @ccall works, including library name and pointer interpolation" begin
1679-
call = ccall_macro_lower(:ccall, ccall_macro_parse( :( libstring.func(
1679+
call = ccall_macro_lower(:ccall, nothing, ccall_macro_parse( :( libstring.func(
16801680
str::Cstring,
16811681
num1::Cint,
16821682
num2::Cint
@@ -1700,7 +1700,7 @@ end
17001700
end)
17011701

17021702
# pointer interpolation
1703-
call = ccall_macro_lower(:ccall, ccall_macro_parse(:( $(Expr(:$, :fptr))("bar"::Cstring)::Cvoid ))...)
1703+
call = ccall_macro_lower(:ccall, nothing, ccall_macro_parse(:( $(Expr(:$, :fptr))("bar"::Cstring)::Cvoid ))...)
17041704
@test Base.remove_linenums!(call) == Base.remove_linenums!(
17051705
quote
17061706
func = $(Expr(:escape, :fptr))
@@ -1852,3 +1852,9 @@ end
18521852
@test cglobal33413_literal() != C_NULL
18531853
@test cglobal33413_literal_notype() != C_NULL
18541854
end
1855+
1856+
@testset "ccall_effects" begin
1857+
ctest_total(x) = @Base.assume_effects :total @ccall libccalltest.ctest(x::Complex{Int})::Complex{Int}
1858+
ctest_total_const() = Val{ctest_total(1 + 2im)}()
1859+
Core.Compiler.return_type(ctest_total_const, Tuple{}) == Val{2 + 0im}
1860+
end

0 commit comments

Comments
 (0)