重写rust核心库,构建中断处理框架 #6
|
@ -0,0 +1,29 @@
|
||||||
|
======== 04-21 16:50 ========
|
||||||
|
Hit null pointer at 0x100370a
|
||||||
|
Stack trace:
|
||||||
|
1 0x0000000001007b90 -> interrupt_req_DE
|
||||||
|
2 0x00000000010072b0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut
|
||||||
|
3 0x0000000001007e60 -> <metaverse::libk::alloc::string::String as core::iter::traits::collect::FromIterator::<char>>::from_iter
|
||||||
|
4 0x0000000001005eb0 -> <alloc::string::String as core::iter::traits::collect::FromIterator<char>>::from_iter
|
||||||
|
5 0x0000000001005d80 -> <alloc::string::String as core::iter::traits::collect::Extend<char>>::extend
|
||||||
|
6 0x0000000001004840 -> alloc::vec::Vec::reserve
|
||||||
|
7 0x0000000001005900 -> alloc::raw_vec::RawVec::reserve::{do_reserve_and_handle}
|
||||||
|
8 0x00000000010055c0 -> alloc::raw_vec::RawVec::grow_amortized
|
||||||
|
9 0x00000000010051e0 -> alloc::raw_vec::finish_grow
|
||||||
|
10 0x0000000001005a90 -> <alloc::alloc::Global as core::alloc::Allocator>::allocate
|
||||||
|
11 0x0000000001004900 -> alloc::alloc::Global::alloc_impl
|
||||||
|
12 0x00000000010048a0 -> alloc::alloc::alloc
|
||||||
|
13 0x00000000010036e0 -> core::ptr::read_volatile::precondition_check
|
||||||
|
使用了core crate中的String,导致最终调用了一个含有未正确链接的函数。
|
||||||
|
|
||||||
|
======== 04-23 13:55 ========
|
||||||
|
Hit null pointer as 0x100351a.
|
||||||
|
Stack trace:
|
||||||
|
0x00000000010054d0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut
|
||||||
|
0x0000000001006170 -> <str as metaverse::libk::alloc::string::ToString>::to_string
|
||||||
|
0x0000000001006080 -> <metaverse::libk::alloc::string::String as core::iter::traits::collect::FromIterator<char>>::from_iter
|
||||||
|
0x0000000001007450 -> <metaverse::libk::alloc::vec::Vec as core::iter::traits::collect::FromIterator>::from_iter
|
||||||
|
0x0000000001006a10 -> metaverse::libk::alloc::vec::Vec::push
|
||||||
|
0x0000000001003f60 -> alloc::alloc::alloc
|
||||||
|
0x00000000010034f0 -> core::ptr::read_volatile::precondition_check
|
||||||
|
使用了core crate的alloc函数,其中含有未正确链接的函数。
|
27
src/Makefile
27
src/Makefile
|
@ -31,16 +31,24 @@ endif
|
||||||
################################
|
################################
|
||||||
# rust语言环境变量
|
# rust语言环境变量
|
||||||
|
|
||||||
|
TARGET_TRIPLE =
|
||||||
|
|
||||||
|
ifeq (${ARCH},x86_64)
|
||||||
|
TARGET_TRIPLE := x86_64-unknown-none
|
||||||
|
endif
|
||||||
|
|
||||||
|
RUSTLIB_PATH = ../target/sysroot/lib/rustlib/${TARGET_TRIPLE}/lib
|
||||||
|
RUST_LIBS = $(shell ls -d ${RUSTLIB_PATH}/lib*.rlib)
|
||||||
|
|
||||||
RSCFLAGS = --emit obj --crate-type staticlib --verbose \
|
RSCFLAGS = --emit obj --crate-type staticlib --verbose \
|
||||||
--crate-name=metaverse \
|
--crate-name=metaverse \
|
||||||
--edition 2021 \
|
--edition 2021 \
|
||||||
-L crate="${PWD}/../rustlib/src/" \
|
|
||||||
-C code-model=large \
|
-C code-model=large \
|
||||||
-C relocation-model=static \
|
-C relocation-model=static \
|
||||||
-C embed-bitcode=no
|
-C embed-bitcode=no \
|
||||||
|
-C panic=abort
|
||||||
|
|
||||||
ifeq (${ARCH},x86_64)
|
ifeq (${ARCH},x86_64)
|
||||||
RSCFLAGS := ${RSCFLAGS} --target x86_64-unknown-none
|
|
||||||
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse
|
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -48,18 +56,14 @@ ifdef release
|
||||||
RSCFLAGS := ${RSCFLAGS} -O
|
RSCFLAGS := ${RSCFLAGS} -O
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RUSTLIB_PATH = ../rustlib/${ARCH}
|
|
||||||
RUST_LIBS = "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_core.rlib"
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
||||||
metaverse.elf: kernel libk rust metaverse.lds font_file.o
|
metaverse.elf: kernel libk rust metaverse.lds font_file.o
|
||||||
@echo -e "\e[1;33mld\e[0m \e[1;32m$@\e[0m \e[34m<--\e[0m \e[32m${SUBOBJS}\e[0m"
|
@echo -e "\e[1;33mld\e[0m \e[1;32m$@\e[0m \e[34m<--\e[0m \e[32m${SUBOBJS}\e[0m"
|
||||||
@ld -T metaverse.lds -Map=metaverse.map -unresolved-symbols=ignore-all -o $@ ${SUBOBJS} ${RUST_LIBS} \
|
@ld -T metaverse.lds -Map=metaverse.map -unresolved-symbols=ignore-all -o $@ ${SUBOBJS} ${RUST_LIBS} \
|
||||||
2>&1 | "${SOURCE}/colorize" "warning:=yellow" "error:=red" "ld=lyellow"
|
2>&1 | "${SOURCE}/colorize" "warning:=lpink" "error:=red" "ld=lyellow"
|
||||||
|
|
||||||
.PHONY: kernel libk all clear postproc rust
|
.PHONY: kernel libk all clear postproc rust rustlib
|
||||||
|
|
||||||
all: postproc metaverse.elf
|
all: postproc metaverse.elf
|
||||||
@echo -e "Build \e[1;32msucceeded\e[0m."
|
@echo -e "Build \e[1;32msucceeded\e[0m."
|
||||||
|
@ -92,7 +96,10 @@ libk:
|
||||||
echo -e "\e[33m-------------------------\e[0m"; \
|
echo -e "\e[33m-------------------------\e[0m"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rust: postproc
|
../target:
|
||||||
|
@-cargo xbuild --target ${TARGET_TRIPLE} --release
|
||||||
|
|
||||||
|
rust: postproc ../target
|
||||||
@echo -e "\e[1m\e[33mrustc\e[0m \e[34m-->\e[0m \e[1m\e[32m$@.o\e[0m"
|
@echo -e "\e[1m\e[33mrustc\e[0m \e[34m-->\e[0m \e[1m\e[32m$@.o\e[0m"
|
||||||
@rustc ${RSCFLAGS} lib.rs -o rust.o
|
@rustc ${RSCFLAGS} lib.rs -o rust.o
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,13 @@
|
||||||
use crate::message;
|
use crate::{
|
||||||
|
kernel::{
|
||||||
use super::{
|
klog::{KernelLogger, LoggerLevel},
|
||||||
klog::{KernelLogger, LoggerLevel},
|
tty::tty::Tty,
|
||||||
tty::tty::{BuilderFunctions::*, Color, Tty},
|
},
|
||||||
|
message_raw,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn kmain_rust() -> ! {
|
extern "C" fn kmain_rust() -> ! {
|
||||||
let tty = Tty::from_id(0).unwrap();
|
let tty = Tty::from_id(0).unwrap();
|
||||||
let mut logger = KernelLogger::new();
|
|
||||||
logger.info(message!(
|
|
||||||
Msg("Hello, "),
|
|
||||||
Msg("Metaverse"),
|
|
||||||
FgColor(Color::GREEN),
|
|
||||||
Msg("!\n")
|
|
||||||
));
|
|
||||||
for msg in logger.iter(LoggerLevel::Info) {
|
|
||||||
tty.print(msg);
|
|
||||||
}
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ use core::{
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn memm_kernel_allocate(size: usize) -> *mut u8;
|
fn memm_kernel_allocate(size: usize) -> *mut u8;
|
||||||
// pub fn memm_user_allocate(size: usize, pid: usize);
|
// pub fn memm_user_allocate(size: usize, pid: usize);
|
||||||
pub fn memm_free(mem: *mut u8);
|
fn memm_free(mem: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct KernelAllocator {}
|
pub struct KernelAllocator {}
|
||||||
|
@ -31,4 +31,4 @@ unsafe impl GlobalAlloc for KernelAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {};
|
pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {};
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
mod memm;
|
pub mod memm;
|
||||||
|
|
|
@ -25,22 +25,43 @@ macro_rules! message_bgc {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! message {
|
macro_rules! message_raw {
|
||||||
( $( $e : expr ),* ) => {{
|
( $( $e : expr ),* ) => {{
|
||||||
use crate::{
|
use crate::{
|
||||||
kernel::tty::tty::{MessageBuilder, BuilderFunctions},
|
kernel::tty::tty::{MessageBuilder, BuilderFunctions::*, Color},
|
||||||
message_msg, message_fgc, message_bgc
|
message_msg, message_fgc, message_bgc
|
||||||
};
|
};
|
||||||
let mut tmp_builder = MessageBuilder::new();
|
let mut tmp_builder = MessageBuilder::new();
|
||||||
$(
|
$(
|
||||||
if let BuilderFunctions::Msg(e) = $e {
|
if let Msg(e) = $e {
|
||||||
message_msg!(tmp_builder, e);
|
message_msg!(tmp_builder, &e);
|
||||||
} else if let BuilderFunctions::FgColor(c) = $e {
|
} else if let FgColor(c) = $e {
|
||||||
message_fgc!(tmp_builder, c);
|
message_fgc!(tmp_builder, c);
|
||||||
} else if let BuilderFunctions::BgColor(c) = $e {
|
} else if let BgColor(c) = $e {
|
||||||
message_bgc!(tmp_builder, c);
|
message_bgc!(tmp_builder, c);
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
tmp_builder.build()
|
tmp_builder.build()
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! message {
|
||||||
|
( $fmtter : expr, $( $e : expr ),* ) => {{
|
||||||
|
use crate::{
|
||||||
|
kernel::tty::tty::{
|
||||||
|
MessageBuilder,
|
||||||
|
FmtMeta,
|
||||||
|
Color,
|
||||||
|
format_message
|
||||||
|
},
|
||||||
|
libk::alloc::vec::Vec,
|
||||||
|
};
|
||||||
|
let mut formatter = $fmtter.chars().collect::<Vec<char>>();
|
||||||
|
let builder = MessageBuilder::new();
|
||||||
|
$(
|
||||||
|
let builder = builder.append(format_message(&mut formatter, $e));
|
||||||
|
)*
|
||||||
|
builder.build()
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
|
@ -233,8 +233,8 @@ pub struct MessageBuilder {
|
||||||
msg: Message,
|
msg: Message,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BuilderFunctions<'a> {
|
pub enum BuilderFunctions<T: ToString> {
|
||||||
Msg(&'a str),
|
Msg(T),
|
||||||
FgColor(Color),
|
FgColor(Color),
|
||||||
BgColor(Color),
|
BgColor(Color),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
|
#![feature(layout_for_ptr)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
use core::alloc::{GlobalAlloc, Layout};
|
||||||
|
|
||||||
|
use crate::kernel::memm::memm::KERNEL_ALLOCATOR;
|
||||||
|
|
||||||
|
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
|
||||||
|
KERNEL_ALLOCATOR.alloc(layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
|
||||||
|
KERNEL_ALLOCATOR.dealloc(ptr, layout);
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ use core::{
|
||||||
ptr::addr_of,
|
ptr::addr_of,
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::alloc::alloc;
|
use crate::libk::alloc::alloc::{alloc, dealloc};
|
||||||
|
|
||||||
pub struct Box<T: ?Sized> {
|
pub struct Box<T: ?Sized> {
|
||||||
inner: *mut T,
|
inner: *mut T,
|
||||||
|
@ -36,3 +36,14 @@ impl<T: ?Sized> DerefMut for Box<T> {
|
||||||
unsafe { self.inner.as_mut().unwrap() }
|
unsafe { self.inner.as_mut().unwrap() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Drop for Box<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
dealloc(
|
||||||
|
self.inner.cast(),
|
||||||
|
Layout::for_value_raw(self.inner.cast_const()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod alloc;
|
||||||
pub mod boxed;
|
pub mod boxed;
|
||||||
pub mod string;
|
pub mod string;
|
||||||
pub mod vec;
|
pub mod vec;
|
||||||
|
|
|
@ -31,6 +31,11 @@ impl String {
|
||||||
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||||
&mut self.u8data[..]
|
&mut self.u8data[..]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, index: usize, item: char) {
|
||||||
|
self.data.insert(index, item);
|
||||||
|
self.u8data.insert(index, item as u8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromIterator<char> for String {
|
impl FromIterator<char> for String {
|
||||||
|
@ -72,6 +77,12 @@ impl AddAssign for String {
|
||||||
|
|
||||||
pub trait ToString {
|
pub trait ToString {
|
||||||
fn to_string(&self) -> String;
|
fn to_string(&self) -> String;
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for str {
|
impl ToString for str {
|
||||||
|
@ -79,3 +90,201 @@ impl ToString for str {
|
||||||
String::from_iter(self.chars())
|
String::from_iter(self.chars())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToString for &'static str {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
(*self).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for u8 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, (tohex(num % 16) + b'0') as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for u16 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, (tohex(num % 16) + b'0') as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ToString for u32 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, (tohex(num % 16) + b'0') as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ToString for u64 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, (tohex(num % 16) + b'0') as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ToString for u128 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, (tohex(num % 16) + b'0') as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use core::{
|
||||||
slice,
|
slice,
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::alloc::{alloc, dealloc};
|
use crate::libk::alloc::alloc::{alloc, dealloc};
|
||||||
|
|
||||||
pub struct Vec<T> {
|
pub struct Vec<T> {
|
||||||
pointer: *mut T,
|
pointer: *mut T,
|
||||||
|
@ -205,7 +205,12 @@ impl<T: Default> IntoIterator for Vec<T> {
|
||||||
type IntoIter = VecIter<T>;
|
type IntoIter = VecIter<T>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
todo!()
|
VecIter {
|
||||||
|
pointer: self.pointer,
|
||||||
|
index: 0,
|
||||||
|
length: self.length,
|
||||||
|
capacity: self.capacity,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue