Open zhuxiujia opened 3 years ago
This demo doesn't support that but adding the functionality wouldn't be too bad. In Cranelift you can make foreign calls to libc functions without too much trouble. See here for where I do that in my Cranelift Lisp.
Once you've got foreign calls working you could concatenate two strings the same way you normally would in C with calls to strcat
and friends.
You can define anonymous string like this:
fn create_anonymous_string(&mut self, string_content: &str) -> Value {
self.data_ctx.define(string_content.as_bytes().to_vec().into_boxed_slice());
let sym = self
.module
.declare_anonymous_data(true, false)
.expect("problem declaring data object");
let _result = self.module
.define_data(sym, &self.data_ctx)
.map_err(|e| e.to_string());
let local_id = self
.module
.declare_data_in_func(sym, &mut self.builder.func);
self.data_ctx.clear();
let pointer = self.module.target_config().pointer_type();
self.builder.ins().symbol_value(pointer, local_id)
}
Call this like:
let mut string_content_with_terminator = string_content.to_owned();
string_content_with_terminator.push('\0');
let symbol = self.create_anonymous_string(&string_content_with_terminator);
The string data created by the above function can be concatenated by using C functions as @ezekiiel said.
// anonymous string1
let value1 = self.translate_expr(expr1);
// anonymous string2
let value2 = self.translate_expr(expr2);
let len1 = self.get_str_len(value1);
let len2 = self.get_str_len(value2);
let len_both = self.builder.ins().iadd(len1, len2);
let one = self.builder.ins().iconst(self.int, 1);
let len_both = self.builder.ins().iadd(len_both, one);
let location = self.malloc(len_both);
self.strcpy(location, value1);
self.strcat(location, value2);
Each C function is called like this:
fn get_str_len(&mut self, val: Value) -> Value {
let mut sig = self.module.make_signature();
let word = self.module.target_config().pointer_type();
sig.params.push(AbiParam::new(word));
sig.returns.push(AbiParam::new(word));
let callee = self.module
.declare_function("strlen", cranelift_module::Linkage::Import, &sig)
.map_err(|e| e.to_string()).unwrap();
let local_callee = self.module
.declare_func_in_func(callee, &mut self.builder.func);
let arg = val;
let args = vec![arg];
let call = self.builder.ins().call(local_callee, &args);
self.builder.inst_results(call)[0]
}
fn malloc(&mut self, size: Value) -> Value {
let mut sig = self.module.make_signature();
let word = self.module.target_config().pointer_type();
sig.params.push(AbiParam::new(word));
sig.returns.push(AbiParam::new(word));
let callee = self.module
.declare_function("malloc", cranelift_module::Linkage::Import, &sig)
.map_err(|e| e.to_string()).unwrap();
let local_callee = self.module
.declare_func_in_func(callee, &mut self.builder.func);
let args = vec![size];
let call = self.builder.ins().call(local_callee, &args);
self.builder.inst_results(call)[0]
}
fn strcpy(&mut self, message_buf: Value, message: Value) {
let mut sig = self.module.make_signature();
let word = self.module.target_config().pointer_type();
sig.params.push(AbiParam::new(word));
sig.params.push(AbiParam::new(word));
let callee = self.module
.declare_function("strcpy", cranelift_module::Linkage::Import, &sig)
.map_err(|e| e.to_string()).unwrap();
let local_callee = self.module
.declare_func_in_func(callee, &mut self.builder.func);
let args = vec![message_buf, message];
let _call = self.builder.ins().call(local_callee, &args);
}
fn strcat(&mut self, message_buf: Value, message: Value) {
let mut sig = self.module.make_signature();
let word = self.module.target_config().pointer_type();
sig.params.push(AbiParam::new(word));
sig.params.push(AbiParam::new(word));
let callee = self.module
.declare_function("strcat", cranelift_module::Linkage::Import, &sig)
.map_err(|e| e.to_string()).unwrap();
let local_callee = self.module
.declare_func_in_func(callee, &mut self.builder.func);
let args = vec![message_buf, message];
let _call = self.builder.ins().call(local_callee, &args);
}
Hello, I am a beginner wasm how do I concatenate strings? Send string?in this jit-demo