util: Add WeakPointer helper for passing around raw pointers

Former-commit-id: eaab1057cf7bf8132ba7b59f6c5315e873064c30
Former-commit-id: 94f947733463b528dd3775d2bc6f55adebc36a2d
This commit is contained in:
Michel Heily 2020-05-29 17:39:35 +03:00
parent 879374a9b0
commit 6e39780b43
2 changed files with 40 additions and 33 deletions

View file

@ -1,5 +1,4 @@
use std::fmt; use std::fmt;
use std::ops::{Deref, DerefMut};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -7,6 +6,7 @@ use super::cartridge::Cartridge;
use super::dma::DmaNotifer; use super::dma::DmaNotifer;
use super::iodev::{IoDevices, WaitControl}; use super::iodev::{IoDevices, WaitControl};
use super::{Addr, Bus}; use super::{Addr, Bus};
use super::util::WeakPointer;
pub mod consts { pub mod consts {
pub const WORK_RAM_SIZE: usize = 256 * 1024; pub const WORK_RAM_SIZE: usize = 256 * 1024;
@ -202,38 +202,7 @@ pub struct SysBus {
pub trace_access: bool, pub trace_access: bool,
} }
#[repr(transparent)] pub type SysBusPtr = WeakPointer<SysBus>;
#[derive(Clone)]
pub struct SysBusPtr {
ptr: *mut SysBus,
}
impl Default for SysBusPtr {
fn default() -> SysBusPtr {
SysBusPtr {
ptr: std::ptr::null_mut::<SysBus>(),
}
}
}
impl SysBusPtr {
pub fn new(ptr: *mut SysBus) -> SysBusPtr {
SysBusPtr { ptr: ptr }
}
}
impl Deref for SysBusPtr {
type Target = SysBus;
fn deref(&self) -> &Self::Target {
unsafe { &*self.ptr }
}
}
impl DerefMut for SysBusPtr {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.ptr }
}
}
macro_rules! memory_map { macro_rules! memory_map {
(read($sb:ident, $read_fn:ident, $addr:expr)) => { (read($sb:ident, $read_fn:ident, $addr:expr)) => {

View file

@ -1,7 +1,9 @@
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::ops::{Deref, DerefMut};
use std::path::Path; use std::path::Path;
use std::ptr;
use std::time; use std::time;
@ -153,3 +155,39 @@ pub mod audio {
} }
} }
} }
#[repr(transparent)]
#[derive(Clone)]
/// Wrapper for passing raw pointers around.
/// Breaks compiler safety guaranties, so must be used with care.
pub struct WeakPointer<T: ?Sized> {
ptr: *mut T,
}
impl<T> WeakPointer<T> {
pub fn new(ptr: *mut T) -> Self {
WeakPointer { ptr }
}
}
impl<T> Deref for WeakPointer<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &(*self.ptr) }
}
}
impl<T> DerefMut for WeakPointer<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut (*self.ptr) }
}
}
impl<T> Default for WeakPointer<T> {
fn default() -> Self {
WeakPointer {
ptr: ptr::null_mut(),
}
}
}