Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/object/tests/basic.rs
3063 views
1
use cranelift_codegen::ir::*;
2
use cranelift_codegen::isa::CallConv;
3
use cranelift_codegen::settings;
4
use cranelift_codegen::{Context, ir::types::I16};
5
use cranelift_entity::EntityRef;
6
use cranelift_frontend::*;
7
use cranelift_module::*;
8
use cranelift_object::*;
9
10
#[test]
11
fn error_on_incompatible_sig_in_declare_function() {
12
let flag_builder = settings::builder();
13
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
14
let isa = isa_builder
15
.finish(settings::Flags::new(flag_builder))
16
.unwrap();
17
let mut module =
18
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
19
let mut sig = Signature {
20
params: vec![AbiParam::new(types::I64)],
21
returns: vec![],
22
call_conv: CallConv::SystemV,
23
};
24
module
25
.declare_function("abc", Linkage::Local, &sig)
26
.unwrap();
27
sig.params[0] = AbiParam::new(types::I32);
28
module
29
.declare_function("abc", Linkage::Local, &sig)
30
.err()
31
.unwrap(); // Make sure this is an error
32
}
33
34
fn define_simple_function(module: &mut ObjectModule) -> FuncId {
35
let sig = Signature {
36
params: vec![],
37
returns: vec![],
38
call_conv: CallConv::SystemV,
39
};
40
41
let func_id = module
42
.declare_function("abc", Linkage::Local, &sig)
43
.unwrap();
44
45
let mut ctx = Context::new();
46
ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);
47
let mut func_ctx = FunctionBuilderContext::new();
48
{
49
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
50
let block = bcx.create_block();
51
bcx.switch_to_block(block);
52
bcx.ins().return_(&[]);
53
}
54
55
module.define_function(func_id, &mut ctx).unwrap();
56
57
func_id
58
}
59
60
#[test]
61
#[should_panic(expected = "Result::unwrap()` on an `Err` value: DuplicateDefinition(\"abc\")")]
62
fn panic_on_define_after_finalize() {
63
let flag_builder = settings::builder();
64
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
65
let isa = isa_builder
66
.finish(settings::Flags::new(flag_builder))
67
.unwrap();
68
let mut module =
69
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
70
71
define_simple_function(&mut module);
72
define_simple_function(&mut module);
73
}
74
75
#[test]
76
#[cfg_attr(not(debug_assertions), ignore = "checks a debug assertion")]
77
#[should_panic(expected = "function \"abc\" with linkage Local must be defined but is not")]
78
fn panic_on_declare_without_define() {
79
let flag_builder = settings::builder();
80
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
81
let isa = isa_builder
82
.finish(settings::Flags::new(flag_builder))
83
.unwrap();
84
let mut module =
85
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
86
87
module
88
.declare_function("abc", Linkage::Local, &Signature::new(CallConv::SystemV))
89
.unwrap();
90
91
module.finish();
92
}
93
94
#[test]
95
fn switch_error() {
96
use cranelift_codegen::settings;
97
98
let sig = Signature {
99
params: vec![AbiParam::new(types::I32)],
100
returns: vec![AbiParam::new(types::I32)],
101
call_conv: CallConv::SystemV,
102
};
103
104
let mut func = Function::with_name_signature(UserFuncName::default(), sig);
105
let mut func_ctx = FunctionBuilderContext::new();
106
{
107
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut func, &mut func_ctx);
108
let start = bcx.create_block();
109
let bb0 = bcx.create_block();
110
let bb1 = bcx.create_block();
111
let bb2 = bcx.create_block();
112
let bb3 = bcx.create_block();
113
println!("{start} {bb0} {bb1} {bb2} {bb3}");
114
115
bcx.declare_var(types::I32);
116
bcx.declare_var(types::I32);
117
let in_val = bcx.append_block_param(start, types::I32);
118
bcx.switch_to_block(start);
119
bcx.def_var(Variable::new(0), in_val);
120
bcx.ins().jump(bb0, &[]);
121
122
bcx.switch_to_block(bb0);
123
let discr = bcx.use_var(Variable::new(0));
124
let mut switch = cranelift_frontend::Switch::new();
125
for &(index, bb) in &[
126
(9, bb1),
127
(13, bb1),
128
(10, bb1),
129
(92, bb1),
130
(39, bb1),
131
(34, bb1),
132
] {
133
switch.set_entry(index, bb);
134
}
135
switch.emit(&mut bcx, discr, bb2);
136
137
bcx.switch_to_block(bb1);
138
let v = bcx.use_var(Variable::new(0));
139
bcx.def_var(Variable::new(1), v);
140
bcx.ins().jump(bb3, &[]);
141
142
bcx.switch_to_block(bb2);
143
let v = bcx.use_var(Variable::new(0));
144
bcx.def_var(Variable::new(1), v);
145
bcx.ins().jump(bb3, &[]);
146
147
bcx.switch_to_block(bb3);
148
let r = bcx.use_var(Variable::new(1));
149
bcx.ins().return_(&[r]);
150
151
bcx.seal_all_blocks();
152
bcx.finalize();
153
}
154
155
let flags = settings::Flags::new(settings::builder());
156
match cranelift_codegen::verify_function(&func, &flags) {
157
Ok(_) => {}
158
Err(err) => {
159
let pretty_error =
160
cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err);
161
panic!("pretty_error:\n{pretty_error}");
162
}
163
}
164
}
165
166
#[test]
167
fn libcall_function() {
168
let flag_builder = settings::builder();
169
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
170
let isa = isa_builder
171
.finish(settings::Flags::new(flag_builder))
172
.unwrap();
173
let mut module =
174
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
175
176
let sig = Signature {
177
params: vec![],
178
returns: vec![],
179
call_conv: CallConv::SystemV,
180
};
181
182
let func_id = module
183
.declare_function("function", Linkage::Local, &sig)
184
.unwrap();
185
186
let mut ctx = Context::new();
187
ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);
188
let mut func_ctx = FunctionBuilderContext::new();
189
{
190
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
191
let block = bcx.create_block();
192
bcx.switch_to_block(block);
193
194
let int = module.target_config().pointer_type();
195
let zero = bcx.ins().iconst(I16, 0);
196
let size = bcx.ins().iconst(int, 10);
197
198
let mut signature = module.make_signature();
199
signature.params.push(AbiParam::new(int));
200
signature.returns.push(AbiParam::new(int));
201
let callee = module
202
.declare_function("malloc", Linkage::Import, &signature)
203
.expect("declare malloc function");
204
let local_callee = module.declare_func_in_func(callee, &mut bcx.func);
205
let argument_exprs = vec![size];
206
let call = bcx.ins().call(local_callee, &argument_exprs);
207
let buffer = bcx.inst_results(call)[0];
208
209
bcx.call_memset(module.target_config(), buffer, zero, size);
210
211
bcx.ins().return_(&[]);
212
}
213
214
module.define_function(func_id, &mut ctx).unwrap();
215
216
module.finish();
217
}
218
219
#[test]
220
#[should_panic(expected = "has a null byte, which is disallowed")]
221
fn reject_nul_byte_symbol_for_func() {
222
let flag_builder = settings::builder();
223
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
224
let isa = isa_builder
225
.finish(settings::Flags::new(flag_builder))
226
.unwrap();
227
let mut module =
228
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
229
230
let sig = Signature {
231
params: vec![],
232
returns: vec![],
233
call_conv: CallConv::SystemV,
234
};
235
236
let _ = module
237
.declare_function("function\u{0}with\u{0}nul\u{0}bytes", Linkage::Local, &sig)
238
.unwrap();
239
}
240
241
#[test]
242
#[should_panic(expected = "has a null byte, which is disallowed")]
243
fn reject_nul_byte_symbol_for_data() {
244
let flag_builder = settings::builder();
245
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
246
let isa = isa_builder
247
.finish(settings::Flags::new(flag_builder))
248
.unwrap();
249
let mut module =
250
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
251
252
let _ = module
253
.declare_data(
254
"data\u{0}with\u{0}nul\u{0}bytes",
255
Linkage::Local,
256
/* writable = */ true,
257
/* tls = */ false,
258
)
259
.unwrap();
260
}
261
262