Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/object/tests/basic.rs
1692 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
fn switch_error() {
77
use cranelift_codegen::settings;
78
79
let sig = Signature {
80
params: vec![AbiParam::new(types::I32)],
81
returns: vec![AbiParam::new(types::I32)],
82
call_conv: CallConv::SystemV,
83
};
84
85
let mut func = Function::with_name_signature(UserFuncName::default(), sig);
86
let mut func_ctx = FunctionBuilderContext::new();
87
{
88
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut func, &mut func_ctx);
89
let start = bcx.create_block();
90
let bb0 = bcx.create_block();
91
let bb1 = bcx.create_block();
92
let bb2 = bcx.create_block();
93
let bb3 = bcx.create_block();
94
println!("{start} {bb0} {bb1} {bb2} {bb3}");
95
96
bcx.declare_var(types::I32);
97
bcx.declare_var(types::I32);
98
let in_val = bcx.append_block_param(start, types::I32);
99
bcx.switch_to_block(start);
100
bcx.def_var(Variable::new(0), in_val);
101
bcx.ins().jump(bb0, &[]);
102
103
bcx.switch_to_block(bb0);
104
let discr = bcx.use_var(Variable::new(0));
105
let mut switch = cranelift_frontend::Switch::new();
106
for &(index, bb) in &[
107
(9, bb1),
108
(13, bb1),
109
(10, bb1),
110
(92, bb1),
111
(39, bb1),
112
(34, bb1),
113
] {
114
switch.set_entry(index, bb);
115
}
116
switch.emit(&mut bcx, discr, bb2);
117
118
bcx.switch_to_block(bb1);
119
let v = bcx.use_var(Variable::new(0));
120
bcx.def_var(Variable::new(1), v);
121
bcx.ins().jump(bb3, &[]);
122
123
bcx.switch_to_block(bb2);
124
let v = bcx.use_var(Variable::new(0));
125
bcx.def_var(Variable::new(1), v);
126
bcx.ins().jump(bb3, &[]);
127
128
bcx.switch_to_block(bb3);
129
let r = bcx.use_var(Variable::new(1));
130
bcx.ins().return_(&[r]);
131
132
bcx.seal_all_blocks();
133
bcx.finalize();
134
}
135
136
let flags = settings::Flags::new(settings::builder());
137
match cranelift_codegen::verify_function(&func, &flags) {
138
Ok(_) => {}
139
Err(err) => {
140
let pretty_error =
141
cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err);
142
panic!("pretty_error:\n{pretty_error}");
143
}
144
}
145
}
146
147
#[test]
148
fn libcall_function() {
149
let flag_builder = settings::builder();
150
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
151
let isa = isa_builder
152
.finish(settings::Flags::new(flag_builder))
153
.unwrap();
154
let mut module =
155
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
156
157
let sig = Signature {
158
params: vec![],
159
returns: vec![],
160
call_conv: CallConv::SystemV,
161
};
162
163
let func_id = module
164
.declare_function("function", Linkage::Local, &sig)
165
.unwrap();
166
167
let mut ctx = Context::new();
168
ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);
169
let mut func_ctx = FunctionBuilderContext::new();
170
{
171
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
172
let block = bcx.create_block();
173
bcx.switch_to_block(block);
174
175
let int = module.target_config().pointer_type();
176
let zero = bcx.ins().iconst(I16, 0);
177
let size = bcx.ins().iconst(int, 10);
178
179
let mut signature = module.make_signature();
180
signature.params.push(AbiParam::new(int));
181
signature.returns.push(AbiParam::new(int));
182
let callee = module
183
.declare_function("malloc", Linkage::Import, &signature)
184
.expect("declare malloc function");
185
let local_callee = module.declare_func_in_func(callee, &mut bcx.func);
186
let argument_exprs = vec![size];
187
let call = bcx.ins().call(local_callee, &argument_exprs);
188
let buffer = bcx.inst_results(call)[0];
189
190
bcx.call_memset(module.target_config(), buffer, zero, size);
191
192
bcx.ins().return_(&[]);
193
}
194
195
module.define_function(func_id, &mut ctx).unwrap();
196
197
module.finish();
198
}
199
200
#[test]
201
#[should_panic(expected = "has a null byte, which is disallowed")]
202
fn reject_nul_byte_symbol_for_func() {
203
let flag_builder = settings::builder();
204
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
205
let isa = isa_builder
206
.finish(settings::Flags::new(flag_builder))
207
.unwrap();
208
let mut module =
209
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
210
211
let sig = Signature {
212
params: vec![],
213
returns: vec![],
214
call_conv: CallConv::SystemV,
215
};
216
217
let _ = module
218
.declare_function("function\u{0}with\u{0}nul\u{0}bytes", Linkage::Local, &sig)
219
.unwrap();
220
}
221
222
#[test]
223
#[should_panic(expected = "has a null byte, which is disallowed")]
224
fn reject_nul_byte_symbol_for_data() {
225
let flag_builder = settings::builder();
226
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
227
let isa = isa_builder
228
.finish(settings::Flags::new(flag_builder))
229
.unwrap();
230
let mut module =
231
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
232
233
let _ = module
234
.declare_data(
235
"data\u{0}with\u{0}nul\u{0}bytes",
236
Linkage::Local,
237
/* writable = */ true,
238
/* tls = */ false,
239
)
240
.unwrap();
241
}
242
243