Skip to content

Commit

Permalink
Use the new Pointer and Length types.
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Feb 20, 2024
1 parent d679d1a commit a939252
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 43 deletions.
10 changes: 8 additions & 2 deletions crates/c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2205,12 +2205,15 @@ impl Bindgen for FunctionBindgen<'_, '_> {
op
));
}
Bitcast::I32ToI64 => {
Bitcast::I32ToI64 | Bitcast::PToP64 => {
results.push(format!("(int64_t) {}", op));
}
Bitcast::I64ToI32 => {
Bitcast::I64ToI32 | Bitcast::P64ToP => {
results.push(format!("(int32_t) {}", op));
}
Bitcast::I64ToP64 | Bitcast::P64ToI64 => {
results.push(format!("{}", op));
}
Bitcast::None => results.push(op.to_string()),
}
}
Expand Down Expand Up @@ -3015,6 +3018,9 @@ fn wasm_type(ty: WasmType) -> &'static str {
WasmType::I64 => "int64_t",
WasmType::F32 => "float",
WasmType::F64 => "double",
WasmType::Pointer => "uintptr_t",
WasmType::Pointer64 => "int64_t",
WasmType::Length => "size_t",
}
}

Expand Down
19 changes: 17 additions & 2 deletions crates/core/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,12 @@ pub enum Bitcast {
I64ToI32,
I64ToF32,

// Pointers
P64ToI64,
I64ToP64,
P64ToP,
PToP64,

None,
}

