rust: transform pointers to references where possible

This commit is contained in:
Lofty 2024-01-16 01:55:50 +00:00 committed by myrtle
parent c5fc34f11a
commit c8e1cbc5f2
2 changed files with 75 additions and 86 deletions

View File

@ -32,7 +32,7 @@ pub struct NetInfo {
} }
impl NetInfo { impl NetInfo {
pub fn driver(&mut self) -> *mut PortRef { pub fn driver(&mut self) -> &mut PortRef {
unsafe { npnr_netinfo_driver(self) } unsafe { npnr_netinfo_driver(self) }
} }
@ -61,15 +61,10 @@ pub struct PortRef {
} }
impl PortRef { impl PortRef {
pub fn cell(&self) -> Option<&CellInfo> {
// SAFETY: handing out &s is safe when we have &self.
unsafe { npnr_portref_cell(self).as_ref() }
}
pub fn cell_mut(&mut self) -> Option<&mut CellInfo> { pub fn cell_mut(&mut self) -> Option<&mut CellInfo> {
// SAFETY: handing out &mut is safe when we have &mut self // SAFETY: handing out &mut is safe when we have &mut self
// as getting multiple &mut CellInfo would require multiple &mut PortRef. // as getting multiple &mut CellInfo would require multiple &mut PortRef.
unsafe { npnr_portref_cell(self).as_mut() } unsafe { npnr_portref_cell(self) }
} }
} }
@ -227,15 +222,11 @@ impl Context {
unsafe { npnr_context_delay_epsilon(self) } unsafe { npnr_context_delay_epsilon(self) }
} }
/// # Safety pub fn source_wire(&self, net: &NetInfo) -> WireId {
/// `net` must be valid and not null.
pub unsafe fn source_wire(&self, net: *const NetInfo) -> WireId {
unsafe { npnr_context_get_netinfo_source_wire(self, net) } unsafe { npnr_context_get_netinfo_source_wire(self, net) }
} }
/// # Safety pub fn sink_wires(&self, net: &NetInfo, sink: &PortRef) -> Vec<WireId> {
/// `net` and `sink` must be valid and not null.
pub unsafe fn sink_wires(&self, net: *const NetInfo, sink: *const PortRef) -> Vec<WireId> {
let mut v = Vec::new(); let mut v = Vec::new();
let mut n = 0; let mut n = 0;
loop { loop {
@ -312,9 +303,7 @@ impl Context {
Loc{x: dst.x - src.x, y: dst.y - src.y, z: 0} Loc{x: dst.x - src.x, y: dst.y - src.y, z: 0}
} }
/// # Safety pub fn pip_avail_for_net(&self, pip: PipId, net: &mut NetInfo) -> bool {
/// `net` must be valid and not null.
pub unsafe fn pip_avail_for_net(&self, pip: PipId, net: *mut NetInfo) -> bool {
unsafe { npnr_context_check_pip_avail_for_net(self, pip, net) } unsafe { npnr_context_check_pip_avail_for_net(self, pip, net) }
} }
@ -359,92 +348,92 @@ extern "C" {
fn npnr_wireid_null() -> WireId; fn npnr_wireid_null() -> WireId;
fn npnr_pipid_null() -> PipId; fn npnr_pipid_null() -> PipId;
fn npnr_context_get_grid_dim_x(ctx: *const Context) -> libc::c_int; fn npnr_context_get_grid_dim_x(ctx: &Context) -> libc::c_int;
fn npnr_context_get_grid_dim_y(ctx: *const Context) -> libc::c_int; fn npnr_context_get_grid_dim_y(ctx: &Context) -> libc::c_int;
fn npnr_context_bind_bel( fn npnr_context_bind_bel(
ctx: *mut Context, ctx: &mut Context,
bel: BelId, bel: BelId,
cell: *mut CellInfo, cell: &mut CellInfo,
strength: PlaceStrength, strength: PlaceStrength,
); );
fn npnr_context_unbind_bel(ctx: *mut Context, bel: BelId); fn npnr_context_unbind_bel(ctx: &mut Context, bel: BelId);
fn npnr_context_check_bel_avail(ctx: *const Context, bel: BelId) -> bool; fn npnr_context_check_bel_avail(ctx: &Context, bel: BelId) -> bool;
fn npnr_context_bind_wire( fn npnr_context_bind_wire(
ctx: *mut Context, ctx: &mut Context,
wire: WireId, wire: WireId,
net: *mut NetInfo, net: &mut NetInfo,
strength: PlaceStrength, strength: PlaceStrength,
); );
fn npnr_context_unbind_wire(ctx: *mut Context, wire: WireId); fn npnr_context_unbind_wire(ctx: &mut Context, wire: WireId);
fn npnr_context_bind_pip( fn npnr_context_bind_pip(
ctx: *mut Context, ctx: &mut Context,
pip: PipId, pip: PipId,
net: *mut NetInfo, net: &mut NetInfo,
strength: PlaceStrength, strength: PlaceStrength,
); );
fn npnr_context_unbind_pip(ctx: *mut Context, pip: PipId); fn npnr_context_unbind_pip(ctx: &mut Context, pip: PipId);
fn npnr_context_get_pip_src_wire(ctx: *const Context, pip: PipId) -> WireId; fn npnr_context_get_pip_src_wire(ctx: &Context, pip: PipId) -> WireId;
fn npnr_context_get_pip_dst_wire(ctx: *const Context, pip: PipId) -> WireId; fn npnr_context_get_pip_dst_wire(ctx: &Context, pip: PipId) -> WireId;
fn npnr_context_estimate_delay(ctx: *const Context, src: WireId, dst: WireId) -> f32; fn npnr_context_estimate_delay(ctx: &Context, src: WireId, dst: WireId) -> f32;
fn npnr_context_delay_epsilon(ctx: *const Context) -> f32; fn npnr_context_delay_epsilon(ctx: &Context) -> f32;
fn npnr_context_get_pip_delay(ctx: *const Context, pip: PipId) -> f32; fn npnr_context_get_pip_delay(ctx: &Context, pip: PipId) -> f32;
fn npnr_context_get_wire_delay(ctx: *const Context, wire: WireId) -> f32; fn npnr_context_get_wire_delay(ctx: &Context, wire: WireId) -> f32;
fn npnr_context_get_wires_leak(ctx: *const Context, wires: *mut *mut WireId) -> u64; fn npnr_context_get_wires_leak(ctx: &Context, wires: *mut *mut WireId) -> u64;
fn npnr_context_get_pips_leak(ctx: *const Context, pips: *mut *mut PipId) -> u64; fn npnr_context_get_pips_leak(ctx: &Context, pips: *mut *mut PipId) -> u64;
fn npnr_context_get_pip_location(ctx: *const Context, pip: PipId) -> Loc; fn npnr_context_get_pip_location(ctx: &Context, pip: PipId) -> Loc;
fn npnr_context_check_pip_avail_for_net( fn npnr_context_check_pip_avail_for_net(
ctx: *const Context, ctx: &Context,
pip: PipId, pip: PipId,
net: *const NetInfo, net: &NetInfo,
) -> bool; ) -> bool;
fn npnr_context_check(ctx: *const Context); fn npnr_context_check(ctx: &Context);
fn npnr_context_debug(ctx: *const Context) -> bool; fn npnr_context_debug(ctx: &Context) -> bool;
fn npnr_context_id(ctx: *const Context, s: *const c_char) -> IdString; fn npnr_context_id(ctx: &Context, s: *const c_char) -> IdString;
fn npnr_context_name_of(ctx: *const Context, s: IdString) -> *const libc::c_char; fn npnr_context_name_of(ctx: &Context, s: IdString) -> &libc::c_char;
fn npnr_context_name_of_pip(ctx: *const Context, pip: PipId) -> *const libc::c_char; fn npnr_context_name_of_pip(ctx: &Context, pip: PipId) -> &libc::c_char;
fn npnr_context_name_of_wire(ctx: *const Context, wire: WireId) -> *const libc::c_char; fn npnr_context_name_of_wire(ctx: &Context, wire: WireId) -> &libc::c_char;
fn npnr_context_verbose(ctx: *const Context) -> bool; fn npnr_context_verbose(ctx: &Context) -> bool;
fn npnr_context_get_netinfo_source_wire(ctx: *const Context, net: *const NetInfo) -> WireId; fn npnr_context_get_netinfo_source_wire(ctx: &Context, net: &NetInfo) -> WireId;
fn npnr_context_get_netinfo_sink_wire( fn npnr_context_get_netinfo_sink_wire(
ctx: *const Context, ctx: &Context,
net: *const NetInfo, net: &NetInfo,
sink: *const PortRef, sink: &PortRef,
n: u32, n: u32,
) -> WireId; ) -> WireId;
fn npnr_context_nets_leak( fn npnr_context_nets_leak(
ctx: *const Context, ctx: &Context,
names: *mut *mut libc::c_int, names: *mut *mut libc::c_int,
nets: *mut *mut *mut NetInfo, nets: *mut *mut *mut NetInfo,
) -> u32; ) -> u32;
fn npnr_context_get_pips_downhill(ctx: *const Context, wire: WireId) -> *mut RawDownhillIter; fn npnr_context_get_pips_downhill(ctx: &Context, wire: WireId) -> &mut RawDownhillIter;
fn npnr_delete_downhill_iter(iter: *mut RawDownhillIter); fn npnr_delete_downhill_iter(iter: &mut RawDownhillIter);
fn npnr_context_get_pips_uphill(ctx: *const Context, wire: WireId) -> *mut RawUphillIter; fn npnr_context_get_pips_uphill(ctx: &Context, wire: WireId) -> &mut RawUphillIter;
fn npnr_delete_uphill_iter(iter: *mut RawUphillIter); fn npnr_delete_uphill_iter(iter: &mut RawUphillIter);
fn npnr_netinfo_driver(net: *mut NetInfo) -> *mut PortRef; fn npnr_netinfo_driver(net: &mut NetInfo) -> &mut PortRef;
fn npnr_netinfo_users_leak(net: *mut NetInfo, users: *mut *mut *mut PortRef) -> u32; fn npnr_netinfo_users_leak(net: &NetInfo, users: *mut *mut *const PortRef) -> u32;
fn npnr_netinfo_is_global(net: *const NetInfo) -> bool; fn npnr_netinfo_is_global(net: &NetInfo) -> bool;
fn npnr_netinfo_udata(net: *const NetInfo) -> NetIndex; fn npnr_netinfo_udata(net: &NetInfo) -> NetIndex;
fn npnr_netinfo_udata_set(net: *mut NetInfo, value: NetIndex); fn npnr_netinfo_udata_set(net: &mut NetInfo, value: NetIndex);
fn npnr_portref_cell(port: *const PortRef) -> *mut CellInfo; fn npnr_portref_cell(port: &mut PortRef) -> Option<&mut CellInfo>;
fn npnr_cellinfo_get_location(info: *const CellInfo) -> Loc; fn npnr_cellinfo_get_location(info: &CellInfo) -> Loc;
fn npnr_inc_downhill_iter(iter: *mut RawDownhillIter); fn npnr_inc_downhill_iter(iter: &mut RawDownhillIter);
fn npnr_deref_downhill_iter(iter: *mut RawDownhillIter) -> PipId; fn npnr_deref_downhill_iter(iter: &mut RawDownhillIter) -> PipId;
fn npnr_is_downhill_iter_done(iter: *mut RawDownhillIter) -> bool; fn npnr_is_downhill_iter_done(iter: &mut RawDownhillIter) -> bool;
fn npnr_inc_uphill_iter(iter: *mut RawUphillIter); fn npnr_inc_uphill_iter(iter: &mut RawUphillIter);
fn npnr_deref_uphill_iter(iter: *mut RawUphillIter) -> PipId; fn npnr_deref_uphill_iter(iter: &mut RawUphillIter) -> PipId;
fn npnr_is_uphill_iter_done(iter: *mut RawUphillIter) -> bool; fn npnr_is_uphill_iter_done(iter: &mut RawUphillIter) -> bool;
} }
/// Store for the nets of a context. /// Store for the nets of a context.
pub struct Nets<'a> { pub struct Nets<'a> {
nets: HashMap<IdString, *mut NetInfo>, nets: HashMap<IdString, &'a mut NetInfo>,
users: HashMap<IdString, &'a [&'a mut PortRef]>, users: HashMap<IdString, &'a [&'a PortRef]>,
index_to_net: Vec<IdString>, index_to_net: Vec<IdString>,
_data: PhantomData<&'a Context>, _data: PhantomData<&'a Context>,
} }
@ -471,21 +460,21 @@ impl<'a> Nets<'a> {
let mut index_to_net = Vec::new(); let mut index_to_net = Vec::new();
for i in 0..size { for i in 0..size {
let name = unsafe { IdString(*names.add(i as usize)) }; let name = unsafe { IdString(*names.add(i as usize)) };
let net = unsafe { *nets_ptr.add(i as usize) }; let net = unsafe { &mut **nets_ptr.add(i as usize) };
let mut users_ptr = std::ptr::null_mut(); let mut users_ptr = std::ptr::null_mut();
// SAFETY: net is not null because it's a &mut, and users is only written to. // SAFETY: net is not null because it's a &mut, and users is only written to.
// Leaking memory is the most convenient FFI I could think of. // Leaking memory is the most convenient FFI I could think of.
let len = let len =
unsafe { npnr_netinfo_users_leak(net, &mut users_ptr as *mut *mut *mut PortRef) }; unsafe { npnr_netinfo_users_leak(net, &mut users_ptr as *mut *mut *const PortRef) };
let users_slice = let users_slice =
unsafe { slice::from_raw_parts(users_ptr as *mut &mut PortRef, len as usize) }; unsafe { slice::from_raw_parts(users_ptr as *mut &PortRef, len as usize) };
nets.insert(name, net);
users.insert(name, users_slice);
let index = index_to_net.len() as i32; let index = index_to_net.len() as i32;
index_to_net.push(name); index_to_net.push(name);
unsafe { unsafe {
npnr_netinfo_udata_set(net, NetIndex(index)); npnr_netinfo_udata_set(net, NetIndex(index));
} }
nets.insert(name, net);
users.insert(name, users_slice);
} }
// Note: the contents of `names` and `nets_ptr` are now lost. // Note: the contents of `names` and `nets_ptr` are now lost.
Self { Self {
@ -497,7 +486,7 @@ impl<'a> Nets<'a> {
} }
/// Find net users given a net's name. /// Find net users given a net's name.
pub fn users_by_name(&self, net: IdString) -> Option<&&[&mut PortRef]> { pub fn users_by_name(&self, net: IdString) -> Option<&&[&PortRef]> {
self.users.get(&net) self.users.get(&net)
} }
@ -514,11 +503,11 @@ impl<'a> Nets<'a> {
self.index_to_net[index.0 as usize] self.index_to_net[index.0 as usize]
} }
pub fn net_from_index(&self, index: NetIndex) -> *mut NetInfo { pub fn net_from_index(&self, index: NetIndex) -> &NetInfo {
*self.nets.get(&self.name_from_index(index)).unwrap() self.nets.get(&self.name_from_index(index)).unwrap()
} }
pub fn to_vec(&self) -> Vec<(&IdString, &*mut NetInfo)> { pub fn to_vec(&self) -> Vec<(&IdString, &&mut NetInfo)> {
let mut v = Vec::new(); let mut v = Vec::new();
v.extend(self.nets.iter()); v.extend(self.nets.iter());
v.sort_by_key(|(name, _net)| name.0); v.sort_by_key(|(name, _net)| name.0);
@ -528,8 +517,8 @@ impl<'a> Nets<'a> {
pub struct NetSinkWireIter<'a> { pub struct NetSinkWireIter<'a> {
ctx: &'a Context, ctx: &'a Context,
net: *const NetInfo, net: &'a NetInfo,
sink: *const PortRef, sink: &'a PortRef,
n: u32, n: u32,
} }
@ -553,8 +542,8 @@ struct RawDownhillIter {
} }
pub struct DownhillPipsIter<'a> { pub struct DownhillPipsIter<'a> {
iter: *mut RawDownhillIter, iter: &'a mut RawDownhillIter,
phantom_data: std::marker::PhantomData<&'a PipId>, phantom_data: PhantomData<&'a PipId>,
} }
impl<'a> Iterator for DownhillPipsIter<'a> { impl<'a> Iterator for DownhillPipsIter<'a> {
@ -583,8 +572,8 @@ struct RawUphillIter {
} }
pub struct UphillPipsIter<'a> { pub struct UphillPipsIter<'a> {
iter: *mut RawUphillIter, iter: &'a mut RawUphillIter,
phantom_data: std::marker::PhantomData<&'a PipId>, phantom_data: PhantomData<&'a PipId>,
} }
impl<'a> Iterator for UphillPipsIter<'a> { impl<'a> Iterator for UphillPipsIter<'a> {

View File

@ -214,7 +214,7 @@ PortRef *npnr_netinfo_driver(NetInfo *net)
return &net->driver; return &net->driver;
} }
uint32_t npnr_netinfo_users_leak(NetInfo *net, PortRef ***users) uint32_t npnr_netinfo_users_leak(const NetInfo *net, const PortRef ***users)
{ {
auto size = net->users.entries(); auto size = net->users.entries();
*users = new PortRef *[size]; *users = new PortRef *[size];