Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/jit/tests/basic.rs
1693 views
1
use cranelift_codegen::ir::*;
2
use cranelift_codegen::isa::{CallConv, OwnedTargetIsa};
3
use cranelift_codegen::settings::{self, Configurable};
4
use cranelift_codegen::{Context, ir::types::I16};
5
use cranelift_entity::EntityRef;
6
use cranelift_frontend::*;
7
use cranelift_jit::*;
8
use cranelift_module::*;
9
10
fn isa() -> Option<OwnedTargetIsa> {
11
let mut flag_builder = settings::builder();
12
flag_builder.set("use_colocated_libcalls", "false").unwrap();
13
// FIXME set back to true once the x64 backend supports it.
14
flag_builder.set("is_pic", "false").unwrap();
15
let isa_builder = cranelift_native::builder().ok()?;
16
isa_builder.finish(settings::Flags::new(flag_builder)).ok()
17
}
18
19
#[test]
20
fn error_on_incompatible_sig_in_declare_function() {
21
let Some(isa) = isa() else {
22
return;
23
};
24
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
25
26
let mut sig = Signature {
27
params: vec![AbiParam::new(types::I64)],
28
returns: vec![],
29
call_conv: CallConv::SystemV,
30
};
31
module
32
.declare_function("abc", Linkage::Local, &sig)
33
.unwrap();
34
sig.params[0] = AbiParam::new(types::I32);
35
module
36
.declare_function("abc", Linkage::Local, &sig)
37
.err()
38
.unwrap(); // Make sure this is an error
39
}
40
41
fn define_simple_function(module: &mut JITModule) -> Result<FuncId, ModuleError> {
42
let sig = Signature {
43
params: vec![],
44
returns: vec![],
45
call_conv: CallConv::SystemV,
46
};
47
48
let func_id = module.declare_function("abc", Linkage::Local, &sig)?;
49
50
let mut ctx = Context::new();
51
ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);
52
let mut func_ctx = FunctionBuilderContext::new();
53
{
54
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
55
let block = bcx.create_block();
56
bcx.switch_to_block(block);
57
bcx.ins().return_(&[]);
58
}
59
60
module.define_function(func_id, &mut ctx)?;
61
62
Ok(func_id)
63
}
64
65
#[test]
66
fn panic_on_define_after_finalize() {
67
let Some(isa) = isa() else {
68
return;
69
};
70
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
71
72
define_simple_function(&mut module).unwrap();
73
define_simple_function(&mut module).err().unwrap();
74
}
75
76
#[test]
77
fn switch_error() {
78
use cranelift_codegen::settings;
79
80
let sig = Signature {
81
params: vec![AbiParam::new(types::I32)],
82
returns: vec![AbiParam::new(types::I32)],
83
call_conv: CallConv::SystemV,
84
};
85
86
let mut func = Function::with_name_signature(UserFuncName::default(), sig);
87
88
let mut func_ctx = FunctionBuilderContext::new();
89
{
90
let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut func, &mut func_ctx);
91
let start = bcx.create_block();
92
let bb0 = bcx.create_block();
93
let bb1 = bcx.create_block();
94
let bb2 = bcx.create_block();
95
let bb3 = bcx.create_block();
96
println!("{start} {bb0} {bb1} {bb2} {bb3}");
97
98
bcx.declare_var(types::I32);
99
bcx.declare_var(types::I32);
100
let in_val = bcx.append_block_param(start, types::I32);
101
bcx.switch_to_block(start);
102
bcx.def_var(Variable::new(0), in_val);
103
bcx.ins().jump(bb0, &[]);
104
105
bcx.switch_to_block(bb0);
106
let discr = bcx.use_var(Variable::new(0));
107
let mut switch = cranelift_frontend::Switch::new();
108
for &(index, bb) in &[
109
(9, bb1),
110
(13, bb1),
111
(10, bb1),
112
(92, bb1),
113
(39, bb1),
114
(34, bb1),
115
] {
116
switch.set_entry(index, bb);
117
}
118
switch.emit(&mut bcx, discr, bb2);
119
120
bcx.switch_to_block(bb1);
121
let v = bcx.use_var(Variable::new(0));
122
bcx.def_var(Variable::new(1), v);
123
bcx.ins().jump(bb3, &[]);
124
125
bcx.switch_to_block(bb2);
126
let v = bcx.use_var(Variable::new(0));
127
bcx.def_var(Variable::new(1), v);
128
bcx.ins().jump(bb3, &[]);
129
130
bcx.switch_to_block(bb3);
131
let r = bcx.use_var(Variable::new(1));
132
bcx.ins().return_(&[r]);
133
134
bcx.seal_all_blocks();
135
bcx.finalize();
136
}
137
138
let flags = settings::Flags::new(settings::builder());
139
match cranelift_codegen::verify_function(&func, &flags) {
140
Ok(_) => {}
141
Err(err) => {
142
let pretty_error =
143
cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err);
144
panic!("pretty_error:\n{pretty_error}");
145
}
146
}
147
}
148
149
#[test]
150
fn libcall_function() {
151
let Some(isa) = isa() else {
152
return;
153
};
154
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
155
156
let sig = Signature {
157
params: vec![],
158
returns: vec![],
159
call_conv: CallConv::SystemV,
160
};
161
162
let func_id = module
163
.declare_function("function", Linkage::Local, &sig)
164
.unwrap();
165
166
let mut ctx = Context::new();
167
ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);
168
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
196
.define_function_with_control_plane(func_id, &mut ctx, &mut Default::default())
197
.unwrap();
198
199
module.finalize_definitions().unwrap();
200
}
201
202
// This used to cause UB. See https://github.com/bytecodealliance/wasmtime/issues/7918.
203
#[test]
204
fn empty_data_object() {
205
let Some(isa) = isa() else {
206
return;
207
};
208
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
209
210
let data_id = module
211
.declare_data("empty", Linkage::Export, false, false)
212
.unwrap();
213
214
let mut data = DataDescription::new();
215
data.define(Box::new([]));
216
module.define_data(data_id, &data).unwrap();
217
}
218
219