-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
c_abi_spec.cr
135 lines (114 loc) · 2.77 KB
/
c_abi_spec.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
require "../../spec_helper"
# These specs just test that building code that passes and
# returns structs generates valid LLVM code
describe "Code gen: C ABI" do
it "passes struct less than 64 bits as { i64 }" do
mod = build(%(
lib LibC
struct Struct
x : Int8
y : Int16
end
fun foo(s : Struct)
end
s = LibC::Struct.new
LibC.foo(s)
)).first_value
str = mod.to_s
str.should contain("call void @foo({ i64 }")
str.should contain("declare void @foo({ i64 })")
end
it "passes struct less than 64 bits as { i64 } in varargs" do
mod = build(%(
lib LibC
struct Struct
x : Int8
y : Int16
end
fun foo(...)
end
s = LibC::Struct.new
LibC.foo(s)
)).first_value
str = mod.to_s
str.should contain("call void (...)* @foo({ i64 }")
end
it "passes struct between 64 and 128 bits as { i64, i64 }" do
mod = build(%(
lib LibC
struct Struct
x : Int64
y : Int16
end
fun foo(s : Struct)
end
s = LibC::Struct.new
LibC.foo(s)
)).first_value
str = mod.to_s
str.should contain("call void @foo({ i64, i64 }")
str.should contain("declare void @foo({ i64, i64 })")
end
it "passes struct bigger than128 bits with byval" do
mod = build(%(
lib LibC
struct Struct
x : Int64
y : Int64
z : Int8
end
fun foo(s : Struct)
end
s = LibC::Struct.new
LibC.foo(s)
)).first_value
str = mod.to_s
str.scan(/byval/).length.should eq(2)
end
it "returns struct less than 64 bits as { i64 }" do
mod = build(%(
lib LibC
struct Struct
x : Int8
y : Int16
end
fun foo : Struct
end
str = LibC.foo
)).first_value
str = mod.to_s
str.should contain("call { i64 } @foo()")
str.should contain("declare { i64 } @foo()")
end
it "returns struct between 64 and 128 bits as { i64, i64 }" do
mod = build(%(
lib LibC
struct Struct
x : Int64
y : Int16
end
fun foo : Struct
end
str = LibC.foo
)).first_value
str = mod.to_s
str.should contain("call { i64, i64 } @foo()")
str.should contain("declare { i64, i64 } @foo()")
end
it "returns struct bigger than 128 bits with sret" do
mod = build(%(
lib LibC
struct Struct
x : Int64
y : Int64
z : Int8
end
fun foo(w : Int32) : Struct
end
str = LibC.foo(1)
)).first_value
str = mod.to_s
str.scan(/sret/).length.should eq(2)
str.should contain("sret, i32") # sret goes as first argument
end
end