rust: transform pointers to references where possible
This commit is contained in:
parent
c5fc34f11a
commit
c8e1cbc5f2
@ -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> {
|
||||||
|
@ -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];
|
||||||
|
Loading…
Reference in New Issue
Block a user