重写rust核心库,构建中断处理框架 #6
|
@ -11,6 +11,7 @@ extern "C" {
|
||||||
pub struct SystemTimeError(Duration);
|
pub struct SystemTimeError(Duration);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Hash)]
|
#[derive(Clone, Copy, Hash)]
|
||||||
|
#[derive(Default)]
|
||||||
pub struct SystemTime {
|
pub struct SystemTime {
|
||||||
unix_time: usize,
|
unix_time: usize,
|
||||||
ns_time: usize,
|
ns_time: usize,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use alloc::vec;
|
use crate::libk::alloc::vec::Vec;
|
||||||
use alloc::vec::Vec;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
clock::time::SystemTime,
|
clock::time::SystemTime,
|
||||||
|
@ -28,12 +27,12 @@ pub struct KernelLogger {
|
||||||
impl KernelLogger {
|
impl KernelLogger {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
fatal_queue: vec![],
|
fatal_queue: Vec::new(),
|
||||||
error_queue: vec![],
|
error_queue: Vec::new(),
|
||||||
warning_queue: vec![],
|
warning_queue: Vec::new(),
|
||||||
info_queue: vec![],
|
info_queue: Vec::new(),
|
||||||
debug_queue: vec![],
|
debug_queue: Vec::new(),
|
||||||
trace_queue: vec![],
|
trace_queue: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,105 +90,18 @@ impl KernelLogger {
|
||||||
self.trace_queue.push((SystemTime::now(), msg));
|
self.trace_queue.push((SystemTime::now(), msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self, level: LoggerLevel) -> LogIterator {
|
pub fn iter(&self, _level: LoggerLevel) -> LogIterator {
|
||||||
let mut logs = vec![];
|
todo!()
|
||||||
match level {
|
|
||||||
LoggerLevel::Fatal => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Error => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Warning => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Info => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
logs.push(&self.info_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Debug => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
logs.push(&self.info_queue);
|
|
||||||
logs.push(&self.debug_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Trace => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
logs.push(&self.info_queue);
|
|
||||||
logs.push(&self.debug_queue);
|
|
||||||
logs.push(&self.trace_queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut res = vec![];
|
|
||||||
let mut indeces = Vec::new();
|
|
||||||
for _ in 0..logs.len() {
|
|
||||||
indeces.push(0usize);
|
|
||||||
}
|
|
||||||
let all_end = |indeces: &Vec<usize>, logs: &Vec<&Vec<(SystemTime, Message)>>| {
|
|
||||||
for i in 0..indeces.len() {
|
|
||||||
if indeces[i] < logs.len() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
};
|
|
||||||
while !all_end(&indeces, &logs) {
|
|
||||||
let mut min_ind = None;
|
|
||||||
let mut min = None;
|
|
||||||
for i in 0..indeces.len() {
|
|
||||||
if indeces[i] >= logs[i].len() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(minx) = min.as_mut() {
|
|
||||||
if logs[i][indeces[i]].0 < *minx {
|
|
||||||
*minx = logs[i][indeces[i]].0;
|
|
||||||
min_ind = Some(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
min = Some(logs[i][indeces[i]].0);
|
|
||||||
min_ind = Some(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(mini) = min_ind {
|
|
||||||
res.push(&logs[mini][indeces[mini]]);
|
|
||||||
indeces[mini] += 1;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LogIterator { logs: res }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LogIterator<'a> {
|
pub struct LogIterator {
|
||||||
logs: Vec<&'a (SystemTime, Message)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for LogIterator<'a> {
|
impl Iterator for LogIterator {
|
||||||
type Item = Message;
|
type Item = Message;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let res = if let Some((time, msg)) = self.logs.first() {
|
todo!()
|
||||||
Some(
|
|
||||||
MessageBuilder::new()
|
|
||||||
.message(time)
|
|
||||||
.append(MessageBuilder::from_message(msg.clone()))
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
if let Some(_) = res {
|
|
||||||
self.logs.remove(0);
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
pub mod rwlock;
|
|
|
@ -1,129 +0,0 @@
|
||||||
use core::{ops::{Deref, DerefMut}, ptr::null_mut};
|
|
||||||
|
|
||||||
use alloc::{vec, vec::Vec};
|
|
||||||
|
|
||||||
/// ## RwLock<T>
|
|
||||||
/// 读写锁
|
|
||||||
///
|
|
||||||
/// * 对于写入操作:
|
|
||||||
///
|
|
||||||
/// 锁没有占用时,获取锁,并执行闭包。
|
|
||||||
///
|
|
||||||
/// 当锁已经被占用,将闭包悬挂。
|
|
||||||
///
|
|
||||||
/// 释放锁时,将所有悬挂的闭包都执行。
|
|
||||||
///
|
|
||||||
/// 正在释放锁时,`write`方法返回`Err(())`
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let num = 6;
|
|
||||||
/// let num = RwLock::new(num);
|
|
||||||
/// if let Err(()) = num.write(
|
|
||||||
/// |n| *n = 10
|
|
||||||
/// ) {}
|
|
||||||
/// let numstr = format!("{}", num.read());
|
|
||||||
/// ````
|
|
||||||
pub struct RwLock<'a, T> {
|
|
||||||
obj: T,
|
|
||||||
locked: bool,
|
|
||||||
dealing_hanged: bool,
|
|
||||||
ptr: *mut RwLockWriteGuard<'a, T>,
|
|
||||||
hanging: Vec<&'a dyn Fn(&mut T)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T> Send for RwLock<'_, T> {}
|
|
||||||
unsafe impl<T> Sync for RwLock<'_, T> {}
|
|
||||||
|
|
||||||
impl<'a, T> RwLock<'a, T> {
|
|
||||||
pub fn new(obj: T) -> Self {
|
|
||||||
Self {
|
|
||||||
obj,
|
|
||||||
locked: false,
|
|
||||||
dealing_hanged: false,
|
|
||||||
ptr: null_mut(),
|
|
||||||
hanging: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(&self) -> RwLockReadGuard<T> {
|
|
||||||
RwLockReadGuard { obj: &self.obj }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write(&'a mut self, f: &'a dyn Fn(&mut T)) -> Result<RwLockWriteGuard<T>, ()> {
|
|
||||||
if self.dealing_hanged {
|
|
||||||
Err(())
|
|
||||||
} else if !self.locked {
|
|
||||||
self.locked = true;
|
|
||||||
f(&mut self.obj);
|
|
||||||
let ptr = { self as *mut RwLock<'a, T> };
|
|
||||||
let obj = &mut self.obj;
|
|
||||||
let mut res = RwLockWriteGuard {
|
|
||||||
obj,
|
|
||||||
ptr,
|
|
||||||
must_deal_hang: false,
|
|
||||||
};
|
|
||||||
self.ptr = &mut res as *mut RwLockWriteGuard<'_, T>;
|
|
||||||
Ok(res)
|
|
||||||
} else {
|
|
||||||
self.hanging.push(f);
|
|
||||||
let ptr = { self as *mut RwLock<'a, T> };
|
|
||||||
let obj = &mut self.obj;
|
|
||||||
Ok(RwLockWriteGuard {
|
|
||||||
obj,
|
|
||||||
ptr,
|
|
||||||
must_deal_hang: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RwLockReadGuard<'a, T> {
|
|
||||||
obj: &'a T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Deref for RwLockReadGuard<'a, T> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Drop for RwLockReadGuard<'a, T> {
|
|
||||||
fn drop(&mut self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RwLockWriteGuard<'a, T> {
|
|
||||||
obj: &'a mut T,
|
|
||||||
ptr: *mut RwLock<'a, T>,
|
|
||||||
must_deal_hang: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
self.obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.must_deal_hang {
|
|
||||||
let p = unsafe { &mut *self.ptr };
|
|
||||||
p.dealing_hanged = true;
|
|
||||||
for f in p.hanging.iter() {
|
|
||||||
f(self.obj);
|
|
||||||
}
|
|
||||||
p.hanging.clear();
|
|
||||||
p.dealing_hanged = false;
|
|
||||||
p.locked = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
use alloc::{
|
use crate::libk::alloc::{
|
||||||
|
boxed::Box,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec,
|
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ impl Tty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct Color(pub u8, pub u8, pub u8);
|
pub struct Color(pub u8, pub u8, pub u8);
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
|
@ -169,7 +169,7 @@ pub struct Resolution {
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default)]
|
||||||
pub struct MessageSection {
|
pub struct MessageSection {
|
||||||
msg: String,
|
msg: String,
|
||||||
fgcolor: Color,
|
fgcolor: Color,
|
||||||
|
@ -179,14 +179,14 @@ pub struct MessageSection {
|
||||||
/// ## Message
|
/// ## Message
|
||||||
///
|
///
|
||||||
/// 用`MessageBuilder`构造一个`Message`对象
|
/// 用`MessageBuilder`构造一个`Message`对象
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Message(Vec<MessageSection>);
|
pub struct Message(Vec<MessageSection>);
|
||||||
|
|
||||||
impl ToString for Message {
|
impl ToString for Message {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
let mut res = String::new();
|
let mut res = String::new();
|
||||||
for MessageSection { msg, .. } in self.0.iter() {
|
for MessageSection { msg, .. } in self.0.iter() {
|
||||||
res += msg;
|
res += msg.clone();
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ impl ToString for Message {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use crate::kernel::tty::tty::BuilderFunctions::*;
|
/// use crate::kernel::tty::tty::BuilderFunctions::*;
|
||||||
///
|
///
|
||||||
/// message!(
|
/// message_raw!(
|
||||||
/// Msg("Hello, "),
|
/// Msg("Hello, "),
|
||||||
/// Msg("Metaverse"),
|
/// Msg("Metaverse"),
|
||||||
/// FgColor(Color::GREEN),
|
/// FgColor(Color::GREEN),
|
||||||
|
@ -242,10 +242,14 @@ pub enum BuilderFunctions<'a> {
|
||||||
impl MessageBuilder {
|
impl MessageBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
msg: Message(vec![]),
|
msg: Message(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.msg.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_message(msg: Message) -> Self {
|
pub fn from_message(msg: Message) -> Self {
|
||||||
Self { msg }
|
Self { msg }
|
||||||
}
|
}
|
||||||
|
@ -302,3 +306,82 @@ impl MessageBuilder {
|
||||||
self.msg
|
self.msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FmtMeta {
|
||||||
|
Color(Color),
|
||||||
|
String(String),
|
||||||
|
ToStringable(Box<dyn ToString>),
|
||||||
|
Hex(u8),
|
||||||
|
Pointer(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
|
||||||
|
let mut msgbuilder = MessageBuilder::new();
|
||||||
|
let mut fmt_start = None;
|
||||||
|
let mut fmt_end = None;
|
||||||
|
for i in 0..fmt.len() {
|
||||||
|
if fmt[i] == '{' {
|
||||||
|
fmt_start = Some(i);
|
||||||
|
}
|
||||||
|
if fmt[i] == '}' {
|
||||||
|
fmt_end = Some(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let tohex = |n: u8| {
|
||||||
|
if n < 10 {
|
||||||
|
(b'0' + n) as char
|
||||||
|
} else {
|
||||||
|
(b'a' + n - 10) as char
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if fmt_start == None || fmt_end == None {
|
||||||
|
msgbuilder.message_mut(&String::from_iter(fmt.iter()));
|
||||||
|
} else {
|
||||||
|
let fmt_start = fmt_start.unwrap();
|
||||||
|
let fmt_end = fmt_end.unwrap();
|
||||||
|
let mut formatter = Vec::new();
|
||||||
|
for _ in fmt_start..=fmt_end {
|
||||||
|
formatter.push(fmt.remove(fmt_start));
|
||||||
|
}
|
||||||
|
formatter.remove(formatter.len() - 1);
|
||||||
|
formatter.remove(0);
|
||||||
|
match meta {
|
||||||
|
FmtMeta::Color(color) => {
|
||||||
|
let first = fmt.split_at(fmt_start).0;
|
||||||
|
msgbuilder.message_mut(&String::from_iter(first.iter()));
|
||||||
|
for _ in 0..fmt_start {
|
||||||
|
fmt.remove(0);
|
||||||
|
}
|
||||||
|
msgbuilder.message_mut(&String::from_iter(formatter.iter()));
|
||||||
|
msgbuilder.foreground_color_mut(color);
|
||||||
|
}
|
||||||
|
FmtMeta::String(s) => {
|
||||||
|
for c in s.chars().rev() {
|
||||||
|
fmt.insert(fmt_start, *c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FmtMeta::ToStringable(s) => {
|
||||||
|
for c in s.to_string().chars().rev() {
|
||||||
|
fmt.insert(fmt_start, *c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FmtMeta::Hex(num) => {
|
||||||
|
fmt.insert(fmt_start, tohex(num >> 4));
|
||||||
|
fmt.insert(fmt_start, tohex(num & 0xf));
|
||||||
|
}
|
||||||
|
FmtMeta::Pointer(mut p) => {
|
||||||
|
for _ in 0..16 {
|
||||||
|
fmt.insert(fmt_start, tohex((p & 0xf) as u8));
|
||||||
|
p >>= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut rests = Vec::new();
|
||||||
|
while !fmt.is_empty() && fmt[0] != '{' {
|
||||||
|
rests.push(fmt.remove(0));
|
||||||
|
}
|
||||||
|
msgbuilder.message_mut(&String::from_iter(rests.iter()));
|
||||||
|
msgbuilder
|
||||||
|
}
|
||||||
|
|
61
src/lib.rs
61
src/lib.rs
|
@ -1,69 +1,14 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![feature(strict_provenance)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::{
|
use core::panic::PanicInfo;
|
||||||
string::{String, ToString},
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use core::{panic::PanicInfo, ptr::null_mut};
|
|
||||||
|
|
||||||
use kernel::tty::tty::{self, tty_enable, tty_text_print, Color};
|
|
||||||
|
|
||||||
pub mod kernel;
|
pub mod kernel;
|
||||||
pub mod libk;
|
pub mod libk;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
unsafe fn kernel_panic_handler(info: &PanicInfo) -> ! {
|
unsafe fn kernel_panic_handler(_info: &PanicInfo) -> ! {
|
||||||
let line_in_file = if let Some(loca) = info.location() {
|
|
||||||
loca.line().to_string()
|
|
||||||
} else {
|
|
||||||
String::new()
|
|
||||||
};
|
|
||||||
let info = {
|
|
||||||
let mut v = Vec::new();
|
|
||||||
v.push(("Kernel Panic: ", (Color::RED, Color::BLACK)));
|
|
||||||
v.push((
|
|
||||||
if let Some(loca) = info.location() {
|
|
||||||
loca.file()
|
|
||||||
} else {
|
|
||||||
"NoFile"
|
|
||||||
},
|
|
||||||
(Color::GREEN, Color::BLACK),
|
|
||||||
));
|
|
||||||
v.push((":", (Color::WHITE, Color::BLACK)));
|
|
||||||
v.push((
|
|
||||||
if let Some(_) = info.location() {
|
|
||||||
line_in_file.as_str()
|
|
||||||
} else {
|
|
||||||
"NoLine"
|
|
||||||
},
|
|
||||||
(Color::WHITE, Color::BLACK),
|
|
||||||
));
|
|
||||||
v.push((": ", (Color::WHITE, Color::BLACK)));
|
|
||||||
v.push((
|
|
||||||
if let Some(&s) = info.payload().downcast_ref::<&str>() {
|
|
||||||
s
|
|
||||||
} else {
|
|
||||||
"Unknown panic."
|
|
||||||
},
|
|
||||||
(Color::BLUE, Color::BLACK),
|
|
||||||
));
|
|
||||||
v.push(("\n", (Color::BLACK, Color::BLACK)));
|
|
||||||
v
|
|
||||||
};
|
|
||||||
let tty = tty::tty_get(0);
|
|
||||||
if tty != null_mut() {
|
|
||||||
let tty = *tty;
|
|
||||||
tty_enable(tty);
|
|
||||||
for (msgo, (fgc, bgc)) in info.into_iter() {
|
|
||||||
let msg = String::from(msgo).as_bytes_mut() as *mut [u8] as *mut u8;
|
|
||||||
let p = msg.offset(msgo.len() as isize);
|
|
||||||
let swp = *p;
|
|
||||||
*p = 0;
|
|
||||||
tty_text_print(tty, msg, u32::from(fgc), u32::from(bgc));
|
|
||||||
*p = swp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
use core::{
|
||||||
|
alloc::Layout,
|
||||||
|
mem::transmute,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
ptr::addr_of,
|
||||||
|
};
|
||||||
|
|
||||||
|
use alloc::alloc::alloc;
|
||||||
|
|
||||||
|
pub struct Box<T: ?Sized> {
|
||||||
|
inner: *mut T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Box<T> {
|
||||||
|
pub fn new(t: T) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let inner = alloc(Layout::for_value(&t));
|
||||||
|
inner.copy_from(addr_of!(t).cast(), 1);
|
||||||
|
Self {
|
||||||
|
inner: transmute(inner),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Deref for Box<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
unsafe { self.inner.as_ref().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> DerefMut for Box<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
unsafe { self.inner.as_mut().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod boxed;
|
||||||
|
pub mod string;
|
||||||
|
pub mod vec;
|
|
@ -0,0 +1,81 @@
|
||||||
|
use core::ops::{Add, AddAssign};
|
||||||
|
|
||||||
|
use super::vec::{Vec, VecIterator};
|
||||||
|
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub struct String {
|
||||||
|
data: Vec<char>,
|
||||||
|
u8data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl String {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
data: Vec::new(),
|
||||||
|
u8data: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.data.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chars(&self) -> VecIterator<char> {
|
||||||
|
self.data.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
|
&self.u8data[..]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||||
|
&mut self.u8data[..]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromIterator<char> for String {
|
||||||
|
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
|
||||||
|
let data = Vec::from_iter(iter);
|
||||||
|
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
|
||||||
|
Self { data, u8data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FromIterator<&'a char> for String {
|
||||||
|
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
|
||||||
|
let data = Vec::from_iter(iter.into_iter().map(|c| *c));
|
||||||
|
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
|
||||||
|
Self { data, u8data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for String {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for String {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(mut self, rhs: Self) -> Self::Output {
|
||||||
|
self.data.append(&mut rhs.chars().map(|c| *c).collect());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddAssign for String {
|
||||||
|
fn add_assign(&mut self, rhs: String) {
|
||||||
|
*self = self.clone() + rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ToString {
|
||||||
|
fn to_string(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for str {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
String::from_iter(self.chars())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,280 @@
|
||||||
|
use core::{
|
||||||
|
alloc::Layout,
|
||||||
|
ops::{Index, IndexMut, Range, RangeFull},
|
||||||
|
ptr::{addr_of_mut, null_mut},
|
||||||
|
slice,
|
||||||
|
};
|
||||||
|
|
||||||
|
use alloc::alloc::{alloc, dealloc};
|
||||||
|
|
||||||
|
pub struct Vec<T> {
|
||||||
|
pointer: *mut T,
|
||||||
|
length: usize,
|
||||||
|
capacity: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Vec<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
pointer: null_mut(),
|
||||||
|
length: 0,
|
||||||
|
capacity: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn extend_capacity(&mut self) {
|
||||||
|
let newp = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
|
||||||
|
self.pointer.copy_to(newp, self.length);
|
||||||
|
dealloc(
|
||||||
|
self.pointer.cast(),
|
||||||
|
Layout::array::<T>(self.capacity).unwrap(),
|
||||||
|
);
|
||||||
|
self.pointer = newp;
|
||||||
|
self.capacity *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, item: T) {
|
||||||
|
if self.pointer.is_null() {
|
||||||
|
self.pointer = unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() };
|
||||||
|
self.capacity = 4;
|
||||||
|
self.length = 0;
|
||||||
|
}
|
||||||
|
if self.capacity == self.length {
|
||||||
|
unsafe { self.extend_capacity() }
|
||||||
|
}
|
||||||
|
unsafe { self.pointer.offset(self.length as isize).write(item) };
|
||||||
|
self.length += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, index: usize, item: T) {
|
||||||
|
if self.capacity == self.length {
|
||||||
|
unsafe { self.extend_capacity() }
|
||||||
|
}
|
||||||
|
let rearlen = self.length - index;
|
||||||
|
unsafe {
|
||||||
|
if rearlen != 0 {
|
||||||
|
let tmp = alloc(Layout::array::<T>(rearlen).unwrap()).cast();
|
||||||
|
self.pointer.offset(index as isize).copy_to(tmp, rearlen);
|
||||||
|
self.pointer.offset(index as isize).write(item);
|
||||||
|
self.pointer
|
||||||
|
.offset(index as isize + 1)
|
||||||
|
.copy_from(tmp, rearlen);
|
||||||
|
} else {
|
||||||
|
self.pointer.offset(self.length as isize).write(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.length += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append(&mut self, v: &mut Self) {
|
||||||
|
while self.capacity < self.length + v.length {
|
||||||
|
unsafe { self.extend_capacity() }
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
self.pointer
|
||||||
|
.offset(self.length as isize)
|
||||||
|
.copy_from(v.pointer.cast_const(), v.length)
|
||||||
|
};
|
||||||
|
self.length += v.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn split_at(&self, index: usize) -> (&[T], &[T]) {
|
||||||
|
if index >= self.length {
|
||||||
|
panic!("Index out of bound.");
|
||||||
|
}
|
||||||
|
(&self[0..index], &self[index..self.length])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.length
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.length == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last_mut(&mut self) -> Option<&mut T> {
|
||||||
|
unsafe { self.pointer.offset(self.length as isize - 1).as_mut() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last(&self) -> Option<&T> {
|
||||||
|
unsafe { self.pointer.offset(self.length as isize - 1).as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, index: usize) -> T {
|
||||||
|
if index >= self.length {
|
||||||
|
panic!("Index out of bound.");
|
||||||
|
}
|
||||||
|
let mut t: T = T::default();
|
||||||
|
let pt = addr_of_mut!(t);
|
||||||
|
unsafe {
|
||||||
|
pt.copy_from(self.pointer.offset(index as isize).cast_const(), 1);
|
||||||
|
self.pointer.offset(index as isize).copy_from(
|
||||||
|
self.pointer.offset(index as isize + 1),
|
||||||
|
self.length - index - 1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> VecIterator<T> {
|
||||||
|
VecIterator {
|
||||||
|
pointer: self.pointer,
|
||||||
|
index: 0,
|
||||||
|
length: self.length,
|
||||||
|
_phantom: &(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Default for Vec<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Index<usize> for Vec<T> {
|
||||||
|
type Output = T;
|
||||||
|
|
||||||
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
|
unsafe { self.pointer.offset(index as isize).as_ref().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Index<Range<usize>> for Vec<T> {
|
||||||
|
type Output = [T];
|
||||||
|
|
||||||
|
fn index(&self, index: Range<usize>) -> &Self::Output {
|
||||||
|
unsafe { &slice::from_raw_parts_mut(self.pointer, self.length)[index] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Index<RangeFull> for Vec<T> {
|
||||||
|
type Output = [T];
|
||||||
|
|
||||||
|
fn index(&self, _: RangeFull) -> &Self::Output {
|
||||||
|
unsafe { slice::from_raw_parts(self.pointer.cast(), self.length) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> IndexMut<RangeFull> for Vec<T> {
|
||||||
|
fn index_mut(&mut self, _: RangeFull) -> &mut Self::Output {
|
||||||
|
unsafe { slice::from_raw_parts_mut(self.pointer.cast(), self.length) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Clone for Vec<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let res = Self {
|
||||||
|
pointer: unsafe { alloc(Layout::array::<T>(self.capacity).unwrap()).cast() },
|
||||||
|
length: self.length,
|
||||||
|
capacity: self.capacity,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
res.pointer
|
||||||
|
.copy_from(self.pointer.cast_const(), self.length)
|
||||||
|
};
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Drop for Vec<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
dealloc(
|
||||||
|
self.pointer.cast(),
|
||||||
|
Layout::array::<T>(self.capacity).unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> FromIterator<T> for Vec<T> {
|
||||||
|
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
|
||||||
|
let mut res = Vec::new();
|
||||||
|
for i in iter {
|
||||||
|
res.push(i);
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> IntoIterator for Vec<T> {
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
type IntoIter = VecIter<T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VecIterator<'a, T> {
|
||||||
|
pointer: *mut T,
|
||||||
|
index: usize,
|
||||||
|
length: usize,
|
||||||
|
_phantom: &'a (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: 'a> Iterator for VecIterator<'a, T> {
|
||||||
|
type Item = &'a T;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.index == self.length {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let res = unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) };
|
||||||
|
self.index += 1;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: 'a> DoubleEndedIterator for VecIterator<'a, T> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.index == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.index -= 1;
|
||||||
|
unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VecIter<T> {
|
||||||
|
pointer: *mut T,
|
||||||
|
index: usize,
|
||||||
|
length: usize,
|
||||||
|
capacity: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Iterator for VecIter<T> {
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.index == self.length {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let mut t = T::default();
|
||||||
|
let res = unsafe {
|
||||||
|
self.pointer
|
||||||
|
.offset(self.index as isize)
|
||||||
|
.copy_to(addr_of_mut!(t), 1);
|
||||||
|
Some(t)
|
||||||
|
};
|
||||||
|
self.index += 1;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Drop for VecIter<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
dealloc(
|
||||||
|
self.pointer.cast(),
|
||||||
|
Layout::array::<T>(self.capacity).unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
pub mod string;
|
pub mod alloc;
|
||||||
|
pub mod core;
|
||||||
|
|
Loading…
Reference in New Issue