Expand Down Expand Up @@ -1862,7 +1868,7 @@ fn cast(from: WasmType, to: WasmType) -> Bitcast {
use WasmType::*;

match (from, to) {
(I32, I32) | (I64, I64) | (F32, F32) | (F64, F64) => Bitcast::None,
(I32, I32) | (I64, I64) | (F32, F32) | (F64, F64) | (Pointer, Pointer) | (Length, Length) => Bitcast::None,

(I32, I64) => Bitcast::I32ToI64,
(F32, I32) => Bitcast::F32ToI32,
Expand All @@ -1875,7 +1881,16 @@ fn cast(from: WasmType, to: WasmType) -> Bitcast {
(F32, I64) => Bitcast::F32ToI64,
(I64, F32) => Bitcast::I64ToF32,

(F32, F64) | (F64, F32) | (F64, I32) | (I32, F64) => unreachable!(),
(I64, Pointer64) => Bitcast::I64ToP64,
(Pointer64, I64) => Bitcast::P64ToI64,
(Pointer, Pointer64) => Bitcast::PToP64,
(Pointer64, Pointer) => Bitcast::P64ToP,

(Pointer | Pointer64 | Length, _) |
(_, Pointer | Pointer64 | Length) |
(F32, F64) | (F64, F32) | (F64, I32) | (I32, F64) => {
unreachable!()
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions crates/csharp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,9 @@ impl Bindgen for FunctionBindgen<'_, '_> {
WasmType::I64 => "0L",
WasmType::F32 => "0.0F",
WasmType::F64 => "0.0D",
WasmType::Pointer => "0",
WasmType::Pointer64 => "0L",
WasmType::Length => "0",
}
.to_owned()
})),
Expand Down Expand Up @@ -2223,6 +2226,9 @@ fn wasm_type(ty: WasmType) -> &'static str {
WasmType::I64 => "long",
WasmType::F32 => "float",
WasmType::F64 => "double",
WasmType::Pointer => "int",
WasmType::Pointer64 => "long",
WasmType::Length => "int",
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/guest-rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ pub mod rt {
return ptr;
}

pub unsafe fn dealloc(ptr: i32, size: usize, align: usize) {
pub unsafe fn dealloc(ptr: *mut core::ffi::c_void, size: usize, align: usize) {
if size == 0 {
return;
}
let layout = Layout::from_size_align_unchecked(size, align);
alloc::dealloc(ptr as *mut u8, layout);
alloc::dealloc(ptr.cast::<u8>(), layout);
}

macro_rules! as_traits {
Expand Down
73 changes: 38 additions & 35 deletions crates/rust/src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,11 @@ impl Bindgen for FunctionBindgen<'_, '_> {
self.import_return_pointer_area_size = self.import_return_pointer_area_size.max(size);
self.import_return_pointer_area_align =
self.import_return_pointer_area_align.max(align);
uwrite!(self.src, "let ptr{tmp} = ret_area.as_mut_ptr() as i32;");
uwrite!(self.src, "let ptr{tmp} = ret_area.as_mut_ptr().cast::<core::ffi::c_void>();");
} else {
self.gen.return_pointer_area_size = self.gen.return_pointer_area_size.max(size);
self.gen.return_pointer_area_align = self.gen.return_pointer_area_align.max(align);
uwriteln!(self.src, "let ptr{tmp} = _RET_AREA.0.as_mut_ptr() as i32;");
uwriteln!(self.src, "let ptr{tmp} = _RET_AREA.0.as_mut_ptr().cast::<core::ffi::c_void>();");
}
format!("ptr{}", tmp)
}
Expand Down Expand Up @@ -313,6 +313,9 @@ impl Bindgen for FunctionBindgen<'_, '_> {
WasmType::I64 => results.push("0i64".to_string()),
WasmType::F32 => results.push("0.0f32".to_string()),
WasmType::F64 => results.push("0.0f64".to_string()),
WasmType::Pointer => results.push("core::ptr::null_mut()".to_string()),
WasmType::Pointer64 => results.push("(core::ptr::null_mut(), core::ptr::null_mut())".to_string()),
WasmType::Length => results.push("0usize".to_string()),
}
}
}
Expand Down Expand Up @@ -655,13 +658,13 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let ptr = format!("ptr{}", tmp);
let len = format!("len{}", tmp);
if realloc.is_none() {
self.push_str(&format!("let {} = {};\n", val, operands[0]));
self.push_str(&format!("let mut {} = {};\n", val, operands[0]));
} else {
let op0 = operands.pop().unwrap();
self.push_str(&format!("let {} = ({}).into_boxed_slice();\n", val, op0));
self.push_str(&format!("let mut {} = ({}).into_boxed_slice();\n", val, op0));
}
self.push_str(&format!("let {} = {}.as_ptr() as i32;\n", ptr, val));
self.push_str(&format!("let {} = {}.len() as i32;\n", len, val));
self.push_str(&format!("let {} = {}.as_mut_ptr().cast::<core::ffi::c_void>();\n", ptr, val));
self.push_str(&format!("let {} = {}.len();\n", len, val));
if realloc.is_some() {
self.push_str(&format!("::core::mem::forget({});\n", val));
}
Expand All @@ -672,9 +675,9 @@ impl Bindgen for FunctionBindgen<'_, '_> {
Instruction::ListCanonLift { .. } => {
let tmp = self.tmp();
let len = format!("len{}", tmp);
self.push_str(&format!("let {} = {} as usize;\n", len, operands[1]));
self.push_str(&format!("let {} = {};\n", len, operands[1]));
let result = format!(
"Vec::from_raw_parts({} as *mut _, {1}, {1})",
"Vec::from_raw_parts({}.cast(), {1}, {1})",
operands[0], len
);
results.push(result);
Expand All @@ -686,13 +689,13 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let ptr = format!("ptr{}", tmp);
let len = format!("len{}", tmp);
if realloc.is_none() {
self.push_str(&format!("let {} = {};\n", val, operands[0]));
self.push_str(&format!("let mut {} = {};\n", val, operands[0]));
} else {
let op0 = format!("{}.into_bytes()", operands[0]);
self.push_str(&format!("let {} = ({}).into_boxed_slice();\n", val, op0));
self.push_str(&format!("let mut {} = ({}).into_boxed_slice();\n", val, op0));
}
self.push_str(&format!("let {} = {}.as_ptr() as i32;\n", ptr, val));
self.push_str(&format!("let {} = {}.len() as i32;\n", len, val));
self.push_str(&format!("let {} = {}.as_mut_ptr().cast::<core::ffi::c_void>();\n", ptr, val));
self.push_str(&format!("let {} = {}.len();\n", len, val));
if realloc.is_some() {
self.push_str(&format!("::core::mem::forget({});\n", val));
}
Expand All @@ -703,10 +706,10 @@ impl Bindgen for FunctionBindgen<'_, '_> {
Instruction::StringLift => {
let tmp = self.tmp();
let len = format!("len{}", tmp);
uwriteln!(self.src, "let {len} = {} as usize;", operands[1]);
uwriteln!(self.src, "let {len} = {};", operands[1]);
uwriteln!(
self.src,
"let bytes{tmp} = Vec::from_raw_parts({} as *mut _, {len}, {len});",
"let bytes{tmp} = Vec::from_raw_parts({}.cast(), {len}, {len});",
operands[0],
);
if self.gen.gen.opts.raw_strings {
Expand All @@ -730,7 +733,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
"let {vec} = {operand0};\n",
operand0 = operands[0]
));
self.push_str(&format!("let {len} = {vec}.len() as i32;\n"));
self.push_str(&format!("let {len} = {vec}.len();\n"));
let size = self.gen.sizes.size(element);
let align = self.gen.sizes.align(element);
self.push_str(&format!(
Expand All @@ -745,11 +748,11 @@ impl Bindgen for FunctionBindgen<'_, '_> {
self.push_str("else {{\n::core::ptr::null_mut()\n}};\n");
self.push_str(&format!("for (i, e) in {vec}.into_iter().enumerate() {{\n",));
self.push_str(&format!(
"let base = {result} as i32 + (i as i32) * {size};\n",
"let base = {result}.byte_add(i * {size});\n",
));
self.push_str(&body);
self.push_str("\n}\n");
results.push(format!("{result} as i32"));
results.push(format!("{result}"));
results.push(len);

if realloc.is_none() {
Expand Down Expand Up @@ -777,7 +780,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
operand1 = operands[1]
));
self.push_str(&format!(
"let mut {result} = Vec::with_capacity({len} as usize);\n",
"let mut {result} = Vec::with_capacity({len});\n",
));

uwriteln!(self.src, "for i in 0..{len} {{");
Expand All @@ -787,7 +790,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
uwriteln!(self.src, "}}");
results.push(result);
self.push_str(&format!(
"{rt}::dealloc({base}, ({len} as usize) * {size}, {align});\n",
"{rt}::dealloc({base}, {len} * {size}, {align});\n",
rt = self.gen.gen.runtime_path(),
));
}
Expand Down Expand Up @@ -876,7 +879,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = *(({} + {offset}) as *const i32);",
"let l{tmp} = *{}.byte_add({offset}).cast::<i32>();",
operands[0]
);
results.push(format!("l{tmp}"));
Expand All @@ -885,7 +888,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = i32::from(*(({} + {offset}) as *const u8));",
"let l{tmp} = i32::from(*{}.byte_add({offset}).cast::<u8>());",
operands[0]
);
results.push(format!("l{tmp}"));
Expand All @@ -894,7 +897,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = i32::from(*(({} + {offset}) as *const i8));",
"let l{tmp} = i32::from(*{}.byte_add({offset}).cast::<i8>());",
operands[0]
);
results.push(format!("l{tmp}"));
Expand All @@ -903,7 +906,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = i32::from(*(({} + {offset}) as *const u16));",
"let l{tmp} = i32::from(*{}.byte_add({offset}).cast::<u16>());",
operands[0]
);
results.push(format!("l{tmp}"));
Expand All @@ -912,7 +915,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = i32::from(*(({} + {offset}) as *const i16));",
"let l{tmp} = i32::from(*{}.byte_add({offset}).cast::<i16>());",
operands[0]
);
results.push(format!("l{tmp}"));
Expand All @@ -921,7 +924,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = *(({} + {offset}) as *const i64);",
"let l{tmp} = *{}.byte_add({offset}).cast::<i64>();",
operands[0]
);
results.push(format!("l{tmp}"));
Expand All @@ -930,7 +933,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = *(({} + {offset}) as *const f32);",
"let l{tmp} = *{}.byte_add({offset}).cast::<f32>();",
operands[0]
);
results.push(format!("l{tmp}"));
Expand All @@ -939,44 +942,44 @@ impl Bindgen for FunctionBindgen<'_, '_> {
let tmp = self.tmp();
uwriteln!(
self.src,
"let l{tmp} = *(({} + {offset}) as *const f64);",
"let l{tmp} = *{}.byte_add({offset}).cast::<f64>();",
operands[0]
);
results.push(format!("l{tmp}"));
}
Instruction::I32Store { offset } => {
self.push_str(&format!(
"*(({} + {}) as *mut i32) = {};\n",
"*{}.byte_add({}).cast::<i32>() = {};\n",
operands[1], offset, operands[0]
));
}
Instruction::I32Store8 { offset } => {
self.push_str(&format!(
"*(({} + {}) as *mut u8) = ({}) as u8;\n",
"*{}.byte_add({}).cast::<u8>() = ({}) as u8;\n",
operands[1], offset, operands[0]
));
}
Instruction::I32Store16 { offset } => {
self.push_str(&format!(
"*(({} + {}) as *mut u16) = ({}) as u16;\n",
"*{}.byte_add({}).cast::<u16>() = ({}) as u16;\n",
operands[1], offset, operands[0]
));
}
Instruction::I64Store { offset } => {
self.push_str(&format!(
"*(({} + {}) as *mut i64) = {};\n",
"*{}.byte_add({}).cast::<i64>() = {};\n",
operands[1], offset, operands[0]
));
}
Instruction::F32Store { offset } => {
self.push_str(&format!(
"*(({} + {}) as *mut f32) = {};\n",
"*{}.byte_add({}).cast::<f32>() = {};\n",
operands[1], offset, operands[0]
));
}
Instruction::F64Store { offset } => {
self.push_str(&format!(
"*(({} + {}) as *mut f64) = {};\n",
"*{}.byte_add({}).cast::<f64>() = {};\n",
operands[1], offset, operands[0]
));
}
Expand All @@ -993,7 +996,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {

Instruction::GuestDeallocateString => {
self.push_str(&format!(
"{rt}::dealloc({op0}, ({op1}) as usize, 1);\n",
"{rt}::dealloc({op0}, {op1}, 1);\n",
rt = self.gen.gen.runtime_path(),
op0 = operands[0],
op1 = operands[1],
Expand Down Expand Up @@ -1048,7 +1051,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
self.push_str("\n}\n");
}
self.push_str(&format!(
"{rt}::dealloc({base}, ({len} as usize) * {size}, {align});\n",
"{rt}::dealloc({base}, {len} * {size}, {align});\n",
rt = self.gen.gen.runtime_path(),
));
}
Expand Down
7 changes: 5 additions & 2 deletions crates/rust/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,13 @@ impl InterfaceGenerator<'_> {
"
#[allow(unused_imports)]
use {rt}::{{alloc, vec::Vec, string::String}};
use core::ffi::c_void;
use core::mem::size_of;
const LEN = ({size} + (sizeof::<*mut c_void>() - 1)) / sizeof::<*mut c_void>();
#[repr(align({align}))]
struct _RetArea([u8; {size}]);
static mut _RET_AREA: _RetArea = _RetArea([0; {size}]);
struct _RetArea([*mut c_void; LEN]);
static mut _RET_AREA: _RetArea = _RetArea([0; LEN]);
",
rt = self.gen.runtime_path(),
align = self.return_pointer_area_align,
Expand Down
7 changes: 7 additions & 0 deletions crates/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,9 @@ fn wasm_type(ty: WasmType) -> &'static str {
WasmType::I64 => "i64",
WasmType::F32 => "f32",
WasmType::F64 => "f64",
WasmType::Pointer => "*mut core::ffi::c_void",
WasmType::Pointer64 => "(*mut core::ffi::c_void, *mut core::ffi::c_void)",
WasmType::Length => "usize",
}
}

Expand All @@ -812,6 +815,10 @@ fn bitcast(casts: &[Bitcast], operands: &[String], results: &mut Vec<String>) {
Bitcast::I64ToF64 => format!("f64::from_bits({} as u64)", operand),
Bitcast::F32ToI64 => format!("i64::from(({}).to_bits())", operand),
Bitcast::I64ToF32 => format!("f32::from_bits({} as u32)", operand),
Bitcast::I64ToP64 => format!("({} as *mut core::ffi::c_void, core::ptr::null_mut())", operand),
Bitcast::P64ToI64 => format!("{}.0 as i64", operand),
Bitcast::PToP64 => format!("({} as *mut core::ffi::c_void, core::ptr::null_mut())", operand),
Bitcast::P64ToP => format!("{}.0 as i64", operand),
});
}
}
Expand Down
Loading

0 comments on commit a939252

Please sign in to comment.